validationmoduleyii2captchasaving-data

Captcha field not validating on Yii2


I finally succeded to get the captcha widget working in the login form of in a Yii2 Users module, but in the register form the captcha field only validates correctly, when calling $user->validate(), but not when calling $user->save().

if ($user->load(Yii::$app->request->post()) && $user->validate()) /* $user->validate() succeeds. */
{
    $user->hash = Yii::$app->security->generatePasswordHash($user->password);
    $user->auth_key = Yii::$app->security->generateRandomString();

    if ($user->save()) /* $user->save() does not succeed. */
    {

The problem seems to be within the validate() method of the Model class, which returns false, after looping the CaptchaValidator:

public function validate($attributeNames = null, $clearErrors = true)
{
    ...
    foreach ($this->getActiveValidators() as $validator) {
        $validator->validateAttributes($this, $attributeNames);
    }
    $this->afterValidate();

    return !$this->hasErrors(); /* Returns false. */

Thanks


Solution

  • The problem is that you are validating your model twice. First time during the $user->validate() call in your if condition. The second time during the $user->save().

    When captcha is validated as valid, the stored code is regenerated. That's why second validation of same code will fail.

    Since your data are already validated there is no reason to validate them again during save. You can pass false as first argument to save() method to tell the model to skip validation.

    if ($user->load(Yii::$app->request->post()) && $user->validate())
    {
        $user->hash = Yii::$app->security->generatePasswordHash($user->password);
        $user->auth_key = Yii::$app->security->generateRandomString();
    
        if ($user->save(false))
        {