Pull to refresh

Отправка письма с прикрепленным файлом из Drupal

Reading time4 min
Views6.4K
На прошлой неделе один из клиентов захотел иметь возможность отправлять из админки письмо свом подписчикам с возможностью прикрепления файла. Конечно, можно было сделать закачку файла из формы на сайт и отправку в письме ссылки на скачивание файла, но, помимо определенных плюсов такого решения, очевидный минус, а именно накапливание ненужных файлов на сервере, заставил меня даже не предлагать клиенту такое костыльное решение.

Итак, по счастью, как правило, в Друпале изобретать велосипед приходится крайне редко, главное уметь найти готовое решение на 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 нужно просто искать, задавать вопросы на специализированных форумах и больше практиковаться :-)

Tags:
Hubs:
Total votes 37: ↑30 and ↓7+23
Comments12

Articles