Drupal → Пишем простой модуль защиты от спама

19.01.2010

Цель модуля — защитить комментарии от автоматического спама, т.е от сообщений, которые создают боты а не люди.

Суть модуля — в форме отправки комментария, добавляем новое поле типа checkbox и подписью "Я не спамер". Боты, в основной массе, не заполняют незнакомые им поля, что позволяет отделить их от людей.

Модуль прошёл проверку в боевых условиях, и за несколько дней не пропустил ни одного спам-коммента.

Итак приступим.

Первым делом выбираем название модуля, пусть это будет Simple AntiSpam, системное название соответственно — simpleantispam.

Вторым шагом создаём папку simpleantispam по адресу sites/all/modules.

Модуль должен состоять как минимум из двух файлов — названиемодуля.info и названиемодуля.module. В .info содержится информация о модуле, а в .module код модуля. Все файлы должны быть в кодировке UTF-8 without BOM.

В созданной во втором шаге папке, создаём файл simpleantispam.info с содержанием:

name = Simple AntiSpam
description = Simple antispam module
version = 6.x-1.0
core = 6.x

где name — название модуля, description — описание модуля, version — версия модуля, core — версия Drupal.

Там же создаём файл simpleantispam.module с содержанием:

<?php
/**
 * @file
 * Simple AntiSpam
 */

Теперь нужно модифицировать форму комментариев и добавить к ней новое поле "Я не спамер". Сделать это можно с помощью хука hook_form_alter(), который позволяет изменить любую форму перед её показом. В конец файла simpleantispam.module добавляем:

/**
 * Реализация hook_form_alter()
 * Добавляем поле "Я не спамер" в форму отправки комментариев для анонимных пользователей.
 */
function simpleantispam_form_alter(&$form, &$form_state, $form_id) {
  global $user;
    
  // форма будет показываться только анонимным пользователям
  if ($form_id == 'comment_form' && !$user->uid) {
    $form['imnotbot'] = array(
      '#type' => 'checkbox',
      '#title' => 'Я не спамер',
      '#weight' => 0.01, // поле будет выводится перед кнопками Сохранить / Предпросмотр. Возможно вам придётся поэкспериментировать со значением
    );
  }
}

Теперь можно активировать модуль на странице управления модулями (admin/build/modules) и под анонимным пользователем посмотреть на результат:

Модифицированная форма отправки комментариев

Не забудьте отключить кэширование страниц для анонимных пользователей (admin/settings/performance) на время тестирования модуля.

Проверить отправленную форму можно с помощью хука hook_comment(). В simpleantispam.module добавляем:

/**
 * Реализация hook_comment()
 * Проверка значения поля "Я не спамер"
 */
function simpleantispam_comment(&$a1, $op) {
  global $user;
    
  // если поле "Я не спамер" не отмечено, то переменная $a1['imnotbot'] будет равна 0
  if ($op == 'validate' && !$user->uid && !$a1['imnotbot']) {
    // выводим сообщение боту
    form_set_error('imnotbot', 'spamers must die :P');

    // логируем сообщение
    watchdog(
      'simpleantispam',
      'Blocked spam comment. <b>Name</b>: @name, <b>message</b>: @comment',
      array('@name' => $a1['name'], '@comment' => $a1['comment']),
      WATCHDOG_WARNING
    );
  }
}

Вот и всё. Крохотный, но работающий модуль. При попытке отправить сообщение без отмеченного поля "Я не спамер", комментатору будет выведено сообщение об ошибке и коммент не попадёт в базу.

Пример работы модуля можно посмотреть на этой странице.

Исходники прилагаются: simpleantispam-6.x-0.2.

Для усиления защиты можно добавить второе поле "Я спамер", скрыть его с помощью CSS и в simpleantispam_comment выкидывать сообщение, если поле заполнено :)

Версия модуля для Drupal 7

Написанное актуально для
Drupal 6.x
Похожие записи

Комментарии

Гость
06.08.2010, 02:13

