[SOLVED] how to remove extra validators ?

I added a dummy reset action in my current controller,




	public function actionReset()

	{

		$email = Yii::app()->request->getQuery('auth');

		$model = new Wsmembers;

		$result = $model->find('WSEmailAddress = :email', array(':email'=>$email));

//		var_dump($result);

		if($result == 1)

		{

			if(isset($_POST['Wsmembers']))

				{

					$model->attributes=$_POST['Wsmembers'];

					if($model->save())

						$this->redirect(array('view','id'=>$model->MemberShipID));

				}

			

			$this->render('updatepwd',array(

				'model'=>$model,

			));			 

		}



then at the updatepwd view, I have this




<h1>Update Password <?php echo $model->MemberShipID; ?></h1>

<div class="form">

<?php echo CHtml::beginForm(); ?>

<?php echo CHtml::errorSummary($model)?>


<div class="row">

	<?php echo CHtml::activeLabelEx($model,'WSLoginPassword'); ?>

	<?php echo CHtml::activeTextField($model,'WSLoginPassword',array('size'=>20,'maxlength'=>50)); ?>

	<?php echo CHtml::error($model,'WSLoginPassword'); ?>

</div>


<div class="row">

	<?php echo CHtml::activeLabelEx($model,'Retype Password'); ?>

	<?php echo CHtml::activePasswordField($model,'WSLoginPassword_repeat'); ?>

</div>


<div class="action">

<?php echo CHtml::submitButton('Update'); ?>

</div>


<?php echo CHtml::endForm(); ?>


</div>



now when I tried to input some wrong stuff at the form it also calls the other

field that does’t exist in my view, what I understand is, this is happening because

I instantiated my members model where all attributes are present that’s why even

the validators to the fields that doesn’t exist where also called

what should I do in order to not include those other validators for the fields

that aren’t present ?

You need to use a scenario. :)

For instance, this is a rule for my lost password scenario:


       	array('usernameoremail','required','on'=>'lostpass'),

Then you just do:


$model = new User;

if($model->validate('lostpass')) {

// get the real user and set the password here

$user->save();

}

I think.

Haven’t implemented that, actually.

Users are just given all their fields, for now.

You could also just use hidden fields, although I think it’s not (really) recommended.

Hi sasori,

Here is a good explanation on how to use and implement ‘scenarios’:

http://php-thoughts.cubedwater.com/2009/validation-scenarios/

Thanks to our programmer pal Jonahs

I tried, but it failed…or maybe I still did something wrong ?

