Reputation: 2040
Is it possible to run a web action in a console controller?
In a web controller (yii\web\Controller) I have an action which I would like to run as a cron job. But if I try to run it in a console controller (yii\console\Controller):
Yii::$app->runAction('controller/action');
then I receive the following error message:
Error: Unknown command "controller/action".
Upvotes: 3
Views: 5175
Reputation: 4149
Run a web action in a console controller:
Yii::$app->controllerNamespace = "app\controllers";
Yii::$app->runAction('controller/action');
Assign controllerNamespace
before running the web action from console.
In addition, disable enableCsrfValidation
for the web action:
public function beforeAction($action)
{
if ($action->id == 'action') {
$this->enableCsrfValidation = false;
}
return parent::beforeAction($action);
}
The
'action'
ID could be replaced with your current web action ID.
Upvotes: 3
Reputation: 2040
The solution with cURL.
In the web controller have to be disabled the CSRF validation:
public function beforeAction() {
if ($this->action->id == 'export') {
Yii::$app->controller->enableCsrfValidation = false;
}
return true;
}
The cURL commands in the console Controller can look e.g. like this:
$ch = curl_init();
$options = array(
CURLOPT_URL => $url,
CURLOPT_REFERER => $url,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_COOKIESESSION => true,
CURLOPT_COOKIEJAR => 'curl-cookie.txt',
CURLOPT_COOKIEFILE => '/var/www/yii/frontend/web/tmp',
CURLOPT_CONNECTTIMEOUT => 120,
CURLOPT_TIMEOUT => 120,
CURLOPT_MAXREDIRS => 10,
CURLOPT_USERAGENT => "Dark Secret Ninja/1.0",
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => "LoginForm[username]=".$username.
"&LoginForm[password]=".$password.
"&LoginForm[rememberMe]=1",
CURLOPT_SSL_VERIFYPEER => false,
);
curl_setopt_array( $ch, $options );
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); //get status code
if ( $httpCode != 200 ){
echo "Return code is {$httpCode} \n"
.curl_error($ch);
} else {
echo htmlspecialchars($response);
}
curl_close($ch);
Upvotes: 1
Reputation: 38
Sorry, I did not understand the context of the question.
As @soju says, you should find a way to do it using CURL, but there is a way.
$config = \yii\helpers\ArrayHelper::merge(
require(Yii::getAlias('@common').'/config/main.php'),
require(Yii::getAlias('@common').'/config/main-local.php'),
require(Yii::getAlias('@frontend').'/config/main.php'),
require(Yii::getAlias('@frontend').'/config/main-local.php')
);
$web_application = new \yii\web\Application($config);
$web_application->runAction('/site/index',['param1' => 1,'param2' => 2]);
You should be aware that the controller works with their behaviors, then the AccessControl could prevent the execution
Upvotes: 2