How to disable some Zend View Helpers - zend-framework

I'm trying to make a way to disable some view helpers that are inside "application/views/helpers"...
What I really want is to put some options on the application.ini to enable or disable some Helpers.
Example on application.ini:
helpers.Helper1=on
helpers.Helper2=off
Now the problem is that when a Helper is off, I want to rewrite some functions of this helper in order to return a different result on the view. In this way, I don't need to change anything in the view script.
I thought in having 2 different php files for each helper, in different locations. One with the real helper and another with the changed helper (to work when it is off on the application.ini).
The problem is that I don't know how to tell the view which one it shoul load...
Does anyone know how it could be done?
FINAL CODE
Ok, after many tries, I put it to work with the following code:
Bootstrap
protected function _initConfigureHelpers(){
$this->bootstrap('view');
$view = $this->getResource('view');
$view->addHelperPath("./../library/ConfigHelpers","Configurable_Helper");
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer'
);
$viewRenderer->setView($view);
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Application_Plugin_ViewPlugins());
return $view;
}
Application_Plugin_ViewPlugins
class Application_Plugin_ViewPlugins extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request){
$front=Zend_Controller_Front::getInstance();
$bootstrap=$front->getParam('bootstrap');
$options=$bootstrap->getOption("helpers");
if (is_array($options)){
$view = $bootstrap->getResource('view');
foreach($options as $option => $value){
$helper=$view->getHelper($option);
if ($helper){
if ($value=="off")
$helper->__disable();
else if ($value!="on")
throw new Exception('The value of helpers.'.$option.' must be "on" or "off" on application.ini.');
} else {
throw new Exception("Inexistent Helper");
}
}
}
}
}
Modified helper example
require_once APPLICATION_HELPERS."CssCrush.php";
class Configurable_Helper_CssCrush extends Zend_View_Helper_CssCrush {
protected $__config_enabled = true;
public function __disable(){
$this->__config_enabled = false;
return $this;
}
public function __enable(){
$this->__config_enabled = true;
return $this;
}
public function cssCrush(){
if ($this->__config_enabled){
return parent::cssCrush();
} else{
return new Modified_CssCrush();
}
}
}
class Modified_CssCrush {
public static function file ( $file, $options = null ) {
return $file;
}
}
APPLICATION_HELPERS is defined on /public/index.php as "../application/views/helpers/".
Now, when I want to add a configurable helper, I put the original helper on "/application/views/helpers/" and then, create a modified version of it on "/library/ConfigHelpers" with the structure of the example above.

What I think you want is Dependency Injection which is coming in zf2, but not available in zf1.
With some tinkering though you can get what you need.
Configuring helpers in the bootstrap
(assumes default project structure)
View helpers paths config : application/configs/application.ini:
resources.view.helperPath.Zf_View_Helper_ = "Zf/View/Helper"
A simple configurable helper, (allows disable/enable but you can obviously add any methods you need (use this as base class for helpers that need the behaviour)
class Zf_View_Helper_Configurable extends Zend_View_Helper_Abstract
{
protected $isEnabled = true;
public function configurable()
{
return $this;
}
public function disable()
{
$this->isEnabled = false;
return $this;
}
public function enable()
{
$this->isEnabled = true;
return $this;
}
public function __toString()
{
if ($this->isEnabled) {
return 'Configurable is enabled';
} else {
return 'Configurable is disabled';
}
}
}
And configure the helpers in the bootstrap:
public function _initConfigureHelpers()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$configurableHelper = $view->configurable();
$configurableHelper->disable();
}
You can add options in the .ini file and grab them in the bootstrap initConfigureHelpers() method.
If you want this behaviour from any default zf helper, do what #Ratzo said and extend those helpers and add the required behaviour and then configure them in your bootstrap.

