Captcha validation

Hi,

I must be missed something. Before adding a captcha, my register page works fine. After adding a captcha field, once I click submit, it always says username exists.

Here is my controller:




 /**

	 * Displays the register page

	 */

	public function actionRegister()

	{

		$model=new RegisterForm;


		// if it is ajax validation request

		if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}


		// collect user input data

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

		{

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

			// validate user input and redirect to the login page if valid

			if($model->validate() && $model->register()) {

                

				// display the login form

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

                

             }

		}

		// display the register form

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

	}



Here is the model:





class RegisterForm extends CFormModel

{

	public $username;

	public $password;

	public $password2;

    public $verifyCode;

    

	private $_identity;


	/**

	 * Declares the validation rules.

	 * The rules state that username and password are required,

	 * and password needs to be authenticated.

	 */

	public function rules()

	{

		return array(

			// username, password and passwords are required

			array('username, password, password2, verifyCode', 'required'),

			// password needs to match password2

			array('password, password2', 'match'),

            // username should be unique

			array('username', 'unique', 'skipOnError'=>true),

            // verifyCode needs to be entered correctly

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

		);

	}


	/**

	 * Declares customized attribute labels.

	 * If not declared here, an attribute would have a label that is

	 * the same as its name with the first letter in upper case.

	 */

	public function attributeLabels()

	{

		return array(

			'verifyCode'=>'Verification Code',

            'password2'=>'Re-type password',

		);

	}

	/**

	 * password and password2 should match.

	 * This is the 'match' validator as declared in rules().

	 */

	public function match($attribute,$params)

	{

		if ( $this->password != $this->password2 ) {

            $this->addError("password", 

                "Two passwords does not match.");

            $this->addError("password2", 

                "Two passwords does not match.");

            return false;

        } else {

            return true;

        }

	}

    

    /**

	 * password and password2 should match.

	 * This is the 'match' validator as declared in rules().

	 */

	public function unique($attribute,$params)

	{

			$this->_identity=new UserIdentity($this->username,$this->password);

			if ( !$this->_identity->register() )

                $this->addError("username", "Username exists, pick new one.");

           

	}


	/**

	 * Register the user using the given username and password in the model.

	 * @return boolean whether register is successful

	 */

	public function register()

	{

		if($this->_identity===null)

		{

			$this->_identity=new UserIdentity($this->username,$this->password);

			$this->_identity->register();

		}

		if($this->_identity->errorCode===UserIdentity::ERROR_NONE)

			return true;

		else

			return false;

	}

}




The UserIdentity class:




class UserIdentity extends CUserIdentity

{

	/**

	 * Authenticates a user.

	 * The example implementation makes sure if the username and password

	 * are both 'demo'.

	 * In practical applications, this should be changed to authenticate

	 * against some persistent user identity storage (e.g. database).

	 * @return boolean whether authentication succeeds.

	 */

    

	public function authenticate()

	{

        $sql = "select `password` from `user` where `username`='$this->username' ";

		$command=Yii::app()->db->createCommand($sql);

        $row=$command->queryRow();

        

        if ($row==false) 

            $this->errorCode=self::ERROR_USERNAME_INVALID;

		else if($row['password'] != md5($this->password))

			$this->errorCode=self::ERROR_PASSWORD_INVALID;

		else

			$this->errorCode=self::ERROR_NONE;

		return !$this->errorCode;

        

     }

     

     public function register()

	{

        $sql = "select username from user where `username`= '$this->username' ";

		$command=Yii::app()->db->createCommand($sql);

        $row=$command->queryRow();

        //print ("row is $row");

        if ($row!=false) 

            $this->errorCode=self::ERROR_USERNAME_INVALID;

		else {

            $sql = "insert into `user` (`username`, `password`) values

                    (:username, :password)";

            $command=Yii::app()->db->createCommand($sql);

            $command->bindParam(":username",$this->username,PDO::PARAM_STR);

            $command->bindParam(":password",md5($this->username),PDO::PARAM_STR);

            $command->execute();

			$this->errorCode=self::ERROR_NONE;

        }

		return !$this->errorCode;

        

     }

}



and last is the view class:




<?php

$this->pageTitle=Yii::app()->name . ' - Register';

$this->breadcrumbs=array(

	'Register',

);

?>




<h1>Login</h1>


<?php if(Yii::app()->user->hasFlash('register')): ?>


<div class="flash-success">

	<?php echo Yii::app()->user->getFlash('register'); ?>

</div>


<?php else: ?>


<p>Please fill out the following form to register a new user:</p>


<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'register-form',

	'enableAjaxValidation'=>true,

)); ?>


	<p class="note">Fields with <span class="required">*</span> are required.</p>


	<div class="row">

		<?php echo $form->labelEx($model,'username'); ?>

		<?php echo $form->textField($model,'username'); ?>

		<?php echo $form->error($model,'username'); ?>

        <p class="hint">

			Hint: You should use the same username as your email id.

		</p>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'password'); ?>

		<?php echo $form->passwordField($model,'password'); ?>

		<?php echo $form->error($model,'password'); ?>

		

	</div>

    

    <div class="row">

		<?php echo $form->labelEx($model,'password2'); ?>

		<?php echo $form->passwordField($model,'password2'); ?>

		<?php echo $form->error($model,'password2'); ?>	

	</div>

	

    <?php if(extension_loaded('gd')): ?>

	<div class="row">

		<?php echo $form->labelEx($model,'verifyCode'); ?>

		<div>

		<?php $this->widget('CCaptcha'); ?>

		<?php echo $form->textField($model,'verifyCode'); ?>

		</div>

		<div class="hint">Please enter the letters as they are shown in the image above.

		<br/>Letters are not case-sensitive.</div>

	</div>

	<?php endif; ?>


	<div class="row buttons">

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

	</div>


<?php $this->endWidget(); ?>

</div><!-- form -->


<?php endif; ?>



Anything wrong?

Thanks!

Found it. Called register twice in the validation. ::)