Erro Validation Password

Hello friends

I´m trying using the password validantion and I had a error, I´m using this sample:

http://www.yiiframework.com/wiki/277/model-password-confirmation-field

I received this error:

Property "User.repeat_password" is not defined.

Why this error?

This is my model:




public function rules()

	{

		return array(

                        array('password, repeat_password', 'required', 'on'=>'insert'),

			array('email,user,name', 'required'),

                        array('email', 'email'),

			array('passeord,repeat_password', 'length', 'max'=>250),

			array('user, name', 'length', 'max'=>50),

			array('email', 'length', 'max'=>250),

                        array('password', 'compare', 'compareAttribute'=>'repeat_password'),

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

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

			array('password, user, name, email', 'safe', 'on'=>'search'),

		);

	}



This is my form:




 <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,'repeat_password'); ?>

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

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

    </div>



This is my controller:




 public function actionInsert(){

        $model = new Users;

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

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

            $model->senha = $this->getHashPassword($_POST['Users']['password']);

            if($model->save()){ $this->redirect(array('index')); }

        }

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

    }



What’s the full trace of the error?

this is the full error:

Property "User.repeat_password" is not defined.

C:\wamp\www\yii\framework\db\ar\CActiveRecord.php(161)

149 * PHP setter magic method.

150 * This method is overridden so that AR attributes can be accessed like properties.

151 * @param string $name property name

152 * @param mixed $value property value

153 */

154 public function __set($name,$value)

155 {

156 if($this->setAttribute($name,$value)===false)

157 {

158 if(isset($this->getMetaData()->relations[$name]))

159 $this->_related[$name]=$value;

160 else

161 parent::__set($name,$value);

162 }

163 }

164

165 /**

166 * Checks if a property value is null.

167 * This method overrides the parent implementation by checking

168 * if the named attribute is null or not.

169 * @param string $name the property name or the event name

170 * @return boolean whether the property value is null

171 */

172 public function __isset($name)

173 {

Stack Trace

#0

C:\wamp\www\yii\framework\db\ar\CActiveRecord.php(161): CComponent->__set("repeat_password", "")

#1

C:\wamp\www\yii\framework\base\CModel.php(472): CActiveRecord->__set("repeat_password", "")

#2

C:\wamp\www\yii\framework\base\CComponent.php(152): CModel->setAttributes(array("nome" => "", "email" => "", "usuario" => "", "password" => "", …))

#3

C:\wamp\www\yii\framework\db\ar\CActiveRecord.php(161): CComponent->__set("attributes", array("nome" => "", "email" => "", "usuario" => "", "password" => "", …))

#4

C:\wamp\www\new_gestao\trunk\protected\controllers\UsuariosController.php(31): CActiveRecord->__set("attributes", array("nome" => "", "email" => "", "usuario" => "", "password" => "", …))

26 $this->render(‘index’);

27 }

28 public function actionCadastro(){

29 $model = new Usuarios;

30 if(isset($_POST[‘Usuarios’])){

31 $model->attributes=$_POST[‘Usuarios’];

32 $model->password = $this->getHashPassword($_POST[‘Usuarios’][‘password’]);

33 if($model->save()){ $this->redirect(array(‘index’)); }

34 }

35 $this->render(‘cadastro’, array(‘model’=>$model));

36 }

#5

C:\wamp\www\yii\framework\web\actions\CInlineAction.php(49): UsuariosController->actionCadastro()

#6

C:\wamp\www\yii\framework\web\CController.php(308): CInlineAction->runWithParams(array("r" => "usuarios/cadastro"))

#7

C:\wamp\www\yii\framework\web\filters\CFilterChain.php(133): CController->runAction(CInlineAction)

#8

C:\wamp\www\yii\framework\web\filters\CFilter.php(40): CFilterChain->run()

#9

C:\wamp\www\yii\framework\web\CController.php(1145): CFilter->filter(CFilterChain)

#10

C:\wamp\www\yii\framework\web\filters\CInlineFilter.php(58): CController->filterAccessControl(CFilterChain)

#11

