Как использовать drupal_mail () для отправки писем с пользовательским шаблоном

31

Я хотел бы использовать эту drupal_mail()функцию для отправки электронных писем, но с собственным шаблоном HTML, чтобы они соответствовали дизайну моего веб-сайта, но я являюсь новичком в области хуков, модулей и т. Д., Поэтому я был бы признателен за какое-то объяснение или Руководство для начинающих, пожалуйста.

Я могу создать шаблон самостоятельно, мне просто нужно знать, как drupal_mail()его использовать.

Энди
источник

Ответы:

39

Если вы пытаетесь отправить почту через свой пользовательский модуль, вы можете следовать приведенному ниже руководству. Скажем, у меня был один модуль под названием «Commerce Canvas (commerce_canvas)» 1. Сначала измените почтовую функцию Drupal для поддержки ссылок и добавьте другие типы кодировки


/**
 * Implements hook_mail_alter()
 * @param string $message
 */
function commerce_canvas_mail_alter(&$message) {
    $headers = array(
        'MIME-Version' => '1.0',
        'Content-Type' => 'text/html; charset=iso-8859-1; format=flowed',
        'Content-Transfer-Encoding' => '8Bit',
        'X-Mailer' => 'Drupal',
    );
    foreach ($headers as $key => $value) {
        $message['headers'][$key] = $value;
    }
}
  1. Затем, подключите HOOK_mail в вашем модуле как

/**
 * Implements hook_mail()
 * @param string $key
 * @param string $message
 * @param unknown_type $params
 */
function commerce_canvas_mail($key, &$message, $params) {

    //Language Selection
    $options = array(
        'langcode' => $message['language']->language,
    );
    switch($key) {
        case "user_payment_notification" :
            $message['subject'] = isset($params['subject']) ? $params['subject'] : $message['subject'] = t('Payment recieved @site-name', array('@site-name' => variable_get('site_name', 'Express Canvas')), $options);
            $message['body'][] = isset($params['body']) ? $params['body'] : NULL;
            if (isset($params['headers']) && is_array($params['headers'])) {
                $message['headers'] += $params['headers'];
            }
            break;
    }
}


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

function commerce_canvas_mail_send(array $values = array()) {
    $module = $values['module'];
    $key = $values['key'];
    $to = $values['to'];
    $from = $values['form'];
    $language = isset($values['lang']) ? $values['lang'] : language_default();
    $params = array(
        'subject' => $values['subject'],
        'body' => $values['body'],
    );
    if(array_key_exists('headers', $values)) {
        $params['headers'] = $values['headers']; //Assumed as an array
    }
    $send = TRUE;
    $mail = drupal_mail($module, $key, $to, $language, $params, $from, $send);
    if($mail['result']) {
        return TRUE;
    } else {
        $error_msg = 'Failed to send the email in commerce_canvas Module';
        watchdog('canvas-email', $error_msg, array(), WATCHDOG_ALERT);
        return FALSE;
    }
}

Эта функция отправит электронное письмо, а также создаст отладочные сообщения, если что-то случится не так. Но, тем не менее, вы не сможете отправлять почту в формате HTML, потому что вам нужно расширить DefaultMailSystem по умолчанию в Drupal 7 своей собственной. Так что нужно сделать следующим образом,


class CommerceCanvasMailSystem extends DefaultMailSystem {
    /**
     * Concatenate and wrap the e-mail body for plain-text mails.
     *
     * @param $message
     *   A message array, as described in hook_mail_alter().
     *
     * @return
     *   The formatted $message.
     */
    public function format(array $message) {
        $message['body'] = implode("\n\n", $message['body']);
        return $message;
    }

    /**
     * Send an e-mail message, using Drupal variables and default settings.
     *
     * @see http://php.net/manual/en/function.mail.php
        * @see drupal_mail()
     *
     * @param $message
     *   A message array, as described in hook_mail_alter().
     * @return
     *   TRUE if the mail was successfully accepted, otherwise FALSE.
     */
    public function mail(array $message) {
        $mimeheaders = array();
        foreach ($message['headers'] as $name => $value) {
            $mimeheaders[] = $name . ': ' . mime_header_encode($value);
        }
        $line_endings = variable_get('mail_line_endings', MAIL_LINE_ENDINGS);
        return mail(
        $message['to'],
        mime_header_encode($message['subject']),
        // Note: e-mail uses CRLF for line-endings. PHP's API requires LF
        // on Unix and CRLF on Windows. Drupal automatically guesses the
        // line-ending format appropriate for your system. If you need to
        // override this, adjust $conf['mail_line_endings'] in settings.php.
        preg_replace('@\r?\n@', $line_endings, $message['body']),
        // For headers, PHP's API suggests that we use CRLF normally,
        // but some MTAs incorrectly replace LF with CRLF. See #234403.
        join("\n", $mimeheaders)
        );
    }
}


Затем вам нужно зарегистрировать новую функцию темы, которая будет вызывать ваш файл шаблона в вашем hook_theme ().


/**
 * Implements hook_theme();
 */
function commerce_canvas_theme($existing, $type, $theme, $path) {
  if($type == 'module') {
    return array(
      'tracking_code_email' => array(
        'variables' => array(
          'image_path' => NULL,
          'user' => NULL,
          'page' => NULL,
        ),
        'template' => 'commerce-canvas-tracking-code',
        'path' => drupal_get_path('module', 'commerce_canvas').'/theme',
      ),

    );
  }
}

