by
KK » Tue Jun 16, 2020 5:14 pm
Validators can be simple PHP functions and don't need to be registered.
For example, if my editable region is defined this way -
- Code: Select all
<cms:editable name='email' label='Email' validator='email | no_duplicate_mail' type='text' />
- there are two validators being used above. The first one 'email' is registered in Couch but the second one is not so Couch will see if a PHP function by that name is available.
If it is,
it will be called with the field being validated (and any arguments that may be set); if not found, it will display an error.
So the function must be put somewhere where it is available to Couch - the kfunctions.php file is a good place for this.
Also, as highlighted in the line above, the function must accept as its parameters the field and the arguments (if applicable).
If you take a look in couch/functions.php, you'll find many functions named validate_* e.g.
- Code: Select all
static function validate_numeric( $field ){
$val = trim( $field->get_data() );
if( !is_numeric($val) ){
return KFuncs::raise_error( "Invalid characters (only numeric values allowed)" );
}
}
Each will accept a $field as its first parameter and some may also accept a second param e.g.
- Code: Select all
static function validate_min_len( $field, $args ){ ..
We'll continue with
validate_numeric as our example.
The $field is actually the editable region being validated so we need to first get the value being inputted in that editable region. That is what this line does.
- Code: Select all
$val = trim( $field->get_data() );
Next we do whatever validation we desire on that value.
If our validations pass, the function silently returns (i.e no news is good news).
If it fails, we return a KFuncs::raise_error like this -
- Code: Select all
return KFuncs::raise_error( "Invalid characters (only numeric values allowed)" );
And those are the only two essential things for any validator - get the value from the editable region and test it and return an error object if validation fails.
I suggest you take a look at the following core validators that use regex (something that you are interested in) -
- Code: Select all
static function validate_email( $field ){
if( !preg_match("/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,10}$/i", trim($field->get_data())) ){
return KFuncs::raise_error( "Invalid email address" );
}
}
static function validate_url( $field ){
// Pattern from http://mathiasbynens.be/demo/url-regex
$pattern = "/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iuS";
if( !preg_match($pattern, trim($field->get_data())) ){
return KFuncs::raise_error( "Invalid URL" );
}
}
static function validate_regex( $field, $args ){
if( !preg_match(trim($args), trim($field->get_data())) ){
return KFuncs::raise_error( "Does not match pattern" );
}
}
Notice how each uses the two points I mentioned.
All the examples above are registered validators (and so are invoked by some easier names) but any custom validator will be exactly the same.
As one last example, remember the custom validator (no_duplicate_email) we used in the very first code example above?
- Code: Select all
<cms:editable name='email' label='Email' validator='email | no_duplicate_mail' type='text' />
Here is the actual code for the function behind it -
- Code: Select all
// custom email validator placed in kfunctions.php
function no_duplicate_mail( $field ){
global $FUNCS, $CTX;
$email = trim( $field->get_data() );
$current_page_id = $field->page->id;
if( strlen($email) ){
// Create Couch script..
$html = "<cms:pages masterpage='contact.php' id='NOT {$current_page_id}' custom_field='email=={$email}' show_future_entries='1' count_only='1' />";
// Pass on the code to Couch for execution using the 'embed' function
$count = $FUNCS->embed( $html, $is_code=1 );
if( $count ){
return KFuncs::raise_error( "Email already exists" );
}
}
}
As you can see, it is just a normal PHP function and uses the same steps as used by the registered core validators.
Hope this is sufficient info for you to code your own validator.