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!