Back compatibility!

I understand, that Yii is under havy development, but back compatibility is very important anyway.

After I upgraded to the SVN yesterday, I found, that the line $cs->renderCoreScript() is not working. OK, I studied the docs and changed that.

But now I see, that in the old variant the line Yii::app()->user->id printed out user's ID. In the ne one ot show the login… Quite strange behavour and it is not expected anyway.

Please could you take care of such things in the future so upgrading to the new versions wasn't a problem.

Thanks!

We are trying very hard to keep BC. I believe in future releases, we will have less and less BC-breaking changes. Version 1.0.3 is probably the last minor version that contains many "major" features.

I'm not aware the change to Yii::app()->user->id. Could you explain how to reproduce it?

Yes, sure.

I have an identity class:

class UserIdentity extends CUserIdentity


{


    const ERROR_USER_INACTIVE = 10;


    


    public function authenticate()


    {


        $record = User::model()->findByAttributes(array('username'=>$this->username));


        if($record === null)


            $this->errorCode = self::ERROR_USERNAME_INVALID;


        elseif($record->password !== md5($this->password))


            $this->errorCode = self::ERROR_PASSWORD_INVALID;


        elseif ($record->active == 0)


            $this->errorCode = self::ERROR_USER_INACTIVE;


        else


        {


            $this->setState('_id', $record->userID);


            $this->setState('_fullName', $record->fullName);


            $this->setState('tafNum', 0);


            $this->errorCode = self::ERROR_NONE;


        }


        return !$this->errorCode;


    }


}

And WebUser class:

<?php


class WebUser extends CWebUser


{


    public function getFullName()


    {


        $name = $this->getState('_fullName');


        if (empty($name))


            return $this->name;


        else return $name;


    }


    


    public function setFullName($nm)


    {


        $this->setState('_fullName', $nm);


    }


    .....


}


?>

And configuration file:

'user'=>array(


            // enable cookie-based authentication


            'class' => 'application.components.WebUser',


            'allowAutoLogin' => true,


            'loginUrl' => 'user/login'


        ),

And calling

Yii::app()->user->id

returns the login of the logged user. However, it is quite predictable because there is the line in CUserIdentity.php:

public function getId()


    {


        return $this->username;


    }

Overriding this method like this:

public function getId()


      {


          $this->getState('_id');


      }

Doesn't help - it outputs an empty string (I don't have any idea why it happens so…)

Also, if I add

public function getId()

    {

        $this->getState('_id');

    }

to the WebUser class, it simply outputs nothing - just empty string.

I can't find any reasonable explanation why it behaves so. Could you explain?

Previously the classes I showed in the beginning worked fine.

Did you forget the 'return' word in your getter method?

Yes… Sorry, so silly mistake…

No problem. Other than this, did you find any other problems?

ClientScript change and this one - nothing else for now. I'll let you know in this thread if I find any more.

Is this (user->id) still a problem?

Well, if I save user's ID in session when authenticating it and then getting it from there in the WebUser class - it's OK. But if I don't do this, it simply returns the username. It can't return anything else without additional code because in the CUserIdentity class there is only $username and $password defined and both getId() and getName() methods return the same. And even if I reload the getId() method:

class UserIdentity extends CUserIdentity


{


    const ERROR_USER_INACTIVE = 10;


    


    public function authenticate()


    {


        $record = User::model()->findByAttributes(array('username'=>$this->username));


        if($record === null)


            $this->errorCode = self::ERROR_USERNAME_INVALID;


        elseif($record->password !== md5($this->password))


            $this->errorCode = self::ERROR_PASSWORD_INVALID;


        elseif ($record->active == 0)


            $this->errorCode = self::ERROR_USER_INACTIVE;


        else


        {


            $this->setState('_id', $record->userID);


            $this->setState('_fullName', $record->fullName);


            $this->setState('tafNum', 0);


            $this->errorCode = self::ERROR_NONE;


        }


        return !$this->errorCode;


    }


    


    public function getId()


    {


        return $this->getState('_id');


    }


}

It still returns user's name. I double checked this.

I'm confused…Is the code you are showing here working as expected? What is $record->userID?

$record->userID is correct.

See, if I have this:

public function authenticate()


    {


        $record = User::model()->findByAttributes(array('username'=>$this->username));


        if($record === null)


            $this->errorCode = self::ERROR_USERNAME_INVALID;


        elseif($record->password !== md5($this->password))


            $this->errorCode = self::ERROR_PASSWORD_INVALID;


        elseif ($record->active == 0)


            $this->errorCode = self::ERROR_USER_INACTIVE;


        else


        {


            $this->setState('_id', $record->userID);


            $this->setState('_fullName', $record->fullName);


            $this->setState('tafNum', 0);


            $this->errorCode = self::ERROR_NONE;


        }


        return !$this->errorCode;


    }


    


    public function getId()


    {


        return $this->getState('_id');


    }

and

class WebUser extends CWebUser


{


//    public function getId()


//    {


//        return $this->getState('_id');


//    }


    


    public function getFullName()


    {


        $name = $this->getState('_fullName');


        if (empty($name))


            return $this->name;


        else return $name;


    }


.....


(WebUser::getId() is commented out.)

Then Yii::app()->user->id returns 'Konstantin' - it is login.

If I have getId() method in the WebUser and don't have it in the UserIdentity:

class WebUser extends CWebUser


{


    public function getId()


    {


        return $this->getState('_id');


    }


....


Then Yii::app()->user->id returns 1 - it is userID, everything is correct.

It works, but the question is why polymorphism doesn't work here…

Weird. You don't need to override CWebUser::getId(). It should work.

Please refer to the updated blog demo for an example.

Quote

Weird. You don't need to override CWebUser::getId(). It should work.

Please refer to the updated blog demo for an example.

I remember last night I spent a good two hours trying to figure out why it wouldn't work. If I didn't override it I'd get a read-only error on user.Id. I'll try it with the latest SVN though, It was a good couple weeks outdated.