Update: Here is model file to download Download Code

CakePHP has many validation rules that can make model data validation much easier. There are 26 core validation rules. You can see here. These 26 rules almost covers all the validation. You can also add multiple validation to one field. But some time you need your own validation or you need to check a value dependent on other value then you need your own validation.

Lets build our scenario. We have a user table and we have user type table. There are two types of user one is admin and other is user i.e normal user. Now in user table we only save username only for admin. if we set validation notempty for username field then CakePHP will validate username even for normal user. This does not suit us. So we need custom validation. lets build our user model.

class User extends AppModel {
	var $name = 'User';
	var $validate = array(
		'name' => array(
			'notempty' => array(
				'rule' => array('notempty'),
				'message' => 'Please enter first name',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
	);
	//The Associations below have been created with all possible keys, those that are not needed can be removed

	var $belongsTo = array(
		'UserType' => array(
			'className' => 'UserType',
			'foreignKey' => 'user_type_id',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		)
	);
}

Here a added a not empty validation for name field and also we made HABTM relation with user_type table. lets add username field in model.

class User extends AppModel {
	var $name = 'User';
	var $validate = array(
		'name' => array(
			'notempty' => array(
				'rule' => array('notempty'),
				'message' => 'Please enter first name',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'username' => array(
			'custom' => array(
				'rule' => array('validateDependentFields'),
				'message' => 'Please enter height',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
	);
}

Now lets build our custom function validateDependentFields. This function will have a parameter which will have the field name. One import thing to remember is that we will have all the post data in $this->data in this function. Lets think user_type_id=1 is for admin and user_type_id=2 is user.

function validateDependentFields($field){
	$passed=true;
	switch(true){
		case array_key_exists('username',$field):
			if(  $this->data['User']['user_type_id']==1 and (!isset($this->data['User']['username']) or empty($this->data['User']['username'])) ){
				$passed=false;
			}else{
				$passed=true;
			}
		break;
	}
	return $passed;
}

This function will now check for the user type and then decide about the username field. You can check for other validation here. We can use this function for multiple fields.

function validateDependentFields($field){
	$passed=true;
	switch(true){
		case array_key_exists('username',$field):
			if(  $this->data['User']['user_type_id']==1 and (!isset($this->data['User']['username']) or empty($this->data['User']['username'])) ){
				$passed=false;
			}else{
				$passed=true;
			}
		break;
		case array_key_exists('class_of',$field):
			if(  $this->data['User']['user_type_id']==1 and (!isset($this->data['User']['class_of']) or empty($this->data['User']['class_of'])) ){
				$passed=false;
			}else{
				$passed=true;
			}
		break;
	}
	return $passed;
}

Easy, simple and highly customizable.