Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

CakePHP 1.2 - Multiple Validation Sets

DZone's Guide to

CakePHP 1.2 - Multiple Validation Sets

· Web Dev Zone
Free Resource

Tips, tricks and tools for creating your own data-driven app, brought to you in partnership with Qlik.

In CakePHP, you define how your data should be validated by setting parameters on the validate property of your model. In version 1.2, there is an on option that can be set on a specific rule that, when set, is either create or update. This allows you to define different rules depending on the type of action being performed. That, in combination with the required and allowEmpty properties, give you a fair amount of control over different validation rules.

Despite that, I developed a slightly different approach that allows for different validation sets to be specified and to be cleanly separated from each other.

I override the validates method within a custom AppModel (stored in /app/app_model.php). The validates method is called when a save call is made or it can be called manually. This custom method can perform in one of two ways:

Method One: Action-specific Validation Sets

It'll first look to see if you have a validation set specified for the current controller action. For example, if you were in the edit action, it'd look for a property in the model called validateEdit. If it doesn't exist, it'll default back to using the normal validate property.

class UsersController extends AppController {
function forgotpassword() {
$this->User->set($this->data);
if ($this->User->validates()) {
// send email to reset password and show success message
}
}
}

The thing I like about this is that the error messaging is handled by the validation and the FormHelper. (Although, a more noticable flash message near the top of the page is also helpful.)

Method Two: Custom Validation Sets

Alternatively, you may wish to specify a validation set manually before calling save or validates on a model. To do this, just specify a validationSet property on the model right before your call. The property will be unset immediately afterwards allowing normal validation rules to be applied.

Here's an alternate approach to the forgotten password example:

class User extends AppModel {
var $validateForgotpassword = array( ... );
}

class UsersController extends AppController {
function forgot() {
$this->User->set($this->data);
$this->User->validationSet = 'forgotpassword';
if ($this->User->validates()) {
// send email to reset password and show success message
}
}
}

The Code

Here is the custom validates method that pulls this all off:

function validates($options = array()) {
// copy the data over from a custom var, otherwise
$actionSet = 'validate' . Inflector::camelize(Router::getParam('action'));
if (isset($this->validationSet)) {
$temp = $this->validate;
$param = 'validate' . $validationSet;
$this->validate = $this->{$param};
} elseif (isset($this->{$actionSet})) {
$temp = $this->validate;
$param = $actionSet;
$this->validate = $this->{$param};
}

$errors = $this->invalidFields($options);

// copy it back
if (isset($temp)) {
$this->validate = $temp;
unset($this->validationSet);
}

if (is_array($errors)) {
return count($errors) === 0;
}
return $errors;
}

Explore data-driven apps with less coding and query writing, brought to you in partnership with Qlik.

Topics:

Published at DZone with permission of Jonathan Snook. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}