5

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 ?

schmunk
  • 4,708
  • 1
  • 27
  • 50
sasori
  • 5,249
  • 16
  • 86
  • 138
  • 1
    Just add `class => 'CWebUser'` and it should work –  May 02 '13 at 13:58
  • 1
    the problem with adding the CWebUser class is that , am running a cron task..when I ran it with the CWebUser class, it is throwing an error `CConsoleApplication and its behaviors do not have a method or closure named getSession` ,what to do then ? – sasori May 02 '13 at 14:01
  • Right, web user for console app does not sound good. Where does it try to use that user? Do you have stack trace? Maybe it is not nessesary? –  May 02 '13 at 14:04
  • there's no stack trace at all, it's looking for the getSession() , when i added the CWebUser class..what should I do to prevent this and let the cron script run properly? – sasori May 02 '13 at 14:09
  • Ok, do not use that `CWebUser` class. If you enable `YII_DEBUG` it should print stack trace in console as well, try to find where it tries to use `CConsoleApplication.user`, see @schmunk answer as well. –  May 02 '13 at 14:14
  • YII_DEBUG is currently set to true in the index.php..but am not seeing any stacktrace at all, aside from those two errors am getting either when I include that User array, and then put the CWebUser in the User array – sasori May 02 '13 at 14:18
  • Please paste the full error message. – Michael Härtl May 02 '13 at 15:18
  • I quoted it in my reply with PeterM – sasori May 02 '13 at 15:19

5 Answers5

4

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.

Community
  • 1
  • 1
ulis bad
  • 41
  • 2
3

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.

schmunk
  • 4,708
  • 1
  • 27
  • 50
  • as i said, if I don't include that array from my first post, when i run the script, it is looking for a class, and then when i put the CWebUser class within the array, it is looking for the getSession function when CConsoleApplication don't have it in the documentation..what to do? – sasori May 02 '13 at 14:13
  • The question is: Why is your `yiic` command using the user module? – schmunk May 02 '13 at 17:19
3

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();
}
  • 1
    please put some hint about why this is a solution. which details are addressed by your code that were unhandled/not managed by the op? – Paolo Dec 18 '14 at 14:18
0

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

sasori
  • 5,249
  • 16
  • 86
  • 138
  • You are a lifesaver! I had the exact same problem...apparently, have to use update() instead of save()... – train May 15 '14 at 20:13
  • 2
    Ehm... Excuse me, but... what are you talking about? There is not even a tiny mention about `save()` or `update()` in your question. I think others will really appreciate, if you answer and question would match a little bit closer. Now, your answer looks like an off-topic one. – trejder Jul 04 '14 at 08:52
  • You rejected the question completely! – Nabi K.A.Z. Aug 24 '17 at 11:19
0

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.

MTurPash
  • 979
  • 1
  • 11
  • 18