Вопрос

I have an extended version of WebUser.

It worked perfectly fine. Until today I activated "autoLogin" with a time. Now when the user comes back, and auto-login kicks in, there is an error in this method:

public function afterLogin($fromCookie)
    {
            parent::afterLogin($fromCookie);

            // Update Last Login
            $model = $this->loadUser(Yii::app()->user->id);
            $model->last_visit = new CDbExpression('NOW()');
            $model->save();
    }

The error is:

Undefined property: CWebApplication::$user

Does that mean that the auto-login does not create the 'user' property anymore??

If I remove those lines, the rest of the site seems to work fine so far.

PHP notice

Undefined property: CWebApplication::$user

/Users/nathan/Git/web/protected/components/WebUser.php(16)

04 // protected/components/WebUser.php
05  
06 class WebUser extends RWebUser {
07  
08     // Store model to not repeat query.
09     private $_model;
10         
11     public function afterLogin($fromCookie)
12     {
13             parent::afterLogin($fromCookie);
14 
15             // Update Last Login
16             $model = $this->loadUser(Yii::app()->user->id);
17             $model->last_visit = new CDbExpression('NOW()');
18             $model->save();
19     }
20  
21     // Return first name.
22     // access it by Yii::app()->user->first_name
23     function getDisplayName(){
24         $user = $this->loadUser(Yii::app()->user->id);
25         return $user->displayName;
26     }
27     
28     function getNotificationCount(){
Stack Trace
#0  
–  /Users/nathan/Git/web/yii/yiilite.php(4087): WebUser->afterLogin(true)
4082                     if($this->autoRenewCookie)
4083                     {
4084                         $cookie->expire=time()+$duration;
4085                         $request->getCookies()->add($cookie->name,$cookie);
4086                     }
4087                     $this->afterLogin(true);
4088                 }
4089             }
4090         }
4091     }
4092     protected function renewCookie()
#1  
–  /Users/nathan/Git/web/yii/yiilite.php(3943): CWebUser->restoreFromCookie()
3938     public function init()
3939     {
3940         parent::init();
3941         Yii::app()->getSession()->open();
3942         if($this->getIsGuest() && $this->allowAutoLogin)
3943             $this->restoreFromCookie();
3944         elseif($this->autoRenewCookie && $this->allowAutoLogin)
3945             $this->renewCookie();
3946         if($this->autoUpdateFlash)
3947             $this->updateFlash();
3948         $this->updateAuthStatus();
#2  
–  /Users/nathan/Git/web/yii/yiilite.php(1050): CWebUser->init()
1045             $config=$this->_componentConfig[$id];
1046             if(!isset($config['enabled']) || $config['enabled'])
1047             {
1048                 unset($config['enabled']);
1049                 $component=Yii::createComponent($config);
1050                 $component->init();
1051                 return $this->_components[$id]=$component;
1052             }
1053         }
1054     }
1055     public function setComponent($id,$component,$merge=true)
#3  
–  /Users/nathan/Git/web/yii/yiilite.php(905): CModule->getComponent("user")
900         $this->init();
901     }
902     public function __get($name)
903     {
904         if($this->hasComponent($name))
905             return $this->getComponent($name);
906         else
907             return parent::__get($name);
908     }
909     public function __isset($name)
910     {
#4  
–  /Users/nathan/Git/web/protected/controllers/SiteController.php(30): CModule->__get("user")
25      * This is the default 'index' action that is invoked
26      * when an action is not explicitly requested by users.
27      */
28     public function actionIndex()
29     {
30         if(Yii::app()->user->checkAccessOrDeny('readHome')){
31                     //URLs to show in the list
32                     $criteria = Yii::app()->params['currentCommunity']->getUrls();
33                     $criteria->limit = 10;
34                     $urls = Url::model()->findAll($criteria);
35                                         
Это было полезно?

Решение

When you call Yii::app()->user->id, the user part is a instance of the CWebUser class (or a child of that class).

When the application loads, it tries to initialize that user component, and as part of that initialization, it logs in a user, and then calls your overridden afterLogin method. Your afterLogin method in turn tries to call the component... but it hasn't finished initializing yet. So rather than get stuck in an infinite loop, Yii just tells you that the user component doesn't exist.

Fortunately, during the login process, a call to changeIdentity is made, which calls setId, which populates the $id attribute of the user component. This id attribute is in fact exactly the same attribute that is called with Yii::app()->user->id, only it is accessed within the object, instead of externally.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top