Model Scenario gets reset?

Hi all,

I have an issue with setting model scenarios I have never encountered before, essentially it seems as if the scenario is being reset to the value ‘1’. Here is an example:

In controller:


$model = Account::model()->findByPk($id);

$model->setScenario('updateEmail');

$model->email = $_POST['account']['email'];

$model->email_confirm = $_POST['account']['email_confirm'];

if($model->save()) {

...

}

Then in the model if I echo out the scenario I just get the number 1


public function afterValidate() {

print_r($this->getScenario());

die();

}

I am perplexed, what is going on here?

That really doesn’t seem right. Can you show your complete model and controller classes?

Are you absolutely sure the "1" is being printed by that statement and not by another debugging statement elsewhere in your code?

are you sure you not overwriting the scenario somewhere else, it would be easy to look at if you could paste your rest of the code here

Ok here goes, it’s a long one!

I am having the issue in the afterValidate function, however I have tried echoing out the scenario in beforeValidate, beforeSave, and afterSave and all have the same issue.

I checked to make sure that it was my print_r($this->getScenario()) that was making the "1" appear, I also ehcoed out the scenario in the controller and it appears fine, the issue happens when I call $model->save() and then magically it is a "1"

Model:




class Account extends CActiveRecord

{

	public $password_confirm;

	public $email_confirm;

	public $update_password;

	

	/**

	 * Returns the static model of the specified AR class.

	 * @param string $className active record class name.

	 * @return Account 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 'account';

	}


	/**

	 * @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('password_confirm, email_confirm, id, notes', 'safe'),

			array('email, first_name, last_name, phone_number, address_1, state, country, city, post_code, password, is_active, create_time', 'required'),

			array('email_confirm', 'required', 'on'=>'updateEmail, register'),

			array('password_confirm', 'required', 'on'=>'updatePassword, register'),

			array('birthday_time, create_time, is_active, auth_id', 'numerical', 'integerOnly'=>true),

			array('first_name, last_name, email, phone_number, address_1, address_2, state, country, city, website, facebook_page, twitter_page', 'length', 'max'=>255),

			array('post_code', 'length', 'max'=>7),

			array('password, salt', 'length', 'max'=>92),

			array('phone_number', 'phoneValidator', 'on'=>'register, updateBilling, updateAdmin, updateAdminPassword'),

			array('email', 'compare', 'compareAttribute'=>'email_confirm', 'on'=>'register, updateEmail'),

			array('password', 'compare', 'compareAttribute'=>'password_confirm', 'on'=>'register, updatePassword'),

			array('email', 'emailValidator', 'on'=>'register, updateEmail, updateAdmin, updateAdminPassword'),

			array('email', 'email', 'on'=>'register, updateEmail, updateAdmin, updateAdminPassword'),

			array('email', 'unique'),

			array('website, facebook_page, twitter_page', 'url', 'on'=>'updatePersonal, updateAdmin, updateAdminPassword'),

			array('email_confirm', 'email', 'on'=>'register, updateEmail'),

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

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

			array('id, first_name, last_name, email, phone_number, address_1, address_2, state, country, post_code, birthday_time, website, facebook_page, twitter_page, password, salt, create_time, is_active, auth_id, notes', '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(

			'accountBridgeMulticrafts' => array(self::HAS_MANY, 'AccountBridgeMulticraft', 'account_id'),

			'accountServices' => array(self::HAS_MANY, 'AccountService', 'account_id'),

			'invoices' => array(self::HAS_MANY, 'Invoice', 'acount_id'),

		);

	}


	/**

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

	 */

	public function attributeLabels()

	{

		return array(

			'id' => 'ID',

			'first_name' => 'First Name',

			'last_name' => 'Last Name',

			'email' => 'Email',

			'phone_number' => 'Phone Number',

			'address_1' => 'Address Line 1',

			'address_2' => 'Address Line 2',

			'state' => 'State/Province',

			'country' => 'Country',

			'post_code' => 'Post/Zip Code',

			'birthday_time' => 'Birthday',

			'website' => 'Website',

			'facebook_page' => 'Facebook Page',

			'twitter_page' => 'Twitter Page',

			'password' => 'Password',

			'salt' => 'Salt',

			'create_time' => 'Create Time',

			'is_active' => 'Is Active',

			'auth_id' => 'Auth Level',

			'notes' => 'Notes',

		);

	}


