Validating fields with custom validateField() functions

Posted by Felix Geisendörfer, on Jan 27, 2006 - in PHP & CakePHP » DataSources, Models & Behaviors

Deprecated post

The authors of this post have marked it as deprecated. This means the information displayed is most likely outdated, inaccurate, boring or a combination of all three.

Policy: We never delete deprecated posts, but they are not listed in our categories or show up in the search anymore.

Comments: You can continue to leave comments on this post, but please consult Google or our search first if you want to get an answer ; ).

Update: Tobius has written up a very detailed tutorial concerning custom validation based on the idea presented here. It's definitly worth to have a look at it in the Wiki! But since it's not making use of generateFields() I'll present a solution with generateFields() including error messages here soon.

Yesterday tobius asked me if there was a way of validating the data to be saved in a model in a more individual manner then the current regex way can handle things. So since I didn't know when something like this will be available in CakePHP I offered to write a little function that would support a base for doing it.

All it does is to hook into the beforeSave() function and then looping through all fields passed to the model and then checks a a function named validateField($value) exists in the model and if yes only validates this field if it returns true. Field will alway be CamelBack for the actual field name in the db. so user_name would be validateUserName($value).

In order to use it putt a file called app_model.php inside of your app directory. This is the code to paste in:

php
  1. class AppModel extends Model
  2. {
  3.     function beforeSave()
  4.     {    
  5.         foreach ($this->data[$this->name] as $field => $value)
  6.         {                
  7.             $tryToCall = array(&$this, 'validate' . Inflector::camelize($field));
  8.            
  9.             if (is_callable($tryToCall))
  10.             {
  11.                 $result = call_user_func(array(&$this, $tryToCall[1]), $value);
  12.                
  13.                 if (!$result)
  14.                 {
  15.                     $this->validationErrors[$field] = 1;                        
  16.                 }
  17.             }
  18.         }          
  19.  
  20.        
  21.         if ($this->validationErrors)
  22.             return false;
  23.     }
  24. }

For anyone who wants to use this: This does not support custom error messages for the validated fields yet. If you need them I can get you on track about what to do for it. Just post in the comments ; ) ...

Associations: I've talked with PhpNut_ about the way associations will work with this and he said the correct way of saving association data is:

php
  1. $this->ModelA->save($this->params[’data’][’ModelA’]);
  2. $this->ModelB->save($this->params[’data’][’ModelB’]);

and not

php
  1. $this->ModelB->save($this->params[’data’]);

So as long as you follow that guidline this should work with just about any model setup. (In case I misunderstood him and this is wrong plz let me know!)

--Felix aka the_undefined