Writing custom validation rules

Published on and tagged with cakephp  model  validation

Sometimes the built-in validation rules are not flexible enough for your specific validation needs, and so you have to write your own validation rules. Fortunately, that’s quite easy.

First, you have to write a method in your model which does the validation. The method must accept at least one parameter (for the value which should be validated). If the data is valid, the method must return true. In the other case it has to return false. Such a method could look like:

public function validateNotEmpty($value) {
    if (trim($value[key($value)]) == '') {
        return false;
    } else {
        return true;

One thing you have to notice is that $value is an array containing one key/value pair (in pre-beta releases it has been a single value). The key is the name of the field you validate, and the value contains what the user entered (and hence what you want to validate).

In the next, and last, step, we have to define that we want to use the method we just wrote to validate a certain field. This is done in the same way as with the built-in validation rules, the only difference is that we have to use the method name as rule name:

public $validate = array('name' => array('rule' => 'validateNotEmpty'));

You can also write validation rules with additional parameters. Let’s say you want to write a validation rule which validates whether a string contains a certain character. The validation method for this purpose may look like:

public function validateContainsChar($value, $char) {
    return (strpos($value[key($value)], $char) !== false);

Now, if we want to ensure that the value of the “name” field contains an “x”, then the $validate array is:

public $validate = array('name' => array('rule' => array('validateContainsChar', 'x')));

That’s it, happy validating!

2 comments baked

  • JohnP

    How would you write a custom validation that looks at more than one value in the model? For example if your model has the following:

    And you wanted to write a validation to ensure (for example) users with the role of “ACADEMIC” had an email address that ended in “.edu”. As far as I can tell, the custom validations only pass in the field being tested.

  • cakebaker

    @John: You could use the ConditionalValidation behavior for this purpose. Or you could do the validation manually in the beforeValidate() method of your model.

    Hope that help!

© daniel hofstetter. Licensed under a Creative Commons License