วิธีใช้ 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. จากนั้นคุณต้องสร้างฟังก์ชัน wrapper เพื่อเรียกใช้เมลจากโมดูลของคุณ

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
ขอบคุณมากสำหรับคำตอบของคุณ - เป็นสิ่งที่ฉันขอ! น่าเสียดายที่ตอนนี้ฉันได้เห็นงานที่เกี่ยวข้องและมีโมดูลที่สามารถทำทุกอย่างให้ฉันฉันคิดว่าฉันจะรอก่อนที่จะรีบสร้างเบ็ดของตัวเอง อย่างไรก็ตามฉันไม่สามารถขอบคุณมากพอสำหรับคำตอบของคุณเพราะมันเป็นทุกสิ่งที่ฉันขอ ฉันหวังว่าฉันจะโหวตได้มากกว่าหนึ่งครั้ง
Andy

11
คำตอบที่ดี ฉันชอบวิธีที่ Drupal ทำสิ่งพื้นฐานให้เรียบง่าย ;-)
artfulrobot

1
But still you won't be able to send the HTML mail...ใช่
Ejaz

@Ejay ใช่คุณสามารถ สิ่งนี้ทำ
Aneek Mukhopadhyay

1
สำหรับบันทึก: มันง่ายขึ้นโดยใช้โมดูลดังต่อไปนี้: drupal.org/project/simple_mail
Gue

11

หากคุณต้องการจัดรูปแบบเมลขาออกด้วยความช่วยเหลือของเทมเพลตที่กำหนดเองคุณควรใช้โมดูลHTML Mail

ให้คุณจัดรูปแบบข้อความของคุณในลักษณะเดียวกับที่คุณจัดวางส่วนที่เหลือของเว็บไซต์

มันทำงานได้ดีกับโมดูลอื่น ๆ เช่นPrint , Mail mimeเป็นต้น

คุณต้องติดตั้งโมดูลระบบเมลเพื่อใช้งานเมล HTML


1
โปรดทราบว่าเมล HTML ทำงานร่วมกับโมดูล Mail Mime ไม่ใช่ Mime Mail (Mime Mail และ HTML Mail ทำสิ่งที่คล้ายกันและแทนที่กัน)
Patrick Kenny

@indrock ขอบคุณสำหรับคำตอบของคุณด้วย คุณรู้หรือไม่ว่าฉันสามารถใช้โมดูลอีเมล HTML เพื่อส่งอีเมลธีมที่ส่งโดยใช้รหัส PHP ได้
Andy

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);

4
ขอแนะนำเสมอให้ส่งอีเมลโดยใช้drupal_mail()แทนที่จะ$system->mail(..ใช้hook_mail_alterฟังก์ชัน (ซึ่งใช้ได้กับจดหมายที่ส่งโดยใช้drupal_mail()เท่านั้น
AjitS

ฉันตระหนักถึงวิธีการใช้ฟังก์ชั่น (ไวยากรณ์ / รหัสฉลาด) ฉันแค่อยากจะรู้วิธีการทำชุดรูปแบบเพื่อให้ฉันสามารถนำไปใช้กับอีเมลทั้งหมดที่ส่งมาด้วยdrupal_mailฯลฯ แต่ขอขอบคุณอยู่แล้ว
Andy

ฉันใช้รหัสนี้มันใช้งานได้ดี แต่มีจดหมายว่างเปล่าส่ง
vishal sirsodiya

3

ในการส่งอีเมล HTML คุณสามารถใช้โมดูลMimemail เมื่อตั้งค่าและกำหนดค่าแล้วคุณสามารถเตรียมเทมเพลตตั้งชื่อmimemail-message.tpl.phpวางไว้ในไดเรกทอรีธีมของคุณและมันจะถูกนำไปใช้กับอีเมลขาออกทั้งหมดโดยอัตโนมัติ (สมมติว่าคุณได้กำหนดค่าเมลทั้งหมดที่จะส่งออกโดย Mimemail) .

drupal_mail()การตั้งค่าโมดูลอาจจะง่ายกว่าเอาชนะ


ขอบคุณสำหรับคำตอบ! ฉันสามารถส่งอีเมลโดยใช้ PHP ด้วยโมดูลนี้ได้หรือไม่ ถ้าเป็นเช่นนั้นคุณช่วยบอกฉันหน่อยได้ไหมว่า?
Andy

Mimemail เมื่อรวมกับโมดูล Mail System จะเข้าควบคุมอีเมลทั้งหมดที่ส่งมาจากเว็บไซต์ ดังนั้นอีเมลทั้งหมดที่ส่งโดยโมดูลใด ๆ รวมถึงโมดูลที่กำหนดเองจะถูกส่งออกโดยอัตโนมัติผ่าน Mimemail หากคุณต้องการ จำกัด อีเมลที่ได้รับผลกระทบคุณสามารถใช้ตัวเลือกการกำหนดค่าโมดูลของระบบจดหมาย
Patrick Kenny

1
ฉันคิดว่านี่ไม่ใช่สิ่งที่แอนดี้ถามอย่างแน่นอน True คุณจะต้องโมดูล Mimemail หรือม้วน MailSystem ของคุณเองจะทำเช่นนี้ แต่อาจจะมีแอนดี้ถามเกี่ยวกับวิธีการรูปแบบร่างกายอีเมลที่ควรจะทำใน hook_mail () ฟังก์ชั่นและรูปแบบ ( 'my_custom_theme') การโทรในมันได้หรือไม่
AyeshK

1
ฉันคิดว่า @Andy ต้องการทราบว่าโมดูล Mimemail มีฟังก์ชั่นที่สามารถเรียกให้ส่งอีเมลได้หรือไม่
kiamlaluno

@kiamlaluno คุณถูกต้องนี่คือสิ่งที่ฉันต้องการทราบโปรด
Andy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.