yii. Accessing a function from a modules controller

11,092

Solution 1

Assuming that the model that you are querying is within your module, there are 3 workarounds.

One

What you can do is define your renderPageLinks() function in the QuickDialModule.php file, i.e inside the QuickDialModule class. Then you can use it like this:

Yii::app()->getModule('QuickDial')->renderPageLinks();

You have to write this function inside your QuickDialModule class :

Class QuickDialModule extends CWebModule{
   public function init(){
     // ... code ...
   }
   // ... code ... other functions

   public function renderPageLinks(){
       // ... do whatever you were doing inside the function ...
   }
}

Edit:
Controllers are instantiated by yii only when the application receives url requests from the user.

Two

You have another work around by declaring your function static. But then you'll have to import the php file that has the class that has the function, into the yii autoloading array in the main.php config file. So change your defaultcontroller renderPageLinks() function to static:

public static function renderPageLinks(){
   // do whatever you were doing
}

Autoload the controller, by modifying main configuration main.php inside protected/config/ folder:

// autoloading model and component classes
'import'=>array(
    'application.models.*',
    'application.components.*',
    'application.modules.quickdial.controllers.*' // this line is added
),

Then call your static function directly:

$this->widget('pageLinkGen', array('pages' => DefaultController::renderPageLinks()));

Of course for this static method to work, you must have only one module with controller DefaultController, or you must not import other modules' controllers, in any case name conflicts could arise.

Three

If you move the function into a controller in the main module(i.e pageLinkGen controller that you have mentioned), then you'll have to import the model that you need into the main module's config main.php(so that yii can find it), to autoloading import array add :

  // autoloading model and component classes
'import'=>array(
    'application.models.*',
    'application.components.*',
    'application.modules.quickdial.models.*' // this line is added
),

so that your controller can find the model.

Solution 2

If the controller has the renderPageLinks function, and assuming $this is a reference to the correct controller, try calling the function by referencing the controller directly:

$this->widget('pageLinkGen', array('pages' => $this->renderPageLinks()));

As far as I know PHP does not support implicit $this

Share:
11,092
Tom T
Author by

Tom T

Updated on August 19, 2022

Comments

  • Tom T
    Tom T over 1 year

    I have a module in my app and under its default controller it has a function called renderPageLinks which returns a array for consumption by a widget.

    The widget, genMenu, is called from /themes/jui/views/layouts/main.php (it generates a menu) I need to pass the data from the renderPageLinks to the widget as a value:

    $this->widget('pageLinkGen', array('pages' => renderPageLinks()));
    

    The problem is Yii cant find the function renderPage Links.

    i tried diffrent combinations of the following with to avail..

    $this->widget('pageLinkGen', array('pages' => 'application.module.QuickDial.default.renderPageLinks()'));
    

    Any suggestions?

    p.s. I have tried to move renderPageLinks() to the controller pageLinkGen but Yii can't find the model used in renderPageLinks().

    • Tom T
      Tom T about 12 years
      on a suggestion by another site i tried $this->widget('pageLinkGen', array('pages' => Yii::app()->getModule('QuickDial')->renderPageLinks())); with out any results. I received the following error: QuickDialModule and its behaviors do not have a method or closure named "renderPageLinks".
    • bool.dev
      bool.dev about 12 years
      for that suggestion to work you'll have to declare the function in the proper place, see my answer, i have explained three methods that i could think of. two of those you have already explored, but not correctly.
  • Tom T
    Tom T about 12 years
    Thanks for the suggestion but this doesn't work. The issue is the view im calling the widget from is in /theme/bootstrap/layouts/main.php, the controller is in protected/modules/QuickDial/controllers/.. I think the solution to this is i need to use a portlet.
  • bool.dev
    bool.dev about 12 years
    let me know if you require any clarifications
  • Tom T
    Tom T about 12 years
    thanks for the help @bool.dev. The problem was the model and the function where both in the same module but they where trying to be called outside of that model by the layout. At least i think this was the issue. I moved the models to /protected/model and created a portlet in the /protected/components
  • bool.dev
    bool.dev about 12 years
    no, that shouldn't be a problem, you were calling the function in the wrong way, and function was not in proper place. i tested it in a layout, and it works. anyway, if you have done something else, which suits you, thats ok. but for the question in the current form, my answer should work, imho. model and function can be in the same module, see how i have imported the model/controller in the answer to allow visibility of the classes.