Como usar drupal_mail () para enviar emails com modelo personalizado

31

Gostaria de usar a drupal_mail()função para enviar e-mails, mas com um modelo HTML personalizado, para que eles estejam de acordo com o design do meu site, mas eu sou um novato em ganchos, módulos etc., por isso gostaria de algum tipo de explicação ou guia para iniciantes, por favor.

Eu mesmo posso criar o modelo, só preciso saber como drupal_mail()usá-lo.

Andy
fonte

Respostas:

39

Se você estiver tentando enviar e-mails através do seu módulo personalizado, siga o guia abaixo mencionado. Digamos, eu tive um módulo chamado "Commerce Canvas (commerce_canvas)" 1. Primeiro altere a função de correio do Drupal para oferecer suporte a links e adicionar outros tipos de codificação


/**
 * 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. Em seguida, conecte o HOOK_mail no seu módulo como

/**
 * 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. Então você precisa criar uma função de invólucro para chamar o email do seu módulo.

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

Esta função enviará o email e também criará mensagens de depuração se algo acontecer de errado. Mas você ainda não poderá enviar o correio em HTML porque precisa estender o DefaultMailSystem padrão do Drupal 7 com o seu. Então, faça o seguinte,


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


Em seguida, você precisa registrar uma nova função de tema que chamará seu arquivo de modelo personalizado em seu 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',
      ),

    );
  }
}

Por último, você precisa chamar essa função de tema no momento do envio do email como,



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

}

Esse é o trecho completo para manipular o email em HTML corretamente no Drupal 7, assim, no hook_theme, você pode fornecer seu modelo personalizado.

Aneek Mukhopadhyay
fonte
1
Muito obrigado pela sua resposta - é exatamente o que eu pedi! Infelizmente agora que vi o trabalho envolvido e que existem módulos por aí que poderiam fazer tudo por mim, acho que vou esperar antes de começar a criar meu próprio gancho. No entanto, não posso agradecer o suficiente por sua resposta, porque é tudo o que pedi. Eu gostaria de poder upvote mais de uma vez
Andy
11
Ótima resposta. Eu amo o jeito Drupal faz coisas básicas tão simples ;-)
artfulrobot
1
But still you won't be able to send the HTML mail..., direito.
Ejaz
@ Ejay, sim você pode. Isso faz isso.
Aneek Mukhopadhyay
1
Para constar: É mais fácil usar o seguinte módulo: drupal.org/project/simple_mail
gue
11

Se você deseja tema os e-mails enviados com a ajuda de modelos personalizados, use o módulo HTML Mail .

Permite que você tema as suas mensagens da mesma forma que o resto do seu site.

Funciona bem com outros módulos, como Print , Mail Mime , etc.

Você precisa instalar o módulo Sistema de Correio para usar o correio em HTML.

AjitS
fonte
1
Observe que o HTML Mail funciona com o módulo Mail Mime, e não o Mime Mail (o Mime Mail e o HTML Mail fazem coisas semelhantes e se substituem).
Patrick Kenny
@indrock Obrigado por sua resposta também. Você sabe se posso usar o módulo HTML Mail para enviar por tema os emails enviados usando o código php?
Andy
4

Exemplo de uso:

    $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
fonte
4
É sempre recomendável para enviar os e-mails usando drupal_mail(), em vez de $system->mail(..no fim de utilizar a hook_mail_alterfunção (que só funciona para e-mails enviados usando drupal_mail().
AjitS
Estou ciente de como usar a função (sintaxe / código), gostaria de saber como criar um tema para que eu possa aplicar a todos os emails enviados com drupal_mailetc, mas obrigado mesmo assim
Andy
Estou usando esse código, está funcionando bem, mas também um email em branco foi enviado.
vishal sirsodiya
3

Para enviar email em HTML, você pode usar o módulo Mimemail . Depois de instalado e configurado, você pode simplesmente preparar o modelo, nomeá-lo mimemail-message.tpl.php, soltá-lo no diretório do tema e ele será aplicado automaticamente a todos os emails de saída (assumindo que você configurou todos os emails para serem enviados pelo Mimemail) .

A configuração do módulo é provavelmente mais fácil do que substituir drupal_mail().

Patrick Kenny
fonte
Obrigado pela sua resposta! Posso enviar e-mails usando PHP com este módulo? Se sim, você poderia me mostrar como, por favor?
Andy
O Mimemail, quando combinado com o módulo Sistema de Correio, assume todos os e-mails enviados pelo site. Assim, todos os e-mails enviados por qualquer módulo, incluindo módulos personalizados, serão automaticamente enviados pelo Mimemail. Se você deseja limitar quais emails são afetados, pode usar as opções de configuração dos módulos do sistema de email.
Patrick Kenny
1
Acho que não foi exatamente isso que Andy perguntou. É verdade que você precisará do módulo Mimemail ou role seu próprio MailSystem para fazer isso, mas Andy poderá ser perguntado sobre como tema o corpo do email que deve ser feito na função hook_mail () e um tema ('my_custom_theme') nele?
precisa saber é
1
Acho que @Andy quer saber se o módulo Mimemail tem uma função que pode ser chamada para enviar e-mails.
kiamlaluno
@kiamlaluno Você está correto, é isso que eu gostaria de saber, por favor #
Andy Andy