Different Scenarios Validations and Before Save Actions


(Thiagovidal) #1

So I’m writing my application administration interface. I used yiic tool to create my model and my crud files.

On my model ‘Users’ i invoked beforeValidate and beforeSave methods to change the attributes.




	public function beforeValidate()

	{

		if(parent::beforeValidate())

		{

			$this->setAttribute('birthday', date('Y-m-d', strtotime($this->bYear . '-' . $this->bMonth . '-' . $this->bDay)));

			$this->setAttribute('activationKey', Yii::app()->user->_encrypt(microtime() . $this->password));

			$this->setAttribute('dateCreation', date('Y-m-d H:i:s'));

			$this->setAttribute('dateLastVisit', date('Y-m-d H:i:s'));

			return true;

		}

	}

	

	public function beforeSave()

	{

		if(parent::beforeSave())

		{

			$this->setAttribute('firstName', strtoupper($this->firstName));

			$this->setAttribute('lastName', strtoupper($this->lastName));

			$this->setAttribute('birthday', date('Y-m-d', strtotime($this->bYear . '-' . $this->bMonth . '-' . $this->bDay)));

			$this->setAttribute('password', Yii::app()->user->_encrypt($this->password));

			$this->setAttribute('activationKey', Yii::app()->user->_encrypt(microtime().$this->password));

			$this->setAttribute('secretAnswer', Yii::app()->user->_encrypt(strtolower($this->secretAnswer)));

			$this->setAttribute('status', 1);

		}

        return true;

	}




Question 1

The problem is that I don’t want this same attributes values on different scenarios ‘create’ and ‘update’.

How can I use this code only when I’m creating a new user?

How can I use another code when I’m updating an existing user?

Question 2

Another newbie question is how can I save the ‘dateLastVisit’ when the user login? I was trying to use the below code on my UserIdentity.php




                        $model=new Users;

			$model->dateLastVisit=date('Y-m-d H:i:s');

			$model->save();



Question 3

If you see the fisrt code above you’ll note that i encrypted the password

$this->setAttribute(‘password’, Yii::app()->user->_encrypt($this->password));

but when the admin edit and save the user the password get encrypted again. How can I solve this?


(Matteo Falsitta) #2

Question 1

You can use $this->isNewRecord for check if is a new record (create) or an old one (update).

Question 2

You should’t to new Users but Users::model()->find($condition).

If your are just logging the user I suppose that you alredy do something like that for check the password, so simply call on the model you loaded




$model->dateLastVisit=date('Y-m-d H:i:s');

$model->save();



without any new

Question 3

Is mainly a question of style. As the password is encrypted it cannot be read, so the only possibility to edit is to set a new password. For edit you can create a field named ‘newPassword’, not required.

In beforesave you can for example do something like that:




if ($this->newPassword)

    $this->password=Yii::app()->user->_encrypt($this->password);



Only for edit.


(Thiagovidal) #3

Thanks a lot. Simple and useful!

But not getting this:

It doesn’t seams to work properly. The value don’t update! But i don’t get any error at all.


(Arekandrei) #4

Looks like your model doesn’t pass validation. Moreover, you don’t need it at all. Try to use:




$model->save(false, array('dateLastVisit'));




(Thiagovidal) #5

Worked like a charm… But, is this create security issues?


(Arekandrei) #6

No, 1) date(‘Y-m-d H:i:s’) won’t return a string which can break SQL query; 2) save() function uses parameters in queries.


(Thiagovidal) #7

Tks. dude!!!