here’s the rules




		return array(

			array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSMembershipSecretQuestion, WSMembershipSecretAnswer', 'required'),

			array('WSEmailAddress, WSLoginName' , 'unique'),

			array('WSLoginPassword','compare','compareAttribute' =>'WSLoginPassword_repeat'),

			array('WSLoginPassword_repeat, WSMembershipMySecretQuestion','safe'),

			array('WSLoginPassword','required','on' => 'reset'),

			array('WSLoginPassword','compare','compareAttribute'=>'WSLoginPassword_repeat','on' => 'reset'),



and here’s my controller




	public function actionReset()

	{

		$email = Yii::app()->request->getQuery('auth');

		$model = new Wsmembers;

		if($model->validate('reset'))

		{

			$result = $model->find('WSEmailAddress = :email', array(':email'=>$email));

			var_dump($result);

			if($result == 1)

			{

				if(isset($_POST['Wsmembers']))

					{

						$model->attributes=$_POST['Wsmembers'];

						if($model->save())

							$this->redirect(array('view','id'=>$model->MemberShipID));

					}

				

				$this->render('updatepass',array(

					'model'=>$model,

				));			 

			}

		}

	}



I also tried this




		return array(

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSLoginPassword_repeat, WSMembershipContactName, WSMembershipSecretQuestion, WSMembershipSecretAnswer, VerifyCode', 'required', 'on' => 'register'),

		array('WSLoginPassword','compare','compareAttribute' =>'WSLoginPassword_repeat','on'=>'register, reset'),

		array('WSEmailConfirmed, WSMembershipSecretQuestion, WSMembershipLoginAttempts, WSMembershipLockedOut, WSMembershipSystemLockedOut, IntroducingMemberID', 'numerical', 'integerOnly'=>true),

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSLoginNameAllUsers', 'length', 'max'=>50),

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSLoginNameAllUsers', 'length', 'max'=>50),

		array('WSLoginPasswordAllUsers', 'length', 'max'=>40),

		array('verifyCode', 'captcha', 'allowEmpty' => !extension_loaded('gd')),

		);






	public function actionReset()

	{

		$email = Yii::app()->request->getQuery('auth');

		$model = new Wsmembers;

		$result = $model->find('WSEmailAddress = :email', array(':email'=>$email));

	

		if($model->validate('reset'))

		{

			$model->save();

		}

				$this->render('updatepass',array(

					'model'=>$model,

				));		

	}



it removes the required “red asterisk symbol” at the registration area, when i tested registering, the validation doesn’t work.

same with the dummy reset action I created , what’s going on ?

Just to check - do you get the $email on every request?

You are using - $email = Yii::app()->request->getQuery(‘auth’);

So in the first link that is going to the reset function you obviously have the “auth” parameter set… but when the update form is displayed you don’t have that parameter… so on the next call to actionReset() $email is empty?

here’s my main problem

i don’t even have the captcha on the update password form and yet yii is trying to validate a non visible form :mellow:

model rule




		return array(

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSLoginPassword_repeat, WSMembershipContactName, WSMembershipSecretQuestion, WSMembershipSecretAnswer, VerifyCode', 'required', 'on' => 'register'),

		array('WSLoginPassword','compare','compareAttribute' =>'WSLoginPassword_repeat','on'=>'register, reset'),

		array('WSEmailConfirmed, WSMembershipSecretQuestion, WSMembershipLoginAttempts, WSMembershipLockedOut, WSMembershipSystemLockedOut, IntroducingMemberID', 'numerical', 'integerOnly'=>true),

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSLoginNameAllUsers', 'length', 'max'=>50),

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSLoginNameAllUsers', 'length', 'max'=>50),

		array('WSLoginPasswordAllUsers', 'length', 'max'=>40),

		array('verifyCode', 'captcha', 'allowEmpty' => !extension_loaded('gd')),

		);



controller




	public function actionReset()

	{

		$email = Yii::app()->request->getQuery('auth');

		$model = new Wsmembers;

		$result = $model->find('WSEmailAddress = :email', array(':email'=>$email));

		$model->setScenario('reset');

		if($model->validate())

		{

//			$model->save();

		}

				$this->render('update',array(

					'model'=>$model,

				));		

	}



update view form




<div class="form">

<?php echo CHtml::beginForm(); ?>

<?php echo CHtml::errorSummary($model)?>


<div class="row">

	<?php echo CHtml::activeLabelEx($model,'WSLoginPassword'); ?>

	<?php echo CHtml::activePasswordField($model,'WSLoginPassword',array('size'=>20,'maxlength'=>50)); ?>

	<?php echo CHtml::error($model,'WSLoginPassword'); ?>

</div>


<div class="row">

	<?php echo CHtml::activeLabelEx($model,'Retype Password'); ?>

	<?php echo CHtml::activePasswordField($model,'WSLoginPassword_repeat'); ?>

</div>


<div class="action">

<?php echo CHtml::submitButton('Update'); ?>

</div>


<?php echo CHtml::endForm(); ?>



can someone tell me what to do ? , I think i did followed this tutorial

Shouldn’t the verifyCode be in a ‘registration’ scenario?

I changed it to this




		return array(

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSMembershipSecretQuestion, WSMembershipSecretAnswer, verifyCode', 'required','on' => 'register'),

		array('WSLoginPassword','compare','compareAttribute' =>'WSLoginPassword_repeat'),

		array('WSLoginPassword_repeat','safe'),

		array('WSLoginPassword','required','on'=>'reset'),

		array('WSEmailConfirmed, WSMembershipSecretQuestion, WSMembershipLoginAttempts, WSMembershipLockedOut, WSMembershipSystemLockedOut, IntroducingMemberID', 'numerical', 'integerOnly'=>true),

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSLoginNameAllUsers', 'length', 'max'=>50),

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSLoginNameAllUsers', 'length', 'max'=>50),

		array('WSLoginPasswordAllUsers', 'length', 'max'=>40),

		array('verifyCode', 'captcha', 'allowEmpty' => !extension_loaded('gd')),

		);



and now i got this

also the password repeat validation doesn’t work :mellow:

I changed the rules again to this




		return array(

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSMembershipSecretQuestion, WSMembershipSecretAnswer, verifyCode', 'required','on' => 'register'),

		array('verifyCode', 'captcha', 'allowEmpty' => !extension_loaded('gd'),'on' => 'register'),

		array('WSLoginPassword','required','on'=>'reset'),

		array('WSLoginPassword','compare','compareAttribute' =>'WSLoginPassword_repeat','on'=>'register, reset'),

		array('WSLoginPassword_repeat','safe'),

		array('WSEmailConfirmed, WSMembershipSecretQuestion, WSMembershipLoginAttempts, WSMembershipLockedOut, WSMembershipSystemLockedOut, IntroducingMemberID', 'numerical', 'integerOnly'=>true),

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSLoginNameAllUsers', 'length', 'max'=>50),

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSLoginNameAllUsers', 'length', 'max'=>50),

		array('WSLoginPasswordAllUsers', 'length', 'max'=>40),

		

		);



and now i got this

am almost there, the re-type password isn’t working :mellow:

just put WSLoginPassword_repeat as required on reset like:




array('WSLoginPassword, WSLoginPassword_reset','required','on'=>'reset')



here’s what i did now based from what you said




		return array(

		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSMembershipSecretQuestion, WSMembershipSecretAnswer, verifyCode','required','on'=>'register'),

		array('verifyCode', 'captcha', 'allowEmpty' => !extension_loaded('gd')),

		array('WSLoginPassword, WSLoginPassword_repeat','required','on'=>'reset'),

		array('WSLoginPassword','compare','compareAttribute' =>'WSLoginPassword_repeat'),



but

I still don’t understand what’s happening…and also whenever I put the ‘on’ => ‘register’ scenario at the first line, the registration area/view loses it’s own

validation ( i mean the red asterisk icon thing )

Hi sasori,

I have checked your code and i am wondering if you have set your model attributes before validation.





public function actionReset()

{

              

$model = new Wsmembers;


if(isset($_POST['Wsmembers'])) // do not know if it is correct, check it!          

{   

   $model->attributes = $_POST['Wsmembers'];             

   $model->setScenario('reset');

   if($model->validate())

   {

      if($model->save()) 

       // redirect? YOU NEED TO DECIDE!

       $this->render('redirectionview', array('model'=>$model,));

   }

                

}

// is this to show the reset form? 

// 

$this->render('update',array('model'=>$model,));


.

.

.

}



Before my answer you had

[color="#000000"]array(‘verifyCode’, ‘captcha’, ‘allowEmpty’ => !extension_loaded(‘gd’),‘on’ => ‘register’),[/color][color="#000000"]

[/color]

then you removed the “on=>register”… that’s why you are getting the message “The verification code is incorect”…

ok I changed it back to this




		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSMembershipSecretQuestion, WSMembershipSecretAnswer, verifyCode','required','on' => 'register'),

		array('verifyCode', 'captcha', 'allowEmpty' => !extension_loaded('gd'), 'on' => 'register'),

		array('WSLoginPassword, WSLoginPassword_repeat','required','on'=>'reset'),

		array('WSLoginPassword','compare','compareAttribute' =>'WSLoginPassword_repeat'),



now, but as you can see, I added the on register scenario to this




		array('verifyCode', 'captcha', 'allowEmpty' => !extension_loaded('gd'), 'on' => 'register'),



and but i am wondering why the validators on my registration area gets disabled when I add the on register scenario at the first line (the red asterisk icon disappears ) ?




array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSMembershipSecretQuestion, WSMembershipSecretAnswer, verifyCode','required','on' => 'register'),



now i got two more problems

once I click the reset link, the update password page already has some input

and the validation error is already being called when I haven’t put anything yet

did I miss something again?

here’s my rules code




		array('WSEmailAddress, WSLoginName, WSLoginPassword, WSMembershipContactName, WSMembershipSecretQuestion, WSMembershipSecretAnswer, verifyCode','required','on'=>'register'),

		array('verifyCode', 'captcha', 'allowEmpty' => !extension_loaded('gd'),'on'=>'register'),

		array('WSLoginPassword','compare','compareAttribute' =>'WSLoginPassword_repeat'),

		array('WSLoginPassword','required','on' => 'reset'),

		array('WSLoginPassword_repeat','safe'),



here’s my controller code




	public function actionReset()

	{

		$model = new Wsmembers;

		$email = Yii::app()->request->getQuery('auth');

		$model->setScenario('reset');

		if(isset($_GET['auth']))

		{

		$model = Wsmembers::model()->find('WSEmailAddress = :email', array(":email"=>$email));	

		$model->WSLoginPassword = sha1($_POST['Wsmembers']['WSLoginPassword']);

		

				if($model->validate('reset'))

				{

					$model->save();

				}

		}

			$this->render('updatepass',array(

		'model'=>$model,

		));			

	}



plus, my code doesn’t save/update the particular row , why?

maybe you forgot:

$model->WSLoginPassword_repeat = $_POST[‘Wsmembers’][‘WSLoginPassword_repeat’];




array('WSEmailAddress,WSLoginName,  WSMembershipContactName, WSMembershipSecretQuestion, WSMembershipSecretAnswer, verifyCode','required','on'=>'register'),

array('verifyCode', 'captcha', 'allowEmpty' => !extension_loaded('gd'),'on'=>'register'),


array('WSLoginPassword','required','on' => 'reset,register'),

array('WSLoginPassword_repeat','required','on' => 'reset'),

array('WSLoginPassword','compare','compareAttribute' =>'WSLoginPassword_repeat'),



AR trying to set rules twice WSLoginPassword Tvice

try this code above

and you have to set couse you tryin to GET auth and you call POST VARIABLE you have to set eather POST other get and you have to post attributs2 password ? :)

couse yor model dont see password_reset field, you didint post it.

and you need to add only email fild withouth $model, yust CHtml::textField(‘email’,array()); and password filds with $model $form->textField($model,‘pass1’); $form->textField($model,‘pass2’); in password recovery view




public function actionReset()

{

$model = new Wsmembers('reset',array(

'criteria'=>array(

'condition'=>'email="'.$_POST['email'].' " ',

)


));





if($model)

{

$model->attributes= $_POST['Wsmembers']; 

if($model->validate)

{

$model->update();

}

}

$this->render('updatepass',array(

'model'=>$model,

));                     

  }






and make function beforeSave () in your model




$this->WSLoginPassword = sha($this->WSLoginPassword);



thanks for all of your help…

the row got updated when I added ‘false’




if($model->save(false))



As we noticed in the previous post, if you change the password to sha1 before save, the compare validator will prevent you to save.

That’s why you have to use save(false), in order to skip validation before save (it is not needed, you already checked the input before).