call to undefined method stdClass::save()

Hello, I’m stuck with this error:

a brief excerpt of the relevant code.




private $userdevicePK;

 public function myfunction()

	 {

	 $devRecord=UserDevice::model()->findByAttributes(array('number'=>$this->username,'deactivated'=>NULL,));

	// ...irrelevant code here..


	$userRecord=User::model()->findByPK($devRecord->user);

	

        $update=UserDevice::model()->findByPK($this->userdevicePK);

  	 $update->user= $userRecord->id;

  	  Dialog::message('about to assign to user #', (string) $update->user);

  	  $update->save(false);

  	

	 }



The dialog shows the correct value to be updated, but when it comes to save() I get this

Fatal Error: Call to undefined method stdClass::save() in … components/UserIdentity.php line 111 ["$update->save(false);]

any guess?? :blink: would be appreciated

mayday!!

Do you have any idea where the UserIdentity is coming from, because that class doesn’t have a save() method!

Just to make sure, can you add the class name to you dialog message! (get_class($update))

cheers

Can you post your UserDevice Model please? There might be something in the before/afterSave() methods that could give a clue.

Also, is your UserDevice->user property an integer or and ActiveRecord object? From the looks of your code it appears to be an integer.

Cheers.

Thank u for the reply

UserIdentity is a base class for the authentication

http://www.yiiframework.com/doc/api/1.1/CBaseUserIdentity

more info here

http://www.yiiframework.com/doc/guide/1.1/en/topics.auth

get_class($update) returns: stdClass

Thank you for your reply

this is UserDevice model




class UserDevice extends CActiveRecord

{

	/**

	 * Returns the static model of the specified AR class.

	 * @return UserDevice 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 'userDevice';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('user, activated, deactivated', 'numerical', 'integerOnly'=>true),

			array('number', 'length', 'max'=>15),

			array('tempPassword', 'length', 'max'=>100),

			// The following rule is used by search().

			// Please remove those attributes that should not be searched.

			array('id, user, number, activated, deactivated, tempPassword', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'id' => 'ID',

			'user' => 'User',

			'number' => 'Number',

			'activated' => 'Activated',

			'deactivated' => 'Deactivated',

			'tempPassword' => 'Temp Password',


		);

	}


	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.

	 */

	public function search()

	{

		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new CDbCriteria;


		$criteria->compare('id',$this->id);

		$criteria->compare('user',$this->user);

		$criteria->compare('number',$this->number,true);

		$criteria->compare('activated',$this->activated);

		$criteria->compare('deactivated',$this->deactivated);

		$criteria->compare('tempPassword',$this->tempPassword,true);




		return new CActiveDataProvider(get_class($this), array(

			'criteria'=>$criteria,

		));

	}

}



It refers to an integer field in the DB

hope this can bring some light

Its not that I don’t know about UserIdentity :) but its there for unknown reason in the error!

I would say that $update should be of type UserDevice!

UPDATE: Now I see, its all taken place inside UserIdenty class :), my mistake. Then I would say that there is no UserDevice for $this->userdevicePK!

Can you insert this in between your dialogue line and the save line:




if ($update == null)

    $update = new UserDevice();



Do you still get the same error msg? If not, then your $update obj isn’t being created/loaded as you expected and you need to go through, line by line, checking for nulls.

Matt

$this->userdevicePK refers to an integer value, and in fact it has the correct value before trying to save it to the DB. All the values are correct, the whole logic of searching through the DB works (findByPK,findByAttributes,etc…) but the save() statement makes the thing crash. :unsure: :blink:

I’ve added the given code




$update=UserDevice::model()->findByPK($this->userdevicePK);

  	      		$update->user= $userRecord->id;

  	      		Dialog::message('about to assign to user #', (string) $update->user);

  	      		if ($update == null)

                           $update = new UserDevice();

  	                $update->save(false);



But $update cannot be null, since $update->user shows the correct value in the Dialog.

This is kinda drivin’ me crazy :o :( <_< :huh: :blink: :-[ :-X

If $update is initially null it will become a stdclass when you assign to $update->user.

/Tommy

True - I found these two articles helpful.

[list=1]

[*]http://stackoverflow.com/questions/931407/what-is-stdclass-in-php (See 2nd answer)

[*]http://krisjordan.com/dynamic-properties-in-php-with-stdclass

[/list]

Thanks Tommy, but as far as I know, given that I did




$update=UserDevice::model()->findByPK($this->userdevicePK);

  	      		$update->user= $userRecord->id;

  	      		Dialog::message('about to assign to user #', (string) $update->user);



maybe I’m missing something, but update can’t be initially null, right?

in fact the whole relevant code of the function for this matter is




	 $devRecord=UserDevice::model()->findByAttributes(array('number'=>$this->username, 'deactivated'=>NULL,));

	 if($devRecord===NULL) 

		   $this->errorCode=self::ERROR_NUMBER_NOT_REGISTERED; //custom error code 

	 else

		 if ($devRecord->user==NULL) 

		 	$this->errorCode=self::ERROR_NUMBER_NOT_REGISTERED; // custom error code

		 else{

		 	$userRecord=User::model()->findByPK($devRecord->user);

		        if ($userRecord->password!==md5($this->password. $userRecord->salt ))

  	                    $this->errorCode=self::ERROR_PASSWORD_INVALID;

  	      	       else{

  	      		   $update=UserDevice::model()->findByPK($this->userdevicePK);

  	      	    	$update->user= $userRecord->id;

  	      		   Dialog::message('about to assign to user #', (string) $update->user);

  	      		$update->save(false);

  	            	}	

		 }

	



and if you print out the $userRecord->id:


Dialog::message('about to assign to user #', (string) $userRecord->id);

Then it shows the correct value, as it previously did with $update->user. As I’ve said, all the data is working fine, all the values are the expected ones, the only unexpected thing is the outcome (crash). In fact, in the first moment I did not have $update defined in my code, I just re-used $devRecord for that matter, but after the fatal error, I introduced that “$update” object (UserDevice class) to test if the error had something to do with the re-using of the devRecord for a new search. And it hadn’t (obviously).

Thank you for your interest on this

Ok, although everything seems ok, something is wrong :)

So just to make sure, did you already do exactly the following:




$update=UserDevice::model()->findByPK($this->userdevicePK);

if ( $update == null ) {

    Dialog::message('NULL') ;

}

Dialog::message( 'class name = ', get_class($update) ) ;

// and now the other stuff

 $update->user= $userRecord->id;



Well, I made a detailed trace via Dialog… just to find out a really strange behaviour. I can’t retrieve $this->userdevicePK from my code, it returns null. The GENERIC scenario is:




class A extends B

{

	

	private $userdevicePK;

        public function authenticate()

	 {

               // ... CODE HERE ...

              $this->userdevicePK; // correct value

            

         }

        public function confirm()

        {

             // ...CODE HERE .. 

              $this->userdevicePK; //undefined value

        }

}



So in authenticate() method I can reference and alter $this->userdevicePK without problem, BUT in confirm() the same access would return undefined, even if I declare $userdevicePK as public, the outcome is the same… :-X

I don’t know if maybe is a good idea to start a new topic solely on this

Maybe you should, but I’m not sure you can translate your problem into something people can help you with.

Anyway, to get you started, you could verify that you’re dealing with the same object using spl_object_hash ( http://nl2.php.net/spl_object_hash )

cheers