yii. Accessing a function from a modules controller
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
Tom T
Updated on August 19, 2022Comments
-
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 inrenderPageLinks()
.-
Tom T about 12 yearson 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 about 12 yearsfor 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 about 12 yearsThanks 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 about 12 yearslet me know if you require any clarifications
-
Tom T about 12 yearsthanks 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 about 12 yearsno, 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.