	/**

	 * 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('first_name',$this->first_name,true);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}


	//before validation operations

	public function beforeValidate() {

		if($this->scenario = 'createAdmin' || $this->scenario == 'updatePersonal' || $this->scenario == 'updateAdmin' || $this->scenario == 'updateAdminPassword') {

			//add url back into facebook and twitter page attribs

			if(strlen($this->facebook_page) > 0) {

				$this->facebook_page = 'http://www.facebook.com/' . $this->facebook_page;

			}

			if(strlen($this->twitter_page) > 0) {

				$this->twitter_page = 'http://www.twitter.com/' . $this->twitter_page;

			}

			

			//reformat birthday into unix timestamp

			if(strlen($this->birthday_time) > 0) {

				list($month, $day, $year) = explode('/', $this->birthday_time);

				

				$this->birthday_time = mktime('12', '00', '00', $month, $day, $year);

			}

		}

		

		//if new record then add timestamp

		if($this->isNewRecord == true) {

			$this->create_time = time();

			$this->is_active = 1;

		}

		

		return true;

	}

	

	//after validation operations

	public function afterValidate() {

		if($this->isNewRecord || $this->scenario == 'updatePassword' || $this->scenario == 'updateAdminPassword') {

			print_r($this->getScenario());

			die();

			$hasher = new PasswordHash;

			$hash = $hasher->create_hash($this->password);

			list($type, $itterations, $salt, $password) = explode(':', $hash);

			

			$this->password = $password;

			$this->password_confirm = $password;

			$this->salt = $salt;

		}

		

		return true;

	}


	//checks if email is unique if not logged in

	public function emailValidator($attribute) {

		print_r($this->getScenario());

		$results = Yii::app()->db->createCommand()

					->select('a.*')

					->from('account a')

					->where('a.email = :email', array(':email' => $this->$attribute))

					->queryAll();

					

		if(count($results) > 0 && Yii::app()->user->isGuest && $this->isNewRecord) {

			$this->addError($attribute, 'Email is already in use!');

		}

		else {

			return;

		}

	}

	

	//phone validator

	public function phoneValidator($attribute) {

		if(!preg_match('/^[+]?([\d]{0,3})?[\(\.\-\s]?([\d]{3})[\)\.\-\s]*([\d]{3})[\.\-\s]?([\d]{4})$/', $this->$attribute)) {

			$this->addError($attribute, 'Phone number is not valid!');

		}

		else {

			return;

		}

	}

}



And the controller:





public function actionUpdateEmail()

	{

		if(isset($_POST['submit'])) {

			//form is submitted, update email address

			$auth_model = new LoginForm();

			

			$auth_model->username = Yii::app()->user->email;

			$auth_model->password = $_POST['account']['password'];

			

			if($auth_model->validate() && $auth_model->authenticateOnly()) {

				//validated owner, we can now save new email address

				$account_model = Account::model()->findByPk(Yii::app()->user->id);

				$old_email = $account_model->email;

				$account_model->setScenario('updateEmail');

				

				$account_model->email = $_POST['account']['email'];

				$account_model->email_confirm = $_POST['account']['email_confirm'];

				

				if($account_model->save()) {

					//need to re-login the user with new email

					$login_model = new LoginForm();

					$login_model->logout();

					

					$login_model->username = $account_model->email;

					$login_model->password = $_POST['account']['password'];

					

					$login_model->login();

					

					//update panel email

					$accountCp = AccountCp::model();

					$accountCp->accountCpEmailUpdate($account_model->id, $old_email);

					

					//send email to old address to inform them of the change

					$emailer = new Emails();

					$emailer->accountEmailChange($account_model, $old_email, 0);

					

					//set success flash and redirect

					Yii::app()->user->setFlash('success', '<i class="fa fa-check"></i> Your email address has been updated! Please use this address on your next login.');

					$this->redirect('index');

				}

				else {

					//failed to save, maybe error in input

					Yii::app()->user->setFlash('error', 'There was an error while saving your information, please check the messages below and try again.');

					$this->render('update_email', array('account_model' => $account_model));

				}

			}

			else {

				//failed auth, wrong password

				Yii::app()->user->setFlash('error', 'Your password was incorrect, please try again.');

				$this->render('update_email', array('login_model' => $auth_model));

			}

		}

		else {

			//nothing submitted yet, just rez the page

			$this->render('update_email');

		}

	}

if($this->scenario = ‘createAdmin’

should be

if($this->scenario == ‘createAdmin’

Derp, I can’t believe it took me all this time and effort to find that one mistake. Thank you so much Ronald!!!!

P.S. It works perfectly now <3