I would like to access an action defined in my widget via a controller. I would like to access the actionGetData() action in my WeekReport widget via the route r=controller/weekReport.getData
This is what I have in my controller:
public function actions() {
return array(
'weekReport.'=>'application.components.WeekReport'
);
}
And in my widget:
public $actionPrefix = 'action';
public static function actions() {
return array(
'getData'=>'WeekReport'
);
}
public function actionGetData() {
//...
}
But Yii throws this error:
Any help? I can not find any good examples to reference…
Not sure, how it’s supposed to be configured - but i think you should leave actionPrefix empty. Otherwhise you’d have to add it to your actionIDs in your route.
EDIT:
Sorry, Antonio, you actually pointed to the same direction. Didn’t read carefully enough.
public function actions() {
return array(
'weekReport.GetData'=>'application.components.WeekReport'
);
}
Now I just get a blank page. I tried setting the $actionPrefix to ‘’, ‘action’, ‘weekReport’, ‘weekReport.’. Still get blank page… I can tell that the widget is being loaded on the request to controller/weekReport.getData. It just does not execute the action
I know now how it works, here the steps my friend:
// create an action class
<?php
class getData extends CAction{
public function run(){
echo 'HELLO WORLD';
}
}
// in your widget:
<?php
class weekReport extends CWidget{
public $actionPrefix = 'test.';
// now is an action provider
public static function actions(){
return array(
'GetData'=>'application.components.actions.getData',
);
}
}
// in your controller
public function actions()
{
return array(
'test.'=>'application.components.weekReport',
);
}
// to call it
index.php?r=site/test.GetData
I really enjoyed this post… I think i will write a wiki about it…
I tried that before creating external CAction files but no luck. As you said, it could be a nice feature to enhance future releases (you are part of the team) with encapsulated actions instead of just external ones.
I created a ticket for this. I am actually not on the dev team anymore… Since I started studying at UC Berkeley as an Electrical Engineering & Computer Sciences major I have not had much time anymore to devote to Yii. IDK why I am still a forum mod…
I found another way to do it by using the run method and checking the actual request. I know it is not what is supposed to be done but… actions are called using the run() method of the component, so you can create a workaround on your widget.
public static function actions(){
return array(
'test'=>'application.components.weekReport',
);
}
public function actionTest(){
echo 'Test';
}
public function run(){
$uri = (Yii::app()->getRequest()->getRequestUri());
$method = 'action'.ucfirst(substr($uri,strrpos($uri,'.')+1));
$this->$method();
}
// use same as before for your controller,
// and to call it
index.php?r=site/test.Test
Good luck with your studies… I wish you the best (I am actually envying you a bit )
Ah… this is very nice except one set-back. The run() method also happens to be called on CBaseController::endWidget(). So when I try to use the widget as an actual widget, the action will also be called which is not desirable in my case.
A workaround though would be to set a flag in init() (which is called in CBaseController::createWidget()) so in run() we can tell how it was called. There are other workarounds too…