I tried to follow the recommendations from this topic: zend framework 2 + routing database
I have a route class:
namespace Application\Router;
use Zend\Mvc\Router\Http\RouteInterface;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\Mvc\Router\RouteMatch;
class Content implements RouteInterface, ServiceLocatorAwareInterface {
protected $defaults = array();
protected $routerPluginManager = null;
public function __construct(array $defaults = array()) {
$this->defaults = $defaults;
}
public function setServiceLocator(\Zend\ServiceManager\ServiceLocatorInterface $routerPluginManager) {
$this->routerPluginManager = $routerPluginManager;
}
public function getServiceLocator() {
return $this->routerPluginManager;
}
public static function factory($options = array()) {
if ($options instanceof \Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (!is_array($options)) {
throw new InvalidArgumentException(__METHOD__ . ' expects an array or Traversable set of options');
}
if (!isset($options['defaults'])) {
$options['defaults'] = array();
}
return new static($options['defaults']);
}
public function match(Request $request, $pathOffset = null) {
if (!method_exists($request, 'getUri')) {
return null;
}
$uri = $request->getUri();
$fullPath = $uri->getPath();
$path = substr($fullPath, $pathOffset);
$alias = trim($path, '/');
$options = $this->defaults;
$options = array_merge($options, array(
'path' => $alias
));
return new RouteMatch($options);
}
public function assemble(array $params = array(), array $options = array()) {
if (array_key_exists('path', $params)) {
return '/' . $params['path'];
}
return '/';
}
public function getAssembledParams() {
return array();
}
}
Pay attention that the match() function returns object of the instance of Zend\Mvc\Router\RouteMatch
However in the file Zend\Mvc\Router\Http\TreeRouteStack it checks for object to be the instance of RouteMatch (without prefix of namespace)
if (
($match = $route->match($request, $baseUrlLength, $options)) instanceof RouteMatch
&& ($pathLength === null || $match->getLength() === $pathLength)
)
And the condition fails in my case because of the namespace.
Any suggestions?
Ok, i figured out what the problem was.
Instead of returning Zend\Mvc\Router\RouteMatch I should return Zend\Mvc\Router\Http\RouteMatch
This fixed my problem
Related
I was receiving an error message because I upgraded to PHP 7 from 5 and added public function helper(heler = array()) but now I receiving a parse error
Message: syntax error, unexpected 'public' (T_PUBLIC)
I have tried moving the array to the My_loader.php file but I receive the same error
<?php (defined('BASEPATH')) OR exit('No direct script access allowed');
class MX_Loader extends CI_Loader {
protected $_module;
public $_ci_plugins = array();
public $_ci_cached_vars = array();
public function __construct() {
parent::__construct();
/* set the module name */
$this->_module = CI::$APP->router->fetch_module();
/* add this module path to the loader variables */
$this->_add_module_paths($this->_module);
}
/** Initialize the module **/
public function _init($controller) {
/* references to ci loader variables */
foreach (get_class_vars('CI_Loader') as $var => $val) {
if ($var != '_ci_ob_level') $this->$var =& CI::$APP->load->$var;
}
/* set a reference to the module controller */
$this->controller = $controller;
$this->__construct();
}
/** Add a module path loader variables **/
public function _add_module_paths($module = '') {
if (empty($module)) return;
foreach (Modules::$locations as $location => $offset) {
/* only add a module path if it exists */
if (is_dir($module_path = $location.$module.'/')) {
array_unshift($this->_ci_model_paths, $module_path);
}
}
}
/** Load a module config file **/
public function config($file = 'config', $use_sections = FALSE, $fail_gracefully = FALSE) {
return CI::$APP->config->load($file, $use_sections, $fail_gracefully, $this->_module);
}
/** Load the database drivers **/
public function database($params = '', $return = FALSE, $active_record = NULL) {
if (class_exists('CI_DB', FALSE) AND $return == FALSE AND $active_record == NULL AND isset(CI::$APP->db) AND is_object(CI::$APP->db))
return;
require_once BASEPATH.'database/DB'.EXT;
if ($return === TRUE) return DB($params, $active_record);
CI::$APP->db = DB($params, $active_record);
return CI::$APP->db;
}
/** Load a module helper **/
public function helper($helper) {
if (is_array($helper)) return $this->helpers($helper);
if (isset($this->_ci_helpers[$helper])) return;
list($path, $_helper) = Modules::find($helper.'_helper', $this->_module, 'helpers/');
if ($path === FALSE) return parent::helper($helper);
Modules::load_file($_helper, $path);
$this->_ci_helpers[$_helper] = TRUE;
}
/** Load an array of helpers **/
public function helpers($helpers) {
foreach ($helpers as $_helper) $this->helper($_helper);
}
/** Load a module language file **/
public function language($langfile, $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '') {
return CI::$APP->lang->load($langfile, $idiom, $return, $add_suffix, $alt_path, $this->_module);
}
public function languages($languages) {
foreach($languages as $_language) $this->language($language);
}
/** Load a module library **/
public function library($library, $params = NULL, $object_name = NULL) {
if (is_array($library)) return $this->libraries($library);
$class = strtolower(end(explode('/', $library)));
public function helper($helper = array())
if (isset($this->_ci_classes[$class]) AND $_alias = $this->_ci_classes[$class])
return CI::$APP->$_alias;
($_alias = strtolower($object_name)) OR $_alias = $class;
list($path, $_library) = Modules::find($library, $this->_module, 'libraries/');
/* load library config file as params */
if ($params == NULL) {
list($path2, $file) = Modules::find($_alias, $this->_module, 'config/');
($path2) AND $params = Modules::load_file($file, $path2, 'config');
}
if ($path === FALSE) {
$this->_ci_load_class($library, $params, $object_name);
$_alias = $this->_ci_classes[$class];
} else {
Modules::load_file($_library, $path);
$library = ucfirst($_library);
CI::$APP->$_alias = new $library($params);
$this->_ci_classes[$class] = $_alias;
}
return CI::$APP->$_alias;
}
/** Load an array of libraries **/
public function libraries($libraries) {
foreach ($libraries as $_library) $this->library($_library);
}
/** Load a module model **/
public function model($model, $object_name = NULL, $connect = FALSE) {
if (is_array($model)) return $this->models($model);
($_alias = $object_name) OR $_alias = end(explode('/', $model));
if (in_array($_alias, $this->_ci_models, TRUE))
return CI::$APP->$_alias;
/* check module */
list($path, $_model) = Modules::find(strtolower($model), $this->_module, 'models/');
if ($path == FALSE) {
/* check application & packages */
parent::model($model, $object_name);
} else {
class_exists('CI_Model', FALSE) OR load_class('Model', 'core');
if ($connect !== FALSE AND ! class_exists('CI_DB', FALSE)) {
if ($connect === TRUE) $connect = '';
$this->database($connect, FALSE, TRUE);
}
Modules::load_file($_model, $path);
$model = ucfirst($_model);
CI::$APP->$_alias = new $model();
$this->_ci_models[] = $_alias;
}
return CI::$APP->$_alias;
}
/** Load an array of models **/
public function models($models) {
foreach ($models as $_model) $this->model($_model);
}
/** Load a module controller **/
public function module($module, $params = NULL) {
if (is_array($module)) return $this->modules($module);
$_alias = strtolower(end(explode('/', $module)));
CI::$APP->$_alias = Modules::load(array($module => $params));
return CI::$APP->$_alias;
}
/** Load an array of controllers **/
public function modules($modules) {
foreach ($modules as $_module) $this->module($_module);
}
/** Load a module plugin **/
public function plugin($plugin) {
if (is_array($plugin)) return $this->plugins($plugin);
if (isset($this->_ci_plugins[$plugin]))
return;
list($path, $_plugin) = Modules::find($plugin.'_pi', $this->_module, 'plugins/');
if ($path === FALSE) return;
Modules::load_file($_plugin, $path);
$this->_ci_plugins[$plugin] = TRUE;
}
/** Load an array of plugins **/
public function plugins($plugins) {
foreach ($plugins as $_plugin) $this->plugin($_plugin);
}
/** Load a module view **/
public function view($view, $vars = array(), $return = FALSE) {
list($path, $view) = Modules::find($view, $this->_module, 'views/');
$this->_ci_view_path = $path;
return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
}
public function _ci_is_instance() {}
public function _ci_get_component($component) {
return CI::$APP->$component;
}
public function __get($class) {
return (isset($this->controller)) ? $this->controller->$class : CI::$APP->$class;
}
public function _ci_load($_ci_data) {
foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val) {
$$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];
}
if ($_ci_path == '') {
$_ci_file = strpos($_ci_view, '.') ? $_ci_view : $_ci_view.EXT;
$_ci_path = $this->_ci_view_path.$_ci_file;
} else {
$_ci_file = end(explode('/', $_ci_path));
}
if ( ! file_exists($_ci_path))
show_error('Unable to load the requested file: '.$_ci_file);
if (is_array($_ci_vars))
$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
extract($this->_ci_cached_vars);
ob_start();
if ((bool) #ini_get('short_open_tag') === FALSE AND CI::$APP->config->item('rewrite_short_tags') == TRUE) {
echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
} else {
include($_ci_path);
}
log_message('debug', 'File loaded: '.$_ci_path);
if ($_ci_return == TRUE) return ob_get_clean();
if (ob_get_level() > $this->_ci_ob_level + 1) {
ob_end_flush();
} else {
CI::$APP->output->append_output(ob_get_clean());
}
}
/** Autoload module items **/
public function _autoloader($autoload) {
$path = FALSE;
if ($this->_module) {
list($path, $file) = Modules::find('constants', $this->_module, 'config/');
/* module constants file */
if ($path != FALSE) {
include_once $path.$file.EXT;
}
list($path, $file) = Modules::find('autoload', $this->_module, 'config/');
/* module autoload file */
if ($path != FALSE) {
$autoload = array_merge(Modules::load_file($file, $path, 'autoload'), $autoload);
}
}
/* nothing to do */
if (count($autoload) == 0) return;
/* autoload package paths */
if (isset($autoload['packages'])) {
foreach ($autoload['packages'] as $package_path) {
$this->add_package_path($package_path);
}
}
/* autoload config */
if (isset($autoload['config'])) {
foreach ($autoload['config'] as $config) {
$this->config($config);
}
}
/* autoload helpers, plugins, languages */
foreach (array('helper', 'plugin', 'language') as $type) {
if (isset($autoload[$type])){
foreach ($autoload[$type] as $item) {
$this->$type($item);
}
}
}
/* autoload database & libraries */
if (isset($autoload['libraries'])) {
if (in_array('database', $autoload['libraries'])) {
/* autoload database */
if ( ! $db = CI::$APP->config->item('database')) {
$db['params'] = 'default';
$db['active_record'] = TRUE;
}
$this->database($db['params'], FALSE, $db['active_record']);
$autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
}
/* autoload libraries */
foreach ($autoload['libraries'] as $library) {
$this->library($library);
}
}
/* autoload models */
if (isset($autoload['model'])) {
foreach ($autoload['model'] as $model => $alias) {
(is_numeric($model)) ? $this->model($alias) : $this->model($model, $alias);
}
}
/* autoload module controllers */
if (isset($autoload['modules'])) {
foreach ($autoload['modules'] as $controller) {
($controller != $this->_module) AND $this->module($controller);
}
}
}
}
/** load the CI class for Modular Separation **/
(class_exists('CI', FALSE)) OR require dirname(__FILE__).'/Ci.php';
It looks like you have an extra line just pasted into the middle of the code at line 105:
$class = strtolower(end(explode('/', $library)));
public function helper($helper = array()) // <===== delete this one
if (isset($this->_ci_classes[$class]) AND $_alias = $this->_ci_classes[$class])
return CI::$APP->$_alias;
If you run php -l <file> on your file(s) from the command line, it will tell you exactly where the errors are.
There are few routers out there but I decided to create a very simple route for a very light site.
Here is my index.php
$route = new Route();
$route->add('/', 'Home');
$route->add('/about', 'About');
$route->add('/contact', 'Contact');
Here is my router:
<?php namespace Laws\Route;
use Laws\Controller\Home;
class Route
{
private $_uri = array();
private $_method = array();
private $_route;
public function __construct()
{
}
public function add($uri, $method = null)
{
$this->_uri[] = '/' . trim($uri, '/');
if ($method != null) {
$this->_method[] = $method;
}
}
public function submit()
{
$uriGetParam = isset($_GET['uri']) ? '/' . $_GET['uri'] : '/';
foreach ($this->_uri as $key => $value) {
if (preg_match("#^$value$#", $uriGetParam)) {
$useMethod = $this->_method[$key];
new $useMethod(); // this returns an error (cannot find Home'
new Home(); // this actually works.
}
}
}
}
new $useMethod(); does not work. returns error 'cannot find Home'
new Home(); actually works.
What am I missing here?
You can use your concurrent way for calling a class or you can use this:
call_user_func(array($classname,$methodname))
I am creating my own MVC framework and the way I handle creation of models is as follows:
class ModelFactory {
public function __construct() {
parent::__construct();
}
public static function Create($model, $params = array()) {
if ( ! empty($model)) {
$model = ucfirst(strtolower($model));
$path = 'application/models/' . $model . '.php';
if (file_exists($path)) {
$path = rtrim(str_replace("/", "\\", $path), '.php');
$modelConstruct = new \ReflectionMethod($path, '__construct');
$numParams = $modelConstruct->getNumberOfParameters();
//fill up missing holes with null values
if (count($params) != $numParams) {
$tempArray = array_fill(0, $numParams, null);
$params = ($params + $tempArray);
}
//instead of thi
return new $path($params);
//I want to DO THIS
return new $path($param1, $param2, $param3 ... $paramN)
//where $paramN is the last value from $params array
}
}
return null;
}
}
a simple Model example:
class UsersModel {
public function __construct($userID, $userName) {
//values of these parameters should be passed from Create function
var_dump($userID, $userName);
}
}
Solved:
Thanks to schokocappucino & pozs I fixed it by doing this:
$modelConstruct = new \ReflectionMethod($path, '__construct');
$numParams = $modelConstruct->getNumberOfParameters();
if (count($params) != $numParams) {
$tempArray = array_fill(0, $numParams, '');
$params = ($params + $tempArray);
}
return (new \ReflectionClass($path))->newInstanceArgs($params);
To get the constructor of a class using reflection, use ReflectionClass::getConstructor().
To create a new instance (with the constructor) using an argument list, use ReflectionClass::newInstanceArgs()
return (new ReflectionClass($path))->newInstanceArgs($params);
Are there any libraries to protect against CSRF(PHP5.1/5.2) or do I need to create on myself? I use this snippet from Chris, but without a library I am getting a lot of duplication on every page.
I found this library for PHP5.3, but I am wondering if there are any on PHP5.1/5.2 because I don't believe yet all hosting support PHP5.3.
Since I use Kohana - I've just extended couple of its core classes. It can be used in any code with a little changes though:
class Form extends Kohana_Form
{
public static function open($action = NULL, array $attributes = null)
{
if (is_null($action))
{
$action = Request::current()->uri . ($_SERVER['QUERY_STRING'] ? '?' . $_SERVER['QUERY_STRING'] : '');
}
$open = parent::open($action, $attributes);
$open .= parent::hidden(self::csrf_token_field(), self::csrf_token());
return $open;
}
public static function csrf_token_field()
{
return 'csrf_token';
}
public static function csrf_token()
{
$session = Session::instance();
$token = $session->get(self::csrf_token_field());
if (!$token)
{
$session->set(self::csrf_token_field(), $token = md5(uniqid()));
}
return $token;
}
}
class Validate extends Kohana_Validate
{
public function __construct(array $array, $csrf = true)
{
parent::__construct($array);
if ($csrf)
$this->add_csrf();
}
public static function factory(array $array, $csrf = true)
{
return new Validate($array, $csrf);
}
private function add_csrf()
{
$this->rules(form::csrf_token_field(), array(
'not_empty' => array(),
'csrf' => array()
));
}
protected function csrf($token)
{
return $token == form::csrf_token();
}
}
I keep getting the following exception with a new resource Im making and i cant figure out why:
PHP Fatal error: Uncaught exception 'Zend_Application_Bootstrap_Exception' with message 'Circular resource dependency detected' in /opt/local/lib/php/Zend/Application/Bootstrap/BootstrapAbstract.php:656
Stack trace:
#0 /opt/local/lib/php/Zend/Application/Bootstrap/BootstrapAbstract.php(623): Zend_Application_Bootstrap_BootstrapAbstract->_executeResource('modules')
#1 /opt/local/lib/php/Zend/Application/Bootstrap/BootstrapAbstract.php(580): Zend_Application_Bootstrap_BootstrapAbstract->_bootstrap('modules')
#2 /Library/WebServer/Documents/doctrine-dev/library/APP/Doctrine/Application/Resource/Doctrine.php(36): Zend_Application_Bootstrap_BootstrapAbstract->bootstrap('modules')
#3 /opt/local/lib/php/Zend/Application/Bootstrap/BootstrapAbstract.php(708): APP_Doctrine_Application_Resource_Doctrine->__construct(Array)
#4 /opt/local/lib/php/Zend/Application/Bootstrap/BootstrapAbstract.php(349): Zend_Application_Bootstrap_BootstrapAbstract->_loadPluginResource('doctrine', Array)
#5 /opt/local/lib/php/Zend/Application/Bootstrap/Bootstra in /opt/local/lib/php/Zend/Application/Bootstrap/BootstrapAbstract.php on line 656
As you'll see below ive created a Doctrine Resource that should load only in the general application bootstrap. In order to perform its tasks it needs the Modules resource to be bootstraped
so it calls $this->getBootstrap()->bootstrap('modules'). the Modules resoure never calls Doctrine though, and this seems to be where i get the circular dependency. Ive tried the code that is currently in the constructor for my Doctrine resource also as part of init directly and that doesnt seem to work either. An even bigger mystery to me though is that if i call $bootstrap->bootstrap('modules')
by itself before calling $bootstrap->bootstrap('doctrine') it all seems to play nicely. So why is there circular reference issue?
Relevant parts of application.xml
<resources>
<frontController>
<controllerDirectory><zf:const zf:name="APPLICATION_PATH" />/controllers</controllerDirectory>
<moduleDirectory><zf:const zf:name="APPLICATION_PATH" />/modules</moduleDirectory>
<moduleControllerDirectoryName value="controllers" />
</frontController>
<modules prefixModuleName="Mod" configFilename="module.xml">
<enabledModules>
<default />
<doctrinetest />
<cms>
<myOption value="Test Option Value" />
</cms>
<menu somevar="menu" />
<article somevar="article" />
</enabledModules>
</modules>
<doctrine>
<connections>
<default dsn="mysql://#####:######localhost/#####">
<attributes useNativeEnum="1" />
</default>
</connections>
<attributes>
<autoAccessorOverride value="1" />
<autoloadTableClasses value="1" />
<modelLoading value="MODEL_LOADING_PEAR" />
</attributes>
<directoryNames>
<sql value="data/sql" />
<fixtures value="data/fixtures" />
<migrations value="data/migrations" />
<yaml value="configs/schemas" />
<models value="models" />
</directoryNames>
</doctrine>
</resources>
Doctrine Resource
<?php
class APP_Doctrine_Application_Resource_Doctrine extends Zend_Application_Resource_ResourceAbstract
{
protected $_manager = null;
protected $_modules = array();
protected $_attributes = null;
protected $_connections = array();
protected $_defaultConnection = null;
protected $_directoryNames = null;
protected $_inflectors = array();
public function __construct($options = null)
{
parent::__construct($options);
$bootstrap = $this->getBootstrap();
$autoloader = $bootstrap->getApplication()->getAutoloader();
$autoloader->pushAutoloader(array('Doctrine_Core', 'autoload'), 'Doctrine');
spl_autoload_register(array('Doctrine_Core', 'modelsAutoload'));
$manager = $this->getManager();
$manager->setAttribute('bootstrap', $bootstrap);
// default module uses the application bootstrap unless overridden!
$modules = array('default' => $bootstrap);
if(!isset($options['useModules']) ||
(isset($options['useModules']) && (boolean) $options['useModules']))
{
$moduleBootstraps = $bootstrap->bootstrap('modules')->getResource('modules');
$modules = array_merge($modules, $moduleBootstraps->getArrayCopy());
}
$this->setModules($modules); // configure the modules
$this->_loadModels(); // load all the models for Doctrine
}
public function init()
{
return $this->getManager();
}
public function setConnections(array $connections)
{
$manager = $this->getManager();
foreach($connections as $name => $config)
{
if(isset($config['dsn']))
{
$conn = $manager->connection($config['dsn'], $name);
}
if(isset($config['attributes']) && isset($conn))
{
$this->setAttributes($config['attributes'], $conn);
}
}
return $this;
}
public function setAttributes(array $attributes, Doctrine_Configurable $object = null)
{
if($object === null)
{
$object = $this->getManager();
}
foreach($attributes as $name => $value)
{
$object->setAttribute(
$this->doctrineConstant($name, 'attr'),
$this->doctrineConstant($value)
);
}
return $this;
}
public function setModules(array $modules)
{
//$this->_modules = $modules;
foreach($modules as $name => $bootstrap)
{
$this->_modules[$name] = $this->_configureModuleOptions($bootstrap);
}
return $this;
}
public function setDirectoryNames(array $directoryNames)
{
$this->_directoryNames = $directoryNames;
return $this;
}
public function getDirectoryNames()
{
return $this->_directoryNames;
}
public function getDirectoryName($key)
{
if(isset($this->_directoryNames[$key]))
{
return $this->_directoryNames[$key];
}
return null;
}
public function getModuleOptions($module = null)
{
if($module === null)
{
return $this->_modules;
}
if(isset($this->_modules[$module]))
{
return $this->_modules[$module];
}
return null;
}
public function doctrineConstant($value, $prefix = '')
{
if($prefix !== '')
{
$prefix .= '_';
}
$const = $this->_getConstantInflector()->filter(array(
'prefix'=>$prefix,
'key' => $value
));
$const = constant($const);
return $const !== null ? $const : $value;
}
/**
* getManager
* #return Doctrine_Manager
*/
public function getManager()
{
if(!$this->_manager)
{
$this->_manager = Doctrine_Manager::getInstance();
}
return $this->_manager;
}
protected function _getConstantInflector()
{
if(!isset($this->_inflectors['constant']))
{
$callback = new Zend_Filter_Callback(array('callback'=>'ucfirst'));
$this->_inflectors['constant'] = new Zend_Filter_Inflector(
'Doctrine_Core::#prefix#key',
array(
':prefix' => array($callback, 'Word_CamelCaseToUnderscore', 'StringToUpper'),
':key' => array('Word_SeparatorToCamelCase', 'Word_CamelCaseToUnderscore', 'StringToUpper')
), null, '#');
}
return $this->_inflectors['constant'];
}
protected function _configureModuleOptions(Zend_Application_Bootstrap_BootstrapAbstract $bootstrap)
{
$coreBootstrapClass = get_class($this->getBootstrap());
if(get_class($bootstrap) === $coreBootstrapClass)
{
// handled differently
$resourceLoader = $bootstrap->bootstrap('DefaultAutoloader')->getResource('DefaultAutoloader');
$moduleName = $resourceLoader->getNamespace();
}
else
{
// handle a module bootstrap
$resourceLoader = $bootstrap->getResourceLoader();
$moduleName = $bootstrap->getModuleName();
}
$resourceTypes = $resourceLoader->getResourceTypes();
$modelResource = isset($resourceTypes['model'])
? $resourceTypes['model']
: array('path'=>'models', 'namespace'=>'Model');
$modulePath = $resourceLoader->getBasePath();
$classPrefix = $modelResource['namespace'];
$modelsPath = $modelResource['path'];
$doctrineOptions = array(
'generateBaseClasses'=>TRUE,
'generateTableClasses'=>TRUE,
'baseClassPrefix'=>'Base_',
'baseClassesDirectory'=> NULL,
'baseTableClassName'=>'Doctrine_Table',
'generateAccessors' => true,
'classPrefix'=>"{$classPrefix}_",
'classPrefixFiles'=>FALSE,
'pearStyle'=>TRUE,
'suffix'=>'.php',
'phpDocPackage'=> $moduleName,
'phpDocSubpackage'=>'Models',
);
$doctrineConfig = array(
'data_fixtures_path' => "$modulePath/{$this->getDirectoryName('fixtures')}",
'models_path' => "$modelsPath",
'migrations_path' => "$modulePath/{$this->getDirectoryName('migrations')}",
'yaml_schema_path' => "$modulePath/{$this->getDirectoryName('yaml')}",
'sql_path' => "$modulePath/{$this->getDirectoryName('sql')}",
'generate_models_options' => $doctrineOptions
);
return $doctrineConfig;
}
protected function _loadModels()
{
$moduleOptions = $this->getModuleOptions();
foreach($moduleOptions as $module => $options)
{
Doctrine_Core::loadModels(
$options['models_path'],
Doctrine_Core::MODEL_LOADING_PEAR,
$options['generate_models_options']['classPrefix']
);
}
return $this;
}
}
Modules Resource
<?php
class APP_Application_Resource_Modules extends Zend_Application_Resource_Modules
{
protected $_prefixModuleNames = false;
protected $_moduleNamePrefix = null;
protected $_defaultModulePrefix = 'Mod';
protected $_configFileName = 'module.xml';
protected $_enabledModules = null;
public function __construct($options = null)
{
if(isset($options['prefixModuleName']))
{
if(($prefix = APP_Toolkit::literalize($options['prefixModuleName']))
!== false)
{
$this->_prefixModuleNames = true;
$this->_moduleNamePrefix = is_string($prefix)
? $prefix
: $this->_defaultModulePrefix;
}
}
if(isset($options['configFileName']))
{
$this->_configFileName = $options['configFileName'];
}
parent::__construct($options);
}
protected function _mergeModuleConfigs(array $applicationConfig)
{
$cacheManager = $this->_getCacheManager();
if(isset($applicationConfig['resources']['modules']['enabledModules']))
{
$applicationModulesOptions = &$applicationConfig['resources']['modules'];
$enabledModules = &$applicationModulesOptions['enabledModules'];
$front = $this->getBootstrap()->getResource('frontcontroller');
foreach($enabledModules as $moduleName => $moduleOptions)
{
// cache testing
// note cache keys for modules are prefixed if prefix is enabled #see _formatModuleName
if(!$cacheManager->test('config', $this->_formatModuleName($moduleName)))
{
$configPath = $front->getModuleDirectory($moduleName).'/configs/'.$this->getConfigFilename();
if(file_exists($configPath))
{
if(strpos($configPath, ".xml") === false)
{
throw new Exception(__CLASS__." is only compatible with XML configuration files.");
}
$config = new Zend_Config_Xml($configPath);
$enabledModules[$moduleName] = array_merge((array) $moduleOptions, $config->toArray());
//$this->setOptions($options);
$cacheManager->save('config', $enabledModules[$moduleName], $this->_formatModuleName($moduleName));
}
}
else
{
$options = $cacheManager->load('config', $this->_formatModuleName($moduleName));
$enabledModules[$moduleName] = array_merge((array) $enabledModules[$moduleName], $options);
}
}
}
return $applicationConfig;
}
public function init()
{
/**
* #var Zend_Application_Bootstrap_BoostrapAbstract
*/
$bootstrap = $this->getBootstrap();
if(!$bootstrap->hasResource('frontController'))
{
$bootstrap->bootstrap('frontController');
}
$front = $bootstrap->getResource('frontController');
$applicationConfig = $this->_mergeModuleConfigs($bootstrap->getOptions());
$bootstrap->setOptions($applicationConfig);
parent::init();
return $this->_bootstraps;
}
/**
* Format a module name to the module class prefix
*
* #param string $name
* #return string
*/
protected function _formatModuleName($name)
{
$name = strtolower($name);
$name = str_replace(array('-', '.'), ' ', $name);
$name = ucwords($name);
$name = str_replace(' ', '', $name);
$options = $this->getOptions();
if($this->prefixEnabled())
{
$name = $this->getModuleNamePrefix().$name;
}
return $name;
}
protected function _getCacheManager()
{
$bootstrap = $this->getBootstrap();
if(!$bootstrap->hasResource('cacheManager'))
{
$bootstrap->bootstrap('cacheManager');
}
return $bootstrap->getResource('cacheManager');
}
public function prefixEnabled()
{
return $this->_prefixModuleNames;
}
public function getModuleNamePrefix()
{
return $this->_moduleNamePrefix;
}
public function getConfigFilename()
{
return $this->_configFileName;
}
public function setEnabledModules($modules)
{
$this->_enabledModules = (array) $modules;
}
public function getEnabledModules($controllerDirectories = null)
{
if($controllerDirectories instanceof Zend_Controller_Front)
{
$controllerDirectories = $controllerDirectories->getControllerDirectory();
}
if(is_array($controllerDirectories))
{
$options = $this->getOptions();
$enabledModules = isset($options['enabledModules'])
? (array) $options['enabledModules']
: array();
$this->_enabledModules = array_intersect_key($controllerDirectories, $enabledModules);
}
elseif(null !== $controllerDirectories)
{
throw new InvalidArgumentException('Argument must be an instance of
Zend_Controller_Front or an array mathing the format of the
return value of Zend_Controller_Front::getControllerDirectory().'
);
}
return $this->_enabledModules;
}
public function setPrefixModuleName($value)
{
$this->_prefixModuleNames = APP_Toolkit::literalize($value);
}
}
Module Bootstrap Base Class
<?php
class APP_Application_Module_Bootstrap extends Zend_Application_Module_Bootstrap
{
public function _initResourceLoader()
{
$loader = $this->getResourceLoader();
$loader->addResourceType('actionhelper', 'helpers', 'Action_Helper');
}
}
Maybe this section of the e-book "Survive the Deep End" might help you : 6.6. Step 5: Fixing ZFExt_Bootstrap -- it specifically speaks about the error you are getting.
(I won't quote as there is quite a couple of long paragraphs, but, hopefully, this'll help)