Comment utiliser drupal_mail () pour envoyer des e-mails avec un modèle personnalisé

31

Je voudrais utiliser la drupal_mail()fonction pour envoyer des e-mails mais avec un modèle HTML personnalisé afin qu'ils soient conformes à la conception de mon site Web, mais je suis un débutant complet pour les crochets et les modules, etc., donc j'apprécierais une sorte d'explication ou guide débutant s'il vous plaît.

Je peux créer le modèle moi-même, j'ai juste besoin de savoir comment l' drupal_mail()utiliser.

Andy
la source

Réponses:

39

Si vous essayez d'envoyer les e-mails via votre module personnalisé, vous pouvez suivre le guide mentionné ci-dessous. Disons, j'avais un module appelé "Commerce Canvas (commerce_canvas)" 1. Tout d'abord, modifiez la fonction de messagerie de Drupal pour prendre en charge les liens et ajouter d'autres types d'encodage


/**
 * 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. Ensuite, connectez le HOOK_mail dans votre module comme

/**
 * 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. Ensuite, vous devez créer une fonction wrapper pour appeler le courrier à partir de votre module.

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

Cette fonction enverra l'e-mail et créera des messages de débogage en cas de problème. Mais vous ne pourrez toujours pas envoyer le courrier HTML car vous devez étendre le DefaultMailSystem par défaut de Drupal 7 avec le vôtre. Il faut donc faire comme suit,


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


Ensuite, vous devez enregistrer une nouvelle fonction de thème qui appellera votre fichier de modèle personnalisé dans votre 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',
      ),

    );
  }
}

Enfin, vous devez appeler cette fonction de thème au moment d'envoyer l'e-mail en tant que,



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

}

Ce sont l'extrait complet pour gérer correctement l'e-mail HTML dans Drupal 7, ainsi dans le hook_theme, vous pouvez donner votre modèle personnalisé.

Aneek Mukhopadhyay
la source
1
Merci beaucoup pour votre réponse - c'est exactement ce que j'ai demandé! Malheureusement, maintenant que j'ai vu le travail impliqué et qu'il existe des modules qui pourraient tout faire pour moi, je pense que j'attendrai avant de me précipiter pour créer mon propre crochet. Cependant, je ne vous remercierai jamais assez pour votre réponse car c'est tout ce que j'ai demandé. J'aimerais pouvoir voter plus d'une fois
Andy
11
Très bonne réponse. J'adore la façon dont Drupal rend les choses de base si simples ;-)
artfulrobot
1
But still you won't be able to send the HTML mail..., droite.
Ejaz
@Ejay, oui, vous le pouvez. Cela fait ça.
Aneek Mukhopadhyay
1
Pour mémoire: il est plus facile d'utiliser le module suivant: drupal.org/project/simple_mail
gue
11

Si vous souhaitez thématiser les e-mails sortants à l'aide de modèles personnalisés, vous devez utiliser le module HTML Mail .

Vous permet de thème vos messages de la même manière que vous le thème du reste de votre site Web.

Il fonctionne bien avec d'autres modules, comme Print , Mail mime , etc.

Vous devez installer le module Mail System pour utiliser la messagerie HTML.

AjitS
la source
1
Veuillez noter que HTML Mail fonctionne avec le module Mail Mime, et non Mime Mail (Mime Mail et HTML Mail font des choses similaires et se remplacent).
Patrick Kenny
@indrock Merci aussi pour votre réponse. Savez-vous si je peux utiliser le module HTML Mail pour thèmeer les e-mails envoyés en utilisant du code php?
Andy
4

Exemple d'utilisation:

    $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
la source
4
Il est toujours recommandé d'envoyer les mails en utilisant drupal_mail()plutôt que $system->mail(..pour utiliser la hook_mail_alterfonction (qui ne fonctionne que pour les mails envoyés en utilisant drupal_mail().
AjitS
Je suis parfaitement conscient de l'utilisation de la fonction (syntaxe / code), je voudrais juste savoir comment créer un thème afin de pouvoir appliquer à tous les e-mails envoyés avec drupal_mailetc, mais merci quand même
Andy
J'utilise ce code, il fonctionne très bien, mais aussi un courrier vierge a été envoyé.
vishal sirsodiya
3

Pour envoyer des e-mails HTML, vous pouvez utiliser le module Mimemail . Une fois qu'il est installé et configuré, vous pouvez simplement préparer le modèle, le nommer mimemail-message.tpl.php, le déposer dans votre répertoire de thèmes et il sera automatiquement appliqué à tous les e-mails sortants (en supposant que vous avez configuré tous les e-mails à envoyer par Mimemail) .

La configuration du module est probablement plus facile que de remplacer drupal_mail().

Patrick Kenny
la source
Merci pour votre réponse! Puis-je envoyer des e-mails en utilisant PHP avec ce module? Si oui, pourriez-vous me montrer comment vous plaire?
Andy
Mimemail, lorsqu'il est combiné avec le module Mail System, prendra en charge tous les e-mails envoyés par le site. Ainsi, tous les e-mails envoyés par n'importe quel module, y compris les modules personnalisés, seront automatiquement envoyés via Mimemail. Si vous souhaitez limiter les e-mails concernés, vous pouvez utiliser les options de configuration des modules de Mail System.
Patrick Kenny
1
Je pense que ce n'est pas exactement ce que Andy a demandé. Certes, vous aurez besoin du module Mimemail ou roulerez votre propre MailSystem pour le faire, mais Andy peut vous demander comment définir le thème du corps de l'e-mail qui devrait être fait dans la fonction hook_mail () et un thème ('my_custom_theme') l'appeler?
AyeshK
1
Je pense que @Andy veut savoir si le module Mimemail a une fonction qui peut être appelée pour envoyer des e-mails.
kiamlaluno
@kiamlaluno Vous avez raison, c'est ce que j'aimerais savoir s'il vous plait
Andy