how to fix CConsoleApplication.user undefined in a command class in yii framework?

5.2k views Asked by At

I am having that error , whenever I ran my simple cron script in shell , any idea how to fix that thing ?, from the error itself, it says the .user is undefiend, when I placed the

'user' => array(
    // enable cookie-based authentication
     'allowAutoLogin' => true,
 'loginUrl' => array('myaccount/blah/login'),

in the console config, it is looking for a "Class" ,, what class am i supposed to include in that array? , this user login url is using an LDAP stuff in loggin in and authentication, what should I do ?

5

There are 5 answers

3
sasori On BEST ANSWER

solved my problem by using update, instead of save in the script...no need to use user array and CWebUser class

1
Stagnantice On

Try this

public static $console_user_id;

public function init() {
    if (Yii::app() instanceof CConsoleApplication) {
        if (self::$console_user_id) $this->id = self::$console_user_id;
        return false;
    }
    parent::init();
}
2
schmunk On

Short answer: You can't use CWebUser in console application. Don't include it in your config/console.php

Long(er) answer: If you rely on a component, which needs CWebUser, you'll have to detect this in the component and create some kind of workaround for this case. Have a look at this code piece for an example how to detect, if you're running a console app.

0
MTurPash On

I had the same problem. Screened all answers given here and found some good point, but solved my problem my way, although it may not be the best.

First off all I had to figure out that my Cron Jon threw the aforementioned Exception because inside the Cron job I was running a script which had this part of code in it

if(Yii::app()->user->isAdmin()) {...} else {...}

So the console threw the error since the user was not defined. I changed my code in such a way that I tested if the console was running it. The changed code is as follows:

$console = false;
try {
    $test = Yii::app()->user->isAdmin();
}
catch (CException $e)  {
    $console = true;
}
if($console || (!$console && Yii::app()->user->isAdmin()) {...} else {...}

As said, not perfect, but maybe a solution for someone.

0
ulis bad On

A CConsoleApplication is for handling offline tasks. For example, the application starts a cronjob within a linux system. The application checks each day if a registered user of your website should change his password, because it must be changed every 3 month. If the password expired send an email.
To preselecting the users you have set a scope condition to check the status of a user, as well as a scope to restricted signed in users on her own data:

    public function scopes(){
                 return array(...,
                    'user'    => array(
                                   'condition'=>'id='.Yii::app()->user->id, 
                                 ),
                    'active'  => array(
                                   'condition'=>'status='.self::STATUS_ACTIVE,
                                 ), ...
                        );
    }

Now, in your CCA-Code you use the active scope to get all users: $usersArray = User::model()->active()->findAll(); ...foreach.... The Problem here is in the use of the extended class, the CActiveRecord-class. Mostly used as a class extension in models, which are stored in a database. In this CActiveRecord-class the CActiveRecord->__call function is used to get all stored scopes of a model. After that the class merged the actually requested scopes with the rest of the database criteria. The fact that all scopes are loaded first occures the error in loading the user-scope, include Yii::app()->user->id. The WebUser is called and throws the exception 'CException' with message 'attribute "CConsoleApplication.user is not defined'. You wouldn't call the WebUser, but the automatism arrange this for you :-)

So, do it like schmunk says. Generate in your scope code an exception part where ensures that Yii::app()->user is not called:

 public function scopes(){
         if (Yii::app() instanceof CConsoleApplication) {
              $user = array(''); //no condition 
         }else{
              $user = array(
                        'condition'=>'id='.Yii::app()->user->id, 
                      );
         }
         return array(
              'user'    => $user,
              'active'  => array(
                                   'condition'=>'status='.self::STATUS_ACTIVE,
                           ), ...
         );
 }

I hope the explanation helps and perhaps also for other problems.