A favore dei posteri, vi trasmetto la soluzione, anche se mi rendo conto che è un po’ specifica per la mia esigenza, che NON è quella di eseguire una action ‘e basta’ ma ne devo proproprio avere l’output.
Nel mio caso specifico si tratta di una action che fa un renderPartial, perchè viene chiamata via ajax allo scopo di aggiornare una parte della pagina dinamicamente.
Questa stessa parte di pagina deve essere inviata via mail tramite console command schedulato tramite cron.
1. Rendere l’action desiderata una function privata, dandogli un nome diverso
questa deve accettare un parametro booleano, per esempio ‘return_output’.
Passare alla function eventuali parametri necessari, nel mio caso la data di riferimento, che è presa dalla chiamata ajax oppure passata a forza come ‘oggi’ se chiamato dal console command
// Called from actionGetReportViaAjax and actionGetReportOutput
private function getReport($date, $return_output)
.
2. Ricreare l’action modificata in modo che si limiti a chiamare la function privata
In questo caso il parametro sarà false. Dopo sarà piu chiaro perchè
public function actionGetReportViaAjax()
{
$request = Yii::app()->getRequest();
$date = $request->getParam("date");
// volendo potete verificare così che sia chiamato solo via ajax
if (!$request->isAjaxRequest) {
throw new Exception("Your request is invalid", 1);
return;
}
// chiamo la function privata dandogli la data e
// chiedendo che NON venga dato restituito l'output come stringa
$this->getReport($date, false);
}
3. Creare una nuova action a specifico uso del console command
In questo caso il parametro
"$return_output"
sarà true.
La function farà semplicemente qualcosa come questo:
public function actionGetReportOutput()
{
// chiamo la funzione passandogli la data
// in questo caso richiedo l'output come stringa
$output = $this->getReport(date("Y-m-d"), true);
return $output;
}
4. Nella function privata (‘getReport’), modificare la parte relativa al renderPartial
In verità come tecnica si applica anche al render normale come tecnica.
Bisogna che i parametri da passare al render siano messi in una variabile, invece che passati esplicitamente come array.
esempio
$param_array = array (
'month_names' => $month_names,
'abbreviated_month_names' => $abbreviated_month_names,
);
Quindi valutiamo se eseguire restituire l’output o no
if ($return_output) {
$renderer = new CPradoViewRenderer();
$view = YiiBase::getPathOfAlias("application.modules.order.views.charged") . "/_report.php";
return $renderer->renderFile($this, $view, $param_array, true);
}
// output
$output = $this->renderPartial("_report", $param_array, $return_output);
5. il console command
Importa esplicitamente il controller
Yii::import('application.modules.order.controllers.ChargedController');
Lo istanzia
$orderController = new ChargedController("Charged");
Esegue l’action specifica appena creata
$output = $orderController->actionGetReportOutput();
Che ne pensate ?