Наконец, вам нужно вызвать эту функцию темы во время отправки электронной почты, как,



function a_custom_function($params) {

$email_text_user = theme('tracking_code_email', array(
                    'image_path' => $base_url . '/' . drupal_get_path('module', 'commerce_canvas') . '/images',
                    'user' => null,
                    'page' => array(
                        'greet_text' => t('Thank you for your order at Express Canvas. Your order is ready and has shipped. You may track your order using FedEx tracking with your tracking number: '.$order->field_tracking_number['und']['0']['value'].''),

                    ),
                ));
$sent_to_user = commerce_canvas_mail_send($email_values_user);

}

Это полный фрагмент кода для корректной обработки электронной почты в формате HTML в Drupal 7, поэтому в hook_theme вы можете указать свой собственный шаблон.

Анек Мухопадхяй
источник
1
Большое спасибо за ваш ответ - это именно то, что я просил! К сожалению, теперь, когда я увидел проделанную работу и что есть модули, которые могут сделать все для меня, я подожду, прежде чем спешу создать свой собственный хук. Тем не менее, я не могу отблагодарить вас за ваш ответ, потому что это все, что я просил. Хотелось бы, чтобы я проголосовал более одного раза
Энди
11
Отличный ответ. Мне нравится, как Drupal делает простые вещи такими простыми ;-)
artfulrobot
1
But still you won't be able to send the HTML mail..., правильно.
Ejaz
@ Эджей, да, можешь. Это делает это.
Aneek Mukhopadhyay
1
Для справки
gue
11

Если вы хотите создать тему для исходящей почты с помощью пользовательских шаблонов, вам следует использовать модуль Почта HTML .

Позволяет создавать темы для ваших сообщений так же, как и для остальной части вашего сайта.

Хорошо работает с другими модулями, такими как Print , Mail Mime и т. Д.

Вы должны установить модуль Почтовой системы , чтобы использовать почту HTML.

AjitS
источник
1
Обратите внимание, что HTML Mail работает с модулем Mail Mime, а не с Mime Mail (Mime Mail и HTML Mail делают схожие вещи и переопределяют друг друга).
Патрик Кенни
@indrock Спасибо за ваш ответ тоже. Знаете ли вы, можно ли использовать модуль «Почта HTML» для писем темы, отправленных с использованием кода php?
Энди
4

Пример использования:

    $module = 'module_name';
    $key = 'key';
    $language = language_default();
    $params = array();
    $from = NULL;
    $send = FALSE;
    $message = drupal_mail($module, $key, $email, $language, $params, $from, $send);

    $message['subject'] = $subject;
    $message['body'] = array();
    $message['body'][] = $line1;
    $message['body'][] = $line2;

    // Retrieve the responsible implementation for this message.
    $system = drupal_mail_system($module, $key);

    // Format the message body.
    $message = $system->format($message);

    // Send e-mail.
    $message['result'] = $system->mail($message);
monymirza
источник
4
Всегда рекомендуется отправлять письма, используя, drupal_mail()а не $system->mail(..использовать эту hook_mail_alterфункцию (которая работает только для писем, отправленных с использованием drupal_mail().
AjitS
Я полностью осведомлен о том, как использовать функцию (с точки зрения синтаксиса и кода), я просто хотел бы знать, как создать тему, чтобы я мог применять ее ко всем электронным письмам, отправленным с помощью drupal_mailetc, но все равно спасибо
Andy
Я использую этот код, он работает нормально, но также отправлено одно пустое письмо.
Вишал Сирсодия
3

Для отправки электронной почты в формате HTML вы можете использовать модуль Mimemail . После того, как он настроен и настроен, вы можете просто подготовить шаблон, mimemail-message.tpl.phpдать ему имя, поместить его в каталог вашей темы, и он будет автоматически применен ко всей исходящей электронной почте (при условии, что вы настроили всю почту для отправки Mimemail) ,

Настройка модуля, вероятно, проще, чем переопределение drupal_mail().

Патрик Кенни
источник
Спасибо за ваш ответ! Могу ли я отправлять электронные письма, используя PHP с этим модулем? Если да, не могли бы вы показать мне, пожалуйста?
Энди
Mimemail, в сочетании с модулем почтовой системы, принимает все электронные письма, отправленные сайтом. Таким образом, все электронные письма, отправленные любым модулем, включая пользовательские модули, будут автоматически отправляться через Mimemail. Если вы хотите ограничить влияние на электронную почту, вы можете использовать параметры конфигурации модулей почтовой системы.
Патрик Кенни
1
Я думаю, что это не то, что Энди спросил точно. Правда, вам понадобится модуль Mimemail или сверните собственную MailSystem, чтобы сделать это, но может быть, Энди спросили, как создать тему для тела письма, что должно быть сделано в функции hook_mail () и вызове theme ('my_custom_theme')?
AyeshK
1
Я думаю, @Andy хочет знать, есть ли в модуле Mimemail функция, которую можно вызывать для отправки электронных писем.
kiamlaluno
@kiamlaluno Вы правы, это то, что я хотел бы знать, пожалуйста
Энди