TuK
TuK

Reputation: 3556

Symfony validation handling

I have a form for changing passwords, it checks the password field for min_length and required. Then it compares the password field with the confirm field.

If I post to this form with less than the minimum required characters (and the password and confirm box match), it throws errors for min length (which is expected) and for password mismatch (unexpected).

Can anyone tell why?

<?php

class ChangeMyPasswordForm extends sfForm {

    const PASSWORD_MIN_LENGTH_MSG = "<li>We could not update your password because your password must be at least 8 characters long. Please choose a different password.</li>";
    const PASSWORD_MISMATCH_MSG   = "<li>We could not update your password because your passwords didn't match. Please try again.</li>";
    const PASSWORD_REQUIRED_MSG   = "<li>We could not update your password because your password was blank. Please enter a password.</li>";

    protected static $labels = array(
        'password' => 'Your Password',
        'confirm'  => 'Re-enter Password',
    );

    /**
     * Called in sfForm's constructor. 
     */
    public function configure()
    {   
        $this->setWidgets(array(
           'password'  => new sfWidgetFormInputPassword(array()),
             'confirm' => new sfWidgetFormInputPassword(array()),
        ));

        $this->setValidators(array(
            'password' => $this->_setPasswordValidator(),
                 'confirm' => new sfValidatorPass(),
        ));

        $this->mergePostValidator(
            new sfValidatorSchemaCompare('password', sfValidatorSchemaCompare::EQUAL, 
                'confirm', array(), array(
                    'invalid' => self::PASSWORD_MISMATCH_MSG,
                )
            )
        );

        $this->widgetSchema->setLabels(self::$labels);
    }

    /**
     * Returns validators for the password field. 
     * @return sfValidatorString 
     */
    private function _setPasswordValidator()
    {
        $v = new sfValidatorString();
        $v->setOption('min_length', 8);
        $v->setMessage('min_length', self::PASSWORD_MIN_LENGTH_MSG);
        $v->setMessage('required', self::PASSWORD_REQUIRED_MSG);

        return $v;
    }
}

edit: this may help => the view where I'm throwing errors

<?php if ($form->hasGlobalErrors() || $form->hasErrors()): ?>
<div class="error">
  <p class="bottom"><b>Oops!</b></p>
  <ul>
    <?php foreach ($form->getGlobalErrors() as $name => $error): ?>
        <?php echo $error ?>
    <?php endforeach; ?>

        <?php foreach ($form->getErrorSchema()->getErrors() as $error): ?>
      <?php echo $error; ?>
    <?php endforeach; ?>
  </ul>
</div>
<? endif; ?>

Upvotes: 1

Views: 429

Answers (2)

TuK
TuK

Reputation: 3556

Finally figured it out. It looks like sfValidatorSchemaCompare compares the entire widget, validators and all (not just the values that they return). So If I'm comparing two widgets, and they dont have the same validators (i.e. one min_length = 3 and the other's min_length = 6), it will fail.

Upvotes: 0

guiman
guiman

Reputation: 1334

The validation process takes place in two phaces: normal validators and post validatos, the first expected error comes from the normal phase of validation (each field). The other unexpected error comes from the post-validator.

When you bind a form with the request values, and as $form->isValid() all validators are processed (normal and post), so if there are errors in any of those (or in this case both), they will be stored in the field to be shown later.

Hope this is clear enough

Edited: sorry, my english is not great and also my mind so, here its something quite helpful (Symfony Forms in Action - Advanced Validaton). Anyway, the first time i read it, i didnt noticed the "both password mach" part so my answer isn't that accurate. Here is an example of widget configuration for registration form i have Symfony registration form widget configuration

Upvotes: 1

Related Questions