Здорово! А легко это адаптировать к другим формам? Например, у меня на сайте задействована Webform и еще разные формы в написании статей (т.е. пользователи пишут) и не только статей.

Я понял, что здесь нужно только найти id формы... это просто.
Еще нужно побаловаться с весом - чтобы чекбокс стал туда, где нужно.
А вот как применить к другим формам hook_comment() ??

Vydrin_AP
06.01.2011, 18:41

Отличный модуль! Не подумываете выложить на орг? И самый главный вопрос - под 7-ку портировать не планируете? Очень надо )) Хотя, сейчас сам попробую, может получится..

Модуль учебный, для полноценной защиты его нужно пилить и пилить ;)

В семёрке убрали hook_comment, теперь ф-ю валидации нужно подцеплять в simpleantispam_form_alter. В остальном всё идентично

Vydrin_AP
06.01.2011, 19:01

Глянул, попробовал переписать - видимо не хватит у меня знаний на портирование )))
Ну а то, что модуль учебный - так это же исправимо )) Просто очень понравилась простота подхода...
Спасибо )) буду искать на орге аналоги под 7-ку..

Петров Николай
05.04.2011, 16:46

за несколько дней не пропустил ни одного спам-коммента

А какова статистика за более продолжительный период времени?
Модуль все так-же эффективен?

Хочу сделать аналог для регистрации, но чуть по сложнее - со скрытыми с помощью CSS элементами формы, заполняемыми (или не заполняемыми) JS

у меня к этому модулю ещё пяток фильтров стоит. так что объективной статистики нет

а я бы использовал hook_form_FORMID_alter()
и
$form['#validate'][] = 'my_validate_function';

Спасибо огромное! Включила Ваш модуль (правда вместе с капчей) и уже 4 дня ни 1 спам-коммента, а одну капчу боты пробивали...

Владимир
20.06.2012, 01:10

Здравствуйте!
Поставил модифицированный мод отсюда http://www.drupal.ru/node/75674
Он включается. но "Я не спамер" не появляется. Разумеется доавлять посты не дает, т.к. чекбокса нет и следовательно галочку некуда ставить. Куда копать? :)

Владимир
20.06.2012, 08:40

Вопрос снимается. Шаблон был таким, исправил)))

Гость
03.07.2012, 18:01

Чисто 1 галка от спама на Д. не спасает - проверено на себе. Рекапча стояла - облом спамерам ... и людям.
Странно, что у меня на wp с тем же фокусом ни 1 спамера. Но с капчей писец.

на этом блоге стоит сабж, спама как видно нет.

На drupal.org есть модуль, реализующий схожую логику, но уже в "промышленном масштабе" : http://drupal.org/project/botcha. Там есть понятие "рецепт" и "книги рецептов" - модуль на основе правил, заложенных в рецепте, изменяет формы (список которых редактируется), позволяя боту выдать себя - а для пользователей форма выглядит абсолютно нормальной.

xandeadx, не выложишь готовый модуль для семерки?

Тогда не поможешь?
simpleantispam_form_alter как из этого примера не выводить чекбокс на семерке. У меня получилось его вывести, только если поставить global $form перед $form['imnotbot'] = array(, не уверен, что это правильно.

в семёрке id формы изменился. посмотри через debug($form_id)

Спасибо за модуль. Можно пожалуйста пример использования при добавлении материала?

Гость
03.03.2013, 06:51

У меня есть 3 вопроса.

  1. Как я понял этот модуль можно использовать даже при агрессивном режиме кэширования (в отличии от всяких капчей), верно?
  2. Подскажите, а нет ли модуля, добавляющего форму для комментариев только в том случае если у пользователя включен js?
  3. Если нет, то, есть ли возможность (и в 6 и в 7) из своего модуля узнать включен ли у пользователя js?

1. не проверял
2. не знаю
3. $_COOKIE['has_js']

Гость
03.03.2013, 11:54

$_COOKIE['has_js']

Спасибо. Мне, почему-то, казалоось что эту куку устанавливает не друпал а какой-то счётчик :) .

Добавить комментарий