Please take a look at the following link Zend_View link
Below is an important points you should consider from the Zend docs.
Note: Default Helper Path
The default helper path always points to the Zend Framework view
helpers, i.e., 'Zend/View/Helper/'. Even if you call setHelperPath()
to overwrite the existing paths, this path will be set to ensure the
default helpers work.
This means that you can't really turn off the helpers, unless you want to go about extending the Zend_View object and overwrite the setHelperPath method. This is not the way to go though.
Here is probably what you want to do. First though, here is my assumption.
Assumption : You want to write your own view helper that slightly alters what the current view helpers do by changing a few methods here or there.
Here is what you should do to accomplish that.
First, write your view helper. Make sure the last part of the class name is the same as the view helper you want to 'overwrite'. You don't have to, but this makes sure the original helper can't be used anymore.
class My_View_Helper_BaseUrl extends Zend_View_Helper_BaseUrl
{
private $_enabled = true;
public function setEnabled( $bool ){ $this->_enabled = (boolean) $bool; }
public function baseUrl(){
if( $this->_enabled ){
return 'testUrl'; //other code
}
else return parent::baseUrl();
}
Now that you have that, do the following
$view->setHelperPath('/path/to/my/helpers', 'My_View_Helper'); //1
echo $view->baseUrl(); //2
Excellent. Now you've effectively shadowed the original BaseUrl helper.
The above code will make it so that the view scans your directory
for any helpers before scanning the default zend directory. When it gets to line
2 the view will find YOUR baseUrl helper first and use THAT instead of the
original baseUrl helper. In the above example it should echo
'testurl' instead of the normal baseUrl behavior.

You can make a custom helper that extends the original helper, for example
class My_Helper_Url extends Zend_View_Helper_Url
{}
and rewrite the methods as you need.

Related

Zend: Action helper not found

I am trying to create a helper of my own. The Safecheck folder is located in the library folder and contains a Helper folder. The class is called Safecheck_Helper_Authority.php (inside library/Safecheck/Helper).
In Bootstrap.php:
protected function _initHelper()
{
Zend_Controller_Action_HelperBroker::addPrefix('Safecheck_Helper');
}
In Safecheck_Helper_Authority.php:
class Safecheck_Helper_Authority extends Zend_Controller_Action_Helper_Abstract
{
public function hasAuthority($userId, array $ids)
{
}
}
I want to user the functions inside this class. But I get the error "Message: Action Helper by name Authority not found", triggered by the following code:
$this->_helper->authority('hasAuthority');
Maybe I am not calling it with the right code? Am I missing something?
in order to call an action helper in this manner $this->_helper->authority('hasAuthority'); you need to define the direct() method in your helper.
class Safecheck_Helper_Authority extends Zend_Controller_Action_Helper_Abstract
{
public function direct($userId, array $ids)
{
// do helper stuff here
}
}
an easy way to register the helper path and prefix is to use the application.ini:
resources.frontController.actionhelperpaths.Safecheck_Helper = APPLICATION_PATH "/../library/Safecheck/Helper"
to do it in bootstrap (not sure if addPrefix() works with library namespaces):
protected function _initHelper()
{
//addPath(path_to_helper, helper_prefix)
Zend_Controller_Action_HelperBroker::addPath('/../library/Safecheck/Helper', 'Safecheck_Helper');
}
a Simple example of an action helper:
class Controller_Action_Helper_Login extends Zend_Controller_Action_Helper_Abstract
{
//prepares a login form for display
public function direct()
{
$form = new Application_Form_Login();
$form->setAction('/index/login');
return $form;
}
}
Have in your application.ini something similar to
resources.frontController.actionhelperpaths.Application_Action_Helper = APPLICATION_PATH "/../classes/Application/Action/Helper"
The path should be changed to reflect your file path.

User defined functions in zend

Where do i place the user defined functions in zend framework. These functions will used across the framework in many controls, views or models. Do i need to convert this to a utility class? Or i can just keep it as a set of functions and include it in index.php.
what is the best practice for this?
Typically you would put your functions into a class in the library for the auto loader. Use the naming conventions for ZF to make life easier.
adjust your application.ini to add a namespace.
Examples:
//application.ini
autoloaderNamespaces[] = "My_"
//this would equate to the folder My in the folder library
/application
/library
/My
//any class you built would be named My_Classname and be called in your app by Classname()
<?php
class My_Classname {
public function myFunction() {
}
}
//in your conrtoller for example you might call
public function indexAction() {
$class = new My_Classname();
$class->myFunction();
//or if you declared myFunction() static...
$class = My_Classname::myFunction();
}
Make it by following ZF directory structure:
Make Action Helpers for Controllers and View Helpers for Views :
In your library folder which is set in set_include_path:
create library/My/View/Helper/Common.php
Like below:
class My_View_Helper_Common extends Zend_View_Helper_Abstract
{
public function common()
{
return $this;
}
public function getCity($id)
{
$registry = Zend_Registry::getInstance();
$DB = $registry['DB'];
$result = $DB->fetchPairs("select * from firm_dtl");
return $result;
}
}
OR Call in View:
$this->common()->getCity($id);
Same process fro action helpers:
Make in library/My/Action/Helper/Common.php

Zend accessing user data in all controllers

Searched and searched for some guidance but cant seem to get anything to work. I wont to access the user data in any index controller to save repetetive code. I have created a ACTION HELPER which calls the Session and returns the users data. Below is how I implemented it all. Calling the helper works but I cant get the data out in any controller.
Application.ini
autoloaderNamespaces[] = "ZC"
Bootstrap.php
protected function _initActionHelpers()
{
Zend_controller_Action_HelperBroker::addHelper(new ZC_Action_Helpers_User());
}
User.php
<?php
Class ZC_Action_Helpers_User extends Zend_Controller_Action_Helper_Abstract
{
public function direct()
{
$storage = new Zend_Auth_Storage_Session();
$data = $storage->read();
$this->_user = $data;
}
}
IndexController.php
<?php
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
$this->_helper->user;
}
I have no problems with the code but say for example how would I get the USERNAME or USERID from the helper???
Thanks for taking the time in looking at this.
J
First, your plugin function have to return the user information and not set it as a class variable:
Class ZC_Action_Helpers_User extends Zend_Controller_Action_Helper_Abstract
{
public function direct()
{
$storage = new Zend_Auth_Storage_Session();
$data = $storage->read();
return $data;
}
}
Then you can use the plugin in any controller you need:
$user = $this->_helper->User->Direct()
You might want to rename some of these functions and classes.
Try to declared in bootstrap path to helpers...
Zend_Controller_Action_HelperBroker::addPath(
APPLICATION_PATH .'/controllers/helpers');
Next use google for this simply question.... howto use helper in ZF

