На прошлой неделе один из клиентов захотел иметь возможность отправлять из админки письмо свом подписчикам с возможностью прикрепления файла. Конечно, можно было сделать закачку файла из формы на сайт и отправку в письме ссылки на скачивание файла, но, помимо определенных плюсов такого решения, очевидный минус, а именно накапливание ненужных файлов на сервере, заставил меня даже не предлагать клиенту такое костыльное решение.
Итак, по счастью, как правило, в Друпале изобретать велосипед приходится крайне редко, главное уметь найти готовое решение на drupal.org. Признаюсь, что пришлось потратить определенное время, чтобы его найти и именно по этому я пишу это сообщение, чтобы сэкономить Ваше время, если перед Вами встанет такая задача.
Мой выбор пал на Mime Mail модуль (http://drupal.org/project/mimemail), другой альтернативы я не нашел.
Для простоты понимания, разбавлю свое повествование примерами (позволю себе выбрать Drupal 6, что связано с тем, что сайта заказчика был на шестерке). Для начала сделаем формочку, для ввода письма и прикрепления файла:
В зависимости от задачи, можно не делать новую форму, а модиффицировать существующую, добавив поле file и функцию обработчик с помощью хука form_alter.
Не буду останавиливаться на валидации данных формы, замечу, что, по крайней мере, поле 'mail_to' нужно отвалидировать. Напишу сразу обработчик этой формы:
Надеюсь, коментариев в коде достаточно, чтобы понять, как это работет. Получатель получит письмо с одним прикрепленным файлом…
Более подробно об использовании функции mimemail() можно почитать в README.txt модуля Mime Mail.
P.S.: Благодарю за обсуждение материала и замечания. Помимо комментариев мне пришло несколько писем с ценными замечаниями. Думаю стоит поделиться тем, что написал мне rrromka:
«Рассылать письма можно всем зарегистрированным пользователям (с фильтром по ролям, например) вне зависимости от того, подписывался пользователь на рассылку явно или нет. Нужно поставить модуль drupal.org/project/simplenews_roles, затем тут: admin/content/simplenews/types в настройках нужной рассылки (рассылка это термин из словаря, который автоматом создает simplenews) указать юзеров из какой роли прикрепить к этой рассылке. А потом как обычно: создаешь материал типа «рассылка», выбираешь рассылку и отправляешь.»
Это замечание еще раз показывает то, что практически все типовые задачи уже решены на drupal.org нужно просто искать, задавать вопросы на специализированных форумах и больше практиковаться :-)
Итак, по счастью, как правило, в Друпале изобретать велосипед приходится крайне редко, главное уметь найти готовое решение на drupal.org. Признаюсь, что пришлось потратить определенное время, чтобы его найти и именно по этому я пишу это сообщение, чтобы сэкономить Ваше время, если перед Вами встанет такая задача.
Мой выбор пал на Mime Mail модуль (http://drupal.org/project/mimemail), другой альтернативы я не нашел.
Для простоты понимания, разбавлю свое повествование примерами (позволю себе выбрать Drupal 6, что связано с тем, что сайта заказчика был на шестерке). Для начала сделаем формочку, для ввода письма и прикрепления файла:
function custom_mail_form() {
$form['#attributes'] = array('enctype' => "multipart/form-data"); // чтобы файлы передавались в функцию обработчик
$form['mail_to'] = array(
'#type' => 'textfield',
'#title' => t('E-mail'),
'#required' => TRUE,
);
$form['mail_subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#required' => TRUE,
);
$form['mail_body'] = array(
'#type' => 'textarea',
'#title' => t('Body'),
'#required' => TRUE,
);
$form['mail_attachment'] = array(
'#type' => 'file',
'#title' => t('Attachment'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Send'),
);
return $form;
}
В зависимости от задачи, можно не делать новую форму, а модиффицировать существующую, добавив поле file и функцию обработчик с помощью хука form_alter.
Не буду останавиливаться на валидации данных формы, замечу, что, по крайней мере, поле 'mail_to' нужно отвалидировать. Напишу сразу обработчик этой формы:
function custom_mail_form_submit($form, &$form_state) {
$folder = file_directory_path()."/mail/"; // назначаем папку, куда будут загружаться прикрепляемые к письму файлы, она должна существовать и быть доступна для записи
$attachment = array(); // массив для данных для прикрепленных файлов
if ($file = file_save_upload('mail_attachment', array(), $folder)) { // загружаем файл
$attachment[] = $file; // помещаем данные о загруженном файле в массив аттачментов
} // в нашем примере аттачмент только один, но, вообще говоря, их может быть много
if (module_exists('mimemail')) { // проверяем, что модуль включен
$message_result = mimemail( // вызываем функцию mimemail, которая умеет отправлять письма с прикрепленными файлами
variable_get('site_mail', ini_get('sendmail_from')), // адрес отправителя
$form_state['values']['mail_to'], // адрес получателя
$form_state['values']['mail_subject'], // тема письма
$form_state['values']['mail_body'], // тело письма в формате HTML, его можно не указывать, если следующий параметр TRUE
TRUE, // этот флаг указывает, что письмо нужно отправлять только в формате plaintext
array(), // сюда можно послать дополнительные хедары для письма в виде ассоциативного массива
check_plain($form_state['values']['mail_body']), // этим параметром мы должны отправить тело письма в формате plaintext, вместо функции check_plain() можно использовать любой другой удобный вам способ фильтрации html тегов
$attachment, // а вот сюда передаем массив объектов типа files, в данном примере у нас один прикрепленный файл
'' // в этом параметре можно передать текстовый идентификатор сообщения, параметр не обязательный
); // функция возвращает TRUE, если письмо отправлено успешно
if($message_result) // проверяем результат отправки письма
drupal_set_message("Mail was sent to ".$form_state['values']['mail_to']);
else
drupal_set_message("Mail was not sent to ".$form_state['values']['mail_to'], "error");
if(count($attachment))
file_delete($attachment[0]->filepath); // удаляем с сайта прикрепленный к письму файл, чтобы не засорять файловую систему
}
else{
drupal_set_message("Please install <a href="http://drupal.org/project/mimemail">Mime Mail</a> module ".$mail, "error"); // просим установить необходимый нам для работы модуль
}
}
Надеюсь, коментариев в коде достаточно, чтобы понять, как это работет. Получатель получит письмо с одним прикрепленным файлом…
Более подробно об использовании функции mimemail() можно почитать в README.txt модуля Mime Mail.
P.S.: Благодарю за обсуждение материала и замечания. Помимо комментариев мне пришло несколько писем с ценными замечаниями. Думаю стоит поделиться тем, что написал мне rrromka:
«Рассылать письма можно всем зарегистрированным пользователям (с фильтром по ролям, например) вне зависимости от того, подписывался пользователь на рассылку явно или нет. Нужно поставить модуль drupal.org/project/simplenews_roles, затем тут: admin/content/simplenews/types в настройках нужной рассылки (рассылка это термин из словаря, который автоматом создает simplenews) указать юзеров из какой роли прикрепить к этой рассылке. А потом как обычно: создаешь материал типа «рассылка», выбираешь рассылку и отправляешь.»
Это замечание еще раз показывает то, что практически все типовые задачи уже решены на drupal.org нужно просто искать, задавать вопросы на специализированных форумах и больше практиковаться :-)