Custom Validation Logic: Difference between revisions
No edit summary |
|||
| (8 intermediate revisions by 3 users not shown) | |||
| Line 13: | Line 13: | ||
Code: | Code: | ||
<syntaxhighlight lang="php"> | |||
public function test_validate(&$record, $mode) | |||
if ($record["test"]!="something") | { | ||
if ($record["test"]!="something") { | |||
atkTriggerError($record, $this->getAttribute("test"), "Test field should be 'something'"); | |||
} | } | ||
} | |||
</syntaxhighlight> | |||
This is the prefered way of adding custom validation to a node. | This is the prefered way of adding custom validation to a node. | ||
The $mode param is either 'add' or 'update', so you could do validation based on the fact if the user was adding a new record or updating an existing one. | The $mode param is either 'add' or 'update', so you could do validation based on the fact if the user was adding a new record or updating an existing one. | ||
Note that because <tt>atkNodeValidator::validateAttributeValue()</tt> specifically exempts empty fields from validation, a custom <tt>test_validate</tt> function cannot be used to check whether a field is empty--<tt>test_validate</tt> will never be called. However, if you only want to ensure that a field is non-empty, you can use the <tt>AF_OBLIGATORY</tt> flag, as described above. e.g. | |||
<syntaxhighlight lang="php"> | |||
public static function meta(atkMetaPolicy $policy) | |||
{ | |||
$policy->setFlag('start_date', AF_OBLIGATORY); | |||
} | |||
</syntaxhighlight> | |||
== Method 2. Overriding a node's validate method. == | == Method 2. Overriding a node's validate method. == | ||
| Line 31: | Line 41: | ||
Code: | Code: | ||
<syntaxhighlight lang="php"> | |||
public function validate(&$record, $mode) | |||
if ($record["skipvalidation"] == 1) | { | ||
if ($record["skipvalidation"] == 1) { | |||
// do nothing, the user told us to not validate the record by | |||
// putting our 'skipvalidation' field for this record to 1. | |||
// (in a real world app, this would not make much sense, but it's | |||
// ok as an example) | |||
} | } else { | ||
// call original validation | |||
parent::validate($record, $mode); | |||
} | } | ||
} | } | ||
</syntaxhighlight> | |||
== Method 3. Custom attribute. == | == Method 3. Custom attribute. == | ||
| Line 53: | Line 62: | ||
Place the following for example in modules/mymod/attributes/class.codeattribute.inc: | Place the following for example in modules/mymod/attributes/class.codeattribute.inc: | ||
<syntaxhighlight lang="php"> | |||
<?php | |||
class codeAttribute extends atkAttribute | |||
{ | |||
public function validate(&$record, $mode) | |||
{ | { | ||
if (!$this->_isValidCode($record[$this->fieldName()])) { | |||
atkTriggerError($record, $this, "not a valid code"); | |||
if (!$this-> | |||
} | } | ||
} | |||
protected function _isValidCode($string) | |||
{ | |||
// your code validation here... | // your code validation here... | ||
return true; | return true; | ||
} | } | ||
} | |||
</syntaxhighlight> | |||
Then, in your node, it's a matter of: | Then, in your node, it's a matter of: | ||
<syntaxhighlight lang="php"> | |||
useattrib("mymod.codeattribute"); | useattrib("mymod.codeattribute"); | ||
..... | ..... | ||
$this->add(new codeAttribute("identifier")); | $this->add(new codeAttribute("identifier")); | ||
</syntaxhighlight> | |||
== Internationalising the error string == | == Internationalising the error string == | ||
| Line 86: | Line 96: | ||
If your app is multilingual, instead of passing an error message to triggerError, you can pass a language key, like this: | If your app is multilingual, instead of passing an error message to triggerError, you can pass a language key, like this: | ||
<syntaxhighlight lang="php"> | |||
triggerError($record, "field", "error_invalidcode"); | triggerError($record, "field", "error_invalidcode"); | ||
</syntaxhighlight> | |||
Then, in your language files, add the key with the translation, like this: | Then, in your language files, add the key with the translation, like this: | ||
<syntaxhighlight lang="php"> | |||
"error_invalidcode"=>"The value is not a valid code" | "error_invalidcode"=>"The value is not a valid code" | ||
</syntaxhighlight> | |||
Latest revision as of 13:24, 12 February 2010
|
ATK Howto: Custom Validation Logic
|
Intro
In an ATK application, there are several validations that the frameworks handles for you; you just need to specify certain flags like AF_UNIQUE or AF_OBLIGATORY. Also, there are attributes that do validation of the input data, such as the atkEmailAttribute, which will not allow the user to enter an invalid e-mail address.
There are times however, when you would want to add custom validation logic to your application. This howto presents 3 ways to do this.
Method 1. Validation of a single attribute
Suppose you have a field named 'test', here's how to create a validation method that is automatically fired whenever the user wants to save a record:
Code:
public function test_validate(&$record, $mode)
{
if ($record["test"]!="something") {
atkTriggerError($record, $this->getAttribute("test"), "Test field should be 'something'");
}
}
This is the prefered way of adding custom validation to a node.
The $mode param is either 'add' or 'update', so you could do validation based on the fact if the user was adding a new record or updating an existing one.
Note that because atkNodeValidator::validateAttributeValue() specifically exempts empty fields from validation, a custom test_validate function cannot be used to check whether a field is empty--test_validate will never be called. However, if you only want to ensure that a field is non-empty, you can use the AF_OBLIGATORY flag, as described above. e.g.
public static function meta(atkMetaPolicy $policy)
{
$policy->setFlag('start_date', AF_OBLIGATORY);
}
Method 2. Overriding a node's validate method.
If you need more flexibility, for example if you need to prevent the original validation of the data, you can completely override the node validate() method.
Code:
public function validate(&$record, $mode)
{
if ($record["skipvalidation"] == 1) {
// do nothing, the user told us to not validate the record by
// putting our 'skipvalidation' field for this record to 1.
// (in a real world app, this would not make much sense, but it's
// ok as an example)
} else {
// call original validation
parent::validate($record, $mode);
}
}
Method 3. Custom attribute.
Finally, if you need to reuse validation of fields in multiple nodes, it's best to create a custom attribute. For example, if you have a 'code' field for entering the code of a record, and there's some company standard for code fields you need to verify, you could create a custom attribute.
Place the following for example in modules/mymod/attributes/class.codeattribute.inc:
<?php
class codeAttribute extends atkAttribute
{
public function validate(&$record, $mode)
{
if (!$this->_isValidCode($record[$this->fieldName()])) {
atkTriggerError($record, $this, "not a valid code");
}
}
protected function _isValidCode($string)
{
// your code validation here...
return true;
}
}
Then, in your node, it's a matter of:
useattrib("mymod.codeattribute");
.....
$this->add(new codeAttribute("identifier"));
Internationalising the error string
If your app is multilingual, instead of passing an error message to triggerError, you can pass a language key, like this:
triggerError($record, "field", "error_invalidcode");
Then, in your language files, add the key with the translation, like this:
"error_invalidcode"=>"The value is not a valid code"