Про защиту от спама в регистрации без включения капчи я уже рассказывал. На очереди борьба с ботами в модуле Веб-формы в битриксе, а так же расскажу как написать свой валидатор.

Защищаться будем по схеме, описанной в заметке про регистрацию, а именно: добавляем в форму невидимое поле, если поле заполнено — к нам пришёл бот.

Предположим, форма у вас создана, поля(в понятии модуля форм — «вопросы») для неё заведены и настроены. Заведём ещё одно, служебное, с типом text (поля типа hidden боты иногда игнорируют и не заполняют). В свойствах «Символьный идентификатор» ему надо придумать, как обычному полю, например user или name. Не стоит называть его antibot.

В поле «Текст ответа» чтобы не писать название, можно считерить и вписать неразрывный пробел (в юникоде: Alt + 0160).

Как вы помните, нам нужно проверять поле на пустоту. По умолчание доступны валидаторы:

  • [number_ext] Число в пределах
  • [text_len] Длина строки
  • [number] Целое число
  • [INN] Проверка ИНН

Вроде бы подходит валидатор text_len. У него в настройках есть 2 параметра: «Минимальная длина», «Максимальная длина». Но для настройки «Максимальная длина» минимум можно указать 1, а нам нужно 0. Можно поставить и 1, но я решил написать свой валидатор, тем более, что я никогда этого не делал.

Документация по написанию своих валидаторов тут. Там всё просто: пишем PHP-класс с нужными методами и подвешиваем его на нужное событие.

Получился вот такой класс валидатора:

<?php
/**
 * Created by olegpro.ru
 * User: Oleg Maksimenko
 * Date: 05.12.2014 3:08
 */
 
namespace Olegpro;
 
use \Bitrix\Main\EventManager;
 
class FormValidatorStringEmpty
{
    function getDescription()
    {
        return array(
            'NAME' => 'empty_string', // идентификатор
            'DESCRIPTION' => 'Пустая строка', // наименование
            'TYPES' => array('text'), // типы полей
            'SETTINGS' => array(__CLASS__, 'getSettings'), // метод, возвращающий массив настроек
            'CONVERT_TO_DB' => array(__CLASS__, 'toDB'), // метод, конвертирующий массив настроек в строку
            'CONVERT_FROM_DB' => array(__CLASS__, 'fromDB'), // метод, конвертирующий строку настроек в массив
            'HANDLER' => array(__CLASS__, 'doValidate') // валидатор
        );
    }
 
    function getSettings()
    {
        return array();
    }
 
    function toDB($arParams)
    {
        // возвращаем сериализованную строку
        return serialize($arParams);
    }
 
    function fromDB($strParams)
    {
        // никаких преобразований не требуется, просто вернем десериализованный массив
        return unserialize($strParams);
    }
 
    function doValidate($arParams, $arQuestion, $arAnswers, $arValues)
    {
        global $APPLICATION;
 
        foreach ($arValues as $value) {
 
            // проверяем на пустоту
            if (strlen(trim($value)) > 0) {
                // вернем ошибку
                $APPLICATION->ThrowException('Ошибка заполнения полей формы. Код ошибки [FKWF1].');
                return false;
            }
 
        }
 
        // все значения прошли валидацию, вернем true
        return true;
    }
}

Положил я его по пути: /bitrix/php_interface/handlers/form_validator_string_empty.php

Ну а подключить его нужно в файле /bitrix/php_interface/init.php

use \Bitrix\Main\EventManager;
use \Bitrix\Main\Loader;
 
EventManager::getInstance()->addEventHandlerCompatible('form', 'onFormValidatorBuildList',
    array('Olegpro\FormValidatorStringEmpty', 'getDescription')
);
 
Loader::registerAutoLoadClasses(null, array(
    'Olegpro\FormValidatorStringEmpty' => '/bitrix/php_interface/handlers/form_validator_string_empty.php',
));

После этого у поля на вкладке «Валидаторы» появится новый валидатор «[empty_string] Пустая строка»:

Кастомный валидатор поля веб-формы

Его-то и нужно добавить к нашему полю для защиты от спама.

Последнее что осталось: скрыть это поле через CSS, чтобы пользователи его не видели.