I had an app that does not make use of yii login and authentication, but still making use of
Yii::app()->user->isGuest
as well as my own defined variables.
I hit an error saying isGuest is readonly. But we can make use of this value to determine whether user has logged in. So how can I change isGuest value??
If you’re looking for a way to access a global boolean called “isGuest”, why not implement the params module by adding it to your config array? Put a key=>value pair in the params array for isGuest. You’ll be able to access it anywhere using Yii::app()->params[‘isGuest’].
Rather, I will like to know how I can change isGuest value, since I did not use Yii login and authentication. In another words, I populate User model myself, but will still like to use Yii::app()->user->isGuest to see if the user is login.
The right way would be to really login this user. CWebUser::getIsGuest() is part of the authentication mechanism and you should not use it to store anything else but the login state of the current user.
To login the user from code (without a login form) you can create an authenticated UserIdentity and use it in a login() call. You can add a helper method to your UserIdentity class that creates such an authenticated identity for you (see here).
Even though mdomba’s suggestion might work i’d consider this: If you start to directly access internals of a class you “circumvent” the interface and thus loose the advantages of clean object encapsulation (read: if the devs decide to change what happens behind the scenes, your solution will stop to work)
Partially agree: What if some other logic is chosen at some time to decide wether a user is a guest? Or put another way: Why use getIsGuest() then? You could use setId() and getId() instead…
to test if a user is a guest, but it’s more readable to use isGuest()
Again, this is not an obscure / not documented / or internal method… My thinking is that if something is well documented… it can be used as the documentation says…
As for your thinking about changing logic in the future… that can happen to any method in the framework…
Hehe, nice discussion. I think both of us have a point here
First i thought, i could "beat" your argument with a look at the IWebUser interface - but i see, that login() is also not contained in that interface definition.
Still to me it feels more natural to say “a user is no guest, if he’s been logged in” (a.k.a. login() was called) than “a user is no guest if he has an id set”. The latter is a more abstract construct. And since i prefer to have a very natural mapping of “real life” to objects i’d prefer to use the login() method.
So can we conclude, it’s a matter of personal taste?
Why “beat”… we are just exposing our thoughts… to maybe help @twb in deciding what to do next
I agree on your comment… but your comment stands if we are using pure Yii code and login method…
as the original poster wrote in the first post, he uses a custom login process… so he just needs to add/incorporate the Yii isGuest() functionality to his login process… and that can be done… very KIS… by just setting the id in this case
Because i was lacking a better word. I like discussions where not the participants try to “beat” each other physcially but let their arguments do a little catfight and both have fun watching this contest. Evolution of ideas, if you like …
Actually this is what I did. I had a custom MyWebUser.php that extends CWebUser, so I can have it to return my own defined variables.
And a MyUserIdentity.php
class MyUserIdentity extends CUserIdentity
{
private $_id;
public function __construct($id)
{
$this->_id=$id;
}
/**
* @return integer the ID of the user record
*/
public function getId()
{
return $this->_id;
}
}
In SiteController.php, I have the following codes.
if(Yii::app()->user->isGuest)
{
$identity=new MyUserIdentity($id);
$duration=0; // 30 days
Yii::app()->user->login($identity,$duration);
}
And in MyWebUser.php, I overwrite the login method.
public function login($identity,$duration=0)
{
parent :: login($identity,$duration=0);
$this->loadUser($identity->getId());
$this->changeIdentity($identity->getId(),$identity->getName(),array('isGuest', false));
}
So when I go to index.php, SiteController.php will ‘login’ the user, and isGuest is found to be false.
It seems to work well, until I realize when I navigate to other pages such as index.php/site/page/view/about
it seems isGuest is back to true and even what I set in Yii::app()->session.add(); is also gone!
You’re code looks overcomplicated to me: You override some of the core methods and thus “disturb” the default authentication mechanism of Yii. Why? My first reaction is: If you do that you should know what you do and thus are on your own, if it doesn’t work.