Add information to Yii::app()->user by extending CWebUser
This little tutorial explains a way how you can retrieve more parameters from Yii::app()->user by adding a component that extends CWebUser and retrieves the user information from database table named User.
There is also another method of doing this that retrieves the variables from session or cookie instead:
How to add more information to Yii::app()->user (based on session or cookie)
Steps to follow:
1. Make sure you have got an database User model.
2. Create a component that extends CWebUser.
3. Specify in the config.php what user class the application must use.
1. The User model should be a file like this, that you probably already have, anyway for who doesn't:
// this file must be stored in: // protected/models/User.php class User extends CActiveRecord { /** * Returns the static model of the specified AR class. * @return CActiveRecord the static model class */ public static function model($className=__CLASS__) { return parent::model($className); } /** * @return string the associated database table name */ public function tableName() { return 'User'; } }
2. Then we create the WebUser component:
// this file must be stored in: // protected/components/WebUser.php class WebUser extends CWebUser { // Store model to not repeat query. private $_model; // Return first name. // access it by Yii::app()->user->first_name function getFirst_Name(){ $user = $this->loadUser(Yii::app()->user->id); return $user->first_name; } // This is a function that checks the field 'role' // in the User model to be equal to 1, that means it's admin // access it by Yii::app()->user->isAdmin() function isAdmin(){ $user = $this->loadUser(Yii::app()->user->id); return intval($user->role) == 1; } // Load user model. protected function loadUser($id=null) { if($this->_model===null) { if($id!==null) $this->_model=User::model()->findByPk($id); } return $this->_model; } }
3. The last step, configure the application
// you must edit protected/config/config.php // and find the application components part // you should have other components defined there // just add the user component or if you // already have it only add 'class' => 'WebUser', // application components 'components'=>array( 'user'=>array( 'class' => 'WebUser', ), ),
That's all now you can use the following commands:
Yii::app()->user->first_name - property that returns name
Yii::app()->user->isAdmin() - function that returns admin status
And now you can add all the functions you want to WebUser component.
Links
Total 7 comments:
Because you must add items with setState before retrieveing them, what will you do if you want to retrieve 50 items? will you store them all on the login?
And what if you want to retrieve something like Yii::app()->user->isBanned()? If you store it into session it wont refresh if you ban the user until he logs out and in again. But this way it will be fresh information because it looks in the database.
Anyway when I'll have trouble with performance from the database query I'll switch on session.
For many user information, I would serialize User AR into session.
For "live" information, I would use cache these informations (delimited by a small restricted time).
I found this method is very usefull to get data in Relational Active Record table. For example, each user have many posts. In WebUser declare
function getModel()
{
$user = $this->loadUser(Yii::app()->user->id);
return $user;
}
And now to get all posts by the current user, you just call Yii::app()->user->model->posts
This worked well for me with php 5.2 but it does not work with php 5.3
I also have experienced problems with this since upgrading to PHP 5.3.
I am using the web log route and have set the CLogFilter::logUser property to true. Now when I access any route in my application as a guest (not logged in), I get the following error:
PHP Error
Trying to get property of non-object
00016: public function getName()
00017: {
00018: $user = $this->loadUser(Yii::app()- >user->id);
00019: return $user->email;
00020: }
My problem was similar to that described by waveslider. The reason is that Guest is not listed in the user table and therefor it has no id, that is Yii::app()->user->id is not set. In php 5.2 it is ok because it assignes default values to variables but php5.3 does not. So we get error "Trying to get property of non-object" because $user is not created.
I solved my problem with code like this:
public function getName()
{
if(Yii::app()->user->getIsGuest())
{
return "";
}
else
{
$user = $this->loadUser(Yii::app()->user->id);
return $user->email;
}
}

Also, I don't recommend this method, because it will always query user table