Creating own validators for Web Forms fields
In this topic
Validator class structure
Validator is the class or set of functions with the following structure:
Method | Description |
---|---|
Validator description | This function passes the validator description, method names and etc. to the validator handler. |
Validator settings | This function returns an array of validator settings. |
Settings processing | Set of features that prepare settings to be integrated into the database and for inverse conversion. |
Validator function | The validator itself. |
Due to inconvenience of handling several functions, it is recommended to unite them into a class (namespace). Further description and provided example will be based on this recommendation. The validator in the example, "Number within range" is realised as the class CFormCustomValidatorNumberEx
.
Validator description
Validator description method is used to an associative array of the following structure:
Parameter | Description |
---|---|
NAME | Validator unique string identifier. |
DESCRIPTION | Validator name. |
TYPES | Array of field types to apply the validator. |
SETTINGS | Name of the method returning array of validator settings. Optional. If the valuator is implemented as the class, the value is an array ("name_class", "name_method"). |
CONVERT_TO_DB | Name of method, responsible for checking validator parameters and transformation of settings array into the string to be saved. Optional, if validator doesn't have settings. If the validator is implemented as the class, the values is an array ("name_class", "name_method"). |
CONVERT_FROM_DB | Name of the method, responsible for reverse conversion of the validator parameters string into an array. Optional, if validator doesn't have settings. If the validator is implemented as the class, the value is an array ("name_class", "name_method"). |
HANDLER | Name of the main method, directly responsible for field value validation. If the validator is implemented as a class, the value is an array ("name_class", "name_method"). |
Example:
function GetDescription() { return array( "NAME" => "custom_number_ex", // identifier "DESCRIPTION" => "Number within range", // name "TYPES" => array("text", "textarea"), // types of fields "SETTINGS" => array("CFormCustomValidatorNumberEx", "GetSettings"), // method, returning the array of settings "CONVERT_TO_DB" => array("CFormCustomValidatorNumberEx", "ToDB"), // method, converting an array of settings into a string "CONVERT_FROM_DB" => array("CFormCustomValidatorNumberEx", "FromDB"), // method, converting settings string into an array "HANDLER" => array("CFormCustomValidatorNumberEx", "DoValidate") // validator ); }
Validator parameters
Method, set by the element SETTINGS
, must return an array of elements of type:
"parameter_name" => array( "TITLE" => "parameter_title", "TYPE" => "parameter_type", "DEFAULT" => "default_value", "VALUES" => array( "value1" => "value_name1", "value2 " => "value_name2", "value3 " => "value_name3" ) )
Parameter | Description |
---|---|
parameter_name | Array key is the parameter string name, unique within this validator. |
TITLE | Parameter name |
TYPE | Type of field to input parameter value. Can have the following values:
|
DEFAULT | Parameter value by default. |
VALUES | Array of elements type "value" => "value name" for parameters type DROPDOWN |
Example:
function GetSettings() { return array( "NUMBER_FROM" => array( "TITLE" => "Number lower threshold", "TYPE" => "TEXT", "DEFAULT" => "0", ), "NUMBER_TO" => array( "TITLE" => "Number upper threshold", "TYPE" => "TEXT", "DEFAULT" => "100", ), "NUMBER_FLOAT" => array( "TITLE" => "Floating number", "TYPE" => "CHECKBOX", "DEFAULT" => "Y", ), ); }
Parameter processing
Processing of validator parameters requires two methods, set in the description by the parameters CONVERT_TO_DB
and CONVERT_FROM_DB
. The first parameter receives an array of values on input and must return their string representation. The second parameter performs reverse conversion. Both methods can also perform random manipulations with parameter values.
Example:
function ToDB($arParams) { // check of passed parameters $arParams["NUMBER_FLOAT"] = $arParams["NUMBER_FLOAT"] == "Y" ? "Y" : "N"; $arParams["NUMBER_FROM"] = $arParams["NUMBER_FLOAT"] == "Y" ? floatval($arParams["NUMBER_FROM"]) : intval($arParams["NUMBER_FROM"]); $arParams["NUMBER_TO"] = $arParams["NUMBER_FLOAT"] == "Y" ? floatval($arParams["NUMBER_TO"]) : intval($arParams["NUMBER_TO"]); // switch of threshold values, if required if ($arParams["NUMBER_FROM"] > $arParams["NUMBER_TO"]) { $tmp = $arParams["NUMBER_FROM"]; $arParams["NUMBER_FROM"] = $arParams["NUMBER_TO"]; $arParams["NUMBER_TO"] = $tmp; } // return serialised string return serialize($arParams); } function FromDB($strParams) { // no conversions required, just return unserialized array return unserialize($strParams); }
Validator
Main method receives 4 parameters on input: validator parameters array,
question parameters array, question answers array and answer values array. It must return true
on successful value validation and
false
otherise. Error description is returned via CMain::ThrowException()
. Error description can use the template
#FIELD_NAME#
to retrieve a field name, experiencing error.
Example:
function DoValidate($arParams, $arQuestion, $arAnswers, $arValues) { global $APPLICATION; foreach ($arValues as $value) { // skip empty values if (strlen($value) <= 0) continue; // Bring value to an integer $value = $arParams["NUMBER_FLOAT"] == "Y" ? floatval($value) : intval($value); // check the integer lower threshold if (strlen($arParams["NUMBER_FROM"]) > 0 && $value < intval($arParams["NUMBER_FROM"])) { // return an error $APPLICATION->ThrowException("#FIELD_NAME#: value too small"); return false; } // check the integer upper value if (strlen($arParams["NUMBER_TO"]) > 0 && $value > intval($arParams["NUMBER_TO"])) { // return an error $APPLICATION->ThrowException("#FIELD_NAME#: value too large"); return false; } } // all values are validated, return true return true; }
Attention: when processing field values of listed types (dropdown, multiselect, radio, checkbox) the validator will receive array of selected answers IDs on input.
Validator integration
Validator class must be connected in any place, where it will be available from the Control Panel and in the public section (see details at page execution sequence, for example, in /bitrix/php_interface/init.php (please be advised, that CModule::IncludeModule("form"); will connect the webform module everywhere at all times.).
Directly, the validator file can be located anywhere - for example in /bitrix/php_interface/include/form/validators/. Connecting validator is performed by installing the validator description function as the event handler onFormValidatorBuildList
.
Example
Summarizing all of the above, create the validator. Validator class is located in the file /bitrix/php_interface/include/form/validators/val_num_ex.php
<? // File listing /bitrix/php_interface/include/form/validators/val_num_ex.php class CFormCustomValidatorNumberEx { function GetDescription() { return array( "NAME" => "custom_number_ex", // identifier "DESCRIPTION" => "Floating number ", // name "TYPES" => array("text", "textarea"), // field types "SETTINGS" => array("CFormCustomValidatorNumberEx", "GetSettings"), // method returning a settings array "CONVERT_TO_DB" => array("CFormCustomValidatorNumberEx", "ToDB"), // method converting a settings array into string "CONVERT_FROM_DB" => array("CFormCustomValidatorNumberEx", "FromDB"), // method converting settings string into an array "HANDLER" => array("CFormCustomValidatorNumberEx", "DoValidate") // validator ); } function GetSettings() { return array( "NUMBER_FROM" => array( "TITLE" => "Number lower threshold", "TYPE" => "TEXT", "DEFAULT" => "0", ), "NUMBER_TO" => array( "TITLE" => "Number upper threshold", "TYPE" => "TEXT", "DEFAULT" => "100", ), "NUMBER_FLOAT" => array( "TITLE" => "Floating number", "TYPE" => "CHECKBOX", "DEFAULT" => "Y", ), ); } function ToDB($arParams) { // check of passed parameters $arParams["NUMBER_FLOAT"] = $arParams["NUMBER_FLOAT"] == "Y" ? "Y" : "N"; $arParams["NUMBER_FROM"] = $arParams["NUMBER_FLOAT"] == "Y" ? floatval($arParams["NUMBER_FROM"]) : intval($arParams["NUMBER_FROM"]); $arParams["NUMBER_TO"] = $arParams["NUMBER_FLOAT"] == "Y" ? floatval($arParams["NUMBER_TO"]) : intval($arParams["NUMBER_TO"]); // switch of threshold values, if required if ($arParams["NUMBER_FROM"] > $arParams["NUMBER_TO"]) { $tmp = $arParams["NUMBER_FROM"]; $arParams["NUMBER_FROM"] = $arParams["NUMBER_TO"]; $arParams["NUMBER_TO"] = $tmp; } // return serialized string return serialize($arParams); } function FromDB($strParams) { // no conversions required, just return unserialized array return unserialize($strParams); } function DoValidate($arParams, $arQuestion, $arAnswers, $arValues) { global $APPLICATION; foreach ($arValues as $value) { // skip empty values if (strlen($value) <= 0) continue; // bring value to an integer $value = $arParams["NUMBER_FLOAT"] == "Y" ? floatval($value) : intval($value); // check number lower threshold if (strlen($arParams["NUMBER_FROM"]) > 0 && $value < intval($arParams["NUMBER_FROM"])) { // return error $APPLICATION->ThrowException("#FIELD_NAME#: value too small"); return false; } // check number upper threshold if (strlen($arParams["NUMBER_TO"]) > 0 && $value > intval($arParams["NUMBER_TO"])) { // return error $APPLICATION->ThrowException("#FIELD_NAME#: value too large"); return false; } } // all values are validated, return true return true; } } // install method CFormCustomValidatorNumberEx as the event handler AddEventHandler("form", "onFormValidatorBuildList", array("CFormCustomValidatorNumberEx", "GetDescription")); ?>
After that, only insert into /bitrix/php_interface/init.php the string
include_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/php_interface/include/form/validators/val_num_ex.php");