Skip to content

Custom validation rules

The built-in rules cover most needs (see Validation rules), but you can add your own with the octa_forms_validation_rules filter. Once registered, a rule is used by its name in any form’s config, exactly like a built-in one.

The filter receives a map of rule name to a callable. Add your entry and return the map:

add_filter( 'octa_forms_validation_rules', function ( array $rules ) {
$rules['even'] = function ( $value, array $params ): bool {
return is_numeric( $value ) && (int) $value % 2 === 0;
};
return $rules;
} );

Now any field can use it:

{ "name": "seats", "type": "text", "label": "Seats", "rules": [{ "r": "even" }] }

Your callable receives:

  • $value — the field’s submitted value. Usually a string. For checkboxes it is a boolean, and for file fields it is the list of uploads.
  • $params — an array of parameters parsed from the rule string. For { "r": "between:1,10" } your callable receives ['1', '10'].

It must return true when the value passes and false when it does not. Return false on unexpected input rather than throwing, so a malformed value fails closed.

Parameters come after a colon in the rule string, split on commas:

{ "r": "between:1,10" }
$rules['between'] = function ( $value, array $params ): bool {
[ $lo, $hi ] = array_map( 'intval', $params + [ 0, 0 ] );
return is_numeric( $value ) && (int) $value >= $lo && (int) $value <= $hi;
};

The regex rule is the exception: its pattern is taken literally and never split, so a comma inside your pattern is safe.

A custom rule uses the message you put in the field’s rule with the m key. If you leave m out, provide a sensible message there, because there is no built-in default text for a rule OctaForms does not ship:

{ "r": "between:1,10", "m": "Please pick a number from 1 to 10." }

A value that passes your rule is still untrusted input. Escape it on output like any other user data. Rules decide acceptance; they do not sanitize.