[ Index ] |
PHP Cross Reference of phpwcms V1.4.7 _r403 (01.11.10) |
[Summary view] [Print] [Text view]
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 */ 20 class 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 = 'iso-8859-1'; 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 = 'root@localhost'; 62 63 /** 64 * Sets the From name of the message. 65 * @var string 66 */ 67 var $FromName = 'Root User'; 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.2'; 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 // Custom enhancement 211 ///////////////////////////////////////////////// 212 213 /** 214 * Use limited headers for mailer method 'mail' 215 * Under some cases there seems to be problems 216 * sending mails by some web servers which works 217 * only base header lines used 218 * @var bool 219 */ 220 var $LimitedMailHeader = false; 221 222 /**#@+ 223 * @access private 224 */ 225 var $smtp = NULL; 226 var $to = array(); 227 var $cc = array(); 228 var $bcc = array(); 229 var $ReplyTo = array(); 230 var $attachment = array(); 231 var $CustomHeader = array(); 232 var $message_type = ''; 233 var $boundary = array(); 234 var $language = array(); 235 var $error_count = 0; 236 var $LE = "\n"; 237 /**#@-*/ 238 239 ///////////////////////////////////////////////// 240 // VARIABLE METHODS 241 ///////////////////////////////////////////////// 242 243 /** 244 * Sets message type to HTML. 245 * @param bool $bool 246 * @return void 247 */ 248 function IsHTML($bool) { 249 if($bool == true) 250 $this->ContentType = 'text/html'; 251 else 252 $this->ContentType = 'text/plain'; 253 } 254 255 /** 256 * Sets Mailer to send message using SMTP. 257 * @return void 258 */ 259 function IsSMTP() { 260 $this->Mailer = 'smtp'; 261 } 262 263 /** 264 * Sets Mailer to send message using PHP mail() function. 265 * @return void 266 */ 267 function IsMail() { 268 $this->Mailer = 'mail'; 269 } 270 271 /** 272 * Sets Mailer to send message using the $Sendmail program. 273 * @return void 274 */ 275 function IsSendmail() { 276 $this->Mailer = 'sendmail'; 277 } 278 279 /** 280 * Sets Mailer to send message using the qmail MTA. 281 * @return void 282 */ 283 function IsQmail() { 284 $this->Sendmail = '/var/qmail/bin/sendmail'; 285 $this->Mailer = 'sendmail'; 286 } 287 288 289 ///////////////////////////////////////////////// 290 // RECIPIENT METHODS 291 ///////////////////////////////////////////////// 292 293 /** 294 * Adds a "To" address. 295 * @param string $address 296 * @param string $name 297 * @return void 298 */ 299 function AddAddress($address, $name = '') { 300 $cur = count($this->to); 301 $this->to[$cur][0] = trim($address); 302 $this->to[$cur][1] = $name; 303 } 304 305 /** 306 * Adds a "Cc" address. Note: this function works 307 * with the SMTP mailer on win32, not with the "mail" 308 * mailer. 309 * @param string $address 310 * @param string $name 311 * @return void 312 */ 313 function AddCC($address, $name = '') { 314 $cur = count($this->cc); 315 $this->cc[$cur][0] = trim($address); 316 $this->cc[$cur][1] = $name; 317 } 318 319 /** 320 * Adds a "Bcc" address. Note: this function works 321 * with the SMTP mailer on win32, not with the "mail" 322 * mailer. 323 * @param string $address 324 * @param string $name 325 * @return void 326 */ 327 function AddBCC($address, $name = '') { 328 $cur = count($this->bcc); 329 $this->bcc[$cur][0] = trim($address); 330 $this->bcc[$cur][1] = $name; 331 } 332 333 /** 334 * Adds a "Reply-to" address. 335 * @param string $address 336 * @param string $name 337 * @return void 338 */ 339 function AddReplyTo($address, $name = '') { 340 $cur = count($this->ReplyTo); 341 $this->ReplyTo[$cur][0] = trim($address); 342 $this->ReplyTo[$cur][1] = $name; 343 } 344 345 346 ///////////////////////////////////////////////// 347 // MAIL SENDING METHODS 348 ///////////////////////////////////////////////// 349 350 /** 351 * Creates message and assigns Mailer. If the message is 352 * not sent successfully then it returns false. Use the ErrorInfo 353 * variable to view description of the error. 354 * @return bool 355 */ 356 function Send() { 357 $header = ''; 358 $body = ''; 359 $result = true; 360 361 if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) 362 { 363 $this->SetError($this->Lang('provide_address')); 364 return false; 365 } 366 367 // Set whether the message is multipart/alternative 368 if(!empty($this->AltBody)) 369 $this->ContentType = 'multipart/alternative'; 370 371 $this->error_count = 0; // reset errors 372 $this->SetMessageType(); 373 $header .= $this->CreateHeader(); 374 $body = $this->CreateBody(); 375 376 if($body == '') { return false; } 377 378 // Choose the mailer 379 switch($this->Mailer) 380 { 381 case 'sendmail': 382 $result = $this->SendmailSend($header, $body); 383 break; 384 case 'mail': 385 $result = $this->MailSend($header, $body); 386 break; 387 case 'smtp': 388 $result = $this->SmtpSend($header, $body); 389 break; 390 default: 391 $this->SetError($this->Mailer . $this->Lang('mailer_not_supported')); 392 $result = false; 393 break; 394 } 395 396 return $result; 397 } 398 399 /** 400 * Sends mail using the $Sendmail program. 401 * @access private 402 * @return bool 403 */ 404 function SendmailSend($header, $body) { 405 if ($this->Sender != '') 406 { 407 //$sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, $this->Sender); 408 // 2007-06-27: bugfix https://sourceforge.net/tracker/index.php?func=detail&aid=1734811&group_id=26031&atid=385707 409 $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender) ); 410 } 411 else 412 { 413 //$sendmail = sprintf("%s -oi -t", $this->Sendmail); 414 // 2007-06-27: bugfix https://sourceforge.net/tracker/index.php?func=detail&aid=1734811&group_id=26031&atid=385707 415 $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail) ); 416 } 417 418 if(!@$mail = popen($sendmail, 'w')) 419 { 420 $this->SetError($this->Lang('execute') . $this->Sendmail); 421 return false; 422 } 423 424 fputs($mail, $header); 425 fputs($mail, $body); 426 427 $result = pclose($mail) >> 8 & 0xFF; 428 if($result != 0) 429 { 430 $this->SetError($this->Lang('execute') . $this->Sendmail); 431 return false; 432 } 433 434 return true; 435 } 436 437 /** 438 * Sends mail using the PHP mail() function. 439 * @access private 440 * @return bool 441 */ 442 function MailSend($header, $body) { 443 $to = ''; 444 for($i = 0; $i < count($this->to); $i++) 445 { 446 if($i != 0) { $to .= ', '; } 447 $to .= $this->to[$i][0]; 448 } 449 450 if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) 451 { 452 $old_from = ini_get('sendmail_from'); 453 ini_set('sendmail_from', $this->Sender); 454 $params = sprintf("-oi -f %s", $this->Sender); 455 $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, 456 $header, $params); 457 } 458 else 459 $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header); 460 461 if (isset($old_from)) 462 ini_set('sendmail_from', $old_from); 463 464 if(!$rt) 465 { 466 $this->SetError($this->Lang('instantiate')); 467 return false; 468 } 469 470 return true; 471 } 472 473 /** 474 * Sends mail via SMTP using PhpSMTP (Author: 475 * Chris Ryan). Returns bool. Returns false if there is a 476 * bad MAIL FROM, RCPT, or DATA input. 477 * @access private 478 * @return bool 479 */ 480 function SmtpSend($header, $body) { 481 include_once($this->PluginDir . 'class.smtp.php'); 482 $error = ''; 483 $bad_rcpt = array(); 484 485 if(!$this->SmtpConnect()) 486 return false; 487 488 $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; 489 if(!$this->smtp->Mail($smtp_from)) 490 { 491 $error = $this->Lang('from_failed') . $smtp_from; 492 $this->SetError($error); 493 $this->smtp->Reset(); 494 return false; 495 } 496 497 // Attempt to send attach all recipients 498 for($i = 0; $i < count($this->to); $i++) 499 { 500 if(!$this->smtp->Recipient($this->to[$i][0])) 501 $bad_rcpt[] = $this->to[$i][0]; 502 } 503 for($i = 0; $i < count($this->cc); $i++) 504 { 505 if(!$this->smtp->Recipient($this->cc[$i][0])) 506 $bad_rcpt[] = $this->cc[$i][0]; 507 } 508 for($i = 0; $i < count($this->bcc); $i++) 509 { 510 if(!$this->smtp->Recipient($this->bcc[$i][0])) 511 $bad_rcpt[] = $this->bcc[$i][0]; 512 } 513 514 if(count($bad_rcpt) > 0) // Create error message 515 { 516 for($i = 0; $i < count($bad_rcpt); $i++) 517 { 518 if($i != 0) { $error .= ', '; } 519 $error .= $bad_rcpt[$i]; 520 } 521 $error = $this->Lang('recipients_failed') . $error; 522 $this->SetError($error); 523 $this->smtp->Reset(); 524 return false; 525 } 526 527 if(!$this->smtp->Data($header . $body)) 528 { 529 $this->SetError($this->Lang('data_not_accepted')); 530 $this->smtp->Reset(); 531 return false; 532 } 533 if($this->SMTPKeepAlive == true) 534 $this->smtp->Reset(); 535 else 536 $this->SmtpClose(); 537 538 return true; 539 } 540 541 /** 542 * Initiates a connection to an SMTP server. Returns false if the 543 * operation failed. 544 * @access private 545 * @return bool 546 */ 547 function SmtpConnect() { 548 if($this->smtp == NULL) { $this->smtp = new SMTP(); } 549 550 $this->smtp->do_debug = $this->SMTPDebug; 551 $hosts = explode(';', $this->Host); 552 $index = 0; 553 $connection = ($this->smtp->Connected()); 554 555 // Retry while there is no connection 556 while($index < count($hosts) && $connection == false) 557 { 558 if(strstr($hosts[$index], ':')) 559 list($host, $port) = explode(':', $hosts[$index]); 560 else 561 { 562 $host = $hosts[$index]; 563 $port = $this->Port; 564 } 565 566 if($this->smtp->Connect($host, $port, $this->Timeout)) 567 { 568 if ($this->Helo != '') 569 $this->smtp->Hello($this->Helo); 570 else 571 $this->smtp->Hello($this->ServerHostname()); 572 573 if($this->SMTPAuth) 574 { 575 if(!$this->smtp->Authenticate($this->Username, $this->Password)) 576 { 577 $this->SetError($this->Lang('authenticate')); 578 $this->smtp->Reset(); 579 $connection = false; 580 } 581 } 582 $connection = true; 583 } 584 $index++; 585 } 586 if(!$connection) 587 $this->SetError($this->Lang('connect_host')); 588 589 return $connection; 590 } 591 592 /** 593 * Closes the active SMTP session if one exists. 594 * @return void 595 */ 596 function SmtpClose() { 597 if($this->smtp != NULL) 598 { 599 if($this->smtp->Connected()) 600 { 601 $this->smtp->Quit(); 602 $this->smtp->Close(); 603 } 604 } 605 } 606 607 /** 608 * Sets the language for all class error messages. Returns false 609 * if it cannot load the language file. The default language type 610 * is English. 611 * @param string $lang_type Type of language (e.g. Portuguese: "br") 612 * @param string $lang_path Path to the language file directory 613 * @param string $default_lang_path Default path to the language file directory 614 * @access public 615 * @return bool 616 */ 617 function SetLanguage($lang_type, $lang_path = '') { 618 $default_lang_path = dirname(__FILE__).'/language/'; 619 if($lang_path == '' || !file_exists($lang_path.'phpmailer.lang-en.php')) { 620 $lang_path = $default_lang_path; 621 } 622 if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) 623 { 624 include($lang_path.'phpmailer.lang-'.$lang_type.'.php'); 625 } 626 elseif(file_exists($lang_path.'phpmailer.lang-en.php')) 627 { 628 include($lang_path.'phpmailer.lang-en.php'); 629 } 630 else 631 { 632 $this->SetError('Could not load language file'); 633 return false; 634 } 635 $this->language = $PHPMAILER_LANG; 636 637 return true; 638 } 639 640 ///////////////////////////////////////////////// 641 // MESSAGE CREATION METHODS 642 ///////////////////////////////////////////////// 643 644 /** 645 * Creates recipient headers. 646 * @access private 647 * @return string 648 */ 649 function AddrAppend($type, $addr) { 650 $addr_str = $type . ': '; 651 $addr_str .= $this->AddrFormat($addr[0]); 652 if(count($addr) > 1) 653 { 654 for($i = 1; $i < count($addr); $i++) 655 $addr_str .= ', ' . $this->AddrFormat($addr[$i]); 656 } 657 $addr_str .= $this->LE; 658 659 return $addr_str; 660 } 661 662 /** 663 * Formats an address correctly. 664 * @access private 665 * @return string 666 */ 667 function AddrFormat($addr) { 668 if(empty($addr[1])) 669 $formatted = $addr[0]; 670 else 671 { 672 $formatted = $this->EncodeHeader($addr[1], 'phrase') . ' <' . 673 $addr[0] . '>'; 674 } 675 676 return $formatted; 677 } 678 679 /** 680 * Wraps message for use with mailers that do not 681 * automatically perform wrapping and for quoted-printable. 682 * Original written by philippe. 683 * @access private 684 * @return string 685 */ 686 function WrapText($message, $length, $qp_mode = false) { 687 $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; 688 689 $message = $this->FixEOL($message); 690 if (substr($message, -1) == $this->LE) 691 $message = substr($message, 0, -1); 692 693 $line = explode($this->LE, $message); 694 $message = ''; 695 for ($i=0 ;$i < count($line); $i++) 696 { 697 $line_part = explode(' ', $line[$i]); 698 $buf = ''; 699 for ($e = 0; $e<count($line_part); $e++) 700 { 701 $word = $line_part[$e]; 702 if ($qp_mode and (strlen($word) > $length)) 703 { 704 // If utf-8 encoding is used, we will need to make sure we don't 705 // split multibyte characters when we wrap 706 $is_utf8 = (strpos(strtolower($this->CharSet),'utf-8') !== False); 707 $space_left = $length - strlen($buf) - 1; 708 if ($e != 0) 709 { 710 if ($space_left > 20) 711 { 712 $len = $space_left; 713 if ($is_utf8) 714 { 715 $len = $this->UTF8CharBoundary($word,$len); 716 } 717 else 718 { 719 if (substr($word, $len - 1, 1) == "=") 720 $len--; 721 elseif (substr($word, $len - 2, 1) == "=") 722 $len -= 2; 723 } 724 $part = substr($word, 0, $len); 725 $word = substr($word, $len); 726 $buf .= ' ' . $part; 727 $message .= $buf . sprintf("=%s", $this->LE); 728 } 729 else 730 { 731 $message .= $buf . $soft_break; 732 } 733 $buf = ''; 734 } 735 while (strlen($word) > 0) 736 { 737 $len = $length; 738 if ($is_utf8) 739 { 740 $len = $this->UTF8CharBoundary($word,$len); 741 } 742 else 743 { 744 if (substr($word, $len - 1, 1) == "=") 745 $len--; 746 elseif (substr($word, $len - 2, 1) == "=") 747 $len -= 2; 748 } 749 750 $part = substr($word, 0, $len); 751 $word = substr($word, $len); 752 753 if (strlen($word) > 0) 754 $message .= $part . sprintf("=%s", $this->LE); 755 else 756 $buf = $part; 757 } 758 } 759 else 760 { 761 $buf_o = $buf; 762 $buf .= ($e == 0) ? $word : (' ' . $word); 763 764 if (strlen($buf) > $length and $buf_o != '') 765 { 766 $message .= $buf_o . $soft_break; 767 $buf = $word; 768 } 769 } 770 } 771 $message .= $buf . $this->LE; 772 } 773 774 return $message; 775 } 776 777 /** 778 * Finds last character boundary prior to $maxLength in a utf-8 779 * Quoted (Printable) Encoded string $encodedText 780 * Original written by Colin Brown. 781 * @param string $encodedText utf8 QP text 782 * @param integer $maxLength finds last character boundary prior to this length 783 * @access private 784 * @return integer 785 */ 786 function UTF8CharBoundary($encodedText, $maxLength) { 787 788 $foundSplitPos = False; 789 $lookBack = 3; 790 791 while (!$foundSplitPos) 792 { 793 $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); 794 $encodedCharPos = strpos($lastChunk,'='); 795 796 if ($encodedCharPos !== False) { 797 // Found start of encoded character byte within last $lookBack chars 798 // Check the encoded byte value (the 2 chars after the '=') 799 $hex = substr($encodedText,$maxLength-$lookBack+$encodedCharPos+1,2); 800 $dec = hexdec($hex); 801 // construct a binary representation of this byte 802 $byte = str_pad(decbin($dec), 8,'0', STR_PAD_LEFT); 803 // First two character tell the type of character byte 804 $isFirstOfMulti = strpos($byte,'11') === 0; 805 $isMiddleOfMulti = strpos($byte,'10') === 0; 806 $isSingle = strpos($byte,'0') === 0; 807 if ($isSingle) 808 { 809 // Single byte character. 810 811 // If the encoded char was found at pos 0, it will fit 812 // otherwise reduce maxLength to start of the encoded char 813 814 $maxLength = $encodedCharPos == 0 ? 815 $maxLength : 816 $maxLength - ($lookBack - $encodedCharPos); 817 $foundSplitPos = True; 818 } 819 elseif ($isFirstOfMulti) 820 { 821 // First byte of a multi byte character 822 823 // Reduce maxLength to split at start of character 824 $maxLength = $maxLength - ($lookBack - $encodedCharPos); 825 $foundSplitPos = True; 826 } 827 elseif ($isMiddleOfMulti) 828 { 829 // Middle byte of a multi byte character, look further back 830 $lookBack += 3; 831 } 832 } else { 833 // no encoded character found 834 $foundSplitPos = True; 835 } 836 } 837 return $maxLength; 838 } 839 840 /** 841 * Set the body wrapping. 842 * @access private 843 * @return void 844 */ 845 function SetWordWrap() { 846 if($this->WordWrap < 1) 847 return; 848 849 switch($this->message_type) 850 { 851 case 'alt': 852 // fall through 853 case 'alt_attachments': 854 $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); 855 break; 856 default: 857 $this->Body = $this->WrapText($this->Body, $this->WordWrap); 858 break; 859 } 860 } 861 862 /** 863 * Assembles message header. 864 * @access private 865 * @return string 866 */ 867 function CreateHeader() { 868 $result = ''; 869 870 // Set the boundaries 871 $uniq_id = md5(uniqid(time())); 872 $this->boundary[1] = 'b1_' . $uniq_id; 873 $this->boundary[2] = 'b2_' . $uniq_id; 874 875 $result .= $this->HeaderLine('Date', $this->RFCDate()); 876 if($this->Sender == '') 877 $result .= $this->HeaderLine('Return-Path', trim($this->From)); 878 else 879 $result .= $this->HeaderLine('Return-Path', trim($this->Sender)); 880 881 // To be created automatically by mail() 882 if($this->Mailer != 'mail') 883 { 884 if(count($this->to) > 0) 885 $result .= $this->AddrAppend('To', $this->to); 886 else if (count($this->cc) == 0) 887 $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); 888 } 889 890 // add CC to header 891 if(count($this->cc) > 0) 892 $result .= $this->AddrAppend('Cc', $this->cc); 893 894 895 $from = array(); 896 $from[0][0] = trim($this->From); 897 $from[0][1] = $this->FromName; 898 $result .= $this->AddrAppend('From', $from); 899 900 // sendmail and mail() extract Bcc from the header before sending 901 if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) 902 $result .= $this->AddrAppend('Bcc', $this->bcc); 903 904 if(count($this->ReplyTo) > 0) 905 $result .= $this->AddrAppend('Reply-to', $this->ReplyTo); 906 907 // mail() sets the subject itself 908 if($this->Mailer != 'mail') 909 $result .= $this->HeaderLine('Subject', $this->EncodeHeader(trim($this->Subject))); 910 911 $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); 912 $result .= $this->HeaderLine('X-Priority', $this->Priority); 913 $result .= $this->HeaderLine('X-Mailer', 'PHPMailer [version ' . $this->Version . ']'); 914 915 if($this->ConfirmReadingTo != '') 916 { 917 $result .= $this->HeaderLine('Disposition-Notification-To', 918 '<' . trim($this->ConfirmReadingTo) . '>'); 919 } 920 921 // Add custom headers 922 for($index = 0; $index < count($this->CustomHeader); $index++) 923 { 924 $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), 925 $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); 926 } 927 $result .= $this->HeaderLine('MIME-Version', '1.0'); 928 929 switch($this->message_type) 930 { 931 case 'plain': 932 $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding); 933 $result .= sprintf("Content-Type: %s; charset=\"%s\"", 934 $this->ContentType, $this->CharSet); 935 break; 936 case 'attachments': 937 // fall through 938 case 'alt_attachments': 939 if($this->InlineImageExists()) 940 { 941 $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 942 'multipart/related', $this->LE, $this->LE, 943 $this->boundary[1], $this->LE); 944 } 945 else 946 { 947 $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;'); 948 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 949 } 950 break; 951 case "alt": 952 $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); 953 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 954 break; 955 } 956 957 if($this->Mailer != 'mail') 958 $result .= $this->LE.$this->LE; 959 960 return $result; 961 } 962 963 /** 964 * Assembles the message body. Returns an empty string on failure. 965 * @access private 966 * @return string 967 */ 968 function CreateBody() { 969 $result = ''; 970 971 $this->SetWordWrap(); 972 973 switch($this->message_type) 974 { 975 case 'alt': 976 $result .= $this->GetBoundary($this->boundary[1], '', 977 'text/plain', ''); 978 $result .= $this->EncodeString($this->AltBody, $this->Encoding); 979 $result .= $this->LE.$this->LE; 980 $result .= $this->GetBoundary($this->boundary[1], '', 981 'text/html', ''); 982 983 $result .= $this->EncodeString($this->Body, $this->Encoding); 984 $result .= $this->LE.$this->LE; 985 986 $result .= $this->EndBoundary($this->boundary[1]); 987 break; 988 case 'plain': 989 $result .= $this->EncodeString($this->Body, $this->Encoding); 990 break; 991 case 'attachments': 992 $result .= $this->GetBoundary($this->boundary[1], '', '', ''); 993 $result .= $this->EncodeString($this->Body, $this->Encoding); 994 $result .= $this->LE; 995 996 $result .= $this->AttachAll(); 997 break; 998 case 'alt_attachments': 999 $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); 1000 $result .= sprintf("Content-Type: %s;%s" . 1001 "\tboundary=\"%s\"%s", 1002 'multipart/alternative', $this->LE, 1003 $this->boundary[2], $this->LE.$this->LE); 1004 1005 // Create text body 1006 $result .= $this->GetBoundary($this->boundary[2], '', 1007 'text/plain', '') . $this->LE; 1008 1009 $result .= $this->EncodeString($this->AltBody, $this->Encoding); 1010 $result .= $this->LE.$this->LE; 1011 1012 // Create the HTML body 1013 $result .= $this->GetBoundary($this->boundary[2], '', 1014 'text/html', '') . $this->LE; 1015 1016 $result .= $this->EncodeString($this->Body, $this->Encoding); 1017 $result .= $this->LE.$this->LE; 1018 1019 $result .= $this->EndBoundary($this->boundary[2]); 1020 1021 $result .= $this->AttachAll(); 1022 break; 1023 } 1024 if($this->IsError()) 1025 $result = ''; 1026 1027 return $result; 1028 } 1029 1030 /** 1031 * Returns the start of a message boundary. 1032 * @access private 1033 */ 1034 function GetBoundary($boundary, $charSet, $contentType, $encoding) { 1035 $result = ''; 1036 if($charSet == '') { $charSet = $this->CharSet; } 1037 if($contentType == '') { $contentType = $this->ContentType; } 1038 if($encoding == '') { $encoding = $this->Encoding; } 1039 1040 $result .= $this->TextLine('--' . $boundary); 1041 $result .= sprintf("Content-Type: %s; charset = \"%s\"", 1042 $contentType, $charSet); 1043 $result .= $this->LE; 1044 $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding); 1045 $result .= $this->LE; 1046 1047 return $result; 1048 } 1049 1050 /** 1051 * Returns the end of a message boundary. 1052 * @access private 1053 */ 1054 function EndBoundary($boundary) { 1055 return $this->LE . '--' . $boundary . '--' . $this->LE; 1056 } 1057 1058 /** 1059 * Sets the message type. 1060 * @access private 1061 * @return void 1062 */ 1063 function SetMessageType() { 1064 if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) 1065 $this->message_type = 'plain'; 1066 else 1067 { 1068 if(count($this->attachment) > 0) 1069 $this->message_type = 'attachments'; 1070 if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) 1071 $this->message_type = 'alt'; 1072 if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) 1073 $this->message_type = 'alt_attachments'; 1074 } 1075 } 1076 1077 /** 1078 * Returns a formatted header line. 1079 * @access private 1080 * @return string 1081 */ 1082 function HeaderLine($name, $value) { 1083 return $name . ': ' . $value . $this->LE; 1084 } 1085 1086 /** 1087 * Returns a formatted mail line. 1088 * @access private 1089 * @return string 1090 */ 1091 function TextLine($value) { 1092 return $value . $this->LE; 1093 } 1094 1095 ///////////////////////////////////////////////// 1096 // ATTACHMENT METHODS 1097 ///////////////////////////////////////////////// 1098 1099 /** 1100 * Adds an attachment from a path on the filesystem. 1101 * Returns false if the file could not be found 1102 * or accessed. 1103 * @param string $path Path to the attachment. 1104 * @param string $name Overrides the attachment name. 1105 * @param string $encoding File encoding (see $Encoding). 1106 * @param string $type File extension (MIME) type. 1107 * @return bool 1108 */ 1109 function AddAttachment($path, $name = '', $encoding = 'base64', 1110 $type = 'application/octet-stream') { 1111 if(!@is_file($path)) 1112 { 1113 $this->SetError($this->Lang('file_access') . $path); 1114 return false; 1115 } 1116 1117 $filename = basename($path); 1118 if($name == '') 1119 $name = $filename; 1120 1121 $cur = count($this->attachment); 1122 $this->attachment[$cur][0] = $path; 1123 $this->attachment[$cur][1] = $filename; 1124 $this->attachment[$cur][2] = $name; 1125 $this->attachment[$cur][3] = $encoding; 1126 $this->attachment[$cur][4] = $type; 1127 $this->attachment[$cur][5] = false; // isStringAttachment 1128 $this->attachment[$cur][6] = 'attachment'; 1129 $this->attachment[$cur][7] = 0; 1130 1131 return true; 1132 } 1133 1134 /** 1135 * Attaches all fs, string, and binary attachments to the message. 1136 * Returns an empty string on failure. 1137 * @access private 1138 * @return string 1139 */ 1140 function AttachAll() { 1141 // Return text of body 1142 $mime = array(); 1143 1144 // Add all attachments 1145 for($i = 0; $i < count($this->attachment); $i++) 1146 { 1147 // Check for string attachment 1148 $bString = $this->attachment[$i][5]; 1149 if ($bString) 1150 $string = $this->attachment[$i][0]; 1151 else 1152 $path = $this->attachment[$i][0]; 1153 1154 $filename = $this->attachment[$i][1]; 1155 $name = $this->attachment[$i][2]; 1156 $encoding = $this->attachment[$i][3]; 1157 $type = $this->attachment[$i][4]; 1158 $disposition = $this->attachment[$i][6]; 1159 $cid = $this->attachment[$i][7]; 1160 1161 $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); 1162 $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); 1163 $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); 1164 1165 if($disposition == 'inline') 1166 $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); 1167 1168 $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", 1169 $disposition, $name, $this->LE.$this->LE); 1170 1171 // Encode as string attachment 1172 if($bString) 1173 { 1174 $mime[] = $this->EncodeString($string, $encoding); 1175 if($this->IsError()) { return ''; } 1176 $mime[] = $this->LE.$this->LE; 1177 } 1178 else 1179 { 1180 $mime[] = $this->EncodeFile($path, $encoding); 1181 if($this->IsError()) { return ''; } 1182 $mime[] = $this->LE.$this->LE; 1183 } 1184 } 1185 1186 $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); 1187 1188 return join('', $mime); 1189 } 1190 1191 /** 1192 * Encodes attachment in requested format. Returns an 1193 * empty string on failure. 1194 * @access private 1195 * @return string 1196 */ 1197 function EncodeFile ($path, $encoding = 'base64') { 1198 if(!@$fd = fopen($path, 'rb')) 1199 { 1200 $this->SetError($this->Lang('file_open') . $path); 1201 return ''; 1202 } 1203 $magic_quotes = get_magic_quotes_runtime(); 1204 set_magic_quotes_runtime(0); 1205 $file_buffer = fread($fd, filesize($path)); 1206 $file_buffer = $this->EncodeString($file_buffer, $encoding); 1207 fclose($fd); 1208 set_magic_quotes_runtime($magic_quotes); 1209 1210 return $file_buffer; 1211 } 1212 1213 /** 1214 * Encodes string to requested format. Returns an 1215 * empty string on failure. 1216 * @access private 1217 * @return string 1218 */ 1219 function EncodeString ($str, $encoding = 'base64') { 1220 $encoded = ''; 1221 switch(strtolower($encoding)) { 1222 case 'base64': 1223 // chunk_split is found in PHP >= 3.0.6 1224 $encoded = chunk_split(base64_encode($str), 76, $this->LE); 1225 break; 1226 case '7bit': 1227 case '8bit': 1228 $encoded = $this->FixEOL($str); 1229 if (substr($encoded, -(strlen($this->LE))) != $this->LE) 1230 $encoded .= $this->LE; 1231 break; 1232 case 'binary': 1233 $encoded = $str; 1234 break; 1235 case 'quoted-printable': 1236 $encoded = $this->EncodeQP($str); 1237 break; 1238 default: 1239 $this->SetError($this->Lang('encoding') . $encoding); 1240 break; 1241 } 1242 return $encoded; 1243 } 1244 1245 /** 1246 * Encode a header string to best of Q, B, quoted or none. 1247 * @access private 1248 * @return string 1249 */ 1250 function EncodeHeader ($str, $position = 'text') { 1251 $x = 0; 1252 1253 switch (strtolower($position)) { 1254 case 'phrase': 1255 if (!preg_match('/[\200-\377]/', $str)) { 1256 // Can't use addslashes as we don't know what value has magic_quotes_sybase. 1257 $encoded = addcslashes($str, "\0..\37\177\\\""); 1258 1259 if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) 1260 return ($encoded); 1261 else 1262 return ("\"$encoded\""); 1263 } 1264 $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); 1265 break; 1266 case 'comment': 1267 $x = preg_match_all('/[()"]/', $str, $matches); 1268 // Fall-through 1269 case 'text': 1270 default: 1271 $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); 1272 break; 1273 } 1274 1275 if ($x == 0) 1276 return ($str); 1277 1278 $maxlen = 75 - 7 - strlen($this->CharSet); 1279 // Try to select the encoding which should produce the shortest output 1280 if (strlen($str)/3 < $x) { 1281 $encoding = 'B'; 1282 $encoded = base64_encode($str); 1283 $maxlen -= $maxlen % 4; 1284 $encoded = trim(chunk_split($encoded, $maxlen, "\n")); 1285 } else { 1286 $encoding = 'Q'; 1287 $encoded = $this->EncodeQ($str, $position); 1288 $encoded = $this->WrapText($encoded, $maxlen, true); 1289 $encoded = str_replace('='.$this->LE, "\n", trim($encoded)); 1290 } 1291 1292 $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded); 1293 $encoded = trim(str_replace("\n", $this->LE, $encoded)); 1294 1295 return $encoded; 1296 } 1297 1298 /** 1299 * Encode string to quoted-printable. 1300 * @access private 1301 * @return string 1302 */ 1303 function EncodeQP ($str) { 1304 $encoded = $this->FixEOL($str); 1305 if (substr($encoded, -(strlen($this->LE))) != $this->LE) 1306 $encoded .= $this->LE; 1307 1308 // Replace every high ascii, control and = characters 1309 $encoded = preg_replace('/([\000-\010\013\014\016-\037\075\177-\377])/e', 1310 "'='.sprintf('%02X', ord('\\1'))", $encoded); 1311 // Replace every spaces and tabs when it's the last character on a line 1312 $encoded = preg_replace("/([\011\040])".$this->LE."/e", 1313 "'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded); 1314 1315 // Maximum line length of 76 characters before CRLF (74 + space + '=') 1316 $encoded = $this->WrapText($encoded, 74, true); 1317 1318 return $encoded; 1319 } 1320 1321 /** 1322 * Encode string to q encoding. 1323 * @access private 1324 * @return string 1325 */ 1326 function EncodeQ ($str, $position = 'text') { 1327 // There should not be any EOL in the string 1328 $encoded = preg_replace("[\r\n]", '', $str); 1329 1330 switch (strtolower($position)) { 1331 case 'phrase': 1332 $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 1333 break; 1334 case 'comment': 1335 $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 1336 case 'text': 1337 default: 1338 // Replace every high ascii, control =, ? and _ characters 1339 $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', 1340 "'='.sprintf('%02X', ord('\\1'))", $encoded); 1341 break; 1342 } 1343 1344 // Replace every spaces to _ (more readable than =20) 1345 $encoded = str_replace(' ', '_', $encoded); 1346 1347 return $encoded; 1348 } 1349 1350 /** 1351 * Adds a string or binary attachment (non-filesystem) to the list. 1352 * This method can be used to attach ascii or binary data, 1353 * such as a BLOB record from a database. 1354 * @param string $string String attachment data. 1355 * @param string $filename Name of the attachment. 1356 * @param string $encoding File encoding (see $Encoding). 1357 * @param string $type File extension (MIME) type. 1358 * @return void 1359 */ 1360 function AddStringAttachment($string, $filename, $encoding = 'base64', 1361 $type = 'application/octet-stream') { 1362 // Append to $attachment array 1363 $cur = count($this->attachment); 1364 $this->attachment[$cur][0] = $string; 1365 $this->attachment[$cur][1] = $filename; 1366 $this->attachment[$cur][2] = $filename; 1367 $this->attachment[$cur][3] = $encoding; 1368 $this->attachment[$cur][4] = $type; 1369 $this->attachment[$cur][5] = true; // isString 1370 $this->attachment[$cur][6] = 'attachment'; 1371 $this->attachment[$cur][7] = 0; 1372 } 1373 1374 /** 1375 * Adds an embedded attachment. This can include images, sounds, and 1376 * just about any other document. Make sure to set the $type to an 1377 * image type. For JPEG images use "image/jpeg" and for GIF images 1378 * use "image/gif". 1379 * @param string $path Path to the attachment. 1380 * @param string $cid Content ID of the attachment. Use this to identify 1381 * the Id for accessing the image in an HTML form. 1382 * @param string $name Overrides the attachment name. 1383 * @param string $encoding File encoding (see $Encoding). 1384 * @param string $type File extension (MIME) type. 1385 * @return bool 1386 */ 1387 function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', 1388 $type = 'application/octet-stream') { 1389 1390 if(!@is_file($path)) 1391 { 1392 $this->SetError($this->Lang('file_access') . $path); 1393 return false; 1394 } 1395 1396 $filename = basename($path); 1397 if($name == '') 1398 $name = $filename; 1399 1400 // Append to $attachment array 1401 $cur = count($this->attachment); 1402 $this->attachment[$cur][0] = $path; 1403 $this->attachment[$cur][1] = $filename; 1404 $this->attachment[$cur][2] = $name; 1405 $this->attachment[$cur][3] = $encoding; 1406 $this->attachment[$cur][4] = $type; 1407 $this->attachment[$cur][5] = false; // isStringAttachment 1408 $this->attachment[$cur][6] = 'inline'; 1409 $this->attachment[$cur][7] = $cid; 1410 1411 return true; 1412 } 1413 1414 /** 1415 * Returns true if an inline attachment is present. 1416 * @access private 1417 * @return bool 1418 */ 1419 function InlineImageExists() { 1420 $result = false; 1421 for($i = 0; $i < count($this->attachment); $i++) 1422 { 1423 if($this->attachment[$i][6] == 'inline') 1424 { 1425 $result = true; 1426 break; 1427 } 1428 } 1429 1430 return $result; 1431 } 1432 1433 ///////////////////////////////////////////////// 1434 // MESSAGE RESET METHODS 1435 ///////////////////////////////////////////////// 1436 1437 /** 1438 * Clears all recipients assigned in the TO array. Returns void. 1439 * @return void 1440 */ 1441 function ClearAddresses() { 1442 $this->to = array(); 1443 } 1444 1445 /** 1446 * Clears all recipients assigned in the CC array. Returns void. 1447 * @return void 1448 */ 1449 function ClearCCs() { 1450 $this->cc = array(); 1451 } 1452 1453 /** 1454 * Clears all recipients assigned in the BCC array. Returns void. 1455 * @return void 1456 */ 1457 function ClearBCCs() { 1458 $this->bcc = array(); 1459 } 1460 1461 /** 1462 * Clears all recipients assigned in the ReplyTo array. Returns void. 1463 * @return void 1464 */ 1465 function ClearReplyTos() { 1466 $this->ReplyTo = array(); 1467 } 1468 1469 /** 1470 * Clears all recipients assigned in the TO, CC and BCC 1471 * array. Returns void. 1472 * @return void 1473 */ 1474 function ClearAllRecipients() { 1475 $this->to = array(); 1476 $this->cc = array(); 1477 $this->bcc = array(); 1478 } 1479 1480 /** 1481 * Clears all previously set filesystem, string, and binary 1482 * attachments. Returns void. 1483 * @return void 1484 */ 1485 function ClearAttachments() { 1486 $this->attachment = array(); 1487 } 1488 1489 /** 1490 * Clears all custom headers. Returns void. 1491 * @return void 1492 */ 1493 function ClearCustomHeaders() { 1494 $this->CustomHeader = array(); 1495 } 1496 1497 1498 ///////////////////////////////////////////////// 1499 // MISCELLANEOUS METHODS 1500 ///////////////////////////////////////////////// 1501 1502 /** 1503 * Adds the error message to the error container. 1504 * Returns void. 1505 * @access private 1506 * @return void 1507 */ 1508 function SetError($msg) { 1509 $this->error_count++; 1510 $this->ErrorInfo = $msg; 1511 } 1512 1513 /** 1514 * Returns the proper RFC 822 formatted date. 1515 * @access private 1516 * @return string 1517 */ 1518 function RFCDate() { 1519 $tz = date('Z'); 1520 $tzs = ($tz < 0) ? '-' : '+'; 1521 $tz = abs($tz); 1522 $tz = ($tz/3600)*100 + ($tz%3600)/60; 1523 $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz); 1524 1525 return $result; 1526 } 1527 1528 /** 1529 * Returns the appropriate server variable. Should work with both 1530 * PHP 4.1.0+ as well as older versions. Returns an empty string 1531 * if nothing is found. 1532 * @access private 1533 * @return mixed 1534 */ 1535 function ServerVar($varName) { 1536 global $HTTP_SERVER_VARS; 1537 global $HTTP_ENV_VARS; 1538 1539 if(!isset($_SERVER)) 1540 { 1541 $_SERVER = $HTTP_SERVER_VARS; 1542 if(!isset($_SERVER['REMOTE_ADDR'])) 1543 $_SERVER = $HTTP_ENV_VARS; // must be Apache 1544 } 1545 1546 if(isset($_SERVER[$varName])) 1547 return $_SERVER[$varName]; 1548 else 1549 return ''; 1550 } 1551 1552 /** 1553 * Returns the server hostname or 'localhost.localdomain' if unknown. 1554 * @access private 1555 * @return string 1556 */ 1557 function ServerHostname() { 1558 if ($this->Hostname != '') 1559 $result = $this->Hostname; 1560 elseif ($this->ServerVar('SERVER_NAME') != '') 1561 $result = $this->ServerVar('SERVER_NAME'); 1562 else 1563 $result = 'localhost.localdomain'; 1564 1565 return $result; 1566 } 1567 1568 /** 1569 * Returns a message in the appropriate language. 1570 * @access private 1571 * @return string 1572 */ 1573 function Lang($key) { 1574 if(count($this->language) < 1) 1575 $this->SetLanguage('en'); // set the default language 1576 1577 if(isset($this->language[$key])) 1578 return $this->language[$key]; 1579 else 1580 return 'Language string failed to load: ' . $key; 1581 } 1582 1583 /** 1584 * Returns true if an error occurred. 1585 * @return bool 1586 */ 1587 function IsError() { 1588 return ($this->error_count > 0); 1589 } 1590 1591 /** 1592 * Changes every end of line from CR or LF to CRLF. 1593 * @access private 1594 * @return string 1595 */ 1596 function FixEOL($str) { 1597 $str = str_replace("\r\n", "\n", $str); 1598 $str = str_replace("\r", "\n", $str); 1599 $str = str_replace("\n", $this->LE, $str); 1600 return $str; 1601 } 1602 1603 /** 1604 * Adds a custom header. 1605 * @return void 1606 */ 1607 function AddCustomHeader($custom_header) { 1608 $this->CustomHeader[] = explode(':', $custom_header, 2); 1609 } 1610 } 1611 1612 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Nov 16 22:51:00 2010 | Cross-referenced by PHPXref 0.7 |