Модуль для отправления почтовых сообщений в Drupal 6

Требуется

Форма обратной связи для Drupal 6 на почтуОтправить почту с сайта на Drupal 6 минимизировав наличие спамеров и капчи.

Отправляю почту

Подготовка

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

Что-бы отогнать спамерских ботов почту можно сгенерить целиком на jQuery или вставить как html, но не оборачивая её в тег <form> (да простит меня валидатор) - роботы будут очень озадачены. Отправку сообщения делаю через $.post(), что отрубит нафик 99% ботов.

Создание формы не описываю, т.к. это очень простая задача. Я её просто вбил в шаблон типа контента в котором содержится информация о сферической организации в вакууме.

Тут же добавил ссылку на свой JavaScript который реализует всю логику работы формы:  drupal_add_js(drupal_get_path('module', 'MY_MODULE') . '/js/contact.js', 'module');

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

Реализация

Создаю путь для приёма почты. Для этого в своём модуле в hook_menu прописываю вызов своей функции при переходе на определённый урл.

$items['my/contact/form'] = array(
  'path' => 'my/contact/form',
  'title' => 'Contact form',
  'access arguments' => array(),
  'page callback' => 'mymodule_contact',
  'access arguments' => array('submit organization form'),
  'type' => MENU_CALLBACK,
);

Теперь по адресу /my/contact/form будет вылазить мой обработчик в виде функции mymodule_contact. Всё, что будет передано после этого адреса пойдёт в параметры функции.

Далее обработчик. Тупая функция, которая выполняет ряд проверок формы на валидность и выводит результат если всё хорошо или всё плохо.

/**
* Submit via e-mail organization contact form
*/
function MYMODULE_contact($param1 = '') {
if (ПРОВЕРКА_НА_СПАМ_И_НА_ВАЛИДНОСТЬ_ОБЯЗАТЕЛЬНЫХ_ПАРАМЕТРОВ) {
$result = array('ok' => FALSE, 'msg' => '', 'success' => TRUE);
if (!empty($_POST['field1']) and !empty($_POST['field5']) and !empty($_POST['field6'])) {
if (!preg_match('/^[_a-z0-9а-я-]+(\.[_a-zа-я0-9-]+)*@[a-zа-я0-9-]+(\.[a-zа-я0-9-]+)*\.[a-zа-я]{2,6}$/ui', $_POST['field5'])) {
$result['msg'] = 'Указан неверный контактый е-мейл';
}
else {
$node = node_load($_POST['nid']);
if (isset($node->field_mail[0]['value']) and !empty($node->field_mail[0]['value'])) {
$mail = array(
'id' => 'my_module_form_contact_organization',
'to' => $node->field_mail[0]['value'],
'subject' => '=?UTF-8?B?'.base64_encode('Заполнена форма обратной связи на сайте example.com').'?=',
'body' => drupal_wrap_mail(
<<<MSG

Имя, фамилия, отчество: {$_POST['field1']}
Организация: {$_POST['field2']}
Должность: {$_POST['field3']}
Телефон: {$_POST['field4']}
Контактый е-мейл: {$_POST['field5']}
Сообщение:
{$_POST['field6']}

MSG
),
'headers' => array(
'Reply-To' => $_POST['field5'],
'Content-Type' => 'text/plain',
'Charset' => 'utf-8',
'Mime-Version' => '1.0',
'Content-Transfer-Encoding' => '8bit',
'Content-Disposition' => 'inline',
),
);
if (drupal_mail_send($mail)) {
$result['ok'] = TRUE;
}
else {
$result['msg'] = 'Ошибка на сервере - попробуйте повторить позже!';
}
}
}
}
else {
$result['msg'] = 'Не заполнены все обязательные поля!';
}
print drupal_json($result);
} else {
// hello spamers! :D
drupal_goto('<front>');
}
exit();
}

На этом с обработчиком вроде как всё закончено - после правок под себя код должен завестить.

Теперь jQuery

В contact.js вбиваю вот такой примитивный код:

$(document).ready(function(){
  $('#MY_FORM_ID button.submit').click(function(){
    $.post(MY_MODULE_URL +'/'+ MY_MODULE_NID,
      {
        nid: MY_MODULE_NID,
        field1: $('#field1').val(),
        field2: $('#field2').val(),
        field3: $('#field3').val(),
        field4: $('#field4').val(),
        field5: $('#field5').val(),
        field6: $('#field6').val(),
        field7: $('#field6').val(),
        field8: $('#field6').val(),
        field9: $('#field6').val(),
      },
      function(data) {
        if (data.msg) {
          alert(data.msg);
        }
        if (data.ok) {
          $('#MY_FORM_ID').html('<h3>Форма успешно отправлена</h3>');
        }
      }, "json");
    });
});

При желании можно дополнительно навесить обработчик ошибок, но не забываем обязательно всё проверять на стороне сервера - подсунуть левые данные как два пальца об асфальт.

А причём здесь Drupal?

Основное таинство отправки сообщения - это правильно сформировать массив сообщения в функции MYMODULE_contact и подсунуть его drupal_mail_send();

 

Вроде всё. Успехов в программировании для Drupal.

Подозреваю что код с минимальными правками сможет мигрировать на Drupal 7, когда будет такая необходимость.

PS: Прочитал? Пригодилось? Оцени, не жмись!

RSSAdd to Google

Обсуждение:

  • Автор: Dmitrii Varvashenia
  • первый комментарий в твитере порадовал.
    написали "велосипедно" и предложили скомбинировать webform и противоспамные модуля
    Загляните по ссылке - возможно там всё проще чем мне казалось :)
  • Отправлено:
  • Автор: (Анонимус)
  • Эх, я то уже прибежал, обрадовался, что тут емейлы через js рассылают. А это всего навсего ajax :(
  • Отправлено:
  • Автор: (Анонимус)
  • Ну и по делу, раз заглянул: отравлять письма надо drupal_mail() а не drupal_mail_send(). Ибо вторая функция - лишь часть полноценного обработчика.

  • Отправлено:
  • Автор: (Анонимус)
  • А! Ну и ещё - в js после вызова $.post() наверное надо return false; или preventDefault(); чтобы не отрабатывало стандартное нажание кнопки.

    Ну и совсем кошерно было бы подключить к форме модуль drupal.org/project/ajax, тогда можно было бы вообще обойтись без написания кастомного js, а сообщения выводить обычным drupal_set_message().

  • Отправлено:
  • Автор: Dmitrii Varvashenia
  • Спасибки за мысли.
    Изучу вопрос как мыло из жопы сроки достанут :)
    По поводу #.post() в моём случае волноваться не нужно - формы как такой нету только набор полей из которые читаются данные жабаскриптом. Так что дефолтного нажатия кнопки там нету. А в более обычных случаях - полностью согласен - нужно false ретурнить.
  • Отправлено:
  • Автор: (Анонимус)
  • И если уж совсем в разнос пойти, то существует функция valid_email_adress(), которая работает гораздо быстрее, чем регулярные выражения :)
  • Отправлено:

Как вам материальчик? *



















Тема:

Мысль:

Как звать-то:

Почта:

PS: Комментарии публикуются только после проверки модератором.

PPS: E-mail'ы не публикуются.

* обязательные поля