Ticket #3862: phpmailer.diff

File phpmailer.diff, 84.8 kB (added by ryan, 2 years ago)

class-phpmailer.php, class-smtp.php, new wp_mail()

  • wp-includes/class-phpmailer.php

    old new  
     1<?php 
     2//////////////////////////////////////////////////// 
     3// PHPMailer - PHP email class 
     4// 
     5// Class for sending email using either 
     6// sendmail, PHP mail(), or SMTP.  Methods are 
     7// based upon the standard AspEmail(tm) classes. 
     8// 
     9// Copyright (C) 2001 - 2003  Brent R. Matzelle 
     10// 
     11// License: LGPL, see LICENSE 
     12//////////////////////////////////////////////////// 
     13 
     14/** 
     15 * PHPMailer - PHP email transport class 
     16 * @package PHPMailer 
     17 * @author Brent R. Matzelle 
     18 * @copyright 2001 - 2003 Brent R. Matzelle 
     19 */ 
     20class PHPMailer 
     21{ 
     22    ///////////////////////////////////////////////// 
     23    // PUBLIC VARIABLES 
     24    ///////////////////////////////////////////////// 
     25 
     26    /** 
     27     * Email priority (1 = High, 3 = Normal, 5 = low). 
     28     * @var int 
     29     */ 
     30    var $Priority          = 3; 
     31 
     32    /** 
     33     * Sets the CharSet of the message. 
     34     * @var string 
     35     */ 
     36    var $CharSet           = "UTF-8"; 
     37 
     38    /** 
     39     * Sets the Content-type of the message. 
     40     * @var string 
     41     */ 
     42    var $ContentType        = "text/plain"; 
     43 
     44    /** 
     45     * Sets the Encoding of the message. Options for this are "8bit", 
     46     * "7bit", "binary", "base64", and "quoted-printable". 
     47     * @var string 
     48     */ 
     49    var $Encoding          = "8bit"; 
     50 
     51    /** 
     52     * Holds the most recent mailer error message. 
     53     * @var string 
     54     */ 
     55    var $ErrorInfo         = ""; 
     56 
     57    /** 
     58     * Sets the From email address for the message. 
     59     * @var string 
     60     */ 
     61    var $From               = "support@wordpress.com"; 
     62 
     63    /** 
     64     * Sets the From name of the message. 
     65     * @var string 
     66     */ 
     67    var $FromName           = "Support"; 
     68 
     69    /** 
     70     * Sets the Sender email (Return-Path) of the message.  If not empty, 
     71     * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. 
     72     * @var string 
     73     */ 
     74    var $Sender            = ""; 
     75 
     76    /** 
     77     * Sets the Subject of the message. 
     78     * @var string 
     79     */ 
     80    var $Subject           = ""; 
     81 
     82    /** 
     83     * Sets the Body of the message.  This can be either an HTML or text body. 
     84     * If HTML then run IsHTML(true). 
     85     * @var string 
     86     */ 
     87    var $Body               = ""; 
     88 
     89    /** 
     90     * Sets the text-only body of the message.  This automatically sets the 
     91     * email to multipart/alternative.  This body can be read by mail 
     92     * clients that do not have HTML email capability such as mutt. Clients 
     93     * that can read HTML will view the normal Body. 
     94     * @var string 
     95     */ 
     96    var $AltBody           = ""; 
     97 
     98    /** 
     99     * Sets word wrapping on the body of the message to a given number of  
     100     * characters. 
     101     * @var int 
     102     */ 
     103    var $WordWrap          = 0; 
     104 
     105    /** 
     106     * Method to send mail: ("mail", "sendmail", or "smtp"). 
     107     * @var string 
     108     */ 
     109    var $Mailer            = "mail"; 
     110 
     111    /** 
     112     * Sets the path of the sendmail program. 
     113     * @var string 
     114     */ 
     115    var $Sendmail          = "/usr/sbin/sendmail"; 
     116     
     117    /** 
     118     * Path to PHPMailer plugins.  This is now only useful if the SMTP class  
     119     * is in a different directory than the PHP include path.   
     120     * @var string 
     121     */ 
     122    var $PluginDir         = ""; 
     123 
     124    /** 
     125     *  Holds PHPMailer version. 
     126     *  @var string 
     127     */ 
     128    var $Version           = "1.73"; 
     129 
     130    /** 
     131     * Sets the email address that a reading confirmation will be sent. 
     132     * @var string 
     133     */ 
     134    var $ConfirmReadingTo  = ""; 
     135 
     136    /** 
     137     *  Sets the hostname to use in Message-Id and Received headers 
     138     *  and as default HELO string. If empty, the value returned 
     139     *  by SERVER_NAME is used or 'localhost.localdomain'. 
     140     *  @var string 
     141     */ 
     142    var $Hostname          = ""; 
     143 
     144    ///////////////////////////////////////////////// 
     145    // SMTP VARIABLES 
     146    ///////////////////////////////////////////////// 
     147 
     148    /** 
     149     *  Sets the SMTP hosts.  All hosts must be separated by a 
     150     *  semicolon.  You can also specify a different port 
     151     *  for each host by using this format: [hostname:port] 
     152     *  (e.g. "smtp1.example.com:25;smtp2.example.com"). 
     153     *  Hosts will be tried in order. 
     154     *  @var string 
     155     */ 
     156    var $Host        = "localhost"; 
     157 
     158    /** 
     159     *  Sets the default SMTP server port. 
     160     *  @var int 
     161     */ 
     162    var $Port        = 25; 
     163 
     164    /** 
     165     *  Sets the SMTP HELO of the message (Default is $Hostname). 
     166     *  @var string 
     167     */ 
     168    var $Helo        = ""; 
     169 
     170    /** 
     171     *  Sets SMTP authentication. Utilizes the Username and Password variables. 
     172     *  @var bool 
     173     */ 
     174    var $SMTPAuth     = false; 
     175 
     176    /** 
     177     *  Sets SMTP username. 
     178     *  @var string 
     179     */ 
     180    var $Username     = ""; 
     181 
     182    /** 
     183     *  Sets SMTP password. 
     184     *  @var string 
     185     */ 
     186    var $Password     = ""; 
     187 
     188    /** 
     189     *  Sets the SMTP server timeout in seconds. This function will not  
     190     *  work with the win32 version. 
     191     *  @var int 
     192     */ 
     193    var $Timeout      = 10; 
     194 
     195    /** 
     196     *  Sets SMTP class debugging on or off. 
     197     *  @var bool 
     198     */ 
     199    var $SMTPDebug    = false; 
     200 
     201    /** 
     202     * Prevents the SMTP connection from being closed after each mail  
     203     * sending.  If this is set to true then to close the connection  
     204     * requires an explicit call to SmtpClose().  
     205     * @var bool 
     206     */ 
     207    var $SMTPKeepAlive = false; 
     208 
     209    /**#@+ 
     210     * @access private 
     211     */ 
     212    var $smtp            = NULL; 
     213    var $to              = array(); 
     214    var $cc              = array(); 
     215    var $bcc             = array(); 
     216    var $ReplyTo         = array(); 
     217    var $attachment      = array(); 
     218    var $CustomHeader    = array(); 
     219    var $message_type    = ""; 
     220    var $boundary        = array(); 
     221    var $language        = array(); 
     222    var $error_count     = 0; 
     223    var $LE              = "\n"; 
     224    /**#@-*/ 
     225     
     226    ///////////////////////////////////////////////// 
     227    // VARIABLE METHODS 
     228    ///////////////////////////////////////////////// 
     229 
     230    /** 
     231     * Sets message type to HTML.   
     232     * @param bool $bool 
     233     * @return void 
     234     */ 
     235    function IsHTML($bool) { 
     236        if($bool == true) 
     237            $this->ContentType = "text/html"; 
     238        else 
     239            $this->ContentType = "text/plain"; 
     240    } 
     241 
     242    /** 
     243     * Sets Mailer to send message using SMTP. 
     244     * @return void 
     245     */ 
     246    function IsSMTP() { 
     247        $this->Mailer = "smtp"; 
     248    } 
     249 
     250    /** 
     251     * Sets Mailer to send message using PHP mail() function. 
     252     * @return void 
     253     */ 
     254    function IsMail() { 
     255        $this->Mailer = "mail"; 
     256    } 
     257 
     258    /** 
     259     * Sets Mailer to send message using the $Sendmail program. 
     260     * @return void 
     261     */ 
     262    function IsSendmail() { 
     263        $this->Mailer = "sendmail"; 
     264    } 
     265 
     266    /** 
     267     * Sets Mailer to send message using the qmail MTA.  
     268     * @return void 
     269     */ 
     270    function IsQmail() { 
     271        $this->Sendmail = "/var/qmail/bin/sendmail"; 
     272        $this->Mailer = "sendmail"; 
     273    } 
     274 
     275 
     276    ///////////////////////////////////////////////// 
     277    // RECIPIENT METHODS 
     278    ///////////////////////////////////////////////// 
     279 
     280    /** 
     281     * Adds a "To" address.   
     282     * @param string $address 
     283     * @param string $name 
     284     * @return void 
     285     */ 
     286    function AddAddress($address, $name = "") { 
     287        $cur = count($this->to); 
     288        $this->to[$cur][0] = trim($address); 
     289        $this->to[$cur][1] = $name; 
     290    } 
     291 
     292    /** 
     293     * Adds a "Cc" address. Note: this function works 
     294     * with the SMTP mailer on win32, not with the "mail" 
     295     * mailer.   
     296     * @param string $address 
     297     * @param string $name 
     298     * @return void 
     299    */ 
     300    function AddCC($address, $name = "") { 
     301        $cur = count($this->cc); 
     302        $this->cc[$cur][0] = trim($address); 
     303        $this->cc[$cur][1] = $name; 
     304    } 
     305 
     306    /** 
     307     * Adds a "Bcc" address. Note: this function works 
     308     * with the SMTP mailer on win32, not with the "mail" 
     309     * mailer.   
     310     * @param string $address 
     311     * @param string $name 
     312     * @return void 
     313     */ 
     314    function AddBCC($address, $name = "") { 
     315        $cur = count($this->bcc); 
     316        $this->bcc[$cur][0] = trim($address); 
     317        $this->bcc[$cur][1] = $name; 
     318    } 
     319 
     320    /** 
     321     * Adds a "Reply-to" address.   
     322     * @param string $address 
     323     * @param string $name 
     324     * @return void 
     325     */ 
     326    function AddReplyTo($address, $name = "") { 
     327        $cur = count($this->ReplyTo); 
     328        $this->ReplyTo[$cur][0] = trim($address); 
     329        $this->ReplyTo[$cur][1] = $name; 
     330    } 
     331 
     332 
     333    ///////////////////////////////////////////////// 
     334    // MAIL SENDING METHODS 
     335    ///////////////////////////////////////////////// 
     336 
     337    /** 
     338     * Creates message and assigns Mailer. If the message is 
     339     * not sent successfully then it returns false.  Use the ErrorInfo 
     340     * variable to view description of the error.   
     341     * @return bool 
     342     */ 
     343    function Send() { 
     344        $header = ""; 
     345        $body = ""; 
     346        $result = true; 
     347 
     348        if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) 
     349        { 
     350            $this->SetError($this->Lang("provide_address")); 
     351            return false; 
     352        } 
     353 
     354        // Set whether the message is multipart/alternative 
     355        if(!empty($this->AltBody)) 
     356            $this->ContentType = "multipart/alternative"; 
     357 
     358        $this->error_count = 0; // reset errors 
     359        $this->SetMessageType(); 
     360        $header .= $this->CreateHeader(); 
     361        $body = $this->CreateBody(); 
     362 
     363        if($body == "") { return false; } 
     364 
     365        // Choose the mailer 
     366        switch($this->Mailer) 
     367        { 
     368            case "sendmail": 
     369                $result = $this->SendmailSend($header, $body); 
     370                break; 
     371            case "mail": 
     372                $result = $this->MailSend($header, $body); 
     373                break; 
     374            case "smtp": 
     375                $result = $this->SmtpSend($header, $body); 
     376                break; 
     377            default: 
     378            $this->SetError($this->Mailer . $this->Lang("mailer_not_supported")); 
     379                $result = false; 
     380                break; 
     381        } 
     382 
     383        return $result; 
     384    } 
     385     
     386    /** 
     387     * Sends mail using the $Sendmail program.   
     388     * @access private 
     389     * @return bool 
     390     */ 
     391    function SendmailSend($header, $body) { 
     392        if ($this->Sender != "") 
     393            $sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, $this->Sender); 
     394        else 
     395            $sendmail = sprintf("%s -oi -t", $this->Sendmail); 
     396 
     397        if(!@$mail = popen($sendmail, "w")) 
     398        { 
     399            $this->SetError($this->Lang("execute") . $this->Sendmail); 
     400            return false; 
     401        } 
     402 
     403        fputs($mail, $header); 
     404        fputs($mail, $body); 
     405         
     406        $result = pclose($mail) >> 8 & 0xFF; 
     407        if($result != 0) 
     408        { 
     409            $this->SetError($this->Lang("execute") . $this->Sendmail); 
     410            return false; 
     411        } 
     412 
     413        return true; 
     414    } 
     415 
     416    /** 
     417     * Sends mail using the PHP mail() function.   
     418     * @access private 
     419     * @return bool 
     420     */ 
     421    function MailSend($header, $body) { 
     422        $to = ""; 
     423        for($i = 0; $i < count($this->to); $i++) 
     424        { 
     425            if($i != 0) { $to .= ", "; } 
     426            $to .= $this->to[$i][0]; 
     427        } 
     428 
     429        if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1) 
     430        { 
     431            $old_from = ini_get("sendmail_from"); 
     432            ini_set("sendmail_from", $this->Sender); 
     433            $params = sprintf("-oi -f %s", $this->Sender); 
     434            $rt = @mail($to, $this->EncodeHeader($this->Subject), $body,  
     435                        $header, $params); 
     436        } 
     437        else 
     438            $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header); 
     439 
     440        if (isset($old_from)) 
     441            ini_set("sendmail_from", $old_from); 
     442 
     443        if(!$rt) 
     444        { 
     445            $this->SetError($this->Lang("instantiate")); 
     446            return false; 
     447        } 
     448 
     449        return true; 
     450    } 
     451 
     452    /** 
     453     * Sends mail via SMTP using PhpSMTP (Author: 
     454     * Chris Ryan).  Returns bool.  Returns false if there is a 
     455     * bad MAIL FROM, RCPT, or DATA input. 
     456     * @access private 
     457     * @return bool 
     458     */ 
     459    function SmtpSend($header, $body) { 
     460        include_once($this->PluginDir . "class.smtp.php"); 
     461        $error = ""; 
     462        $bad_rcpt = array(); 
     463 
     464        if(!$this->SmtpConnect()) 
     465            return false; 
     466 
     467        $smtp_from = ($this->Sender == "") ? $this->From : $this->Sender; 
     468        if(!$this->smtp->Mail($smtp_from)) 
     469        { 
     470            $error = $this->Lang("from_failed") . $smtp_from; 
     471            $this->SetError($error); 
     472            $this->smtp->Reset(); 
     473            return false; 
     474        } 
     475 
     476        // Attempt to send attach all recipients 
     477        for($i = 0; $i < count($this->to); $i++) 
     478        { 
     479            if(!$this->smtp->Recipient($this->to[$i][0])) 
     480                $bad_rcpt[] = $this->to[$i][0]; 
     481        } 
     482        for($i = 0; $i < count($this->cc); $i++) 
     483        { 
     484            if(!$this->smtp->Recipient($this->cc[$i][0])) 
     485                $bad_rcpt[] = $this->cc[$i][0]; 
     486        } 
     487        for($i = 0; $i < count($this->bcc); $i++) 
     488        { 
     489            if(!$this->smtp->Recipient($this->bcc[$i][0])) 
     490                $bad_rcpt[] = $this->bcc[$i][0]; 
     491        } 
     492 
     493        if(count($bad_rcpt) > 0) // Create error message 
     494        { 
     495            for($i = 0; $i < count($bad_rcpt); $i++) 
     496            { 
     497                if($i != 0) { $error .= ", "; } 
     498                $error .= $bad_rcpt[$i]; 
     499            } 
     500            $error = $this->Lang("recipients_failed") . $error; 
     501            $this->SetError($error); 
     502            $this->smtp->Reset(); 
     503            return false; 
     504        } 
     505 
     506        if(!$this->smtp->Data($header . $body)) 
     507        { 
     508            $this->SetError($this->Lang("data_not_accepted")); 
     509            $this->smtp->Reset(); 
     510            return false; 
     511        } 
     512        if($this->SMTPKeepAlive == true) 
     513            $this->smtp->Reset(); 
     514        else 
     515            $this->SmtpClose(); 
     516 
     517        return true; 
     518    } 
     519 
     520    /** 
     521     * Initiates a connection to an SMTP server.  Returns false if the  
     522     * operation failed. 
     523     * @access private 
     524     * @return bool 
     525     */ 
     526    function SmtpConnect() { 
     527        if($this->smtp == NULL) { $this->smtp = new SMTP(); } 
     528 
     529        $this->smtp->do_debug = $this->SMTPDebug; 
     530        $hosts = explode(";", $this->Host); 
     531        $index = 0; 
     532        $connection = ($this->smtp->Connected());  
     533 
     534        // Retry while there is no connection 
     535        while($index < count($hosts) && $connection == false) 
     536        { 
     537            if(strstr($hosts[$index], ":")) 
     538                list($host, $port) = explode(":", $hosts[$index]); 
     539            else 
     540            { 
     541                $host = $hosts[$index]; 
     542                $port = $this->Port; 
     543            } 
     544 
     545            if($this->smtp->Connect($host, $port, $this->Timeout)) 
     546            { 
     547                if ($this->Helo != '') 
     548                    $this->smtp->Hello($this->Helo); 
     549                else 
     550                    $this->smtp->Hello($this->ServerHostname()); 
     551         
     552                if($this->SMTPAuth) 
     553                { 
     554                    if(!$this->smtp->Authenticate($this->Username,  
     555                                                  $this->Password)) 
     556                    { 
     557                        $this->SetError($this->Lang("authenticate")); 
     558                        $this->smtp->Reset(); 
     559                        $connection = false; 
     560                    } 
     561                } 
     562                $connection = true; 
     563            } 
     564            $index++; 
     565        } 
     566        if(!$connection) 
     567            $this->SetError($this->Lang("connect_host")); 
     568 
     569        return $connection; 
     570    } 
     571 
     572    /** 
     573     * Closes the active SMTP session if one exists. 
     574     * @return void 
     575     */ 
     576    function SmtpClose() { 
     577        if($this->smtp != NULL) 
     578        { 
     579            if($this->smtp->Connected()) 
     580            { 
     581                $this->smtp->Quit(); 
     582                $this->smtp->Close(); 
     583            } 
     584        } 
     585    } 
     586 
     587    /** 
     588     * Sets the language for all class error messages.  Returns false  
     589     * if it cannot load the language file.  The default language type 
     590     * is English. 
     591     * @param string $lang_type Type of language (e.g. Portuguese: "br") 
     592     * @param string $lang_path Path to the language file directory 
     593     * @access public 
     594     * @return bool 
     595     */ 
     596    function SetLanguage($lang_type, $lang_path = "language/") { 
     597        if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) 
     598            include($lang_path.'phpmailer.lang-'.$lang_type.'.php'); 
     599        else if(file_exists($lang_path.'phpmailer.lang-en.php')) 
     600            include($lang_path.'phpmailer.lang-en.php'); 
     601        else 
     602        { 
     603            $this->SetError("Could not load language file"); 
     604            return false; 
     605        } 
     606        $this->language = $PHPMAILER_LANG; 
     607     
     608        return true; 
     609    } 
     610 
     611    ///////////////////////////////////////////////// 
     612    // MESSAGE CREATION METHODS 
     613    ///////////////////////////////////////////////// 
     614 
     615    /** 
     616     * Creates recipient headers.   
     617     * @access private 
     618     * @return string 
     619     */ 
     620    function AddrAppend($type, $addr) { 
     621        $addr_str = $type . ": "; 
     622        $addr_str .= $this->AddrFormat($addr[0]); 
     623        if(count($addr) > 1) 
     624        { 
     625            for($i = 1; $i < count($addr); $i++) 
     626                $addr_str .= ", " . $this->AddrFormat($addr[$i]); 
     627        } 
     628        $addr_str .= $this->LE; 
     629 
     630        return $addr_str; 
     631    } 
     632     
     633    /** 
     634     * Formats an address correctly.  
     635     * @access private 
     636     * @return string 
     637     */ 
     638    function AddrFormat($addr) { 
     639        if(empty($addr[1])) 
     640            $formatted = $addr[0]; 
     641        else 
     642        { 
     643            $formatted = $this->EncodeHeader($addr[1], 'phrase') . " <" .  
     644                         $addr[0] . ">"; 
     645        } 
     646 
     647        return $formatted; 
     648    } 
     649 
     650    /** 
     651     * Wraps message for use with mailers that do not 
     652     * automatically perform wrapping and for quoted-printable. 
     653     * Original written by philippe.   
     654     * @access private 
     655     * @return string 
     656     */ 
     657    function WrapText($message, $length, $qp_mode = false) { 
     658        $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; 
     659 
     660        $message = $this->FixEOL($message); 
     661        if (substr($message, -1) == $this->LE) 
     662            $message = substr($message, 0, -1); 
     663 
     664        $line = explode($this->LE, $message); 
     665        $message = ""; 
     666        for ($i=0 ;$i < count($line); $i++) 
     667        { 
     668          $line_part = explode(" ", $line[$i]); 
     669          $buf = ""; 
     670          for ($e = 0; $e<count($line_part); $e++) 
     671          { 
     672              $word = $line_part[$e]; 
     673              if ($qp_mode and (strlen($word) > $length)) 
     674              { 
     675                $space_left = $length - strlen($buf) - 1; 
     676                if ($e != 0) 
     677                { 
     678                    if ($space_left > 20) 
     679                    { 
     680                        $len = $space_left; 
     681                        if (substr($word, $len - 1, 1) == "=") 
     682                          $len--; 
     683                        elseif (substr($word, $len - 2, 1) == "=") 
     684                          $len -= 2; 
     685                        $part = substr($word, 0, $len); 
     686                        $word = substr($word, $len); 
     687                        $buf .= " " . $part; 
     688                        $message .= $buf . sprintf("=%s", $this->LE); 
     689                    } 
     690                    else 
     691                    { 
     692                        $message .= $buf . $soft_break; 
     693                    } 
     694                    $buf = ""; 
     695                } 
     696                while (strlen($word) > 0) 
     697                { 
     698                    $len = $length; 
     699                    if (substr($word, $len - 1, 1) == "=") 
     700                        $len--; 
     701                    elseif (substr($word, $len - 2, 1) == "=") 
     702                        $len -= 2; 
     703                    $part = substr($word, 0, $len); 
     704                    $word = substr($word, $len); 
     705 
     706                    if (strlen($word) > 0) 
     707                        $message .= $part . sprintf("=%s", $this->LE); 
     708                    else 
     709                        $buf = $part; 
     710                } 
     711              } 
     712              else 
     713              { 
     714                $buf_o = $buf; 
     715                $buf .= ($e == 0) ? $word : (" " . $word);  
     716 
     717                if (strlen($buf) > $length and $buf_o != "") 
     718                { 
     719                    $message .= $buf_o . $soft_break; 
     720                    $buf = $word; 
     721                } 
     722              } 
     723          } 
     724          $message .= $buf . $this->LE; 
     725        } 
     726 
     727        return $message; 
     728    } 
     729     
     730    /** 
     731     * Set the body wrapping. 
     732     * @access private 
     733     * @return void 
     734     */ 
     735    function SetWordWrap() { 
     736        if($this->WordWrap < 1) 
     737            return; 
     738             
     739        switch($this->message_type) 
     740        { 
     741           case "alt": 
     742              // fall through 
     743           case "alt_attachments": 
     744              $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); 
     745              break; 
     746           default: 
     747              $this->Body = $this->WrapText($this->Body, $this->WordWrap); 
     748              break; 
     749        } 
     750    } 
     751 
     752    /** 
     753     * Assembles message header.   
     754     * @access private 
     755     * @return string 
     756     */ 
     757    function CreateHeader() { 
     758        $result = ""; 
     759         
     760        // Set the boundaries 
     761        $uniq_id = md5(uniqid(time())); 
     762        $this->boundary[1] = "b1_" . $uniq_id; 
     763        $this->boundary[2] = "b2_" . $uniq_id; 
     764 
     765        $result .= $this->HeaderLine("Date", $this->RFCDate()); 
     766        if($this->Sender == "") 
     767            $result .= $this->HeaderLine("Return-Path", trim($this->From)); 
     768        else 
     769            $result .= $this->HeaderLine("Return-Path", trim($this->Sender)); 
     770         
     771        // To be created automatically by mail() 
     772        if($this->Mailer != "mail") 
     773        { 
     774            if(count($this->to) > 0) 
     775                $result .= $this->AddrAppend("To", $this->to); 
     776            else if (count($this->cc) == 0) 
     777                $result .= $this->HeaderLine("To", "undisclosed-recipients:;"); 
     778            if(count($this->cc) > 0) 
     779                $result .= $this->AddrAppend("Cc", $this->cc); 
     780        } 
     781 
     782        $from = array(); 
     783        $from[0][0] = trim($this->From); 
     784        $from[0][1] = $this->FromName; 
     785        $result .= $this->AddrAppend("From", $from);  
     786 
     787        // sendmail and mail() extract Bcc from the header before sending 
     788        if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0)) 
     789            $result .= $this->AddrAppend("Bcc", $this->bcc); 
     790 
     791        if(count($this->ReplyTo) > 0) 
     792            $result .= $this->AddrAppend("Reply-to", $this->ReplyTo); 
     793 
     794        // mail() sets the subject itself 
     795        if($this->Mailer != "mail") 
     796            $result .= $this->HeaderLine("Subject", $this->EncodeHeader(trim($this->Subject))); 
     797 
     798        $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); 
     799        $result .= $this->HeaderLine("X-Priority", $this->Priority); 
     800         
     801        if($this->ConfirmReadingTo != "") 
     802        { 
     803            $result .= $this->HeaderLine("Disposition-Notification-To",  
     804                       "<" . trim($this->ConfirmReadingTo) . ">"); 
     805        } 
     806 
     807        // Add custom headers 
     808        for($index = 0; $index < count($this->CustomHeader); $index++) 
     809        { 
     810            $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]),  
     811                       $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); 
     812        } 
     813        $result .= $this->HeaderLine("MIME-Version", "1.0"); 
     814 
     815        switch($this->message_type) 
     816        { 
     817            case "plain": 
     818                $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding); 
     819                $result .= sprintf("Content-Type: %s; charset=\"%s\"", 
     820                                    $this->ContentType, $this->CharSet); 
     821                break; 
     822            case "attachments": 
     823                // fall through 
     824            case "alt_attachments": 
     825                if($this->InlineImageExists()) 
     826                { 
     827                    $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s",  
     828                                    "multipart/related", $this->LE, $this->LE,  
     829                                    $this->boundary[1], $this->LE); 
     830                } 
     831                else 
     832                { 
     833                    $result .= $this->HeaderLine("Content-Type", "multipart/mixed;"); 
     834                    $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 
     835                } 
     836                break; 
     837            case "alt": 
     838                $result .= $this->HeaderLine("Content-Type", "multipart/alternative;"); 
     839                $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 
     840                break; 
     841        } 
     842 
     843        if($this->Mailer != "mail") 
     844            $result .= $this->LE.$this->LE; 
     845 
     846        return $result; 
     847    } 
     848 
     849    /** 
     850     * Assembles the message body.  Returns an empty string on failure. 
     851     * @access private 
     852     * @return string 
     853     */ 
     854    function CreateBody() { 
     855        $result = ""; 
     856 
     857        $this->SetWordWrap(); 
     858 
     859        switch($this->message_type) 
     860        { 
     861            case "alt": 
     862                $result .= $this->GetBoundary($this->boundary[1], "",  
     863                                              "text/plain", ""); 
     864                $result .= $this->EncodeString($this->AltBody, $this->Encoding); 
     865                $result .= $this->LE.$this->LE; 
     866                $result .= $this->GetBoundary($this->boundary[1], "",  
     867                                              "text/html", ""); 
     868                 
     869                $result .= $this->EncodeString($this->Body, $this->Encoding); 
     870                $result .= $this->LE.$this->LE; 
     871     
     872                $result .= $this->EndBoundary($this->boundary[1]); 
     873                break; 
     874            case "plain": 
     875                $result .= $this->EncodeString($this->Body, $this->Encoding); 
     876                break; 
     877            case "attachments": 
     878                $result .= $this->GetBoundary($this->boundary[1], "", "", ""); 
     879                $result .= $this->EncodeString($this->Body, $this->Encoding); 
     880                $result .= $this->LE; 
     881      
     882                $result .= $this->AttachAll(); 
     883                break; 
     884            case "alt_attachments": 
     885                $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); 
     886                $result .= sprintf("Content-Type: %s;%s" . 
     887                                   "\tboundary=\"%s\"%s", 
     888                                   "multipart/alternative", $this->LE,  
     889                                   $this->boundary[2], $this->LE.$this->LE); 
     890     
     891                // Create text body 
     892                $result .= $this->GetBoundary($this->boundary[2], "",  
     893                                              "text/plain", "") . $this->LE; 
     894 
     895                $result .= $this->EncodeString($this->AltBody, $this->Encoding); 
     896                $result .= $this->LE.$this->LE; 
     897     
     898                // Create the HTML body 
     899                $result .= $this->GetBoundary($this->boundary[2], "",  
     900                                              "text/html", "") . $this->LE; 
     901     
     902                $result .= $this->EncodeString($this->Body, $this->Encoding); 
     903                $result .= $this->LE.$this->LE; 
     904 
     905                $result .= $this->EndBoundary($this->boundary[2]); 
     906                 
     907                $result .= $this->AttachAll(); 
     908                break; 
     909        } 
     910        if($this->IsError()) 
     911            $result = ""; 
     912 
     913        return $result; 
     914    } 
     915 
     916    /** 
     917     * Returns the start of a message boundary. 
     918     * @access private 
     919     */ 
     920    function GetBoundary($boundary, $charSet, $contentType, $encoding) { 
     921        $result = ""; 
     922        if($charSet == "") { $charSet = $this->CharSet; } 
     923        if($contentType == "") { $contentType = $this->ContentType; } 
     924        if($encoding == "") { $encoding = $this->Encoding; } 
     925 
     926        $result .= $this->TextLine("--" . $boundary); 
     927        $result .= sprintf("Content-Type: %s; charset = \"%s\"",  
     928                            $contentType, $charSet); 
     929        $result .= $this->LE; 
     930        $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding); 
     931        $result .= $this->LE; 
     932        
     933        return $result; 
     934    } 
     935     
     936    /** 
     937     * Returns the end of a message boundary. 
     938     * @access private 
     939     */ 
     940    function EndBoundary($boundary) { 
     941        return $this->LE . "--" . $boundary . "--" . $this->LE;  
     942    } 
     943     
     944    /** 
     945     * Sets the message type. 
     946     * @access private 
     947     * @return void 
     948     */ 
     949    function SetMessageType() { 
     950        if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) 
     951            $this->message_type = "plain"; 
     952        else 
     953        { 
     954            if(count($this->attachment) > 0) 
     955                $this->message_type = "attachments"; 
     956            if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) 
     957                $this->message_type = "alt"; 
     958            if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) 
     959                $this->message_type = "alt_attachments"; 
     960        } 
     961    } 
     962 
     963    /** 
     964     * Returns a formatted header line. 
     965     * @access private 
     966     * @return string 
     967     */ 
     968    function HeaderLine($name, $value) { 
     969        return $name . ": " . $value . $this->LE; 
     970    } 
     971 
     972    /** 
     973     * Returns a formatted mail line. 
     974     * @access private 
     975     * @return string 
     976     */ 
     977    function TextLine($value) { 
     978        return $value . $this->LE; 
     979    } 
     980 
     981    ///////////////////////////////////////////////// 
     982    // ATTACHMENT METHODS 
     983    ///////////////////////////////////////////////// 
     984 
     985    /** 
     986     * Adds an attachment from a path on the filesystem. 
     987     * Returns false if the file could not be found 
     988     * or accessed. 
     989     * @param string $path Path to the attachment. 
     990     * @param string $name Overrides the attachment name. 
     991     * @param string $encoding File encoding (see $Encoding). 
     992     * @param string $type File extension (MIME) type. 
     993     * @return bool 
     994     */ 
     995    function AddAttachment($path, $name = "", $encoding = "base64",  
     996                           $type = "application/octet-stream") { 
     997        if(!@is_file($path)) 
     998        { 
     999            $this->SetError($this->Lang("file_access") . $path); 
     1000            return false; 
     1001        } 
     1002 
     1003        $filename = basename($path); 
     1004        if($name == "") 
     1005            $name = $filename; 
     1006 
     1007        $cur = count($this->attachment); 
     1008        $this->attachment[$cur][0] = $path; 
     1009        $this->attachment[$cur][1] = $filename; 
     1010        $this->attachment[$cur][2] = $name; 
     1011        $this->attachment[$cur][3] = $encoding; 
     1012        $this->attachment[$cur][4] = $type; 
     1013        $this->attachment[$cur][5] = false; // isStringAttachment 
     1014        $this->attachment[$cur][6] = "attachment"; 
     1015        $this->attachment[$cur][7] = 0; 
     1016 
     1017        return true; 
     1018    } 
     1019 
     1020    /** 
     1021     * Attaches all fs, string, and binary attachments to the message. 
     1022     * Returns an empty string on failure. 
     1023     * @access private 
     1024