Yii2: compare validation of password and repassword

Boolean_Type picture Boolean_Type · Jul 30, 2015 · Viewed 10.7k times · Source

I'm a beginner of Yii, that's why can't figure out, what's wrong. I use the same model - Users - for login, registration and edition profile.

Users model:

class Users extends \yii\db\ActiveRecord {
    public $password_repeat; //have no this value in DB, that's why write it as property directly. Need only for profile editing

    public function rules() {
        return [
            [['username', 'password', 'authKey', 'accessToken'], 'safe'],
            [['username', 'password'], 'required'],
            [['username', 'password', 'authKey', 'accessToken'], 'string', 'max' => 255],
            [['is_admin'], 'boolean'],

//don't use scenarios() here. Use 'on' instead 
            ['password_repeat', 'required', 'on' => 'update'],
            ['password_repeat', 'compare', 'compareAttribute'=>'password', 'message'=>"Passwords don't match", 'on' => 'update' ],        
        ];
    }
}

view snippet:

<?php $form = ActiveForm::begin([
    'id' => 'data-form',
    'options' => ['class' => 'form-horizontal', 'enctype' => 'multipart/form-data'],
    'fieldConfig' => [
        'template' => "{label}\n<div class=\"col-lg-3\">{input}</div>\n<div class=\"col-lg-6\">{error}</div>",
        'labelOptions' => ['class' => 'col-lg-1 control-label'],
    ],
]); ?>

<?= $form->field($user_data, 'username') ?>

<?= $form->field($logo_data, 'imageFile')->fileInput() ?>

 <?= $form->field($user_data, 'password')->passwordInput(['value'=>''])?>
 <?= $form->field($user_data, 'password_repeat')->passwordInput(['value'=>''])?>

 <?= Html::submitButton('Zapisz', ['class' => 'btn btn-primary btn-block', 'name' => 'data-button']) ?>

<?php ActiveForm::end(); ?>

Site controller action:

public function actionProfile(){
    //3 model instances to retrieve data from users && company_profiles and logo
    $user_data = Users::find()->where(['id'=>Yii::$app->user->id])->one();
    $company_profile_data = CompanyProfiles::find()->where(['user_id'=>Yii::$app->user->id])->one();
    $logo_data = new UploadLogo();

    //here I upload file through $logo_data

    if (isset($_POST['Users'])){
        $user_data->username = $_POST['Users']['username'];
        $company_profile_data->firm_data = $_POST['CompanyProfiles']['firm_data'];
        //other assignments

        $user_data->scenario = 'update'; //specially for 'profile' page           

        if (($_POST[Users][password] !== '') && ($_POST[Users][password_repeat]) !== '' && ($_POST[Users][password] == $_POST[Users][password_repeat]))
           $user_data->password_repeat = $user_data->password = md5($_POST[Users][password]); //MAYBE, problem is here?

        $user_data->update();
        $company_profile_data->update();
    }

    return $this->render('profile', ['user_data' => $user_data, 'company_profile_data' => $company_profile_data, 'logo_data' => $logo_data]);
}

I use update scenario for profile editing page. During this scenario password_repeat is required and need to be the same as password. But it doesn't work as expected. A: When i try to submit form without entered password AND repass, I see message "can't be blank" only for password. Then I put value in ONLY pass input, and page reloads (DB table doesn't changes), and after reloading I see message "can't be blank" this time for repass field! But the most strange is that before next page reloading everything work normal. After reloading goto A; :) If I delete scenario, everything is ok with validation. But I can't delete it, cause in this case registration fails (repass field becomes required to fill).

So, what need I to do my with pass-repass functionality to work it fine (with scenario 'update')? Where is mistake?

Answer

Boolean_Type picture Boolean_Type · Jul 31, 2015

Got it! I just need to move this codeline:

$user_data->scenario = 'update';

from IF stmt. And now I want to make a habit to assign scenario property directly under creating model instance.