Zend Framework call view helper from a Zend_View_Helper
Asked Answered
E

4

8

I have a helper called Zend_View_Helper_FormVars that's used by one of my modules. I also have a common helper in application/common/helpers/GeneralFunctions.php

I'm trying to call a function from Zend_View_Helper_FormVars that's in GeneralFunctions.php.

Here is the short version of Zend_View_Helper_FormVars:

class Zend_View_Helper_FormVars
{
    public $reqFieldVisual='<span class="req">*</span>';
    public $roles=array('admin'=>'admin', 'user'=>'user');
    public $paymentMethods=array('1'=>'Check', '2'=>'Credit Card',
                '3'=>'Cash', '4'=>'Other');


    public function formVars(){
        $this->baseUrl=Zend_Controller_Front::getInstance()->getBaseUrl();
        return $this;
    }

    public function mkCategoryCodeSelectGroup($codeTypeArr=array(),
        $codesArr=array()) {
        $html='';
        $html.=Zend_View_Helper_GeneralFunctions::generalFunctions()->progressMeter();
        return $html;
    }
}

Here is the code in GeneralFunctions.php:

class Zend_View_Helper_GeneralFunctions
{
    public function generalFunctions(){
        $this->baseUrl=Zend_Controller_Front::getInstance()->getBaseUrl();
        return $this;   
    }

    public function progressMeter() {
        $html='';
        $html.='<span id="progressWrapper">';
        $html.='<span id="progressMeter"></span>';
        $html.='</span>';
        $html.='';
        return $html;
    }
}

Also, forgot to mention that I have the GeneralFunctions helper auto loaded in the Bootstrap like this and it's available to all my modules already:

$view->addHelperPath(APPLICATION_PATH .'/common/helpers', 'View_Helper');

Here is what I tried, but am getting an error:

// application/Bootstrap.php ----------->
function _initViewHelpers() {
    // add a helper for use for all modules
    $view->addHelperPath(APPLICATION_PATH .'/Common/Helper', 'Common_Helper');
}
//-------------------->


// application/common/helpers/General.php ----------->
class Zend_View_Helper_General extends Zend_View_Helper_Abstract
{
    public function general(){
        return $this;
    }   
    public function test(){
        return 'test 123';
    }
}
//-------------------->

// application/modules/dashboard/views/helpers/DashboardHelper.php ----------->
class Zend_View_Helper_DashboardHelper extends Common_Helper_General
{

    public function dashboardHelper(){
        return $this;
    }

    public function dashboardTest(){
        return 'from dashboard';
    }

}
//-------------------->

// application/modules/dashboard/views/scripts/index/index.phtml ----------->
echo $this->dashboardHelper()->test();
//-------------------->

Error message I get:

Fatal error: Class 'Common_Helper_General' not found in /Applications/MAMP/htdocs/mysite/application/modules/dashboard/views/helpers/DashboardHelper.php on line 2

Epifaniaepifano answered 25/11, 2009 at 22:23 Comment(1)
I would recommend namespacing View Helpers with your own prefix (not Zend!) and adding the helper path for this.Gordongordy
G
14

It's actually really simple to call another View Helper.

Make sure that your view helper extends Zend_View_Helper_Abstract, so that it has access to the $view. Then you may simply call helpers as you would from a view, i.e.

$this->view->generalFunctions()->progressMeter();

Based on your example above:

<?php

class Zend_View_Helper_FormVars extends Zend_View_Helper_Abstract {

    /* ... */

    public function mkCategoryCodeSelectGroup($codeTypeArr=array(),
        $codesArr=array()) {
        $html='';
        $html. $this->view->generalFunctions()->progressMeter();
        return $html;
    }
}
Gordongordy answered 27/11, 2009 at 18:10 Comment(2)
Thanks David. That worked also. There seems to be so many ways to do things with the Zend Framework. I like it, but it can be confusing at times.Epifaniaepifano
The trick here was to subclass Zend_View_Helper_Abstract, something that's difficult to spot in the manual. Once you have a view reference you'll realise that you can call functions as usual. Often in ZF there are multiple ways to retrieve object references. In this case you could technically retrieve the view from the ViewRendered or a registry. My example is neatest.Gordongordy
S
0

