Drupal → Пишем простой модуль защиты от спама
Цель модуля — защитить комментарии от автоматического спама, т.е от сообщений, которые создают боты а не люди.
Суть модуля — в форме отправки комментария, добавляем новое поле типа 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
выкидывать сообщение, если поле заполнено :)
Комментарии
А мне нравится...
Здорово! А легко это адаптировать к другим формам? Например, у меня на сайте задействована Webform и еще разные формы в написании статей (т.е. пользователи пишут) и не только статей.
Я понял, что здесь нужно только найти id формы... это просто.
Еще нужно побаловаться с весом - чтобы чекбокс стал туда, где нужно.
А вот как применить к другим формам hook_comment() ??
для других форм есть hook_form_alter
Отличный модуль! Не подумываете выложить на орг? И самый главный вопрос - под 7-ку портировать не планируете? Очень надо )) Хотя, сейчас сам попробую, может получится..
Модуль учебный, для полноценной защиты его нужно пилить и пилить ;)
В семёрке убрали
hook_comment
, теперь ф-ю валидации нужно подцеплять вsimpleantispam_form_alter
. В остальном всё идентичноГлянул, попробовал переписать - видимо не хватит у меня знаний на портирование )))
Ну а то, что модуль учебный - так это же исправимо )) Просто очень понравилась простота подхода...
Спасибо )) буду искать на орге аналоги под 7-ку..
А какова статистика за более продолжительный период времени?
Модуль все так-же эффективен?
Хочу сделать аналог для регистрации, но чуть по сложнее - со скрытыми с помощью CSS элементами формы, заполняемыми (или не заполняемыми) JS
у меня к этому модулю ещё пяток фильтров стоит. так что объективной статистики нет
Сделал для регистрации посложнее:
http://www.drupal.ru/node/60401
Спасибо, попрообую=)
а я бы использовал hook_form_FORMID_alter()
и
$form['#validate'][] = 'my_validate_function';
Спасибо огромное! Включила Ваш модуль (правда вместе с капчей) и уже 4 дня ни 1 спам-коммента, а одну капчу боты пробивали...
Здравствуйте!
Поставил модифицированный мод отсюда http://www.drupal.ru/node/75674
Он включается. но "Я не спамер" не появляется. Разумеется доавлять посты не дает, т.к. чекбокса нет и следовательно галочку некуда ставить. Куда копать? :)
Вопрос снимается. Шаблон был таким, исправил)))
Чисто 1 галка от спама на Д. не спасает - проверено на себе. Рекапча стояла - облом спамерам ... и людям.
Странно, что у меня на wp с тем же фокусом ни 1 спамера. Но с капчей писец.
на этом блоге стоит сабж, спама как видно нет.
На drupal.org есть модуль, реализующий схожую логику, но уже в "промышленном масштабе" : http://drupal.org/project/botcha. Там есть понятие "рецепт" и "книги рецептов" - модуль на основе правил, заложенных в рецепте, изменяет формы (список которых редактируется), позволяя боту выдать себя - а для пользователей форма выглядит абсолютно нормальной.
xandeadx, не выложишь готовый модуль для семерки?
у меня его нет
Тогда не поможешь?
simpleantispam_form_alter
как из этого примера не выводить чекбокс на семерке. У меня получилось его вывести, только если поставитьglobal $form
перед$form['imnotbot'] = array(
, не уверен, что это правильно.в семёрке id формы изменился. посмотри через
debug($form_id)
Спасибо за модуль. Можно пожалуйста пример использования при добавлении материала?
У меня есть 3 вопроса.
1. не проверял
2. не знаю
3. $_COOKIE['has_js']
Спасибо. Мне, почему-то, казалоось что эту куку устанавливает не друпал а какой-то счётчик :) .
Оставить комментарий