Zend Framework - Zend_Loader_PluginLoader - php

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"

Related

Can we Integrate Laravel project as a library in CodeIgniter?

I want to increase the functionality of my CodeIgniter project by integrating some code that is written in laravel? how do I approach,
Can I include the code via library in CodeIgniter ? If yes How?
I only want to include controllers and ORM into the CI.
Laravel code is a kind of api fetcher with function talks with other
3rd party services.
Yes you can use composer to install Laravel specific modules/projects, third-party projects in your CodeIginter. Just include autoload in your `index.php' file at top
// Composer autoload
require_once __DIR__.'/vendor/autoload.php';
I am using Eloquent as ORM in my CodeIgniter codebase.
Create a classmap to your app directory in composer.json
"autoload": {
"psr-4": { "YourApp\\": ["application/"] },
Use Eloquent
To use Eloquent, you will require to create a library to setup Eloquent for use.
/**
* Capsule setting manager for Illuminate/database
*/
use Illuminate\Database\Capsule\Manager as CapsuleManager;
use Illuminate\Events\Dispatcher;
use Illuminate\Container\Container;
class Capsule extends CapsuleManager {
public function __construct()
{
parent::__construct();
//Loaded by CI
if(function_exists('get_instance')) {
$ci = &get_instance();
$db = new stdClass;
$db = $ci->db;
} else {
require_once __DIR__.'/../config/database.php';
$db = (object) $db['default'];
}
$this->addConnection(array(
'driver' => $db->dbdriver,
'host' => $db->hostname,
'database' => $db->database,
'username' => $db->username,
'password' => $db->password,
'charset' => $db->char_set,
'collation' => $db->dbcollat,
'prefix' => $db->dbprefix,
));
$this->setEventDispatcher(new Dispatcher(new Container));
// Make this Capsule instance available globally via static methods... (optional)
$this->setAsGlobal();
// Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher())
$this->bootEloquent();
}
}
// END Capsule Class
Now load the auto load the library, and you have the eloquent beauty.
Similarly, you can use MonoLog for logging, Whoops for error display, Formers\Former for form building etc.
Use Whoops
You can place this code somewhere after autload and defining CI Environment in your index.php to use beautiful https://github.com/filp/whoops library
if (ENVIRONMENT == 'development') {
$whoops = new \Whoops\Run;
$whoops->pushHandler(new Whoops\Handler\PrettyPageHandler());
$whoops->register();
}
You can also extend CI_Router to use Laravel style routing in your Code Igniter app.
Blade Templating
You can extend the CI_Loader to use Blade templating in Code Igniter. Create a new file MY_Loader in your application/core directory with this code.
use Illuminate\Blade\Environment;
use Illuminate\Blade\Loader;
use Illuminate\Blade\View;
class MY_Loader extends CI_Loader {
public function __construct()
{
parent::__construct();
}
public function blade($view, array $parameters = array())
{
$CI =& get_instance();
$CI->config->load('blade', true);
return new View(
new Environment(Loader::make(
$CI->config->item('views_path', 'blade'),
$CI->config->item('cache_path', 'blade')
)),
$view, $parameters
);
}
}
You may have to create a config file blade.php in your application/config directory to store blade specific configurations.
//config/blade.php
$config['views_path'] = APPPATH . 'views/blade/';
$config['cache_path'] = APPPATH . 'cache/blade/';
Now you can do something like this in your controller
class Home extends CI_Controller {
public function index()
{
// Prepare some test data for our views
$array = explode('-', date('d-m-Y'));
list($d, $m, $y) = $array;
// Basic view with no data
echo $this->load->blade('home.index');
// Passing a single value
echo $this->load->blade('home.index')->with('day', $d);
// Multiple values with method chaining
echo $this->load->blade('home.index')
->with('day', $d)
->with('month', $m)
->with('year', $y);
// Passing an array
echo $this->load->blade('home.index', array(
'day' => $d,
'month' => $m,
'year' => $y
));
}
}

Symfony ClassLoader won't load

I'm developing a small php framework for personal use. I am trying to autoload classes with UniversalClassLoader which is used in Symfony, but when I try to use some these classes I got error
Fatal error: Class 'Controller' not found in /opt/lampp/htdocs/web/globeapi/Start.php on line 14
Here is Start.php file code.
require('../libraries/loader/Loader.php');
use Symfony\Component\ClassLoader\UniversalClassLoader;
$auto = require('../config/Auto.php');
$Loader = new UniversalClassLoader();
$Loader->registerNamespaces($auto);
$Loader->register();
Controller::test();
Here is code of Controller class
namespace Libraries\Controller;
class Controller
{
function Controller()
{
}
public static function test()
{
echo 1;
}
}
here is code of Auto.php file which returns array of classes for autoloading.
return array(
'Libraries\Controller' => '../libraries/controller/Controller.php',
'Libraries\Module' => '../libraries/module/Module.php',
'Libraries\View' => '../libraries/view/View.php',
'Libraries\Sammy' => '../libraries/sammy/Sammy.php',
'Libraries\Routes' => '../config/Routes.php'
);
My answer is using the current version of Symfony (2.2) and the UniversalClassLoader. The general idea is to follow the PSR-0 standard so that you don't have to define a mapping entry for each file. Just by following simple naming and location conventions your classes will be found - neat, isn't it? :-) (note that both directory and file names are case sensitive).
The directory structure (the vendor directory is created by composer)
app.php
composer.json
src
App
Libraries
Controller
Controller.php
vendor
symfony
class-loader
Symfony
Component
ClassLoader
The composer.json
{
"require": {
"symfony/class-loader": "2.2.*"
}
}
The content of app.php:
require_once 'vendor/symfony/class-loader/Symfony/Component/ClassLoader/UniversalClassLoader.php';
use Symfony\Component\ClassLoader\UniversalClassLoader;
$loader = new UniversalClassLoader();
$loader->registerNamespace('App', 'src');
$loader->register();
\App\Libraries\Controller\Controller::test();
And finally the controller class:
//src/App/Libraries/Controller/Controller.php
namespace App\Libraries\Controller;
class Controller
{
public static function test()
{
echo 1;
}
}

Zend Action Helpers not loading through Action HelperBroker

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');

Zend framework: Forms in modules

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 = ""

Zend Framework: Autoloading a Class Library

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.

Categories