You possibly haven't configured your autoloader to load classes from the application/common/helpers/ folder.

See Zend_Application_Module_Autoloader for default paths. You should add your new folder to this.

Submission answered 26/11, 2009 at 2:15 Comment(0)
W
0

You are calling your class without instantiating it.

Your generalFunctions() function uses the $this pointer, which won't work; also it isn't a static method.

One option is set progress meter to be a static function and call it directly like this:

Zend_View_Helper_GeneralFunctions::progressMeter();

Another option is to instantiate your class first.

Wilheminawilhide answered 26/11, 2009 at 4:50 Comment(1)
I forgot to mention, that I have the GeneralFunctions helper auto loaded in the Bootstrap like this and it's available to all my modules already: $view->addHelperPath(APPLICATION_PATH .'/common/helpers', 'View_Helper'); Hi Jai, I made it work like you said by instantiating it first like this: $genFun=new Zend_View_Helper_GeneralFunctions(); $html.=$genFun->progressMeter();Epifaniaepifano
T
0

I see several problems with your provided code.

  1. You are attempting to call Zend_View_Helper_GeneralFunctions::generalFunctions() as a static method when it is declared as a class method (ie you have to instantiate an instance of the class to use it) by reason of your omission of the static keyword.
  2. If you in fact want to use generalFunctions() as a static method and correct this then you will need to either make baseUrl a static property or you will have to instantiate an instance of the class and then return that instance.
  3. The idea of using your GeneralFunctions class as a container for static methods that are called directly is really a symptom of deeper problems and is rightly labeled a code smell. If you think that I'm lying take a look at the high priority items for the Zend Framework 2.0 (hint: it involves removing all static methods from the framework). Or you can always ask SO what they think of static methods :-).

Looking at your given class name for the general functions class Zend_View_Helper_GeneralFunctions and given the current scenario where you are trying to use the GeneralFunctions helper inside another helper, I would surmise that you really need to do one of two things.

  1. You need to have every helper class subclass the GeneralFunctions class so that all of your helpers have these functions available. Basically, ask yourself if your helpers all start out life as GeneralFunction helpers with extended functionality beyond. This solution uses inheritance to solve your problem.
  2. Every view helper should contain an instance of the View object being acted upon. Therefore in theory you should be able to access any other view helper via the magic __call method (I think there is also an explicit method but I always use the magic method). It might look like so in your scenario:

    public function mkCategoryCodeSelectGroup($codeTypeArr=array(), $codesArr=array()) 
    {
        $html='';
        $html.= $this->generalFunctions()->progressMeter();
        return $html;
    }
    

    In this scenario the __call method would load the GeneralFunctions helper and would then would call the progressMeter() method from the GeneralFunctions helper.

    Now your GeneralFunctions helper class would probably look like this:

    class Zend_View_Helper_GeneralFunctions
    {
        public function __construct()
        {
            $this->baseUrl = Zend_Controller_Front::getInstance()->getBaseUrl();
        }
    
        public function progressMeter() {
            $html='';
            $html.='<span id="progressWrapper">';
            $html.='<span id="progressMeter"></span>';
            $html.='</span>';
            $html.='';
            return $html;
        }
    }
    
Tripetalous answered 26/11, 2009 at 5:46 Comment(2)
But I'm interested in making my code better by what you said Noah. So, what you're saying is that I can extend all my view helpers like this: class Zend_View_Helper_FormVars extends Zend_View_Helper_GeneralFunctions And when I need a function from either of those classes in a view script for example, I would call $this->formVars()->someFunction(); And someFunction() can be in the FormVars class or the GeneralFunctions class ? thank youEpifaniaepifano
@Epifaniaepifano - You can extend the GeneralFunctions View Helper class with all of your View Helper classes like you're suggesting. Or, you can simply use the GeneralFunctions View Helper as a View Helper all on its own as I indicated in the sample code. Using this method, your other View Helpers still inherit the default Abstract class and then you call methods from the GeneralFunctions View Helper via the magic __call() method.Tripetalous

© 2022 - 2024 — McMap. All rights reserved.