Cómo usar drupal_mail () para enviar correos electrónicos con plantillas personalizadas

31

Me gustaría usar la drupal_mail()función para enviar correos electrónicos, pero con una plantilla HTML personalizada para que estén en consonancia con el diseño de mi sitio web, pero soy un novato completo en ganchos y módulos, etc., por lo que agradecería algún tipo de explicación o Guía de principiantes por favor.

Puedo crear la plantilla yo mismo, solo necesito saber cómo drupal_mail()usarla.

Andy
fuente

Respuestas:

39

Si está intentando enviar los correos a través de su módulo personalizado, puede seguir la guía mencionada a continuación. Digamos que tenía un módulo llamado "Commerce Canvas (commerce_canvas)" 1. Primero modifique la función de correo de Drupal para admitir enlaces y agregar otros tipos de codificación


/**
 * 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. Luego, enganche el HOOK_mail en su 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. Luego debe crear una función de contenedor para invocar el correo desde su 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 función enviará el correo electrónico y creará mensajes de depuración si algo sucede mal. Pero aún así no podrá enviar el correo HTML porque necesita extender el DefaultMailSystem predeterminado de Drupal 7 con el suyo. Entonces necesito hacer lo siguiente,


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


A continuación, debe registrar una nueva función de tema que llamará a su archivo de plantilla personalizada en su 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, debe llamar a esta función de tema a la hora de enviar el correo electrónico 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);

}

Estos son los fragmentos completos para manejar el correo electrónico HTML correctamente en Drupal 7, por lo tanto, en el hook_theme puede dar su plantilla personalizada.

Aneek Mukhopadhyay
fuente
1
Muchas gracias por su respuesta, ¡es exactamente lo que pedí! Desafortunadamente, ahora que he visto el trabajo involucrado y que hay módulos que pueden hacer todo por mí, creo que esperaré antes de apresurarme a crear mi propio gancho. Sin embargo, no puedo agradecerle lo suficiente por su respuesta porque es todo lo que pedí. Desearía poder votar más de una vez
Andy
11
Gran respuesta. Me encanta la forma en que Drupal hace las cosas básicas tan simples ;-)
artfulrobot
1
But still you won't be able to send the HTML mail..., Derecha.
Ejaz
@Ejay, sí puedes. Esto hace eso.
Aneek Mukhopadhyay
1
Para el registro: es más fácil usar el siguiente módulo: drupal.org/project/simple_mail
gue
11

Si desea crear un tema para los correos salientes con la ayuda de plantillas personalizadas, debe usar el módulo de correo HTML .

Le permite tema sus mensajes de la misma manera que tema el resto de su sitio web.

Funciona bien con otros módulos, como Print , Mail mime , etc.

Debe instalar el módulo del sistema de correo para utilizar el correo HTML.

AjitS
fuente
1
Tenga en cuenta que HTML Mail funciona con el módulo Mail Mime, no con Mime Mail (Mime Mail y HTML Mail hacen cosas similares y se anulan entre sí).
Patrick Kenny el
@indrock Gracias por tu respuesta también. ¿Sabes si puedo usar el módulo de correo HTML para enviar correos electrónicos temáticos enviados con código php?
Andy
4

Ejemplo 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
fuente
44
Siempre se recomienda enviar los correos usando en drupal_mail()lugar de $system->mail(..usar la hook_mail_alterfunción (que solo funciona para los correos enviados usando drupal_mail().
AjitS
Soy completamente consciente de cómo usar la función (sintaxis / código inteligente), solo me gustaría saber cómo hacer un tema para poder aplicar a todos los correos electrónicos enviados con drupal_mailetc., pero gracias de todos modos
Andy
Estoy usando este código, está funcionando bien, pero también ha enviado un correo en blanco.
vishal sirsodiya
3

Para enviar correo electrónico HTML, puede usar el módulo Mimemail . Una vez que está configurado y configurado, simplemente puede preparar la plantilla, nombrarla mimemail-message.tpl.php, soltarla en su directorio de temas y se aplicará automáticamente a todos los correos electrónicos salientes (suponiendo que haya configurado todo el correo para que Mimemail lo envíe) .

Configurar el módulo es probablemente más fácil que anularlo drupal_mail().

Patrick Kenny
fuente
¡Gracias por su respuesta! ¿Puedo enviar correos electrónicos usando PHP con este módulo? Si es así, ¿podría mostrarme cómo, por favor?
Andy
Mimemail, cuando se combina con el módulo del Sistema de Correo, se hará cargo de todos los correos electrónicos enviados por el sitio. Por lo tanto, todos los correos electrónicos enviados por cualquier módulo, incluidos los módulos personalizados, se enviarán automáticamente a través de Mimemail. Si desea limitar qué correos electrónicos se ven afectados, puede usar las opciones de configuración de módulos del Sistema de correo.
Patrick Kenny el
1
Creo que esto no es lo que Andy preguntó exactamente. Es cierto, necesitará el módulo Mimemail o rodará su propio MailSystem para hacer esto, pero se le puede preguntar a Andy sobre cómo crear un tema para el cuerpo del correo electrónico que se debe hacer en la función hook_mail () y una llamada de tema ('my_custom_theme').
AyeshK
1
Creo que @Andy quiere saber si el módulo Mimemail tiene una función a la que se pueda llamar para enviar correos electrónicos.
kiamlaluno
@kiamlaluno Tienes razón, esto es lo que me gustaría saber, por favor
Andy