Having an issue, default mail system works, all other (mime, newsletter) also works, but HTML mail refuse to work. Each time webform / order (drupal commerce) is sent, website goes to WSOD with a message "an error has occured"

Log says:

TypeError: Argument 1 passed to _mailsystem_html_to_text() must be an instance of DOMNode, null given, called in /var/www/mpt.sk/public_html/sites/all/modules/mailsystem/html_to_text.inc on line 122 v _mailsystem_html_to_text() (riadok 161 z /var/www/mpt.sk/public_html/sites/all/modules/mailsystem/html_to_text.inc).

Not sure how to solve this, was not able to find anything relevant in issue thread or anywhere on internet. Note that my server runs PHP Version 7.0.26-1+ubuntu14.04.1+deb.sury.org+1

However the issue is not present on our test server (basic hosting configuration) also running php 7.0, might some package not be installed? When I checked the line it looks like "$dom->documentElement" is blank but I am not sure, not a good coder.

Thanks for any advice.

Comments

lubwn created an issue. See original summary.

lubwn’s picture

I did fixed this issue by somehow, not sure whether the fix is stable or not, but it works for now.

On line 122 in file html_to_text.inc change this:

$text = _mailsystem_html_to_text($dom->documentElement, $allowed_tags, $notes);

To this:

$text = _mailsystem_html_to_text($dom, $allowed_tags, $notes);

I noticed that $dom in this context does not have available property documentElement in printed array, it is just missing despite the fact that in the official PHP documentation documentElement property should be always available.

I think this is not a problem of module itself, but rather configuration of my server or PHP itself, not sure, however it works for now so maybe it will help someone in the future.

salvis’s picture

Thank you for reporting this and documenting your fix, which is actually in mailsystem, not in htmlmail.

Here's what we're looking at:

/**
 * Transform an HTML string into plain text, preserving the structure of the
 * markup. Useful for preparing the body of a node to be sent by e-mail.
 *
 * The output will be suitable for use as 'format=flowed; delsp=yes' text
 * (RFC 3676) and can be passed directly to drupal_mail() for sending.
 *
 * We deliberately use variable_get('mail_line_endings', MAIL_LINE_ENDINGS)
 * rather than "\r\n".
 *
 * This function provides suitable alternatives for the following tags:
 *
 * <a> <address> <b> <blockquote> <br /> <caption> <cite> <dd> <div> <dl> <dt>
 * <em> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <ol> <p> <pre> <strong>
 * <table> <tbody> <td> <tfoot> <thead> <tr> <u> <ul>
 *
 * The following tag attributes are supported:
 * - <a href=...>: Hyperlink destination urls.
 * - <li value=...>: Ordered list item numbers.
 * - <ol start=...>: Ordered list start number.
 *
 * @param $string
 *   The string to be transformed.
 * @param $allowed_tags
 *   (optional) If supplied, a list of tags that will be transformed. If
 *   omitted, all supported tags are transformed.
 *
 * @return
 *   The transformed string.
 *
 * @see drupal_mail()
 */
function mailsystem_html_to_text($string, $allowed_tags = NULL) {
  $eol = variable_get('mail_line_endings', MAIL_LINE_ENDINGS);
  // Cache list of supported tags.
  static $supported_tags;
  if (!isset($supported_tags)) {
    $supported_tags = array(
      'a', 'address', 'b', 'blockquote', 'br', 'cite', 'dd', 'div', 'dl',
      'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'li',
      'ol', 'p', 'pre', 'strong', 'table', 'td', 'tr', 'u', 'ul',
    );
  }

  // Make sure only supported tags are kept.
  $allowed_tags = isset($allowed_tags) ? array_intersect($supported_tags, $allowed_tags) : $supported_tags;

  // Parse $string into a DOM tree.
  $dom = filter_dom_load($string);
  $notes = array();
  // Recursively convert the DOM tree into plain text.
  $text = _mailsystem_html_to_text($dom->documentElement, $allowed_tags, $notes);
  // Hard-wrap at 1000 characters (including the line break sequence)
  // and space-stuff special lines.
  $text = mailsystem_wrap_mail($text, array('max' => 1000 - strlen($eol), 'hard' => TRUE));
  // Change non-breaking spaces back to regular spaces, and trim line breaks.
  // chr(160) is the non-breaking space character.
  $text = str_replace(chr(160), ' ', trim($text, $eol));
  // Add footnotes;
  if ($notes) {
    // Add a blank line before the footnote list.
    $text .= $eol;
    foreach ($notes as $url => $note) {
      $text .= $eol . '[' . $note . '] ' . $url;
    }
  }
  return $text;
}

htmlmail does use this function, but it's only passing a string. The function then calls filter_dom_load() to create the contents of the $dom variable.

Can you try to find out what the strings are that are being passed in to mailsystem_html_to_text() either on your test server or your production server?

Maybe you're looking at a situation like
#1494910: mailsystem_html_to_text() function did not return any text or
#1786546: mailsystem_html_to_text() function did not return any text
and this throws an error now with PHP 7 and it used to just return an empty string under earlier versions?

salvis’s picture

Status: Active » Postponed (maintainer needs more info)

Also, please try the 2.70 version!

TR’s picture

Status: Postponed (maintainer needs more info) » Closed (cannot reproduce)