views:

82

answers:

1

I have a bunch of name/email fields in my form like this:

data[Friend][0][name]
data[Friend][1][name]
data[Friend][2][name]

etc.

and

data[Friend][0][email]
data[Friend][1][email]
data[Friend][2][email]

etc.

I have a custom validation rule on each one that checks to see if the corresponding field is filled in. Ie. if data[Friend][2][name] then data[Friend][2][email] MUST be filled in.

FYI, heres what one of the two rules look like:

My form validation rule: ( I have an email validation too but that's irrelevant here)

'name' => array(
    'checkEmail' => array(
      'rule' => 'hasEmail',
      'message' => 'You must fill in the name field',
      'last' => true
    )
)

My custom rule code:

function hasEmail($data){
  $name = array_values($data);
  $name = $name[0]; 
  if(strlen($name) == 0){
    return empty($this->data['Friend']['email']);
  }
  return true;
}

I need to make it so that one of the pairs should be filled in as a minimum. It can be any as long as the indexes correspond.

I can't figure a way, as if I set the form rule to be required or allowEmpty false, it fails on ALL empty fields. How can I check for the existence of 1 pair and if present, carry on?

Also, I need to strip out all of the remaining empty [Friend] fields, so my saveAll() doesn't save a load of empty rows, but I think I can handle that part using extract in my controller. The main problem is this validation. Thanks.

+1  A: 

I would have a look at the Model::beforeValidate callback (API).

Using this callback to output debug information should help you figure out how many times it fires and what data is available to the model on each call.

With this information, you could then create a flag when you find your first matching pair, and tamper with either the Model::validates array or the Model::data array to bypass subsequent validation attempts.

As for your last point, you may be able to use Set::filter to easily remove blank fields from your data set.

deizel