WordPress.org

Make WordPress Core

Ticket #15912: 15912.001.diff

File 15912.001.diff, 156.4 KB (added by cnorris23, 3 years ago)
  • wp-includes/class-phpmailer.php

     
    22/*~ class.phpmailer.php 
    33.---------------------------------------------------------------------------. 
    44|  Software: PHPMailer - PHP email class                                    | 
    5 |   Version: 2.0.4                                                          | 
    6 |   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  | 
     5|   Version: 5.1                                                            | 
     6|   Contact: via sourceforge.net support pages (also www.worxware.com)      | 
    77|      Info: http://phpmailer.sourceforge.net                               | 
    88|   Support: http://sourceforge.net/projects/phpmailer/                     | 
    99| ------------------------------------------------------------------------- | 
    10 |    Author: Andy Prevost (project admininistrator)                         | 
    11 |    Author: Brent R. Matzelle (original founder)                           | 
    12 | Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               | 
     10|     Admin: Andy Prevost (project admininistrator)                         | 
     11|   Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net | 
     12|          : Marcus Bointon (coolbru) coolbru@users.sourceforge.net         | 
     13|   Founder: Brent R. Matzelle (original founder)                           | 
     14| Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved.               | 
    1315| Copyright (c) 2001-2003, Brent R. Matzelle                                | 
    1416| ------------------------------------------------------------------------- | 
    1517|   License: Distributed under the Lesser General Public License (LGPL)     | 
     
    1820| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     | 
    1921| FITNESS FOR A PARTICULAR PURPOSE.                                         | 
    2022| ------------------------------------------------------------------------- | 
    21 | We offer a number of paid services (www.codeworxtech.com):                | 
     23| We offer a number of paid services (www.worxware.com):                    | 
    2224| - Web Hosting on highly optimized fast and secure servers                 | 
    2325| - Technology Consulting                                                   | 
    2426| - Oursourcing (highly qualified programmers and graphic designers)        | 
    2527'---------------------------------------------------------------------------' 
    26  */ 
     28*/ 
     29 
    2730/** 
    2831 * PHPMailer - PHP email transport class 
     32 * NOTE: Requires PHP version 5 or later 
    2933 * @package PHPMailer 
    3034 * @author Andy Prevost 
     35 * @author Marcus Bointon 
    3136 * @copyright 2004 - 2009 Andy Prevost 
     37 * @version $Id: class.phpmailer.php 447 2009-05-25 01:36:38Z codeworxtech $ 
     38 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License 
    3239 */ 
    3340 
     41if (version_compare(PHP_VERSION, '5.0.0', '<') ) exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n"); 
     42 
    3443class PHPMailer { 
    3544 
    3645  ///////////////////////////////////////////////// 
     
    4150   * Email priority (1 = High, 3 = Normal, 5 = low). 
    4251   * @var int 
    4352   */ 
    44   var $Priority          = 3; 
     53  public $Priority          = 3; 
    4554 
    4655  /** 
    4756   * Sets the CharSet of the message. 
    4857   * @var string 
    4958   */ 
    50   var $CharSet           = 'iso-8859-1'; 
     59  public $CharSet           = 'iso-8859-1'; 
    5160 
    5261  /** 
    5362   * Sets the Content-type of the message. 
    5463   * @var string 
    5564   */ 
    56   var $ContentType        = 'text/plain'; 
     65  public $ContentType       = 'text/plain'; 
    5766 
    5867  /** 
    59    * Sets the Encoding of the message. Options for this are "8bit", 
    60    * "7bit", "binary", "base64", and "quoted-printable". 
     68   * Sets the Encoding of the message. Options for this are 
     69   *  "8bit", "7bit", "binary", "base64", and "quoted-printable". 
    6170   * @var string 
    6271   */ 
    63   var $Encoding          = '8bit'; 
     72  public $Encoding          = '8bit'; 
    6473 
    6574  /** 
    6675   * Holds the most recent mailer error message. 
    6776   * @var string 
    6877   */ 
    69   var $ErrorInfo         = ''; 
     78  public $ErrorInfo         = ''; 
    7079 
    7180  /** 
    7281   * Sets the From email address for the message. 
    7382   * @var string 
    7483   */ 
    75   var $From              = 'root@localhost'; 
     84  public $From              = 'root@localhost'; 
    7685 
    7786  /** 
    7887   * Sets the From name of the message. 
    7988   * @var string 
    8089   */ 
    81   var $FromName          = 'Root User'; 
     90  public $FromName          = 'Root User'; 
    8291 
    8392  /** 
    8493   * Sets the Sender email (Return-Path) of the message.  If not empty, 
    8594   * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. 
    8695   * @var string 
    8796   */ 
    88   var $Sender            = ''; 
     97  public $Sender            = ''; 
    8998 
    9099  /** 
    91100   * Sets the Subject of the message. 
    92101   * @var string 
    93102   */ 
    94   var $Subject           = ''; 
     103  public $Subject           = ''; 
    95104 
    96105  /** 
    97106   * Sets the Body of the message.  This can be either an HTML or text body. 
    98107   * If HTML then run IsHTML(true). 
    99108   * @var string 
    100109   */ 
    101   var $Body              = ''; 
     110  public $Body              = ''; 
    102111 
    103112  /** 
    104113   * Sets the text-only body of the message.  This automatically sets the 
     
    107116   * that can read HTML will view the normal Body. 
    108117   * @var string 
    109118   */ 
    110   var $AltBody           = ''; 
     119  public $AltBody           = ''; 
    111120 
    112121  /** 
    113122   * Sets word wrapping on the body of the message to a given number of 
    114123   * characters. 
    115124   * @var int 
    116125   */ 
    117   var $WordWrap          = 0; 
     126  public $WordWrap          = 0; 
    118127 
    119128  /** 
    120129   * Method to send mail: ("mail", "sendmail", or "smtp"). 
    121130   * @var string 
    122131   */ 
    123   var $Mailer            = 'mail'; 
     132  public $Mailer            = 'mail'; 
    124133 
    125134  /** 
    126135   * Sets the path of the sendmail program. 
    127136   * @var string 
    128137   */ 
    129   var $Sendmail          = '/usr/sbin/sendmail'; 
     138  public $Sendmail          = '/usr/sbin/sendmail'; 
    130139 
    131140  /** 
    132    * Path to PHPMailer plugins.  This is now only useful if the SMTP class 
     141   * Path to PHPMailer plugins.  Useful if the SMTP class 
    133142   * is in a different directory than the PHP include path. 
    134143   * @var string 
    135144   */ 
    136   var $PluginDir         = ''; 
     145  public $PluginDir         = ''; 
    137146 
    138147  /** 
    139    * Holds PHPMailer version. 
    140    * @var string 
    141    */ 
    142   var $Version           = "2.0.4"; 
    143  
    144   /** 
    145148   * Sets the email address that a reading confirmation will be sent. 
    146149   * @var string 
    147150   */ 
    148   var $ConfirmReadingTo  = ''; 
     151  public $ConfirmReadingTo  = ''; 
    149152 
    150153  /** 
    151154   * Sets the hostname to use in Message-Id and Received headers 
     
    153156   * by SERVER_NAME is used or 'localhost.localdomain'. 
    154157   * @var string 
    155158   */ 
    156   var $Hostname          = ''; 
     159  public $Hostname          = ''; 
    157160 
    158161  /** 
    159162   * Sets the message ID to be used in the Message-Id header. 
    160163   * If empty, a unique id will be generated. 
    161164   * @var string 
    162165   */ 
    163   var $MessageID         = ''; 
     166  public $MessageID         = ''; 
    164167 
    165168  ///////////////////////////////////////////////// 
    166169  // PROPERTIES FOR SMTP 
     
    174177   * Hosts will be tried in order. 
    175178   * @var string 
    176179   */ 
    177   var $Host        = 'localhost'; 
     180  public $Host          = 'localhost'; 
    178181 
    179182  /** 
    180183   * Sets the default SMTP server port. 
    181184   * @var int 
    182185   */ 
    183   var $Port        = 25; 
     186  public $Port          = 25; 
    184187 
    185188  /** 
    186189   * Sets the SMTP HELO of the message (Default is $Hostname). 
    187190   * @var string 
    188191   */ 
    189   var $Helo        = ''; 
     192  public $Helo          = ''; 
    190193 
    191194  /** 
    192195   * Sets connection prefix. 
    193196   * Options are "", "ssl" or "tls" 
    194197   * @var string 
    195198   */ 
    196   var $SMTPSecure = ""; 
     199  public $SMTPSecure    = ''; 
    197200 
    198201  /** 
    199202   * Sets SMTP authentication. Utilizes the Username and Password variables. 
    200203   * @var bool 
    201204   */ 
    202   var $SMTPAuth     = false; 
     205  public $SMTPAuth      = false; 
    203206 
    204207  /** 
    205208   * Sets SMTP username. 
    206209   * @var string 
    207210   */ 
    208   var $Username     = ''; 
     211  public $Username      = ''; 
    209212 
    210213  /** 
    211214   * Sets SMTP password. 
    212215   * @var string 
    213216   */ 
    214   var $Password     = ''; 
     217  public $Password      = ''; 
    215218 
    216219  /** 
    217    * Sets the SMTP server timeout in seconds. This function will not 
    218    * work with the win32 version. 
     220   * Sets the SMTP server timeout in seconds. 
     221   * This function will not work with the win32 version. 
    219222   * @var int 
    220223   */ 
    221   var $Timeout      = 10; 
     224  public $Timeout       = 10; 
    222225 
    223226  /** 
    224227   * Sets SMTP class debugging on or off. 
    225228   * @var bool 
    226229   */ 
    227   var $SMTPDebug    = false; 
     230  public $SMTPDebug     = false; 
    228231 
    229232  /** 
    230233   * Prevents the SMTP connection from being closed after each mail 
     
    232235   * requires an explicit call to SmtpClose(). 
    233236   * @var bool 
    234237   */ 
    235   var $SMTPKeepAlive = false; 
     238  public $SMTPKeepAlive = false; 
    236239 
    237240  /** 
    238241   * Provides the ability to have the TO field process individual 
    239242   * emails, instead of sending to entire TO addresses 
    240243   * @var bool 
    241244   */ 
    242   var $SingleTo = false; 
     245  public $SingleTo      = false; 
    243246 
     247   /** 
     248   * If SingleTo is true, this provides the array to hold the email addresses 
     249   * @var bool 
     250   */ 
     251  public $SingleToArray = array(); 
     252 
     253 /** 
     254   * Provides the ability to change the line ending 
     255   * @var string 
     256   */ 
     257  public $LE              = "\n"; 
     258 
     259  /** 
     260   * Used with DKIM DNS Resource Record 
     261   * @var string 
     262   */ 
     263  public $DKIM_selector   = 'phpmailer'; 
     264 
     265  /** 
     266   * Used with DKIM DNS Resource Record 
     267   * optional, in format of email address 'you@yourdomain.com' 
     268   * @var string 
     269   */ 
     270  public $DKIM_identity   = ''; 
     271 
     272  /** 
     273   * Used with DKIM DNS Resource Record 
     274   * optional, in format of email address 'you@yourdomain.com' 
     275   * @var string 
     276   */ 
     277  public $DKIM_domain     = ''; 
     278 
     279  /** 
     280   * Used with DKIM DNS Resource Record 
     281   * optional, in format of email address 'you@yourdomain.com' 
     282   * @var string 
     283   */ 
     284  public $DKIM_private    = ''; 
     285 
     286  /** 
     287   * Callback Action function name 
     288   * the function that handles the result of the send email action. Parameters: 
     289   *   bool    $result        result of the send action 
     290   *   string  $to            email address of the recipient 
     291   *   string  $cc            cc email addresses 
     292   *   string  $bcc           bcc email addresses 
     293   *   string  $subject       the subject 
     294   *   string  $body          the email body 
     295   * @var string 
     296   */ 
     297  public $action_function = ''; //'callbackAction'; 
     298 
     299  /** 
     300   * Sets the PHPMailer Version number 
     301   * @var string 
     302   */ 
     303  public $Version         = '5.1'; 
     304 
    244305  ///////////////////////////////////////////////// 
    245   // PROPERTIES, PRIVATE 
     306  // PROPERTIES, PRIVATE AND PROTECTED 
    246307  ///////////////////////////////////////////////// 
    247308 
    248   var $smtp            = NULL; 
    249   var $to              = array(); 
    250   var $cc              = array(); 
    251   var $bcc             = array(); 
    252   var $ReplyTo         = array(); 
    253   var $attachment      = array(); 
    254   var $CustomHeader    = array(); 
    255   var $message_type    = ''; 
    256   var $boundary        = array(); 
    257   var $language        = array(); 
    258   var $error_count     = 0; 
    259   var $LE              = "\n"; 
    260   var $sign_cert_file  = ""; 
    261   var $sign_key_file   = ""; 
    262   var $sign_key_pass   = ""; 
     309  private   $smtp           = NULL; 
     310  private   $to             = array(); 
     311  private   $cc             = array(); 
     312  private   $bcc            = array(); 
     313  private   $ReplyTo        = array(); 
     314  private   $all_recipients = array(); 
     315  private   $attachment     = array(); 
     316  private   $CustomHeader   = array(); 
     317  private   $message_type   = ''; 
     318  private   $boundary       = array(); 
     319  protected $language       = array(); 
     320  private   $error_count    = 0; 
     321  private   $sign_cert_file = ""; 
     322  private   $sign_key_file  = ""; 
     323  private   $sign_key_pass  = ""; 
     324  private   $exceptions     = false; 
    263325 
    264326  ///////////////////////////////////////////////// 
     327  // CONSTANTS 
     328  ///////////////////////////////////////////////// 
     329 
     330  const STOP_MESSAGE  = 0; // message only, continue processing 
     331  const STOP_CONTINUE = 1; // message?, likely ok to continue processing 
     332  const STOP_CRITICAL = 2; // message, plus full stop, critical error reached 
     333 
     334  ///////////////////////////////////////////////// 
    265335  // METHODS, VARIABLES 
    266336  ///////////////////////////////////////////////// 
    267337 
    268338  /** 
     339   * Constructor 
     340   * @param boolean $exceptions Should we throw external exceptions? 
     341   */ 
     342  public function __construct($exceptions = false) { 
     343    $this->exceptions = ($exceptions == true); 
     344  } 
     345 
     346  /** 
    269347   * Sets message type to HTML. 
    270    * @param bool $bool 
     348   * @param bool $ishtml 
    271349   * @return void 
    272350   */ 
    273   function IsHTML($bool) { 
    274     if($bool == true) { 
     351  public function IsHTML($ishtml = true) { 
     352    if ($ishtml) { 
    275353      $this->ContentType = 'text/html'; 
    276354    } else { 
    277355      $this->ContentType = 'text/plain'; 
     
    282360   * Sets Mailer to send message using SMTP. 
    283361   * @return void 
    284362   */ 
    285   function IsSMTP() { 
     363  public function IsSMTP() { 
    286364    $this->Mailer = 'smtp'; 
    287365  } 
    288366 
     
    290368   * Sets Mailer to send message using PHP mail() function. 
    291369   * @return void 
    292370   */ 
    293   function IsMail() { 
     371  public function IsMail() { 
    294372    $this->Mailer = 'mail'; 
    295373  } 
    296374 
     
    298376   * Sets Mailer to send message using the $Sendmail program. 
    299377   * @return void 
    300378   */ 
    301   function IsSendmail() { 
     379  public function IsSendmail() { 
     380    if (!stristr(ini_get('sendmail_path'), 'sendmail')) { 
     381      $this->Sendmail = '/var/qmail/bin/sendmail'; 
     382    } 
    302383    $this->Mailer = 'sendmail'; 
    303384  } 
    304385 
     
    306387   * Sets Mailer to send message using the qmail MTA. 
    307388   * @return void 
    308389   */ 
    309   function IsQmail() { 
    310     $this->Sendmail = '/var/qmail/bin/sendmail'; 
     390  public function IsQmail() { 
     391    if (stristr(ini_get('sendmail_path'), 'qmail')) { 
     392      $this->Sendmail = '/var/qmail/bin/sendmail'; 
     393    } 
    311394    $this->Mailer = 'sendmail'; 
    312395  } 
    313396 
     
    319402   * Adds a "To" address. 
    320403   * @param string $address 
    321404   * @param string $name 
    322    * @return void 
     405   * @return boolean true on success, false if address already used 
    323406   */ 
    324   function AddAddress($address, $name = '') { 
    325     $cur = count($this->to); 
    326     $this->to[$cur][0] = trim($address); 
    327     $this->to[$cur][1] = $name; 
     407  public function AddAddress($address, $name = '') { 
     408    return $this->AddAnAddress('to', $address, $name); 
    328409  } 
    329410 
    330411  /** 
    331    * Adds a "Cc" address. Note: this function works 
    332    * with the SMTP mailer on win32, not with the "mail" 
    333    * mailer. 
     412   * Adds a "Cc" address. 
     413   * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer. 
    334414   * @param string $address 
    335415   * @param string $name 
    336    * @return void 
     416   * @return boolean true on success, false if address already used 
    337417   */ 
    338   function AddCC($address, $name = '') { 
    339     $cur = count($this->cc); 
    340     $this->cc[$cur][0] = trim($address); 
    341     $this->cc[$cur][1] = $name; 
     418  public function AddCC($address, $name = '') { 
     419    return $this->AddAnAddress('cc', $address, $name); 
    342420  } 
    343421 
    344422  /** 
    345    * Adds a "Bcc" address. Note: this function works 
    346    * with the SMTP mailer on win32, not with the "mail" 
    347    * mailer. 
     423   * Adds a "Bcc" address. 
     424   * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer. 
    348425   * @param string $address 
    349426   * @param string $name 
    350    * @return void 
     427   * @return boolean true on success, false if address already used 
    351428   */ 
    352   function AddBCC($address, $name = '') { 
    353     $cur = count($this->bcc); 
    354     $this->bcc[$cur][0] = trim($address); 
    355     $this->bcc[$cur][1] = $name; 
     429  public function AddBCC($address, $name = '') { 
     430    return $this->AddAnAddress('bcc', $address, $name); 
    356431  } 
    357432 
    358433  /** 
    359    * Adds a "Reply-To" address. 
     434   * Adds a "Reply-to" address. 
    360435   * @param string $address 
    361436   * @param string $name 
    362    * @return void 
     437   * @return boolean 
    363438   */ 
    364   function AddReplyTo($address, $name = '') { 
    365     $cur = count($this->ReplyTo); 
    366     $this->ReplyTo[$cur][0] = trim($address); 
    367     $this->ReplyTo[$cur][1] = $name; 
     439  public function AddReplyTo($address, $name = '') { 
     440    return $this->AddAnAddress('ReplyTo', $address, $name); 
    368441  } 
    369442 
     443  /** 
     444   * Adds an address to one of the recipient arrays 
     445   * Addresses that have been added already return false, but do not throw exceptions 
     446   * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo' 
     447   * @param string $address The email address to send to 
     448   * @param string $name 
     449   * @return boolean true on success, false if address already used or invalid in some way 
     450   * @access private 
     451   */ 
     452  private function AddAnAddress($kind, $address, $name = '') { 
     453    if (!preg_match('/^(to|cc|bcc|ReplyTo)$/', $kind)) { 
     454      echo 'Invalid recipient array: ' . kind; 
     455      return false; 
     456    } 
     457    $address = trim($address); 
     458    $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim 
     459    if (!self::ValidateAddress($address)) { 
     460      $this->SetError($this->Lang('invalid_address').': '. $address); 
     461      if ($this->exceptions) { 
     462        throw new phpmailerException($this->Lang('invalid_address').': '.$address); 
     463      } 
     464      echo $this->Lang('invalid_address').': '.$address; 
     465      return false; 
     466    } 
     467    if ($kind != 'ReplyTo') { 
     468      if (!isset($this->all_recipients[strtolower($address)])) { 
     469        array_push($this->$kind, array($address, $name)); 
     470        $this->all_recipients[strtolower($address)] = true; 
     471        return true; 
     472      } 
     473    } else { 
     474      if (!array_key_exists(strtolower($address), $this->ReplyTo)) { 
     475        $this->ReplyTo[strtolower($address)] = array($address, $name); 
     476      return true; 
     477    } 
     478  } 
     479  return false; 
     480} 
     481 
     482/** 
     483 * Set the From and FromName properties 
     484 * @param string $address 
     485 * @param string $name 
     486 * @return boolean 
     487 */ 
     488  public function SetFrom($address, $name = '',$auto=1) { 
     489    $address = trim($address); 
     490    $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim 
     491    if (!self::ValidateAddress($address)) { 
     492      $this->SetError($this->Lang('invalid_address').': '. $address); 
     493      if ($this->exceptions) { 
     494        throw new phpmailerException($this->Lang('invalid_address').': '.$address); 
     495      } 
     496      echo $this->Lang('invalid_address').': '.$address; 
     497      return false; 
     498    } 
     499    $this->From = $address; 
     500    $this->FromName = $name; 
     501    if ($auto) { 
     502      if (empty($this->ReplyTo)) { 
     503        $this->AddAnAddress('ReplyTo', $address, $name); 
     504      } 
     505      if (empty($this->Sender)) { 
     506        $this->Sender = $address; 
     507      } 
     508    } 
     509    return true; 
     510  } 
     511 
     512  /** 
     513   * Check that a string looks roughly like an email address should 
     514   * Static so it can be used without instantiation 
     515   * Tries to use PHP built-in validator in the filter extension (from PHP 5.2), falls back to a reasonably competent regex validator 
     516   * Conforms approximately to RFC2822 
     517   * @link http://www.hexillion.com/samples/#Regex Original pattern found here 
     518   * @param string $address The email address to check 
     519   * @return boolean 
     520   * @static 
     521   * @access public 
     522   */ 
     523  public static function ValidateAddress($address) { 
     524    if (function_exists('filter_var')) { //Introduced in PHP 5.2 
     525      if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) { 
     526        return false; 
     527      } else { 
     528        return true; 
     529      } 
     530    } else { 
     531      return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[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); 
     532    } 
     533  } 
     534 
    370535  ///////////////////////////////////////////////// 
    371536  // METHODS, MAIL SENDING 
    372537  ///////////////////////////////////////////////// 
     
    377542   * variable to view description of the error. 
    378543   * @return bool 
    379544   */ 
    380   function Send() { 
    381     $header = ''; 
    382     $body = ''; 
    383     $result = true; 
     545  public function Send() { 
     546    try { 
     547      if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { 
     548        throw new phpmailerException($this->Lang('provide_address'), self::STOP_CRITICAL); 
     549      } 
    384550 
    385     if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { 
    386       $this->SetError($this->Lang('provide_address')); 
    387       return false; 
    388     } 
     551      // Set whether the message is multipart/alternative 
     552      if(!empty($this->AltBody)) { 
     553        $this->ContentType = 'multipart/alternative'; 
     554      } 
    389555 
    390     /* Set whether the message is multipart/alternative */ 
    391     if(!empty($this->AltBody)) { 
    392       $this->ContentType = 'multipart/alternative'; 
    393     } 
     556      $this->error_count = 0; // reset errors 
     557      $this->SetMessageType(); 
     558      $header = $this->CreateHeader(); 
     559      $body = $this->CreateBody(); 
    394560 
    395     $this->error_count = 0; // reset errors 
    396     $this->SetMessageType(); 
    397     $header .= $this->CreateHeader(); 
    398     $body = $this->CreateBody(); 
     561      if (empty($this->Body)) { 
     562        throw new phpmailerException($this->Lang('empty_message'), self::STOP_CRITICAL); 
     563      } 
    399564 
    400     if($body == '') { 
     565      // digitally sign with DKIM if enabled 
     566      if ($this->DKIM_domain && $this->DKIM_private) { 
     567        $header_dkim = $this->DKIM_Add($header,$this->Subject,$body); 
     568        $header = str_replace("\r\n","\n",$header_dkim) . $header; 
     569      } 
     570 
     571      // Choose the mailer and send through it 
     572      switch($this->Mailer) { 
     573        case 'sendmail': 
     574          return $this->SendmailSend($header, $body); 
     575        case 'smtp': 
     576          return $this->SmtpSend($header, $body); 
     577        default: 
     578          return $this->MailSend($header, $body); 
     579      } 
     580 
     581    } catch (phpmailerException $e) { 
     582      $this->SetError($e->getMessage()); 
     583      if ($this->exceptions) { 
     584        throw $e; 
     585      } 
     586      echo $e->getMessage()."\n"; 
    401587      return false; 
    402588    } 
    403  
    404     /* Choose the mailer */ 
    405     switch($this->Mailer) { 
    406       case 'sendmail': 
    407         $result = $this->SendmailSend($header, $body); 
    408         break; 
    409       case 'smtp': 
    410         $result = $this->SmtpSend($header, $body); 
    411         break; 
    412       case 'mail': 
    413         $result = $this->MailSend($header, $body); 
    414         break; 
    415       default: 
    416         $result = $this->MailSend($header, $body); 
    417         break; 
    418         //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported')); 
    419         //$result = false; 
    420         //break; 
    421     } 
    422  
    423     return $result; 
    424589  } 
    425590 
    426591  /** 
    427592   * Sends mail using the $Sendmail program. 
    428    * @access private 
     593   * @param string $header The message headers 
     594   * @param string $body The message body 
     595   * @access protected 
    429596   * @return bool 
    430597   */ 
    431   function SendmailSend($header, $body) { 
     598  protected function SendmailSend($header, $body) { 
    432599    if ($this->Sender != '') { 
    433600      $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); 
    434601    } else { 
    435602      $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail)); 
    436603    } 
    437  
    438     if(!@$mail = popen($sendmail, 'w')) { 
    439       $this->SetError($this->Lang('execute') . $this->Sendmail); 
    440       return false; 
     604    if ($this->SingleTo === true) { 
     605      foreach ($this->SingleToArray as $key => $val) { 
     606        if(!@$mail = popen($sendmail, 'w')) { 
     607          throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); 
     608        } 
     609        fputs($mail, "To: " . $val . "\n"); 
     610        fputs($mail, $header); 
     611        fputs($mail, $body); 
     612        $result = pclose($mail); 
     613        // implement call back function if it exists 
     614        $isSent = ($result == 0) ? 1 : 0; 
     615        $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); 
     616        if($result != 0) { 
     617          throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); 
     618        } 
     619      } 
     620    } else { 
     621      if(!@$mail = popen($sendmail, 'w')) { 
     622        throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); 
     623      } 
     624      fputs($mail, $header); 
     625      fputs($mail, $body); 
     626      $result = pclose($mail); 
     627      // implement call back function if it exists 
     628      $isSent = ($result == 0) ? 1 : 0; 
     629      $this->doCallback($isSent,$this->to,$this->cc,$this->bcc,$this->Subject,$body); 
     630      if($result != 0) { 
     631        throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); 
     632      } 
    441633    } 
    442  
    443     fputs($mail, $header); 
    444     fputs($mail, $body); 
    445  
    446     $result = pclose($mail); 
    447     if (version_compare(phpversion(), '4.2.3') == -1) { 
    448       $result = $result >> 8 & 0xFF; 
    449     } 
    450     if($result != 0) { 
    451       $this->SetError($this->Lang('execute') . $this->Sendmail); 
    452       return false; 
    453     } 
    454634    return true; 
    455635  } 
    456636 
    457637  /** 
    458638   * Sends mail using the PHP mail() function. 
    459    * @access private 
     639   * @param string $header The message headers 
     640   * @param string $body The message body 
     641   * @access protected 
    460642   * @return bool 
    461643   */ 
    462   function MailSend($header, $body) { 
    463  
    464     $to = ''; 
    465     for($i = 0; $i < count($this->to); $i++) { 
    466       if($i != 0) { $to .= ', '; } 
    467       $to .= $this->AddrFormat($this->to[$i]); 
     644  protected function MailSend($header, $body) { 
     645    $toArr = array(); 
     646    foreach($this->to as $t) { 
     647      $toArr[] = $this->AddrFormat($t); 
    468648    } 
     649    $to = implode(', ', $toArr); 
    469650 
    470     $toArr = split(',', $to); 
    471  
    472651    $params = sprintf("-oi -f %s", $this->Sender); 
    473     if ($this->Sender != '' && strlen(ini_get('safe_mode')) < 1) { 
     652    if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) { 
    474653      $old_from = ini_get('sendmail_from'); 
    475654      ini_set('sendmail_from', $this->Sender); 
    476655      if ($this->SingleTo === true && count($toArr) > 1) { 
    477656        foreach ($toArr as $key => $val) { 
    478657          $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); 
     658          // implement call back function if it exists 
     659          $isSent = ($rt == 1) ? 1 : 0; 
     660          $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); 
    479661        } 
    480662      } else { 
    481663        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); 
     664        // implement call back function if it exists 
     665        $isSent = ($rt == 1) ? 1 : 0; 
     666        $this->doCallback($isSent,$to,$this->cc,$this->bcc,$this->Subject,$body); 
    482667      } 
    483668    } else { 
    484669      if ($this->SingleTo === true && count($toArr) > 1) { 
    485670        foreach ($toArr as $key => $val) { 
    486671          $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); 
     672          // implement call back function if it exists 
     673          $isSent = ($rt == 1) ? 1 : 0; 
     674          $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); 
    487675        } 
    488676      } else { 
    489677        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header); 
     678        // implement call back function if it exists 
     679        $isSent = ($rt == 1) ? 1 : 0; 
     680        $this->doCallback($isSent,$to,$this->cc,$this->bcc,$this->Subject,$body); 
    490681      } 
    491682    } 
    492  
    493683    if (isset($old_from)) { 
    494684      ini_set('sendmail_from', $old_from); 
    495685    } 
    496  
    497686    if(!$rt) { 
    498       $this->SetError($this->Lang('instantiate')); 
    499       return false; 
     687      throw new phpmailerException($this->Lang('instantiate'), self::STOP_CRITICAL); 
    500688    } 
    501  
    502689    return true; 
    503690  } 
    504691 
    505692  /** 
    506    * Sends mail via SMTP using PhpSMTP (Author: 
    507    * Chris Ryan).  Returns bool.  Returns false if there is a 
    508    * bad MAIL FROM, RCPT, or DATA input. 
    509    * @access private 
     693   * Sends mail via SMTP using PhpSMTP 
     694   * Returns false if there is a bad MAIL FROM, RCPT, or DATA input. 
     695   * @param string $header The message headers 
     696   * @param string $body The message body 
     697   * @uses SMTP 
     698   * @access protected 
    510699   * @return bool 
    511700   */ 
    512   function SmtpSend($header, $body) { 
    513     include_once($this->PluginDir . 'class-smtp.php'); 
    514     $error = ''; 
     701  protected function SmtpSend($header, $body) { 
     702    require_once $this->PluginDir . 'class.smtp.php'; 
    515703    $bad_rcpt = array(); 
    516704 
    517705    if(!$this->SmtpConnect()) { 
    518       return false; 
     706      throw new phpmailerException($this->Lang('smtp_connect_failed'), self::STOP_CRITICAL); 
    519707    } 
    520  
    521708    $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; 
    522709    if(!$this->smtp->Mail($smtp_from)) { 
    523       $error = $this->Lang('from_failed') . $smtp_from; 
    524       $this->SetError($error); 
    525       $this->smtp->Reset(); 
    526       return false; 
     710      throw new phpmailerException($this->Lang('from_failed') . $smtp_from, self::STOP_CRITICAL); 
    527711    } 
    528712 
    529     /* Attempt to send attach all recipients */ 
    530     for($i = 0; $i < count($this->to); $i++) { 
    531       if(!$this->smtp->Recipient($this->to[$i][0])) { 
    532         $bad_rcpt[] = $this->to[$i][0]; 
     713    // Attempt to send attach all recipients 
     714    foreach($this->to as $to) { 
     715      if (!$this->smtp->Recipient($to[0])) { 
     716        $bad_rcpt[] = $to[0]; 
     717        // implement call back function if it exists 
     718        $isSent = 0; 
     719        $this->doCallback($isSent,$to[0],'','',$this->Subject,$body); 
     720      } else { 
     721        // implement call back function if it exists 
     722        $isSent = 1; 
     723        $this->doCallback($isSent,$to[0],'','',$this->Subject,$body); 
    533724      } 
    534725    } 
    535     for($i = 0; $i < count($this->cc); $i++) { 
    536       if(!$this->smtp->Recipient($this->cc[$i][0])) { 
    537         $bad_rcpt[] = $this->cc[$i][0]; 
     726    foreach($this->cc as $cc) { 
     727      if (!$this->smtp->Recipient($cc[0])) { 
     728        $bad_rcpt[] = $cc[0]; 
     729        // implement call back function if it exists 
     730        $isSent = 0; 
     731        $this->doCallback($isSent,'',$cc[0],'',$this->Subject,$body); 
     732      } else { 
     733        // implement call back function if it exists 
     734        $isSent = 1; 
     735        $this->doCallback($isSent,'',$cc[0],'',$this->Subject,$body); 
    538736      } 
    539737    } 
    540     for($i = 0; $i < count($this->bcc); $i++) { 
    541       if(!$this->smtp->Recipient($this->bcc[$i][0])) { 
    542         $bad_rcpt[] = $this->bcc[$i][0]; 
     738    foreach($this->bcc as $bcc) { 
     739      if (!$this->smtp->Recipient($bcc[0])) { 
     740        $bad_rcpt[] = $bcc[0]; 
     741        // implement call back function if it exists 
     742        $isSent = 0; 
     743        $this->doCallback($isSent,'','',$bcc[0],$this->Subject,$body); 
     744      } else { 
     745        // implement call back function if it exists 
     746        $isSent = 1; 
     747        $this->doCallback($isSent,'','',$bcc[0],$this->Subject,$body); 
    543748      } 
    544749    } 
    545750 
    546     if(count($bad_rcpt) > 0) { // Create error message 
    547       for($i = 0; $i < count($bad_rcpt); $i++) { 
    548         if($i != 0) { 
    549           $error .= ', '; 
    550         } 
    551         $error .= $bad_rcpt[$i]; 
    552       } 
    553       $error = $this->Lang('recipients_failed') . $error; 
    554       $this->SetError($error); 
    555       $this->smtp->Reset(); 
    556       return false; 
     751 
     752    if (count($bad_rcpt) > 0 ) { //Create error message for any bad addresses 
     753      $badaddresses = implode(', ', $bad_rcpt); 
     754      throw new phpmailerException($this->Lang('recipients_failed') . $badaddresses); 
    557755    } 
    558  
    559756    if(!$this->smtp->Data($header . $body)) { 
    560       $this->SetError($this->Lang('data_not_accepted')); 
    561       $this->smtp->Reset(); 
    562       return false; 
     757      throw new phpmailerException($this->Lang('data_not_accepted'), self::STOP_CRITICAL); 
    563758    } 
    564759    if($this->SMTPKeepAlive == true) { 
    565760      $this->smtp->Reset(); 
    566     } else { 
    567       $this->SmtpClose(); 
    568761    } 
    569  
    570762    return true; 
    571763  } 
    572764 
    573765  /** 
    574    * Initiates a connection to an SMTP server.  Returns false if the 
    575    * operation failed. 
    576    * @access private 
     766   * Initiates a connection to an SMTP server. 
     767   * Returns false if the operation failed. 
     768   * @uses SMTP 
     769   * @access public 
    577770   * @return bool 
    578771   */ 
    579   function SmtpConnect() { 
    580     if($this->smtp == NULL) { 
     772  public function SmtpConnect() { 
     773    if(is_null($this->smtp)) { 
    581774      $this->smtp = new SMTP(); 
    582775    } 
    583776 
    584777    $this->smtp->do_debug = $this->SMTPDebug; 
    585778    $hosts = explode(';', $this->Host); 
    586779    $index = 0; 
    587     $connection = ($this->smtp->Connected()); 
     780    $connection = $this->smtp->Connected(); 
    588781 
    589     /* Retry while there is no connection */ 
    590     while($index < count($hosts) && $connection == false) { 
    591       $hostinfo = array(); 
    592       if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) { 
    593         $host = $hostinfo[1]; 
    594         $port = $hostinfo[2]; 
    595       } else { 
    596         $host = $hosts[$index]; 
    597         $port = $this->Port; 
    598       } 
    599  
    600       if($this->smtp->Connect(((!empty($this->SMTPSecure))?$this->SMTPSecure.'://':'').$host, $port, $this->Timeout)) { 
    601         if ($this->Helo != '') { 
    602           $this->smtp->Hello($this->Helo); 
     782    // Retry while there is no connection 
     783    try { 
     784      while($index < count($hosts) && !$connection) { 
     785        $hostinfo = array(); 
     786        if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) { 
     787          $host = $hostinfo[1]; 
     788          $port = $hostinfo[2]; 
    603789        } else { 
    604           $this->smtp->Hello($this->ServerHostname()); 
     790          $host = $hosts[$index]; 
     791          $port = $this->Port; 
    605792        } 
    606793 
    607         $connection = true; 
    608         if($this->SMTPAuth) { 
    609           if(!$this->smtp->Authenticate($this->Username, $this->Password)) { 
    610             $this->SetError($this->Lang('authenticate')); 
    611             $this->smtp->Reset(); 
    612             $connection = false; 
     794        $tls = ($this->SMTPSecure == 'tls'); 
     795        $ssl = ($this->SMTPSecure == 'ssl'); 
     796 
     797        if ($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) { 
     798 
     799          $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname()); 
     800          $this->smtp->Hello($hello); 
     801 
     802          if ($tls) { 
     803            if (!$this->smtp->StartTLS()) { 
     804              throw new phpmailerException($this->Lang('tls')); 
     805            } 
     806 
     807            //We must resend HELO after tls negotiation 
     808            $this->smtp->Hello($hello); 
    613809          } 
     810 
     811          $connection = true; 
     812          if ($this->SMTPAuth) { 
     813            if (!$this->smtp->Authenticate($this->Username, $this->Password)) { 
     814              throw new phpmailerException($this->Lang('authenticate')); 
     815            } 
     816          } 
    614817        } 
     818        $index++; 
     819        if (!$connection) { 
     820          throw new phpmailerException($this->Lang('connect_host')); 
     821        } 
    615822      } 
    616       $index++; 
     823    } catch (phpmailerException $e) { 
     824      $this->smtp->Reset(); 
     825      throw $e; 
    617826    } 
    618     if(!$connection) { 
    619       $this->SetError($this->Lang('connect_host')); 
    620     } 
    621  
    622     return $connection; 
     827    return true; 
    623828  } 
    624829 
    625830  /** 
    626831   * Closes the active SMTP session if one exists. 
    627832   * @return void 
    628833   */ 
    629   function SmtpClose() { 
    630     if($this->smtp != NULL) { 
     834  public function SmtpClose() { 
     835    if(!is_null($this->smtp)) { 
    631836      if($this->smtp->Connected()) { 
    632837        $this->smtp->Quit(); 
    633838        $this->smtp->Close(); 
     
    636841  } 
    637842 
    638843  /** 
    639    * Sets the language for all class error messages.  Returns false 
    640    * if it cannot load the language file.  The default language type 
    641    * is English. 
    642    * @param string $lang_type Type of language (e.g. Portuguese: "br") 
    643    * @param string $lang_path Path to the language file directory 
    644    * @access public 
    645    * @return bool 
    646    */ 
    647   function SetLanguage($lang_type, $lang_path = 'language/') { 
    648     if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) { 
    649       include($lang_path.'phpmailer.lang-'.$lang_type.'.php'); 
    650     } elseif (file_exists($lang_path.'phpmailer.lang-en.php')) { 
    651       include($lang_path.'phpmailer.lang-en.php'); 
    652     } else { 
    653       $PHPMAILER_LANG = array(); 
    654       $PHPMAILER_LANG["provide_address"]      = 'You must provide at least one ' . 
    655       $PHPMAILER_LANG["mailer_not_supported"] = ' mailer is not supported.'; 
    656       $PHPMAILER_LANG["execute"]              = 'Could not execute: '; 
    657       $PHPMAILER_LANG["instantiate"]          = 'Could not instantiate mail function.'; 
    658       $PHPMAILER_LANG["authenticate"]         = 'SMTP Error: Could not authenticate.'; 
    659       $PHPMAILER_LANG["from_failed"]          = 'The following From address failed: '; 
    660       $PHPMAILER_LANG["recipients_failed"]    = 'SMTP Error: The following ' . 
    661       $PHPMAILER_LANG["data_not_accepted"]    = 'SMTP Error: Data not accepted.'; 
    662       $PHPMAILER_LANG["connect_host"]         = 'SMTP Error: Could not connect to SMTP host.'; 
    663       $PHPMAILER_LANG["file_access"]          = 'Could not access file: '; 
    664       $PHPMAILER_LANG["file_open"]            = 'File Error: Could not open file: '; 
    665       $PHPMAILER_LANG["encoding"]             = 'Unknown encoding: '; 
    666       $PHPMAILER_LANG["signing"]              = 'Signing Error: '; 
     844  * Sets the language for all class error messages. 
     845  * Returns false if it cannot load the language file.  The default language is English. 
     846  * @param string $langcode ISO 639-1 2-character language code (e.g. Portuguese: "br") 
     847  * @param string $lang_path Path to the language file directory 
     848  * @access public 
     849  */ 
     850  function SetLanguage($langcode = 'en', $lang_path = 'language/') { 
     851    //Define full set of translatable strings 
     852    $PHPMAILER_LANG = array( 
     853      'provide_address' => 'You must provide at least one recipient email address.', 
     854      'mailer_not_supported' => ' mailer is not supported.', 
     855      'execute' => 'Could not execute: ', 
     856      'instantiate' => 'Could not instantiate mail function.', 
     857      'authenticate' => 'SMTP Error: Could not authenticate.', 
     858      'from_failed' => 'The following From address failed: ', 
     859      'recipients_failed' => 'SMTP Error: The following recipients failed: ', 
     860      'data_not_accepted' => 'SMTP Error: Data not accepted.', 
     861      'connect_host' => 'SMTP Error: Could not connect to SMTP host.', 
     862      'file_access' => 'Could not access file: ', 
     863      'file_open' => 'File Error: Could not open file: ', 
     864      'encoding' => 'Unknown encoding: ', 
     865      'signing' => 'Signing Error: ', 
     866      'smtp_error' => 'SMTP server error: ', 
     867      'empty_message' => 'Message body empty', 
     868      'invalid_address' => 'Invalid address', 
     869      'variable_set' => 'Cannot set or reset variable: ' 
     870    ); 
     871    //Overwrite language-specific strings. This way we'll never have missing translations - no more "language string failed to load"! 
     872    $l = true; 
     873    if ($langcode != 'en') { //There is no English translation file 
     874      $l = @include $lang_path.'phpmailer.lang-'.$langcode.'.php'; 
    667875    } 
    668876    $this->language = $PHPMAILER_LANG; 
     877    return ($l == true); //Returns false if language not found 
     878  } 
    669879 
    670     return true; 
     880  /** 
     881  * Return the current array of language strings 
     882  * @return array 
     883  */ 
     884  public function GetTranslations() { 
     885    return $this->language; 
    671886  } 
    672887 
    673888  ///////////////////////////////////////////////// 
     
    676891 
    677892  /** 
    678893   * Creates recipient headers. 
    679    * @access private 
     894   * @access public 
    680895   * @return string 
    681896   */ 
    682   function AddrAppend($type, $addr) { 
     897  public function AddrAppend($type, $addr) { 
    683898    $addr_str = $type . ': '; 
    684     $addr_str .= $this->AddrFormat($addr[0]); 
    685     if(count($addr) > 1) { 
    686       for($i = 1; $i < count($addr); $i++) { 
    687         $addr_str .= ', ' . $this->AddrFormat($addr[$i]); 
    688       } 
     899    $addresses = array(); 
     900    foreach ($addr as $a) { 
     901      $addresses[] = $this->AddrFormat($a); 
    689902    } 
     903    $addr_str .= implode(', ', $addresses); 
    690904    $addr_str .= $this->LE; 
    691905 
    692906    return $addr_str; 
     
    694908 
    695909  /** 
    696910   * Formats an address correctly. 
    697    * @access private 
     911   * @access public 
    698912   * @return string 
    699913   */ 
    700   function AddrFormat($addr) { 
    701     if(empty($addr[1])) { 
    702       $formatted = $this->SecureHeader($addr[0]); 
     914  public function AddrFormat($addr) { 
     915    if (empty($addr[1])) { 
     916      return $this->SecureHeader($addr[0]); 
    703917    } else { 
    704       $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">"; 
     918      return $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">"; 
    705919    } 
    706  
    707     return $formatted; 
    708920  } 
    709921 
    710922  /** 
    711923   * Wraps message for use with mailers that do not 
    712924   * automatically perform wrapping and for quoted-printable. 
    713925   * Original written by philippe. 
    714    * @access private 
     926   * @param string $message The message to wrap 
     927   * @param integer $length The line length to wrap to 
     928   * @param boolean $qp_mode Whether to run in Quoted-Printable mode 
     929   * @access public 
    715930   * @return string 
    716931   */ 
    717   function WrapText($message, $length, $qp_mode = false) { 
     932  public function WrapText($message, $length, $qp_mode = false) { 
    718933    $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; 
    719934    // If utf-8 encoding is used, we will need to make sure we don't 
    720935    // split multibyte characters when we wrap 
     
    7911006   * Finds last character boundary prior to maxLength in a utf-8 
    7921007   * quoted (printable) encoded string. 
    7931008   * Original written by Colin Brown. 
    794    * @access private 
     1009   * @access public 
    7951010   * @param string $encodedText utf-8 QP text 
    7961011   * @param int    $maxLength   find last character boundary prior to this length 
    7971012   * @return int 
    7981013   */ 
    799   function UTF8CharBoundary($encodedText, $maxLength) { 
     1014  public function UTF8CharBoundary($encodedText, $maxLength) { 
    8001015    $foundSplitPos = false; 
    8011016    $lookBack = 3; 
    8021017    while (!$foundSplitPos) { 
     
    8281043    return $maxLength; 
    8291044  } 
    8301045 
     1046 
    8311047  /** 
    8321048   * Set the body wrapping. 
    833    * @access private 
     1049   * @access public 
    8341050   * @return void 
    8351051   */ 
    836   function SetWordWrap() { 
     1052  public function SetWordWrap() { 
    8371053    if($this->WordWrap < 1) { 
    8381054      return; 
    8391055    } 
    8401056 
    8411057    switch($this->message_type) { 
    8421058      case 'alt': 
    843         /* fall through */ 
    8441059      case 'alt_attachments': 
    8451060        $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); 
    8461061        break; 
     
    8521067 
    8531068  /** 
    8541069   * Assembles message header. 
    855    * @access private 
    856    * @return string 
     1070   * @access public 
     1071   * @return string The assembled header 
    8571072   */ 
    858   function CreateHeader() { 
     1073  public function CreateHeader() { 
    8591074    $result = ''; 
    8601075 
    861     /* Set the boundaries */ 
     1076    // Set the boundaries 
    8621077    $uniq_id = md5(uniqid(time())); 
    8631078    $this->boundary[1] = 'b1_' . $uniq_id; 
    8641079    $this->boundary[2] = 'b2_' . $uniq_id; 
    8651080 
    866     $result .= $this->HeaderLine('Date', $this->RFCDate()); 
     1081    $result .= $this->HeaderLine('Date', self::RFCDate()); 
    8671082    if($this->Sender == '') { 
    8681083      $result .= $this->HeaderLine('Return-Path', trim($this->From)); 
    8691084    } else { 
    8701085      $result .= $this->HeaderLine('Return-Path', trim($this->Sender)); 
    8711086    } 
    8721087 
    873     /* To be created automatically by mail() */ 
     1088    // To be created automatically by mail() 
    8741089    if($this->Mailer != 'mail') { 
    875       if(count($this->to) > 0) { 
    876         $result .= $this->AddrAppend('To', $this->to); 
    877       } elseif (count($this->cc) == 0) { 
    878         $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); 
     1090      if ($this->SingleTo === true) { 
     1091        foreach($this->to as $t) { 
     1092          $this->SingleToArray[] = $this->AddrFormat($t); 
     1093        } 
     1094      } else { 
     1095        if(count($this->to) > 0) { 
     1096          $result .= $this->AddrAppend('To', $this->to); 
     1097        } elseif (count($this->cc) == 0) { 
     1098          $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); 
     1099        } 
    8791100      } 
    8801101    } 
    8811102 
     
    8841105    $from[0][1] = $this->FromName; 
    8851106    $result .= $this->AddrAppend('From', $from); 
    8861107 
    887     /* sendmail and mail() extract Cc from the header before sending */ 
    888     if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) { 
     1108    // sendmail and mail() extract Cc from the header before sending 
     1109    if(count($this->cc) > 0) { 
    8891110      $result .= $this->AddrAppend('Cc', $this->cc); 
    8901111    } 
    8911112 
    892     /* sendmail and mail() extract Bcc from the header before sending */ 
     1113    // sendmail and mail() extract Bcc from the header before sending 
    8931114    if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) { 
    8941115      $result .= $this->AddrAppend('Bcc', $this->bcc); 
    8951116    } 
    8961117 
    8971118    if(count($this->ReplyTo) > 0) { 
    898       $result .= $this->AddrAppend('Reply-To', $this->ReplyTo); 
     1119      $result .= $this->AddrAppend('Reply-to', $this->ReplyTo); 
    8991120    } 
    9001121 
    901     /* mail() sets the subject itself */ 
     1122    // mail() sets the subject itself 
    9021123    if($this->Mailer != 'mail') { 
    9031124      $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject))); 
    9041125    } 
     
    9091130      $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); 
    9101131    } 
    9111132    $result .= $this->HeaderLine('X-Priority', $this->Priority); 
    912     $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.sourceforge.net) [version ' . $this->Version . ']'); 
     1133    $result .= $this->HeaderLine('X-Mailer', 'PHPMailer '.$this->Version.' (phpmailer.sourceforge.net)'); 
    9131134 
    9141135    if($this->ConfirmReadingTo != '') { 
    9151136      $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); 
     
    9291150 
    9301151  /** 
    9311152   * Returns the message MIME. 
    932    * @access private 
     1153   * @access public 
    9331154   * @return string 
    9341155   */ 
    935   function GetMailMIME() { 
     1156  public function GetMailMIME() { 
    9361157    $result = ''; 
    9371158    switch($this->message_type) { 
    9381159      case 'plain': 
     
    9401161        $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet); 
    9411162        break; 
    9421163      case 'attachments': 
    943         /* fall through */ 
    9441164      case 'alt_attachments': 
    9451165        if($this->InlineImageExists()){ 
    9461166          $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE); 
     
    9641184 
    9651185  /** 
    9661186   * Assembles the message body.  Returns an empty string on failure. 
    967    * @access private 
    968    * @return string 
     1187   * @access public 
     1188   * @return string The assembled message body 
    9691189   */ 
    970   function CreateBody() { 
    971     $result = ''; 
     1190  public function CreateBody() { 
     1191    $body = ''; 
     1192 
    9721193    if ($this->sign_key_file) { 
    973       $result .= $this->GetMailMIME(); 
     1194      $body .= $this->GetMailMIME(); 
    9741195    } 
    9751196 
    9761197    $this->SetWordWrap(); 
    9771198 
    9781199    switch($this->message_type) { 
    9791200      case 'alt': 
    980         $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); 
    981         $result .= $this->EncodeString($this->AltBody, $this->Encoding); 
    982         $result .= $this->LE.$this->LE; 
    983         $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', ''); 
    984         $result .= $this->EncodeString($this->Body, $this->Encoding); 
    985         $result .= $this->LE.$this->LE; 
    986         $result .= $this->EndBoundary($this->boundary[1]); 
     1201        $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); 
     1202        $body .= $this->EncodeString($this->AltBody, $this->Encoding); 
     1203        $body .= $this->LE.$this->LE; 
     1204        $body .= $this->GetBoundary($this->boundary[1], '', 'text/html', ''); 
     1205        $body .= $this->EncodeString($this->Body, $this->Encoding); 
     1206        $body .= $this->LE.$this->LE; 
     1207        $body .= $this->EndBoundary($this->boundary[1]); 
    9871208        break; 
    9881209      case 'plain': 
    989         $result .= $this->EncodeString($this->Body, $this->Encoding); 
     1210        $body .= $this->EncodeString($this->Body, $this->Encoding); 
    9901211        break; 
    9911212      case 'attachments': 
    992         $result .= $this->GetBoundary($this->boundary[1], '', '', ''); 
    993         $result .= $this->EncodeString($this->Body, $this->Encoding); 
    994         $result .= $this->LE; 
    995         $result .= $this->AttachAll(); 
     1213        $body .= $this->GetBoundary($this->boundary[1], '', '', ''); 
     1214        $body .= $this->EncodeString($this->Body, $this->Encoding); 
     1215        $body .= $this->LE; 
     1216        $body .= $this->AttachAll(); 
    9961217        break; 
    9971218      case 'alt_attachments': 
    998         $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); 
    999         $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE); 
    1000         $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body 
    1001         $result .= $this->EncodeString($this->AltBody, $this->Encoding); 
    1002         $result .= $this->LE.$this->LE; 
    1003         $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body 
    1004         $result .= $this->EncodeString($this->Body, $this->Encoding); 
    1005         $result .= $this->LE.$this->LE; 
    1006         $result .= $this->EndBoundary($this->boundary[2]); 
    1007         $result .= $this->AttachAll(); 
     1219        $body .= sprintf("--%s%s", $this->boundary[1], $this->LE); 
     1220        $body .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE); 
     1221        $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body 
     1222        $body .= $this->EncodeString($this->AltBody, $this->Encoding); 
     1223        $body .= $this->LE.$this->LE; 
     1224        $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body 
     1225        $body .= $this->EncodeString($this->Body, $this->Encoding); 
     1226        $body .= $this->LE.$this->LE; 
     1227        $body .= $this->EndBoundary($this->boundary[2]); 
     1228        $body .= $this->AttachAll(); 
    10081229        break; 
    10091230    } 
    10101231 
    1011     if($this->IsError()) { 
    1012       $result = ''; 
    1013     } else if ($this->sign_key_file) { 
    1014       $file = tempnam("", "mail"); 
    1015       $fp = fopen($file, "w"); 
    1016       fwrite($fp, $result); 
    1017       fclose($fp); 
    1018       $signed = tempnam("", "signed"); 
    1019  
    1020       if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) { 
    1021         $fp = fopen($signed, "r"); 
    1022         $result = fread($fp, filesize($this->sign_key_file)); 
    1023         $result = ''; 
    1024         while(!feof($fp)){ 
    1025           $result = $result . fread($fp, 1024); 
     1232    if ($this->IsError()) { 
     1233      $body = ''; 
     1234    } elseif ($this->sign_key_file) { 
     1235      try { 
     1236        $file = tempnam('', 'mail'); 
     1237        file_put_contents($file, $body); //TODO check this worked 
     1238        $signed = tempnam("", "signed"); 
     1239        if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), NULL)) { 
     1240          @unlink($file); 
     1241          @unlink($signed); 
     1242          $body = file_get_contents($signed); 
     1243        } else { 
     1244          @unlink($file); 
     1245          @unlink($signed); 
     1246          throw new phpmailerException($this->Lang("signing").openssl_error_string()); 
    10261247        } 
    1027         fclose($fp); 
    1028       } else { 
    1029         $this->SetError($this->Lang("signing").openssl_error_string()); 
    1030         $result = ''; 
     1248      } catch (phpmailerException $e) { 
     1249        $body = ''; 
     1250        if ($this->exceptions) { 
     1251          throw $e; 
     1252        } 
    10311253      } 
    1032  
    1033       unlink($file); 
    1034       unlink($signed); 
    10351254    } 
    10361255 
    1037     return $result; 
     1256    return $body; 
    10381257  } 
    10391258 
    10401259  /** 
    10411260   * Returns the start of a message boundary. 
    10421261   * @access private 
    10431262   */ 
    1044   function GetBoundary($boundary, $charSet, $contentType, $encoding) { 
     1263  private function GetBoundary($boundary, $charSet, $contentType, $encoding) { 
    10451264    $result = ''; 
    10461265    if($charSet == '') { 
    10471266      $charSet = $this->CharSet; 
     
    10651284   * Returns the end of a message boundary. 
    10661285   * @access private 
    10671286   */ 
    1068   function EndBoundary($boundary) { 
     1287  private function EndBoundary($boundary) { 
    10691288    return $this->LE . '--' . $boundary . '--' . $this->LE; 
    10701289  } 
    10711290 
     
    10741293   * @access private 
    10751294   * @return void 
    10761295   */ 
    1077   function SetMessageType() { 
     1296  private function SetMessageType() { 
    10781297    if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) { 
    10791298      $this->message_type = 'plain'; 
    10801299    } else { 
     
    10901309    } 
    10911310  } 
    10921311 
    1093   /* Returns a formatted header line. 
    1094    * @access private 
     1312  /** 
     1313   *  Returns a formatted header line. 
     1314   * @access public 
    10951315   * @return string 
    10961316   */ 
    1097   function HeaderLine($name, $value) { 
     1317  public function HeaderLine($name, $value) { 
    10981318    return $name . ': ' . $value . $this->LE; 
    10991319  } 
    11001320 
    11011321  /** 
    11021322   * Returns a formatted mail line. 
    1103    * @access private 
     1323   * @access public 
    11041324   * @return string 
    11051325   */ 
    1106   function TextLine($value) { 
     1326  public function TextLine($value) { 
    11071327    return $value . $this->LE; 
    11081328  } 
    11091329 
     
    11211341   * @param string $type File extension (MIME) type. 
    11221342   * @return bool 
    11231343   */ 
    1124   function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 
    1125     if(!@is_file($path)) { 
    1126       $this->SetError($this->Lang('file_access') . $path); 
    1127       return false; 
    1128     } 
     1344  public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 
     1345    try { 
     1346      if ( !@is_file($path) ) { 
     1347        throw new phpmailerException($this->Lang('file_access') . $path, self::STOP_CONTINUE); 
     1348      } 
     1349      $filename = basename($path); 
     1350      if ( $name == '' ) { 
     1351        $name = $filename; 
     1352      } 
    11291353 
    1130     $filename = basename($path); 
    1131     if($name == '') { 
    1132       $name = $filename; 
     1354      $this->attachment[] = array( 
     1355        0 => $path, 
     1356        1 => $filename, 
     1357        2 => $name, 
     1358        3 => $encoding, 
     1359        4 => $type, 
     1360        5 => false,  // isStringAttachment 
     1361        6 => 'attachment', 
     1362        7 => 0 
     1363      ); 
     1364 
     1365    } catch (phpmailerException $e) { 
     1366      $this->SetError($e->getMessage()); 
     1367      if ($this->exceptions) { 
     1368        throw $e; 
     1369      } 
     1370      echo $e->getMessage()."\n"; 
     1371      if ( $e->getCode() == self::STOP_CRITICAL ) { 
     1372        return false; 
     1373      } 
    11331374    } 
    1134  
    1135     $cur = count($this->attachment); 
    1136     $this->attachment[$cur][0] = $path; 
    1137     $this->attachment[$cur][1] = $filename; 
    1138     $this->attachment[$cur][2] = $name; 
    1139     $this->attachment[$cur][3] = $encoding; 
    1140     $this->attachment[$cur][4] = $type; 
    1141     $this->attachment[$cur][5] = false; // isStringAttachment 
    1142     $this->attachment[$cur][6] = 'attachment'; 
    1143     $this->attachment[$cur][7] = 0; 
    1144  
    11451375    return true; 
    11461376  } 
    11471377 
    11481378  /** 
     1379  * Return the current array of attachments 
     1380  * @return array 
     1381  */ 
     1382  public function GetAttachments() { 
     1383    return $this->attachment; 
     1384  } 
     1385 
     1386  /** 
    11491387   * Attaches all fs, string, and binary attachments to the message. 
    11501388   * Returns an empty string on failure. 
    11511389   * @access private 
    11521390   * @return string 
    11531391   */ 
    1154   function AttachAll() { 
    1155     /* Return text of body */ 
     1392  private function AttachAll() { 
     1393    // Return text of body 
    11561394    $mime = array(); 
     1395    $cidUniq = array(); 
     1396    $incl = array(); 
    11571397 
    1158     /* Add all attachments */ 
    1159     for($i = 0; $i < count($this->attachment); $i++) { 
    1160       /* Check for string attachment */ 
    1161       $bString = $this->attachment[$i][5]; 
     1398    // Add all attachments 
     1399    foreach ($this->attachment as $attachment) { 
     1400      // Check for string attachment 
     1401      $bString = $attachment[5]; 
    11621402      if ($bString) { 
    1163         $string = $this->attachment[$i][0]; 
     1403        $string = $attachment[0]; 
    11641404      } else { 
    1165         $path = $this->attachment[$i][0]; 
     1405        $path = $attachment[0]; 
    11661406      } 
    11671407 
    1168       $filename    = $this->attachment[$i][1]; 
    1169       $name        = $this->attachment[$i][2]; 
    1170       $encoding    = $this->attachment[$i][3]; 
    1171       $type        = $this->attachment[$i][4]; 
    1172       $disposition = $this->attachment[$i][6]; 
    1173       $cid         = $this->attachment[$i][7]; 
     1408      if (in_array($attachment[0], $incl)) { continue; } 
     1409      $filename    = $attachment[1]; 
     1410      $name        = $attachment[2]; 
     1411      $encoding    = $attachment[3]; 
     1412      $type        = $attachment[4]; 
     1413      $disposition = $attachment[6]; 
     1414      $cid         = $attachment[7]; 
     1415      $incl[]      = $attachment[0]; 
     1416      if ( $disposition == 'inline' && isset($cidUniq[$cid]) ) { continue; } 
     1417      $cidUniq[$cid] = true; 
    11741418 
    11751419      $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); 
    11761420      $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE); 
     
    11821426 
    11831427      $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE); 
    11841428 
    1185       /* Encode as string attachment */ 
     1429      // Encode as string attachment 
    11861430      if($bString) { 
    11871431        $mime[] = $this->EncodeString($string, $encoding); 
    11881432        if($this->IsError()) { 
     
    12041448  } 
    12051449 
    12061450  /** 
    1207    * Encodes attachment in requested format.  Returns an 
    1208    * empty string on failure. 
     1451   * Encodes attachment in requested format. 
     1452   * Returns an empty string on failure. 
     1453   * @param string $path The full path to the file 
     1454   * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' 
     1455   * @see EncodeFile() 
    12091456   * @access private 
    12101457   * @return string 
    12111458   */ 
    1212   function EncodeFile ($path, $encoding = 'base64') { 
    1213     if(!@$fd = fopen($path, 'rb')) { 
    1214       $this->SetError($this->Lang('file_open') . $path); 
     1459  private function EncodeFile($path, $encoding = 'base64') { 
     1460    try { 
     1461      if (!is_readable($path)) { 
     1462        throw new phpmailerException($this->Lang('file_open') . $path, self::STOP_CONTINUE); 
     1463      } 
     1464      if (function_exists('get_magic_quotes')) { 
     1465        function get_magic_quotes() { 
     1466          return false; 
     1467        } 
     1468      } 
     1469      if (PHP_VERSION < 6) { 
     1470        $magic_quotes = get_magic_quotes_runtime(); 
     1471        set_magic_quotes_runtime(0); 
     1472      } 
     1473      $file_buffer  = file_get_contents($path); 
     1474      $file_buffer  = $this->EncodeString($file_buffer, $encoding); 
     1475      if (PHP_VERSION < 6) { set_magic_quotes_runtime($magic_quotes); } 
     1476      return $file_buffer; 
     1477    } catch (Exception $e) { 
     1478      $this->SetError($e->getMessage()); 
    12151479      return ''; 
    12161480    } 
    1217     $magic_quotes = get_magic_quotes_runtime(); 
    1218     set_magic_quotes_runtime(0); 
    1219     $file_buffer = fread($fd, filesize($path)); 
    1220     $file_buffer = $this->EncodeString($file_buffer, $encoding); 
    1221     fclose($fd); 
    1222     set_magic_quotes_runtime($magic_quotes); 
    1223  
    1224     return $file_buffer; 
    12251481  } 
    12261482 
    12271483  /** 
    1228    * Encodes string to requested format. Returns an 
    1229    * empty string on failure. 
    1230    * @access private 
     1484   * Encodes string to requested format. 
     1485   * Returns an empty string on failure. 
     1486   * @param string $str The text to encode 
     1487   * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' 
     1488   * @access public 
    12311489   * @return string 
    12321490   */ 
    1233   function EncodeString ($str, $encoding = 'base64') { 
     1491  public function EncodeString ($str, $encoding = 'base64') { 
    12341492    $encoded = ''; 
    12351493    switch(strtolower($encoding)) { 
    12361494      case 'base64': 
    1237         /* chunk_split is found in PHP >= 3.0.6 */ 
    12381495        $encoded = chunk_split(base64_encode($str), 76, $this->LE); 
    12391496        break; 
    12401497      case '7bit': 
    12411498      case '8bit': 
    12421499        $encoded = $this->FixEOL($str); 
     1500        //Make sure it ends with a line break 
    12431501        if (substr($encoded, -(strlen($this->LE))) != $this->LE) 
    12441502          $encoded .= $this->LE; 
    12451503        break; 
     
    12571515  } 
    12581516 
    12591517  /** 
    1260    * Encode a header string to best of Q, B, quoted or none. 
    1261    * @access private 
     1518   * Encode a header string to best (shortest) of Q, B, quoted or none. 
     1519   * @access public 
    12621520   * @return string 
    12631521   */ 
    1264   function EncodeHeader ($str, $position = 'text') { 
     1522  public function EncodeHeader($str, $position = 'text') { 
    12651523    $x = 0; 
    12661524 
    12671525    switch (strtolower($position)) { 
    12681526      case 'phrase': 
    12691527        if (!preg_match('/[\200-\377]/', $str)) { 
    1270           /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */ 
     1528          // Can't use addslashes as we don't know what value has magic_quotes_sybase 
    12711529          $encoded = addcslashes($str, "\0..\37\177\\\""); 
    12721530          if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { 
    12731531            return ($encoded); 
     
    12791537        break; 
    12801538      case 'comment': 
    12811539        $x = preg_match_all('/[()"]/', $str, $matches); 
    1282         /* Fall-through */ 
     1540        // Fall-through 
    12831541      case 'text': 
    12841542      default: 
    12851543        $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); 
     
    12911549    } 
    12921550 
    12931551    $maxlen = 75 - 7 - strlen($this->CharSet); 
    1294     /* Try to select the encoding which should produce the shortest output */ 
     1552    // Try to select the encoding which should produce the shortest output 
    12951553    if (strlen($str)/3 < $x) { 
    12961554      $encoding = 'B'; 
    12971555      if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) { 
    1298      // Use a custom function which correctly encodes and wraps long 
    1299      // multibyte strings without breaking lines within a character 
     1556        // Use a custom function which correctly encodes and wraps long 
     1557        // multibyte strings without breaking lines within a character 
    13001558        $encoded = $this->Base64EncodeWrapMB($str); 
    13011559      } else { 
    13021560        $encoded = base64_encode($str); 
     
    13181576 
    13191577  /** 
    13201578   * Checks if a string contains multibyte characters. 
    1321    * @access private 
     1579   * @access public 
    13221580   * @param string $str multi-byte text to wrap encode 
    13231581   * @return bool 
    13241582   */ 
    1325   function HasMultiBytes($str) { 
     1583  public function HasMultiBytes($str) { 
    13261584    if (function_exists('mb_strlen')) { 
    13271585      return (strlen($str) > mb_strlen($str, $this->CharSet)); 
    13281586    } else { // Assume no multibytes (we can't handle without mbstring functions anyway) 
    1329       return False; 
     1587      return false; 
    13301588    } 
    13311589  } 
    13321590 
     
    13341592   * Correctly encodes and wraps long multibyte strings for mail headers 
    13351593   * without breaking lines within a character. 
    13361594   * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php 
    1337    * @access private 
     1595   * @access public 
    13381596   * @param string $str multi-byte text to wrap encode 
    13391597   * @return string 
    13401598   */ 
    1341   function Base64EncodeWrapMB($str) { 
     1599  public function Base64EncodeWrapMB($str) { 
    13421600    $start = "=?".$this->CharSet."?B?"; 
    13431601    $end = "?="; 
    13441602    $encoded = ""; 
     
    13711629  } 
    13721630 
    13731631  /** 
    1374    * Encode string to quoted-printable. 
    1375    * @access private 
    1376    * @return string 
    1377    */ 
    1378   function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) { 
     1632  * Encode string to quoted-printable. 
     1633  * Only uses standard PHP, slow, but will always work 
     1634  * @access public 
     1635  * @param string $string the text to encode 
     1636  * @param integer $line_max Number of chars allowed on a line before wrapping 
     1637  * @return string 
     1638  */ 
     1639  public function EncodeQPphp( $input = '', $line_max = 76, $space_conv = false) { 
    13791640    $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); 
    13801641    $lines = preg_split('/(?:\r\n|\r|\n)/', $input); 
    13811642    $eol = "\r\n"; 
     
    14171678  } 
    14181679 
    14191680  /** 
    1420    * Callback for converting to "=XX". 
    1421    * @access private 
    1422    * @return string 
    1423    */ 
    1424   function EncodeQ_callback ($matches) { 
    1425     return sprintf('=%02X', ord($matches[1])); 
     1681  * Encode string to RFC2045 (6.7) quoted-printable format 
     1682  * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version 
     1683  * Also results in same content as you started with after decoding 
     1684  * @see EncodeQPphp() 
     1685  * @access public 
     1686  * @param string $string the text to encode 
     1687  * @param integer $line_max Number of chars allowed on a line before wrapping 
     1688  * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function 
     1689  * @return string 
     1690  * @author Marcus Bointon 
     1691  */ 
     1692  public function EncodeQP($string, $line_max = 76, $space_conv = false) { 
     1693    if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3) 
     1694      return quoted_printable_encode($string); 
     1695    } 
     1696    $filters = stream_get_filters(); 
     1697    if (!in_array('convert.*', $filters)) { //Got convert stream filter? 
     1698      return $this->EncodeQPphp($string, $line_max, $space_conv); //Fall back to old implementation 
     1699    } 
     1700    $fp = fopen('php://temp/', 'r+'); 
     1701    $string = preg_replace('/\r\n?/', $this->LE, $string); //Normalise line breaks 
     1702    $params = array('line-length' => $line_max, 'line-break-chars' => $this->LE); 
     1703    $s = stream_filter_append($fp, 'convert.quoted-printable-encode', STREAM_FILTER_READ, $params); 
     1704    fputs($fp, $string); 
     1705    rewind($fp); 
     1706    $out = stream_get_contents($fp); 
     1707    stream_filter_remove($s); 
     1708    $out = preg_replace('/^\./m', '=2E', $out); //Encode . if it is first char on a line, workaround for bug in Exchange 
     1709    fclose($fp); 
     1710    return $out; 
    14261711  } 
    14271712 
    14281713  /** 
    14291714   * Encode string to q encoding. 
    1430    * @access private 
     1715   * @link http://tools.ietf.org/html/rfc2047 
     1716   * @param string $str the text to encode 
     1717   * @param string $position Where the text is going to be used, see the RFC for what that means 
     1718   * @access public 
    14311719   * @return string 
    14321720   */ 
    1433   function EncodeQ ($str, $position = 'text') { 
    1434     /* There should not be any EOL in the string */ 
    1435     $encoded = preg_replace("/[\r\n]/", '', $str); 
     1721  public function EncodeQ ($str, $position = 'text') { 
     1722    // There should not be any EOL in the string 
     1723    $encoded = preg_replace('/[\r\n]*/', '', $str); 
    14361724 
    14371725    switch (strtolower($position)) { 
    14381726      case 'phrase': 
    1439         $encoded = preg_replace_callback("/([^A-Za-z0-9!*+\/ -])/", 
    1440                                          array('PHPMailer', 'EncodeQ_callback'), $encoded); 
     1727        $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 
    14411728        break; 
    14421729      case 'comment': 
    1443         $encoded = preg_replace_callback("/([\(\)\"])/", 
    1444                                          array('PHPMailer', 'EncodeQ_callback'), $encoded); 
    1445         break; 
     1730        $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 
    14461731      case 'text': 
    14471732      default: 
    1448         /* Replace every high ascii, control =, ? and _ characters */ 
    1449         $encoded = preg_replace_callback('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/', 
    1450                                          array('PHPMailer', 'EncodeQ_callback'), $encoded); 
     1733        // Replace every high ascii, control =, ? and _ characters 
     1734        //TODO using /e (equivalent to eval()) is probably not a good idea 
     1735        $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', 
     1736              "'='.sprintf('%02X', ord('\\1'))", $encoded); 
    14511737        break; 
    14521738    } 
    14531739 
    1454     /* Replace every spaces to _ (more readable than =20) */ 
     1740    // Replace every spaces to _ (more readable than =20) 
    14551741    $encoded = str_replace(' ', '_', $encoded); 
    14561742 
    14571743    return $encoded; 
     
    14671753   * @param string $type File extension (MIME) type. 
    14681754   * @return void 
    14691755   */ 
    1470   function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') { 
    1471     /* Append to $attachment array */ 
    1472     $cur = count($this->attachment); 
    1473     $this->attachment[$cur][0] = $string; 
    1474     $this->attachment[$cur][1] = $filename; 
    1475     $this->attachment[$cur][2] = $filename; 
    1476     $this->attachment[$cur][3] = $encoding; 
    1477     $this->attachment[$cur][4] = $type; 
    1478     $this->attachment[$cur][5] = true; // isString 
    1479     $this->attachment[$cur][6] = 'attachment'; 
    1480     $this->attachment[$cur][7] = 0; 
     1756  public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') { 
     1757    // Append to $attachment array 
     1758    $this->attachment[] = array( 
     1759      0 => $string, 
     1760      1 => $filename, 
     1761      2 => basename($filename), 
     1762      3 => $encoding, 
     1763      4 => $type, 
     1764      5 => true,  // isStringAttachment 
     1765      6 => 'attachment', 
     1766      7 => 0 
     1767    ); 
    14811768  } 
    14821769 
    14831770  /** 
     
    14931780   * @param string $type File extension (MIME) type. 
    14941781   * @return bool 
    14951782   */ 
    1496   function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 
     1783  public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 
    14971784 
    1498     if(!@is_file($path)) { 
     1785    if ( !@is_file($path) ) { 
    14991786      $this->SetError($this->Lang('file_access') . $path); 
    15001787      return false; 
    15011788    } 
    15021789 
    15031790    $filename = basename($path); 
    1504     if($name == '') { 
     1791    if ( $name == '' ) { 
    15051792      $name = $filename; 
    15061793    } 
    15071794 
    1508     /* Append to $attachment array */ 
    1509     $cur = count($this->attachment); 
    1510     $this->attachment[$cur][0] = $path; 
    1511     $this->attachment[$cur][1] = $filename; 
    1512     $this->attachment[$cur][2] = $name; 
    1513     $this->attachment[$cur][3] = $encoding; 
    1514     $this->attachment[$cur][4] = $type; 
    1515     $this->attachment[$cur][5] = false; 
    1516     $this->attachment[$cur][6] = 'inline'; 
    1517     $this->attachment[$cur][7] = $cid; 
     1795    // Append to $attachment array 
     1796    $this->attachment[] = array( 
     1797      0 => $path, 
     1798      1 => $filename, 
     1799      2 => $name, 
     1800      3 => $encoding, 
     1801      4 => $type, 
     1802      5 => false,  // isStringAttachment 
     1803      6 => 'inline', 
     1804      7 => $cid 
     1805    ); 
    15181806 
    15191807    return true; 
    15201808  } 
    15211809 
    15221810  /** 
    15231811   * Returns true if an inline attachment is present. 
    1524    * @access private 
     1812   * @access public 
    15251813   * @return bool 
    15261814   */ 
    1527   function InlineImageExists() { 
    1528     $result = false; 
    1529     for($i = 0; $i < count($this->attachment); $i++) { 
    1530       if($this->attachment[$i][6] == 'inline') { 
    1531         $result = true; 
    1532         break; 
     1815  public function InlineImageExists() { 
     1816    foreach($this->attachment as $attachment) { 
     1817      if ($attachment[6] == 'inline') { 
     1818        return true; 
    15331819      } 
    15341820    } 
    1535  
    1536     return $result; 
     1821    return false; 
    15371822  } 
    15381823 
    15391824  ///////////////////////////////////////////////// 
     
    15441829   * Clears all recipients assigned in the TO array.  Returns void. 
    15451830   * @return void 
    15461831   */ 
    1547   function ClearAddresses() { 
     1832  public function ClearAddresses() { 
     1833    foreach($this->to as $to) { 
     1834      unset($this->all_recipients[strtolower($to[0])]); 
     1835    } 
    15481836    $this->to = array(); 
    15491837  } 
    15501838 
     
    15521840   * Clears all recipients assigned in the CC array.  Returns void. 
    15531841   * @return void 
    15541842   */ 
    1555   function ClearCCs() { 
     1843  public function ClearCCs() { 
     1844    foreach($this->cc as $cc) { 
     1845      unset($this->all_recipients[strtolower($cc[0])]); 
     1846    } 
    15561847    $this->cc = array(); 
    15571848  } 
    15581849 
     
    15601851   * Clears all recipients assigned in the BCC array.  Returns void. 
    15611852   * @return void 
    15621853   */ 
    1563   function ClearBCCs() { 
     1854  public function ClearBCCs() { 
     1855    foreach($this->bcc as $bcc) { 
     1856      unset($this->all_recipients[strtolower($bcc[0])]); 
     1857    } 
    15641858    $this->bcc = array(); 
    15651859  } 
    15661860 
     
    15681862   * Clears all recipients assigned in the ReplyTo array.  Returns void. 
    15691863   * @return void 
    15701864   */ 
    1571   function ClearReplyTos() { 
     1865  public function ClearReplyTos() { 
    15721866    $this->ReplyTo = array(); 
    15731867  } 
    15741868 
     
    15771871   * array.  Returns void. 
    15781872   * @return void 
    15791873   */ 
    1580   function ClearAllRecipients() { 
     1874  public function ClearAllRecipients() { 
    15811875    $this->to = array(); 
    15821876    $this->cc = array(); 
    15831877    $this->bcc = array(); 
     1878    $this->all_recipients = array(); 
    15841879  } 
    15851880 
    15861881  /** 
     
    15881883   * attachments.  Returns void. 
    15891884   * @return void 
    15901885   */ 
    1591   function ClearAttachments() { 
     1886  public function ClearAttachments() { 
    15921887    $this->attachment = array(); 
    15931888  } 
    15941889 
     
    15961891   * Clears all custom headers.  Returns void. 
    15971892   * @return void 
    15981893   */ 
    1599   function ClearCustomHeaders() { 
     1894  public function ClearCustomHeaders() { 
    16001895    $this->CustomHeader = array(); 
    16011896  } 
    16021897 
     
    16061901 
    16071902  /** 
    16081903   * Adds the error message to the error container. 
    1609    * Returns void. 
    1610    * @access private 
     1904   * @access protected 
    16111905   * @return void 
    16121906   */ 
    1613   function SetError($msg) { 
     1907  protected function SetError($msg) { 
    16141908    $this->error_count++; 
     1909    if ($this->Mailer == 'smtp' and !is_null($this->smtp)) { 
     1910      $lasterror = $this->smtp->getError(); 
     1911      if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) { 
     1912        $msg .= '<p>' . $this->Lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n"; 
     1913      } 
     1914    } 
    16151915    $this->ErrorInfo = $msg; 
    16161916  } 
    16171917 
    16181918  /** 
    16191919   * Returns the proper RFC 822 formatted date. 
    1620    * @access private 
     1920   * @access public 
    16211921   * @return string 
     1922   * @static 
    16221923   */ 
    1623   function RFCDate() { 
     1924  public static function RFCDate() { 
    16241925    $tz = date('Z'); 
    16251926    $tzs = ($tz < 0) ? '-' : '+'; 
    16261927    $tz = abs($tz); 
     
    16311932  } 
    16321933 
    16331934  /** 
    1634    * Returns the appropriate server variable.  Should work with both 
    1635    * PHP 4.1.0+ as well as older versions.  Returns an empty string 
    1636    * if nothing is found. 
    1637    * @access private 
    1638    * @return mixed 
    1639    */ 
    1640   function ServerVar($varName) { 
    1641     global $HTTP_SERVER_VARS; 
    1642     global $HTTP_ENV_VARS; 
    1643  
    1644     if(!isset($_SERVER)) { 
    1645       $_SERVER = $HTTP_SERVER_VARS; 
    1646       if(!isset($_SERVER['REMOTE_ADDR'])) { 
    1647         $_SERVER = $HTTP_ENV_VARS; // must be Apache 
    1648       } 
    1649     } 
    1650  
    1651     if(isset($_SERVER[$varName])) { 
    1652       return $_SERVER[$varName]; 
    1653     } else { 
    1654       return ''; 
    1655     } 
    1656   } 
    1657  
    1658   /** 
    16591935   * Returns the server hostname or 'localhost.localdomain' if unknown. 
    16601936   * @access private 
    16611937   * @return string 
    16621938   */ 
    1663   function ServerHostname() { 
    1664     if ($this->Hostname != '') { 
     1939  private function ServerHostname() { 
     1940    if (!empty($this->Hostname)) { 
    16651941      $result = $this->Hostname; 
    1666     } elseif ($this->ServerVar('SERVER_NAME') != '') { 
    1667       $result = $this->ServerVar('SERVER_NAME'); 
     1942    } elseif (isset($_SERVER['SERVER_NAME'])) { 
     1943      $result = $_SERVER['SERVER_NAME']; 
    16681944    } else { 
    16691945      $result = 'localhost.localdomain'; 
    16701946    } 
     
    16771953   * @access private 
    16781954   * @return string 
    16791955   */ 
    1680   function Lang($key) { 
     1956  private function Lang($key) { 
    16811957    if(count($this->language) < 1) { 
    16821958      $this->SetLanguage('en'); // set the default language 
    16831959    } 
     
    16911967 
    16921968  /** 
    16931969   * Returns true if an error occurred. 
     1970   * @access public 
    16941971   * @return bool 
    16951972   */ 
    1696   function IsError() { 
     1973  public function IsError() { 
    16971974    return ($this->error_count > 0); 
    16981975  } 
    16991976 
     
    17021979   * @access private 
    17031980   * @return string 
    17041981   */ 
    1705   function FixEOL($str) { 
     1982  private function FixEOL($str) { 
    17061983    $str = str_replace("\r\n", "\n", $str); 
    17071984    $str = str_replace("\r", "\n", $str); 
    17081985    $str = str_replace("\n", $this->LE, $str); 
     
    17111988 
    17121989  /** 
    17131990   * Adds a custom header. 
     1991   * @access public 
    17141992   * @return void 
    17151993   */ 
    1716   function AddCustomHeader($custom_header) { 
     1994  public function AddCustomHeader($custom_header) { 
    17171995    $this->CustomHeader[] = explode(':', $custom_header, 2); 
    17181996  } 
    17191997 
     
    17222000   * @access public 
    17232001   * @return $message 
    17242002   */ 
    1725   function MsgHTML($message,$basedir='') { 
     2003  public function MsgHTML($message, $basedir = '') { 
    17262004    preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images); 
    17272005    if(isset($images[2])) { 
    17282006      foreach($images[2] as $i => $url) { 
    17292007        // do not change urls for absolute images (thanks to corvuscorax) 
    1730         if (!preg_match('/^[A-z][A-z]*:\/\//',$url)) { 
     2008        if (!preg_match('#^[A-z]+://#',$url)) { 
    17312009          $filename = basename($url); 
    17322010          $directory = dirname($url); 
    17332011          ($directory == '.')?$directory='':''; 
    17342012          $cid = 'cid:' . md5($filename); 
    1735           $fileParts = split("\.", $filename); 
    1736           $ext = $fileParts[1]; 
    1737           $mimeType = $this->_mime_types($ext); 
     2013          $ext = pathinfo($filename, PATHINFO_EXTENSION); 
     2014          $mimeType  = self::_mime_types($ext); 
    17382015          if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; } 
    17392016          if ( strlen($directory) > 1 && substr($directory,-1) != '/') { $directory .= '/'; } 
    17402017          if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) { 
     
    17462023    $this->IsHTML(true); 
    17472024    $this->Body = $message; 
    17482025    $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message))); 
    1749     if ( !empty($textMsg) && empty($this->AltBody) ) { 
     2026    if (!empty($textMsg) && empty($this->AltBody)) { 
    17502027      $this->AltBody = html_entity_decode($textMsg); 
    17512028    } 
    1752     if ( empty($this->AltBody) ) { 
    1753       $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . "\n\n"; 
     2029    if (empty($this->AltBody)) { 
     2030      $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n"; 
    17542031    } 
    17552032  } 
    17562033 
    17572034  /** 
    1758    * Gets the mime type of the embedded or inline image 
    1759    * @access private 
    1760    * @return mime type of ext 
     2035   * Gets the MIME type of the embedded or inline image 
     2036   * @param string File extension 
     2037   * @access public 
     2038   * @return string MIME type of ext 
     2039   * @static 
    17612040   */ 
    1762   function _mime_types($ext = '') { 
     2041  public static function _mime_types($ext = '') { 
    17632042    $mimes = array( 
    1764       'ai'    =>  'application/postscript', 
    1765       'aif'   =>  'audio/x-aiff', 
    1766       'aifc'  =>  'audio/x-aiff', 
    1767       'aiff'  =>  'audio/x-aiff', 
    1768       'avi'   =>  'video/x-msvideo', 
     2043      'hqx'   =>  'application/mac-binhex40', 
     2044      'cpt'   =>  'application/mac-compactpro', 
     2045      'doc'   =>  'application/msword', 
    17692046      'bin'   =>  'application/macbinary', 
    1770       'bmp'   =>  'image/bmp', 
     2047      'dms'   =>  'application/octet-stream', 
     2048      'lha'   =>  'application/octet-stream', 
     2049      'lzh'   =>  'application/octet-stream', 
     2050      'exe'   =>  'application/octet-stream', 
    17712051      'class' =>  'application/octet-stream', 
    1772       'cpt'   =>  'application/mac-compactpro', 
    1773       'css'   =>  'text/css', 
     2052      'psd'   =>  'application/octet-stream', 
     2053      'so'    =>  'application/octet-stream', 
     2054      'sea'   =>  'application/octet-stream', 
     2055      'dll'   =>  'application/octet-stream', 
     2056      'oda'   =>  'application/oda', 
     2057      'pdf'   =>  'application/pdf', 
     2058      'ai'    =>  'application/postscript', 
     2059      'eps'   =>  'application/postscript', 
     2060      'ps'    =>  'application/postscript', 
     2061      'smi'   =>  'application/smil', 
     2062      'smil'  =>  'application/smil', 
     2063      'mif'   =>  'application/vnd.mif', 
     2064      'xls'   =>  'application/vnd.ms-excel', 
     2065      'ppt'   =>  'application/vnd.ms-powerpoint', 
     2066      'wbxml' =>  'application/vnd.wap.wbxml', 
     2067      'wmlc'  =>  'application/vnd.wap.wmlc', 
    17742068      'dcr'   =>  'application/x-director', 
    17752069      'dir'   =>  'application/x-director', 
    1776       'dll'   =>  'application/octet-stream', 
    1777       'dms'   =>  'application/octet-stream', 
    1778       'doc'   =>  'application/msword', 
     2070      'dxr'   =>  'application/x-director', 
    17792071      'dvi'   =>  'application/x-dvi', 
    1780       'dxr'   =>  'application/x-director', 
    1781       'eml'   =>  'message/rfc822', 
    1782       'eps'   =>  'application/postscript', 
    1783       'exe'   =>  'application/octet-stream', 
    1784       'gif'   =>  'image/gif', 
    17852072      'gtar'  =>  'application/x-gtar', 
    1786       'htm'   =>  'text/html', 
    1787       'html'  =>  'text/html', 
    1788       'jpe'   =>  'image/jpeg', 
    1789       'jpeg'  =>  'image/jpeg', 
    1790       'jpg'   =>  'image/jpeg', 
    1791       'hqx'   =>  'application/mac-binhex40', 
     2073      'php'   =>  'application/x-httpd-php', 
     2074      'php4'  =>  'application/x-httpd-php', 
     2075      'php3'  =>  'application/x-httpd-php', 
     2076      'phtml' =>  'application/x-httpd-php', 
     2077      'phps'  =>  'application/x-httpd-php-source', 
    17922078      'js'    =>  'application/x-javascript', 
    1793       'lha'   =>  'application/octet-stream', 
    1794       'log'   =>  'text/plain', 
    1795       'lzh'   =>  'application/octet-stream', 
     2079      'swf'   =>  'application/x-shockwave-flash', 
     2080      'sit'   =>  'application/x-stuffit', 
     2081      'tar'   =>  'application/x-tar', 
     2082      'tgz'   =>  'application/x-tar', 
     2083      'xhtml' =>  'application/xhtml+xml', 
     2084      'xht'   =>  'application/xhtml+xml', 
     2085      'zip'   =>  'application/zip', 
    17962086      'mid'   =>  'audio/midi', 
    17972087      'midi'  =>  'audio/midi', 
    1798       'mif'   =>  'application/vnd.mif', 
    1799       'mov'   =>  'video/quicktime', 
    1800       'movie' =>  'video/x-sgi-movie', 
     2088      'mpga'  =>  'audio/mpeg', 
    18012089      'mp2'   =>  'audio/mpeg', 
    18022090      'mp3'   =>  'audio/mpeg', 
    1803       'mpe'   =>  'video/mpeg', 
    1804       'mpeg'  =>  'video/mpeg', 
    1805       'mpg'   =>  'video/mpeg', 
    1806       'mpga'  =>  'audio/mpeg', 
    1807       'oda'   =>  'application/oda', 
    1808       'pdf'   =>  'application/pdf', 
    1809       'php'   =>  'application/x-httpd-php', 
    1810       'php3'  =>  'application/x-httpd-php', 
    1811       'php4'  =>  'application/x-httpd-php', 
    1812       'phps'  =>  'application/x-httpd-php-source', 
    1813       'phtml' =>  'application/x-httpd-php', 
    1814       'png'   =>  'image/png', 
    1815       'ppt'   =>  'application/vnd.ms-powerpoint', 
    1816       'ps'    =>  'application/postscript', 
    1817       'psd'   =>  'application/octet-stream', 
    1818       'qt'    =>  'video/quicktime', 
    1819       'ra'    =>  'audio/x-realaudio', 
     2091      'aif'   =>  'audio/x-aiff', 
     2092      'aiff'  =>  'audio/x-aiff', 
     2093      'aifc'  =>  'audio/x-aiff', 
    18202094      'ram'   =>  'audio/x-pn-realaudio', 
    18212095      'rm'    =>  'audio/x-pn-realaudio', 
    18222096      'rpm'   =>  'audio/x-pn-realaudio-plugin', 
    1823       'rtf'   =>  'text/rtf', 
    1824       'rtx'   =>  'text/richtext', 
     2097      'ra'    =>  'audio/x-realaudio', 
    18252098      'rv'    =>  'video/vnd.rn-realvideo', 
    1826       'sea'   =>  'application/octet-stream', 
     2099      'wav'   =>  'audio/x-wav', 
     2100      'bmp'   =>  'image/bmp', 
     2101      'gif'   =>  'image/gif', 
     2102      'jpeg'  =>  'image/jpeg', 
     2103      'jpg'   =>  'image/jpeg', 
     2104      'jpe'   =>  'image/jpeg', 
     2105      'png'   =>  'image/png', 
     2106      'tiff'  =>  'image/tiff', 
     2107      'tif'   =>  'image/tiff', 
     2108      'css'   =>  'text/css', 
     2109      'html'  =>  'text/html', 
     2110      'htm'   =>  'text/html', 
    18272111      'shtml' =>  'text/html', 
    1828       'sit'   =>  'application/x-stuffit', 
    1829       'so'    =>  'application/octet-stream', 
    1830       'smi'   =>  'application/smil', 
    1831       'smil'  =>  'application/smil', 
    1832       'swf'   =>  'application/x-shockwave-flash', 
    1833       'tar'   =>  'application/x-tar', 
     2112      'txt'   =>  'text/plain', 
    18342113      'text'  =>  'text/plain', 
    1835       'txt'   =>  'text/plain', 
    1836       'tgz'   =>  'application/x-tar', 
    1837       'tif'   =>  'image/tiff', 
    1838       'tiff'  =>  'image/tiff', 
    1839       'wav'   =>  'audio/x-wav', 
    1840       'wbxml' =>  'application/vnd.wap.wbxml', 
    1841       'wmlc'  =>  'application/vnd.wap.wmlc', 
     2114      'log'   =>  'text/plain', 
     2115      'rtx'   =>  'text/richtext', 
     2116      'rtf'   =>  'text/rtf', 
     2117      'xml'   =>  'text/xml', 
     2118      'xsl'   =>  'text/xml', 
     2119      'mpeg'  =>  'video/mpeg', 
     2120      'mpg'   =>  'video/mpeg', 
     2121      'mpe'   =>  'video/mpeg', 
     2122      'qt'    =>  'video/quicktime', 
     2123      'mov'   =>  'video/quicktime', 
     2124      'avi'   =>  'video/x-msvideo', 
     2125      'movie' =>  'video/x-sgi-movie', 
     2126      'doc'   =>  'application/msword', 
    18422127      'word'  =>  'application/msword', 
    1843       'xht'   =>  'application/xhtml+xml', 
    1844       'xhtml' =>  'application/xhtml+xml', 
    18452128      'xl'    =>  'application/excel', 
    1846       'xls'   =>  'application/vnd.ms-excel', 
    1847       'xml'   =>  'text/xml', 
    1848       'xsl'   =>  'text/xml', 
    1849       'zip'   =>  'application/zip' 
     2129      'eml'   =>  'message/rfc822' 
    18502130    ); 
    1851     return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; 
     2131    return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; 
    18522132  } 
    18532133 
    18542134  /** 
    1855    * Set (or reset) Class Objects (variables) 
     2135  * Set (or reset) Class Objects (variables) 
     2136  * 
     2137  * Usage Example: 
     2138  * $page->set('X-Priority', '3'); 
     2139  * 
     2140  * @access public 
     2141  * @param string $name Parameter Name 
     2142  * @param mixed $value Parameter Value 
     2143  * NOTE: will not work with arrays, there are no arrays to set/reset 
     2144  * @todo Should this not be using __set() magic function? 
     2145  */ 
     2146  public function set($name, $value = '') { 
     2147    try { 
     2148      if (isset($this->$name) ) { 
     2149        $this->$name = $value; 
     2150      } else { 
     2151        throw new phpmailerException($this->Lang('variable_set') . $name, self::STOP_CRITICAL); 
     2152      } 
     2153    } catch (Exception $e) { 
     2154      $this->SetError($e->getMessage()); 
     2155      if ($e->getCode() == self::STOP_CRITICAL) { 
     2156        return false; 
     2157      } 
     2158    } 
     2159    return true; 
     2160  } 
     2161 
     2162  /** 
     2163   * Strips newlines to prevent header injection. 
     2164   * @access public 
     2165   * @param string $str String 
     2166   * @return string 
     2167   */ 
     2168  public function SecureHeader($str) { 
     2169    $str = str_replace("\r", '', $str); 
     2170    $str = str_replace("\n", '', $str); 
     2171    return trim($str); 
     2172  } 
     2173 
     2174  /** 
     2175   * Set the private key file and password to sign the message. 
    18562176   * 
    1857    * Usage Example: 
    1858    * $page->set('X-Priority', '3'); 
     2177   * @access public 
     2178   * @param string $key_filename Parameter File Name 
     2179   * @param string $key_pass Password for private key 
     2180   */ 
     2181  public function Sign($cert_filename, $key_filename, $key_pass) { 
     2182    $this->sign_cert_file = $cert_filename; 
     2183    $this->sign_key_file = $key_filename; 
     2184    $this->sign_key_pass = $key_pass; 
     2185  } 
     2186 
     2187  /** 
     2188   * Set the private key file and password to sign the message. 
    18592189   * 
    18602190   * @access public 
    1861    * @param string $name Parameter Name 
    1862    * @param mixed $value Parameter Value 
    1863    * NOTE: will not work with arrays, there are no arrays to set/reset 
     2191   * @param string $key_filename Parameter File Name 
     2192   * @param string $key_pass Password for private key 
    18642193   */ 
    1865   function set ( $name, $value = '' ) { 
    1866     if ( isset($this->$name) ) { 
    1867       $this->$name = $value; 
    1868     } else { 
    1869       $this->SetError('Cannot set or reset variable ' . $name); 
    1870       return false; 
     2194  public function DKIM_QP($txt) { 
     2195    $tmp=""; 
     2196    $line=""; 
     2197    for ($i=0;$i<strlen($txt);$i++) { 
     2198      $ord=ord($txt[$i]); 
     2199      if ( ((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E)) ) { 
     2200        $line.=$txt[$i]; 
     2201      } else { 
     2202        $line.="=".sprintf("%02X",$ord); 
     2203      } 
    18712204    } 
     2205    return $line; 
    18722206  } 
    18732207 
    18742208  /** 
    1875    * Read a file from a supplied filename and return it. 
     2209   * Generate DKIM signature 
    18762210   * 
    18772211   * @access public 
    1878    * @param string $filename Parameter File Name 
     2212   * @param string $s Header 
    18792213   */ 
    1880   function getFile($filename) { 
    1881     $return = ''; 
    1882     if ($fp = fopen($filename, 'rb')) { 
    1883       while (!feof($fp)) { 
    1884         $return .= fread($fp, 1024); 
    1885       } 
    1886       fclose($fp); 
    1887       return $return; 
     2214  public function DKIM_Sign($s) { 
     2215    $privKeyStr = file_get_contents($this->DKIM_private); 
     2216    if ($this->DKIM_passphrase!='') { 
     2217      $privKey = openssl_pkey_get_private($privKeyStr,$this->DKIM_passphrase); 
    18882218    } else { 
    1889       return false; 
     2219      $privKey = $privKeyStr; 
    18902220    } 
     2221    if (openssl_sign($s, $signature, $privKey)) { 
     2222      return base64_encode($signature); 
     2223    } 
    18912224  } 
    18922225 
    18932226  /** 
    1894    * Strips newlines to prevent header injection. 
    1895    * @access private 
    1896    * @param string $str String 
    1897    * @return string 
     2227   * Generate DKIM Canonicalization Header 
     2228   * 
     2229   * @access public 
     2230   * @param string $s Header 
    18982231   */ 
    1899   function SecureHeader($str) { 
    1900     $str = trim($str); 
    1901     $str = str_replace("\r", "", $str); 
    1902     $str = str_replace("\n", "", $str); 
    1903     return $str; 
     2232  public function DKIM_HeaderC($s) { 
     2233    $s=preg_replace("/\r\n\s+/"," ",$s); 
     2234    $lines=explode("\r\n",$s); 
     2235    foreach ($lines as $key=>$line) { 
     2236      list($heading,$value)=explode(":",$line,2); 
     2237      $heading=strtolower($heading); 
     2238      $value=preg_replace("/\s+/"," ",$value) ; // Compress useless spaces 
     2239      $lines[$key]=$heading.":".trim($value) ; // Don't forget to remove WSP around the value 
     2240    } 
     2241    $s=implode("\r\n",$lines); 
     2242    return $s; 
    19042243  } 
    19052244 
    19062245  /** 
    1907    * Set the private key file and password to sign the message. 
     2246   * Generate DKIM Canonicalization Body 
    19082247   * 
    19092248   * @access public 
    1910    * @param string $key_filename Parameter File Name 
    1911    * @param string $key_pass Password for private key 
     2249   * @param string $body Message Body 
    19122250   */ 
    1913   function Sign($cert_filename, $key_filename, $key_pass) { 
    1914     $this->sign_cert_file = $cert_filename; 
    1915     $this->sign_key_file = $key_filename; 
    1916     $this->sign_key_pass = $key_pass; 
     2251  public function DKIM_BodyC($body) { 
     2252    if ($body == '') return "\r\n"; 
     2253    // stabilize line endings 
     2254    $body=str_replace("\r\n","\n",$body); 
     2255    $body=str_replace("\n","\r\n",$body); 
     2256    // END stabilize line endings 
     2257    while (substr($body,strlen($body)-4,4) == "\r\n\r\n") { 
     2258      $body=substr($body,0,strlen($body)-2); 
     2259    } 
     2260    return $body; 
    19172261  } 
    19182262 
     2263  /** 
     2264   * Create the DKIM header, body, as new header 
     2265   * 
     2266   * @access public 
     2267   * @param string $headers_line Header lines 
     2268   * @param string $subject Subject 
     2269   * @param string $body Body 
     2270   */ 
     2271  public function DKIM_Add($headers_line,$subject,$body) { 
     2272    $DKIMsignatureType    = 'rsa-sha1'; // Signature & hash algorithms 
     2273    $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body 
     2274    $DKIMquery            = 'dns/txt'; // Query method 
     2275    $DKIMtime             = time() ; // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone) 
     2276    $subject_header       = "Subject: $subject"; 
     2277    $headers              = explode("\r\n",$headers_line); 
     2278    foreach($headers as $header) { 
     2279      if (strpos($header,'From:') === 0) { 
     2280        $from_header=$header; 
     2281      } elseif (strpos($header,'To:') === 0) { 
     2282        $to_header=$header; 
     2283      } 
     2284    } 
     2285    $from     = str_replace('|','=7C',$this->DKIM_QP($from_header)); 
     2286    $to       = str_replace('|','=7C',$this->DKIM_QP($to_header)); 
     2287    $subject  = str_replace('|','=7C',$this->DKIM_QP($subject_header)) ; // Copied header fields (dkim-quoted-printable 
     2288    $body     = $this->DKIM_BodyC($body); 
     2289    $DKIMlen  = strlen($body) ; // Length of body 
     2290    $DKIMb64  = base64_encode(pack("H*", sha1($body))) ; // Base64 of packed binary SHA-1 hash of body 
     2291    $ident    = ($this->DKIM_identity == '')? '' : " i=" . $this->DKIM_identity . ";"; 
     2292    $dkimhdrs = "DKIM-Signature: v=1; a=" . $DKIMsignatureType . "; q=" . $DKIMquery . "; l=" . $DKIMlen . "; s=" . $this->DKIM_selector . ";\r\n". 
     2293                "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n". 
     2294                "\th=From:To:Subject;\r\n". 
     2295                "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n". 
     2296                "\tz=$from\r\n". 
     2297                "\t|$to\r\n". 
     2298                "\t|$subject;\r\n". 
     2299                "\tbh=" . $DKIMb64 . ";\r\n". 
     2300                "\tb="; 
     2301    $toSign   = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs); 
     2302    $signed   = $this->DKIM_Sign($toSign); 
     2303    return "X-PHPMAILER-DKIM: phpmailer.worxware.com\r\n".$dkimhdrs.$signed."\r\n"; 
     2304  } 
     2305 
     2306  protected function doCallback($isSent,$to,$cc,$bcc,$subject,$body) { 
     2307    if (!empty($this->action_function) && function_exists($this->action_function)) { 
     2308      $params = array($isSent,$to,$cc,$bcc,$subject,$body); 
     2309      call_user_func_array($this->action_function,$params); 
     2310    } 
     2311  } 
    19192312} 
    19202313 
    1921 ?> 
     2314class phpmailerException extends Exception { 
     2315  public function errorMessage() { 
     2316    $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n"; 
     2317    return $errorMsg; 
     2318  } 
     2319} 
     2320?> 
     2321 No newline at end of file 
  • wp-includes/class-pop3.php

     
    11<?php 
     2/*~ class.pop3.php 
     3.---------------------------------------------------------------------------. 
     4|  Software: PHPMailer - PHP email class                                    | 
     5|   Version: 5.1                                                            | 
     6|   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  | 
     7|      Info: http://phpmailer.sourceforge.net                               | 
     8|   Support: http://sourceforge.net/projects/phpmailer/                     | 
     9| ------------------------------------------------------------------------- | 
     10|     Admin: Andy Prevost (project admininistrator)                         | 
     11|   Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net | 
     12|          : Marcus Bointon (coolbru) coolbru@users.sourceforge.net         | 
     13|   Founder: Brent R. Matzelle (original founder)                           | 
     14| Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved.               | 
     15| Copyright (c) 2001-2003, Brent R. Matzelle                                | 
     16| ------------------------------------------------------------------------- | 
     17|   License: Distributed under the Lesser General Public License (LGPL)     | 
     18|            http://www.gnu.org/copyleft/lesser.html                        | 
     19| This program is distributed in the hope that it will be useful - WITHOUT  | 
     20| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     | 
     21| FITNESS FOR A PARTICULAR PURPOSE.                                         | 
     22| ------------------------------------------------------------------------- | 
     23| We offer a number of paid services (www.codeworxtech.com):                | 
     24| - Web Hosting on highly optimized fast and secure servers                 | 
     25| - Technology Consulting                                                   | 
     26| - Oursourcing (highly qualified programmers and graphic designers)        | 
     27'---------------------------------------------------------------------------' 
     28*/ 
     29 
    230/** 
    3  * mail_fetch/setup.php 
     31 * PHPMailer - PHP POP Before SMTP Authentication Class 
     32 * NOTE: Designed for use with PHP version 5 and up 
     33 * @package PHPMailer 
     34 * @author Andy Prevost 
     35 * @author Marcus Bointon 
     36 * @copyright 2004 - 2009 Andy Prevost 
     37 * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL) 
     38 * @version $Id$ 
     39 */ 
     40 
     41/** 
     42 * POP Before SMTP Authentication Class 
     43 * Version 5.0.0 
    444 * 
    5  * @package SquirrelMail 
     45 * Author: Richard Davey (rich@corephp.co.uk) 
     46 * Modifications: Andy Prevost 
     47 * License: LGPL, see PHPMailer License 
    648 * 
    7  * @copyright (c) 1999-2006 The SquirrelMail Project Team 
     49 * Specifically for PHPMailer to allow POP before SMTP authentication. 
     50 * Does not yet work with APOP - if you have an APOP account, contact Richard Davey 
     51 * and we can test changes to this script. 
    852 * 
    9  * @copyright (c) 1999 CDI (cdi@thewebmasters.net) All Rights Reserved 
    10  * Modified by Philippe Mingo 2001 mingo@rotedic.com 
    11  * An RFC 1939 compliant wrapper class for the POP3 protocol. 
     53 * This class is based on the structure of the SMTP class originally authored by Chris Ryan 
    1254 * 
    13  * Licensed under the GNU GPL. For full terms see the file COPYING. 
    14  * @license http://opensource.org/licenses/gpl-license.php GNU General Public License 
     55 * This class is rfc 1939 compliant and implements all the commands 
     56 * required for POP3 connection, authentication and disconnection. 
    1557 * 
    16  * pop3 class 
    17  * 
    18  * $Id$ 
     58 * @package PHPMailer 
     59 * @author Richard Davey 
    1960 */ 
    2061 
    2162class POP3 { 
    22     var $ERROR      = '';       //  Error string. 
     63  /** 
     64   * Default POP3 port 
     65   * @var int 
     66   */ 
     67  public $POP3_PORT = 110; 
    2368 
    24     var $TIMEOUT    = 60;       //  Default timeout before giving up on a 
    25                                 //  network operation. 
     69  /** 
     70   * Default Timeout 
     71   * @var int 
     72   */ 
     73  public $POP3_TIMEOUT = 30; 
    2674 
    27     var $COUNT      = -1;       //  Mailbox msg count 
     75  /** 
     76   * POP3 Carriage Return + Line Feed 
     77   * @var string 
     78   */ 
     79  public $CRLF = "\r\n"; 
    2880 
    29     var $BUFFER     = 512;      //  Socket buffer for socket fgets() calls. 
    30                                 //  Per RFC 1939 the returned line a POP3 
    31                                 //  server can send is 512 bytes. 
     81  /** 
     82   * Displaying Debug warnings? (0 = now, 1+ = yes) 
     83   * @var int 
     84   */ 
     85  public $do_debug = 2; 
    3286 
    33     var $FP         = '';       //  The connection to the server's 
    34                                 //  file descriptor 
     87  /** 
     88   * POP3 Mail Server 
     89   * @var string 
     90   */ 
     91  public $host; 
    3592 
    36     var $MAILSERVER = '';       // Set this to hard code the server name 
     93  /** 
     94   * POP3 Port 
     95   * @var int 
     96   */ 
     97  public $port; 
    3798 
    38     var $DEBUG      = FALSE;    // set to true to echo pop3 
    39                                 // commands and responses to error_log 
    40                                 // this WILL log passwords! 
     99  /** 
     100   * POP3 Timeout Value 
     101   * @var int 
     102   */ 
     103  public $tval; 
    41104 
    42     var $BANNER     = '';       //  Holds the banner returned by the 
    43                                 //  pop server - used for apop() 
     105  /** 
     106   * POP3 Username 
     107   * @var string 
     108   */ 
     109  public $username; 
    44110 
    45     var $ALLOWAPOP  = FALSE;    //  Allow or disallow apop() 
    46                                 //  This must be set to true 
    47                                 //  manually 
     111  /** 
     112   * POP3 Password 
     113   * @var string 
     114   */ 
     115  public $password; 
    48116 
    49     function POP3 ( $server = '', $timeout = '' ) { 
    50         settype($this->BUFFER,"integer"); 
    51         if( !empty($server) ) { 
    52             // Do not allow programs to alter MAILSERVER 
    53             // if it is already specified. They can get around 
    54             // this if they -really- want to, so don't count on it. 
    55             if(empty($this->MAILSERVER)) 
    56                 $this->MAILSERVER = $server; 
    57         } 
    58         if(!empty($timeout)) { 
    59             settype($timeout,"integer"); 
    60             $this->TIMEOUT = $timeout; 
    61             if (!ini_get('safe_mode')) 
    62                 set_time_limit($timeout); 
    63         } 
    64         return true; 
    65     } 
     117  ///////////////////////////////////////////////// 
     118  // PROPERTIES, PRIVATE AND PROTECTED 
     119  ///////////////////////////////////////////////// 
    66120 
    67     function update_timer () { 
    68         if (!ini_get('safe_mode')) 
    69             set_time_limit($this->TIMEOUT); 
    70         return true; 
    71     } 
     121  private $pop_conn; 
     122  private $connected; 
     123  private $error;     //  Error log array 
    72124 
    73     function connect ($server, $port = 110)  { 
    74         //  Opens a socket to the specified server. Unless overridden, 
    75         //  port defaults to 110. Returns true on success, false on fail 
     125  /** 
     126   * Constructor, sets the initial values 
     127   * @access public 
     128   * @return POP3 
     129   */ 
     130  public function __construct() { 
     131    $this->pop_conn  = 0; 
     132    $this->connected = false; 
     133    $this->error     = null; 
     134  } 
    76135 
    77         // If MAILSERVER is set, override $server with it's value 
     136  /** 
     137   * Combination of public events - connect, login, disconnect 
     138   * @access public 
     139   * @param string $host 
     140   * @param integer $port 
     141   * @param integer $tval 
     142   * @param string $username 
     143   * @param string $password 
     144   */ 
     145  public function Authorise ($host, $port = false, $tval = false, $username, $password, $debug_level = 0) { 
     146    $this->host = $host; 
    78147 
    79         if (!isset($port) || !$port) {$port = 110;} 
    80         if(!empty($this->MAILSERVER)) 
    81             $server = $this->MAILSERVER; 
     148    //  If no port value is passed, retrieve it 
     149    if ($port == false) { 
     150      $this->port = $this->POP3_PORT; 
     151    } else { 
     152      $this->port = $port; 
     153    } 
    82154 
    83         if(empty($server)){ 
    84             $this->ERROR = "POP3 connect: " . _("No server specified"); 
    85             unset($this->FP); 
    86             return false; 
    87         } 
     155    //  If no port value is passed, retrieve it 
     156    if ($tval == false) { 
     157      $this->tval = $this->POP3_TIMEOUT; 
     158    } else { 
     159      $this->tval = $tval; 
     160    } 
    88161 
    89         $fp = @fsockopen("$server", $port, $errno, $errstr); 
     162    $this->do_debug = $debug_level; 
     163    $this->username = $username; 
     164    $this->password = $password; 
    90165 
    91         if(!$fp) { 
    92             $this->ERROR = "POP3 connect: " . _("Error ") . "[$errno] [$errstr]"; 
    93             unset($this->FP); 
    94             return false; 
    95         } 
     166    //  Refresh the error log 
     167    $this->error = null; 
    96168 
    97         socket_set_blocking($fp,-1); 
    98         $this->update_timer(); 
    99         $reply = fgets($fp,$this->BUFFER); 
    100         $reply = $this->strip_clf($reply); 
    101         if($this->DEBUG) 
    102             error_log("POP3 SEND [connect: $server] GOT [$reply]",0); 
    103         if(!$this->is_ok($reply)) { 
    104             $this->ERROR = "POP3 connect: " . _("Error ") . "[$reply]"; 
    105             unset($this->FP); 
    106             return false; 
    107         } 
    108         $this->FP = $fp; 
    109         $this->BANNER = $this->parse_banner($reply); 
    110         return true; 
    111     } 
     169    //  Connect 
     170    $result = $this->Connect($this->host, $this->port, $this->tval); 
    112171 
    113     function user ($user = "") { 
    114         // Sends the USER command, returns true or false 
     172    if ($result) { 
     173      $login_result = $this->Login($this->username, $this->password); 
    115174 
    116         if( empty($user) ) { 
    117             $this->ERROR = "POP3 user: " . _("no login ID submitted"); 
    118             return false; 
    119         } elseif(!isset($this->FP)) { 
    120             $this->ERROR = "POP3 user: " . _("connection not established"); 
    121             return false; 
    122         } else { 
    123             $reply = $this->send_cmd("USER $user"); 
    124             if(!$this->is_ok($reply)) { 
    125                 $this->ERROR = "POP3 user: " . _("Error ") . "[$reply]"; 
    126                 return false; 
    127             } else 
    128                 return true; 
    129         } 
    130     } 
     175      if ($login_result) { 
     176        $this->Disconnect(); 
    131177 
    132     function pass ($pass = "")     { 
    133         // Sends the PASS command, returns # of msgs in mailbox, 
    134         // returns false (undef) on Auth failure 
     178        return true; 
     179      } 
    135180 
    136         if(empty($pass)) { 
    137             $this->ERROR = "POP3 pass: " . _("No password submitted"); 
    138             return false; 
    139         } elseif(!isset($this->FP)) { 
    140             $this->ERROR = "POP3 pass: " . _("connection not established"); 
    141             return false; 
    142         } else { 
    143             $reply = $this->send_cmd("PASS $pass"); 
    144             if(!$this->is_ok($reply)) { 
    145                 $this->ERROR = "POP3 pass: " . _("Authentication failed") . " [$reply]"; 
    146                 $this->quit(); 
    147                 return false; 
    148             } else { 
    149                 //  Auth successful. 
    150                 $count = $this->last("count"); 
    151                 $this->COUNT = $count; 
    152                 return $count; 
    153             } 
    154         } 
    155181    } 
    156182 
    157     function apop ($login,$pass) { 
    158         //  Attempts an APOP login. If this fails, it'll 
    159         //  try a standard login. YOUR SERVER MUST SUPPORT 
    160         //  THE USE OF THE APOP COMMAND! 
    161         //  (apop is optional per rfc1939) 
     183    //  We need to disconnect regardless if the login succeeded 
     184    $this->Disconnect(); 
    162185 
    163         if(!isset($this->FP)) { 
    164             $this->ERROR = "POP3 apop: " . _("No connection to server"); 
    165             return false; 
    166         } elseif(!$this->ALLOWAPOP) { 
    167             $retVal = $this->login($login,$pass); 
    168             return $retVal; 
    169         } elseif(empty($login)) { 
    170             $this->ERROR = "POP3 apop: " . _("No login ID submitted"); 
    171             return false; 
    172         } elseif(empty($pass)) { 
    173             $this->ERROR = "POP3 apop: " . _("No password submitted"); 
    174             return false; 
    175         } else { 
    176             $banner = $this->BANNER; 
    177             if( (!$banner) or (empty($banner)) ) { 
    178                 $this->ERROR = "POP3 apop: " . _("No server banner") . ' - ' . _("abort"); 
    179                 $retVal = $this->login($login,$pass); 
    180                 return $retVal; 
    181             } else { 
    182                 $AuthString = $banner; 
    183                 $AuthString .= $pass; 
    184                 $APOPString = md5($AuthString); 
    185                 $cmd = "APOP $login $APOPString"; 
    186                 $reply = $this->send_cmd($cmd); 
    187                 if(!$this->is_ok($reply)) { 
    188                     $this->ERROR = "POP3 apop: " . _("apop authentication failed") . ' - ' . _("abort"); 
    189                     $retVal = $this->login($login,$pass); 
    190                     return $retVal; 
    191                 } else { 
    192                     //  Auth successful. 
    193                     $count = $this->last("count"); 
    194                     $this->COUNT = $count; 
    195                     return $count; 
    196                 } 
    197             } 
    198         } 
    199     } 
     186    return false; 
     187  } 
    200188 
    201     function login ($login = "", $pass = "") { 
    202         // Sends both user and pass. Returns # of msgs in mailbox or 
    203         // false on failure (or -1, if the error occurs while getting 
    204         // the number of messages.) 
    205  
    206         if( !isset($this->FP) ) { 
    207             $this->ERROR = "POP3 login: " . _("No connection to server"); 
    208             return false; 
    209         } else { 
    210             $fp = $this->FP; 
    211             if( !$this->user( $login ) ) { 
    212                 //  Preserve the error generated by user() 
    213                 return false; 
    214             } else { 
    215                 $count = $this->pass($pass); 
    216                 if( (!$count) || ($count == -1) ) { 
    217                     //  Preserve the error generated by last() and pass() 
    218                     return false; 
    219                 } else 
    220                     return $count; 
    221             } 
    222         } 
     189  /** 
     190   * Connect to the POP3 server 
     191   * @access public 
     192   * @param string $host 
     193   * @param integer $port 
     194   * @param integer $tval 
     195   * @return boolean 
     196   */ 
     197  public function Connect ($host, $port = false, $tval = 30) { 
     198    //  Are we already connected? 
     199    if ($this->connected) { 
     200      return true; 
    223201    } 
    224202 
    225     function top ($msgNum, $numLines = "0") { 
    226         //  Gets the header and first $numLines of the msg body 
    227         //  returns data in an array with each returned line being 
    228         //  an array element. If $numLines is empty, returns 
    229         //  only the header information, and none of the body. 
     203    /* 
     204    On Windows this will raise a PHP Warning error if the hostname doesn't exist. 
     205    Rather than supress it with @fsockopen, let's capture it cleanly instead 
     206    */ 
    230207 
    231         if(!isset($this->FP)) { 
    232             $this->ERROR = "POP3 top: " . _("No connection to server"); 
    233             return false; 
    234         } 
    235         $this->update_timer(); 
     208    set_error_handler(array(&$this, 'catchWarning')); 
    236209 
    237         $fp = $this->FP; 
    238         $buffer = $this->BUFFER; 
    239         $cmd = "TOP $msgNum $numLines"; 
    240         fwrite($fp, "TOP $msgNum $numLines\r\n"); 
    241         $reply = fgets($fp, $buffer); 
    242         $reply = $this->strip_clf($reply); 
    243         if($this->DEBUG) { 
    244             @error_log("POP3 SEND [$cmd] GOT [$reply]",0); 
    245         } 
    246         if(!$this->is_ok($reply)) 
    247         { 
    248             $this->ERROR = "POP3 top: " . _("Error ") . "[$reply]"; 
    249             return false; 
    250         } 
     210    //  Connect to the POP3 server 
     211    $this->pop_conn = fsockopen($host,    //  POP3 Host 
     212                  $port,    //  Port # 
     213                  $errno,   //  Error Number 
     214                  $errstr,  //  Error Message 
     215                  $tval);   //  Timeout (seconds) 
    251216 
    252         $count = 0; 
    253         $MsgArray = array(); 
     217    //  Restore the error handler 
     218    restore_error_handler(); 
    254219 
    255         $line = fgets($fp,$buffer); 
    256         while ( !ereg("^\.\r\n",$line)) 
    257         { 
    258             $MsgArray[$count] = $line; 
    259             $count++; 
    260             $line = fgets($fp,$buffer); 
    261             if(empty($line))    { break; } 
    262         } 
    263  
    264         return $MsgArray; 
     220    //  Does the Error Log now contain anything? 
     221    if ($this->error && $this->do_debug >= 1) { 
     222      $this->displayErrors(); 
    265223    } 
    266224 
    267     function pop_list ($msgNum = "") { 
    268         //  If called with an argument, returns that msgs' size in octets 
    269         //  No argument returns an associative array of undeleted 
    270         //  msg numbers and their sizes in octets 
     225    //  Did we connect? 
     226    if ($this->pop_conn == false) { 
     227      //  It would appear not... 
     228      $this->error = array( 
     229        'error' => "Failed to connect to server $host on port $port", 
     230        'errno' => $errno, 
     231        'errstr' => $errstr 
     232      ); 
    271233 
    272         if(!isset($this->FP)) 
    273         { 
    274             $this->ERROR = "POP3 pop_list: " . _("No connection to server"); 
    275             return false; 
    276         } 
    277         $fp = $this->FP; 
    278         $Total = $this->COUNT; 
    279         if( (!$Total) or ($Total == -1) ) 
    280         { 
    281             return false; 
    282         } 
    283         if($Total == 0) 
    284         { 
    285             return array("0","0"); 
    286             // return -1;   // mailbox empty 
    287         } 
     234      if ($this->do_debug >= 1) { 
     235        $this->displayErrors(); 
     236      } 
    288237 
    289         $this->update_timer(); 
    290  
    291         if(!empty($msgNum)) 
    292         { 
    293             $cmd = "LIST $msgNum"; 
    294             fwrite($fp,"$cmd\r\n"); 
    295             $reply = fgets($fp,$this->BUFFER); 
    296             $reply = $this->strip_clf($reply); 
    297             if($this->DEBUG) { 
    298                 @error_log("POP3 SEND [$cmd] GOT [$reply]",0); 
    299             } 
    300             if(!$this->is_ok($reply)) 
    301             { 
    302                 $this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]"; 
    303                 return false; 
    304             } 
    305             list($junk,$num,$size) = preg_split('/\s+/',$reply); 
    306             return $size; 
    307         } 
    308         $cmd = "LIST"; 
    309         $reply = $this->send_cmd($cmd); 
    310         if(!$this->is_ok($reply)) 
    311         { 
    312             $reply = $this->strip_clf($reply); 
    313             $this->ERROR = "POP3 pop_list: " . _("Error ") .  "[$reply]"; 
    314             return false; 
    315         } 
    316         $MsgArray = array(); 
    317         $MsgArray[0] = $Total; 
    318         for($msgC=1;$msgC <= $Total; $msgC++) 
    319         { 
    320             if($msgC > $Total) { break; } 
    321             $line = fgets($fp,$this->BUFFER); 
    322             $line = $this->strip_clf($line); 
    323             if(ereg("^\.",$line)) 
    324             { 
    325                 $this->ERROR = "POP3 pop_list: " . _("Premature end of list"); 
    326                 return false; 
    327             } 
    328             list($thisMsg,$msgSize) = preg_split('/\s+/',$line); 
    329             settype($thisMsg,"integer"); 
    330             if($thisMsg != $msgC) 
    331             { 
    332                 $MsgArray[$msgC] = "deleted"; 
    333             } 
    334             else 
    335             { 
    336                 $MsgArray[$msgC] = $msgSize; 
    337             } 
    338         } 
    339         return $MsgArray; 
     238      return false; 
    340239    } 
    341240 
    342     function get ($msgNum) { 
    343         //  Retrieve the specified msg number. Returns an array 
    344         //  where each line of the msg is an array element. 
     241    //  Increase the stream time-out 
    345242 
    346         if(!isset($this->FP)) 
    347         { 
    348             $this->ERROR = "POP3 get: " . _("No connection to server"); 
    349             return false; 
    350         } 
     243    //  Check for PHP 4.3.0 or later 
     244    if (version_compare(phpversion(), '5.0.0', 'ge')) { 
     245      stream_set_timeout($this->pop_conn, $tval, 0); 
     246    } else { 
     247      //  Does not work on Windows 
     248      if (substr(PHP_OS, 0, 3) !== 'WIN') { 
     249        socket_set_timeout($this->pop_conn, $tval, 0); 
     250      } 
     251    } 
    351252 
    352         $this->update_timer(); 
     253    //  Get the POP3 server response 
     254    $pop3_response = $this->getResponse(); 
    353255 
    354         $fp = $this->FP; 
    355         $buffer = $this->BUFFER; 
    356         $cmd = "RETR $msgNum"; 
    357         $reply = $this->send_cmd($cmd); 
     256    //  Check for the +OK 
     257    if ($this->checkResponse($pop3_response)) { 
     258    //  The connection is established and the POP3 server is talking 
     259    $this->connected = true; 
     260      return true; 
     261    } 
    358262 
    359         if(!$this->is_ok($reply)) 
    360         { 
    361             $this->ERROR = "POP3 get: " . _("Error ") . "[$reply]"; 
    362             return false; 
    363         } 
     263  } 
    364264 
    365         $count = 0; 
    366         $MsgArray = array(); 
     265  /** 
     266   * Login to the POP3 server (does not support APOP yet) 
     267   * @access public 
     268   * @param string $username 
     269   * @param string $password 
     270   * @return boolean 
     271   */ 
     272  public function Login ($username = '', $password = '') { 
     273    if ($this->connected == false) { 
     274      $this->error = 'Not connected to POP3 server'; 
    367275 
    368         $line = fgets($fp,$buffer); 
    369         while ( !ereg("^\.\r\n",$line)) 
    370         { 
    371             if ( $line[0] == '.' ) { $line = substr($line,1); } 
    372             $MsgArray[$count] = $line; 
    373             $count++; 
    374             $line = fgets($fp,$buffer); 
    375             if(empty($line))    { break; } 
    376         } 
    377         return $MsgArray; 
     276      if ($this->do_debug >= 1) { 
     277        $this->displayErrors(); 
     278      } 
    378279    } 
    379280 
    380     function last ( $type = "count" ) { 
    381         //  Returns the highest msg number in the mailbox. 
    382         //  returns -1 on error, 0+ on success, if type != count 
    383         //  results in a popstat() call (2 element array returned) 
    384  
    385         $last = -1; 
    386         if(!isset($this->FP)) 
    387         { 
    388             $this->ERROR = "POP3 last: " . _("No connection to server"); 
    389             return $last; 
    390         } 
    391  
    392         $reply = $this->send_cmd("STAT"); 
    393         if(!$this->is_ok($reply)) 
    394         { 
    395             $this->ERROR = "POP3 last: " . _("Error ") . "[$reply]"; 
    396             return $last; 
    397         } 
    398  
    399         $Vars = preg_split('/\s+/',$reply); 
    400         $count = $Vars[1]; 
    401         $size = $Vars[2]; 
    402         settype($count,"integer"); 
    403         settype($size,"integer"); 
    404         if($type != "count") 
    405         { 
    406             return array($count,$size); 
    407         } 
    408         return $count; 
     281    if (empty($username)) { 
     282      $username = $this->username; 
    409283    } 
    410284 
    411     function reset () { 
    412         //  Resets the status of the remote server. This includes 
    413         //  resetting the status of ALL msgs to not be deleted. 
    414         //  This method automatically closes the connection to the server. 
    415  
    416         if(!isset($this->FP)) 
    417         { 
    418             $this->ERROR = "POP3 reset: " . _("No connection to server"); 
    419             return false; 
    420         } 
    421         $reply = $this->send_cmd("RSET"); 
    422         if(!$this->is_ok($reply)) 
    423         { 
    424             //  The POP3 RSET command -never- gives a -ERR 
    425             //  response - if it ever does, something truely 
    426             //  wild is going on. 
    427  
    428             $this->ERROR = "POP3 reset: " . _("Error ") . "[$reply]"; 
    429             @error_log("POP3 reset: ERROR [$reply]",0); 
    430         } 
    431         $this->quit(); 
    432         return true; 
     285    if (empty($password)) { 
     286      $password = $this->password; 
    433287    } 
    434288 
    435     function send_cmd ( $cmd = "" ) 
    436     { 
    437         //  Sends a user defined command string to the 
    438         //  POP server and returns the results. Useful for 
    439         //  non-compliant or custom POP servers. 
    440         //  Do NOT includ the \r\n as part of your command 
    441         //  string - it will be appended automatically. 
     289    $pop_username = "USER $username" . $this->CRLF; 
     290    $pop_password = "PASS $password" . $this->CRLF; 
    442291 
    443         //  The return value is a standard fgets() call, which 
    444         //  will read up to $this->BUFFER bytes of data, until it 
    445         //  encounters a new line, or EOF, whichever happens first. 
     292    //  Send the Username 
     293    $this->sendString($pop_username); 
     294    $pop3_response = $this->getResponse(); 
    446295 
    447         //  This method works best if $cmd responds with only 
    448         //  one line of data. 
     296    if ($this->checkResponse($pop3_response)) { 
     297      //  Send the Password 
     298      $this->sendString($pop_password); 
     299      $pop3_response = $this->getResponse(); 
    449300 
    450         if(!isset($this->FP)) 
    451         { 
    452             $this->ERROR = "POP3 send_cmd: " . _("No connection to server"); 
    453             return false; 
    454         } 
    455  
    456         if(empty($cmd)) 
    457         { 
    458             $this->ERROR = "POP3 send_cmd: " . _("Empty command string"); 
    459             return ""; 
    460         } 
    461  
    462         $fp = $this->FP; 
    463         $buffer = $this->BUFFER; 
    464         $this->update_timer(); 
    465         fwrite($fp,"$cmd\r\n"); 
    466         $reply = fgets($fp,$buffer); 
    467         $reply = $this->strip_clf($reply); 
    468         if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); } 
    469         return $reply; 
    470     } 
    471  
    472     function quit() { 
    473         //  Closes the connection to the POP3 server, deleting 
    474         //  any msgs marked as deleted. 
    475  
    476         if(!isset($this->FP)) 
    477         { 
    478             $this->ERROR = "POP3 quit: " . _("connection does not exist"); 
    479             return false; 
    480         } 
    481         $fp = $this->FP; 
    482         $cmd = "QUIT"; 
    483         fwrite($fp,"$cmd\r\n"); 
    484         $reply = fgets($fp,$this->BUFFER); 
    485         $reply = $this->strip_clf($reply); 
    486         if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); } 
    487         fclose($fp); 
    488         unset($this->FP); 
     301      if ($this->checkResponse($pop3_response)) { 
    489302        return true; 
     303      } else { 
     304        return false; 
     305      } 
     306    } else { 
     307      return false; 
    490308    } 
     309  } 
    491310 
    492     function popstat () { 
    493         //  Returns an array of 2 elements. The number of undeleted 
    494         //  msgs in the mailbox, and the size of the mbox in octets. 
     311  /** 
     312   * Disconnect from the POP3 server 
     313   * @access public 
     314   */ 
     315  public function Disconnect () { 
     316    $this->sendString('QUIT'); 
    495317 
    496         $PopArray = $this->last("array"); 
     318    fclose($this->pop_conn); 
     319  } 
    497320 
    498         if($PopArray == -1) { return false; } 
     321  ///////////////////////////////////////////////// 
     322  //  Private Methods 
     323  ///////////////////////////////////////////////// 
    499324 
    500         if( (!$PopArray) or (empty($PopArray)) ) 
    501         { 
    502             return false; 
    503         } 
    504         return $PopArray; 
    505     } 
     325  /** 
     326   * Get the socket response back. 
     327   * $size is the maximum number of bytes to retrieve 
     328   * @access private 
     329   * @param integer $size 
     330   * @return string 
     331   */ 
     332  private function getResponse ($size = 128) { 
     333    $pop3_response = fgets($this->pop_conn, $size); 
    506334 
    507     function uidl ($msgNum = "") 
    508     { 
    509         //  Returns the UIDL of the msg specified. If called with 
    510         //  no arguments, returns an associative array where each 
    511         //  undeleted msg num is a key, and the msg's uidl is the element 
    512         //  Array element 0 will contain the total number of msgs 
     335    return $pop3_response; 
     336  } 
    513337 
    514         if(!isset($this->FP)) { 
    515             $this->ERROR = "POP3 uidl: " . _("No connection to server"); 
    516             return false; 
    517         } 
     338  /** 
     339   * Send a string down the open socket connection to the POP3 server 
     340   * @access private 
     341   * @param string $string 
     342   * @return integer 
     343   */ 
     344  private function sendString ($string) { 
     345    $bytes_sent = fwrite($this->pop_conn, $string, strlen($string)); 
    518346 
    519         $fp = $this->FP; 
    520         $buffer = $this->BUFFER; 
     347    return $bytes_sent; 
     348  } 
    521349 
    522         if(!empty($msgNum)) { 
    523             $cmd = "UIDL $msgNum"; 
    524             $reply = $this->send_cmd($cmd); 
    525             if(!$this->is_ok($reply)) 
    526             { 
    527                 $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]"; 
    528                 return false; 
    529             } 
    530             list ($ok,$num,$myUidl) = preg_split('/\s+/',$reply); 
    531             return $myUidl; 
    532         } else { 
    533             $this->update_timer(); 
     350  /** 
     351   * Checks the POP3 server response for +OK or -ERR 
     352   * @access private 
     353   * @param string $string 
     354   * @return boolean 
     355   */ 
     356  private function checkResponse ($string) { 
     357    if (substr($string, 0, 3) !== '+OK') { 
     358      $this->error = array( 
     359        'error' => "Server reported an error: $string", 
     360        'errno' => 0, 
     361        'errstr' => '' 
     362      ); 
    534363 
    535             $UIDLArray = array(); 
    536             $Total = $this->COUNT; 
    537             $UIDLArray[0] = $Total; 
     364      if ($this->do_debug >= 1) { 
     365        $this->displayErrors(); 
     366      } 
    538367 
    539             if ($Total < 1) 
    540             { 
    541                 return $UIDLArray; 
    542             } 
    543             $cmd = "UIDL"; 
    544             fwrite($fp, "UIDL\r\n"); 
    545             $reply = fgets($fp, $buffer); 
    546             $reply = $this->strip_clf($reply); 
    547             if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); } 
    548             if(!$this->is_ok($reply)) 
    549             { 
    550                 $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]"; 
    551                 return false; 
    552             } 
    553  
    554             $line = ""; 
    555             $count = 1; 
    556             $line = fgets($fp,$buffer); 
    557             while ( !ereg("^\.\r\n",$line)) { 
    558                 if(ereg("^\.\r\n",$line)) { 
    559                     break; 
    560                 } 
    561                 list ($msg,$msgUidl) = preg_split('/\s+/',$line); 
    562                 $msgUidl = $this->strip_clf($msgUidl); 
    563                 if($count == $msg) { 
    564                     $UIDLArray[$msg] = $msgUidl; 
    565                 } 
    566                 else 
    567                 { 
    568                     $UIDLArray[$count] = 'deleted'; 
    569                 } 
    570                 $count++; 
    571                 $line = fgets($fp,$buffer); 
    572             } 
    573         } 
    574         return $UIDLArray; 
     368      return false; 
     369    } else { 
     370      return true; 
    575371    } 
    576372 
    577     function delete ($msgNum = "") { 
    578         //  Flags a specified msg as deleted. The msg will not 
    579         //  be deleted until a quit() method is called. 
     373  } 
    580374 
    581         if(!isset($this->FP)) 
    582         { 
    583             $this->ERROR = "POP3 delete: " . _("No connection to server"); 
    584             return false; 
    585         } 
    586         if(empty($msgNum)) 
    587         { 
    588             $this->ERROR = "POP3 delete: " . _("No msg number submitted"); 
    589             return false; 
    590         } 
    591         $reply = $this->send_cmd("DELE $msgNum"); 
    592         if(!$this->is_ok($reply)) 
    593         { 
    594             $this->ERROR = "POP3 delete: " . _("Command failed ") . "[$reply]"; 
    595             return false; 
    596         } 
    597         return true; 
    598     } 
     375  /** 
     376   * If debug is enabled, display the error message array 
     377   * @access private 
     378   */ 
     379  private function displayErrors () { 
     380    echo '<pre>'; 
    599381 
    600     //  ********************************************************* 
    601  
    602     //  The following methods are internal to the class. 
    603  
    604     function is_ok ($cmd = "") { 
    605         //  Return true or false on +OK or -ERR 
    606  
    607         if( empty($cmd) ) 
    608             return false; 
    609         else 
    610             return( ereg ("^\+OK", $cmd ) ); 
     382    foreach ($this->error as $single_error) { 
     383      print_r($single_error); 
    611384    } 
    612385 
    613     function strip_clf ($text = "") { 
    614         // Strips \r\n from server responses 
     386    echo '</pre>'; 
     387  } 
    615388 
    616         if(empty($text)) 
    617             return $text; 
    618         else { 
    619             $stripped = str_replace("\r",'',$text); 
    620             $stripped = str_replace("\n",'',$stripped); 
    621             return $stripped; 
    622         } 
    623     } 
     389  /** 
     390   * Takes over from PHP for the socket warning handler 
     391   * @access private 
     392   * @param integer $errno 
     393   * @param string $errstr 
     394   * @param string $errfile 
     395   * @param integer $errline 
     396   */ 
     397  private function catchWarning ($errno, $errstr, $errfile, $errline) { 
     398    $this->error[] = array( 
     399      'error' => "Connecting to the POP3 server raised a PHP warning: ", 
     400      'errno' => $errno, 
     401      'errstr' => $errstr 
     402    ); 
     403  } 
    624404 
    625     function parse_banner ( $server_text ) { 
    626         $outside = true; 
    627         $banner = ""; 
    628         $length = strlen($server_text); 
    629         for($count =0; $count < $length; $count++) 
    630         { 
    631             $digit = substr($server_text,$count,1); 
    632             if(!empty($digit))             { 
    633                 if( (!$outside) && ($digit != '<') && ($digit != '>') ) 
    634                 { 
    635                     $banner .= $digit; 
    636                 } 
    637                 if ($digit == '<') 
    638                 { 
    639                     $outside = false; 
    640                 } 
    641                 if($digit == '>') 
    642                 { 
    643                     $outside = true; 
    644                 } 
    645             } 
    646         } 
    647         $banner = $this->strip_clf($banner);    // Just in case 
    648         return "<$banner>"; 
    649     } 
    650  
    651 }   // End class 
    652 ?> 
     405  //  End of class 
     406} 
     407?> 
     408 No newline at end of file 
  • wp-includes/class-smtp.php

     
    22/*~ class.smtp.php 
    33.---------------------------------------------------------------------------. 
    44|  Software: PHPMailer - PHP email class                                    | 
    5 |   Version: 2.0.4                                                          | 
     5|   Version: 5.1                                                            | 
    66|   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  | 
    77|      Info: http://phpmailer.sourceforge.net                               | 
    88|   Support: http://sourceforge.net/projects/phpmailer/                     | 
    99| ------------------------------------------------------------------------- | 
    10 |    Author: Andy Prevost (project admininistrator)                         | 
    11 |    Author: Brent R. Matzelle (original founder)                           | 
    12 | Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               | 
     10|     Admin: Andy Prevost (project admininistrator)                         | 
     11|   Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net | 
     12|          : Marcus Bointon (coolbru) coolbru@users.sourceforge.net         | 
     13|   Founder: Brent R. Matzelle (original founder)                           | 
     14| Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved.               | 
    1315| Copyright (c) 2001-2003, Brent R. Matzelle                                | 
    1416| ------------------------------------------------------------------------- | 
    1517|   License: Distributed under the Lesser General Public License (LGPL)     | 
     
    2325| - Technology Consulting                                                   | 
    2426| - Oursourcing (highly qualified programmers and graphic designers)        | 
    2527'---------------------------------------------------------------------------' 
     28*/ 
     29 
     30/** 
     31 * PHPMailer - PHP SMTP email transport class 
     32 * NOTE: Designed for use with PHP version 5 and up 
     33 * @package PHPMailer 
     34 * @author Andy Prevost 
     35 * @author Marcus Bointon 
     36 * @copyright 2004 - 2008 Andy Prevost 
     37 * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL) 
     38 * @version $Id: class.smtp.php 444 2009-05-05 11:22:26Z coolbru $ 
    2639 */ 
     40 
    2741/** 
    2842 * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP 
    2943 * commands except TURN which will always return a not implemented 
    3044 * error. SMTP also provides some utility methods for sending mail 
    3145 * to an SMTP server. 
    32  * @package PHPMailer 
    33  * @author Chris Ryan 
     46 * original author: Chris Ryan 
    3447 */ 
    3548 
    36 class SMTP 
    37 { 
     49class SMTP { 
    3850  /** 
    3951   *  SMTP server port 
    4052   *  @var int 
    4153   */ 
    42   var $SMTP_PORT = 25; 
     54  public $SMTP_PORT = 25; 
    4355 
    4456  /** 
    4557   *  SMTP reply line ending 
    4658   *  @var string 
    4759   */ 
    48   var $CRLF = "\r\n"; 
     60  public $CRLF = "\r\n"; 
    4961 
    5062  /** 
    5163   *  Sets whether debugging is turned on 
    5264   *  @var bool 
    5365   */ 
    54   var $do_debug;       # the level of debug to perform 
     66  public $do_debug;       // the level of debug to perform 
    5567 
    5668  /** 
    5769   *  Sets VERP use on/off (default is off) 
    5870   *  @var bool 
    5971   */ 
    60   var $do_verp = false; 
     72  public $do_verp = false; 
    6173 
    62   /**#@+ 
    63    * @access private 
    64    */ 
    65   var $smtp_conn;      # the socket to the server 
    66   var $error;          # error if any on the last call 
    67   var $helo_rply;      # the reply the server sent to us for HELO 
    68   /**#@-*/ 
     74  ///////////////////////////////////////////////// 
     75  // PROPERTIES, PRIVATE AND PROTECTED 
     76  ///////////////////////////////////////////////// 
    6977 
     78  private $smtp_conn; // the socket to the server 
     79  private $error;     // error if any on the last call 
     80  private $helo_rply; // the reply the server sent to us for HELO 
     81 
    7082  /** 
    7183   * Initialize the class so that the data is in a known state. 
    7284   * @access public 
    7385   * @return void 
    7486   */ 
    75   function SMTP() { 
     87  public function __construct() { 
    7688    $this->smtp_conn = 0; 
    7789    $this->error = null; 
    7890    $this->helo_rply = null; 
     
    8092    $this->do_debug = 0; 
    8193  } 
    8294 
    83   /************************************************************* 
    84    *                    CONNECTION FUNCTIONS                  * 
    85    ***********************************************************/ 
     95  ///////////////////////////////////////////////// 
     96  // CONNECTION FUNCTIONS 
     97  ///////////////////////////////////////////////// 
    8698 
    8799  /** 
    88100   * Connect to the server specified on the port specified. 
     
    97109   * @access public 
    98110   * @return bool 
    99111   */ 
    100   function Connect($host,$port=0,$tval=30) { 
    101     # set the error val to null so there is no confusion 
     112  public function Connect($host, $port = 0, $tval = 30) { 
     113    // set the error val to null so there is no confusion 
    102114    $this->error = null; 
    103115 
    104     # make sure we are __not__ connected 
     116    // make sure we are __not__ connected 
    105117    if($this->connected()) { 
    106       # ok we are connected! what should we do? 
    107       # for now we will just give an error saying we 
    108       # are already connected 
     118      // already connected, generate error 
    109119      $this->error = array("error" => "Already connected to a server"); 
    110120      return false; 
    111121    } 
     
    114124      $port = $this->SMTP_PORT; 
    115125    } 
    116126 
    117     #connect to the smtp server 
    118     $this->smtp_conn = fsockopen($host,    # the host of the server 
    119                                  $port,    # the port to use 
    120                                  $errno,   # error number if any 
    121                                  $errstr,  # error message if any 
    122                                  $tval);   # give up after ? secs 
    123     # verify we connected properly 
     127    // connect to the smtp server 
     128    $this->smtp_conn = @fsockopen($host,    // the host of the server 
     129                                 $port,    // the port to use 
     130                                 $errno,   // error number if any 
     131                                 $errstr,  // error message if any 
     132                                 $tval);   // give up after ? secs 
     133    // verify we connected properly 
    124134    if(empty($this->smtp_conn)) { 
    125135      $this->error = array("error" => "Failed to connect to server", 
    126136                           "errno" => $errno, 
    127137                           "errstr" => $errstr); 
    128138      if($this->do_debug >= 1) { 
    129         echo "SMTP -> ERROR: " . $this->error["error"] . 
    130                  ": $errstr ($errno)" . $this->CRLF; 
     139        echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />'; 
    131140      } 
    132141      return false; 
    133142    } 
    134143 
    135     # sometimes the SMTP server takes a little longer to respond 
    136     # so we will give it a longer timeout for the first read 
    137     // Windows still does not have support for this timeout function 
     144    // SMTP server can take longer to respond, give longer timeout for first read 
     145    // Windows does not have support for this timeout function 
    138146    if(substr(PHP_OS, 0, 3) != "WIN") 
    139147     socket_set_timeout($this->smtp_conn, $tval, 0); 
    140148 
    141     # get any announcement stuff 
     149    // get any announcement 
    142150    $announce = $this->get_lines(); 
    143151 
    144     # set the timeout  of any socket functions at 1/10 of a second 
    145     //if(function_exists("socket_set_timeout")) 
    146     //   socket_set_timeout($this->smtp_conn, 0, 100000); 
     152    if($this->do_debug >= 2) { 
     153      echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />'; 
     154    } 
    147155 
     156    return true; 
     157  } 
     158 
     159  /** 
     160   * Initiate a TLS communication with the server. 
     161   * 
     162   * SMTP CODE 220 Ready to start TLS 
     163   * SMTP CODE 501 Syntax error (no parameters allowed) 
     164   * SMTP CODE 454 TLS not available due to temporary reason 
     165   * @access public 
     166   * @return bool success 
     167   */ 
     168  public function StartTLS() { 
     169    $this->error = null; # to avoid confusion 
     170 
     171    if(!$this->connected()) { 
     172      $this->error = array("error" => "Called StartTLS() without being connected"); 
     173      return false; 
     174    } 
     175 
     176    fputs($this->smtp_conn,"STARTTLS" . $this->CRLF); 
     177 
     178    $rply = $this->get_lines(); 
     179    $code = substr($rply,0,3); 
     180 
    148181    if($this->do_debug >= 2) { 
    149       echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce; 
     182      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'; 
    150183    } 
    151184 
     185    if($code != 220) { 
     186      $this->error = 
     187         array("error"     => "STARTTLS not accepted from server", 
     188               "smtp_code" => $code, 
     189               "smtp_msg"  => substr($rply,4)); 
     190      if($this->do_debug >= 1) { 
     191        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
     192      } 
     193      return false; 
     194    } 
     195 
     196    // Begin encrypted connection 
     197    if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { 
     198      return false; 
     199    } 
     200 
    152201    return true; 
    153202  } 
    154203 
     
    158207   * @access public 
    159208   * @return bool 
    160209   */ 
    161   function Authenticate($username, $password) { 
     210  public function Authenticate($username, $password) { 
    162211    // Start authentication 
    163212    fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); 
    164213 
     
    171220              "smtp_code" => $code, 
    172221              "smtp_msg" => substr($rply,4)); 
    173222      if($this->do_debug >= 1) { 
    174         echo "SMTP -> ERROR: " . $this->error["error"] . 
    175                  ": " . $rply . $this->CRLF; 
     223        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    176224      } 
    177225      return false; 
    178226    } 
     
    189237              "smtp_code" => $code, 
    190238              "smtp_msg" => substr($rply,4)); 
    191239      if($this->do_debug >= 1) { 
    192         echo "SMTP -> ERROR: " . $this->error["error"] . 
    193                  ": " . $rply . $this->CRLF; 
     240        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    194241      } 
    195242      return false; 
    196243    } 
     
    207254              "smtp_code" => $code, 
    208255              "smtp_msg" => substr($rply,4)); 
    209256      if($this->do_debug >= 1) { 
    210         echo "SMTP -> ERROR: " . $this->error["error"] . 
    211                  ": " . $rply . $this->CRLF; 
     257        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    212258      } 
    213259      return false; 
    214260    } 
     
    218264 
    219265  /** 
    220266   * Returns true if connected to a server otherwise false 
    221    * @access private 
     267   * @access public 
    222268   * @return bool 
    223269   */ 
    224   function Connected() { 
     270  public function Connected() { 
    225271    if(!empty($this->smtp_conn)) { 
    226272      $sock_status = socket_get_status($this->smtp_conn); 
    227273      if($sock_status["eof"]) { 
    228         # hmm this is an odd situation... the socket is 
    229         # valid but we are not connected anymore 
     274        // the socket is valid but we are not connected 
    230275        if($this->do_debug >= 1) { 
    231             echo "SMTP -> NOTICE:" . $this->CRLF . 
    232                  "EOF caught while checking if connected"; 
     276            echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected"; 
    233277        } 
    234278        $this->Close(); 
    235279        return false; 
    236280      } 
    237       return true; # everything looks good 
     281      return true; // everything looks good 
    238282    } 
    239283    return false; 
    240284  } 
     
    246290   * @access public 
    247291   * @return void 
    248292   */ 
    249   function Close() { 
    250     $this->error = null; # so there is no confusion 
     293  public function Close() { 
     294    $this->error = null; // so there is no confusion 
    251295    $this->helo_rply = null; 
    252296    if(!empty($this->smtp_conn)) { 
    253       # close the connection and cleanup 
     297      // close the connection and cleanup 
    254298      fclose($this->smtp_conn); 
    255299      $this->smtp_conn = 0; 
    256300    } 
    257301  } 
    258302 
    259   /*************************************************************** 
    260    *                        SMTP COMMANDS                       * 
    261    *************************************************************/ 
     303  ///////////////////////////////////////////////// 
     304  // SMTP COMMANDS 
     305  ///////////////////////////////////////////////// 
    262306 
    263307  /** 
    264308   * Issues a data command and sends the msg_data to the server 
    265309   * finializing the mail transaction. $msg_data is the message 
    266310   * that is to be send with the headers. Each header needs to be 
    267311   * on a single line followed by a <CRLF> with the message headers 
    268    * and the message body being separated by and additional <CRLF>. 
     312   * and the message body being seperated by and additional <CRLF>. 
    269313   * 
    270314   * Implements rfc 821: DATA <CRLF> 
    271315   * 
     
    279323   * @access public 
    280324   * @return bool 
    281325   */ 
    282   function Data($msg_data) { 
    283     $this->error = null; # so no confusion is caused 
     326  public function Data($msg_data) { 
     327    $this->error = null; // so no confusion is caused 
    284328 
    285329    if(!$this->connected()) { 
    286330      $this->error = array( 
     
    294338    $code = substr($rply,0,3); 
    295339 
    296340    if($this->do_debug >= 2) { 
    297       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     341      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'; 
    298342    } 
    299343 
    300344    if($code != 354) { 
     
    303347              "smtp_code" => $code, 
    304348              "smtp_msg" => substr($rply,4)); 
    305349      if($this->do_debug >= 1) { 
    306         echo "SMTP -> ERROR: " . $this->error["error"] . 
    307                  ": " . $rply . $this->CRLF; 
     350        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    308351      } 
    309352      return false; 
    310353    } 
    311354 
    312     # the server is ready to accept data! 
    313     # according to rfc 821 we should not send more than 1000 
    314     # including the CRLF 
    315     # characters on a single line so we will break the data up 
    316     # into lines by \r and/or \n then if needed we will break 
    317     # each of those into smaller lines to fit within the limit. 
    318     # in addition we will be looking for lines that start with 
    319     # a period '.' and append and additional period '.' to that 
    320     # line. NOTE: this does not count towards are limit. 
     355    /* the server is ready to accept data! 
     356     * according to rfc 821 we should not send more than 1000 
     357     * including the CRLF 
     358     * characters on a single line so we will break the data up 
     359     * into lines by \r and/or \n then if needed we will break 
     360     * each of those into smaller lines to fit within the limit. 
     361     * in addition we will be looking for lines that start with 
     362     * a period '.' and append and additional period '.' to that 
     363     * line. NOTE: this does not count towards limit. 
     364     */ 
    321365 
    322     # normalize the line breaks so we know the explode works 
     366    // normalize the line breaks so we know the explode works 
    323367    $msg_data = str_replace("\r\n","\n",$msg_data); 
    324368    $msg_data = str_replace("\r","\n",$msg_data); 
    325369    $lines = explode("\n",$msg_data); 
    326370 
    327     # we need to find a good way to determine is headers are 
    328     # in the msg_data or if it is a straight msg body 
    329     # currently I am assuming rfc 822 definitions of msg headers 
    330     # and if the first field of the first line (':' sperated) 
    331     # does not contain a space then it _should_ be a header 
    332     # and we can process all lines before a blank "" line as 
    333     # headers. 
     371    /* we need to find a good way to determine is headers are 
     372     * in the msg_data or if it is a straight msg body 
     373     * currently I am assuming rfc 822 definitions of msg headers 
     374     * and if the first field of the first line (':' sperated) 
     375     * does not contain a space then it _should_ be a header 
     376     * and we can process all lines before a blank "" line as 
     377     * headers. 
     378     */ 
     379 
    334380    $field = substr($lines[0],0,strpos($lines[0],":")); 
    335381    $in_headers = false; 
    336382    if(!empty($field) && !strstr($field," ")) { 
    337383      $in_headers = true; 
    338384    } 
    339385 
    340     $max_line_length = 998; # used below; set here for ease in change 
     386    $max_line_length = 998; // used below; set here for ease in change 
    341387 
    342388    while(list(,$line) = @each($lines)) { 
    343389      $lines_out = null; 
    344390      if($line == "" && $in_headers) { 
    345391        $in_headers = false; 
    346392      } 
    347       # ok we need to break this line up into several 
    348       # smaller lines 
     393      // ok we need to break this line up into several smaller lines 
    349394      while(strlen($line) > $max_line_length) { 
    350395        $pos = strrpos(substr($line,0,$max_line_length)," "); 
    351396 
    352         # Patch to fix DOS attack 
     397        // Patch to fix DOS attack 
    353398        if(!$pos) { 
    354399          $pos = $max_line_length - 1; 
     400          $lines_out[] = substr($line,0,$pos); 
     401          $line = substr($line,$pos); 
     402        } else { 
     403          $lines_out[] = substr($line,0,$pos); 
     404          $line = substr($line,$pos + 1); 
    355405        } 
    356406 
    357         $lines_out[] = substr($line,0,$pos); 
    358         $line = substr($line,$pos + 1); 
    359         # if we are processing headers we need to 
    360         # add a LWSP-char to the front of the new line 
    361         # rfc 822 on long msg headers 
     407        /* if processing headers add a LWSP-char to the front of new line 
     408         * rfc 822 on long msg headers 
     409         */ 
    362410        if($in_headers) { 
    363411          $line = "\t" . $line; 
    364412        } 
    365413      } 
    366414      $lines_out[] = $line; 
    367415 
    368       # now send the lines to the server 
     416      // send the lines to the server 
    369417      while(list(,$line_out) = @each($lines_out)) { 
    370418        if(strlen($line_out) > 0) 
    371419        { 
     
    377425      } 
    378426    } 
    379427 
    380     # ok all the message data has been sent so lets get this 
    381     # over with aleady 
     428    // message data has been sent 
    382429    fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF); 
    383430 
    384431    $rply = $this->get_lines(); 
    385432    $code = substr($rply,0,3); 
    386433 
    387434    if($this->do_debug >= 2) { 
    388       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     435      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'; 
    389436    } 
    390437 
    391438    if($code != 250) { 
     
    394441              "smtp_code" => $code, 
    395442              "smtp_msg" => substr($rply,4)); 
    396443      if($this->do_debug >= 1) { 
    397         echo "SMTP -> ERROR: " . $this->error["error"] . 
    398                  ": " . $rply . $this->CRLF; 
     444        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    399445      } 
    400446      return false; 
    401447    } 
     
    403449  } 
    404450 
    405451  /** 
    406    * Expand takes the name and asks the server to list all the 
    407    * people who are members of the _list_. Expand will return 
    408    * back and array of the result or false if an error occurs. 
    409    * Each value in the array returned has the format of: 
    410    *     [ <full-name> <sp> ] <path> 
    411    * The definition of <path> is defined in rfc 821 
    412    * 
    413    * Implements rfc 821: EXPN <SP> <string> <CRLF> 
    414    * 
    415    * SMTP CODE SUCCESS: 250 
    416    * SMTP CODE FAILURE: 550 
    417    * SMTP CODE ERROR  : 500,501,502,504,421 
    418    * @access public 
    419    * @return string array 
    420    */ 
    421   function Expand($name) { 
    422     $this->error = null; # so no confusion is caused 
    423  
    424     if(!$this->connected()) { 
    425       $this->error = array( 
    426             "error" => "Called Expand() without being connected"); 
    427       return false; 
    428     } 
    429  
    430     fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF); 
    431  
    432     $rply = $this->get_lines(); 
    433     $code = substr($rply,0,3); 
    434  
    435     if($this->do_debug >= 2) { 
    436       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    437     } 
    438  
    439     if($code != 250) { 
    440       $this->error = 
    441         array("error" => "EXPN not accepted from server", 
    442               "smtp_code" => $code, 
    443               "smtp_msg" => substr($rply,4)); 
    444       if($this->do_debug >= 1) { 
    445         echo "SMTP -> ERROR: " . $this->error["error"] . 
    446                  ": " . $rply . $this->CRLF; 
    447       } 
    448       return false; 
    449     } 
    450  
    451     # parse the reply and place in our array to return to user 
    452     $entries = explode($this->CRLF,$rply); 
    453     while(list(,$l) = @each($entries)) { 
    454       $list[] = substr($l,4); 
    455     } 
    456  
    457     return $list; 
    458   } 
    459  
    460   /** 
    461452   * Sends the HELO command to the smtp server. 
    462453   * This makes sure that we and the server are in 
    463454   * the same known state. 
     
    469460   * @access public 
    470461   * @return bool 
    471462   */ 
    472   function Hello($host="") { 
    473     $this->error = null; # so no confusion is caused 
     463  public function Hello($host = '') { 
     464    $this->error = null; // so no confusion is caused 
    474465 
    475466    if(!$this->connected()) { 
    476467      $this->error = array( 
     
    478469      return false; 
    479470    } 
    480471 
    481     # if a hostname for the HELO was not specified determine 
    482     # a suitable one to send 
     472    // if hostname for HELO was not specified send default 
    483473    if(empty($host)) { 
    484       # we need to determine some sort of appopiate default 
    485       # to send to the server 
     474      // determine appropriate default to send to server 
    486475      $host = "localhost"; 
    487476    } 
    488477 
    489478    // Send extended hello first (RFC 2821) 
    490     if(!$this->SendHello("EHLO", $host)) 
    491     { 
    492       if(!$this->SendHello("HELO", $host)) 
    493           return false; 
     479    if(!$this->SendHello("EHLO", $host)) { 
     480      if(!$this->SendHello("HELO", $host)) { 
     481        return false; 
     482      } 
    494483    } 
    495484 
    496485    return true; 
     
    501490   * @access private 
    502491   * @return bool 
    503492   */ 
    504   function SendHello($hello, $host) { 
     493  private function SendHello($hello, $host) { 
    505494    fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF); 
    506495 
    507496    $rply = $this->get_lines(); 
    508497    $code = substr($rply,0,3); 
    509498 
    510499    if($this->do_debug >= 2) { 
    511       echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply; 
     500      echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />'; 
    512501    } 
    513502 
    514503    if($code != 250) { 
     
    517506              "smtp_code" => $code, 
    518507              "smtp_msg" => substr($rply,4)); 
    519508      if($this->do_debug >= 1) { 
    520         echo "SMTP -> ERROR: " . $this->error["error"] . 
    521                  ": " . $rply . $this->CRLF; 
     509        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    522510      } 
    523511      return false; 
    524512    } 
     
    529517  } 
    530518 
    531519  /** 
    532    * Gets help information on the keyword specified. If the keyword 
    533    * is not specified then returns generic help, ussually contianing 
    534    * A list of keywords that help is available on. This function 
    535    * returns the results back to the user. It is up to the user to 
    536    * handle the returned data. If an error occurs then false is 
    537    * returned with $this->error set appropiately. 
    538    * 
    539    * Implements rfc 821: HELP [ <SP> <string> ] <CRLF> 
    540    * 
    541    * SMTP CODE SUCCESS: 211,214 
    542    * SMTP CODE ERROR  : 500,501,502,504,421 
    543    * @access public 
    544    * @return string 
    545    */ 
    546   function Help($keyword="") { 
    547     $this->error = null; # to avoid confusion 
    548  
    549     if(!$this->connected()) { 
    550       $this->error = array( 
    551               "error" => "Called Help() without being connected"); 
    552       return false; 
    553     } 
    554  
    555     $extra = ""; 
    556     if(!empty($keyword)) { 
    557       $extra = " " . $keyword; 
    558     } 
    559  
    560     fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF); 
    561  
    562     $rply = $this->get_lines(); 
    563     $code = substr($rply,0,3); 
    564  
    565     if($this->do_debug >= 2) { 
    566       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    567     } 
    568  
    569     if($code != 211 && $code != 214) { 
    570       $this->error = 
    571         array("error" => "HELP not accepted from server", 
    572               "smtp_code" => $code, 
    573               "smtp_msg" => substr($rply,4)); 
    574       if($this->do_debug >= 1) { 
    575         echo "SMTP -> ERROR: " . $this->error["error"] . 
    576                  ": " . $rply . $this->CRLF; 
    577       } 
    578       return false; 
    579     } 
    580  
    581     return $rply; 
    582   } 
    583  
    584   /** 
    585520   * Starts a mail transaction from the email address specified in 
    586521   * $from. Returns true if successful or false otherwise. If True 
    587522   * the mail transaction is started and then one or more Recipient 
     
    595530   * @access public 
    596531   * @return bool 
    597532   */ 
    598   function Mail($from) { 
    599     $this->error = null; # so no confusion is caused 
     533  public function Mail($from) { 
     534    $this->error = null; // so no confusion is caused 
    600535 
    601536    if(!$this->connected()) { 
    602537      $this->error = array( 
     
    611546    $code = substr($rply,0,3); 
    612547 
    613548    if($this->do_debug >= 2) { 
    614       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     549      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'; 
    615550    } 
    616551 
    617552    if($code != 250) { 
     
    620555              "smtp_code" => $code, 
    621556              "smtp_msg" => substr($rply,4)); 
    622557      if($this->do_debug >= 1) { 
    623         echo "SMTP -> ERROR: " . $this->error["error"] . 
    624                  ": " . $rply . $this->CRLF; 
     558        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    625559      } 
    626560      return false; 
    627561    } 
     
    629563  } 
    630564 
    631565  /** 
    632    * Sends the command NOOP to the SMTP server. 
    633    * 
    634    * Implements from rfc 821: NOOP <CRLF> 
    635    * 
    636    * SMTP CODE SUCCESS: 250 
    637    * SMTP CODE ERROR  : 500, 421 
    638    * @access public 
    639    * @return bool 
    640    */ 
    641   function Noop() { 
    642     $this->error = null; # so no confusion is caused 
    643  
    644     if(!$this->connected()) { 
    645       $this->error = array( 
    646               "error" => "Called Noop() without being connected"); 
    647       return false; 
    648     } 
    649  
    650     fputs($this->smtp_conn,"NOOP" . $this->CRLF); 
    651  
    652     $rply = $this->get_lines(); 
    653     $code = substr($rply,0,3); 
    654  
    655     if($this->do_debug >= 2) { 
    656       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    657     } 
    658  
    659     if($code != 250) { 
    660       $this->error = 
    661         array("error" => "NOOP not accepted from server", 
    662               "smtp_code" => $code, 
    663               "smtp_msg" => substr($rply,4)); 
    664       if($this->do_debug >= 1) { 
    665         echo "SMTP -> ERROR: " . $this->error["error"] . 
    666                  ": " . $rply . $this->CRLF; 
    667       } 
    668       return false; 
    669     } 
    670     return true; 
    671   } 
    672  
    673   /** 
    674566   * Sends the quit command to the server and then closes the socket 
    675567   * if there is no error or the $close_on_error argument is true. 
    676568   * 
     
    681573   * @access public 
    682574   * @return bool 
    683575   */ 
    684   function Quit($close_on_error=true) { 
    685     $this->error = null; # so there is no confusion 
     576  public function Quit($close_on_error = true) { 
     577    $this->error = null; // so there is no confusion 
    686578 
    687579    if(!$this->connected()) { 
    688580      $this->error = array( 
     
    690582      return false; 
    691583    } 
    692584 
    693     # send the quit command to the server 
     585    // send the quit command to the server 
    694586    fputs($this->smtp_conn,"quit" . $this->CRLF); 
    695587 
    696     # get any good-bye messages 
     588    // get any good-bye messages 
    697589    $byemsg = $this->get_lines(); 
    698590 
    699591    if($this->do_debug >= 2) { 
    700       echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg; 
     592      echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />'; 
    701593    } 
    702594 
    703595    $rval = true; 
     
    705597 
    706598    $code = substr($byemsg,0,3); 
    707599    if($code != 221) { 
    708       # use e as a tmp var cause Close will overwrite $this->error 
     600      // use e as a tmp var cause Close will overwrite $this->error 
    709601      $e = array("error" => "SMTP server rejected quit command", 
    710602                 "smtp_code" => $code, 
    711603                 "smtp_rply" => substr($byemsg,4)); 
    712604      $rval = false; 
    713605      if($this->do_debug >= 1) { 
    714         echo "SMTP -> ERROR: " . $e["error"] . ": " . 
    715                  $byemsg . $this->CRLF; 
     606        echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />'; 
    716607      } 
    717608    } 
    718609 
     
    735626   * @access public 
    736627   * @return bool 
    737628   */ 
    738   function Recipient($to) { 
    739     $this->error = null; # so no confusion is caused 
     629  public function Recipient($to) { 
     630    $this->error = null; // so no confusion is caused 
    740631 
    741632    if(!$this->connected()) { 
    742633      $this->error = array( 
     
    750641    $code = substr($rply,0,3); 
    751642 
    752643    if($this->do_debug >= 2) { 
    753       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     644      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'; 
    754645    } 
    755646 
    756647    if($code != 250 && $code != 251) { 
     
    759650              "smtp_code" => $code, 
    760651              "smtp_msg" => substr($rply,4)); 
    761652      if($this->do_debug >= 1) { 
    762         echo "SMTP -> ERROR: " . $this->error["error"] . 
    763                  ": " . $rply . $this->CRLF; 
     653        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    764654      } 
    765655      return false; 
    766656    } 
     
    779669   * @access public 
    780670   * @return bool 
    781671   */ 
    782   function Reset() { 
    783     $this->error = null; # so no confusion is caused 
     672  public function Reset() { 
     673    $this->error = null; // so no confusion is caused 
    784674 
    785675    if(!$this->connected()) { 
    786676      $this->error = array( 
     
    794684    $code = substr($rply,0,3); 
    795685 
    796686    if($this->do_debug >= 2) { 
    797       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     687      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'; 
    798688    } 
    799689 
    800690    if($code != 250) { 
     
    803693              "smtp_code" => $code, 
    804694              "smtp_msg" => substr($rply,4)); 
    805695      if($this->do_debug >= 1) { 
    806         echo "SMTP -> ERROR: " . $this->error["error"] . 
    807                  ": " . $rply . $this->CRLF; 
     696        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    808697      } 
    809698      return false; 
    810699    } 
     
    818707   * the mail transaction is started and then one or more Recipient 
    819708   * commands may be called followed by a Data command. This command 
    820709   * will send the message to the users terminal if they are logged 
    821    * in. 
    822    * 
    823    * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF> 
    824    * 
    825    * SMTP CODE SUCCESS: 250 
    826    * SMTP CODE SUCCESS: 552,451,452 
    827    * SMTP CODE SUCCESS: 500,501,502,421 
    828    * @access public 
    829    * @return bool 
    830    */ 
    831   function Send($from) { 
    832     $this->error = null; # so no confusion is caused 
    833  
    834     if(!$this->connected()) { 
    835       $this->error = array( 
    836               "error" => "Called Send() without being connected"); 
    837       return false; 
    838     } 
    839  
    840     fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF); 
    841  
    842     $rply = $this->get_lines(); 
    843     $code = substr($rply,0,3); 
    844  
    845     if($this->do_debug >= 2) { 
    846       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    847     } 
    848  
    849     if($code != 250) { 
    850       $this->error = 
    851         array("error" => "SEND not accepted from server", 
    852               "smtp_code" => $code, 
    853               "smtp_msg" => substr($rply,4)); 
    854       if($this->do_debug >= 1) { 
    855         echo "SMTP -> ERROR: " . $this->error["error"] . 
    856                  ": " . $rply . $this->CRLF; 
    857       } 
    858       return false; 
    859     } 
    860     return true; 
    861   } 
    862  
    863   /** 
    864    * Starts a mail transaction from the email address specified in 
    865    * $from. Returns true if successful or false otherwise. If True 
    866    * the mail transaction is started and then one or more Recipient 
    867    * commands may be called followed by a Data command. This command 
    868    * will send the message to the users terminal if they are logged 
    869710   * in and send them an email. 
    870711   * 
    871712   * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF> 
     
    876717   * @access public 
    877718   * @return bool 
    878719   */ 
    879   function SendAndMail($from) { 
    880     $this->error = null; # so no confusion is caused 
     720  public function SendAndMail($from) { 
     721    $this->error = null; // so no confusion is caused 
    881722 
    882723    if(!$this->connected()) { 
    883724      $this->error = array( 
     
    891732    $code = substr($rply,0,3); 
    892733 
    893734    if($this->do_debug >= 2) { 
    894       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
     735      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'; 
    895736    } 
    896737 
    897738    if($code != 250) { 
     
    900741              "smtp_code" => $code, 
    901742              "smtp_msg" => substr($rply,4)); 
    902743      if($this->do_debug >= 1) { 
    903         echo "SMTP -> ERROR: " . $this->error["error"] . 
    904                  ": " . $rply . $this->CRLF; 
     744        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    905745      } 
    906746      return false; 
    907747    } 
     
    909749  } 
    910750 
    911751  /** 
    912    * Starts a mail transaction from the email address specified in 
    913    * $from. Returns true if successful or false otherwise. If True 
    914    * the mail transaction is started and then one or more Recipient 
    915    * commands may be called followed by a Data command. This command 
    916    * will send the message to the users terminal if they are logged 
    917    * in or mail it to them if they are not. 
    918    * 
    919    * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF> 
    920    * 
    921    * SMTP CODE SUCCESS: 250 
    922    * SMTP CODE SUCCESS: 552,451,452 
    923    * SMTP CODE SUCCESS: 500,501,502,421 
    924    * @access public 
    925    * @return bool 
    926    */ 
    927   function SendOrMail($from) { 
    928     $this->error = null; # so no confusion is caused 
    929  
    930     if(!$this->connected()) { 
    931       $this->error = array( 
    932           "error" => "Called SendOrMail() without being connected"); 
    933       return false; 
    934     } 
    935  
    936     fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF); 
    937  
    938     $rply = $this->get_lines(); 
    939     $code = substr($rply,0,3); 
    940  
    941     if($this->do_debug >= 2) { 
    942       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    943     } 
    944  
    945     if($code != 250) { 
    946       $this->error = 
    947         array("error" => "SOML not accepted from server", 
    948               "smtp_code" => $code, 
    949               "smtp_msg" => substr($rply,4)); 
    950       if($this->do_debug >= 1) { 
    951         echo "SMTP -> ERROR: " . $this->error["error"] . 
    952                  ": " . $rply . $this->CRLF; 
    953       } 
    954       return false; 
    955     } 
    956     return true; 
    957   } 
    958  
    959   /** 
    960752   * This is an optional command for SMTP that this class does not 
    961753   * support. This method is here to make the RFC821 Definition 
    962754   * complete for this class and __may__ be implimented in the future 
     
    969761   * @access public 
    970762   * @return bool 
    971763   */ 
    972   function Turn() { 
     764  public function Turn() { 
    973765    $this->error = array("error" => "This method, TURN, of the SMTP ". 
    974766                                    "is not implemented"); 
    975767    if($this->do_debug >= 1) { 
    976       echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF; 
     768      echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />'; 
    977769    } 
    978770    return false; 
    979771  } 
    980772 
    981773  /** 
    982    * Verifies that the name is recognized by the server. 
    983    * Returns false if the name could not be verified otherwise 
    984    * the response from the server is returned. 
    985    * 
    986    * Implements rfc 821: VRFY <SP> <string> <CRLF> 
    987    * 
    988    * SMTP CODE SUCCESS: 250,251 
    989    * SMTP CODE FAILURE: 550,551,553 
    990    * SMTP CODE ERROR  : 500,501,502,421 
    991    * @access public 
    992    * @return int 
    993    */ 
    994   function Verify($name) { 
    995     $this->error = null; # so no confusion is caused 
    996  
    997     if(!$this->connected()) { 
    998       $this->error = array( 
    999               "error" => "Called Verify() without being connected"); 
    1000       return false; 
    1001     } 
    1002  
    1003     fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF); 
    1004  
    1005     $rply = $this->get_lines(); 
    1006     $code = substr($rply,0,3); 
    1007  
    1008     if($this->do_debug >= 2) { 
    1009       echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; 
    1010     } 
    1011  
    1012     if($code != 250 && $code != 251) { 
    1013       $this->error = 
    1014         array("error" => "VRFY failed on name '$name'", 
    1015               "smtp_code" => $code, 
    1016               "smtp_msg" => substr($rply,4)); 
    1017       if($this->do_debug >= 1) { 
    1018         echo "SMTP -> ERROR: " . $this->error["error"] . 
    1019                  ": " . $rply . $this->CRLF; 
    1020       } 
    1021       return false; 
    1022     } 
    1023     return $rply; 
     774  * Get the current error 
     775  * @access public 
     776  * @return array 
     777  */ 
     778  public function getError() { 
     779    return $this->error; 
    1024780  } 
    1025781 
    1026   /******************************************************************* 
    1027    *                       INTERNAL FUNCTIONS                       * 
    1028    ******************************************************************/ 
     782  ///////////////////////////////////////////////// 
     783  // INTERNAL FUNCTIONS 
     784  ///////////////////////////////////////////////// 
    1029785 
    1030786  /** 
    1031787   * Read in as many lines as possible 
     
    1036792   * @access private 
    1037793   * @return string 
    1038794   */ 
    1039   function get_lines() { 
     795  private function get_lines() { 
    1040796    $data = ""; 
    1041797    while($str = @fgets($this->smtp_conn,515)) { 
    1042798      if($this->do_debug >= 4) { 
    1043         echo "SMTP -> get_lines(): \$data was \"$data\"" . 
    1044                  $this->CRLF; 
    1045         echo "SMTP -> get_lines(): \$str is \"$str\"" . 
    1046                  $this->CRLF; 
     799        echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />'; 
     800        echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />'; 
    1047801      } 
    1048802      $data .= $str; 
    1049803      if($this->do_debug >= 4) { 
    1050         echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF; 
     804        echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />'; 
    1051805      } 
    1052       # if the 4th character is a space then we are done reading 
    1053       # so just break the loop 
     806      // if 4th character is a space, we are done reading, break the loop 
    1054807      if(substr($str,3,1) == " ") { break; } 
    1055808    } 
    1056809    return $data; 
     
    1058811 
    1059812} 
    1060813 
    1061  
    1062  ?> 
     814?> 
     815 No newline at end of file