All About Validation in CakePHP 1.2

3 07 2007

Validation in v1.1 of CakePHP was quite simple, and many found it lacking in features and flexibility. This is evidenced by the number of alternatives that people have written such as Daniel Hofstetter, Evan Sagge and Adeel Khan’s ruby-esque approach.

However in CakePHP 1.2 there has been a major rework of the Validation class’s inner workings, and the way Model::invalidFields() works.

The New $validate

The new $validate can take a number of different constructs now. There are 3 ways to define your validation rules and you can mix and match as needed.

Construct 1: CakePHP 1.1 way
The old CakePHP 1.1 $validate construct will still work

var $validate = array('fieldName' => 'ruleName')

Construct 2: Single Rule per field
You can now define more complex rules using the following construct. (Parameters explained later)

var $validate = array(
  'fieldName' => array(
    'rule' => 'ruleName' // or 'rule' => array('ruleName',  'param1', 'param2' ...)
    'required' => true,'allowEmpty' => false,
    'on' => 'create', // or update
    'message' => 'Your Error Message'
    )
  );

Constrct 3: Multiple Rules per field
Similar to Construct 2, however you can define multiple validation rules for a single field.

var $validate = array(
  'fieldName' => array(
    'rule_index' => array(
      'rule' => 'ruleName' // or 'rule' => array('ruleName',  'param1', 'param2' ...)
      'required' => true,'allowEmpty' => false,
      'on' => 'create', // or update
      'message' => 'Your Error Message'
      )
    )
  );

The new Parameters

The new $validate supports a number of parameters. The only required parameter is ‘rule’.

rule – mixed:
The Rule parameter defines the validation method and takes either a single value or an array. Rule may be (in order of preference) a method of your model, a method of the Validation class or a Regular Expression. If Rule is an array and ‘ruleName’ is a method, all other members of the array will be passed to the method. eg.

var $validate = array('username' => array('rule' => array('between', 6, 20)));

allowEmpty – bool:
This defines the behaviour when an empty value for the field is found. ‘allowEmpty’ => false will cause the validation to fail when the field data is empty. N.B: This rule is only enforced when there is an actual fieldName index in the data array.

Default is false.

required – bool:
‘required’ => true means that an index with fieldName must exist in the data array, i.e. validation will fail if isset($data['ModelName']['fieldName']) fails. N.B Required does not care if the value is empty – see allowEmpty above.

Default is false.

on – string (‘create’ or ‘update’):
If on is defined , the validation rule will only be applied on model ‘create’ or ‘update’. If not defined it is applied everytime. This may be useful for situations such as created_by is required on record creation, but on update it must not be defined.

Default is null, i.e. apply rule everytime.

message – string:
Message is the error message that will be stored in validationErrors. If message is not define, it will attempt to use rule_index (in Construct 3) if it is a string, otherwise it will default to ‘This field cannot be left blank’.

There is also another parameter ‘last’ defined in the code but it is not used as yet. Not sure what it’s use will be either.

A Full Example

This is the actual validate variable from my User model. It contains a mixture of the above constructs and techniques.

var $validate = array(
  'username'   => array(
    VALID_NOT_EMPTY,
    'alphanumeric' => array(
      'rule' => 'alphanumeric',
      'message' => 'Username may only consist of letter and numbers'),
    'length' => array(
      'rule' => array('between', 6, 20),
      'message' => 'Username must be between 6 and 20 characters in length')
  ),
  'name'     => VALID_NOT_EMPTY,
  'email'   => array(
    'Invalid email format' => VALID_EMAIL,
    VALID_NOT_EMPTY
  ),
  'passwrd'   => array(
    VALID_NOT_EMPTY,
    'length' => array(
      'rule' => array('minLength', 6),
      'message' => 'Password must be at least 6 characters in length'),
    'strong' => array(
      'rule' => 'isStrong',
      'message' => 'Your password is not strong enough')
  )
);

Disclaimer: My knowledge of the new validation was gained from the Bakery Article Multiple Rules of Validation, CakeBaker’s article Validation with CakePHP 1.2 and mostly from looking at the source code. If I have interpreted something incorrectly, please let me know.


Actions

Information

16 responses

8 07 2007
All About Validation in CakePHP 1.2 - Part 2 « Another Cake Baker

[...] About Validation in CakePHP 1.2 – Part 2 6 07 2007 In my previous article I discussed the new constructs for Model::validate. This article follows on from this and is a run down of the new validation methods and rules [...]

30 08 2007
CakePHP 1.2: The Romance Continues … « Ahsan’s Laboratory

[...] All about Validation in CakePHP 1.2 by Another Cake Baker. [...]

3 09 2007
Ahsan

Hi,

A very useful post indeed. Thanks for writing. Just a correction though, you wrote that:

“‘allowEmpty’ => true will cause the validation to fail when the field data is empty”

After checking it with the latest 1.2 code from the svn, I think it is completely the opposite. ‘allowEmpty’ => true will validated successfully if the field date is empty. Infact, ‘allowEmpty’ => false will cause the validation to fail if the field date is empty.

Correct me if Im wrong.

Thanks

3 09 2007
Ahsan

Please, forgive my typos in the last comment:
validated => validate
date => data

3 09 2007
Geoff

Thanks Ahsan, it does work as you say and I have corrected the post.

Geoff

14 09 2007
madjik

Nice article ! Thank you for posting it.

Do you know how to disable from a controller the validation on a certain field ?

For example, I don’t want the e-mail address to be checked, but all the rest of the validations should occure when using validates() ?

Thanks !

15 09 2007
Geoff

madjik,

The way I do this when needed is simply use an unset($this->validate['rule_index']) before calling validates() or save().

Geoff

17 09 2007
Tim

thanks for the article,

Do you guys know how i can access the error messages in my controller?
Is their something like the method getVar(for views) in a controller so i know which & what variabels are being send to the controller?

Tim,

18 09 2007
Geoff

Tim,

You can see which fields caused the invalidation with $this->Model->invalidFields which is an array.

Geoff

20 09 2007
Loud Baking » Blog Archive » CakePHP's advanced model fields validation

[...] checking different blogs and tutorials, the bakery, API and IRC channel, it was obvious that some kind of documentation for [...]

15 10 2007
Lo nuevo en CakePHP 1.2 y las diferencias con CakePHP 1.1

[...] Todo acerca de la validación en CakePHP 1.2 parte 1 por otro Cake Baker. [...]

18 07 2008
pizaninja

What about i18n ?

I would like to do something like that :
replace in my model:
‘message’ => ‘Username must be between 6 and 20 characters in length’
by :
‘message’ => __(‘Username must be between 6 and 20 characters in length’)

How could I easily use cake i18n capabilities ?

17 12 2008
zamos

I think you do not need __() in this case. just put your message in your .po file and it should work just fine.

poz.

4 02 2009
Ajay kumar singh

Where we have to call validate();

3 03 2009
CakePHP validation and validation contexts - tình huống validation trong cakePHP « Datgs’ Blog

[...] http://lemoncake.wordpress.com/2007/07/03/all-about-validation-in-cakephp-12/(nguồn tham khảo) Posted in All posts, CakePHP. Tags: cake, CakePHP, context, situation, tình huống, validation. [...]

24 07 2009
[PRONIQUE] CakePHP Developer Links

[...] All About Validation in CakePHP 1.2 « Another Cake Baker [...]

Leave a comment