Как в MODX Revo избавиться от спама с FormIt, AjaxForm

Сегодня разберем пару методов борьбы со спамом в MODX Revo с форм на FormIt, AjaxForm.

Один из самых действенных методов борьбы со спамом — поставить рекапчу от гугла, как это сделать я писал здесь. На данном методе останавливаться не буду. Опишу альтернативные способы без каких либо капч, при помощи добавление скрытого поля в форму — тут по сути несколько вариаций

Способ 1

Вариация 1.

Добавляем в форму следующие строки


<input class="forminpun" type="hidden" name="nospam:blank" value="" />
<input class="forminpun" type="hidden" name="work-email" value="" />

и добавляем их в вызов, в параметр validate

&validate='message:required,work-email:blank'

Не идеальная защита, но частично помогает

Вариация 2.

Добавляем в форму строчку

<input type="text" class="s-message" name="s-message" value="" />

точно так же как и в первом случае в валидате добавляем,

&validate='s-message:blank'

далее скрываем это поле при помощи css.

.s-message{display:none}

Данная вариация спасает отспама получше, но не кто не мешает их объединить)

Способ 2 (для FromIt + AjaxForm)

За частую спам-боты заполняют все поля и отключат js, по этому добавляем с помощью js в форму поле, и если это поле будет заполнено или отсутствовать, форма не отправиться

Создаем сниппет validate со следующим содержимым:

<?php
function text_error(){
return false;
die();
}
if(isset($_POST['org'])){
if($hook->getValue('org')!=''){
$modx->log(xPDO::LOG_LEVEL_ERROR, 'Ошибка заполнения формы: не пустое поле антиспама');
$modx->log(xPDO::LOG_LEVEL_ERROR, print_r($_POST, 1));
text_error();
}else{
return true;
}
}else{
$modx->log(xPDO::LOG_LEVEL_ERROR, 'Ошибка заполнения формы: нет поля антиспама');
$modx->log(xPDO::LOG_LEVEL_ERROR, print_r($_POST, 1));
text_error();
}

В вызов формы хук validate — название выше созданного сниппета

&hooks='validate, email, FormItSaveForm'

Ну и пишем небольшой скриптик на JavaScript (с jQuery)

$(function(){
// Антиспам
$('.ajax_form').append('<input type="text" name="org" value="" class="_org" style="visibility:hidden; height: 0; width: 0; padding: 0; border:none;"/>')
// Антиспам х
})

где .ajax_form — класс формы

Способ 3 — в основном от ручного спама ну и от части роботов

Суть в том что обычно спамеры пытаются отправить ссылку на какой нибудь сайт, а реальные пользователи обычно просто задают вопрос, типа как сколько стоит, как купить, и т.д. Поэтому первое — запрещаем ввод ссылок. Так же в сниппете предусмотрена проверка поля ввода телефона.

Создаем сниппет antispam со следующим содержимым

<?php
/*Сниппет, проверяющий содержание формы на признаки спама*/
//Определяем значения служебных переменных по умолчанию
$success=true;
$haserror=false;
//Массив запрещенных фрагментов строк
//Если в каком либо поле формы встретится один из ниже перечисленных фрагментов, то далее обрабатывать сообщение не будем
$forb=array(
'@',
'http',
'://',
'www'
);
//Пробегаем по массиву запрещенных фрагментов
foreach ($forb as $f){
if($haserror==false){ //Если еще не встретился запрещенный фрагмент
$haserror=strpos($value,$f); //Проверяем его в значении текущего проверяемого поля ввода
}
}
/*Проверка телефона (если не нужна, просто закомментируйте строки 22-25)*/
if(substr_count($key,'phone')>0){ //Если проверке подвергается поле ввода телефона
if($value!='' and strlen($value)<16){$haserror=1;} //для поля ввода телефона проверяем длину введенного значения (при использовании скрипта форматирования это будет строка из 16 символов всегда!)
}
//Если была обнаружена ошибка
if ($haserror!=false) {
$validator->addError($key,'Недопустимое значение!');
$modx->log(xPDO::LOG_LEVEL_ERROR,'Антиспам: IP='.$_SERVER['REMOTE_ADDR'].' СОДЕРЖАНИЕ '.$key.': '.$value);
$success=false;
}
//Возвращаем результат работы валидатора
return $success;

Далее подключаем сниппет в formIt в виде кастомного валидатора

&customValidators='antispam'

и прописывать валидацию к нужным полям. Как правило, это поле message.

&validate='message:antispam'

Данный сниппет пишет содержание в лог на всякий случай

А как защищаетесь от спама вы?