По сути было найдено два решения:
1) Скрытое поле и проверка на пустоту, но, к сожалению, роботы научились распознавать такие поля.
2) использовать сервис Akmist, который проверяет содержимое, но почему-то он отвалился и я так не сумел найти к нему подход.
В итоге — написал простое, но тие не менее эффективное решение, основанное на проверке проведенного времени на странице. Роботы они ведь что делают? Загружают страницу, парсят, находят форму, заполняют — отправляют. На все про все по моей личной статистике уходит не больше секунды, в то время как обычный пользователь для заполнения формы тратит как минимум секунд 30.
Итак, от слов к делу.
Для eForm (evolutionCMS).
Создаем сниппет checkSpamTime, вставляем в него код:
<?php
if ($_SESSION['now'])
{
$_SESSION['lt'] = $_SESSION['now'];
}
$_SESSION['now'] = microtime(true);
if (!function_exists('checkSpamTime'))
{
function checkSpamTime(&$fields)
{
$time = $_SESSION['now'] - $_SESSION['lt'];
if (($time<2) or ($time>1440)) exit(); //Здесь проверяем сколько секунд прошло с момента точки входа. 5 - с запасом, можно ставить и единицу
}
}
Далее делаем вызов сниппета над вызовом eForm (если используется несколько форм, необходимо поставить ОДИН раз над самой верхней), и в самом сниппете пишем &eFormOnBeforeMailSent=`checkSpamTime`
В итоге у нас получается что-то вроде такого:
[!checkSpamTime!]
[!eForm?
/*...*/
&eFormOnBeforeMailSent=`checkSpamTime`
/*...*/
!]
Для formLister (evolutionCMS)
Создаем сниппет checkSpamTimeFL, вставляем в него код
<?php
if ($FormLister->isSubmitted())
{
$flag = false;
$now = microtime(true);
if ((isset($_SESSION['now'])) && ((($now - $_SESSION['now']) > 2) && (($now - $_SESSION['now']) < 1440)))
{
$flag = true;
}
$FormLister->setValid($flag);
}
else
{
$_SESSION['now'] = microtime(true);
}
и вызываем его в prepare.
В итоге у нас получается что-то вроде такого:
[!FormLister?
/*...*/
&prepare=`checkSpamTimeFL`
/*...*/
!]
За обновление решения спасибо Pathologic
Для FormIt (Modx Revolution)
Создаем сниппет checkSpamTime, вставляем код:
<?php
if (count($_POST))
{
$flag = false;
$now = microtime(true);
if ((isset($_SESSION['now'])) && ((($now - $_SESSION['now']) > 2) && (($now - $_SESSION['now']) < 1440)))
{
$flag = true;
}
return $flag;
}
else
{
$_SESSION['now'] = microtime(true);
}
Замечание. Я с Ревой знаком поверхностно, поэтому может кто подскажет: на что заменить проверку count($_POST)? Я че-та не нашел ничего более изящного((
И вписываем его первым в хук и пре хук, т.е.
[ [ !FormIt?
/*...*/
&hooks=`checkSpamTime,email`
&preHooks=`checkSpamTime`
/*...*/
] ]
Все три варианта проверены — работают)
P.S. Спасибо руководству сайта за блокировку моего предыдущего аккаунта)
Андрей Казунин 30.05.2018 13:43 #
kirilldiweb 19.06.2019 11:16 #
Дмитрий Танцирев 26.08.2019 12:49 #
В сниппете checkSpamTime для eForm.
Если мы первый раз зашли на сайт, то у нас не сохранится переменная «lt» в сессию. Соответственно в функции checkSpamTime из $_SESSION['now'] мы будем вычитать ноль. И далее оно пройдет проверку.
Переписал мальца:
Дмитрий Танцирев 26.08.2019 14:06 #
Алексей Либер 17.09.2019 12:03 #
Суть в том, что форма отправляет данные не сниппету, а странице. Поэтому чем выше сниппет поставлен, тем скорее он сработает.
Честно — в твоих словах логики больше чем в моем решении, но мое решение то реально работает)))
norton 15.12.2020 12:07 #
Алексей Либер 15.12.2020 12:18 #
norton 15.12.2020 12:21 #
Алексей Либер 15.12.2020 12:21 #
norton 16.12.2020 11:30 #