<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[17676] trunk/wp-includes: Update phpmailer and smtp to 5.1.</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.wordpress.org/changeset/17676">17676</a></dd>
<dt>Author</dt> <dd>ryan</dd>
<dt>Date</dt> <dd>2011-04-21 20:29:30 +0000 (Thu, 21 Apr 2011)</dd>
</dl>

<h3>Log Message</h3>
<pre>Update phpmailer and smtp to 5.1. Props MattyRob cnorris23. fixes <a href="http://trac.wordpress.org/ticket/15912">#15912</a></pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkwpincludesclassphpmailerphp">trunk/wp-includes/class-phpmailer.php</a></li>
<li><a href="#trunkwpincludesclasssmtpphp">trunk/wp-includes/class-smtp.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkwpincludesclassphpmailerphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/class-phpmailer.php (17675 => 17676)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/class-phpmailer.php        2011-04-21 20:20:56 UTC (rev 17675)
+++ trunk/wp-includes/class-phpmailer.php        2011-04-21 20:29:30 UTC (rev 17676)
</span><span class="lines">@@ -2,14 +2,16 @@
</span><span class="cx"> /*~ class.phpmailer.php
</span><span class="cx"> .---------------------------------------------------------------------------.
</span><span class="cx"> |  Software: PHPMailer - PHP email class                                    |
</span><del>-|   Version: 2.0.4                                                          |
-|   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  |
</del><ins>+|   Version: 5.1                                                            |
+|   Contact: via sourceforge.net support pages (also www.worxware.com)      |
</ins><span class="cx"> |      Info: http://phpmailer.sourceforge.net                               |
</span><span class="cx"> |   Support: http://sourceforge.net/projects/phpmailer/                     |
</span><span class="cx"> | ------------------------------------------------------------------------- |
</span><del>-|    Author: Andy Prevost (project admininistrator)                         |
-|    Author: Brent R. Matzelle (original founder)                           |
-| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               |
</del><ins>+|     Admin: Andy Prevost (project admininistrator)                         |
+|   Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
+|          : Marcus Bointon (coolbru) coolbru@users.sourceforge.net         |
+|   Founder: Brent R. Matzelle (original founder)                           |
+| Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved.               |
</ins><span class="cx"> | Copyright (c) 2001-2003, Brent R. Matzelle                                |
</span><span class="cx"> | ------------------------------------------------------------------------- |
</span><span class="cx"> |   License: Distributed under the Lesser General Public License (LGPL)     |
</span><span class="lines">@@ -18,19 +20,26 @@
</span><span class="cx"> | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |
</span><span class="cx"> | FITNESS FOR A PARTICULAR PURPOSE.                                         |
</span><span class="cx"> | ------------------------------------------------------------------------- |
</span><del>-| We offer a number of paid services (www.codeworxtech.com):                |
</del><ins>+| We offer a number of paid services (www.worxware.com):                    |
</ins><span class="cx"> | - Web Hosting on highly optimized fast and secure servers                 |
</span><span class="cx"> | - Technology Consulting                                                   |
</span><span class="cx"> | - Oursourcing (highly qualified programmers and graphic designers)        |
</span><span class="cx"> '---------------------------------------------------------------------------'
</span><del>- */
</del><ins>+*/
+
</ins><span class="cx"> /**
</span><span class="cx">  * PHPMailer - PHP email transport class
</span><ins>+ * NOTE: Requires PHP version 5 or later
</ins><span class="cx">  * @package PHPMailer
</span><span class="cx">  * @author Andy Prevost
</span><ins>+ * @author Marcus Bointon
</ins><span class="cx">  * @copyright 2004 - 2009 Andy Prevost
</span><ins>+ * @version $Id: class.phpmailer.php 447 2009-05-25 01:36:38Z codeworxtech $
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
</ins><span class="cx">  */
</span><span class="cx"> 
</span><ins>+if (version_compare(PHP_VERSION, '5.0.0', '&lt;') ) exit(&quot;Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n&quot;);
+
</ins><span class="cx"> class PHPMailer {
</span><span class="cx"> 
</span><span class="cx">   /////////////////////////////////////////////////
</span><span class="lines">@@ -41,64 +50,64 @@
</span><span class="cx">    * Email priority (1 = High, 3 = Normal, 5 = low).
</span><span class="cx">    * @var int
</span><span class="cx">    */
</span><del>-  var $Priority          = 3;
</del><ins>+  public $Priority          = 3;
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the CharSet of the message.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $CharSet           = 'iso-8859-1';
</del><ins>+  public $CharSet           = 'iso-8859-1';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the Content-type of the message.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $ContentType        = 'text/plain';
</del><ins>+  public $ContentType       = 'text/plain';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Sets the Encoding of the message. Options for this are &quot;8bit&quot;,
-   * &quot;7bit&quot;, &quot;binary&quot;, &quot;base64&quot;, and &quot;quoted-printable&quot;.
</del><ins>+   * Sets the Encoding of the message. Options for this are
+   *  &quot;8bit&quot;, &quot;7bit&quot;, &quot;binary&quot;, &quot;base64&quot;, and &quot;quoted-printable&quot;.
</ins><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $Encoding          = '8bit';
</del><ins>+  public $Encoding          = '8bit';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Holds the most recent mailer error message.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $ErrorInfo         = '';
</del><ins>+  public $ErrorInfo         = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the From email address for the message.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $From              = 'root@localhost';
</del><ins>+  public $From              = 'root@localhost';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the From name of the message.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $FromName          = 'Root User';
</del><ins>+  public $FromName          = 'Root User';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the Sender email (Return-Path) of the message.  If not empty,
</span><span class="cx">    * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $Sender            = '';
</del><ins>+  public $Sender            = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the Subject of the message.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $Subject           = '';
</del><ins>+  public $Subject           = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the Body of the message.  This can be either an HTML or text body.
</span><span class="cx">    * If HTML then run IsHTML(true).
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $Body              = '';
</del><ins>+  public $Body              = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the text-only body of the message.  This automatically sets the
</span><span class="lines">@@ -107,45 +116,39 @@
</span><span class="cx">    * that can read HTML will view the normal Body.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $AltBody           = '';
</del><ins>+  public $AltBody           = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets word wrapping on the body of the message to a given number of
</span><span class="cx">    * characters.
</span><span class="cx">    * @var int
</span><span class="cx">    */
</span><del>-  var $WordWrap          = 0;
</del><ins>+  public $WordWrap          = 0;
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Method to send mail: (&quot;mail&quot;, &quot;sendmail&quot;, or &quot;smtp&quot;).
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $Mailer            = 'mail';
</del><ins>+  public $Mailer            = 'mail';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the path of the sendmail program.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $Sendmail          = '/usr/sbin/sendmail';
</del><ins>+  public $Sendmail          = '/usr/sbin/sendmail';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Path to PHPMailer plugins.  This is now only useful if the SMTP class
</del><ins>+   * Path to PHPMailer plugins.  Useful if the SMTP class
</ins><span class="cx">    * is in a different directory than the PHP include path.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $PluginDir         = '';
</del><ins>+  public $PluginDir         = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Holds PHPMailer version.
-   * @var string
-   */
-  var $Version           = &quot;2.0.4&quot;;
-
-  /**
</del><span class="cx">    * Sets the email address that a reading confirmation will be sent.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $ConfirmReadingTo  = '';
</del><ins>+  public $ConfirmReadingTo  = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the hostname to use in Message-Id and Received headers
</span><span class="lines">@@ -153,14 +156,14 @@
</span><span class="cx">    * by SERVER_NAME is used or 'localhost.localdomain'.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $Hostname          = '';
</del><ins>+  public $Hostname          = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the message ID to be used in the Message-Id header.
</span><span class="cx">    * If empty, a unique id will be generated.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $MessageID         = '';
</del><ins>+  public $MessageID         = '';
</ins><span class="cx"> 
</span><span class="cx">   /////////////////////////////////////////////////
</span><span class="cx">   // PROPERTIES FOR SMTP
</span><span class="lines">@@ -174,57 +177,57 @@
</span><span class="cx">    * Hosts will be tried in order.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $Host        = 'localhost';
</del><ins>+  public $Host          = 'localhost';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the default SMTP server port.
</span><span class="cx">    * @var int
</span><span class="cx">    */
</span><del>-  var $Port        = 25;
</del><ins>+  public $Port          = 25;
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets the SMTP HELO of the message (Default is $Hostname).
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $Helo        = '';
</del><ins>+  public $Helo          = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets connection prefix.
</span><span class="cx">    * Options are &quot;&quot;, &quot;ssl&quot; or &quot;tls&quot;
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $SMTPSecure = &quot;&quot;;
</del><ins>+  public $SMTPSecure    = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets SMTP authentication. Utilizes the Username and Password variables.
</span><span class="cx">    * @var bool
</span><span class="cx">    */
</span><del>-  var $SMTPAuth     = false;
</del><ins>+  public $SMTPAuth      = false;
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets SMTP username.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $Username     = '';
</del><ins>+  public $Username      = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets SMTP password.
</span><span class="cx">    * @var string
</span><span class="cx">    */
</span><del>-  var $Password     = '';
</del><ins>+  public $Password      = '';
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Sets the SMTP server timeout in seconds. This function will not
-   * work with the win32 version.
</del><ins>+   * Sets the SMTP server timeout in seconds.
+   * This function will not work with the win32 version.
</ins><span class="cx">    * @var int
</span><span class="cx">    */
</span><del>-  var $Timeout      = 10;
</del><ins>+  public $Timeout       = 10;
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sets SMTP class debugging on or off.
</span><span class="cx">    * @var bool
</span><span class="cx">    */
</span><del>-  var $SMTPDebug    = false;
</del><ins>+  public $SMTPDebug     = false;
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Prevents the SMTP connection from being closed after each mail
</span><span class="lines">@@ -232,46 +235,121 @@
</span><span class="cx">    * requires an explicit call to SmtpClose().
</span><span class="cx">    * @var bool
</span><span class="cx">    */
</span><del>-  var $SMTPKeepAlive = false;
</del><ins>+  public $SMTPKeepAlive = false;
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Provides the ability to have the TO field process individual
</span><span class="cx">    * emails, instead of sending to entire TO addresses
</span><span class="cx">    * @var bool
</span><span class="cx">    */
</span><del>-  var $SingleTo = false;
</del><ins>+  public $SingleTo      = false;
</ins><span class="cx"> 
</span><ins>+   /**
+   * If SingleTo is true, this provides the array to hold the email addresses
+   * @var bool
+   */
+  public $SingleToArray = array();
+
+ /**
+   * Provides the ability to change the line ending
+   * @var string
+   */
+  public $LE              = &quot;\n&quot;;
+
+  /**
+   * Used with DKIM DNS Resource Record
+   * @var string
+   */
+  public $DKIM_selector   = 'phpmailer';
+
+  /**
+   * Used with DKIM DNS Resource Record
+   * optional, in format of email address 'you@yourdomain.com'
+   * @var string
+   */
+  public $DKIM_identity   = '';
+
+  /**
+   * Used with DKIM DNS Resource Record
+   * optional, in format of email address 'you@yourdomain.com'
+   * @var string
+   */
+  public $DKIM_domain     = '';
+
+  /**
+   * Used with DKIM DNS Resource Record
+   * optional, in format of email address 'you@yourdomain.com'
+   * @var string
+   */
+  public $DKIM_private    = '';
+
+  /**
+   * Callback Action function name
+   * the function that handles the result of the send email action. Parameters:
+   *   bool    $result        result of the send action
+   *   string  $to            email address of the recipient
+   *   string  $cc            cc email addresses
+   *   string  $bcc           bcc email addresses
+   *   string  $subject       the subject
+   *   string  $body          the email body
+   * @var string
+   */
+  public $action_function = ''; //'callbackAction';
+
+  /**
+   * Sets the PHPMailer Version number
+   * @var string
+   */
+  public $Version         = '5.1';
+
</ins><span class="cx">   /////////////////////////////////////////////////
</span><del>-  // PROPERTIES, PRIVATE
</del><ins>+  // PROPERTIES, PRIVATE AND PROTECTED
</ins><span class="cx">   /////////////////////////////////////////////////
</span><span class="cx"> 
</span><del>-  var $smtp            = NULL;
-  var $to              = array();
-  var $cc              = array();
-  var $bcc             = array();
-  var $ReplyTo         = array();
-  var $attachment      = array();
-  var $CustomHeader    = array();
-  var $message_type    = '';
-  var $boundary        = array();
-  var $language        = array();
-  var $error_count     = 0;
-  var $LE              = &quot;\n&quot;;
-  var $sign_cert_file  = &quot;&quot;;
-  var $sign_key_file   = &quot;&quot;;
-  var $sign_key_pass   = &quot;&quot;;
</del><ins>+  private   $smtp           = NULL;
+  private   $to             = array();
+  private   $cc             = array();
+  private   $bcc            = array();
+  private   $ReplyTo        = array();
+  private   $all_recipients = array();
+  private   $attachment     = array();
+  private   $CustomHeader   = array();
+  private   $message_type   = '';
+  private   $boundary       = array();
+  protected $language       = array();
+  private   $error_count    = 0;
+  private   $sign_cert_file = &quot;&quot;;
+  private   $sign_key_file  = &quot;&quot;;
+  private   $sign_key_pass  = &quot;&quot;;
+  private   $exceptions     = false;
</ins><span class="cx"> 
</span><span class="cx">   /////////////////////////////////////////////////
</span><ins>+  // CONSTANTS
+  /////////////////////////////////////////////////
+
+  const STOP_MESSAGE  = 0; // message only, continue processing
+  const STOP_CONTINUE = 1; // message?, likely ok to continue processing
+  const STOP_CRITICAL = 2; // message, plus full stop, critical error reached
+
+  /////////////////////////////////////////////////
</ins><span class="cx">   // METHODS, VARIABLES
</span><span class="cx">   /////////////////////////////////////////////////
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+   * Constructor
+   * @param boolean $exceptions Should we throw external exceptions?
+   */
+  public function __construct($exceptions = false) {
+    $this-&gt;exceptions = ($exceptions == true);
+  }
+
+  /**
</ins><span class="cx">    * Sets message type to HTML.
</span><del>-   * @param bool $bool
</del><ins>+   * @param bool $ishtml
</ins><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function IsHTML($bool) {
-    if($bool == true) {
</del><ins>+  public function IsHTML($ishtml = true) {
+    if ($ishtml) {
</ins><span class="cx">       $this-&gt;ContentType = 'text/html';
</span><span class="cx">     } else {
</span><span class="cx">       $this-&gt;ContentType = 'text/plain';
</span><span class="lines">@@ -282,7 +360,7 @@
</span><span class="cx">    * Sets Mailer to send message using SMTP.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function IsSMTP() {
</del><ins>+  public function IsSMTP() {
</ins><span class="cx">     $this-&gt;Mailer = 'smtp';
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -290,7 +368,7 @@
</span><span class="cx">    * Sets Mailer to send message using PHP mail() function.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function IsMail() {
</del><ins>+  public function IsMail() {
</ins><span class="cx">     $this-&gt;Mailer = 'mail';
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -298,7 +376,10 @@
</span><span class="cx">    * Sets Mailer to send message using the $Sendmail program.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function IsSendmail() {
</del><ins>+  public function IsSendmail() {
+    if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
+      $this-&gt;Sendmail = '/var/qmail/bin/sendmail';
+    }
</ins><span class="cx">     $this-&gt;Mailer = 'sendmail';
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -306,8 +387,10 @@
</span><span class="cx">    * Sets Mailer to send message using the qmail MTA.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function IsQmail() {
-    $this-&gt;Sendmail = '/var/qmail/bin/sendmail';
</del><ins>+  public function IsQmail() {
+    if (stristr(ini_get('sendmail_path'), 'qmail')) {
+      $this-&gt;Sendmail = '/var/qmail/bin/sendmail';
+    }
</ins><span class="cx">     $this-&gt;Mailer = 'sendmail';
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -319,54 +402,136 @@
</span><span class="cx">    * Adds a &quot;To&quot; address.
</span><span class="cx">    * @param string $address
</span><span class="cx">    * @param string $name
</span><del>-   * @return void
</del><ins>+   * @return boolean true on success, false if address already used
</ins><span class="cx">    */
</span><del>-  function AddAddress($address, $name = '') {
-    $cur = count($this-&gt;to);
-    $this-&gt;to[$cur][0] = trim($address);
-    $this-&gt;to[$cur][1] = $name;
</del><ins>+  public function AddAddress($address, $name = '') {
+    return $this-&gt;AddAnAddress('to', $address, $name);
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Adds a &quot;Cc&quot; address. Note: this function works
-   * with the SMTP mailer on win32, not with the &quot;mail&quot;
-   * mailer.
</del><ins>+   * Adds a &quot;Cc&quot; address.
+   * Note: this function works with the SMTP mailer on win32, not with the &quot;mail&quot; mailer.
</ins><span class="cx">    * @param string $address
</span><span class="cx">    * @param string $name
</span><del>-   * @return void
</del><ins>+   * @return boolean true on success, false if address already used
</ins><span class="cx">    */
</span><del>-  function AddCC($address, $name = '') {
-    $cur = count($this-&gt;cc);
-    $this-&gt;cc[$cur][0] = trim($address);
-    $this-&gt;cc[$cur][1] = $name;
</del><ins>+  public function AddCC($address, $name = '') {
+    return $this-&gt;AddAnAddress('cc', $address, $name);
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Adds a &quot;Bcc&quot; address. Note: this function works
-   * with the SMTP mailer on win32, not with the &quot;mail&quot;
-   * mailer.
</del><ins>+   * Adds a &quot;Bcc&quot; address.
+   * Note: this function works with the SMTP mailer on win32, not with the &quot;mail&quot; mailer.
</ins><span class="cx">    * @param string $address
</span><span class="cx">    * @param string $name
</span><del>-   * @return void
</del><ins>+   * @return boolean true on success, false if address already used
</ins><span class="cx">    */
</span><del>-  function AddBCC($address, $name = '') {
-    $cur = count($this-&gt;bcc);
-    $this-&gt;bcc[$cur][0] = trim($address);
-    $this-&gt;bcc[$cur][1] = $name;
</del><ins>+  public function AddBCC($address, $name = '') {
+    return $this-&gt;AddAnAddress('bcc', $address, $name);
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Adds a &quot;Reply-To&quot; address.
</del><ins>+   * Adds a &quot;Reply-to&quot; address.
</ins><span class="cx">    * @param string $address
</span><span class="cx">    * @param string $name
</span><del>-   * @return void
</del><ins>+   * @return boolean
</ins><span class="cx">    */
</span><del>-  function AddReplyTo($address, $name = '') {
-    $cur = count($this-&gt;ReplyTo);
-    $this-&gt;ReplyTo[$cur][0] = trim($address);
-    $this-&gt;ReplyTo[$cur][1] = $name;
</del><ins>+  public function AddReplyTo($address, $name = '') {
+    return $this-&gt;AddAnAddress('ReplyTo', $address, $name);
</ins><span class="cx">   }
</span><span class="cx"> 
</span><ins>+  /**
+   * Adds an address to one of the recipient arrays
+   * Addresses that have been added already return false, but do not throw exceptions
+   * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo'
+   * @param string $address The email address to send to
+   * @param string $name
+   * @return boolean true on success, false if address already used or invalid in some way
+   * @access private
+   */
+  private function AddAnAddress($kind, $address, $name = '') {
+    if (!preg_match('/^(to|cc|bcc|ReplyTo)$/', $kind)) {
+      echo 'Invalid recipient array: ' . kind;
+      return false;
+    }
+    $address = trim($address);
+    $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
+    if (!self::ValidateAddress($address)) {
+      $this-&gt;SetError($this-&gt;Lang('invalid_address').': '. $address);
+      if ($this-&gt;exceptions) {
+        throw new phpmailerException($this-&gt;Lang('invalid_address').': '.$address);
+      }
+      echo $this-&gt;Lang('invalid_address').': '.$address;
+      return false;
+    }
+    if ($kind != 'ReplyTo') {
+      if (!isset($this-&gt;all_recipients[strtolower($address)])) {
+        array_push($this-&gt;$kind, array($address, $name));
+        $this-&gt;all_recipients[strtolower($address)] = true;
+        return true;
+      }
+    } else {
+      if (!array_key_exists(strtolower($address), $this-&gt;ReplyTo)) {
+        $this-&gt;ReplyTo[strtolower($address)] = array($address, $name);
+      return true;
+    }
+  }
+  return false;
+}
+
+/**
+ * Set the From and FromName properties
+ * @param string $address
+ * @param string $name
+ * @return boolean
+ */
+  public function SetFrom($address, $name = '',$auto=1) {
+    $address = trim($address);
+    $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
+    if (!self::ValidateAddress($address)) {
+      $this-&gt;SetError($this-&gt;Lang('invalid_address').': '. $address);
+      if ($this-&gt;exceptions) {
+        throw new phpmailerException($this-&gt;Lang('invalid_address').': '.$address);
+      }
+      echo $this-&gt;Lang('invalid_address').': '.$address;
+      return false;
+    }
+    $this-&gt;From = $address;
+    $this-&gt;FromName = $name;
+    if ($auto) {
+      if (empty($this-&gt;ReplyTo)) {
+        $this-&gt;AddAnAddress('ReplyTo', $address, $name);
+      }
+      if (empty($this-&gt;Sender)) {
+        $this-&gt;Sender = $address;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Check that a string looks roughly like an email address should
+   * Static so it can be used without instantiation
+   * Tries to use PHP built-in validator in the filter extension (from PHP 5.2), falls back to a reasonably competent regex validator
+   * Conforms approximately to RFC2822
+   * @link http://www.hexillion.com/samples/#Regex Original pattern found here
+   * @param string $address The email address to check
+   * @return boolean
+   * @static
+   * @access public
+   */
+  public static function ValidateAddress($address) {
+    if (function_exists('filter_var')) { //Introduced in PHP 5.2
+      if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) {
+        return false;
+      } else {
+        return true;
+      }
+    } else {
+      return preg_match('/^(?:[\w\!\#\$\%\&amp;\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&amp;\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);
+    }
+  }
+
</ins><span class="cx">   /////////////////////////////////////////////////
</span><span class="cx">   // METHODS, MAIL SENDING
</span><span class="cx">   /////////////////////////////////////////////////
</span><span class="lines">@@ -377,257 +542,297 @@
</span><span class="cx">    * variable to view description of the error.
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function Send() {
-    $header = '';
-    $body = '';
-    $result = true;
</del><ins>+  public function Send() {
+    try {
+      if ((count($this-&gt;to) + count($this-&gt;cc) + count($this-&gt;bcc)) &lt; 1) {
+        throw new phpmailerException($this-&gt;Lang('provide_address'), self::STOP_CRITICAL);
+      }
</ins><span class="cx"> 
</span><del>-    if((count($this-&gt;to) + count($this-&gt;cc) + count($this-&gt;bcc)) &lt; 1) {
-      $this-&gt;SetError($this-&gt;Lang('provide_address'));
-      return false;
-    }
</del><ins>+      // Set whether the message is multipart/alternative
+      if(!empty($this-&gt;AltBody)) {
+        $this-&gt;ContentType = 'multipart/alternative';
+      }
</ins><span class="cx"> 
</span><del>-    /* Set whether the message is multipart/alternative */
-    if(!empty($this-&gt;AltBody)) {
-      $this-&gt;ContentType = 'multipart/alternative';
-    }
</del><ins>+      $this-&gt;error_count = 0; // reset errors
+      $this-&gt;SetMessageType();
+      $header = $this-&gt;CreateHeader();
+      $body = $this-&gt;CreateBody();
</ins><span class="cx"> 
</span><del>-    $this-&gt;error_count = 0; // reset errors
-    $this-&gt;SetMessageType();
-    $header .= $this-&gt;CreateHeader();
-    $body = $this-&gt;CreateBody();
</del><ins>+      if (empty($this-&gt;Body)) {
+        throw new phpmailerException($this-&gt;Lang('empty_message'), self::STOP_CRITICAL);
+      }
</ins><span class="cx"> 
</span><del>-    if($body == '') {
</del><ins>+      // digitally sign with DKIM if enabled
+      if ($this-&gt;DKIM_domain &amp;&amp; $this-&gt;DKIM_private) {
+        $header_dkim = $this-&gt;DKIM_Add($header,$this-&gt;Subject,$body);
+        $header = str_replace(&quot;\r\n&quot;,&quot;\n&quot;,$header_dkim) . $header;
+      }
+
+      // Choose the mailer and send through it
+      switch($this-&gt;Mailer) {
+        case 'sendmail':
+          return $this-&gt;SendmailSend($header, $body);
+        case 'smtp':
+          return $this-&gt;SmtpSend($header, $body);
+        default:
+          return $this-&gt;MailSend($header, $body);
+      }
+
+    } catch (phpmailerException $e) {
+      $this-&gt;SetError($e-&gt;getMessage());
+      if ($this-&gt;exceptions) {
+        throw $e;
+      }
+      echo $e-&gt;getMessage().&quot;\n&quot;;
</ins><span class="cx">       return false;
</span><span class="cx">     }
</span><del>-
-    /* Choose the mailer */
-    switch($this-&gt;Mailer) {
-      case 'sendmail':
-        $result = $this-&gt;SendmailSend($header, $body);
-        break;
-      case 'smtp':
-        $result = $this-&gt;SmtpSend($header, $body);
-        break;
-      case 'mail':
-        $result = $this-&gt;MailSend($header, $body);
-        break;
-      default:
-        $result = $this-&gt;MailSend($header, $body);
-        break;
-        //$this-&gt;SetError($this-&gt;Mailer . $this-&gt;Lang('mailer_not_supported'));
-        //$result = false;
-        //break;
-    }
-
-    return $result;
</del><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sends mail using the $Sendmail program.
</span><del>-   * @access private
</del><ins>+   * @param string $header The message headers
+   * @param string $body The message body
+   * @access protected
</ins><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function SendmailSend($header, $body) {
</del><ins>+  protected function SendmailSend($header, $body) {
</ins><span class="cx">     if ($this-&gt;Sender != '') {
</span><span class="cx">       $sendmail = sprintf(&quot;%s -oi -f %s -t&quot;, escapeshellcmd($this-&gt;Sendmail), escapeshellarg($this-&gt;Sender));
</span><span class="cx">     } else {
</span><span class="cx">       $sendmail = sprintf(&quot;%s -oi -t&quot;, escapeshellcmd($this-&gt;Sendmail));
</span><span class="cx">     }
</span><del>-
-    if(!@$mail = popen($sendmail, 'w')) {
-      $this-&gt;SetError($this-&gt;Lang('execute') . $this-&gt;Sendmail);
-      return false;
</del><ins>+    if ($this-&gt;SingleTo === true) {
+      foreach ($this-&gt;SingleToArray as $key =&gt; $val) {
+        if(!@$mail = popen($sendmail, 'w')) {
+          throw new phpmailerException($this-&gt;Lang('execute') . $this-&gt;Sendmail, self::STOP_CRITICAL);
+        }
+        fputs($mail, &quot;To: &quot; . $val . &quot;\n&quot;);
+        fputs($mail, $header);
+        fputs($mail, $body);
+        $result = pclose($mail);
+        // implement call back function if it exists
+        $isSent = ($result == 0) ? 1 : 0;
+        $this-&gt;doCallback($isSent,$val,$this-&gt;cc,$this-&gt;bcc,$this-&gt;Subject,$body);
+        if($result != 0) {
+          throw new phpmailerException($this-&gt;Lang('execute') . $this-&gt;Sendmail, self::STOP_CRITICAL);
+        }
+      }
+    } else {
+      if(!@$mail = popen($sendmail, 'w')) {
+        throw new phpmailerException($this-&gt;Lang('execute') . $this-&gt;Sendmail, self::STOP_CRITICAL);
+      }
+      fputs($mail, $header);
+      fputs($mail, $body);
+      $result = pclose($mail);
+      // implement call back function if it exists
+      $isSent = ($result == 0) ? 1 : 0;
+      $this-&gt;doCallback($isSent,$this-&gt;to,$this-&gt;cc,$this-&gt;bcc,$this-&gt;Subject,$body);
+      if($result != 0) {
+        throw new phpmailerException($this-&gt;Lang('execute') . $this-&gt;Sendmail, self::STOP_CRITICAL);
+      }
</ins><span class="cx">     }
</span><del>-
-    fputs($mail, $header);
-    fputs($mail, $body);
-
-    $result = pclose($mail);
-    if (version_compare(phpversion(), '4.2.3') == -1) {
-      $result = $result &gt;&gt; 8 &amp; 0xFF;
-    }
-    if($result != 0) {
-      $this-&gt;SetError($this-&gt;Lang('execute') . $this-&gt;Sendmail);
-      return false;
-    }
</del><span class="cx">     return true;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Sends mail using the PHP mail() function.
</span><del>-   * @access private
</del><ins>+   * @param string $header The message headers
+   * @param string $body The message body
+   * @access protected
</ins><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function MailSend($header, $body) {
-
-    $to = '';
-    for($i = 0; $i &lt; count($this-&gt;to); $i++) {
-      if($i != 0) { $to .= ', '; }
-      $to .= $this-&gt;AddrFormat($this-&gt;to[$i]);
</del><ins>+  protected function MailSend($header, $body) {
+    $toArr = array();
+    foreach($this-&gt;to as $t) {
+      $toArr[] = $this-&gt;AddrFormat($t);
</ins><span class="cx">     }
</span><ins>+    $to = implode(', ', $toArr);
</ins><span class="cx"> 
</span><del>-    $toArr = split(',', $to);
-
</del><span class="cx">     $params = sprintf(&quot;-oi -f %s&quot;, $this-&gt;Sender);
</span><del>-    if ($this-&gt;Sender != '' &amp;&amp; strlen(ini_get('safe_mode')) &lt; 1) {
</del><ins>+    if ($this-&gt;Sender != '' &amp;&amp; strlen(ini_get('safe_mode'))&lt; 1) {
</ins><span class="cx">       $old_from = ini_get('sendmail_from');
</span><span class="cx">       ini_set('sendmail_from', $this-&gt;Sender);
</span><span class="cx">       if ($this-&gt;SingleTo === true &amp;&amp; count($toArr) &gt; 1) {
</span><span class="cx">         foreach ($toArr as $key =&gt; $val) {
</span><span class="cx">           $rt = @mail($val, $this-&gt;EncodeHeader($this-&gt;SecureHeader($this-&gt;Subject)), $body, $header, $params);
</span><ins>+          // implement call back function if it exists
+          $isSent = ($rt == 1) ? 1 : 0;
+          $this-&gt;doCallback($isSent,$val,$this-&gt;cc,$this-&gt;bcc,$this-&gt;Subject,$body);
</ins><span class="cx">         }
</span><span class="cx">       } else {
</span><span class="cx">         $rt = @mail($to, $this-&gt;EncodeHeader($this-&gt;SecureHeader($this-&gt;Subject)), $body, $header, $params);
</span><ins>+        // implement call back function if it exists
+        $isSent = ($rt == 1) ? 1 : 0;
+        $this-&gt;doCallback($isSent,$to,$this-&gt;cc,$this-&gt;bcc,$this-&gt;Subject,$body);
</ins><span class="cx">       }
</span><span class="cx">     } else {
</span><span class="cx">       if ($this-&gt;SingleTo === true &amp;&amp; count($toArr) &gt; 1) {
</span><span class="cx">         foreach ($toArr as $key =&gt; $val) {
</span><span class="cx">           $rt = @mail($val, $this-&gt;EncodeHeader($this-&gt;SecureHeader($this-&gt;Subject)), $body, $header, $params);
</span><ins>+          // implement call back function if it exists
+          $isSent = ($rt == 1) ? 1 : 0;
+          $this-&gt;doCallback($isSent,$val,$this-&gt;cc,$this-&gt;bcc,$this-&gt;Subject,$body);
</ins><span class="cx">         }
</span><span class="cx">       } else {
</span><span class="cx">         $rt = @mail($to, $this-&gt;EncodeHeader($this-&gt;SecureHeader($this-&gt;Subject)), $body, $header);
</span><ins>+        // implement call back function if it exists
+        $isSent = ($rt == 1) ? 1 : 0;
+        $this-&gt;doCallback($isSent,$to,$this-&gt;cc,$this-&gt;bcc,$this-&gt;Subject,$body);
</ins><span class="cx">       }
</span><span class="cx">     }
</span><del>-
</del><span class="cx">     if (isset($old_from)) {
</span><span class="cx">       ini_set('sendmail_from', $old_from);
</span><span class="cx">     }
</span><del>-
</del><span class="cx">     if(!$rt) {
</span><del>-      $this-&gt;SetError($this-&gt;Lang('instantiate'));
-      return false;
</del><ins>+      throw new phpmailerException($this-&gt;Lang('instantiate'), self::STOP_CRITICAL);
</ins><span class="cx">     }
</span><del>-
</del><span class="cx">     return true;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Sends mail via SMTP using PhpSMTP (Author:
-   * Chris Ryan).  Returns bool.  Returns false if there is a
-   * bad MAIL FROM, RCPT, or DATA input.
-   * @access private
</del><ins>+   * Sends mail via SMTP using PhpSMTP
+   * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
+   * @param string $header The message headers
+   * @param string $body The message body
+   * @uses SMTP
+   * @access protected
</ins><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function SmtpSend($header, $body) {
-    include_once($this-&gt;PluginDir . 'class-smtp.php');
-    $error = '';
</del><ins>+  protected function SmtpSend($header, $body) {
+    require_once $this-&gt;PluginDir . 'class-smtp.php';
</ins><span class="cx">     $bad_rcpt = array();
</span><span class="cx"> 
</span><span class="cx">     if(!$this-&gt;SmtpConnect()) {
</span><del>-      return false;
</del><ins>+      throw new phpmailerException($this-&gt;Lang('smtp_connect_failed'), self::STOP_CRITICAL);
</ins><span class="cx">     }
</span><del>-
</del><span class="cx">     $smtp_from = ($this-&gt;Sender == '') ? $this-&gt;From : $this-&gt;Sender;
</span><span class="cx">     if(!$this-&gt;smtp-&gt;Mail($smtp_from)) {
</span><del>-      $error = $this-&gt;Lang('from_failed') . $smtp_from;
-      $this-&gt;SetError($error);
-      $this-&gt;smtp-&gt;Reset();
-      return false;
</del><ins>+      throw new phpmailerException($this-&gt;Lang('from_failed') . $smtp_from, self::STOP_CRITICAL);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    /* Attempt to send attach all recipients */
-    for($i = 0; $i &lt; count($this-&gt;to); $i++) {
-      if(!$this-&gt;smtp-&gt;Recipient($this-&gt;to[$i][0])) {
-        $bad_rcpt[] = $this-&gt;to[$i][0];
</del><ins>+    // Attempt to send attach all recipients
+    foreach($this-&gt;to as $to) {
+      if (!$this-&gt;smtp-&gt;Recipient($to[0])) {
+        $bad_rcpt[] = $to[0];
+        // implement call back function if it exists
+        $isSent = 0;
+        $this-&gt;doCallback($isSent,$to[0],'','',$this-&gt;Subject,$body);
+      } else {
+        // implement call back function if it exists
+        $isSent = 1;
+        $this-&gt;doCallback($isSent,$to[0],'','',$this-&gt;Subject,$body);
</ins><span class="cx">       }
</span><span class="cx">     }
</span><del>-    for($i = 0; $i &lt; count($this-&gt;cc); $i++) {
-      if(!$this-&gt;smtp-&gt;Recipient($this-&gt;cc[$i][0])) {
-        $bad_rcpt[] = $this-&gt;cc[$i][0];
</del><ins>+    foreach($this-&gt;cc as $cc) {
+      if (!$this-&gt;smtp-&gt;Recipient($cc[0])) {
+        $bad_rcpt[] = $cc[0];
+        // implement call back function if it exists
+        $isSent = 0;
+        $this-&gt;doCallback($isSent,'',$cc[0],'',$this-&gt;Subject,$body);
+      } else {
+        // implement call back function if it exists
+        $isSent = 1;
+        $this-&gt;doCallback($isSent,'',$cc[0],'',$this-&gt;Subject,$body);
</ins><span class="cx">       }
</span><span class="cx">     }
</span><del>-    for($i = 0; $i &lt; count($this-&gt;bcc); $i++) {
-      if(!$this-&gt;smtp-&gt;Recipient($this-&gt;bcc[$i][0])) {
-        $bad_rcpt[] = $this-&gt;bcc[$i][0];
</del><ins>+    foreach($this-&gt;bcc as $bcc) {
+      if (!$this-&gt;smtp-&gt;Recipient($bcc[0])) {
+        $bad_rcpt[] = $bcc[0];
+        // implement call back function if it exists
+        $isSent = 0;
+        $this-&gt;doCallback($isSent,'','',$bcc[0],$this-&gt;Subject,$body);
+      } else {
+        // implement call back function if it exists
+        $isSent = 1;
+        $this-&gt;doCallback($isSent,'','',$bcc[0],$this-&gt;Subject,$body);
</ins><span class="cx">       }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if(count($bad_rcpt) &gt; 0) { // Create error message
-      for($i = 0; $i &lt; count($bad_rcpt); $i++) {
-        if($i != 0) {
-          $error .= ', ';
-        }
-        $error .= $bad_rcpt[$i];
-      }
-      $error = $this-&gt;Lang('recipients_failed') . $error;
-      $this-&gt;SetError($error);
-      $this-&gt;smtp-&gt;Reset();
-      return false;
</del><ins>+
+    if (count($bad_rcpt) &gt; 0 ) { //Create error message for any bad addresses
+      $badaddresses = implode(', ', $bad_rcpt);
+      throw new phpmailerException($this-&gt;Lang('recipients_failed') . $badaddresses);
</ins><span class="cx">     }
</span><del>-
</del><span class="cx">     if(!$this-&gt;smtp-&gt;Data($header . $body)) {
</span><del>-      $this-&gt;SetError($this-&gt;Lang('data_not_accepted'));
-      $this-&gt;smtp-&gt;Reset();
-      return false;
</del><ins>+      throw new phpmailerException($this-&gt;Lang('data_not_accepted'), self::STOP_CRITICAL);
</ins><span class="cx">     }
</span><span class="cx">     if($this-&gt;SMTPKeepAlive == true) {
</span><span class="cx">       $this-&gt;smtp-&gt;Reset();
</span><del>-    } else {
-      $this-&gt;SmtpClose();
</del><span class="cx">     }
</span><del>-
</del><span class="cx">     return true;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Initiates a connection to an SMTP server.  Returns false if the
-   * operation failed.
-   * @access private
</del><ins>+   * Initiates a connection to an SMTP server.
+   * Returns false if the operation failed.
+   * @uses SMTP
+   * @access public
</ins><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function SmtpConnect() {
-    if($this-&gt;smtp == NULL) {
</del><ins>+  public function SmtpConnect() {
+    if(is_null($this-&gt;smtp)) {
</ins><span class="cx">       $this-&gt;smtp = new SMTP();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     $this-&gt;smtp-&gt;do_debug = $this-&gt;SMTPDebug;
</span><span class="cx">     $hosts = explode(';', $this-&gt;Host);
</span><span class="cx">     $index = 0;
</span><del>-    $connection = ($this-&gt;smtp-&gt;Connected());
</del><ins>+    $connection = $this-&gt;smtp-&gt;Connected();
</ins><span class="cx"> 
</span><del>-    /* Retry while there is no connection */
-    while($index &lt; count($hosts) &amp;&amp; $connection == false) {
-      $hostinfo = array();
-      if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) {
-        $host = $hostinfo[1];
-        $port = $hostinfo[2];
-      } else {
-        $host = $hosts[$index];
-        $port = $this-&gt;Port;
-      }
-
-      if($this-&gt;smtp-&gt;Connect(((!empty($this-&gt;SMTPSecure))?$this-&gt;SMTPSecure.'://':'').$host, $port, $this-&gt;Timeout)) {
-        if ($this-&gt;Helo != '') {
-          $this-&gt;smtp-&gt;Hello($this-&gt;Helo);
</del><ins>+    // Retry while there is no connection
+    try {
+      while($index &lt; count($hosts) &amp;&amp; !$connection) {
+        $hostinfo = array();
+        if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) {
+          $host = $hostinfo[1];
+          $port = $hostinfo[2];
</ins><span class="cx">         } else {
</span><del>-          $this-&gt;smtp-&gt;Hello($this-&gt;ServerHostname());
</del><ins>+          $host = $hosts[$index];
+          $port = $this-&gt;Port;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        $connection = true;
-        if($this-&gt;SMTPAuth) {
-          if(!$this-&gt;smtp-&gt;Authenticate($this-&gt;Username, $this-&gt;Password)) {
-            $this-&gt;SetError($this-&gt;Lang('authenticate'));
-            $this-&gt;smtp-&gt;Reset();
-            $connection = false;
</del><ins>+        $tls = ($this-&gt;SMTPSecure == 'tls');
+        $ssl = ($this-&gt;SMTPSecure == 'ssl');
+
+        if ($this-&gt;smtp-&gt;Connect(($ssl ? 'ssl://':'').$host, $port, $this-&gt;Timeout)) {
+
+          $hello = ($this-&gt;Helo != '' ? $this-&gt;Helo : $this-&gt;ServerHostname());
+          $this-&gt;smtp-&gt;Hello($hello);
+
+          if ($tls) {
+            if (!$this-&gt;smtp-&gt;StartTLS()) {
+              throw new phpmailerException($this-&gt;Lang('tls'));
+            }
+
+            //We must resend HELO after tls negotiation
+            $this-&gt;smtp-&gt;Hello($hello);
</ins><span class="cx">           }
</span><ins>+
+          $connection = true;
+          if ($this-&gt;SMTPAuth) {
+            if (!$this-&gt;smtp-&gt;Authenticate($this-&gt;Username, $this-&gt;Password)) {
+              throw new phpmailerException($this-&gt;Lang('authenticate'));
+            }
+          }
</ins><span class="cx">         }
</span><ins>+        $index++;
+        if (!$connection) {
+          throw new phpmailerException($this-&gt;Lang('connect_host'));
+        }
</ins><span class="cx">       }
</span><del>-      $index++;
</del><ins>+    } catch (phpmailerException $e) {
+      $this-&gt;smtp-&gt;Reset();
+      throw $e;
</ins><span class="cx">     }
</span><del>-    if(!$connection) {
-      $this-&gt;SetError($this-&gt;Lang('connect_host'));
-    }
-
-    return $connection;
</del><ins>+    return true;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Closes the active SMTP session if one exists.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function SmtpClose() {
-    if($this-&gt;smtp != NULL) {
</del><ins>+  public function SmtpClose() {
+    if(!is_null($this-&gt;smtp)) {
</ins><span class="cx">       if($this-&gt;smtp-&gt;Connected()) {
</span><span class="cx">         $this-&gt;smtp-&gt;Quit();
</span><span class="cx">         $this-&gt;smtp-&gt;Close();
</span><span class="lines">@@ -636,38 +841,48 @@
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Sets the language for all class error messages.  Returns false
-   * if it cannot load the language file.  The default language type
-   * is English.
-   * @param string $lang_type Type of language (e.g. Portuguese: &quot;br&quot;)
-   * @param string $lang_path Path to the language file directory
-   * @access public
-   * @return bool
-   */
-  function SetLanguage($lang_type, $lang_path = 'language/') {
-    if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) {
-      include($lang_path.'phpmailer.lang-'.$lang_type.'.php');
-    } elseif (file_exists($lang_path.'phpmailer.lang-en.php')) {
-      include($lang_path.'phpmailer.lang-en.php');
-    } else {
-      $PHPMAILER_LANG = array();
-      $PHPMAILER_LANG[&quot;provide_address&quot;]      = 'You must provide at least one ' .
-      $PHPMAILER_LANG[&quot;mailer_not_supported&quot;] = ' mailer is not supported.';
-      $PHPMAILER_LANG[&quot;execute&quot;]              = 'Could not execute: ';
-      $PHPMAILER_LANG[&quot;instantiate&quot;]          = 'Could not instantiate mail function.';
-      $PHPMAILER_LANG[&quot;authenticate&quot;]         = 'SMTP Error: Could not authenticate.';
-      $PHPMAILER_LANG[&quot;from_failed&quot;]          = 'The following From address failed: ';
-      $PHPMAILER_LANG[&quot;recipients_failed&quot;]    = 'SMTP Error: The following ' .
-      $PHPMAILER_LANG[&quot;data_not_accepted&quot;]    = 'SMTP Error: Data not accepted.';
-      $PHPMAILER_LANG[&quot;connect_host&quot;]         = 'SMTP Error: Could not connect to SMTP host.';
-      $PHPMAILER_LANG[&quot;file_access&quot;]          = 'Could not access file: ';
-      $PHPMAILER_LANG[&quot;file_open&quot;]            = 'File Error: Could not open file: ';
-      $PHPMAILER_LANG[&quot;encoding&quot;]             = 'Unknown encoding: ';
-      $PHPMAILER_LANG[&quot;signing&quot;]              = 'Signing Error: ';
</del><ins>+  * Sets the language for all class error messages.
+  * Returns false if it cannot load the language file.  The default language is English.
+  * @param string $langcode ISO 639-1 2-character language code (e.g. Portuguese: &quot;br&quot;)
+  * @param string $lang_path Path to the language file directory
+  * @access public
+  */
+  function SetLanguage($langcode = 'en', $lang_path = 'language/') {
+    //Define full set of translatable strings
+    $PHPMAILER_LANG = array(
+      'provide_address' =&gt; 'You must provide at least one recipient email address.',
+      'mailer_not_supported' =&gt; ' mailer is not supported.',
+      'execute' =&gt; 'Could not execute: ',
+      'instantiate' =&gt; 'Could not instantiate mail function.',
+      'authenticate' =&gt; 'SMTP Error: Could not authenticate.',
+      'from_failed' =&gt; 'The following From address failed: ',
+      'recipients_failed' =&gt; 'SMTP Error: The following recipients failed: ',
+      'data_not_accepted' =&gt; 'SMTP Error: Data not accepted.',
+      'connect_host' =&gt; 'SMTP Error: Could not connect to SMTP host.',
+      'file_access' =&gt; 'Could not access file: ',
+      'file_open' =&gt; 'File Error: Could not open file: ',
+      'encoding' =&gt; 'Unknown encoding: ',
+      'signing' =&gt; 'Signing Error: ',
+      'smtp_error' =&gt; 'SMTP server error: ',
+      'empty_message' =&gt; 'Message body empty',
+      'invalid_address' =&gt; 'Invalid address',
+      'variable_set' =&gt; 'Cannot set or reset variable: '
+    );
+    //Overwrite language-specific strings. This way we'll never have missing translations - no more &quot;language string failed to load&quot;!
+    $l = true;
+    if ($langcode != 'en') { //There is no English translation file
+      $l = @include $lang_path.'phpmailer.lang-'.$langcode.'.php';
</ins><span class="cx">     }
</span><span class="cx">     $this-&gt;language = $PHPMAILER_LANG;
</span><ins>+    return ($l == true); //Returns false if language not found
+  }
</ins><span class="cx"> 
</span><del>-    return true;
</del><ins>+  /**
+  * Return the current array of language strings
+  * @return array
+  */
+  public function GetTranslations() {
+    return $this-&gt;language;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /////////////////////////////////////////////////
</span><span class="lines">@@ -676,17 +891,16 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Creates recipient headers.
</span><del>-   * @access private
</del><ins>+   * @access public
</ins><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function AddrAppend($type, $addr) {
</del><ins>+  public function AddrAppend($type, $addr) {
</ins><span class="cx">     $addr_str = $type . ': ';
</span><del>-    $addr_str .= $this-&gt;AddrFormat($addr[0]);
-    if(count($addr) &gt; 1) {
-      for($i = 1; $i &lt; count($addr); $i++) {
-        $addr_str .= ', ' . $this-&gt;AddrFormat($addr[$i]);
-      }
</del><ins>+    $addresses = array();
+    foreach ($addr as $a) {
+      $addresses[] = $this-&gt;AddrFormat($a);
</ins><span class="cx">     }
</span><ins>+    $addr_str .= implode(', ', $addresses);
</ins><span class="cx">     $addr_str .= $this-&gt;LE;
</span><span class="cx"> 
</span><span class="cx">     return $addr_str;
</span><span class="lines">@@ -694,27 +908,28 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Formats an address correctly.
</span><del>-   * @access private
</del><ins>+   * @access public
</ins><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function AddrFormat($addr) {
-    if(empty($addr[1])) {
-      $formatted = $this-&gt;SecureHeader($addr[0]);
</del><ins>+  public function AddrFormat($addr) {
+    if (empty($addr[1])) {
+      return $this-&gt;SecureHeader($addr[0]);
</ins><span class="cx">     } else {
</span><del>-      $formatted = $this-&gt;EncodeHeader($this-&gt;SecureHeader($addr[1]), 'phrase') . &quot; &lt;&quot; . $this-&gt;SecureHeader($addr[0]) . &quot;&gt;&quot;;
</del><ins>+      return $this-&gt;EncodeHeader($this-&gt;SecureHeader($addr[1]), 'phrase') . &quot; &lt;&quot; . $this-&gt;SecureHeader($addr[0]) . &quot;&gt;&quot;;
</ins><span class="cx">     }
</span><del>-
-    return $formatted;
</del><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Wraps message for use with mailers that do not
</span><span class="cx">    * automatically perform wrapping and for quoted-printable.
</span><span class="cx">    * Original written by philippe.
</span><del>-   * @access private
</del><ins>+   * @param string $message The message to wrap
+   * @param integer $length The line length to wrap to
+   * @param boolean $qp_mode Whether to run in Quoted-Printable mode
+   * @access public
</ins><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function WrapText($message, $length, $qp_mode = false) {
</del><ins>+  public function WrapText($message, $length, $qp_mode = false) {
</ins><span class="cx">     $soft_break = ($qp_mode) ? sprintf(&quot; =%s&quot;, $this-&gt;LE) : $this-&gt;LE;
</span><span class="cx">     // If utf-8 encoding is used, we will need to make sure we don't
</span><span class="cx">     // split multibyte characters when we wrap
</span><span class="lines">@@ -791,12 +1006,12 @@
</span><span class="cx">    * Finds last character boundary prior to maxLength in a utf-8
</span><span class="cx">    * quoted (printable) encoded string.
</span><span class="cx">    * Original written by Colin Brown.
</span><del>-   * @access private
</del><ins>+   * @access public
</ins><span class="cx">    * @param string $encodedText utf-8 QP text
</span><span class="cx">    * @param int    $maxLength   find last character boundary prior to this length
</span><span class="cx">    * @return int
</span><span class="cx">    */
</span><del>-  function UTF8CharBoundary($encodedText, $maxLength) {
</del><ins>+  public function UTF8CharBoundary($encodedText, $maxLength) {
</ins><span class="cx">     $foundSplitPos = false;
</span><span class="cx">     $lookBack = 3;
</span><span class="cx">     while (!$foundSplitPos) {
</span><span class="lines">@@ -828,19 +1043,19 @@
</span><span class="cx">     return $maxLength;
</span><span class="cx">   }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">   /**
</span><span class="cx">    * Set the body wrapping.
</span><del>-   * @access private
</del><ins>+   * @access public
</ins><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function SetWordWrap() {
</del><ins>+  public function SetWordWrap() {
</ins><span class="cx">     if($this-&gt;WordWrap &lt; 1) {
</span><span class="cx">       return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     switch($this-&gt;message_type) {
</span><span class="cx">       case 'alt':
</span><del>-        /* fall through */
</del><span class="cx">       case 'alt_attachments':
</span><span class="cx">         $this-&gt;AltBody = $this-&gt;WrapText($this-&gt;AltBody, $this-&gt;WordWrap);
</span><span class="cx">         break;
</span><span class="lines">@@ -852,30 +1067,36 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Assembles message header.
</span><del>-   * @access private
-   * @return string
</del><ins>+   * @access public
+   * @return string The assembled header
</ins><span class="cx">    */
</span><del>-  function CreateHeader() {
</del><ins>+  public function CreateHeader() {
</ins><span class="cx">     $result = '';
</span><span class="cx"> 
</span><del>-    /* Set the boundaries */
</del><ins>+    // Set the boundaries
</ins><span class="cx">     $uniq_id = md5(uniqid(time()));
</span><span class="cx">     $this-&gt;boundary[1] = 'b1_' . $uniq_id;
</span><span class="cx">     $this-&gt;boundary[2] = 'b2_' . $uniq_id;
</span><span class="cx"> 
</span><del>-    $result .= $this-&gt;HeaderLine('Date', $this-&gt;RFCDate());
</del><ins>+    $result .= $this-&gt;HeaderLine('Date', self::RFCDate());
</ins><span class="cx">     if($this-&gt;Sender == '') {
</span><span class="cx">       $result .= $this-&gt;HeaderLine('Return-Path', trim($this-&gt;From));
</span><span class="cx">     } else {
</span><span class="cx">       $result .= $this-&gt;HeaderLine('Return-Path', trim($this-&gt;Sender));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    /* To be created automatically by mail() */
</del><ins>+    // To be created automatically by mail()
</ins><span class="cx">     if($this-&gt;Mailer != 'mail') {
</span><del>-      if(count($this-&gt;to) &gt; 0) {
-        $result .= $this-&gt;AddrAppend('To', $this-&gt;to);
-      } elseif (count($this-&gt;cc) == 0) {
-        $result .= $this-&gt;HeaderLine('To', 'undisclosed-recipients:;');
</del><ins>+      if ($this-&gt;SingleTo === true) {
+        foreach($this-&gt;to as $t) {
+          $this-&gt;SingleToArray[] = $this-&gt;AddrFormat($t);
+        }
+      } else {
+        if(count($this-&gt;to) &gt; 0) {
+          $result .= $this-&gt;AddrAppend('To', $this-&gt;to);
+        } elseif (count($this-&gt;cc) == 0) {
+          $result .= $this-&gt;HeaderLine('To', 'undisclosed-recipients:;');
+        }
</ins><span class="cx">       }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -884,21 +1105,21 @@
</span><span class="cx">     $from[0][1] = $this-&gt;FromName;
</span><span class="cx">     $result .= $this-&gt;AddrAppend('From', $from);
</span><span class="cx"> 
</span><del>-    /* sendmail and mail() extract Cc from the header before sending */
-    if((($this-&gt;Mailer == 'sendmail') || ($this-&gt;Mailer == 'mail')) &amp;&amp; (count($this-&gt;cc) &gt; 0)) {
</del><ins>+    // sendmail and mail() extract Cc from the header before sending
+    if(count($this-&gt;cc) &gt; 0) {
</ins><span class="cx">       $result .= $this-&gt;AddrAppend('Cc', $this-&gt;cc);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    /* sendmail and mail() extract Bcc from the header before sending */
</del><ins>+    // sendmail and mail() extract Bcc from the header before sending
</ins><span class="cx">     if((($this-&gt;Mailer == 'sendmail') || ($this-&gt;Mailer == 'mail')) &amp;&amp; (count($this-&gt;bcc) &gt; 0)) {
</span><span class="cx">       $result .= $this-&gt;AddrAppend('Bcc', $this-&gt;bcc);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if(count($this-&gt;ReplyTo) &gt; 0) {
</span><del>-      $result .= $this-&gt;AddrAppend('Reply-To', $this-&gt;ReplyTo);
</del><ins>+      $result .= $this-&gt;AddrAppend('Reply-to', $this-&gt;ReplyTo);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    /* mail() sets the subject itself */
</del><ins>+    // mail() sets the subject itself
</ins><span class="cx">     if($this-&gt;Mailer != 'mail') {
</span><span class="cx">       $result .= $this-&gt;HeaderLine('Subject', $this-&gt;EncodeHeader($this-&gt;SecureHeader($this-&gt;Subject)));
</span><span class="cx">     }
</span><span class="lines">@@ -909,7 +1130,7 @@
</span><span class="cx">       $result .= sprintf(&quot;Message-ID: &lt;%s@%s&gt;%s&quot;, $uniq_id, $this-&gt;ServerHostname(), $this-&gt;LE);
</span><span class="cx">     }
</span><span class="cx">     $result .= $this-&gt;HeaderLine('X-Priority', $this-&gt;Priority);
</span><del>-    $result .= $this-&gt;HeaderLine('X-Mailer', 'PHPMailer (phpmailer.sourceforge.net) [version ' . $this-&gt;Version . ']');
</del><ins>+    $result .= $this-&gt;HeaderLine('X-Mailer', 'PHPMailer '.$this-&gt;Version.' (phpmailer.sourceforge.net)');
</ins><span class="cx"> 
</span><span class="cx">     if($this-&gt;ConfirmReadingTo != '') {
</span><span class="cx">       $result .= $this-&gt;HeaderLine('Disposition-Notification-To', '&lt;' . trim($this-&gt;ConfirmReadingTo) . '&gt;');
</span><span class="lines">@@ -929,10 +1150,10 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Returns the message MIME.
</span><del>-   * @access private
</del><ins>+   * @access public
</ins><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function GetMailMIME() {
</del><ins>+  public function GetMailMIME() {
</ins><span class="cx">     $result = '';
</span><span class="cx">     switch($this-&gt;message_type) {
</span><span class="cx">       case 'plain':
</span><span class="lines">@@ -940,7 +1161,6 @@
</span><span class="cx">         $result .= sprintf(&quot;Content-Type: %s; charset=\&quot;%s\&quot;&quot;, $this-&gt;ContentType, $this-&gt;CharSet);
</span><span class="cx">         break;
</span><span class="cx">       case 'attachments':
</span><del>-        /* fall through */
</del><span class="cx">       case 'alt_attachments':
</span><span class="cx">         if($this-&gt;InlineImageExists()){
</span><span class="cx">           $result .= sprintf(&quot;Content-Type: %s;%s\ttype=\&quot;text/html\&quot;;%s\tboundary=\&quot;%s\&quot;%s&quot;, 'multipart/related', $this-&gt;LE, $this-&gt;LE, $this-&gt;boundary[1], $this-&gt;LE);
</span><span class="lines">@@ -964,84 +1184,83 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Assembles the message body.  Returns an empty string on failure.
</span><del>-   * @access private
-   * @return string
</del><ins>+   * @access public
+   * @return string The assembled message body
</ins><span class="cx">    */
</span><del>-  function CreateBody() {
-    $result = '';
</del><ins>+  public function CreateBody() {
+    $body = '';
+
</ins><span class="cx">     if ($this-&gt;sign_key_file) {
</span><del>-      $result .= $this-&gt;GetMailMIME();
</del><ins>+      $body .= $this-&gt;GetMailMIME();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     $this-&gt;SetWordWrap();
</span><span class="cx"> 
</span><span class="cx">     switch($this-&gt;message_type) {
</span><span class="cx">       case 'alt':
</span><del>-        $result .= $this-&gt;GetBoundary($this-&gt;boundary[1], '', 'text/plain', '');
-        $result .= $this-&gt;EncodeString($this-&gt;AltBody, $this-&gt;Encoding);
-        $result .= $this-&gt;LE.$this-&gt;LE;
-        $result .= $this-&gt;GetBoundary($this-&gt;boundary[1], '', 'text/html', '');
-        $result .= $this-&gt;EncodeString($this-&gt;Body, $this-&gt;Encoding);
-        $result .= $this-&gt;LE.$this-&gt;LE;
-        $result .= $this-&gt;EndBoundary($this-&gt;boundary[1]);
</del><ins>+        $body .= $this-&gt;GetBoundary($this-&gt;boundary[1], '', 'text/plain', '');
+        $body .= $this-&gt;EncodeString($this-&gt;AltBody, $this-&gt;Encoding);
+        $body .= $this-&gt;LE.$this-&gt;LE;
+        $body .= $this-&gt;GetBoundary($this-&gt;boundary[1], '', 'text/html', '');
+        $body .= $this-&gt;EncodeString($this-&gt;Body, $this-&gt;Encoding);
+        $body .= $this-&gt;LE.$this-&gt;LE;
+        $body .= $this-&gt;EndBoundary($this-&gt;boundary[1]);
</ins><span class="cx">         break;
</span><span class="cx">       case 'plain':
</span><del>-        $result .= $this-&gt;EncodeString($this-&gt;Body, $this-&gt;Encoding);
</del><ins>+        $body .= $this-&gt;EncodeString($this-&gt;Body, $this-&gt;Encoding);
</ins><span class="cx">         break;
</span><span class="cx">       case 'attachments':
</span><del>-        $result .= $this-&gt;GetBoundary($this-&gt;boundary[1], '', '', '');
-        $result .= $this-&gt;EncodeString($this-&gt;Body, $this-&gt;Encoding);
-        $result .= $this-&gt;LE;
-        $result .= $this-&gt;AttachAll();
</del><ins>+        $body .= $this-&gt;GetBoundary($this-&gt;boundary[1], '', '', '');
+        $body .= $this-&gt;EncodeString($this-&gt;Body, $this-&gt;Encoding);
+        $body .= $this-&gt;LE;
+        $body .= $this-&gt;AttachAll();
</ins><span class="cx">         break;
</span><span class="cx">       case 'alt_attachments':
</span><del>-        $result .= sprintf(&quot;--%s%s&quot;, $this-&gt;boundary[1], $this-&gt;LE);
-        $result .= sprintf(&quot;Content-Type: %s;%s&quot; . &quot;\tboundary=\&quot;%s\&quot;%s&quot;, 'multipart/alternative', $this-&gt;LE, $this-&gt;boundary[2], $this-&gt;LE.$this-&gt;LE);
-        $result .= $this-&gt;GetBoundary($this-&gt;boundary[2], '', 'text/plain', '') . $this-&gt;LE; // Create text body
-        $result .= $this-&gt;EncodeString($this-&gt;AltBody, $this-&gt;Encoding);
-        $result .= $this-&gt;LE.$this-&gt;LE;
-        $result .= $this-&gt;GetBoundary($this-&gt;boundary[2], '', 'text/html', '') . $this-&gt;LE; // Create the HTML body
-        $result .= $this-&gt;EncodeString($this-&gt;Body, $this-&gt;Encoding);
-        $result .= $this-&gt;LE.$this-&gt;LE;
-        $result .= $this-&gt;EndBoundary($this-&gt;boundary[2]);
-        $result .= $this-&gt;AttachAll();
</del><ins>+        $body .= sprintf(&quot;--%s%s&quot;, $this-&gt;boundary[1], $this-&gt;LE);
+        $body .= sprintf(&quot;Content-Type: %s;%s&quot; . &quot;\tboundary=\&quot;%s\&quot;%s&quot;, 'multipart/alternative', $this-&gt;LE, $this-&gt;boundary[2], $this-&gt;LE.$this-&gt;LE);
+        $body .= $this-&gt;GetBoundary($this-&gt;boundary[2], '', 'text/plain', '') . $this-&gt;LE; // Create text body
+        $body .= $this-&gt;EncodeString($this-&gt;AltBody, $this-&gt;Encoding);
+        $body .= $this-&gt;LE.$this-&gt;LE;
+        $body .= $this-&gt;GetBoundary($this-&gt;boundary[2], '', 'text/html', '') . $this-&gt;LE; // Create the HTML body
+        $body .= $this-&gt;EncodeString($this-&gt;Body, $this-&gt;Encoding);
+        $body .= $this-&gt;LE.$this-&gt;LE;
+        $body .= $this-&gt;EndBoundary($this-&gt;boundary[2]);
+        $body .= $this-&gt;AttachAll();
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if($this-&gt;IsError()) {
-      $result = '';
-    } else if ($this-&gt;sign_key_file) {
-      $file = tempnam(&quot;&quot;, &quot;mail&quot;);
-      $fp = fopen($file, &quot;w&quot;);
-      fwrite($fp, $result);
-      fclose($fp);
-      $signed = tempnam(&quot;&quot;, &quot;signed&quot;);
-
-      if (@openssl_pkcs7_sign($file, $signed, &quot;file://&quot;.$this-&gt;sign_cert_file, array(&quot;file://&quot;.$this-&gt;sign_key_file, $this-&gt;sign_key_pass), null)) {
-        $fp = fopen($signed, &quot;r&quot;);
-        $result = fread($fp, filesize($this-&gt;sign_key_file));
-        $result = '';
-        while(!feof($fp)){
-          $result = $result . fread($fp, 1024);
</del><ins>+    if ($this-&gt;IsError()) {
+      $body = '';
+    } elseif ($this-&gt;sign_key_file) {
+      try {
+        $file = tempnam('', 'mail');
+        file_put_contents($file, $body); //TODO check this worked
+        $signed = tempnam(&quot;&quot;, &quot;signed&quot;);
+        if (@openssl_pkcs7_sign($file, $signed, &quot;file://&quot;.$this-&gt;sign_cert_file, array(&quot;file://&quot;.$this-&gt;sign_key_file, $this-&gt;sign_key_pass), NULL)) {
+          @unlink($file);
+          @unlink($signed);
+          $body = file_get_contents($signed);
+        } else {
+          @unlink($file);
+          @unlink($signed);
+          throw new phpmailerException($this-&gt;Lang(&quot;signing&quot;).openssl_error_string());
</ins><span class="cx">         }
</span><del>-        fclose($fp);
-      } else {
-        $this-&gt;SetError($this-&gt;Lang(&quot;signing&quot;).openssl_error_string());
-        $result = '';
</del><ins>+      } catch (phpmailerException $e) {
+        $body = '';
+        if ($this-&gt;exceptions) {
+          throw $e;
+        }
</ins><span class="cx">       }
</span><del>-
-      unlink($file);
-      unlink($signed);
</del><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return $result;
</del><ins>+    return $body;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Returns the start of a message boundary.
</span><span class="cx">    * @access private
</span><span class="cx">    */
</span><del>-  function GetBoundary($boundary, $charSet, $contentType, $encoding) {
</del><ins>+  private function GetBoundary($boundary, $charSet, $contentType, $encoding) {
</ins><span class="cx">     $result = '';
</span><span class="cx">     if($charSet == '') {
</span><span class="cx">       $charSet = $this-&gt;CharSet;
</span><span class="lines">@@ -1065,7 +1284,7 @@
</span><span class="cx">    * Returns the end of a message boundary.
</span><span class="cx">    * @access private
</span><span class="cx">    */
</span><del>-  function EndBoundary($boundary) {
</del><ins>+  private function EndBoundary($boundary) {
</ins><span class="cx">     return $this-&gt;LE . '--' . $boundary . '--' . $this-&gt;LE;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -1074,7 +1293,7 @@
</span><span class="cx">    * @access private
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function SetMessageType() {
</del><ins>+  private function SetMessageType() {
</ins><span class="cx">     if(count($this-&gt;attachment) &lt; 1 &amp;&amp; strlen($this-&gt;AltBody) &lt; 1) {
</span><span class="cx">       $this-&gt;message_type = 'plain';
</span><span class="cx">     } else {
</span><span class="lines">@@ -1090,20 +1309,21 @@
</span><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> 
</span><del>-  /* Returns a formatted header line.
-   * @access private
</del><ins>+  /**
+   *  Returns a formatted header line.
+   * @access public
</ins><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function HeaderLine($name, $value) {
</del><ins>+  public function HeaderLine($name, $value) {
</ins><span class="cx">     return $name . ': ' . $value . $this-&gt;LE;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Returns a formatted mail line.
</span><del>-   * @access private
</del><ins>+   * @access public
</ins><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function TextLine($value) {
</del><ins>+  public function TextLine($value) {
</ins><span class="cx">     return $value . $this-&gt;LE;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -1121,56 +1341,80 @@
</span><span class="cx">    * @param string $type File extension (MIME) type.
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
-    if(!@is_file($path)) {
-      $this-&gt;SetError($this-&gt;Lang('file_access') . $path);
-      return false;
-    }
</del><ins>+  public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
+    try {
+      if ( !@is_file($path) ) {
+        throw new phpmailerException($this-&gt;Lang('file_access') . $path, self::STOP_CONTINUE);
+      }
+      $filename = basename($path);
+      if ( $name == '' ) {
+        $name = $filename;
+      }
</ins><span class="cx"> 
</span><del>-    $filename = basename($path);
-    if($name == '') {
-      $name = $filename;
</del><ins>+      $this-&gt;attachment[] = array(
+        0 =&gt; $path,
+        1 =&gt; $filename,
+        2 =&gt; $name,
+        3 =&gt; $encoding,
+        4 =&gt; $type,
+        5 =&gt; false,  // isStringAttachment
+        6 =&gt; 'attachment',
+        7 =&gt; 0
+      );
+
+    } catch (phpmailerException $e) {
+      $this-&gt;SetError($e-&gt;getMessage());
+      if ($this-&gt;exceptions) {
+        throw $e;
+      }
+      echo $e-&gt;getMessage().&quot;\n&quot;;
+      if ( $e-&gt;getCode() == self::STOP_CRITICAL ) {
+        return false;
+      }
</ins><span class="cx">     }
</span><del>-
-    $cur = count($this-&gt;attachment);
-    $this-&gt;attachment[$cur][0] = $path;
-    $this-&gt;attachment[$cur][1] = $filename;
-    $this-&gt;attachment[$cur][2] = $name;
-    $this-&gt;attachment[$cur][3] = $encoding;
-    $this-&gt;attachment[$cur][4] = $type;
-    $this-&gt;attachment[$cur][5] = false; // isStringAttachment
-    $this-&gt;attachment[$cur][6] = 'attachment';
-    $this-&gt;attachment[$cur][7] = 0;
-
</del><span class="cx">     return true;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><ins>+  * Return the current array of attachments
+  * @return array
+  */
+  public function GetAttachments() {
+    return $this-&gt;attachment;
+  }
+
+  /**
</ins><span class="cx">    * Attaches all fs, string, and binary attachments to the message.
</span><span class="cx">    * Returns an empty string on failure.
</span><span class="cx">    * @access private
</span><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function AttachAll() {
-    /* Return text of body */
</del><ins>+  private function AttachAll() {
+    // Return text of body
</ins><span class="cx">     $mime = array();
</span><ins>+    $cidUniq = array();
+    $incl = array();
</ins><span class="cx"> 
</span><del>-    /* Add all attachments */
-    for($i = 0; $i &lt; count($this-&gt;attachment); $i++) {
-      /* Check for string attachment */
-      $bString = $this-&gt;attachment[$i][5];
</del><ins>+    // Add all attachments
+    foreach ($this-&gt;attachment as $attachment) {
+      // Check for string attachment
+      $bString = $attachment[5];
</ins><span class="cx">       if ($bString) {
</span><del>-        $string = $this-&gt;attachment[$i][0];
</del><ins>+        $string = $attachment[0];
</ins><span class="cx">       } else {
</span><del>-        $path = $this-&gt;attachment[$i][0];
</del><ins>+        $path = $attachment[0];
</ins><span class="cx">       }
</span><span class="cx"> 
</span><del>-      $filename    = $this-&gt;attachment[$i][1];
-      $name        = $this-&gt;attachment[$i][2];
-      $encoding    = $this-&gt;attachment[$i][3];
-      $type        = $this-&gt;attachment[$i][4];
-      $disposition = $this-&gt;attachment[$i][6];
-      $cid         = $this-&gt;attachment[$i][7];
</del><ins>+      if (in_array($attachment[0], $incl)) { continue; }
+      $filename    = $attachment[1];
+      $name        = $attachment[2];
+      $encoding    = $attachment[3];
+      $type        = $attachment[4];
+      $disposition = $attachment[6];
+      $cid         = $attachment[7];
+      $incl[]      = $attachment[0];
+      if ( $disposition == 'inline' &amp;&amp; isset($cidUniq[$cid]) ) { continue; }
+      $cidUniq[$cid] = true;
</ins><span class="cx"> 
</span><span class="cx">       $mime[] = sprintf(&quot;--%s%s&quot;, $this-&gt;boundary[1], $this-&gt;LE);
</span><span class="cx">       $mime[] = sprintf(&quot;Content-Type: %s; name=\&quot;%s\&quot;%s&quot;, $type, $this-&gt;EncodeHeader($this-&gt;SecureHeader($name)), $this-&gt;LE);
</span><span class="lines">@@ -1182,7 +1426,7 @@
</span><span class="cx"> 
</span><span class="cx">       $mime[] = sprintf(&quot;Content-Disposition: %s; filename=\&quot;%s\&quot;%s&quot;, $disposition, $this-&gt;EncodeHeader($this-&gt;SecureHeader($name)), $this-&gt;LE.$this-&gt;LE);
</span><span class="cx"> 
</span><del>-      /* Encode as string attachment */
</del><ins>+      // Encode as string attachment
</ins><span class="cx">       if($bString) {
</span><span class="cx">         $mime[] = $this-&gt;EncodeString($string, $encoding);
</span><span class="cx">         if($this-&gt;IsError()) {
</span><span class="lines">@@ -1204,42 +1448,56 @@
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Encodes attachment in requested format.  Returns an
-   * empty string on failure.
</del><ins>+   * Encodes attachment in requested format.
+   * Returns an empty string on failure.
+   * @param string $path The full path to the file
+   * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
+   * @see EncodeFile()
</ins><span class="cx">    * @access private
</span><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function EncodeFile ($path, $encoding = 'base64') {
-    if(!@$fd = fopen($path, 'rb')) {
-      $this-&gt;SetError($this-&gt;Lang('file_open') . $path);
</del><ins>+  private function EncodeFile($path, $encoding = 'base64') {
+    try {
+      if (!is_readable($path)) {
+        throw new phpmailerException($this-&gt;Lang('file_open') . $path, self::STOP_CONTINUE);
+      }
+      if (function_exists('get_magic_quotes')) {
+        function get_magic_quotes() {
+          return false;
+        }
+      }
+      if (PHP_VERSION &lt; 6) {
+        $magic_quotes = get_magic_quotes_runtime();
+        set_magic_quotes_runtime(0);
+      }
+      $file_buffer  = file_get_contents($path);
+      $file_buffer  = $this-&gt;EncodeString($file_buffer, $encoding);
+      if (PHP_VERSION &lt; 6) { set_magic_quotes_runtime($magic_quotes); }
+      return $file_buffer;
+    } catch (Exception $e) {
+      $this-&gt;SetError($e-&gt;getMessage());
</ins><span class="cx">       return '';
</span><span class="cx">     }
</span><del>-    $magic_quotes = get_magic_quotes_runtime();
-    set_magic_quotes_runtime(0);
-    $file_buffer = fread($fd, filesize($path));
-    $file_buffer = $this-&gt;EncodeString($file_buffer, $encoding);
-    fclose($fd);
-    set_magic_quotes_runtime($magic_quotes);
-
-    return $file_buffer;
</del><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Encodes string to requested format. Returns an
-   * empty string on failure.
-   * @access private
</del><ins>+   * Encodes string to requested format.
+   * Returns an empty string on failure.
+   * @param string $str The text to encode
+   * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
+   * @access public
</ins><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function EncodeString ($str, $encoding = 'base64') {
</del><ins>+  public function EncodeString ($str, $encoding = 'base64') {
</ins><span class="cx">     $encoded = '';
</span><span class="cx">     switch(strtolower($encoding)) {
</span><span class="cx">       case 'base64':
</span><del>-        /* chunk_split is found in PHP &gt;= 3.0.6 */
</del><span class="cx">         $encoded = chunk_split(base64_encode($str), 76, $this-&gt;LE);
</span><span class="cx">         break;
</span><span class="cx">       case '7bit':
</span><span class="cx">       case '8bit':
</span><span class="cx">         $encoded = $this-&gt;FixEOL($str);
</span><ins>+        //Make sure it ends with a line break
</ins><span class="cx">         if (substr($encoded, -(strlen($this-&gt;LE))) != $this-&gt;LE)
</span><span class="cx">           $encoded .= $this-&gt;LE;
</span><span class="cx">         break;
</span><span class="lines">@@ -1257,17 +1515,17 @@
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Encode a header string to best of Q, B, quoted or none.
-   * @access private
</del><ins>+   * Encode a header string to best (shortest) of Q, B, quoted or none.
+   * @access public
</ins><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function EncodeHeader ($str, $position = 'text') {
</del><ins>+  public function EncodeHeader($str, $position = 'text') {
</ins><span class="cx">     $x = 0;
</span><span class="cx"> 
</span><span class="cx">     switch (strtolower($position)) {
</span><span class="cx">       case 'phrase':
</span><span class="cx">         if (!preg_match('/[\200-\377]/', $str)) {
</span><del>-          /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */
</del><ins>+          // Can't use addslashes as we don't know what value has magic_quotes_sybase
</ins><span class="cx">           $encoded = addcslashes($str, &quot;\0..\37\177\\\&quot;&quot;);
</span><span class="cx">           if (($str == $encoded) &amp;&amp; !preg_match('/[^A-Za-z0-9!#$%&amp;\'*+\/=?^_`{|}~ -]/', $str)) {
</span><span class="cx">             return ($encoded);
</span><span class="lines">@@ -1279,7 +1537,7 @@
</span><span class="cx">         break;
</span><span class="cx">       case 'comment':
</span><span class="cx">         $x = preg_match_all('/[()&quot;]/', $str, $matches);
</span><del>-        /* Fall-through */
</del><ins>+        // Fall-through
</ins><span class="cx">       case 'text':
</span><span class="cx">       default:
</span><span class="cx">         $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
</span><span class="lines">@@ -1291,12 +1549,12 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     $maxlen = 75 - 7 - strlen($this-&gt;CharSet);
</span><del>-    /* Try to select the encoding which should produce the shortest output */
</del><ins>+    // Try to select the encoding which should produce the shortest output
</ins><span class="cx">     if (strlen($str)/3 &lt; $x) {
</span><span class="cx">       $encoding = 'B';
</span><span class="cx">       if (function_exists('mb_strlen') &amp;&amp; $this-&gt;HasMultiBytes($str)) {
</span><del>-     // Use a custom function which correctly encodes and wraps long
-     // multibyte strings without breaking lines within a character
</del><ins>+        // Use a custom function which correctly encodes and wraps long
+        // multibyte strings without breaking lines within a character
</ins><span class="cx">         $encoded = $this-&gt;Base64EncodeWrapMB($str);
</span><span class="cx">       } else {
</span><span class="cx">         $encoded = base64_encode($str);
</span><span class="lines">@@ -1318,15 +1576,15 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Checks if a string contains multibyte characters.
</span><del>-   * @access private
</del><ins>+   * @access public
</ins><span class="cx">    * @param string $str multi-byte text to wrap encode
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function HasMultiBytes($str) {
</del><ins>+  public function HasMultiBytes($str) {
</ins><span class="cx">     if (function_exists('mb_strlen')) {
</span><span class="cx">       return (strlen($str) &gt; mb_strlen($str, $this-&gt;CharSet));
</span><span class="cx">     } else { // Assume no multibytes (we can't handle without mbstring functions anyway)
</span><del>-      return False;
</del><ins>+      return false;
</ins><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -1334,11 +1592,11 @@
</span><span class="cx">    * Correctly encodes and wraps long multibyte strings for mail headers
</span><span class="cx">    * without breaking lines within a character.
</span><span class="cx">    * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
</span><del>-   * @access private
</del><ins>+   * @access public
</ins><span class="cx">    * @param string $str multi-byte text to wrap encode
</span><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function Base64EncodeWrapMB($str) {
</del><ins>+  public function Base64EncodeWrapMB($str) {
</ins><span class="cx">     $start = &quot;=?&quot;.$this-&gt;CharSet.&quot;?B?&quot;;
</span><span class="cx">     $end = &quot;?=&quot;;
</span><span class="cx">     $encoded = &quot;&quot;;
</span><span class="lines">@@ -1371,11 +1629,14 @@
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Encode string to quoted-printable.
-   * @access private
-   * @return string
-   */
-  function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) {
</del><ins>+  * Encode string to quoted-printable.
+  * Only uses standard PHP, slow, but will always work
+  * @access public
+  * @param string $string the text to encode
+  * @param integer $line_max Number of chars allowed on a line before wrapping
+  * @return string
+  */
+  public function EncodeQPphp( $input = '', $line_max = 76, $space_conv = false) {
</ins><span class="cx">     $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
</span><span class="cx">     $lines = preg_split('/(?:\r\n|\r|\n)/', $input);
</span><span class="cx">     $eol = &quot;\r\n&quot;;
</span><span class="lines">@@ -1417,41 +1678,66 @@
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Callback for converting to &quot;=XX&quot;.
-   * @access private
-   * @return string
-   */
-  function EncodeQ_callback ($matches) {
-    return sprintf('=%02X', ord($matches[1]));
</del><ins>+  * Encode string to RFC2045 (6.7) quoted-printable format
+  * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version
+  * Also results in same content as you started with after decoding
+  * @see EncodeQPphp()
+  * @access public
+  * @param string $string the text to encode
+  * @param integer $line_max Number of chars allowed on a line before wrapping
+  * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function
+  * @return string
+  * @author Marcus Bointon
+  */
+  public function EncodeQP($string, $line_max = 76, $space_conv = false) {
+    if (function_exists('quoted_printable_encode')) { //Use native function if it's available (&gt;= PHP5.3)
+      return quoted_printable_encode($string);
+    }
+    $filters = stream_get_filters();
+    if (!in_array('convert.*', $filters)) { //Got convert stream filter?
+      return $this-&gt;EncodeQPphp($string, $line_max, $space_conv); //Fall back to old implementation
+    }
+    $fp = fopen('php://temp/', 'r+');
+    $string = preg_replace('/\r\n?/', $this-&gt;LE, $string); //Normalise line breaks
+    $params = array('line-length' =&gt; $line_max, 'line-break-chars' =&gt; $this-&gt;LE);
+    $s = stream_filter_append($fp, 'convert.quoted-printable-encode', STREAM_FILTER_READ, $params);
+    fputs($fp, $string);
+    rewind($fp);
+    $out = stream_get_contents($fp);
+    stream_filter_remove($s);
+    $out = preg_replace('/^\./m', '=2E', $out); //Encode . if it is first char on a line, workaround for bug in Exchange
+    fclose($fp);
+    return $out;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Encode string to q encoding.
</span><del>-   * @access private
</del><ins>+   * @link http://tools.ietf.org/html/rfc2047
+   * @param string $str the text to encode
+   * @param string $position Where the text is going to be used, see the RFC for what that means
+   * @access public
</ins><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function EncodeQ ($str, $position = 'text') {
-    /* There should not be any EOL in the string */
-    $encoded = preg_replace(&quot;/[\r\n]/&quot;, '', $str);
</del><ins>+  public function EncodeQ ($str, $position = 'text') {
+    // There should not be any EOL in the string
+    $encoded = preg_replace('/[\r\n]*/', '', $str);
</ins><span class="cx"> 
</span><span class="cx">     switch (strtolower($position)) {
</span><span class="cx">       case 'phrase':
</span><del>-        $encoded = preg_replace_callback(&quot;/([^A-Za-z0-9!*+\/ -])/&quot;,
-                                         array('PHPMailer', 'EncodeQ_callback'), $encoded);
</del><ins>+        $encoded = preg_replace(&quot;/([^A-Za-z0-9!*+\/ -])/e&quot;, &quot;'='.sprintf('%02X', ord('\\1'))&quot;, $encoded);
</ins><span class="cx">         break;
</span><span class="cx">       case 'comment':
</span><del>-        $encoded = preg_replace_callback(&quot;/([\(\)\&quot;])/&quot;,
-                                         array('PHPMailer', 'EncodeQ_callback'), $encoded);
-        break;
</del><ins>+        $encoded = preg_replace(&quot;/([\(\)\&quot;])/e&quot;, &quot;'='.sprintf('%02X', ord('\\1'))&quot;, $encoded);
</ins><span class="cx">       case 'text':
</span><span class="cx">       default:
</span><del>-        /* Replace every high ascii, control =, ? and _ characters */
-        $encoded = preg_replace_callback('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/',
-                                         array('PHPMailer', 'EncodeQ_callback'), $encoded);
</del><ins>+        // Replace every high ascii, control =, ? and _ characters
+        //TODO using /e (equivalent to eval()) is probably not a good idea
+        $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
+              &quot;'='.sprintf('%02X', ord('\\1'))&quot;, $encoded);
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    /* Replace every spaces to _ (more readable than =20) */
</del><ins>+    // Replace every spaces to _ (more readable than =20)
</ins><span class="cx">     $encoded = str_replace(' ', '_', $encoded);
</span><span class="cx"> 
</span><span class="cx">     return $encoded;
</span><span class="lines">@@ -1467,17 +1753,18 @@
</span><span class="cx">    * @param string $type File extension (MIME) type.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
-    /* Append to $attachment array */
-    $cur = count($this-&gt;attachment);
-    $this-&gt;attachment[$cur][0] = $string;
-    $this-&gt;attachment[$cur][1] = $filename;
-    $this-&gt;attachment[$cur][2] = $filename;
-    $this-&gt;attachment[$cur][3] = $encoding;
-    $this-&gt;attachment[$cur][4] = $type;
-    $this-&gt;attachment[$cur][5] = true; // isString
-    $this-&gt;attachment[$cur][6] = 'attachment';
-    $this-&gt;attachment[$cur][7] = 0;
</del><ins>+  public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
+    // Append to $attachment array
+    $this-&gt;attachment[] = array(
+      0 =&gt; $string,
+      1 =&gt; $filename,
+      2 =&gt; basename($filename),
+      3 =&gt; $encoding,
+      4 =&gt; $type,
+      5 =&gt; true,  // isStringAttachment
+      6 =&gt; 'attachment',
+      7 =&gt; 0
+    );
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -1493,47 +1780,45 @@
</span><span class="cx">    * @param string $type File extension (MIME) type.
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
</del><ins>+  public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
</ins><span class="cx"> 
</span><del>-    if(!@is_file($path)) {
</del><ins>+    if ( !@is_file($path) ) {
</ins><span class="cx">       $this-&gt;SetError($this-&gt;Lang('file_access') . $path);
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     $filename = basename($path);
</span><del>-    if($name == '') {
</del><ins>+    if ( $name == '' ) {
</ins><span class="cx">       $name = $filename;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    /* Append to $attachment array */
-    $cur = count($this-&gt;attachment);
-    $this-&gt;attachment[$cur][0] = $path;
-    $this-&gt;attachment[$cur][1] = $filename;
-    $this-&gt;attachment[$cur][2] = $name;
-    $this-&gt;attachment[$cur][3] = $encoding;
-    $this-&gt;attachment[$cur][4] = $type;
-    $this-&gt;attachment[$cur][5] = false;
-    $this-&gt;attachment[$cur][6] = 'inline';
-    $this-&gt;attachment[$cur][7] = $cid;
</del><ins>+    // Append to $attachment array
+    $this-&gt;attachment[] = array(
+      0 =&gt; $path,
+      1 =&gt; $filename,
+      2 =&gt; $name,
+      3 =&gt; $encoding,
+      4 =&gt; $type,
+      5 =&gt; false,  // isStringAttachment
+      6 =&gt; 'inline',
+      7 =&gt; $cid
+    );
</ins><span class="cx"> 
</span><span class="cx">     return true;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Returns true if an inline attachment is present.
</span><del>-   * @access private
</del><ins>+   * @access public
</ins><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function InlineImageExists() {
-    $result = false;
-    for($i = 0; $i &lt; count($this-&gt;attachment); $i++) {
-      if($this-&gt;attachment[$i][6] == 'inline') {
-        $result = true;
-        break;
</del><ins>+  public function InlineImageExists() {
+    foreach($this-&gt;attachment as $attachment) {
+      if ($attachment[6] == 'inline') {
+        return true;
</ins><span class="cx">       }
</span><span class="cx">     }
</span><del>-
-    return $result;
</del><ins>+    return false;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /////////////////////////////////////////////////
</span><span class="lines">@@ -1544,7 +1829,10 @@
</span><span class="cx">    * Clears all recipients assigned in the TO array.  Returns void.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function ClearAddresses() {
</del><ins>+  public function ClearAddresses() {
+    foreach($this-&gt;to as $to) {
+      unset($this-&gt;all_recipients[strtolower($to[0])]);
+    }
</ins><span class="cx">     $this-&gt;to = array();
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -1552,7 +1840,10 @@
</span><span class="cx">    * Clears all recipients assigned in the CC array.  Returns void.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function ClearCCs() {
</del><ins>+  public function ClearCCs() {
+    foreach($this-&gt;cc as $cc) {
+      unset($this-&gt;all_recipients[strtolower($cc[0])]);
+    }
</ins><span class="cx">     $this-&gt;cc = array();
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -1560,7 +1851,10 @@
</span><span class="cx">    * Clears all recipients assigned in the BCC array.  Returns void.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function ClearBCCs() {
</del><ins>+  public function ClearBCCs() {
+    foreach($this-&gt;bcc as $bcc) {
+      unset($this-&gt;all_recipients[strtolower($bcc[0])]);
+    }
</ins><span class="cx">     $this-&gt;bcc = array();
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -1568,7 +1862,7 @@
</span><span class="cx">    * Clears all recipients assigned in the ReplyTo array.  Returns void.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function ClearReplyTos() {
</del><ins>+  public function ClearReplyTos() {
</ins><span class="cx">     $this-&gt;ReplyTo = array();
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -1577,10 +1871,11 @@
</span><span class="cx">    * array.  Returns void.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function ClearAllRecipients() {
</del><ins>+  public function ClearAllRecipients() {
</ins><span class="cx">     $this-&gt;to = array();
</span><span class="cx">     $this-&gt;cc = array();
</span><span class="cx">     $this-&gt;bcc = array();
</span><ins>+    $this-&gt;all_recipients = array();
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="lines">@@ -1588,7 +1883,7 @@
</span><span class="cx">    * attachments.  Returns void.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function ClearAttachments() {
</del><ins>+  public function ClearAttachments() {
</ins><span class="cx">     $this-&gt;attachment = array();
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -1596,7 +1891,7 @@
</span><span class="cx">    * Clears all custom headers.  Returns void.
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function ClearCustomHeaders() {
</del><ins>+  public function ClearCustomHeaders() {
</ins><span class="cx">     $this-&gt;CustomHeader = array();
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -1606,21 +1901,27 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Adds the error message to the error container.
</span><del>-   * Returns void.
-   * @access private
</del><ins>+   * @access protected
</ins><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function SetError($msg) {
</del><ins>+  protected function SetError($msg) {
</ins><span class="cx">     $this-&gt;error_count++;
</span><ins>+    if ($this-&gt;Mailer == 'smtp' and !is_null($this-&gt;smtp)) {
+      $lasterror = $this-&gt;smtp-&gt;getError();
+      if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) {
+        $msg .= '&lt;p&gt;' . $this-&gt;Lang('smtp_error') . $lasterror['smtp_msg'] . &quot;&lt;/p&gt;\n&quot;;
+      }
+    }
</ins><span class="cx">     $this-&gt;ErrorInfo = $msg;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Returns the proper RFC 822 formatted date.
</span><del>-   * @access private
</del><ins>+   * @access public
</ins><span class="cx">    * @return string
</span><ins>+   * @static
</ins><span class="cx">    */
</span><del>-  function RFCDate() {
</del><ins>+  public static function RFCDate() {
</ins><span class="cx">     $tz = date('Z');
</span><span class="cx">     $tzs = ($tz &lt; 0) ? '-' : '+';
</span><span class="cx">     $tz = abs($tz);
</span><span class="lines">@@ -1631,40 +1932,15 @@
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Returns the appropriate server variable.  Should work with both
-   * PHP 4.1.0+ as well as older versions.  Returns an empty string
-   * if nothing is found.
-   * @access private
-   * @return mixed
-   */
-  function ServerVar($varName) {
-    global $HTTP_SERVER_VARS;
-    global $HTTP_ENV_VARS;
-
-    if(!isset($_SERVER)) {
-      $_SERVER = $HTTP_SERVER_VARS;
-      if(!isset($_SERVER['REMOTE_ADDR'])) {
-        $_SERVER = $HTTP_ENV_VARS; // must be Apache
-      }
-    }
-
-    if(isset($_SERVER[$varName])) {
-      return $_SERVER[$varName];
-    } else {
-      return '';
-    }
-  }
-
-  /**
</del><span class="cx">    * Returns the server hostname or 'localhost.localdomain' if unknown.
</span><span class="cx">    * @access private
</span><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function ServerHostname() {
-    if ($this-&gt;Hostname != '') {
</del><ins>+  private function ServerHostname() {
+    if (!empty($this-&gt;Hostname)) {
</ins><span class="cx">       $result = $this-&gt;Hostname;
</span><del>-    } elseif ($this-&gt;ServerVar('SERVER_NAME') != '') {
-      $result = $this-&gt;ServerVar('SERVER_NAME');
</del><ins>+    } elseif (isset($_SERVER['SERVER_NAME'])) {
+      $result = $_SERVER['SERVER_NAME'];
</ins><span class="cx">     } else {
</span><span class="cx">       $result = 'localhost.localdomain';
</span><span class="cx">     }
</span><span class="lines">@@ -1677,7 +1953,7 @@
</span><span class="cx">    * @access private
</span><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function Lang($key) {
</del><ins>+  private function Lang($key) {
</ins><span class="cx">     if(count($this-&gt;language) &lt; 1) {
</span><span class="cx">       $this-&gt;SetLanguage('en'); // set the default language
</span><span class="cx">     }
</span><span class="lines">@@ -1691,9 +1967,10 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Returns true if an error occurred.
</span><ins>+   * @access public
</ins><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function IsError() {
</del><ins>+  public function IsError() {
</ins><span class="cx">     return ($this-&gt;error_count &gt; 0);
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -1702,7 +1979,7 @@
</span><span class="cx">    * @access private
</span><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function FixEOL($str) {
</del><ins>+  private function FixEOL($str) {
</ins><span class="cx">     $str = str_replace(&quot;\r\n&quot;, &quot;\n&quot;, $str);
</span><span class="cx">     $str = str_replace(&quot;\r&quot;, &quot;\n&quot;, $str);
</span><span class="cx">     $str = str_replace(&quot;\n&quot;, $this-&gt;LE, $str);
</span><span class="lines">@@ -1711,9 +1988,10 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Adds a custom header.
</span><ins>+   * @access public
</ins><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function AddCustomHeader($custom_header) {
</del><ins>+  public function AddCustomHeader($custom_header) {
</ins><span class="cx">     $this-&gt;CustomHeader[] = explode(':', $custom_header, 2);
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -1722,19 +2000,18 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return $message
</span><span class="cx">    */
</span><del>-  function MsgHTML($message,$basedir='') {
</del><ins>+  public function MsgHTML($message, $basedir = '') {
</ins><span class="cx">     preg_match_all(&quot;/(src|background)=\&quot;(.*)\&quot;/Ui&quot;, $message, $images);
</span><span class="cx">     if(isset($images[2])) {
</span><span class="cx">       foreach($images[2] as $i =&gt; $url) {
</span><span class="cx">         // do not change urls for absolute images (thanks to corvuscorax)
</span><del>-        if (!preg_match('/^[A-z][A-z]*:\/\//',$url)) {
</del><ins>+        if (!preg_match('#^[A-z]+://#',$url)) {
</ins><span class="cx">           $filename = basename($url);
</span><span class="cx">           $directory = dirname($url);
</span><span class="cx">           ($directory == '.')?$directory='':'';
</span><span class="cx">           $cid = 'cid:' . md5($filename);
</span><del>-          $fileParts = split(&quot;\.&quot;, $filename);
-          $ext = $fileParts[1];
-          $mimeType = $this-&gt;_mime_types($ext);
</del><ins>+          $ext = pathinfo($filename, PATHINFO_EXTENSION);
+          $mimeType  = self::_mime_types($ext);
</ins><span class="cx">           if ( strlen($basedir) &gt; 1 &amp;&amp; substr($basedir,-1) != '/') { $basedir .= '/'; }
</span><span class="cx">           if ( strlen($directory) &gt; 1 &amp;&amp; substr($directory,-1) != '/') { $directory .= '/'; }
</span><span class="cx">           if ( $this-&gt;AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) {
</span><span class="lines">@@ -1746,176 +2023,298 @@
</span><span class="cx">     $this-&gt;IsHTML(true);
</span><span class="cx">     $this-&gt;Body = $message;
</span><span class="cx">     $textMsg = trim(strip_tags(preg_replace('/&lt;(head|title|style|script)[^&gt;]*&gt;.*?&lt;\/\\1&gt;/s','',$message)));
</span><del>-    if ( !empty($textMsg) &amp;&amp; empty($this-&gt;AltBody) ) {
</del><ins>+    if (!empty($textMsg) &amp;&amp; empty($this-&gt;AltBody)) {
</ins><span class="cx">       $this-&gt;AltBody = html_entity_decode($textMsg);
</span><span class="cx">     }
</span><del>-    if ( empty($this-&gt;AltBody) ) {
-      $this-&gt;AltBody = 'To view this email message, open the email in with HTML compatibility!' . &quot;\n\n&quot;;
</del><ins>+    if (empty($this-&gt;AltBody)) {
+      $this-&gt;AltBody = 'To view this email message, open it in a program that understands HTML!' . &quot;\n\n&quot;;
</ins><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Gets the mime type of the embedded or inline image
-   * @access private
-   * @return mime type of ext
</del><ins>+   * Gets the MIME type of the embedded or inline image
+   * @param string File extension
+   * @access public
+   * @return string MIME type of ext
+   * @static
</ins><span class="cx">    */
</span><del>-  function _mime_types($ext = '') {
</del><ins>+  public static function _mime_types($ext = '') {
</ins><span class="cx">     $mimes = array(
</span><del>-      'ai'    =&gt;  'application/postscript',
-      'aif'   =&gt;  'audio/x-aiff',
-      'aifc'  =&gt;  'audio/x-aiff',
-      'aiff'  =&gt;  'audio/x-aiff',
-      'avi'   =&gt;  'video/x-msvideo',
</del><ins>+      'hqx'   =&gt;  'application/mac-binhex40',
+      'cpt'   =&gt;  'application/mac-compactpro',
+      'doc'   =&gt;  'application/msword',
</ins><span class="cx">       'bin'   =&gt;  'application/macbinary',
</span><del>-      'bmp'   =&gt;  'image/bmp',
</del><ins>+      'dms'   =&gt;  'application/octet-stream',
+      'lha'   =&gt;  'application/octet-stream',
+      'lzh'   =&gt;  'application/octet-stream',
+      'exe'   =&gt;  'application/octet-stream',
</ins><span class="cx">       'class' =&gt;  'application/octet-stream',
</span><del>-      'cpt'   =&gt;  'application/mac-compactpro',
-      'css'   =&gt;  'text/css',
</del><ins>+      'psd'   =&gt;  'application/octet-stream',
+      'so'    =&gt;  'application/octet-stream',
+      'sea'   =&gt;  'application/octet-stream',
+      'dll'   =&gt;  'application/octet-stream',
+      'oda'   =&gt;  'application/oda',
+      'pdf'   =&gt;  'application/pdf',
+      'ai'    =&gt;  'application/postscript',
+      'eps'   =&gt;  'application/postscript',
+      'ps'    =&gt;  'application/postscript',
+      'smi'   =&gt;  'application/smil',
+      'smil'  =&gt;  'application/smil',
+      'mif'   =&gt;  'application/vnd.mif',
+      'xls'   =&gt;  'application/vnd.ms-excel',
+      'ppt'   =&gt;  'application/vnd.ms-powerpoint',
+      'wbxml' =&gt;  'application/vnd.wap.wbxml',
+      'wmlc'  =&gt;  'application/vnd.wap.wmlc',
</ins><span class="cx">       'dcr'   =&gt;  'application/x-director',
</span><span class="cx">       'dir'   =&gt;  'application/x-director',
</span><del>-      'dll'   =&gt;  'application/octet-stream',
-      'dms'   =&gt;  'application/octet-stream',
-      'doc'   =&gt;  'application/msword',
</del><ins>+      'dxr'   =&gt;  'application/x-director',
</ins><span class="cx">       'dvi'   =&gt;  'application/x-dvi',
</span><del>-      'dxr'   =&gt;  'application/x-director',
-      'eml'   =&gt;  'message/rfc822',
-      'eps'   =&gt;  'application/postscript',
-      'exe'   =&gt;  'application/octet-stream',
-      'gif'   =&gt;  'image/gif',
</del><span class="cx">       'gtar'  =&gt;  'application/x-gtar',
</span><del>-      'htm'   =&gt;  'text/html',
-      'html'  =&gt;  'text/html',
-      'jpe'   =&gt;  'image/jpeg',
-      'jpeg'  =&gt;  'image/jpeg',
-      'jpg'   =&gt;  'image/jpeg',
-      'hqx'   =&gt;  'application/mac-binhex40',
</del><ins>+      'php'   =&gt;  'application/x-httpd-php',
+      'php4'  =&gt;  'application/x-httpd-php',
+      'php3'  =&gt;  'application/x-httpd-php',
+      'phtml' =&gt;  'application/x-httpd-php',
+      'phps'  =&gt;  'application/x-httpd-php-source',
</ins><span class="cx">       'js'    =&gt;  'application/x-javascript',
</span><del>-      'lha'   =&gt;  'application/octet-stream',
-      'log'   =&gt;  'text/plain',
-      'lzh'   =&gt;  'application/octet-stream',
</del><ins>+      'swf'   =&gt;  'application/x-shockwave-flash',
+      'sit'   =&gt;  'application/x-stuffit',
+      'tar'   =&gt;  'application/x-tar',
+      'tgz'   =&gt;  'application/x-tar',
+      'xhtml' =&gt;  'application/xhtml+xml',
+      'xht'   =&gt;  'application/xhtml+xml',
+      'zip'   =&gt;  'application/zip',
</ins><span class="cx">       'mid'   =&gt;  'audio/midi',
</span><span class="cx">       'midi'  =&gt;  'audio/midi',
</span><del>-      'mif'   =&gt;  'application/vnd.mif',
-      'mov'   =&gt;  'video/quicktime',
-      'movie' =&gt;  'video/x-sgi-movie',
</del><ins>+      'mpga'  =&gt;  'audio/mpeg',
</ins><span class="cx">       'mp2'   =&gt;  'audio/mpeg',
</span><span class="cx">       'mp3'   =&gt;  'audio/mpeg',
</span><del>-      'mpe'   =&gt;  'video/mpeg',
-      'mpeg'  =&gt;  'video/mpeg',
-      'mpg'   =&gt;  'video/mpeg',
-      'mpga'  =&gt;  'audio/mpeg',
-      'oda'   =&gt;  'application/oda',
-      'pdf'   =&gt;  'application/pdf',
-      'php'   =&gt;  'application/x-httpd-php',
-      'php3'  =&gt;  'application/x-httpd-php',
-      'php4'  =&gt;  'application/x-httpd-php',
-      'phps'  =&gt;  'application/x-httpd-php-source',
-      'phtml' =&gt;  'application/x-httpd-php',
-      'png'   =&gt;  'image/png',
-      'ppt'   =&gt;  'application/vnd.ms-powerpoint',
-      'ps'    =&gt;  'application/postscript',
-      'psd'   =&gt;  'application/octet-stream',
-      'qt'    =&gt;  'video/quicktime',
-      'ra'    =&gt;  'audio/x-realaudio',
</del><ins>+      'aif'   =&gt;  'audio/x-aiff',
+      'aiff'  =&gt;  'audio/x-aiff',
+      'aifc'  =&gt;  'audio/x-aiff',
</ins><span class="cx">       'ram'   =&gt;  'audio/x-pn-realaudio',
</span><span class="cx">       'rm'    =&gt;  'audio/x-pn-realaudio',
</span><span class="cx">       'rpm'   =&gt;  'audio/x-pn-realaudio-plugin',
</span><del>-      'rtf'   =&gt;  'text/rtf',
-      'rtx'   =&gt;  'text/richtext',
</del><ins>+      'ra'    =&gt;  'audio/x-realaudio',
</ins><span class="cx">       'rv'    =&gt;  'video/vnd.rn-realvideo',
</span><del>-      'sea'   =&gt;  'application/octet-stream',
</del><ins>+      'wav'   =&gt;  'audio/x-wav',
+      'bmp'   =&gt;  'image/bmp',
+      'gif'   =&gt;  'image/gif',
+      'jpeg'  =&gt;  'image/jpeg',
+      'jpg'   =&gt;  'image/jpeg',
+      'jpe'   =&gt;  'image/jpeg',
+      'png'   =&gt;  'image/png',
+      'tiff'  =&gt;  'image/tiff',
+      'tif'   =&gt;  'image/tiff',
+      'css'   =&gt;  'text/css',
+      'html'  =&gt;  'text/html',
+      'htm'   =&gt;  'text/html',
</ins><span class="cx">       'shtml' =&gt;  'text/html',
</span><del>-      'sit'   =&gt;  'application/x-stuffit',
-      'so'    =&gt;  'application/octet-stream',
-      'smi'   =&gt;  'application/smil',
-      'smil'  =&gt;  'application/smil',
-      'swf'   =&gt;  'application/x-shockwave-flash',
-      'tar'   =&gt;  'application/x-tar',
</del><ins>+      'txt'   =&gt;  'text/plain',
</ins><span class="cx">       'text'  =&gt;  'text/plain',
</span><del>-      'txt'   =&gt;  'text/plain',
-      'tgz'   =&gt;  'application/x-tar',
-      'tif'   =&gt;  'image/tiff',
-      'tiff'  =&gt;  'image/tiff',
-      'wav'   =&gt;  'audio/x-wav',
-      'wbxml' =&gt;  'application/vnd.wap.wbxml',
-      'wmlc'  =&gt;  'application/vnd.wap.wmlc',
</del><ins>+      'log'   =&gt;  'text/plain',
+      'rtx'   =&gt;  'text/richtext',
+      'rtf'   =&gt;  'text/rtf',
+      'xml'   =&gt;  'text/xml',
+      'xsl'   =&gt;  'text/xml',
+      'mpeg'  =&gt;  'video/mpeg',
+      'mpg'   =&gt;  'video/mpeg',
+      'mpe'   =&gt;  'video/mpeg',
+      'qt'    =&gt;  'video/quicktime',
+      'mov'   =&gt;  'video/quicktime',
+      'avi'   =&gt;  'video/x-msvideo',
+      'movie' =&gt;  'video/x-sgi-movie',
+      'doc'   =&gt;  'application/msword',
</ins><span class="cx">       'word'  =&gt;  'application/msword',
</span><del>-      'xht'   =&gt;  'application/xhtml+xml',
-      'xhtml' =&gt;  'application/xhtml+xml',
</del><span class="cx">       'xl'    =&gt;  'application/excel',
</span><del>-      'xls'   =&gt;  'application/vnd.ms-excel',
-      'xml'   =&gt;  'text/xml',
-      'xsl'   =&gt;  'text/xml',
-      'zip'   =&gt;  'application/zip'
</del><ins>+      'eml'   =&gt;  'message/rfc822'
</ins><span class="cx">     );
</span><del>-    return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
</del><ins>+    return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Set (or reset) Class Objects (variables)
</del><ins>+  * Set (or reset) Class Objects (variables)
+  *
+  * Usage Example:
+  * $page-&gt;set('X-Priority', '3');
+  *
+  * @access public
+  * @param string $name Parameter Name
+  * @param mixed $value Parameter Value
+  * NOTE: will not work with arrays, there are no arrays to set/reset
+  * @todo Should this not be using __set() magic function?
+  */
+  public function set($name, $value = '') {
+    try {
+      if (isset($this-&gt;$name) ) {
+        $this-&gt;$name = $value;
+      } else {
+        throw new phpmailerException($this-&gt;Lang('variable_set') . $name, self::STOP_CRITICAL);
+      }
+    } catch (Exception $e) {
+      $this-&gt;SetError($e-&gt;getMessage());
+      if ($e-&gt;getCode() == self::STOP_CRITICAL) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Strips newlines to prevent header injection.
+   * @access public
+   * @param string $str String
+   * @return string
+   */
+  public function SecureHeader($str) {
+    $str = str_replace(&quot;\r&quot;, '', $str);
+    $str = str_replace(&quot;\n&quot;, '', $str);
+    return trim($str);
+  }
+
+  /**
+   * Set the private key file and password to sign the message.
</ins><span class="cx">    *
</span><del>-   * Usage Example:
-   * $page-&gt;set('X-Priority', '3');
</del><ins>+   * @access public
+   * @param string $key_filename Parameter File Name
+   * @param string $key_pass Password for private key
+   */
+  public function Sign($cert_filename, $key_filename, $key_pass) {
+    $this-&gt;sign_cert_file = $cert_filename;
+    $this-&gt;sign_key_file = $key_filename;
+    $this-&gt;sign_key_pass = $key_pass;
+  }
+
+  /**
+   * Set the private key file and password to sign the message.
</ins><span class="cx">    *
</span><span class="cx">    * @access public
</span><del>-   * @param string $name Parameter Name
-   * @param mixed $value Parameter Value
-   * NOTE: will not work with arrays, there are no arrays to set/reset
</del><ins>+   * @param string $key_filename Parameter File Name
+   * @param string $key_pass Password for private key
</ins><span class="cx">    */
</span><del>-  function set ( $name, $value = '' ) {
-    if ( isset($this-&gt;$name) ) {
-      $this-&gt;$name = $value;
-    } else {
-      $this-&gt;SetError('Cannot set or reset variable ' . $name);
-      return false;
</del><ins>+  public function DKIM_QP($txt) {
+    $tmp=&quot;&quot;;
+    $line=&quot;&quot;;
+    for ($i=0;$i&lt;strlen($txt);$i++) {
+      $ord=ord($txt[$i]);
+      if ( ((0x21 &lt;= $ord) &amp;&amp; ($ord &lt;= 0x3A)) || $ord == 0x3C || ((0x3E &lt;= $ord) &amp;&amp; ($ord &lt;= 0x7E)) ) {
+        $line.=$txt[$i];
+      } else {
+        $line.=&quot;=&quot;.sprintf(&quot;%02X&quot;,$ord);
+      }
</ins><span class="cx">     }
</span><ins>+    return $line;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Read a file from a supplied filename and return it.
</del><ins>+   * Generate DKIM signature
</ins><span class="cx">    *
</span><span class="cx">    * @access public
</span><del>-   * @param string $filename Parameter File Name
</del><ins>+   * @param string $s Header
</ins><span class="cx">    */
</span><del>-  function getFile($filename) {
-    $return = '';
-    if ($fp = fopen($filename, 'rb')) {
-      while (!feof($fp)) {
-        $return .= fread($fp, 1024);
-      }
-      fclose($fp);
-      return $return;
</del><ins>+  public function DKIM_Sign($s) {
+    $privKeyStr = file_get_contents($this-&gt;DKIM_private);
+    if ($this-&gt;DKIM_passphrase!='') {
+      $privKey = openssl_pkey_get_private($privKeyStr,$this-&gt;DKIM_passphrase);
</ins><span class="cx">     } else {
</span><del>-      return false;
</del><ins>+      $privKey = $privKeyStr;
</ins><span class="cx">     }
</span><ins>+    if (openssl_sign($s, $signature, $privKey)) {
+      return base64_encode($signature);
+    }
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Strips newlines to prevent header injection.
-   * @access private
-   * @param string $str String
-   * @return string
</del><ins>+   * Generate DKIM Canonicalization Header
+   *
+   * @access public
+   * @param string $s Header
</ins><span class="cx">    */
</span><del>-  function SecureHeader($str) {
-    $str = trim($str);
-    $str = str_replace(&quot;\r&quot;, &quot;&quot;, $str);
-    $str = str_replace(&quot;\n&quot;, &quot;&quot;, $str);
-    return $str;
</del><ins>+  public function DKIM_HeaderC($s) {
+    $s=preg_replace(&quot;/\r\n\s+/&quot;,&quot; &quot;,$s);
+    $lines=explode(&quot;\r\n&quot;,$s);
+    foreach ($lines as $key=&gt;$line) {
+      list($heading,$value)=explode(&quot;:&quot;,$line,2);
+      $heading=strtolower($heading);
+      $value=preg_replace(&quot;/\s+/&quot;,&quot; &quot;,$value) ; // Compress useless spaces
+      $lines[$key]=$heading.&quot;:&quot;.trim($value) ; // Don't forget to remove WSP around the value
+    }
+    $s=implode(&quot;\r\n&quot;,$lines);
+    return $s;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Set the private key file and password to sign the message.
</del><ins>+   * Generate DKIM Canonicalization Body
</ins><span class="cx">    *
</span><span class="cx">    * @access public
</span><del>-   * @param string $key_filename Parameter File Name
-   * @param string $key_pass Password for private key
</del><ins>+   * @param string $body Message Body
</ins><span class="cx">    */
</span><del>-  function Sign($cert_filename, $key_filename, $key_pass) {
-    $this-&gt;sign_cert_file = $cert_filename;
-    $this-&gt;sign_key_file = $key_filename;
-    $this-&gt;sign_key_pass = $key_pass;
</del><ins>+  public function DKIM_BodyC($body) {
+    if ($body == '') return &quot;\r\n&quot;;
+    // stabilize line endings
+    $body=str_replace(&quot;\r\n&quot;,&quot;\n&quot;,$body);
+    $body=str_replace(&quot;\n&quot;,&quot;\r\n&quot;,$body);
+    // END stabilize line endings
+    while (substr($body,strlen($body)-4,4) == &quot;\r\n\r\n&quot;) {
+      $body=substr($body,0,strlen($body)-2);
+    }
+    return $body;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><ins>+  /**
+   * Create the DKIM header, body, as new header
+   *
+   * @access public
+   * @param string $headers_line Header lines
+   * @param string $subject Subject
+   * @param string $body Body
+   */
+  public function DKIM_Add($headers_line,$subject,$body) {
+    $DKIMsignatureType    = 'rsa-sha1'; // Signature &amp; hash algorithms
+    $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
+    $DKIMquery            = 'dns/txt'; // Query method
+    $DKIMtime             = time() ; // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
+    $subject_header       = &quot;Subject: $subject&quot;;
+    $headers              = explode(&quot;\r\n&quot;,$headers_line);
+    foreach($headers as $header) {
+      if (strpos($header,'From:') === 0) {
+        $from_header=$header;
+      } elseif (strpos($header,'To:') === 0) {
+        $to_header=$header;
+      }
+    }
+    $from     = str_replace('|','=7C',$this-&gt;DKIM_QP($from_header));
+    $to       = str_replace('|','=7C',$this-&gt;DKIM_QP($to_header));
+    $subject  = str_replace('|','=7C',$this-&gt;DKIM_QP($subject_header)) ; // Copied header fields (dkim-quoted-printable
+    $body     = $this-&gt;DKIM_BodyC($body);
+    $DKIMlen  = strlen($body) ; // Length of body
+    $DKIMb64  = base64_encode(pack(&quot;H*&quot;, sha1($body))) ; // Base64 of packed binary SHA-1 hash of body
+    $ident    = ($this-&gt;DKIM_identity == '')? '' : &quot; i=&quot; . $this-&gt;DKIM_identity . &quot;;&quot;;
+    $dkimhdrs = &quot;DKIM-Signature: v=1; a=&quot; . $DKIMsignatureType . &quot;; q=&quot; . $DKIMquery . &quot;; l=&quot; . $DKIMlen . &quot;; s=&quot; . $this-&gt;DKIM_selector . &quot;;\r\n&quot;.
+                &quot;\tt=&quot; . $DKIMtime . &quot;; c=&quot; . $DKIMcanonicalization . &quot;;\r\n&quot;.
+                &quot;\th=From:To:Subject;\r\n&quot;.
+                &quot;\td=&quot; . $this-&gt;DKIM_domain . &quot;;&quot; . $ident . &quot;\r\n&quot;.
+                &quot;\tz=$from\r\n&quot;.
+                &quot;\t|$to\r\n&quot;.
+                &quot;\t|$subject;\r\n&quot;.
+                &quot;\tbh=&quot; . $DKIMb64 . &quot;;\r\n&quot;.
+                &quot;\tb=&quot;;
+    $toSign   = $this-&gt;DKIM_HeaderC($from_header . &quot;\r\n&quot; . $to_header . &quot;\r\n&quot; . $subject_header . &quot;\r\n&quot; . $dkimhdrs);
+    $signed   = $this-&gt;DKIM_Sign($toSign);
+    return &quot;X-PHPMAILER-DKIM: phpmailer.worxware.com\r\n&quot;.$dkimhdrs.$signed.&quot;\r\n&quot;;
+  }
+
+  protected function doCallback($isSent,$to,$cc,$bcc,$subject,$body) {
+    if (!empty($this-&gt;action_function) &amp;&amp; function_exists($this-&gt;action_function)) {
+      $params = array($isSent,$to,$cc,$bcc,$subject,$body);
+      call_user_func_array($this-&gt;action_function,$params);
+    }
+  }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-?&gt;
</del><ins>+class phpmailerException extends Exception {
+  public function errorMessage() {
+    $errorMsg = '&lt;strong&gt;' . $this-&gt;getMessage() . &quot;&lt;/strong&gt;&lt;br /&gt;\n&quot;;
+    return $errorMsg;
+  }
+}
+?&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkwpincludesclasssmtpphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/class-smtp.php (17675 => 17676)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/class-smtp.php        2011-04-21 20:20:56 UTC (rev 17675)
+++ trunk/wp-includes/class-smtp.php        2011-04-21 20:29:30 UTC (rev 17676)
</span><span class="lines">@@ -2,14 +2,16 @@
</span><span class="cx"> /*~ class.smtp.php
</span><span class="cx"> .---------------------------------------------------------------------------.
</span><span class="cx"> |  Software: PHPMailer - PHP email class                                    |
</span><del>-|   Version: 2.0.4                                                          |
</del><ins>+|   Version: 5.1                                                            |
</ins><span class="cx"> |   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  |
</span><span class="cx"> |      Info: http://phpmailer.sourceforge.net                               |
</span><span class="cx"> |   Support: http://sourceforge.net/projects/phpmailer/                     |
</span><span class="cx"> | ------------------------------------------------------------------------- |
</span><del>-|    Author: Andy Prevost (project admininistrator)                         |
-|    Author: Brent R. Matzelle (original founder)                           |
-| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               |
</del><ins>+|     Admin: Andy Prevost (project admininistrator)                         |
+|   Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
+|          : Marcus Bointon (coolbru) coolbru@users.sourceforge.net         |
+|   Founder: Brent R. Matzelle (original founder)                           |
+| Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved.               |
</ins><span class="cx"> | Copyright (c) 2001-2003, Brent R. Matzelle                                |
</span><span class="cx"> | ------------------------------------------------------------------------- |
</span><span class="cx"> |   License: Distributed under the Lesser General Public License (LGPL)     |
</span><span class="lines">@@ -23,56 +25,66 @@
</span><span class="cx"> | - Technology Consulting                                                   |
</span><span class="cx"> | - Oursourcing (highly qualified programmers and graphic designers)        |
</span><span class="cx"> '---------------------------------------------------------------------------'
</span><ins>+*/
+
+/**
+ * PHPMailer - PHP SMTP email transport class
+ * NOTE: Designed for use with PHP version 5 and up
+ * @package PHPMailer
+ * @author Andy Prevost
+ * @author Marcus Bointon
+ * @copyright 2004 - 2008 Andy Prevost
+ * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
+ * @version $Id: class.smtp.php 444 2009-05-05 11:22:26Z coolbru $
</ins><span class="cx">  */
</span><ins>+
</ins><span class="cx"> /**
</span><span class="cx">  * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
</span><span class="cx">  * commands except TURN which will always return a not implemented
</span><span class="cx">  * error. SMTP also provides some utility methods for sending mail
</span><span class="cx">  * to an SMTP server.
</span><del>- * @package PHPMailer
- * @author Chris Ryan
</del><ins>+ * original author: Chris Ryan
</ins><span class="cx">  */
</span><span class="cx"> 
</span><del>-class SMTP
-{
</del><ins>+class SMTP {
</ins><span class="cx">   /**
</span><span class="cx">    *  SMTP server port
</span><span class="cx">    *  @var int
</span><span class="cx">    */
</span><del>-  var $SMTP_PORT = 25;
</del><ins>+  public $SMTP_PORT = 25;
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    *  SMTP reply line ending
</span><span class="cx">    *  @var string
</span><span class="cx">    */
</span><del>-  var $CRLF = &quot;\r\n&quot;;
</del><ins>+  public $CRLF = &quot;\r\n&quot;;
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    *  Sets whether debugging is turned on
</span><span class="cx">    *  @var bool
</span><span class="cx">    */
</span><del>-  var $do_debug;       # the level of debug to perform
</del><ins>+  public $do_debug;       // the level of debug to perform
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    *  Sets VERP use on/off (default is off)
</span><span class="cx">    *  @var bool
</span><span class="cx">    */
</span><del>-  var $do_verp = false;
</del><ins>+  public $do_verp = false;
</ins><span class="cx"> 
</span><del>-  /**#@+
-   * @access private
-   */
-  var $smtp_conn;      # the socket to the server
-  var $error;          # error if any on the last call
-  var $helo_rply;      # the reply the server sent to us for HELO
-  /**#@-*/
</del><ins>+  /////////////////////////////////////////////////
+  // PROPERTIES, PRIVATE AND PROTECTED
+  /////////////////////////////////////////////////
</ins><span class="cx"> 
</span><ins>+  private $smtp_conn; // the socket to the server
+  private $error;     // error if any on the last call
+  private $helo_rply; // the reply the server sent to us for HELO
+
</ins><span class="cx">   /**
</span><span class="cx">    * Initialize the class so that the data is in a known state.
</span><span class="cx">    * @access public
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function SMTP() {
</del><ins>+  public function __construct() {
</ins><span class="cx">     $this-&gt;smtp_conn = 0;
</span><span class="cx">     $this-&gt;error = null;
</span><span class="cx">     $this-&gt;helo_rply = null;
</span><span class="lines">@@ -80,9 +92,9 @@
</span><span class="cx">     $this-&gt;do_debug = 0;
</span><span class="cx">   }
</span><span class="cx"> 
</span><del>-  /*************************************************************
-   *                    CONNECTION FUNCTIONS                  *
-   ***********************************************************/
</del><ins>+  /////////////////////////////////////////////////
+  // CONNECTION FUNCTIONS
+  /////////////////////////////////////////////////
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Connect to the server specified on the port specified.
</span><span class="lines">@@ -97,15 +109,13 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function Connect($host,$port=0,$tval=30) {
-    # set the error val to null so there is no confusion
</del><ins>+  public function Connect($host, $port = 0, $tval = 30) {
+    // set the error val to null so there is no confusion
</ins><span class="cx">     $this-&gt;error = null;
</span><span class="cx"> 
</span><del>-    # make sure we are __not__ connected
</del><ins>+    // make sure we are __not__ connected
</ins><span class="cx">     if($this-&gt;connected()) {
</span><del>-      # ok we are connected! what should we do?
-      # for now we will just give an error saying we
-      # are already connected
</del><ins>+      // already connected, generate error
</ins><span class="cx">       $this-&gt;error = array(&quot;error&quot; =&gt; &quot;Already connected to a server&quot;);
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="lines">@@ -114,41 +124,80 @@
</span><span class="cx">       $port = $this-&gt;SMTP_PORT;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    #connect to the smtp server
-    $this-&gt;smtp_conn = fsockopen($host,    # the host of the server
-                                 $port,    # the port to use
-                                 $errno,   # error number if any
-                                 $errstr,  # error message if any
-                                 $tval);   # give up after ? secs
-    # verify we connected properly
</del><ins>+    // connect to the smtp server
+    $this-&gt;smtp_conn = @fsockopen($host,    // the host of the server
+                                 $port,    // the port to use
+                                 $errno,   // error number if any
+                                 $errstr,  // error message if any
+                                 $tval);   // give up after ? secs
+    // verify we connected properly
</ins><span class="cx">     if(empty($this-&gt;smtp_conn)) {
</span><span class="cx">       $this-&gt;error = array(&quot;error&quot; =&gt; &quot;Failed to connect to server&quot;,
</span><span class="cx">                            &quot;errno&quot; =&gt; $errno,
</span><span class="cx">                            &quot;errstr&quot; =&gt; $errstr);
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: $errstr ($errno)&quot; . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: $errstr ($errno)&quot; . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    # sometimes the SMTP server takes a little longer to respond
-    # so we will give it a longer timeout for the first read
-    // Windows still does not have support for this timeout function
</del><ins>+    // SMTP server can take longer to respond, give longer timeout for first read
+    // Windows does not have support for this timeout function
</ins><span class="cx">     if(substr(PHP_OS, 0, 3) != &quot;WIN&quot;)
</span><span class="cx">      socket_set_timeout($this-&gt;smtp_conn, $tval, 0);
</span><span class="cx"> 
</span><del>-    # get any announcement stuff
</del><ins>+    // get any announcement
</ins><span class="cx">     $announce = $this-&gt;get_lines();
</span><span class="cx"> 
</span><del>-    # set the timeout  of any socket functions at 1/10 of a second
-    //if(function_exists(&quot;socket_set_timeout&quot;))
-    //   socket_set_timeout($this-&gt;smtp_conn, 0, 100000);
</del><ins>+    if($this-&gt;do_debug &gt;= 2) {
+      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $announce . $this-&gt;CRLF . '&lt;br /&gt;';
+    }
</ins><span class="cx"> 
</span><ins>+    return true;
+  }
+
+  /**
+   * Initiate a TLS communication with the server.
+   *
+   * SMTP CODE 220 Ready to start TLS
+   * SMTP CODE 501 Syntax error (no parameters allowed)
+   * SMTP CODE 454 TLS not available due to temporary reason
+   * @access public
+   * @return bool success
+   */
+  public function StartTLS() {
+    $this-&gt;error = null; # to avoid confusion
+
+    if(!$this-&gt;connected()) {
+      $this-&gt;error = array(&quot;error&quot; =&gt; &quot;Called StartTLS() without being connected&quot;);
+      return false;
+    }
+
+    fputs($this-&gt;smtp_conn,&quot;STARTTLS&quot; . $this-&gt;CRLF);
+
+    $rply = $this-&gt;get_lines();
+    $code = substr($rply,0,3);
+
</ins><span class="cx">     if($this-&gt;do_debug &gt;= 2) {
</span><del>-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $announce;
</del><ins>+      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if($code != 220) {
+      $this-&gt;error =
+         array(&quot;error&quot;     =&gt; &quot;STARTTLS not accepted from server&quot;,
+               &quot;smtp_code&quot; =&gt; $code,
+               &quot;smtp_msg&quot;  =&gt; substr($rply,4));
+      if($this-&gt;do_debug &gt;= 1) {
+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
+      }
+      return false;
+    }
+
+    // Begin encrypted connection
+    if(!stream_socket_enable_crypto($this-&gt;smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
+      return false;
+    }
+
</ins><span class="cx">     return true;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="lines">@@ -158,7 +207,7 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function Authenticate($username, $password) {
</del><ins>+  public function Authenticate($username, $password) {
</ins><span class="cx">     // Start authentication
</span><span class="cx">     fputs($this-&gt;smtp_conn,&quot;AUTH LOGIN&quot; . $this-&gt;CRLF);
</span><span class="cx"> 
</span><span class="lines">@@ -171,8 +220,7 @@
</span><span class="cx">               &quot;smtp_code&quot; =&gt; $code,
</span><span class="cx">               &quot;smtp_msg&quot; =&gt; substr($rply,4));
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="lines">@@ -189,8 +237,7 @@
</span><span class="cx">               &quot;smtp_code&quot; =&gt; $code,
</span><span class="cx">               &quot;smtp_msg&quot; =&gt; substr($rply,4));
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="lines">@@ -207,8 +254,7 @@
</span><span class="cx">               &quot;smtp_code&quot; =&gt; $code,
</span><span class="cx">               &quot;smtp_msg&quot; =&gt; substr($rply,4));
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="lines">@@ -218,23 +264,21 @@
</span><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Returns true if connected to a server otherwise false
</span><del>-   * @access private
</del><ins>+   * @access public
</ins><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function Connected() {
</del><ins>+  public function Connected() {
</ins><span class="cx">     if(!empty($this-&gt;smtp_conn)) {
</span><span class="cx">       $sock_status = socket_get_status($this-&gt;smtp_conn);
</span><span class="cx">       if($sock_status[&quot;eof&quot;]) {
</span><del>-        # hmm this is an odd situation... the socket is
-        # valid but we are not connected anymore
</del><ins>+        // the socket is valid but we are not connected
</ins><span class="cx">         if($this-&gt;do_debug &gt;= 1) {
</span><del>-            echo &quot;SMTP -&gt; NOTICE:&quot; . $this-&gt;CRLF .
-                 &quot;EOF caught while checking if connected&quot;;
</del><ins>+            echo &quot;SMTP -&gt; NOTICE:&quot; . $this-&gt;CRLF . &quot;EOF caught while checking if connected&quot;;
</ins><span class="cx">         }
</span><span class="cx">         $this-&gt;Close();
</span><span class="cx">         return false;
</span><span class="cx">       }
</span><del>-      return true; # everything looks good
</del><ins>+      return true; // everything looks good
</ins><span class="cx">     }
</span><span class="cx">     return false;
</span><span class="cx">   }
</span><span class="lines">@@ -246,26 +290,26 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return void
</span><span class="cx">    */
</span><del>-  function Close() {
-    $this-&gt;error = null; # so there is no confusion
</del><ins>+  public function Close() {
+    $this-&gt;error = null; // so there is no confusion
</ins><span class="cx">     $this-&gt;helo_rply = null;
</span><span class="cx">     if(!empty($this-&gt;smtp_conn)) {
</span><del>-      # close the connection and cleanup
</del><ins>+      // close the connection and cleanup
</ins><span class="cx">       fclose($this-&gt;smtp_conn);
</span><span class="cx">       $this-&gt;smtp_conn = 0;
</span><span class="cx">     }
</span><span class="cx">   }
</span><span class="cx"> 
</span><del>-  /***************************************************************
-   *                        SMTP COMMANDS                       *
-   *************************************************************/
</del><ins>+  /////////////////////////////////////////////////
+  // SMTP COMMANDS
+  /////////////////////////////////////////////////
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Issues a data command and sends the msg_data to the server
</span><span class="cx">    * finializing the mail transaction. $msg_data is the message
</span><span class="cx">    * that is to be send with the headers. Each header needs to be
</span><span class="cx">    * on a single line followed by a &lt;CRLF&gt; with the message headers
</span><del>-   * and the message body being separated by and additional &lt;CRLF&gt;.
</del><ins>+   * and the message body being seperated by and additional &lt;CRLF&gt;.
</ins><span class="cx">    *
</span><span class="cx">    * Implements rfc 821: DATA &lt;CRLF&gt;
</span><span class="cx">    *
</span><span class="lines">@@ -279,8 +323,8 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function Data($msg_data) {
-    $this-&gt;error = null; # so no confusion is caused
</del><ins>+  public function Data($msg_data) {
+    $this-&gt;error = null; // so no confusion is caused
</ins><span class="cx"> 
</span><span class="cx">     if(!$this-&gt;connected()) {
</span><span class="cx">       $this-&gt;error = array(
</span><span class="lines">@@ -294,7 +338,7 @@
</span><span class="cx">     $code = substr($rply,0,3);
</span><span class="cx"> 
</span><span class="cx">     if($this-&gt;do_debug &gt;= 2) {
</span><del>-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
</del><ins>+      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if($code != 354) {
</span><span class="lines">@@ -303,69 +347,73 @@
</span><span class="cx">               &quot;smtp_code&quot; =&gt; $code,
</span><span class="cx">               &quot;smtp_msg&quot; =&gt; substr($rply,4));
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    # the server is ready to accept data!
-    # according to rfc 821 we should not send more than 1000
-    # including the CRLF
-    # characters on a single line so we will break the data up
-    # into lines by \r and/or \n then if needed we will break
-    # each of those into smaller lines to fit within the limit.
-    # in addition we will be looking for lines that start with
-    # a period '.' and append and additional period '.' to that
-    # line. NOTE: this does not count towards are limit.
</del><ins>+    /* the server is ready to accept data!
+     * according to rfc 821 we should not send more than 1000
+     * including the CRLF
+     * characters on a single line so we will break the data up
+     * into lines by \r and/or \n then if needed we will break
+     * each of those into smaller lines to fit within the limit.
+     * in addition we will be looking for lines that start with
+     * a period '.' and append and additional period '.' to that
+     * line. NOTE: this does not count towards limit.
+     */
</ins><span class="cx"> 
</span><del>-    # normalize the line breaks so we know the explode works
</del><ins>+    // normalize the line breaks so we know the explode works
</ins><span class="cx">     $msg_data = str_replace(&quot;\r\n&quot;,&quot;\n&quot;,$msg_data);
</span><span class="cx">     $msg_data = str_replace(&quot;\r&quot;,&quot;\n&quot;,$msg_data);
</span><span class="cx">     $lines = explode(&quot;\n&quot;,$msg_data);
</span><span class="cx"> 
</span><del>-    # we need to find a good way to determine is headers are
-    # in the msg_data or if it is a straight msg body
-    # currently I am assuming rfc 822 definitions of msg headers
-    # and if the first field of the first line (':' sperated)
-    # does not contain a space then it _should_ be a header
-    # and we can process all lines before a blank &quot;&quot; line as
-    # headers.
</del><ins>+    /* we need to find a good way to determine is headers are
+     * in the msg_data or if it is a straight msg body
+     * currently I am assuming rfc 822 definitions of msg headers
+     * and if the first field of the first line (':' sperated)
+     * does not contain a space then it _should_ be a header
+     * and we can process all lines before a blank &quot;&quot; line as
+     * headers.
+     */
+
</ins><span class="cx">     $field = substr($lines[0],0,strpos($lines[0],&quot;:&quot;));
</span><span class="cx">     $in_headers = false;
</span><span class="cx">     if(!empty($field) &amp;&amp; !strstr($field,&quot; &quot;)) {
</span><span class="cx">       $in_headers = true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    $max_line_length = 998; # used below; set here for ease in change
</del><ins>+    $max_line_length = 998; // used below; set here for ease in change
</ins><span class="cx"> 
</span><span class="cx">     while(list(,$line) = @each($lines)) {
</span><span class="cx">       $lines_out = null;
</span><span class="cx">       if($line == &quot;&quot; &amp;&amp; $in_headers) {
</span><span class="cx">         $in_headers = false;
</span><span class="cx">       }
</span><del>-      # ok we need to break this line up into several
-      # smaller lines
</del><ins>+      // ok we need to break this line up into several smaller lines
</ins><span class="cx">       while(strlen($line) &gt; $max_line_length) {
</span><span class="cx">         $pos = strrpos(substr($line,0,$max_line_length),&quot; &quot;);
</span><span class="cx"> 
</span><del>-        # Patch to fix DOS attack
</del><ins>+        // Patch to fix DOS attack
</ins><span class="cx">         if(!$pos) {
</span><span class="cx">           $pos = $max_line_length - 1;
</span><ins>+          $lines_out[] = substr($line,0,$pos);
+          $line = substr($line,$pos);
+        } else {
+          $lines_out[] = substr($line,0,$pos);
+          $line = substr($line,$pos + 1);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        $lines_out[] = substr($line,0,$pos);
-        $line = substr($line,$pos + 1);
-        # if we are processing headers we need to
-        # add a LWSP-char to the front of the new line
-        # rfc 822 on long msg headers
</del><ins>+        /* if processing headers add a LWSP-char to the front of new line
+         * rfc 822 on long msg headers
+         */
</ins><span class="cx">         if($in_headers) {
</span><span class="cx">           $line = &quot;\t&quot; . $line;
</span><span class="cx">         }
</span><span class="cx">       }
</span><span class="cx">       $lines_out[] = $line;
</span><span class="cx"> 
</span><del>-      # now send the lines to the server
</del><ins>+      // send the lines to the server
</ins><span class="cx">       while(list(,$line_out) = @each($lines_out)) {
</span><span class="cx">         if(strlen($line_out) &gt; 0)
</span><span class="cx">         {
</span><span class="lines">@@ -377,15 +425,14 @@
</span><span class="cx">       }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    # ok all the message data has been sent so lets get this
-    # over with aleady
</del><ins>+    // message data has been sent
</ins><span class="cx">     fputs($this-&gt;smtp_conn, $this-&gt;CRLF . &quot;.&quot; . $this-&gt;CRLF);
</span><span class="cx"> 
</span><span class="cx">     $rply = $this-&gt;get_lines();
</span><span class="cx">     $code = substr($rply,0,3);
</span><span class="cx"> 
</span><span class="cx">     if($this-&gt;do_debug &gt;= 2) {
</span><del>-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
</del><ins>+      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if($code != 250) {
</span><span class="lines">@@ -394,8 +441,7 @@
</span><span class="cx">               &quot;smtp_code&quot; =&gt; $code,
</span><span class="cx">               &quot;smtp_msg&quot; =&gt; substr($rply,4));
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="lines">@@ -403,61 +449,6 @@
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Expand takes the name and asks the server to list all the
-   * people who are members of the _list_. Expand will return
-   * back and array of the result or false if an error occurs.
-   * Each value in the array returned has the format of:
-   *     [ &lt;full-name&gt; &lt;sp&gt; ] &lt;path&gt;
-   * The definition of &lt;path&gt; is defined in rfc 821
-   *
-   * Implements rfc 821: EXPN &lt;SP&gt; &lt;string&gt; &lt;CRLF&gt;
-   *
-   * SMTP CODE SUCCESS: 250
-   * SMTP CODE FAILURE: 550
-   * SMTP CODE ERROR  : 500,501,502,504,421
-   * @access public
-   * @return string array
-   */
-  function Expand($name) {
-    $this-&gt;error = null; # so no confusion is caused
-
-    if(!$this-&gt;connected()) {
-      $this-&gt;error = array(
-            &quot;error&quot; =&gt; &quot;Called Expand() without being connected&quot;);
-      return false;
-    }
-
-    fputs($this-&gt;smtp_conn,&quot;EXPN &quot; . $name . $this-&gt;CRLF);
-
-    $rply = $this-&gt;get_lines();
-    $code = substr($rply,0,3);
-
-    if($this-&gt;do_debug &gt;= 2) {
-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
-    }
-
-    if($code != 250) {
-      $this-&gt;error =
-        array(&quot;error&quot; =&gt; &quot;EXPN not accepted from server&quot;,
-              &quot;smtp_code&quot; =&gt; $code,
-              &quot;smtp_msg&quot; =&gt; substr($rply,4));
-      if($this-&gt;do_debug &gt;= 1) {
-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
-      }
-      return false;
-    }
-
-    # parse the reply and place in our array to return to user
-    $entries = explode($this-&gt;CRLF,$rply);
-    while(list(,$l) = @each($entries)) {
-      $list[] = substr($l,4);
-    }
-
-    return $list;
-  }
-
-  /**
</del><span class="cx">    * Sends the HELO command to the smtp server.
</span><span class="cx">    * This makes sure that we and the server are in
</span><span class="cx">    * the same known state.
</span><span class="lines">@@ -469,8 +460,8 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function Hello($host=&quot;&quot;) {
-    $this-&gt;error = null; # so no confusion is caused
</del><ins>+  public function Hello($host = '') {
+    $this-&gt;error = null; // so no confusion is caused
</ins><span class="cx"> 
</span><span class="cx">     if(!$this-&gt;connected()) {
</span><span class="cx">       $this-&gt;error = array(
</span><span class="lines">@@ -478,19 +469,17 @@
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    # if a hostname for the HELO was not specified determine
-    # a suitable one to send
</del><ins>+    // if hostname for HELO was not specified send default
</ins><span class="cx">     if(empty($host)) {
</span><del>-      # we need to determine some sort of appopiate default
-      # to send to the server
</del><ins>+      // determine appropriate default to send to server
</ins><span class="cx">       $host = &quot;localhost&quot;;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Send extended hello first (RFC 2821)
</span><del>-    if(!$this-&gt;SendHello(&quot;EHLO&quot;, $host))
-    {
-      if(!$this-&gt;SendHello(&quot;HELO&quot;, $host))
-          return false;
</del><ins>+    if(!$this-&gt;SendHello(&quot;EHLO&quot;, $host)) {
+      if(!$this-&gt;SendHello(&quot;HELO&quot;, $host)) {
+        return false;
+      }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return true;
</span><span class="lines">@@ -501,14 +490,14 @@
</span><span class="cx">    * @access private
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function SendHello($hello, $host) {
</del><ins>+  private function SendHello($hello, $host) {
</ins><span class="cx">     fputs($this-&gt;smtp_conn, $hello . &quot; &quot; . $host . $this-&gt;CRLF);
</span><span class="cx"> 
</span><span class="cx">     $rply = $this-&gt;get_lines();
</span><span class="cx">     $code = substr($rply,0,3);
</span><span class="cx"> 
</span><span class="cx">     if($this-&gt;do_debug &gt;= 2) {
</span><del>-      echo &quot;SMTP -&gt; FROM SERVER: &quot; . $this-&gt;CRLF . $rply;
</del><ins>+      echo &quot;SMTP -&gt; FROM SERVER: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if($code != 250) {
</span><span class="lines">@@ -517,8 +506,7 @@
</span><span class="cx">               &quot;smtp_code&quot; =&gt; $code,
</span><span class="cx">               &quot;smtp_msg&quot; =&gt; substr($rply,4));
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="lines">@@ -529,59 +517,6 @@
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Gets help information on the keyword specified. If the keyword
-   * is not specified then returns generic help, ussually contianing
-   * A list of keywords that help is available on. This function
-   * returns the results back to the user. It is up to the user to
-   * handle the returned data. If an error occurs then false is
-   * returned with $this-&gt;error set appropiately.
-   *
-   * Implements rfc 821: HELP [ &lt;SP&gt; &lt;string&gt; ] &lt;CRLF&gt;
-   *
-   * SMTP CODE SUCCESS: 211,214
-   * SMTP CODE ERROR  : 500,501,502,504,421
-   * @access public
-   * @return string
-   */
-  function Help($keyword=&quot;&quot;) {
-    $this-&gt;error = null; # to avoid confusion
-
-    if(!$this-&gt;connected()) {
-      $this-&gt;error = array(
-              &quot;error&quot; =&gt; &quot;Called Help() without being connected&quot;);
-      return false;
-    }
-
-    $extra = &quot;&quot;;
-    if(!empty($keyword)) {
-      $extra = &quot; &quot; . $keyword;
-    }
-
-    fputs($this-&gt;smtp_conn,&quot;HELP&quot; . $extra . $this-&gt;CRLF);
-
-    $rply = $this-&gt;get_lines();
-    $code = substr($rply,0,3);
-
-    if($this-&gt;do_debug &gt;= 2) {
-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
-    }
-
-    if($code != 211 &amp;&amp; $code != 214) {
-      $this-&gt;error =
-        array(&quot;error&quot; =&gt; &quot;HELP not accepted from server&quot;,
-              &quot;smtp_code&quot; =&gt; $code,
-              &quot;smtp_msg&quot; =&gt; substr($rply,4));
-      if($this-&gt;do_debug &gt;= 1) {
-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
-      }
-      return false;
-    }
-
-    return $rply;
-  }
-
-  /**
</del><span class="cx">    * Starts a mail transaction from the email address specified in
</span><span class="cx">    * $from. Returns true if successful or false otherwise. If True
</span><span class="cx">    * the mail transaction is started and then one or more Recipient
</span><span class="lines">@@ -595,8 +530,8 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function Mail($from) {
-    $this-&gt;error = null; # so no confusion is caused
</del><ins>+  public function Mail($from) {
+    $this-&gt;error = null; // so no confusion is caused
</ins><span class="cx"> 
</span><span class="cx">     if(!$this-&gt;connected()) {
</span><span class="cx">       $this-&gt;error = array(
</span><span class="lines">@@ -611,7 +546,7 @@
</span><span class="cx">     $code = substr($rply,0,3);
</span><span class="cx"> 
</span><span class="cx">     if($this-&gt;do_debug &gt;= 2) {
</span><del>-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
</del><ins>+      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if($code != 250) {
</span><span class="lines">@@ -620,8 +555,7 @@
</span><span class="cx">               &quot;smtp_code&quot; =&gt; $code,
</span><span class="cx">               &quot;smtp_msg&quot; =&gt; substr($rply,4));
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="lines">@@ -629,48 +563,6 @@
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Sends the command NOOP to the SMTP server.
-   *
-   * Implements from rfc 821: NOOP &lt;CRLF&gt;
-   *
-   * SMTP CODE SUCCESS: 250
-   * SMTP CODE ERROR  : 500, 421
-   * @access public
-   * @return bool
-   */
-  function Noop() {
-    $this-&gt;error = null; # so no confusion is caused
-
-    if(!$this-&gt;connected()) {
-      $this-&gt;error = array(
-              &quot;error&quot; =&gt; &quot;Called Noop() without being connected&quot;);
-      return false;
-    }
-
-    fputs($this-&gt;smtp_conn,&quot;NOOP&quot; . $this-&gt;CRLF);
-
-    $rply = $this-&gt;get_lines();
-    $code = substr($rply,0,3);
-
-    if($this-&gt;do_debug &gt;= 2) {
-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
-    }
-
-    if($code != 250) {
-      $this-&gt;error =
-        array(&quot;error&quot; =&gt; &quot;NOOP not accepted from server&quot;,
-              &quot;smtp_code&quot; =&gt; $code,
-              &quot;smtp_msg&quot; =&gt; substr($rply,4));
-      if($this-&gt;do_debug &gt;= 1) {
-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
-      }
-      return false;
-    }
-    return true;
-  }
-
-  /**
</del><span class="cx">    * Sends the quit command to the server and then closes the socket
</span><span class="cx">    * if there is no error or the $close_on_error argument is true.
</span><span class="cx">    *
</span><span class="lines">@@ -681,8 +573,8 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function Quit($close_on_error=true) {
-    $this-&gt;error = null; # so there is no confusion
</del><ins>+  public function Quit($close_on_error = true) {
+    $this-&gt;error = null; // so there is no confusion
</ins><span class="cx"> 
</span><span class="cx">     if(!$this-&gt;connected()) {
</span><span class="cx">       $this-&gt;error = array(
</span><span class="lines">@@ -690,14 +582,14 @@
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    # send the quit command to the server
</del><ins>+    // send the quit command to the server
</ins><span class="cx">     fputs($this-&gt;smtp_conn,&quot;quit&quot; . $this-&gt;CRLF);
</span><span class="cx"> 
</span><del>-    # get any good-bye messages
</del><ins>+    // get any good-bye messages
</ins><span class="cx">     $byemsg = $this-&gt;get_lines();
</span><span class="cx"> 
</span><span class="cx">     if($this-&gt;do_debug &gt;= 2) {
</span><del>-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $byemsg;
</del><ins>+      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $byemsg . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     $rval = true;
</span><span class="lines">@@ -705,14 +597,13 @@
</span><span class="cx"> 
</span><span class="cx">     $code = substr($byemsg,0,3);
</span><span class="cx">     if($code != 221) {
</span><del>-      # use e as a tmp var cause Close will overwrite $this-&gt;error
</del><ins>+      // use e as a tmp var cause Close will overwrite $this-&gt;error
</ins><span class="cx">       $e = array(&quot;error&quot; =&gt; &quot;SMTP server rejected quit command&quot;,
</span><span class="cx">                  &quot;smtp_code&quot; =&gt; $code,
</span><span class="cx">                  &quot;smtp_rply&quot; =&gt; substr($byemsg,4));
</span><span class="cx">       $rval = false;
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $e[&quot;error&quot;] . &quot;: &quot; .
-                 $byemsg . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $e[&quot;error&quot;] . &quot;: &quot; . $byemsg . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -735,8 +626,8 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function Recipient($to) {
-    $this-&gt;error = null; # so no confusion is caused
</del><ins>+  public function Recipient($to) {
+    $this-&gt;error = null; // so no confusion is caused
</ins><span class="cx"> 
</span><span class="cx">     if(!$this-&gt;connected()) {
</span><span class="cx">       $this-&gt;error = array(
</span><span class="lines">@@ -750,7 +641,7 @@
</span><span class="cx">     $code = substr($rply,0,3);
</span><span class="cx"> 
</span><span class="cx">     if($this-&gt;do_debug &gt;= 2) {
</span><del>-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
</del><ins>+      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if($code != 250 &amp;&amp; $code != 251) {
</span><span class="lines">@@ -759,8 +650,7 @@
</span><span class="cx">               &quot;smtp_code&quot; =&gt; $code,
</span><span class="cx">               &quot;smtp_msg&quot; =&gt; substr($rply,4));
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="lines">@@ -779,8 +669,8 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function Reset() {
-    $this-&gt;error = null; # so no confusion is caused
</del><ins>+  public function Reset() {
+    $this-&gt;error = null; // so no confusion is caused
</ins><span class="cx"> 
</span><span class="cx">     if(!$this-&gt;connected()) {
</span><span class="cx">       $this-&gt;error = array(
</span><span class="lines">@@ -794,7 +684,7 @@
</span><span class="cx">     $code = substr($rply,0,3);
</span><span class="cx"> 
</span><span class="cx">     if($this-&gt;do_debug &gt;= 2) {
</span><del>-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
</del><ins>+      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if($code != 250) {
</span><span class="lines">@@ -803,8 +693,7 @@
</span><span class="cx">               &quot;smtp_code&quot; =&gt; $code,
</span><span class="cx">               &quot;smtp_msg&quot; =&gt; substr($rply,4));
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="lines">@@ -818,54 +707,6 @@
</span><span class="cx">    * the mail transaction is started and then one or more Recipient
</span><span class="cx">    * commands may be called followed by a Data command. This command
</span><span class="cx">    * will send the message to the users terminal if they are logged
</span><del>-   * in.
-   *
-   * Implements rfc 821: SEND &lt;SP&gt; FROM:&lt;reverse-path&gt; &lt;CRLF&gt;
-   *
-   * SMTP CODE SUCCESS: 250
-   * SMTP CODE SUCCESS: 552,451,452
-   * SMTP CODE SUCCESS: 500,501,502,421
-   * @access public
-   * @return bool
-   */
-  function Send($from) {
-    $this-&gt;error = null; # so no confusion is caused
-
-    if(!$this-&gt;connected()) {
-      $this-&gt;error = array(
-              &quot;error&quot; =&gt; &quot;Called Send() without being connected&quot;);
-      return false;
-    }
-
-    fputs($this-&gt;smtp_conn,&quot;SEND FROM:&quot; . $from . $this-&gt;CRLF);
-
-    $rply = $this-&gt;get_lines();
-    $code = substr($rply,0,3);
-
-    if($this-&gt;do_debug &gt;= 2) {
-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
-    }
-
-    if($code != 250) {
-      $this-&gt;error =
-        array(&quot;error&quot; =&gt; &quot;SEND not accepted from server&quot;,
-              &quot;smtp_code&quot; =&gt; $code,
-              &quot;smtp_msg&quot; =&gt; substr($rply,4));
-      if($this-&gt;do_debug &gt;= 1) {
-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
-      }
-      return false;
-    }
-    return true;
-  }
-
-  /**
-   * Starts a mail transaction from the email address specified in
-   * $from. Returns true if successful or false otherwise. If True
-   * the mail transaction is started and then one or more Recipient
-   * commands may be called followed by a Data command. This command
-   * will send the message to the users terminal if they are logged
</del><span class="cx">    * in and send them an email.
</span><span class="cx">    *
</span><span class="cx">    * Implements rfc 821: SAML &lt;SP&gt; FROM:&lt;reverse-path&gt; &lt;CRLF&gt;
</span><span class="lines">@@ -876,8 +717,8 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function SendAndMail($from) {
-    $this-&gt;error = null; # so no confusion is caused
</del><ins>+  public function SendAndMail($from) {
+    $this-&gt;error = null; // so no confusion is caused
</ins><span class="cx"> 
</span><span class="cx">     if(!$this-&gt;connected()) {
</span><span class="cx">       $this-&gt;error = array(
</span><span class="lines">@@ -891,7 +732,7 @@
</span><span class="cx">     $code = substr($rply,0,3);
</span><span class="cx"> 
</span><span class="cx">     if($this-&gt;do_debug &gt;= 2) {
</span><del>-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
</del><ins>+      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if($code != 250) {
</span><span class="lines">@@ -900,8 +741,7 @@
</span><span class="cx">               &quot;smtp_code&quot; =&gt; $code,
</span><span class="cx">               &quot;smtp_msg&quot; =&gt; substr($rply,4));
</span><span class="cx">       if($this-&gt;do_debug &gt;= 1) {
</span><del>-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] . &quot;: &quot; . $rply . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       return false;
</span><span class="cx">     }
</span><span class="lines">@@ -909,54 +749,6 @@
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Starts a mail transaction from the email address specified in
-   * $from. Returns true if successful or false otherwise. If True
-   * the mail transaction is started and then one or more Recipient
-   * commands may be called followed by a Data command. This command
-   * will send the message to the users terminal if they are logged
-   * in or mail it to them if they are not.
-   *
-   * Implements rfc 821: SOML &lt;SP&gt; FROM:&lt;reverse-path&gt; &lt;CRLF&gt;
-   *
-   * SMTP CODE SUCCESS: 250
-   * SMTP CODE SUCCESS: 552,451,452
-   * SMTP CODE SUCCESS: 500,501,502,421
-   * @access public
-   * @return bool
-   */
-  function SendOrMail($from) {
-    $this-&gt;error = null; # so no confusion is caused
-
-    if(!$this-&gt;connected()) {
-      $this-&gt;error = array(
-          &quot;error&quot; =&gt; &quot;Called SendOrMail() without being connected&quot;);
-      return false;
-    }
-
-    fputs($this-&gt;smtp_conn,&quot;SOML FROM:&quot; . $from . $this-&gt;CRLF);
-
-    $rply = $this-&gt;get_lines();
-    $code = substr($rply,0,3);
-
-    if($this-&gt;do_debug &gt;= 2) {
-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
-    }
-
-    if($code != 250) {
-      $this-&gt;error =
-        array(&quot;error&quot; =&gt; &quot;SOML not accepted from server&quot;,
-              &quot;smtp_code&quot; =&gt; $code,
-              &quot;smtp_msg&quot; =&gt; substr($rply,4));
-      if($this-&gt;do_debug &gt;= 1) {
-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
-      }
-      return false;
-    }
-    return true;
-  }
-
-  /**
</del><span class="cx">    * This is an optional command for SMTP that this class does not
</span><span class="cx">    * support. This method is here to make the RFC821 Definition
</span><span class="cx">    * complete for this class and __may__ be implimented in the future
</span><span class="lines">@@ -969,63 +761,27 @@
</span><span class="cx">    * @access public
</span><span class="cx">    * @return bool
</span><span class="cx">    */
</span><del>-  function Turn() {
</del><ins>+  public function Turn() {
</ins><span class="cx">     $this-&gt;error = array(&quot;error&quot; =&gt; &quot;This method, TURN, of the SMTP &quot;.
</span><span class="cx">                                     &quot;is not implemented&quot;);
</span><span class="cx">     if($this-&gt;do_debug &gt;= 1) {
</span><del>-      echo &quot;SMTP -&gt; NOTICE: &quot; . $this-&gt;error[&quot;error&quot;] . $this-&gt;CRLF;
</del><ins>+      echo &quot;SMTP -&gt; NOTICE: &quot; . $this-&gt;error[&quot;error&quot;] . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">     }
</span><span class="cx">     return false;
</span><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">   /**
</span><del>-   * Verifies that the name is recognized by the server.
-   * Returns false if the name could not be verified otherwise
-   * the response from the server is returned.
-   *
-   * Implements rfc 821: VRFY &lt;SP&gt; &lt;string&gt; &lt;CRLF&gt;
-   *
-   * SMTP CODE SUCCESS: 250,251
-   * SMTP CODE FAILURE: 550,551,553
-   * SMTP CODE ERROR  : 500,501,502,421
-   * @access public
-   * @return int
-   */
-  function Verify($name) {
-    $this-&gt;error = null; # so no confusion is caused
-
-    if(!$this-&gt;connected()) {
-      $this-&gt;error = array(
-              &quot;error&quot; =&gt; &quot;Called Verify() without being connected&quot;);
-      return false;
-    }
-
-    fputs($this-&gt;smtp_conn,&quot;VRFY &quot; . $name . $this-&gt;CRLF);
-
-    $rply = $this-&gt;get_lines();
-    $code = substr($rply,0,3);
-
-    if($this-&gt;do_debug &gt;= 2) {
-      echo &quot;SMTP -&gt; FROM SERVER:&quot; . $this-&gt;CRLF . $rply;
-    }
-
-    if($code != 250 &amp;&amp; $code != 251) {
-      $this-&gt;error =
-        array(&quot;error&quot; =&gt; &quot;VRFY failed on name '$name'&quot;,
-              &quot;smtp_code&quot; =&gt; $code,
-              &quot;smtp_msg&quot; =&gt; substr($rply,4));
-      if($this-&gt;do_debug &gt;= 1) {
-        echo &quot;SMTP -&gt; ERROR: &quot; . $this-&gt;error[&quot;error&quot;] .
-                 &quot;: &quot; . $rply . $this-&gt;CRLF;
-      }
-      return false;
-    }
-    return $rply;
</del><ins>+  * Get the current error
+  * @access public
+  * @return array
+  */
+  public function getError() {
+    return $this-&gt;error;
</ins><span class="cx">   }
</span><span class="cx"> 
</span><del>-  /*******************************************************************
-   *                       INTERNAL FUNCTIONS                       *
-   ******************************************************************/
</del><ins>+  /////////////////////////////////////////////////
+  // INTERNAL FUNCTIONS
+  /////////////////////////////////////////////////
</ins><span class="cx"> 
</span><span class="cx">   /**
</span><span class="cx">    * Read in as many lines as possible
</span><span class="lines">@@ -1036,21 +792,18 @@
</span><span class="cx">    * @access private
</span><span class="cx">    * @return string
</span><span class="cx">    */
</span><del>-  function get_lines() {
</del><ins>+  private function get_lines() {
</ins><span class="cx">     $data = &quot;&quot;;
</span><span class="cx">     while($str = @fgets($this-&gt;smtp_conn,515)) {
</span><span class="cx">       if($this-&gt;do_debug &gt;= 4) {
</span><del>-        echo &quot;SMTP -&gt; get_lines(): \$data was \&quot;$data\&quot;&quot; .
-                 $this-&gt;CRLF;
-        echo &quot;SMTP -&gt; get_lines(): \$str is \&quot;$str\&quot;&quot; .
-                 $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; get_lines(): \$data was \&quot;$data\&quot;&quot; . $this-&gt;CRLF . '&lt;br /&gt;';
+        echo &quot;SMTP -&gt; get_lines(): \$str is \&quot;$str\&quot;&quot; . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><span class="cx">       $data .= $str;
</span><span class="cx">       if($this-&gt;do_debug &gt;= 4) {
</span><del>-        echo &quot;SMTP -&gt; get_lines(): \$data is \&quot;$data\&quot;&quot; . $this-&gt;CRLF;
</del><ins>+        echo &quot;SMTP -&gt; get_lines(): \$data is \&quot;$data\&quot;&quot; . $this-&gt;CRLF . '&lt;br /&gt;';
</ins><span class="cx">       }
</span><del>-      # if the 4th character is a space then we are done reading
-      # so just break the loop
</del><ins>+      // if 4th character is a space, we are done reading, break the loop
</ins><span class="cx">       if(substr($str,3,1) == &quot; &quot;) { break; }
</span><span class="cx">     }
</span><span class="cx">     return $data;
</span><span class="lines">@@ -1058,5 +811,4 @@
</span><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-
- ?&gt;
</del><ins>+?&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre>
</div>
</div>

</body>
</html>