0

I am trying to setup Model validation on one field that only need to be checked if another field equals a particular value.

My first field is query which is a dropdown with many values, one value is 'Other' if this is selected then I need the second field 'query_other' to not be empty.

I have this setup in my Item Model:

public $validate = array(
   'query' => array(
        'notempty' => array(
            'rule' => array('notempty'),
            'message' => 'THE QUERY IS REQUIRED',
            //'allowEmpty' => false,
            //'required' => false,
            //'last' => false, // Stop validation after this rule
            //'on' => 'create', // Limit validation to 'create' or 'update' operations
        ),
    ),
    'query_other' => array(
        'notempty' => array(
            'rule' => array('if_query_other', 'query'),
            'message' => 'REASON IS REQUIRED',
            //'allowEmpty' => false,
            //'required' => false,
            //'last' => false, // Stop validation after this rule
            //'on' => 'create', // Limit validation to 'create' or 'update' operations
        ),
    ),
);

I then have this custom function which is being called above.

 function if_query_other(&$data, $check, $query_field) {

    if($this->data[$this->name][$query_field] == 'Other' && $check == NULL)
    {
        return false;
    }
    else
    {
        return true;
    }
  }

It's not working, I am currently getting this error: Parameter 1 to Item::if_query_other() expected to be a reference, value given

CakePHP Version 2.3.6

Thanks

sluggerdog
  • 843
  • 4
  • 12
  • 35
  • Where is the validation function located, in the model itself, or in a behaviour? Also you should always mention your exact CakePHP version! – ndm Aug 12 '13 at 00:46
  • Thanks, the validation is within the Item Model, I am using cakePHp version 2.3.6. – sluggerdog Aug 12 '13 at 00:50

1 Answers1

2

The error message is pretty clear, parameter 1 is passed by value, not by reference as your method signature requires. There is nothing to be passed by reference to a custom validation method, so simply remove the &, respectively remove the first parameter from the signature altogether.

The first parameter passed to a custom validation method will always be the data of the field to validate (in key => value format), followed by possible parameters defined in the rule array, like for example your fieldname. So $check would have never been null unless you would have defined null in the rule array, ie 'rule' => array('if_query_other', null), consequently your third parameter would have never been the fieldname.

Long story short, you need to define two parameters only, the first will contain the data of the field to validate, the second one the additional value defined in the rule array.

Here's an example, it checks whether the field passed in $query_field exists and whether its value equals Other, if it does it returns whether the value of the current field is not empty (I'm assuming the built-in Validation::notEmpty() is sufficient enough for your "not empty" check needs). If the value of the $query_field field doesn't equal Other, then this rule will always validate successfully, ie the value then isn't required to be not empty.

...

App::uses('Hash', 'Utility');
App::uses('Validation', 'Utility');

class Item extends AppModel
{
    ...

    public function if_query_other($check, $query_field)
    {
        if(Hash::get($this->data[$this->alias], $query_field) === 'Other')
        {
            return Validation::notEmpty(current($check));
        }

        return true;
    }
}
ndm
  • 59,784
  • 9
  • 71
  • 110
  • Great thanks, it doesn't seem to be kicking in however so I wonder am I calling it correctly (as above?) I don't get any errors now though but if the field is empty is still goes though. – sluggerdog Aug 12 '13 at 22:36
  • I've tested it with your exact validation rules, and it works as expected for me, if `query` is `Other` and `query_other` is empty, it throws an error. After reading your question again I've noticed that you mentioned `other` as well as `Other`, so make sure that you are using the correctly cased comparison value. Other than that it's pretty hard to tell what might be wrong in your setup, you'll have to do some debugging, check whether `if_query_other` is actually invoked, check the contents of the passed values, the result of `Hash::get` and `Validation::notEmpty`, etc... – ndm Aug 12 '13 at 23:27
  • Thanks, I'm wondering if my $validate rule above is calling your function incorrectly? – sluggerdog Aug 13 '13 at 00:42
  • No, it's fine (tough the rule for `query` should be `noEmpty`, with a capital `E`, however since methods in PHP are case insensitive this shouldn't matter and would lead to other error messages if it would), as I said, I've use those exact rules and it works: http://ge.tt/7Upw5ko/v/0 – ndm Aug 13 '13 at 01:10
  • OK Great thanks, it must be something else causing issues. Thanks again for your help. – sluggerdog Aug 13 '13 at 01:41