C:\wamp\www\yii\framework\web\filters\CFilterChain.php(130): CInlineFilter->filter(CFilterChain)

#12

C:\wamp\www\yii\framework\web\CController.php(291): CFilterChain->run()

#13

C:\wamp\www\yii\framework\web\CController.php(265): CController->runActionWithFilters(CInlineAction, array("accessControl"))

#14

C:\wamp\www\yii\framework\web\CWebApplication.php(282): CController->run("cadastro")

#15

C:\wamp\www\yii\framework\web\CWebApplication.php(141): CWebApplication->runController("usuarios/cadastro")

#16

C:\wamp\www\yii\framework\base\CApplication.php(184): CWebApplication->processRequest()

#17

C:\wamp\www\new_gestao\trunk\index.php(13): CApplication->run()

08 defined(‘YII_DEBUG’) or define(‘YII_DEBUG’,true);

09 // specify how many levels of call stack should be shown in each log message

10 defined(‘YII_TRACE_LEVEL’) or define(‘YII_TRACE_LEVEL’,3);

11

12 require_once($yii);

13 Yii::createWebApplication($config)->run();

what do you see when you put


 print_r($model->attributes);

 exit;

after


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

?

Regards.

Nothing, I see only the error menssenger.

whether I don’t put the repeat_password, The application run and I see

Array ( [username] => bb [name] => aa [email] => aa@aa.com [password] => 123456 [nivel] => auxiliar [id] => )

And you have included


public $repeat_password;

at the top of your User class?

thank you for help.

I did not put this line. After I fix this line in my code when I send informations, I receive this return on form validation:

Password must be repeated exactly.

If I put this line:

print_r($model->attributes);

I see:

Array ( [username] => bb [name] => aa [email] => aa@aa.com [password] => 123456 [nivel] => auxiliar [id] => )

The field repeat_password don’t be on array.

I type exactly password in both fields. Whats wrong? Where I return a confirmation about password?

The $repeat_password should not appear in the $model->attributes array. You are not storing it to the data base are you? It should be just a temporary holder to do a comparison on. Where is your $model->validate() happening? I think the issue will be that your password is being hashed before the compare is being done to $repeat_password. So it is trying to compare a password like "password123" to something like "$2a$10$RblB0RCDMa7f4FXA9ptXWeHfIgxx3HNaZhk3Is26lPkdSJQVeKjxa" which will obviously not match.

Edit: Yeah, it looks like you hash the password before validation happens. What if you change your controller to something like


public function actionInsert(){

        $model = new Users;

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

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

            if($model->validate) {

                $model->senha = $this->getHashPassword($_POST['Users']['password']);

                if($model->save()){ $this->redirect(array('index')); }

            }

        }

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

    }

Thank you for help.

I type wrong, I type this:

$model->attributes

But the correct is:

print_r($_POST[‘Usuarios’]);

The problem was hash:

$model->password = $this->getHashPasseord($_POST[‘Users’][‘password’]);

This is the function:

protected function getHashPassword($password)

    {


        &#036;hash = CPasswordHelper::hashPassword(&#036;password);


        return &#036;hash;


    }

So repeat_password ever be for example "pass123", but password is for example $2a$13$kA2Va0.9.l5s7mqU4Qi1l.RMCvPDW66szlYZxUJ3Q8tp/iHoB8IcO

To solve the problem I create a $initialPassword:

Model:




 public $repeat_password;

 

    public $initialPassword;


public function rules()

    {

        return array(

            //password and repeat password

            array('password, repeat_password,initialPassword ', 'required', 'on'=>'insert'),

            array('password, repeat_password, initialPassword', 'length', 'min'=>6, 'max'=>40),

            array('initialPassword', 'compare', 'compareAttribute'=>'repeat_password'),

 

        );

    }



Controller:




public function actionInclude(){

        $model = new Users;

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

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

            $model->senha = $this->getHashPassword($_POST['Users']['password']);

            $model->initialPassword = $_POST['Users']['password'];

            if($model->save()){ $this->redirect(array('index')); }

        }

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

    }




What Do You think?