Zend Framework: How to inject a controller property from a Zend_Controller_Plugin

I wrote a plugin that needs to set a property on the controller that's currently being dispatched. For example, if my plugin is:
class Application_Plugin_Foo extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
// Get an instance of the current controller and inject the $foo property
// ???->foo = 'foo';
}
}
I want to be able to do this:
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
$this->view->foo = $this->foo;
}
}
}
Any help is greatly appreciated!
The action controller is not directly accessible directly from a front-controller plugin. It's the dispatcher that instantiates the controller object and he doesn't appear to save it anywhere accessible.
However, the controller is accessible from any registered action helpers. Since action helpers have a preDispatch hook, you could do your injection there.
So, in library/My/Controller/Helper/Inject.php:
class My_Controller_Helper_Inject extends Zend_Controller_Action_Helper_Abstract
{
public function preDispatch()
{
$controller = $this->getActionController();
$controller->myParamName = 'My param value';
}
}
Then register an instance of the helper in application/Bootstrap.php:
protected function _initControllerInject()
{
Zend_Controller_Action_HelperBroker::addHelper(
new My_Controller_Helper_Inject()
);
}
And, as always, be sure to include My_ as an autoloader namespace in configs/application.ini:
autoloaderNamespaces[] = "My_"
Then, in the controller, access the value directly as a public member variable:
public function myAction()
{
var_dump($this->myParamName);
}
One thing to note: Since the helper uses the preDispatch() hook, I believe it will get called on every action, even an internal forward().
Browsing through the API, I didn't find a way to reach the controller directly (I'm guessing this loop is performed before the controller exists). What I could find is almost as easy to access, albeit with a bit different syntax.
Via request params
class Application_Plugin_Foo extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
$yourParam = 'your value';
if($request->getParam('yourParam')) {
// decide if you want to overwrite it, the following assumes that you do not care
$request->setParam('yourParam', $yourParam);
}
}
}
And in a Zend_Controller_Action::xxxAction():
$this->getParam('yourParam');
Via Zend_Controller_Action_Helper_Abstract
There's another way mentioned in MWOP's blog, but it takes the form of an action helper instead: A Simple Resource Injector for ZF Action Controllers. His example would let you access any variable in Zend_Controller_Action as $this->yourParam.

Probable reasons why autoloading wont work in Zend Framework 1.10.2?

Iam writing an application using Zend Framework 1.10.2.
I created few model classes and a controller to process them.
When Iam executing my application and accessing the admin controller. Iam seeing this error.
Fatal error: Class 'Application_Model_DbTable_Users' not found in C:\xampp\htdocs\bidpopo\application\controllers\AdminController.php on line 16
The error clearly shows its an autoloading error.
Hence I wrote this code in the bootstrap file.
protected function initAutoload()
{
$modeLoader = new Zend_Application_Module_AutoLoader(array
('namespace'=>'','basePath'=>APPLICATION_PATH ));
//echo(APPLICATION_PATH);
return $modeLoader;
}
Still the error remains :( . Can anyone suggest me what Iam missing out here?
This is the location of the Model Users class.
C:\xampp\htdocs\bidpopo\application\models\DbTable\Users.php
This is its code.
class Application_Model_DbTable_Users extends Zend_Db_Table_Abstract
{
//put your code here
protected $_name='users';
public function getUser($id)
{
$id = (int)$id;
$row = $this->fetchrow('id='.$id);
if(!$row)
{throw new Exception("Could not find row id - $id");}
return $row->toArray();
}
public function addUser($userDetailArray)
{
$this->insert($userDetailsArray);
}
public function updateUser($id,$userDetailArray)
{
$this->update($userDetailArray,'id='.(int)$id);
}
public function deleteUser($id)
{
$this->delete('id='. (int)$id);
}
}
This is the Admin Controller's code
class AdminController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
$this->view->title= "All Users";
$this->view->headTitle($this->view->title);
$users = new Application_Model_DbTable_Users();
$this->view->users = $users->fetchAll();
}
public function addUserAction()
{
// action body
}
public function editUserAction()
{
// action body
}
public function deleteUserAction()
{
// action body
}
You application classes don't follow the proper naming convention for the namespace you've set. The Zend_Application_Module_AutoLoader is a little different than the normal autoloader in that it doesn't simply change the '_' in the class name with '/'. It looks at the second part of the class name and then checks a folder for the existence of the class based on that.
You need to change the line:
$modeLoader = new Zend_Application_Module_AutoLoader(array(
'namespace'=>'Application',
'basePath'=>APPLICATION_PATH
));
This means it will autoload all module classes prefixed with 'Application_'. When it the second part of the class is 'Model_' it will look in "{$basePath}/models" for the class. The '_' in the rest of the class name will be replaced with '/'. So the file path of the file will be "{$basePath}/models/DbTable/Users.php".
Read more here.