brndnmg
brndnmg

Reputation: 257

at least one field must be filled, cakephp validation

I have 4 optional fields, but at least 1 field (any field) must be filled?

any easy way to do this?

Upvotes: 1

Views: 2883

Answers (2)

deceze
deceze

Reputation: 521995

A custom validation rule is the way to go!

var $validate = array(
    'myField1' => array('atLeastOne'),
    'myField2' => array('atLeastOne'),
    'myField3' => array('atLeastOne'),
    'myField4' => array('atLeastOne')
);

function atLeastOne($data) {
    return !empty($this->data[$this->name]['myField1'])
           || !empty($this->data[$this->name]['myField2'])
           || !empty($this->data[$this->name]['myField3'])
           || !empty($this->data[$this->name]['myField4']);
}

You could also pass in extra parameters of all the fields you want to compare and make a more general function out of it.

var $validate = array(
    'myField1' => array('atLeastOne', 'myField2', 'myField3', 'myField4'),
    ...
);

// just pulled out of thin air (i.e. untested)
function atLeastOne($data) {
    $args = func_get_args();  // will contain $data, 'myField2', 'myField3', ...

    foreach ($args as $name) {
        if (is_array($name)) {
            $name = current(array_keys($name));
        }
        if (!empty($this->data[$this->name][$name])) {
            return true;
        }
    }

    return false;
}

Upvotes: 6

brettkelly
brettkelly

Reputation: 28205

You're probably going to need to implement the validation manually using the beforeValidate() callback. Example (in your model, which we'll call Item):

function beforeValidate(){
    $valid = false;
    if(!empty($this->data['Item']['foo'])){
        $valid = true;
    }
    // do that same thing for the other three fields, setting $valid to true if any of the fields has a value.
    return $valid && parent::beforeValidate(); 
}

You could also do one long comparison assignment like this, but I find this type of crap really hard to read:

function beforeValidate(){
    $valid = !empty($this->data['Item']['foo']) || !empty($this->data['Item']['bar']) || !empty($this->data['Item']['baz']) || !empty($this->data['Item']['bling'])
    return $valid && parent::beforeValidate(); 
}

Good luck!

Upvotes: 0

Related Questions