I'm using SimpleNews and have an idea for a potential project, but don't know the best way of carrying it out. I'm using SimpleNews, which requires the Mimemail module to send html emails. But I'd also like to use the SMTP mail module.
From what I can see, these two modules currently don't work together because they both override the drupal_mail() function and the smtp_library variable.
I'd like to make it so that you have the option to:

  1. To send html mail
  2. To send the email via smtp
  3. To add a field to allow adding custom headers (see this forum node)

I assume this would involve combining the two modules and using conditionals to process the emails based on the settings? I'm new to Drupal and don't know tons about this stuff, but I'm willing to learn and to do the work necessary if someone can point me in the right direction in terms of the best strategy for developing this.

Thanks.

-bennybobw

Comments

kdesmet’s picture

bennybob,

I spent yesterday looking at the code as well.

1. mimemail already has the option to choose between more engines to send mails

$engine = variable_get('mimemail_engine', 'mimemail') .'_mailengine';

  if (!function_exists($engine)) {
    return false;
  }

  return $engine('send', $message);

setting the variable 'mimemail_egine' to 'smtp' and implementing smtp_mailengine in the smtp module would already get us far.

2. The most difficult thing to overcome is the multiple declaration of the drupal_mail_wrapper function. Both functions should be able to exist if not used seperately but if used combined only one can be declared.
The drupal_mail (http://api.drupal.org/api/5/function/drupal_mail) check which smtp_library is installed, so an "if" in the smtp module like used in the mimemail module should solve that issue and should only declare the drupal_mail_wrapper method once.

if (strpos(variable_get('smtp_library', ''), 'mimemail')
  && !function_exists('drupal_mail_wrapper')) {

  function drupal_mail_wrapper($mailkey, $to, $subject, $body, $from, $headers) {
    return mimemail($from, $to, $subject, $body, null, $headers);
  }
}

3. refactor drupal_mail_wrapper in the smtp module to use it's own smtp_mailengine function

With these changes, 'mimemail' should be the smtp_library to send mails with and 'mimemail_engine' should be set to SMTP.

sarcasticboy’s picture

Hi all -

I am also needing to get mimemail to send via smtp. I have started down this road, currently having implemented the mailengine function so mimemail can see smtp - now getting some interesting errors and wanted to know if anyone is working on this - would LOVE to collaborate.

david

bennybobw’s picture

David,
There's a bunch of extra code in phpmailer that's not needed. I was actually looking at only using the smtp.phpmailer.class to make this smaller and lighter. I have a bunch of stuff already written. Maybe we can collaborate.

paul_gregory’s picture

I've had a good look on Drupal and Google and can't find any more information. Has anyone come up with a definitive way to use Mimemail and SMTP together or indeed created some combined source? The cannot redeclare drupal_mail_wrapper() error is driving me mad!

ebassile’s picture

Just like you, I have been searching around for a solution for close to a month (on and off).

Not being able to find one, I decided to start reading the code and trying to understand what's happening.

Please note that I have never programmed PHP before. All I did is copy/paste and read a bit about arrays on PHP's website.

My site is running with Drupal 5. You can check it out at www.bp2x.com.

Here's what you need to do:
1. disable the drupal_mail_wrapper() from mimemail

if (strpos(variable_get('smtp_library', ''), 'mimemail')
  && !function_exists('drupal_mail_wrapper')) {
/*
  function drupal_mail_wrapper($mailkey, $to, $subject, $body, $from, $headers) {
    return mimemail($from, $to, $subject, $body, null, $headers);
  }
  */
}

2. rename drupal_mail_wrapper() function drupal_mail_wrapper($mailkey, $to, $subject, $body, $from, $header) { from the smtp module to internal_drupal_mail_wrapper()

function internal_drupal_mail_wrapper($mailkey, $to, $subject, $body, $from, $header) {

3. create a new drupal_mail_wrapper() for the smtp module with the following code

function drupal_mail_wrapper($mailkey, $to, $subject, $body, $from, $header) {

	$message = mimemail_prepare($from, $to, $subject, $body, false, $header);
	
	$status = true;

	if (is_array($message['address'])) {
		foreach ($message['address'] as $a) {
	        $status = internal_drupal_mail_wrapper('mimemail',
	          $a,
	          $message['subject'],
	          $message['body'],
			  $mnessage['sender'],
	          $message['headers']
	        ) && $status;
	    
	    }
	}
	else {
		$status = internal_drupal_mail_wrapper('mimemail',
	          $message['address'],
	          $message['subject'],
	          $message['body'],
			  $mnessage['sender'],
	          $message['headers']
	        ) && $status;
	}
	  
	  return $status;
}

That's it.

I tested it with simplenews, creating an account, and sending a new password for an existing account. They all work fine.

Further testing revealed a problem with sending HTML messages from simplenews. It was working because mimemail was sending the messages through teh PHP mail function and not using the overriden smtp mail function. So I made the following modifications.

4. Create a new function in smtp module (see code below)

function smtpmail($sender, $recipient, $subject, $body, $plaintext=null, $headers=array(), $text=null, $attachments=array()) {

	$header['Content-Type'] = 'text/html';
	
	$sender = variable_get('site_mail', ini_get('sendmail_from'));
	
	return internal_drupal_mail_wrapper('smtpmail', $recipient, $subject, $body, $sender, $header);
}

5. Modify simplenews.module, comment calling mimemail and add a call to the smtpmail function we created above.

    return smtpmail($from, $mail->to, $mail->subject, $mail->body, $plain_text_only, $headers, $plain_text_body);
    //return mimemail($from, $mail->to, $mail->subject, $mail->body, $plain_text_only, $headers, $plain_text_body);

6. Add a new condition to the smtp.module in the function

function internal_drupal_mail_wrapper($mailkey, $to, $subject, $body, $from, $header) {

after the lines

    else { //Else the header key is not special, just add it.
      $mail->AddCustomHeader($key . ": " . $value); //Add header line.
    }
  }

The new code added is:

  if ($mailkey == 'mimemail')
  {
	$mail->message_type = "pre";
  }

This tells the SMTP module not to format the email message body, since it is already mime encoded by the mimemail module.

And then I ticked the "Use mime mail for all messages" option in "Home » Administer » Site configuration » Mail".

It's a bloody dirty hack but at least now I can send html newsletters to my users again.

axle_foley00’s picture

ebassile:

I tried what you had done but I'm still not able to send any messages using SimpleNews. Is there anything else that needs to be done?

Edit: I think I got it working now. Seems I also needed to ensure that I had the latest version of SimpleNews, which was 5.x-1.2.

Thanks for your fix ebassile. :)

evelien’s picture

How would this effect other modules that use the smtp? (like sending new password to existing users within drupal)?

which version of smtp.module is used for editing? Can't find the code mentioned within step 6 and step 2 is rather strange, is this about the funtion definition within line 166, because that function is named _drupal_mail_wrapper.
Within smtp.module is only one line with function drupal_mail_wrapper, which is line 326:

if (!module_exists('mimemail') || (module_exists('mimemail') && variable_get('mimemail_alter', 0) == 0)) {
if (!function_exists('drupal_mail_wrapper')) {
function drupal_mail_wrapper($mailkey, $to, $subject, $body, $from, $headers) {
return _drupal_mail_wrapper($mailkey, $to, $subject, $body, $from, $headers);
}
}
}

But if you would rename 326 to internal_drupal_mail_wrapper, step 6 makes no sense at all.
(I'm using smtp.-5.x-1.0)