Jump to:

23481 Posts in 18965 Topics by 2878 members

General Questions

SilverStripe Forums » General Questions » Using PHPMailer to send emails from external SMTP

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1 2
Go to End
Author Topic: 35079 Views
  • jhirm
    Community Member
    21 Posts

    Using PHPMailer to send emails from external SMTP Link to this post

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

       $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" .

       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->IsHTML(true); // send as HTML
       $phpmailer->Subject = $subject;
       $phpmailer->Body = $fullBody;
       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.

  • Jeramie
    Community Member
    34 Posts

    Re: Using PHPMailer to send emails from external SMTP Link to this post

    This post was instrumental to me keeping Silverstripe in production for us on our shared hosted space. I followed the instructions and had no issues getting it up and running outside of setting the proper SMTP etc. Those were issues on my behalf, Iam a php n00b. Thanks for the great write up.

  • dalesaurus
    Community Member
    283 Posts

    Re: Using PHPMailer to send emails from external SMTP Link to this post

    If you are reading this and thinking of giving it a go, take a moment to reconsider. There is a better way! Please see my post on fixing your php's mail() function before you consider hacking up core SS files:


  • MrGingerbear
    Community Member
    1 Post

    Re: Using PHPMailer to send emails from external SMTP Link to this post

    You seem to have a typo in your PHP in step 5, near the end.

    $phpmailer->Username = "user@domain.com; // SMTP username

    should read:

    $phpmailer->Username = "user@domain.com"; // SMTP username

    (missing ending double quote)
    No biggie, but you will have some issues if you copy and paste directly.

  • biapar
    Forum Moderator
    435 Posts

    Re: Using PHPMailer to send emails from external SMTP Link to this post

    I read that smtp autentication is possible setting up php.ini:

    [mail function]
    smtp_port = 25
    username = USERNAME
    password = YOUR_PASSWORD

  • jhirm
    Community Member
    21 Posts

    Re: Using PHPMailer to send emails from external SMTP Link to this post

    It's been a while since I wrote this, just happened to stumble upon it again. Delasaurus is absolutely correct, modifying the core is NEVER a good idea, unless it's absolutely necessary! His post (http://www.silverstripe.org/general-questions/show/269276) presents a method for setting up php's built-in mail() function to send via an SMTP relay, which indeed is a MUCH preferred option... if you've got sufficient server access to make the necessary changes. In my experience, I've run into two scenarios which kept me from doing this: 1) Small site with shared hosting. It's rare that a shared host will allow you to install software or make server changes. 2) Huge site with corporate IT department. Putting in a server change request means waiting for weeks to get it installed on Dev, QA, and production servers, which isn't conducive to smooth development.

    But yeah. If you're able to modify the server's mail sending capabilities, don't consider modifying the core!

  • KungK
    Community Member
    14 Posts

    Re: Using PHPMailer to send emails from external SMTP Link to this post

    I noticed there's a unsupported module that solves this issue (http://silverstripe.org/smtpmailer-module/). I tried it and it worked like a charm, any reason not to use it?

    Edit: Only tried with GMail smtp though.

  • Indika
    Community Member
    3 Posts

    Re: Using PHPMailer to send emails from external SMTP Link to this post

    But some time hotmail can get encoding error .

    If you really interest to fix them, you can use my instructions on my blog--- http://indikagamage.com/blog/how-to-use-phpmailer-with-silverstripe-without-any-hotmail-issues/

Page: 1 2
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.