There is a thread about this in the archives, but I figured I'd start a new one with instructions for SilverStripe 2.3.1, since the process is a little different. Here is what I did to get this working:
1) Download PHPMailer
2) Expand the .tar/.zip into your SS root, rename phpmailer
3) In your _config.php, add the following:
/* { PHPMAILER */
$path = Director::baseFolder().'/phpmailer/';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
require_once 'class.phpmailer.php';
/* PHPMAILER } */
4) In saphire/email/Mailer.php, add a new function in the Mailer class beneath sendHTML() called sendHTML_phpMailer():
function sendHTML_phpMailer($to, $from, $subject, $htmlContent, $attachedFiles = false, $customheaders = false, $plainContent = false, $inlineImages = false) {
return htmlEmail_phpMailer($to, $from, $subject, $htmlContent, $attachedFiles, $customheaders, $plainContent, $inlineImages);
}
5) In the same file (Mailer.php), but outside the class, add the htmlEmail_phpMailer() function that is called by sendHTML_phpMailer(). It is nearly identical to the htmlEmail function, except that instead of using php's mail() function to send the email it uses a PHPMailer object:
/*
* Use phpMailer to send from external SMTP
*/
function htmlEmail_phpMailer($to, $from, $subject, $htmlContent, $attachedFiles = false, $customheaders = false, $plainContent = false, $inlineImages = false) {
if ($customheaders && is_array($customheaders) == false) {
echo "htmlEmail($to, $from, $subject, ...) could not send mail: improper \$customheaders passed:<BR>";
dieprintr($headers);
}
$subjectIsUnicode = (strpos($subject,"&#") !== false);
$bodyIsUnicode = (strpos($htmlContent,"&#") !== false);
$plainEncoding = "";
// We generate plaintext content by default, but you can pass custom stuff
$plainEncoding = '';
if(!$plainContent) {
$plainContent = Convert::xml2raw($htmlContent);
if(isset($bodyIsUnicode) && $bodyIsUnicode) $plainEncoding = "base64";
}
// If the subject line contains extended characters, we must encode the
$subject = Convert::xml2raw($subject);
if(isset($subjectIsUnicode) && $subjectIsUnicode)
$subject = "=?UTF-8?B?" . base64_encode($subject) . "?=";
// Make the plain text part
$headers["Content-Type"] = "text/plain; charset=\"utf-8\"";
$headers["Content-Transfer-Encoding"] = $plainEncoding ? $plainEncoding : "quoted-printable";
$plainPart = processHeaders($headers, ($plainEncoding == "base64") ? chunk_split(base64_encode($plainContent),60) : wordwrap($plainContent,120));
// Make the HTML part
$headers["Content-Type"] = "text/html; charset=\"utf-8\"";
// Add basic wrapper tags if the body tag hasn't been given
if(stripos($htmlContent, '<body') === false) {
$htmlContent =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" .
"<HTML><HEAD>\n" .
"<META http-equiv=Content-Type content=\"text/html; charset=utf-8\">\n" .
"<STYLE type=3Dtext/css></STYLE>\n\n".
"</HEAD>\n" .
"<BODY bgColor=#ffffff>\n" .
$htmlContent .
"\n</BODY>\n" .
"</HTML>";
}
if($inlineImages) {
$htmlPart = wrapImagesInline($htmlContent);
} else {
$headers["Content-Transfer-Encoding"] = "quoted-printable";
$htmlPart = processHeaders($headers, wordwrap(QuotedPrintable_encode($htmlContent),120));
}
list($messageBody, $messageHeaders) = encodeMultipart(array($plainPart,$htmlPart), "multipart/alternative");
// Messages with attachments are handled differently
if($attachedFiles && is_array($attachedFiles)) {
// The first part is the message itself
$fullMessage = processHeaders($messageHeaders, $messageBody);
$messageParts = array($fullMessage);
// Include any specified attachments as additional parts
foreach($attachedFiles as $file) {
if($file['tmp_name'] && $file['name']) {
$messageParts[] = encodeFileForEmail($file['tmp_name'], $file['name']);
} else {
$messageParts[] = encodeFileForEmail($file);
}
}
// We further wrap all of this into another multipart block
list($fullBody, $headers) = encodeMultipart($messageParts, "multipart/mixed");
// Messages without attachments do not require such treatment
} else {
$headers = $messageHeaders;
$fullBody = $messageBody;
}
// Email headers
$headers["From"] = validEmailAddr($from);
// Messages with the X-SilverStripeMessageID header can be tracked
if(isset($customheaders["X-SilverStripeMessageID"]) && defined('BOUNCE_EMAIL')) {
$bounceAddress = BOUNCE_EMAIL;
} else {
$bounceAddress = $from;
}
// Strip the human name from the bounce address
if(ereg('^([^<>]*)<([^<>]+)> *$', $bounceAddress, $parts)) $bounceAddress = $parts[2];
// $headers["Sender"] = $from;
$headers["X-Mailer"] = X_MAILER;
if (!isset($customheaders["X-Priority"])) $headers["X-Priority"] = 3;
$headers = array_merge((array)$headers, (array)$customheaders);
// the carbon copy header has to be 'Cc', not 'CC' or 'cc' -- ensure this.
if (isset($headers['CC'])) { $headers['Cc'] = $headers['CC']; unset($headers['CC']); }
if (isset($headers['cc'])) { $headers['Cc'] = $headers['cc']; unset($headers['cc']); }
// the carbon copy header has to be 'Bcc', not 'BCC' or 'bcc' -- ensure this.
if (isset($headers['BCC'])) {$headers['Bcc']=$headers['BCC']; unset($headers['BCC']); }
if (isset($headers['bcc'])) {$headers['Bcc']=$headers['bcc']; unset($headers['bcc']); }
// Send the email
$headers = processHeaders($headers);
$to = validEmailAddr($to);
// Send using phpMailer created in the _config.php file
$phpmailer = new PHPMailer();
$phpmailer->CharSet = "UTF-8";
$phpmailer->IsSMTP(); // send via SMTP
$phpmailer->Host = "smtp.domain.com"; // SMTP servers
$phpmailer->SMTPAuth = true; // turn on SMTP authentication
$phpmailer->Username = "user@domain.com"; // SMTP username
$phpmailer->Password = "password"; // SMTP password
$phpmailer->From = "from@domain.com";
$phpmailer->FromName = "From Name";
$phpmailer->ClearAddresses();
$phpmailer->AddAddress($to);
$phpmailer->IsHTML(true); // send as HTML
$phpmailer->Subject = $subject;
$phpmailer->Body = $fullBody;
$phpmailer->AddCustomHeader($headers);
if(!$phpmailer->Send()) {
return false;
} else {
return true;
}
}
6) In saphire/email/Email.php, find the send() function. Change the last return statement so that it uses the new phpMailer functions if the PHPMailer class is loaded, as follows:
if (class_exists("PHPMailer")) {
return self::mailer()->sendHTML_phpMailer($to, $this->from, $subject, $this->body, $this->attachments, $headers, $this->plaintext_body);
} else {
return self::mailer()->sendHTML($to, $this->from, $subject, $this->body, $this->attachments, $headers, $this->plaintext_body);
}
That's it. It seems to work. I know it seems strange to manually set the From and FromName this way, but for me the function failed without these variables set like this. However, because the From address is set in the headers, your manually set From address is overridden. So when sending from the Newsletter module, for instance, the from address you enter in your newsletter type is what appears in the sent email, NOT the $phpmailer->From address.