What I want to do:
Create a number of modules with the forms folder inside them.
What I did:
Create a bootstrapper inside the module and added an _initAutoload function with the specific module name as namespace.
For instance, an admin module with the following bootstrapper:
class Admin_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Admin_',
'basePath' => dirname(__FILE__),
));
return $autoloader;
}
}
My question is:
Is this the correct way of doing what I want? - I tried it without having the admin bootstrapper, but it couldn't find my form, until I added the bootstrapper.
Cheers
Chris
The autoloader is automatically set up for each module bootstrap. You don't need to configure it manually.
class Admin_Bootstrap extends Zend_Application_Module_Bootstrap {}
is all you need.
Then put your forms in /application/modules/admin/forms/.
Admin_Form_Myform extends Zend_Form {...}
For your custom resources, customize resourceAutoloader:
class Admin_Bootstrap extends Zend_Application_Module_Bootstrap
{
public function _initAuloload()
{
$resourceLoader = $this->_resourceAuloloader;
// var_dump($resourceLoader);
}
}
Remember to add also in your apllication.ini
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules = ""
Related
I want to instantiate a class every time a page is loaded in CodeIgniter.
It looks like the /application/config/autoload.php is the place to do this. Is that correct?
I added this line to the package's autoload:
$autoload['packages'] = array('/application/third_party/Autoload.php');
Now I need this code to be executed on every page, where can I make this happen?
$bugsnag = new Bugsnag_Client("YOUR-API-KEY-HERE");
set_error_handler(array($bugsnag, "errorHandler"));
set_exception_handler(array($bugsnag, "exceptionHandler"));
To auto load a package (according to CI), you should put the package path/name in following array, like
$autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared');
But it doesn't execute any code automatically but makes your package available to use without explicitly loading it.
To make some code execute every time, you can put that code in your base controller's constructor function. Also, you can put the code in your config.php file. If you have an extended base controller, like application/core/MY_Controller.php
class MY_Controller extends CI_Controller {
//
}
Then you can use it's constructor function like
class MY_Controller extends CI_Controller {
function __construct()
{
parent::__construct();
$this->bugsnag = new Bugsnag_Client("YOUR-API-KEY-HERE");
set_error_handler(array($bugsnag, "errorHandler"));
set_exception_handler(array($bugsnag, "exceptionHandler"));
}
}
Rest of your controllers will use/extend MY_Controller instead of CI_Controller.
But you can also use a hook in this case (to register custom exception handlers), in application/config/hooks.php file, put following code
$hook['pre_controller'][] = array(
'class' => 'CustomExceptionHook',
'function' => 'SetExceptionHandlers',
'filename' => 'CustomExceptionHook.php',
'filepath' => 'hooks'
);
Create a class in application/hooks/CustomExceptionHook.php folder, like
class CustomExceptionHook
{
public function SetExceptionHandlers()
{
// add package path (if not auto-loaded)
$this->load->add_package_path(APPPATH.'third_party/package_folder/');
// load package (if not auto-loaded)
$this->load->library('Bugsnag_Client');
set_error_handler(array($this->Bugsnag_Client, "errorHandler"));
set_exception_handler(array($this->Bugsnag_Client, "exceptionHandler"));
}
}
Well let me explain it how you can do it.
As you have autoloaded the package its fine now you need to do this.
Create a MY_Controller in application/core/ directory.
Class MY_Controller Extends CI_Controller{
public $bugsnag = '';
public function __construct(){
parent::__construct();
$this->bugsnag = new Bugsnag_Client("YOUR-API-KEY-HERE");
set_error_handler(array($bugsnag, "errorHandler"));
set_exception_handler(array($bugsnag, "exceptionHandler"));
}
}
Note $this->bugsnag contains the object now. When you need to access it in any page you can simply do it like this by extending the parent class
Class Test Extends MY_Controller{
public function __construct(){
parent::__construct();
}
public function index(){
echo '<pre>';
print_R($this->bugsnag);
}
}
Here is a version of MY_Controller.php
This is using BugSnag via composer install
Using this method exposes the $this->_bugsnag variable to the entire CI System
class MY_Controller extends CI_Controller {
// Application Version
public $_app_version;
// Bugsnag
public $_bugsnag = NULL;
/**
* Constructor
*/
public function __construct() {
parent::__construct();
// Dont print errors to screen
ini_set('display_errors', 0);
// Load configs
$this->load->config('appversion');
$this->load->config('bugsnag');
$this->_app_version = $this->config->item('app_version');
// INIT: bugsnag
// https://docs.bugsnag.com/platforms/php/other/configuration-options/
$this->_bugsnag = Bugsnag\Client::make( $this->config->item('bugsnagAPIKey') );
$this->_bugsnag->setErrorReportingLevel( E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED );
$this->_bugsnag->setNotifyReleaseStages( ['developement', 'testing', 'production'] );
$this->_bugsnag->setReleaseStage( ENVIRONMENT );
$this->_bugsnag->setAppType( 'API Server' );
$this->_bugsnag->setAppVersion( $this->_app_version );
$this->_bugsnag->setHostname( $_SERVER['HTTP_HOST'] );
$this->_bugsnag->setProjectRoot( realpath(APPPATH) );
$this->_bugsnag->setFilters( ['password'] );
Bugsnag\Handler::register( $this->_bugsnag );
// Load Helpers
// Load Libraries
// Load Languages
}
}
You can now access the BugSnag methods like this.
$this->_bugsnag->leaveBreadcrumb( 'Hello' );
$this->_bugsnag->notifyException( $e );
Create a MY_Controller & inherit all your controllers off that. You can find more on this by Googling "MY_Controller"
In my module bootstrap:
<?php
class Api_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initAllowedMethods()
{
$front = Zend_Controller_Front::getInstance();
$front->setParam('api_allowedMethods', array('POST'));
}
protected function _initActionHelperBrokers()
{
Zend_Controller_Action_HelperBroker::addPath(APPLICATION_PATH . '/modules/api/controllers/helpers', 'Api_Controller_Action_Helper_');
Zend_Controller_Action_HelperBroker::addHelper(new Api_Controller_Action_Helper_Model());
}
}
There is a Api_Controller_Action_Helper_Model at /var/www/project/application/modules/api/controller/helpers/Model.php
But I get:
PHP Fatal error: Class 'Api_Controller_Action_Helper_Model' not found in /var/www/accounts.amh.localhost/application/modules/api/Bootstrap.php on line 15
As far as I can tell from the API and http://akrabat.com/zend-framework/using-action-helpers-in-zend-framework/ this should work.
I'm pretty sure this isn't a bootstrapping issue like I have had before, as I am specifically add the path/prefix right before trying to add the helper.
What else might I have missed?
The problem here is that the module autoloader does not know about controller action helper resources.
Try something like this in your module bootstrap
protected function _initResourceLoader()
{
$resourceLoader = $this->getResourceLoader();
$resourceLoader->addResourceType('actionhelper',
'controllers/helpers', 'Controller_Action_Helper');
}
All that being said, as your helper has an empty constructor, you could omit the addHelper() line and just let the broker automatically create it when requested in your controllers, eg
$helper = $this->getHelper('Model');
I'm just really starting with the Zend Framework, and currently I'm having a problem with the Zend_Loader_PluginLoader.
I managed to get a module specific plugin working easily enough using the following code:
class Api_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initPlugins()
{
$loader = new Zend_Loader_PluginLoader(array(
'Api_Plugin' => 'application/modules/api/plugins',
));
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Api_Plugin_ErrorControllerSelectorPlugin());
}
}
Edit: The class file is located at application/modules/api/plugins/ErrorControllerSelectorPlugin.php
I then tried to adapt this to get a plugin loaded for the whole application using:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initAppAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'App',
'basePath' => dirname(__FILE__),
));
return $autoloader;
}
protected function _initPlugins()
{
$loader = new Zend_Loader_PluginLoader(array(
'My_Plugin' => 'application/plugins',
));
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new My_Plugin_ModuleConfigLoaderPlugin());
}
}
But I'm getting errors:
Fatal error: Class 'My_Plugin_ModuleConfigLoaderPlugin' not found in /var/www/localhost/application/Bootstrap.php on line 22
Edit: The class file is located at application/plugins/ModuleConfigLoaderPlugin.php
So - since the files are where I would expect them to be as far as the prefix/path pairs sent to Zend_Loader_PluginLoader() and the code in both cases are the same, what's the difference?
How do I get it to recognise my application-level plugins?
If you want the app-level plugin to reside within the namespace My_, you either need to put the My folder out in the library folder or declare the app-level namespace to be My_.
Assuming that you already have other stuff within your top-level app that uses the App_ namespace, then the easiest thing would be the former: move your My folder out into the library.
So, the plugin would reside in:
library/My/Plugins/ModuleConfigLoaderPlugin.php.
Then make sure that your configs/application.ini registers the My_ namespace:
autoloaderNamespaces[] = "My_"
Then the app-level Bootstrap could contain something like:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initAppAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'App',
'basePath' => dirname(__FILE__),
));
return $autoloader;
}
protected function _initPlugins()
{
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new My_Plugin_ModuleConfigLoaderPlugin());
}
}
Alternatively, since your plugin does not sem to require any params, you could instantiate it via configs/application.ini using:
resources.frontcontroller.plugins[] = "My_Plugin_ModuleConfigLoaderPlugin"
i have 3 moulde like blow ,
application
|
modules
|
default
|---models
|--views
|--forms
|--controller-
|-indexController
|-errorController
admin
|---models-
|-user.php
|--views
|--forms
|--controller--
|-userController
cars
|---models
|--views
|--forms
|--controller
bootstrap.php
and in my appliction.ini
i have this config
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules = ""
and in my bootsrap file i have this autoloader
$modelLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH ));
so i can not access to my models class in userController and other controllers
i have this code in my userController
$userModel = new admin_Model_Users();
but i got error can not find this class
and this class is in user.php
class admin_Model_Users extends Zend_Db_Table_Abstract
{
public function getListUser() {
}
}
someone may help where is my wrong and how could fix this problem?
Get rid of
$modelLoader = new
Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH ));
and add
Bootstrap.php in you module:
class Admin_Bootstrap extends Zend_Application_Module_Bootstrap
{
}
also name your class Admin_Model_Users and use it accordigly where appropriorate.
Use capital "U" in the filename, capital "A" in the class name. I mean names should be consistent and in accordance to ZF guidelines.
Also in ini file:
change entry to
resources.modules[] =
Try the following:
class admin_Model_Users extends Zend_Db_Table_Abstract
Should become
class Models_UsersAdmin extends Zend_Db_Table_Abstract
$userModel = new admin_Model_Users();
Should become
$userModel = new Models_UsersAdmin();
Update
in you're application.ini file where you register you're namespaces add the following line:
autoloaderNamespaces[] = "Models" ( or register the namespace "Models" at bootstrap )
;define modules after controller in application.ini file
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
I've got a class library in defined here .../projectname/library/Me/Myclass.php defined as follows:
<?php
class Me_Myclass{
}
?>
I've got the following bootstrap:
<?php
/**
* Application bootstrap
*
* #uses Zend_Application_Bootstrap_Bootstrap
*/
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
/**
* Bootstrap autoloader for application resources
*
* #return Zend_Application_Module_Autoloader
*/
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Default',
'basePath' => dirname(__FILE__),
));
$autoloader->registerNamespace('Me_');
return $autoloader;
}
/**
* Bootstrap the view doctype
*
* #return void
*/
protected function _initDoctype()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$view->doctype('XHTML1_STRICT');
}
/**
* Bootstrap registry and store configuration information
*
* #return void
*/
protected function _initRegistry()
{
$config = new Zend_Config_Ini(APPLICATION_PATH .
'/configs/application.ini', APPLICATION_ENV,
array('allowModifications'=>true));
Zend_Registry::set('configuration', $config);
}
}
In my controller I try to instantiate the class like this:
<?php
class SomeController extends Zend_Controller_Action
{
public function indexAction()
{
$classMaker=new Me_Myclass();
}
}
?>
When I navigate directly to http:/something.com/projectname/some?id=1 I get the following error:
Fatal error: Class 'Me_Myclass' not found in /home/myuser/work/projectname/application/controllers/SomeController.php on line x
Any ideas?
Potentially Pertinent Miscellany:
The autoloader seems to work when I'm extending models with classes I've defined in other folders under application/library.
Someone suggested changing the 'Default', which I attempted but it didn't appear to fix the problem and had the added negative impact of breaking function of models using this namespace.
You class needs to be name Me_Myclass:
class Me_Myclass
{
}
Move your library folder up a level so that you have the folder structure:
/
/application
/library
/public
And then in your Bootstrap add the following to the _initAutoload():
Zend_Loader_Autoloader::getInstance()->registerNamespace('Me_');
you can define the autoload dir in the config.ini file like this:
autoloaderNamespaces[] = "Me_"
;You could add as many as you want Classes dir:
autoloaderNamespaces[] = "Another_"
autoloaderNamespaces[] = "Third_"
works 100%
I think #smack0007 means replace the contents of your _initAutoload method with Zend_Loader_Autoloader::getInstance()->registerNamespace('Me_'); so it looks like this:
protected function _initAutoload()
{
Zend_Loader_Autoloader::getInstance()->registerNamespace('Me_');
}
Not sure if this is your problem, but I just spent the last day and half trying to figure out my own similar problem (first time loading it up on Linux from Windows). Turns out I was blind to my library's folder name case.
/library
/Tlib
is not the same as (on *nix)
/library
/tlib
Class name is typically this
class Tlib_FooMe {
...
}
Hope this helps someone who is similarly absentminded.