web-dev-qa-db-fra.com

Courrier HTML sans utiliser de modules

J'essaie d'utiliser la classe MailManager dans Drupal 8 pour envoyer du courrier HTML. Je l'ai fait fonctionner, mais il n'analyse pas le balisage HTML. Je pense que quelque chose ne va pas avec les en-têtes de l'e-mail.

Ce que j'ai est un module personnalisé (Custom_forward) qui contient un formulaire et qui appelle Mailmanager::mail() dans sa méthode submitForm(), qui contient le code suivant.

        // Email body
        $header = $sender . ' thought you would like to see this page from the website.';
        $personal_message = $form_state->getValues()['message_body'];
        $entity_url_value = '<a href="' . $entity_url->toString() . '">Go to article</a>';
        $message = $header . '<br>' . $personal_message . '<br>' . $entity_url_value;

        // Email
        $langcode = 'en';
        $mailManager = \Drupal::service('plugin.manager.mail');
        $to = $form_state->getValues()['recipient'];

        $params['title'] = 'Forward';
        $params['message'] = $message;
        $result = $mailManager->mail('custom_forward', 'forward', $to, $langcode, $params, NULL, true);

        if ($result['result'] !== true) {
            drupal_set_message(t('There was a problem sending your message and it was not sent.'), 'error');
            \Drupal::logger('mail-log')->error($message);
        }
        else {
            drupal_set_message(t('Your message has been sent.'));
        }

Selon Drupal vous avez également besoin de la méthode hook_mail dans mytheme.theme pour pouvoir envoyer un message, vous pouvez voir cette méthode ici:

function custom_forward_mail($key, &$message, $params) {
  $message['body'] = [];
  $message['subject'] = [];
  $message['headers'] = array(
    'content-type' => 'text/html',
    'charset' => 'UTF-8',
    'format' => 'flowed',
    'delsp' => 'yes',
    'from' => \Drupal::config('system.site')->get('mail')
  );

  switch ($key) {
    case 'forward':
      $message['subject'] = $params['title'];
      $message['body'][] = '<html><body>' . $params['message'] . '</body></html>';
      break;
  }
}

Comme vous pouvez le voir, je configure le type de contenu sur text/html et cela devrait indiquer au système de messagerie d'analyser le contenu en HTML, mais cela ne fonctionne pas pour certaines raisons.

Ceci est un e-mail de test. Tout le balisage HTML n'est pas affiché, mais ne fonctionne pas non plus.

Bassem thought you would like to see this page from the website. personal message Go to article [1] [1] http://myhost/node/81
3
Bassem Mohamed

Sans module, il n'est pas possible d'envoyer des e-mails HTML. En effet, le plugin par défaut que la classe MailManager (qui est un gestionnaire de plugins) utilise pour envoyer efficacement des e-mails contient le code suivant. (Voir PhpMail.php .)

public function format(array $message) {

    // Join the body array into one string.
    $message['body'] = implode("\n\n", $message['body']);

    // Convert any HTML to plain-text.
    $message['body'] = MailFormatHelper::htmlToText($message['body']);

    // Wrap the mail body for sending.
    $message['body'] = MailFormatHelper::wrapMail($message['body']);
    return $message;
  }

Le commentaire indique clairement: Convertissez n'importe quel code HTML en texte brut.

Si vous regardez MailFormatHelper::htmlToText() , vous verrez le code qui convertit le balisage HTML en texte brut, en particulier ce qui suit qui change n'importe quelle balise <a> Comme vous vu dans votre e-mail de test.

  // Replace inline <a> tags with the text of link and a footnote.
  // 'See <a href="https://www.drupal.org">the Drupal site</a>' becomes
  // 'See the Drupal site [1]' with the URL included as a footnote.
  static::htmlToMailUrls(NULL, TRUE);
  $pattern = '@(<a[^>]+?href="([^"]*)"[^>]*?>(.+?)</a>)@i';
  $string = preg_replace_callback($pattern, 'static::htmlToMailUrls', $string);
  $urls = static::htmlToMailUrls();
  $footnotes = '';
  if (count($urls)) {
    $footnotes .= "\n";
    for ($i = 0, $max = count($urls); $i < $max; $i++) {
      $footnotes .= '[' . ($i + 1) . '] ' . $urls[$i] . "\n";
    }
  }

Vous avez besoin d'un module qui définit un nouveau plugin de messagerie en utilisant une implémentation différente de la méthode format() et que la classe MailManager l'utilise. Comme indiqué dans la documentation de MailManager::getInstance() , la classe utilise la configuration dans system.mail.interface. (Le tableau renvoyé par \Drupal::config('system.mail.interface').) Dans votre exemple, une valeur de tableau pour custom_forward_formard (par exemple 'custom_forward_forward => 'custom_forward_mail', où custom_forward_mail est l'ID de plugin pour la classe implémentée par votre module) ferait l'affaire.

9
kiamlaluno

Le module de messagerie par défaut ne vous permet pas d'envoyer des messages html, mais il existe un hack pour cela. avant d'assigner une variable html au corps, veuillez utiliser PHP function htmlentities, cela empêche la suppression des balises html du message. et vous pouvez obtenir le courrier html.

$message['body'][] =  htmlentities($msg); 

c'est pour un piratage rapide .. sans modifier aucun code de base.

1
Shahbaz Zafar