WordPress.org

Make WordPress Core

Changeset 17676


Ignore:
Timestamp:
04/21/11 20:29:30 (4 years ago)
Author:
ryan
Message:

Update phpmailer and smtp to 5.1. Props MattyRob cnorris23. fixes #15912

Location:
trunk/wp-includes
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/class-phpmailer.php

    r11341 r17676  
    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| ------------------------------------------------------------------------- | 
     
    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 */ 
     40 
     41if (version_compare(PHP_VERSION, '5.0.0', '<') ) exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n"); 
    3342 
    3443class PHPMailer { 
     
    4251   * @var int 
    4352   */ 
    44   var $Priority          = 3; 
     53  public $Priority          = 3; 
    4554 
    4655  /** 
     
    4857   * @var string 
    4958   */ 
    50   var $CharSet           = 'iso-8859-1'; 
     59  public $CharSet           = 'iso-8859-1'; 
    5160 
    5261  /** 
     
    5463   * @var string 
    5564   */ 
    56   var $ContentType        = 'text/plain'; 
    57  
    58   /** 
    59    * Sets the Encoding of the message. Options for this are "8bit", 
    60    * "7bit", "binary", "base64", and "quoted-printable". 
    61    * @var string 
    62    */ 
    63   var $Encoding          = '8bit'; 
     65  public $ContentType       = 'text/plain'; 
     66 
     67  /** 
     68   * Sets the Encoding of the message. Options for this are 
     69   *  "8bit", "7bit", "binary", "base64", and "quoted-printable". 
     70   * @var string 
     71   */ 
     72  public $Encoding          = '8bit'; 
    6473 
    6574  /** 
     
    6776   * @var string 
    6877   */ 
    69   var $ErrorInfo         = ''; 
     78  public $ErrorInfo         = ''; 
    7079 
    7180  /** 
     
    7382   * @var string 
    7483   */ 
    75   var $From              = 'root@localhost'; 
     84  public $From              = 'root@localhost'; 
    7685 
    7786  /** 
     
    7988   * @var string 
    8089   */ 
    81   var $FromName          = 'Root User'; 
     90  public $FromName          = 'Root User'; 
    8291 
    8392  /** 
     
    8695   * @var string 
    8796   */ 
    88   var $Sender            = ''; 
     97  public $Sender            = ''; 
    8998 
    9099  /** 
     
    92101   * @var string 
    93102   */ 
    94   var $Subject           = ''; 
     103  public $Subject           = ''; 
    95104 
    96105  /** 
     
    99108   * @var string 
    100109   */ 
    101   var $Body              = ''; 
     110  public $Body              = ''; 
    102111 
    103112  /** 
     
    108117   * @var string 
    109118   */ 
    110   var $AltBody           = ''; 
     119  public $AltBody           = ''; 
    111120 
    112121  /** 
     
    115124   * @var int 
    116125   */ 
    117   var $WordWrap          = 0; 
     126  public $WordWrap          = 0; 
    118127 
    119128  /** 
     
    121130   * @var string 
    122131   */ 
    123   var $Mailer            = 'mail'; 
     132  public $Mailer            = 'mail'; 
    124133 
    125134  /** 
     
    127136   * @var string 
    128137   */ 
    129   var $Sendmail          = '/usr/sbin/sendmail'; 
    130  
    131   /** 
    132    * Path to PHPMailer plugins.  This is now only useful if the SMTP class 
     138  public $Sendmail          = '/usr/sbin/sendmail'; 
     139 
     140  /** 
     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         = ''; 
    137  
    138   /** 
    139    * Holds PHPMailer version. 
    140    * @var string 
    141    */ 
    142   var $Version           = "2.0.4"; 
     145  public $PluginDir         = ''; 
    143146 
    144147  /** 
     
    146149   * @var string 
    147150   */ 
    148   var $ConfirmReadingTo  = ''; 
     151  public $ConfirmReadingTo  = ''; 
    149152 
    150153  /** 
     
    154157   * @var string 
    155158   */ 
    156   var $Hostname          = ''; 
     159  public $Hostname          = ''; 
    157160 
    158161  /** 
     
    161164   * @var string 
    162165   */ 
    163   var $MessageID         = ''; 
     166  public $MessageID         = ''; 
    164167 
    165168  ///////////////////////////////////////////////// 
     
    175178   * @var string 
    176179   */ 
    177   var $Host        = 'localhost'; 
     180  public $Host          = 'localhost'; 
    178181 
    179182  /** 
     
    181184   * @var int 
    182185   */ 
    183   var $Port        = 25; 
     186  public $Port          = 25; 
    184187 
    185188  /** 
     
    187190   * @var string 
    188191   */ 
    189   var $Helo        = ''; 
     192  public $Helo          = ''; 
    190193 
    191194  /** 
     
    194197   * @var string 
    195198   */ 
    196   var $SMTPSecure = ""; 
     199  public $SMTPSecure    = ''; 
    197200 
    198201  /** 
     
    200203   * @var bool 
    201204   */ 
    202   var $SMTPAuth     = false; 
     205  public $SMTPAuth      = false; 
    203206 
    204207  /** 
     
    206209   * @var string 
    207210   */ 
    208   var $Username     = ''; 
     211  public $Username      = ''; 
    209212 
    210213  /** 
     
    212215   * @var string 
    213216   */ 
    214   var $Password     = ''; 
    215  
    216   /** 
    217    * Sets the SMTP server timeout in seconds. This function will not 
    218    * work with the win32 version. 
     217  public $Password      = ''; 
     218 
     219  /** 
     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  /** 
     
    225228   * @var bool 
    226229   */ 
    227   var $SMTPDebug    = false; 
     230  public $SMTPDebug     = false; 
    228231 
    229232  /** 
     
    233236   * @var bool 
    234237   */ 
    235   var $SMTPKeepAlive = false; 
     238  public $SMTPKeepAlive = false; 
    236239 
    237240  /** 
     
    240243   * @var bool 
    241244   */ 
    242   var $SingleTo = false; 
     245  public $SingleTo      = false; 
     246 
     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'; 
    243304 
    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; 
     325 
     326  ///////////////////////////////////////////////// 
     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 
    263333 
    264334  ///////////////////////////////////////////////// 
     
    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 { 
     
    283361   * @return void 
    284362   */ 
    285   function IsSMTP() { 
     363  public function IsSMTP() { 
    286364    $this->Mailer = 'smtp'; 
    287365  } 
     
    291369   * @return void 
    292370   */ 
    293   function IsMail() { 
     371  public function IsMail() { 
    294372    $this->Mailer = 'mail'; 
    295373  } 
     
    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  } 
     
    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  } 
     
    320403   * @param string $address 
    321404   * @param string $name 
    322    * @return void 
    323    */ 
    324   function AddAddress($address, $name = '') { 
    325     $cur = count($this->to); 
    326     $this->to[$cur][0] = trim($address); 
    327     $this->to[$cur][1] = $name; 
    328   } 
    329  
    330   /** 
    331    * Adds a "Cc" address. Note: this function works 
    332    * with the SMTP mailer on win32, not with the "mail" 
    333    * mailer. 
     405   * @return boolean true on success, false if address already used 
     406   */ 
     407  public function AddAddress($address, $name = '') { 
     408    return $this->AddAnAddress('to', $address, $name); 
     409  } 
     410 
     411  /** 
     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 
    337    */ 
    338   function AddCC($address, $name = '') { 
    339     $cur = count($this->cc); 
    340     $this->cc[$cur][0] = trim($address); 
    341     $this->cc[$cur][1] = $name; 
    342   } 
    343  
    344   /** 
    345    * Adds a "Bcc" address. Note: this function works 
    346    * with the SMTP mailer on win32, not with the "mail" 
    347    * mailer. 
     416   * @return boolean true on success, false if address already used 
     417   */ 
     418  public function AddCC($address, $name = '') { 
     419    return $this->AddAnAddress('cc', $address, $name); 
     420  } 
     421 
     422  /** 
     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 
    351    */ 
    352   function AddBCC($address, $name = '') { 
    353     $cur = count($this->bcc); 
    354     $this->bcc[$cur][0] = trim($address); 
    355     $this->bcc[$cur][1] = $name; 
    356   } 
    357  
    358   /** 
    359    * Adds a "Reply-To" address. 
     427   * @return boolean true on success, false if address already used 
     428   */ 
     429  public function AddBCC($address, $name = '') { 
     430    return $this->AddAnAddress('bcc', $address, $name); 
     431  } 
     432 
     433  /** 
     434   * Adds a "Reply-to" address. 
    360435   * @param string $address 
    361436   * @param string $name 
    362    * @return void 
    363    */ 
    364   function AddReplyTo($address, $name = '') { 
    365     $cur = count($this->ReplyTo); 
    366     $this->ReplyTo[$cur][0] = trim($address); 
    367     $this->ReplyTo[$cur][1] = $name; 
     437   * @return boolean 
     438   */ 
     439  public function AddReplyTo($address, $name = '') { 
     440    return $this->AddAnAddress('ReplyTo', $address, $name); 
     441  } 
     442 
     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    } 
    368533  } 
    369534 
     
    378543   * @return bool 
    379544   */ 
    380   function Send() { 
    381     $header = ''; 
    382     $body = ''; 
    383     $result = true; 
    384  
    385     if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { 
    386       $this->SetError($this->Lang('provide_address')); 
     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      } 
     550 
     551      // Set whether the message is multipart/alternative 
     552      if(!empty($this->AltBody)) { 
     553        $this->ContentType = 'multipart/alternative'; 
     554      } 
     555 
     556      $this->error_count = 0; // reset errors 
     557      $this->SetMessageType(); 
     558      $header = $this->CreateHeader(); 
     559      $body = $this->CreateBody(); 
     560 
     561      if (empty($this->Body)) { 
     562        throw new phpmailerException($this->Lang('empty_message'), self::STOP_CRITICAL); 
     563      } 
     564 
     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"; 
    387587      return false; 
    388588    } 
    389  
    390     /* Set whether the message is multipart/alternative */ 
    391     if(!empty($this->AltBody)) { 
    392       $this->ContentType = 'multipart/alternative'; 
    393     } 
    394  
    395     $this->error_count = 0; // reset errors 
    396     $this->SetMessageType(); 
    397     $header .= $this->CreateHeader(); 
    398     $body = $this->CreateBody(); 
    399  
    400     if($body == '') { 
    401       return false; 
    402     } 
    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)); 
     
    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; 
    441     } 
    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; 
     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      } 
    453633    } 
    454634    return true; 
     
    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]); 
    468     } 
    469  
    470     $toArr = split(',', $to); 
     644  protected function MailSend($header, $body) { 
     645    $toArr = array(); 
     646    foreach($this->to as $t) { 
     647      $toArr[] = $this->AddrFormat($t); 
     648    } 
     649    $to = implode(', ', $toArr); 
    471650 
    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); 
     
    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 { 
     
    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); 
    490       } 
    491     } 
    492  
     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); 
     681      } 
     682    } 
    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; 
    500     } 
    501  
     687      throw new phpmailerException($this->Lang('instantiate'), self::STOP_CRITICAL); 
     688    } 
    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; 
    519     } 
    520  
     706      throw new phpmailerException($this->Lang('smtp_connect_failed'), self::STOP_CRITICAL); 
     707    } 
    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; 
    527     } 
    528  
    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]; 
    533       } 
    534     } 
    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]; 
    538       } 
    539     } 
    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]; 
    543       } 
    544     } 
    545  
    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; 
    557     } 
    558  
     710      throw new phpmailerException($this->Lang('from_failed') . $smtp_from, self::STOP_CRITICAL); 
     711    } 
     712 
     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); 
     724      } 
     725    } 
     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); 
     736      } 
     737    } 
     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); 
     748      } 
     749    } 
     750 
     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); 
     755    } 
    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(); 
    568     } 
    569  
     761    } 
    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    } 
     
    585778    $hosts = explode(';', $this->Host); 
    586779    $index = 0; 
    587     $connection = ($this->smtp->Connected()); 
    588  
    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); 
     780    $connection = $this->smtp->Connected(); 
     781 
     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); 
     809          } 
     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            } 
    613816          } 
    614817        } 
    615       } 
    616       $index++; 
    617     } 
    618     if(!$connection) { 
    619       $this->SetError($this->Lang('connect_host')); 
    620     } 
    621  
    622     return $connection; 
     818        $index++; 
     819        if (!$connection) { 
     820          throw new phpmailerException($this->Lang('connect_host')); 
     821        } 
     822      } 
     823    } catch (phpmailerException $e) { 
     824      $this->smtp->Reset(); 
     825      throw $e; 
     826    } 
     827    return true; 
    623828  } 
    624829 
     
    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(); 
     
    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; 
    669  
    670     return true; 
     877    return ($l == true); //Returns false if language not found 
     878  } 
     879 
     880  /** 
     881  * Return the current array of language strings 
     882  * @return array 
     883  */ 
     884  public function GetTranslations() { 
     885    return $this->language; 
    671886  } 
    672887 
     
    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       } 
    689     } 
     899    $addresses = array(); 
     900    foreach ($addr as $a) { 
     901      $addresses[] = $this->AddrFormat($a); 
     902    } 
     903    $addr_str .= implode(', ', $addresses); 
    690904    $addr_str .= $this->LE; 
    691905 
     
    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]) . ">"; 
    705     } 
    706  
    707     return $formatted; 
     918      return $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">"; 
     919    } 
    708920  } 
    709921 
     
    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 
     
    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; 
     
    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; 
     
    8411057    switch($this->message_type) { 
    8421058      case 'alt': 
    843         /* fall through */ 
    8441059      case 'alt_attachments': 
    8451060        $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); 
     
    8531068  /** 
    8541069   * Assembles message header. 
    855    * @access private 
    856    * @return string 
    857    */ 
    858   function CreateHeader() { 
     1070   * @access public 
     1071   * @return string The assembled header 
     1072   */ 
     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)); 
     
    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    } 
     
    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); 
     
    8961117 
    8971118    if(count($this->ReplyTo) > 0) { 
    898       $result .= $this->AddrAppend('Reply-To', $this->ReplyTo); 
    899     } 
    900  
    901     /* mail() sets the subject itself */ 
     1119      $result .= $this->AddrAppend('Reply-to', $this->ReplyTo); 
     1120    } 
     1121 
     1122    // mail() sets the subject itself 
    9021123    if($this->Mailer != 'mail') { 
    9031124      $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject))); 
     
    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 != '') { 
     
    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) { 
     
    9411162        break; 
    9421163      case 'attachments': 
    943         /* fall through */ 
    9441164      case 'alt_attachments': 
    9451165        if($this->InlineImageExists()){ 
     
    9651185  /** 
    9661186   * Assembles the message body.  Returns an empty string on failure. 
    967    * @access private 
    968    * @return string 
    969    */ 
    970   function CreateBody() { 
    971     $result = ''; 
     1187   * @access public 
     1188   * @return string The assembled message body 
     1189   */ 
     1190  public function CreateBody() { 
     1191    $body = ''; 
     1192 
    9721193    if ($this->sign_key_file) { 
    973       $result .= $this->GetMailMIME(); 
     1194      $body .= $this->GetMailMIME(); 
    9741195    } 
    9751196 
     
    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 = ''; 
    1031       } 
    1032  
    1033       unlink($file); 
    1034       unlink($signed); 
    1035     } 
    1036  
    1037     return $result; 
     1248      } catch (phpmailerException $e) { 
     1249        $body = ''; 
     1250        if ($this->exceptions) { 
     1251          throw $e; 
     1252        } 
     1253      } 
     1254    } 
     1255 
     1256    return $body; 
    10381257  } 
    10391258 
     
    10421261   * @access private 
    10431262   */ 
    1044   function GetBoundary($boundary, $charSet, $contentType, $encoding) { 
     1263  private function GetBoundary($boundary, $charSet, $contentType, $encoding) { 
    10451264    $result = ''; 
    10461265    if($charSet == '') { 
     
    10661285   * @access private 
    10671286   */ 
    1068   function EndBoundary($boundary) { 
     1287  private function EndBoundary($boundary) { 
    10691288    return $this->LE . '--' . $boundary . '--' . $this->LE; 
    10701289  } 
     
    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'; 
     
    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  } 
     
    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  } 
     
    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     } 
    1129  
    1130     $filename = basename($path); 
    1131     if($name == '') { 
    1132       $name = $filename; 
    1133     } 
    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  
     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      } 
     1353 
     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      } 
     1374    } 
    11451375    return true; 
     1376  } 
     1377 
     1378  /** 
     1379  * Return the current array of attachments 
     1380  * @return array 
     1381  */ 
     1382  public function GetAttachments() { 
     1383    return $this->attachment; 
    11461384  } 
    11471385 
     
    11521390   * @return string 
    11531391   */ 
    1154   function AttachAll() { 
    1155     /* Return text of body */ 
     1392  private function AttachAll() { 
     1393    // Return text of body 
    11561394    $mime = array(); 
    1157  
    1158     /* Add all attachments */ 
    1159     for($i = 0; $i < count($this->attachment); $i++) { 
    1160       /* Check for string attachment */ 
    1161       $bString = $this->attachment[$i][5]; 
     1395    $cidUniq = array(); 
     1396    $incl = array(); 
     1397 
     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]; 
    1166       } 
    1167  
    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]; 
     1405        $path = $attachment[0]; 
     1406      } 
     1407 
     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); 
     
    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); 
     
    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; 
    1225   } 
    1226  
    1227   /** 
    1228    * Encodes string to requested format. Returns an 
    1229    * empty string on failure. 
    1230    * @access private 
     1481  } 
     1482 
     1483  /** 
     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; 
     
    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; 
     
    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 
     
    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)) { 
     
    12801538      case 'comment': 
    12811539        $x = preg_match_all('/[()"]/', $str, $matches); 
    1282         /* Fall-through */ 
     1540        // Fall-through 
    12831541      case 'text': 
    12841542      default: 
     
    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 { 
     
    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  } 
     
    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 = "?="; 
     
    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); 
     
    14181679 
    14191680  /** 
    1420    * Callback for converting to "=XX". 
    1421    * @access private 
     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; 
     1711  } 
     1712 
     1713  /** 
     1714   * Encode string to q encoding. 
     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 
    14221719   * @return string 
    14231720   */ 
    1424   function EncodeQ_callback ($matches) { 
    1425     return sprintf('=%02X', ord($matches[1])); 
    1426   } 
    1427  
    1428   /** 
    1429    * Encode string to q encoding. 
    1430    * @access private 
    1431    * @return string 
    1432    */ 
    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 
     
    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 
     
    14941781   * @return bool 
    14951782   */ 
    1496   function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 
    1497  
    1498     if(!@is_file($path)) { 
     1783  public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 
     1784 
     1785    if ( !@is_file($path) ) { 
    14991786      $this->SetError($this->Lang('file_access') . $path); 
    15001787      return false; 
     
    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; 
     
    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; 
    1533       } 
    1534     } 
    1535  
    1536     return $result; 
     1815  public function InlineImageExists() { 
     1816    foreach($this->attachment as $attachment) { 
     1817      if ($attachment[6] == 'inline') { 
     1818        return true; 
     1819      } 
     1820    } 
     1821    return false; 
    15371822  } 
    15381823 
     
    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  } 
     
    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  } 
     
    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  } 
     
    15691863   * @return void 
    15701864   */ 
    1571   function ClearReplyTos() { 
     1865  public function ClearReplyTos() { 
    15721866    $this->ReplyTo = array(); 
    15731867  } 
     
    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 
     
    15891884   * @return void 
    15901885   */ 
    1591   function ClearAttachments() { 
     1886  public function ClearAttachments() { 
    15921887    $this->attachment = array(); 
    15931888  } 
     
    15971892   * @return void 
    15981893   */ 
    1599   function ClearCustomHeaders() { 
     1894  public function ClearCustomHeaders() { 
    16001895    $this->CustomHeader = array(); 
    16011896  } 
     
    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  } 
     
    16181918  /** 
    16191919   * Returns the proper RFC 822 formatted date. 
    1620    * @access private 
     1920   * @access public 
    16211921   * @return string 
    1622    */ 
    1623   function RFCDate() { 
     1922   * @static 
     1923   */ 
     1924  public static function RFCDate() { 
    16241925    $tz = date('Z'); 
    16251926    $tzs = ($tz < 0) ? '-' : '+'; 
     
    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'; 
     
    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 
     
    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  } 
     
    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); 
     
    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  } 
     
    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 .= '/'; } 
     
    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"; 
    1754     } 
    1755   } 
    1756  
    1757   /** 
    1758    * Gets the mime type of the embedded or inline image 
    1759    * @access private 
    1760    * @return mime type of ext 
    1761    */ 
    1762   function _mime_types($ext = '') { 
     2029    if (empty($this->AltBody)) { 
     2030      $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n"; 
     2031    } 
     2032  } 
     2033 
     2034  /** 
     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 
     2040   */ 
     2041  public static function _mime_types($ext = '') { 
    17632042    $mimes = array( 
     2043      'hqx'   =>  'application/mac-binhex40', 
     2044      'cpt'   =>  'application/mac-compactpro', 
     2045      'doc'   =>  'application/msword', 
     2046      'bin'   =>  'application/macbinary', 
     2047      'dms'   =>  'application/octet-stream', 
     2048      'lha'   =>  'application/octet-stream', 
     2049      'lzh'   =>  'application/octet-stream', 
     2050      'exe'   =>  'application/octet-stream', 
     2051      'class' =>  'application/octet-stream', 
     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', 
    17642058      'ai'    =>  'application/postscript', 
    1765       'aif'   =>  'audio/x-aiff', 
    1766       'aifc'  =>  'audio/x-aiff', 
    1767       'aiff'  =>  'audio/x-aiff', 
    1768       'avi'   =>  'video/x-msvideo', 
    1769       'bin'   =>  'application/macbinary', 
    1770       'bmp'   =>  'image/bmp', 
    1771       'class' =>  'application/octet-stream', 
    1772       'cpt'   =>  'application/mac-compactpro', 
    1773       'css'   =>  'text/css', 
     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', 
     2097      'ra'    =>  'audio/x-realaudio', 
     2098      'rv'    =>  'video/vnd.rn-realvideo', 
     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', 
     2111      'shtml' =>  'text/html', 
     2112      'txt'   =>  'text/plain', 
     2113      'text'  =>  'text/plain', 
     2114      'log'   =>  'text/plain', 
     2115      'rtx'   =>  'text/richtext', 
    18232116      'rtf'   =>  'text/rtf', 
    1824       'rtx'   =>  'text/richtext', 
    1825       'rv'    =>  'video/vnd.rn-realvideo', 
    1826       'sea'   =>  'application/octet-stream', 
    1827       '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', 
    1834       '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', 
    1842       'word'  =>  'application/msword', 
    1843       'xht'   =>  'application/xhtml+xml', 
    1844       'xhtml' =>  'application/xhtml+xml', 
    1845       'xl'    =>  'application/excel', 
    1846       'xls'   =>  'application/vnd.ms-excel', 
    18472117      'xml'   =>  'text/xml', 
    18482118      'xsl'   =>  'text/xml', 
    1849       'zip'   =>  'application/zip' 
     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', 
     2127      'word'  =>  'application/msword', 
     2128      'xl'    =>  'application/excel', 
     2129      'eml'   =>  'message/rfc822' 
    18502130    ); 
    1851     return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; 
    1852   } 
    1853  
    1854   /** 
    1855    * Set (or reset) Class Objects (variables) 
    1856    * 
    1857    * Usage Example: 
    1858    * $page->set('X-Priority', '3'); 
    1859    * 
    1860    * @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 
    1864    */ 
    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; 
    1871     } 
    1872   } 
    1873  
    1874   /** 
    1875    * Read a file from a supplied filename and return it. 
    1876    * 
    1877    * @access public 
    1878    * @param string $filename Parameter File Name 
    1879    */ 
    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; 
    1888     } else { 
    1889       return false; 
    1890     } 
     2131    return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; 
     2132  } 
     2133 
     2134  /** 
     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; 
    18912160  } 
    18922161 
    18932162  /** 
    18942163   * Strips newlines to prevent header injection. 
    1895    * @access private 
     2164   * @access public 
    18962165   * @param string $str String 
    18972166   * @return string 
    18982167   */ 
    1899   function SecureHeader($str) { 
    1900     $str = trim($str); 
    1901     $str = str_replace("\r", "", $str); 
    1902     $str = str_replace("\n", "", $str); 
    1903     return $str; 
     2168  public function SecureHeader($str) { 
     2169    $str = str_replace("\r", '', $str); 
     2170    $str = str_replace("\n", '', $str); 
     2171    return trim($str); 
    19042172  } 
    19052173 
     
    19112179   * @param string $key_pass Password for private key 
    19122180   */ 
    1913   function Sign($cert_filename, $key_filename, $key_pass) { 
     2181  public function Sign($cert_filename, $key_filename, $key_pass) { 
    19142182    $this->sign_cert_file = $cert_filename; 
    19152183    $this->sign_key_file = $key_filename; 
     
    19172185  } 
    19182186 
     2187  /** 
     2188   * Set the private key file and password to sign the message. 
     2189   * 
     2190   * @access public 
     2191   * @param string $key_filename Parameter File Name 
     2192   * @param string $key_pass Password for private key 
     2193   */ 
     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      } 
     2204    } 
     2205    return $line; 
     2206  } 
     2207 
     2208  /** 
     2209   * Generate DKIM signature 
     2210   * 
     2211   * @access public 
     2212   * @param string $s Header 
     2213   */ 
     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); 
     2218    } else { 
     2219      $privKey = $privKeyStr; 
     2220    } 
     2221    if (openssl_sign($s, $signature, $privKey)) { 
     2222      return base64_encode($signature); 
     2223    } 
     2224  } 
     2225 
     2226  /** 
     2227   * Generate DKIM Canonicalization Header 
     2228   * 
     2229   * @access public 
     2230   * @param string $s Header 
     2231   */ 
     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; 
     2243  } 
     2244 
     2245  /** 
     2246   * Generate DKIM Canonicalization Body 
     2247   * 
     2248   * @access public 
     2249   * @param string $body Message Body 
     2250   */ 
     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; 
     2261  } 
     2262 
     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 
     2314class phpmailerException extends Exception { 
     2315  public function errorMessage() { 
     2316    $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n"; 
     2317    return $errorMsg; 
     2318  } 
     2319} 
    19212320?> 
  • trunk/wp-includes/class-smtp.php

    r13425 r17676  
    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| ------------------------------------------------------------------------- | 
     
    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 
     
    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  /** 
     
    4658   *  @var string 
    4759   */ 
    48   var $CRLF = "\r\n"; 
     60  public $CRLF = "\r\n"; 
    4961 
    5062  /** 
     
    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  /** 
     
    5870   *  @var bool 
    5971   */ 
    60   var $do_verp = false; 
    61  
    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   /**#@-*/ 
     72  public $do_verp = false; 
     73 
     74  ///////////////////////////////////////////////// 
     75  // PROPERTIES, PRIVATE AND PROTECTED 
     76  ///////////////////////////////////////////////// 
     77 
     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 
    6981 
    7082  /** 
     
    7385   * @return void 
    7486   */ 
    75   function SMTP() { 
     87  public function __construct() { 
    7688    $this->smtp_conn = 0; 
    7789    $this->error = null; 
     
    8193  } 
    8294 
    83   /************************************************************* 
    84    *                    CONNECTION FUNCTIONS                  * 
    85    ***********************************************************/ 
     95  ///////////////////////////////////////////////// 
     96  // CONNECTION FUNCTIONS 
     97  ///////////////////////////////////////////////// 
    8698 
    8799  /** 
     
    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; 
     
    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", 
     
    127137                           "errstr" => $errstr); 
    128138      if($this->do_debug >= 1) { 
    129         echo "SMTP -> ERROR: " . $this->error["error"] . 
    130                  ": $errstr ($errno)" . $this->CRLF; 
    131       } 
    132       return false; 
    133     } 
    134  
    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 
     139        echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />'; 
     140      } 
     141      return false; 
     142    } 
     143 
     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); 
    147  
    148     if($this->do_debug >= 2) { 
    149       echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce; 
     152    if($this->do_debug >= 2) { 
     153      echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />'; 
     154    } 
     155 
     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 
     181    if($this->do_debug >= 2) { 
     182      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'; 
     183    } 
     184 
     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; 
    150199    } 
    151200 
     
    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); 
     
    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; 
     
    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; 
     
    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; 
     
    219265  /** 
    220266   * Returns true if connected to a server otherwise false 
    221    * @access private 
    222    * @return bool 
    223    */ 
    224   function Connected() { 
     267   * @access public 
     268   * @return bool 
     269   */ 
     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; 
     
    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; 
     
    257301  } 
    258302 
    259   /*************************************************************** 
    260    *                        SMTP COMMANDS                       * 
    261    *************************************************************/ 
     303  ///////////////////////////////////////////////// 
     304  // SMTP COMMANDS 
     305  ///////////////////////////////////////////////// 
    262306 
    263307  /** 
     
    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> 
     
    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()) { 
     
    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 
     
    304348              "smtp_msg" => substr($rply,4)); 
    305349      if($this->do_debug >= 1) { 
    306         echo "SMTP -> ERROR: " . $this->error["error"] . 
    307                  ": " . $rply . $this->CRLF; 
    308       } 
    309       return false; 
    310     } 
    311  
    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. 
    321  
    322     # normalize the line breaks so we know the explode works 
     350        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
     351      } 
     352      return false; 
     353    } 
     354 
     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     */ 
     365 
     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; 
     
    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)) { 
     
    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; 
     
    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) 
     
    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 
     
    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 
     
    395442              "smtp_msg" => substr($rply,4)); 
    396443      if($this->do_debug >= 1) { 
    397         echo "SMTP -> ERROR: " . $this->error["error"] . 
    398                  ": " . $rply . $this->CRLF; 
    399       } 
    400       return false; 
    401     } 
    402     return true; 
    403   } 
    404  
    405   /** 
    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; 
     444        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
     445      } 
     446      return false; 
     447    } 
     448    return true; 
    458449  } 
    459450 
     
    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()) { 
     
    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 
     
    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 
     
    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 
     
    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; 
     
    527515 
    528516    return true; 
    529   } 
    530  
    531   /** 
    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; 
    582517  } 
    583518 
     
    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()) { 
     
    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 
     
    621556              "smtp_msg" => substr($rply,4)); 
    622557      if($this->do_debug >= 1) { 
    623         echo "SMTP -> ERROR: " . $this->error["error"] . 
    624                  ": " . $rply . $this->CRLF; 
    625       } 
    626       return false; 
    627     } 
    628     return true; 
    629   } 
    630  
    631   /** 
    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; 
     558        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    667559      } 
    668560      return false; 
     
    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()) { 
     
    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 
     
    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, 
     
    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    } 
     
    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()) { 
     
    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 
     
    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; 
     
    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()) { 
     
    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 
     
    804694              "smtp_msg" => substr($rply,4)); 
    805695      if($this->do_debug >= 1) { 
    806         echo "SMTP -> ERROR: " . $this->error["error"] . 
    807                  ": " . $rply . $this->CRLF; 
    808       } 
    809       return false; 
    810     } 
    811  
    812     return true; 
    813   } 
    814  
    815   /** 
    816    * Starts a mail transaction from the email address specified in 
    817    * $from. Returns true if successful or false otherwise. If True 
    818    * the mail transaction is started and then one or more Recipient 
    819    * commands may be called followed by a Data command. This command 
    820    * 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     } 
     696        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
     697      } 
     698      return false; 
     699    } 
     700 
    860701    return true; 
    861702  } 
     
    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()) { 
     
    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 
     
    901742              "smtp_msg" => substr($rply,4)); 
    902743      if($this->do_debug >= 1) { 
    903         echo "SMTP -> ERROR: " . $this->error["error"] . 
    904                  ": " . $rply . $this->CRLF; 
    905       } 
    906       return false; 
    907     } 
    908     return true; 
    909   } 
    910  
    911   /** 
    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; 
     744        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'; 
    953745      } 
    954746      return false; 
     
    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; 
     
    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; 
    1024   } 
    1025  
    1026   /******************************************************************* 
    1027    *                       INTERNAL FUNCTIONS                       * 
    1028    ******************************************************************/ 
     774  * Get the current error 
     775  * @access public 
     776  * @return array 
     777  */ 
     778  public function getError() { 
     779    return $this->error; 
     780  } 
     781 
     782  ///////////////////////////////////////////////// 
     783  // INTERNAL FUNCTIONS 
     784  ///////////////////////////////////////////////// 
    1029785 
    1030786  /** 
     
    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; 
    1051       } 
    1052       # if the 4th character is a space then we are done reading 
    1053       # so just break the loop 
     804        echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />'; 
     805      } 
     806      // if 4th character is a space, we are done reading, break the loop 
    1054807      if(substr($str,3,1) == " ") { break; } 
    1055808    } 
     
    1059812} 
    1060813 
    1061  
    1062  ?> 
     814?> 
Note: See TracChangeset for help on using the changeset viewer.