Password Confirmation

Hello,

I have the following function in users model:

    public function validation()
    {

      $this->validate(new EmailValidator(array(
        'field' => 'email',
        'message' => 'O campo Email não tem um endereço de email válido.'
      )));

       $this->validate(new Uniqueness(
            array(
                "field"   => "username",
                "message" => "O username já existe!"
            ))       
       );

       $this->validate(new Uniqueness(
            array(
                "field"   => "numero",
                "message" => "O numero já existe!"
            ))       
       );

       $this->validate(new Uniqueness(
            array(
                "field"   => "email",
                "message" => "O email já existe!"
            ))       
       );

       return $this->validationHasFailed() != true;

    }

I have 2 password fields to validate , password and confirm password, so can i use this function to validate the password / confirm password ?? how ??

thx!



82.2k

I think that use the models validation would not be useful here since the password confirmation is not a field in the table. You can use the validators in the Validator component or Form component to set up that validation:

https://github.com/phalcon/vokuro/blob/master/app/forms/SignUpForm.php#L64



4.0k
edited Jan '15

Thank you for a response here Phalcon. Maybe you could help come up with an idea to make the validation a bit more... Model Friendly, if you will.

I've been working on a REST api where there aren't any form components. Yes, we could add them. Pass all API data to the form component and continue that route, but it adds another unnecessary layer of management (form component filtering/validation followed by the database validation).

I do understand that at the ORM level, this would not compare to values in the database, but instead another property in the current object. So as to why it is not part of the Model Validator, I do understand, to a point.

Here is part of the class to show how we envisioned this working.

<?php

use Phalcon\Mvc\Model\Validator\Uniqueness,
    Phalcon\Mvc\Model\Validator\Email,
    Phalcon\Mvc\Model\Validator\StringLength;

class Users extends \Phalcon\Mvc\Model {
    ...
    protected $email_address;
    protected $password;
    protected $confirm_password;
    ...
    public function setEmailAddress($email_address)
    {
        $this->email_address = $email_address;
        return $this;
    }

    public function setPassword($password)
    {
        $this->password = $password;

        return $this;
    }
    public function setConfirmPassword($confirm_password)
    {
        $this->confirm_password = $confirm_password;

        return $this;
    }

    // Getters here
    ...

    // Column Mapping - Does not include confirm_password
    public function columnMap()
    {
        return array(
            'email_address' => 'email_address',
            'password' => 'password',
        );
    }

    public function validation(){
        $this->validate(new \Phalcon\Mvc\Model\Confirmation([
            'field' => 'password',

            'with' => 'confirm_password',
            ... or ...
            'with_value' => $this->getConfirmPassword(),
            'message' => 'Password\'s do not match'
        ]));    

        return !$this->validationHasFailed();
    }

}

The other way we've looked into doing this is to use beforeValidationOnUpdate/beforeValidationOnCreate. This just feels like a hack for something that should be much more simple.

    public function beforeValidationOnCreate(){
        $confirm_data = [
            'password' => $this->getPassword(),
            'confirm_password' => $this->getConfirmPassword()
        ];

        $validator = new Phalcon\Validation();
        $validator->add('password', new \Phalcon\Validation\Validator\Confirmation(array(
            'message' => 'Password doesn\'t match confirmation',
            'with' => 'confirm_password'
        )));

        $messages = $validator->validate($confirm_data);
        if (count($messages)) {
            foreach ($messages as $message) {
                $model_message = new Phalcon\Mvc\Model\Message(
                    $message->getMessage(),
                    'password',
                    'ConfirmPassword'
                );
                $this->appendMessage($model_message);
            }
            return false;
        }
    }

The above method does work, but again, it doesn't feel right.

    public function validation(){
        $this->validate(new \Phalcon\Mvc\Model\Confirmation([
            'field' => 'password',

            'with' => 'confirm_password',
            ... or ...
            'with_value' => $this->getConfirmPassword(),
            'message' => 'Password\'s do not match'
        ]));    

        return !$this->validationHasFailed();
    }

This method feels much more "natural" if you will, versus the beforeValidationOn[Create/Update] method above.

Hi,

Just wondering if you ever figured this out?