Zend view helper not available in module - php

I've read many posts about how to register a custom view helper. This has not been my issue. I have custom view helpers working from my library; however, they seem to only be accessible from the "default" module (i.e. outside of a module). When attempting to call the helper from within a module, I get the following error:
Message: Plugin by name 'IsCurrent' was not found in the registry; used paths: Zend_View_Helper_: Zend/View/Helper/:/Users/firemanrob/Development/Projects/mysite.com/www/application/modules/admin/views/helpers/
As stated above, when I make this call from the outside of a module, it works fine...
if ($this->isCurrent(...
But this same line, in a view script, in a module produces the error.
My helper class is in a file called
library/Sc/View/Helper/IsCurrent.php
The class is defined and function declared as such:
class Sc_View_Helper_IsCurrent extends Zend_View_Helper_Abstract {
public function isCurrent($startTime, $endTime) {
My Bootstrap.php file (among other things) contains this:
function _initViewHelpers() {
$this->bootstrap('layout');
$layout = $this->getResource('layout');
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->setViewSuffix('php');
unset($viewRenderer);
/* #var $view Zend_View */
$view = $layout->getView();
$options = Zend_Registry::get('options');
if (Zend_Registry::isRegistered('db')) {
$this->_db = Zend_Registry::get('db');
} else {
$db = $this->getPluginResource('db');
$this->_db = Zend_Db::factory($db->getAdapter(), $db->getParams());
Zend_Registry::set('db', $this->_db);
}
$view->doctype('HTML5');
$view->headMeta()->appendHttpEquiv('Content-Type', 'text/html;charset=utf-8');
$view->headTitle($options->template->websiteBaseTitle);
$view->headTitle()->setSeparator(' | ');
$view->addHelperPath("Sc/View/Helper", "Sc_View_Helper");
}
The only thing my application.ini file contains, pertaining to modules or view helpers is:
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0
; setup modules
resources.modules[] =
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
;content settings
content.path = "../application/content"
;layout settings
resources.layout.layoutpath = APPLICATION_PATH "/layouts"
resources.layout.viewSuffix = php
resources.layout.layout = "default"
autoloadernamespaces[] = Amg
autoloadernamespaces[] = Sc
autoloadernamespaces[] = Phpmailer
I've tried commenting out the resources.modules[] line, as I read something similar in another post. That just broke everything.
The particular module that I'm trying to call this from is called "admin" and in that module's folder is another Bootstrap.php file that contains only:
<?php
class Admin_Bootstrap extends Zend_Application_Module_Bootstrap
{
}
Any suggestions of how I can make this working view helper visible to my modules as well?

This is a bit of a long shot, but could you try commenting out the three view renderer lines you currently have and adding the following to the end of your _initViewHelpers() function instead:
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
$viewRenderer->setViewSuffix('php');
$stack = Zend_Controller_Action_HelperBroker::getStack();
$stack->push($viewRenderer);
This should ensure that the $view object you're configuring is the one that the view renderer uses. Your helper path isn't in the error that you're getting, which suggests this is coming from a different view object.
I don't have an explanation as to why it works in the default module but not the admin one. If it worked from within a layout, but not from a view script that might make a little more sense.

It looks like you're using a relative filepath for you view helpers - this could explain why it works when you're in the default module but not in others because in other modules you change the relative path to your view helper is different than when in a module. Try something like $view->addHelperPath("/ABSOLUTE/PATH/TO/library/Sc/View/Helper", "Sc_View_Helper");

Related

error in zend framework model creation

i am just started using zend framework. i created a project in zend
structure
application
configs
application.ini
layouts
modules
core
DB
Dbclass.php
Table
default
controllers
views
forms
bootstrap.php
library
public
index
my bootstrap file contain
public function _autoload(){
set_include_path(
'/application/modules/core/DB'
. PATH_SEPARATOR .
'/application/modules/core/Table'
. PATH_SEPARATOR .
get_include_path());
}
public function _init(){
$front = Zend_Controller_Front::getInstance();
$front->setControllerDirectory(array(
'default' => APPLICATION_PATH.'/modules/default/controllers'
));
}
my application.ini file contain
[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
phpSettings.date.timezone = "Europe/London"
;includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = "Application"
;resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.moduleControllerDirectory = APPLICATION_PATH "/modules/controllers"
resources.frontController.defaultModule = "default"
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.params.displayExceptions = 0
when i create a object in indexcontroller
$new_object = new Dbclass();
there is an error showing that
Fatal error: Class 'Dbclass' not found in D:\xampp\htdocs\pubman\application\modules\default\controllers\IndexController.php on line 16
if any one know this please help me.
thanks in advance.
Several comments/observations:
You method Bootstrap::_autoload() will not run. Bootstrap will automatically run all methods of the form _initXXX().
Typically, you would not put the models in modules/core/DB/*. You would put them in modules/core/models/* The default resource autoloader knows to look for them there.
You are specifying the appnamespace Application_. That means that all the classes inside directories like application/models, application/services, application/forms, etc would be named in the form Application_Model_Something, not just Something as you have. But since you have placed these classes inside the core module, they would be named something like Core_Model_Something.
If you want to use modules, then you should have a resources.modules[] = declaration in your application/configs/application.ini
You would typically have a Bootstrap class for each module - named, for exmaple, Core_Bootstrap - extending Zend_Application_Module_Bootstrap. This will ensure the standard resource autoloader for the module gets invoked.
This should get you closer. Frankly, there are a lot of things going on there, so this is unlikely to be a complete list. The essential part is to understand what the system would need to know in order to load a class that is not on the include_path (like models, forms, etc): a namespace prefix, a base path at which it needs to start performing its PSR-0 construction.

Zend - db table not found in another module

I have an application with three modules:default, disciplines and plans. In disciplines I have a dbtable which works fine in this module, but if I want to use the dbtable in module plans inside plans_dbtable I get
Class 'Disciplines_Model_DbTable_Disciplines' not found in C:\xampp\htdocs\proiect_mps\application\modules\plans\models\DbTable\Plans.php on line 43.
Require_once and include don't solve the problem. I have Disciplines_Boostrap and Plans_Bootstrap classes written. But it doesn't work. Any ideas?
class Plans_Model_DbTable_Plans extends Zend_Db_Table_Abstract
{
...
public function addPlan(
$year,
$name,
$code,
$domain,
$specialization,
$years)
{
// Id-ul disciplinei
$id_discipline = 0;
$discipline = new Disciplines_Model_DbTable_Disciplines();
....
}
...
}
Since you're using Zend I would not suggest your answer of having a require_once to be the best Basically if you have your configuration nice you dont need to have require_once any place. This might be of a help :
In file application.ini
;Module Configuration
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.moduleControllerDirectoryName = "controllers"
; Enables Modules bootstrap resource plugin, so each module directory has a bootstrap.php file
resources.modules = 1
and in you BootStrap.php file
protected function _initFrontController() {
// The Zend_Front_Controller class implements the Singleton pattern
$frontController = Zend_Controller_Front::getInstance();
// look in the modules directory and automatically make modules out of all folders found
$frontController->addModuleDirectory(APPLICATION_PATH . '/modules');
// forces the front controller to forward all errors to the default error controller (may already be false by default)
$frontController->throwExceptions(false);
return $frontController;
}
And yes you will need to have Bootstrap.php for your every module
class Disciplines_Bootstrap extends Zend_Application_Module_Bootstrap
{
/**
* This file is ABSOLUTELY NECESSARY to get module autoloading to work.
* Otherwise calls to "$form = new Module_Form_MyForm()" will fail.
*/
}
I think I've resolved it myself. I had to write
require_once(APPLICATION_PATH.'/modules/disciplines/models/DbTable/Disciplines.php');
instead of
require_once '/proiect_mps/application/modules/disciplines/models/DbTable/Disciplines.php';
This also works:
require_once('/../../../disciplines/models/DbTable/Disciplines.php');
for my folder structure.

Zend Framework - Accessing custom configuration files

I created a custom XML configuration file called config.xml and placed it in the configs directory in the Zend Framework. I want to use it in one of my controllers using Zend_Config_Xml. What I have is not working, and it says "An error occurred. Application error". How do I read in a custom XML config file from a controller? This is what I have in my controller so far:
class IndexController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
// action body
$config = new Zend_Config_Xml('config.xml', 'staging');
echo $config->host;
}
}
Probably just the path you need to fix:
$config = new Zend_Config_Xml(APPLICATION_PATH.'/configs/config.xml', 'staging');
if not, check the error log to see what the actual error message is.
Edit: To do this in the bootstrap, the easiest (although perhaps not best) way is to add a new resource method and store the config object in the registry. Add this to your bootstrap class:
protected function _initCustomConfig()
{
$config = new Zend_Config_Xml('config.xml', 'staging');
Zend_Registry::set('config', $config);
return $config;
}
you can then access it later using:
$config = Zend_Registry::get('config');
If you're debugging the issue locally, first enable better error reporting by adding these commands in your application.ini's development section:
phpSettings.error_reporting = E_ALL
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
By default, zend framework doesn't show internal errors.
If you're loading a Zend_Config file, it's always better to load it using an absolute path.
public function indexAction()
{
// action body
$config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/config.xml', 'staging');
echo $config->host;
}

How to include custom folder in config in Zend Framework?

How to add include path to custom folder in application.ini in Zend Framework?
I need access to some classes from custom folder.
Thx for answers.
Kamilos
includePaths.customfolder = APPLICATION_PATH "/../customfolder"
structure your applications:
application
data
library
public
in application.ini
data_uploads = APPLICATION_PATH "/../data/uploads"
in Bootstrap.php
public function _initDefines()
{
define('DATA_UPLOADS', $this->getOption('data_uploads'));
}
now you can use DATA_UPLOADS define in your script php! ;)
UPDATE
add this to application.ini
autoloadernamespaces[] = "Foo_"
in you libray add directory Foo! In this directory add your classes.
the filename class will be Bar.php and class name will be Foo_Bar!

Autoloading forms and models for each module in Zend?

How can someone autoload every form and model for each module? Consider the following file structure:
application/
modules/
foo/
forms/
Register.php
models/
Account.php
Bootstrap.php
bar/
forms/
Publish.php
models/
Article.php
Bootstrap.php
Bootstrap.php
And for example, in foo/Bootstrap.php you have the following (non-functional) code:
class Foo_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initAutoLoad()
{
$loader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => APPLICATION_PATH . '/modules/foo',
'namespace' => 'Foo',
));
$loader->addResourceType('form', 'forms', 'Form')
->addResourceType('model', 'models', 'Model');
return $loader;
}
}
Basic question: How can the bootstrap be modified so that it does load every form and model from the Foo module?
Extra question: Is it possible to have a global autoloader that loads in forms and models from every module? If so, how?
Edit (most common questions about the issue):
The default Zend naming conventions are being used for classes. Such as Bar_Model_Article, Bar_Model_Mapper_Article, Bar_Model_DbTable_Article, Bar_Form_Publish, ... (And are being placed in their respective folder.)
It isn't just one module that doesn't get its classes loaded, it's all of them.
There is no problem autoloading classes using the Zend autoloader when using a plain no-module application with multiple models, mappers, dbtables and forms.
Fix
As #Tim Fountain mentioned the module bootstraps weren't being run, meaning none of the automatic loading occurred that's baked into Zend. Eventually, I found where the problem was in my case. I had to remove the following lines from my configuration:
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
Agreed, the global bootstrap won't work anymore; but it's a lot better than having module bootstraps not functioning. If anyone knows how to still have the global bootstrap, feel free to leave a comment. Hope this can be of help to others with a similar problem.
The module bootstrap class sets up the module autoloader automatically, so you can remove your example _initAutoload() function leaving just an empty class and it should all just work. See: http://framework.zend.com/manual/en/zend.loader.autoloader-resource.html#zend.loader.autoloader-resource.module
Edit: It sounds like your module bootstraps aren't being run. This is not an uncommon problem as the way it all fits together can be a bit confusing. The quickest way to verify this would be to just add an init method to one of them with an echo and an exit and see if it ever gets output.
Module bootstraps are pulled in and run by the 'modules' resource within Zend Application. You need to trigger this resource in some way because ZF won't go hunting around for module bootstraps just in case they are there. The most common way to do this is to include this line in your application.ini:
resources.modules[] = ""
alternatively you can manually setup the resource from your main Bootstrap file.
I also had it always like that. But since the release of 1.10 (wild guess), you can remove that bootstrap code and just put the following line in your application.ini:
appnamespace = "Foo"
I personally leave mine empty.

Categories