4.1.5.2 Adding your own Validation Methods
Sometimes checking data with regular expression patterns is not enough. For example, if you want to ensure that a promotional code can only be used 25 times, you need to add your own validation function, as shown below:
<?php
class User extends AppModel {
var $name = 'User';
var $validate = array(
'promotion_code' => array(
'rule' => array('limitDuplicates', 25),
'message' => 'This code has been used too many times.'
)
);
function limitDuplicates($check, $limit){
//$check will have value: array('promomotion_code' => 'some-value')
//$limit will have value: 25
$existing_promo_count = $this->find( 'count', array('conditions' => $check, 'recursive' => -1) );
return $existing_promo_count < $limit;
}
}
?>
<?phpclass User extends AppModel {var $name = 'User';var $validate = array('promotion_code' => array('rule' => array('limitDuplicates', 25),'message' => 'This code has been used too many times.'));function limitDuplicates($check, $limit){//$check will have value: array('promomotion_code' => 'some-value')//$limit will have value: 25$existing_promo_count = $this->find( 'count', array('conditions' => $check, 'recursive' => -1) );return $existing_promo_count < $limit;}}?>
The current field to be validated is passed into the function as first parameter as an associated array with field name as key and posted data as value.
If you want to pass extra parameters to your validation function, add elements onto the ‘rule’ array, and handle them as extra params (after the main $check param) in your function.
Your validation function can be in the model (as in the example above), or in a behavior that the model implements. This includes mapped methods.
Model/behavior methods are checked first, before looking for a method on the Validation class. This means that you can override existing validation methods (such as alphaNumeric()) at an application level (by adding the method to AppModel), or at model level.
When writing a validation rule which can be used by multiple fields, take care to extract the field value from the $check array. The $check array is passed with the form field name as its key and the field value as its value. The full record being validated is stored in $this->data member variable.
<?php
class Post extends AppModel {
var $name = 'Post';
var $validate = array(
'slug' => array(
'rule' => 'alphaNumericDashUnderscore',
'message' => 'Slug can only be letters, numbers, dash and underscore'
)
);
function alphaNumericDashUnderscore($check) {
// $data array is passed using the form field name as the key
// have to extract the value to make the function generic
$value = array_values($check);
$value = $value[0];
return preg_match('|^[0-9a-zA-Z_-]*$|', $value);
}
}
?>
<?phpclass Post extends AppModel {var $name = 'Post';var $validate = array('slug' => array('rule' => 'alphaNumericDashUnderscore','message' => 'Slug can only be letters, numbers, dash and underscore'));function alphaNumericDashUnderscore($check) {// $data array is passed using the form field name as the key// have to extract the value to make the function generic$value = array_values($check);$value = $value[0];return preg_match('|^[0-9a-zA-Z_-]*$|', $value);}}?>
