We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

model validation when dynamic updating

<?php

class User extends \Phalcon\Mvc\Model
{

    protected $id;
    protected $name;
    protected $email;
    protected $mobile;
    protected $password;

    public function initialize()
    {
        $this->useDynamicUpdate(true);
    }

    public function validation()
    {
        $this->validate(new Email(array(
            "field" => "email",
            "message" => "The email is invalid"
        )));
        $this->validate(new Uniqueness(array(
            "field" => "email",
            "message" => "The email must be unique"
        )));
        return $this->validationHasFailed() != true;
    }
     ...................

}
$record = User::findFirst(1);
$record->setMobile('13507083599');
if ($record->update() == false) {
    foreach ($record->getMessages() as $message) {
        echo $message, "\n";
    }
} else {
    echo "update ok";
}

when I only update the mobile field, the email field validation is also excecuted, any solution for validating dynamic update fields?

I try to move the validation to the setter method, but the result is not right.

public function setEmail($email)
 {
        $this->validate(new Email(array(
            "field" => "email",
            "message" => "The email is invalid"
        )));
        $this->validate(new Uniqueness(array(
            "field" => "email",
            "message" => "The email must be unique"
        )));
        if ($this->validationHasFailed()) {
            foreach ($this->getMessages() as $message) {
                throw new \Exception($message);
            }
            return false;
        }

        $this->email = $email;
        return $this;
    }


17.5k

If it's in your validation, it's going to get executed. My suggestion would be to move the validation to beforeCreate so it's only fired on creation. Still, it shouldn't be an issue if you're saving the user object and the user has a valid email address to begin with. Something like this, maybe:

public function beforeCreate() {
        $validation = new Validation();
        $validation->add('email',new Email([
            "message" => "Email address is invalid."
        ]));
        $messages = $validation->validate(["email"=>$email]);
        return count($messages) == 0;
}
edited Jun '15

thanks for your reply, but your solution is not so perfect, the fields in the user object may be null.

for example, registering by steps:

step 1: create account with name and password

step 2: if user want login with email, send a mail to confirm the email

step 3: if user want login with mobile number, send a sms to confirm the mobile

is there any api method to get what fields are updating, if so I can handle the validations by condition.

If it's in your validation, it's going to get executed. My suggestion would be to move the validation to beforeCreate so it's only fired on creation. Still, it shouldn't be an issue if you're saving the user object and the user has a valid email address to begin with. Something like this, maybe:

public function beforeCreate() {
       $validation = new Validation();
       $validation->add('email',new Email([
           "message" => "Email address is invalid."
       ]));
       $messages = $validation->validate(["email"=>$email]);
       return count($messages) == 0;
}


17.5k

Why not capture the name, number, and password on create and do the validations once?

assume user object has 10 required fields, filling these fields once may make user give up.

Why not capture the name, number, and password on create and do the validations once?



17.5k

If the fields are required, they must be filled in.

If you have 10 fields and only two or three are required on create then validate those two or three fields on create and add a skipAttributesOnCreate array to your model.

I'm not at my computer to post code samples, but you could then add a beforeUpdate function that conditionally checks for null values of the fields that are not required. If (!empty($var)) { validate field }