00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00035
00036
00038
00040
00045
00046
00051
00052
00057
00058
00064
00065
00070
00071
00076
00077
00082
00083
00089
00090
00095
00096
00102
00103
00111
00112
00118
00119
00124
00125
00130
00131
00137
00138
00143
00144
00149
00150
00157
00158
00164
00165
00167
00169
00178
00179
00184
00185
00190
00191
00197
00198
00203
00204
00209
00210
00215
00216
00222
00223
00228
00229
00236
00237
00243
00244
00246
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00265
00267
00273
00274
00275
00276
00277
00278
00279
00280
00285
00286
00287
00288
00293
00294
00295
00296
00301
00302
00303
00304
00309
00310
00311
00312
00313
00315
00317
00324
00325
00326
00327
00328
00329
00338
00339
00340
00341
00342
00343
00352
00353
00354
00355
00356
00357
00364
00365
00366
00367
00368
00369
00371
00373
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 if(!empty($this->AltBody)) {
00392 $this->ContentType = 'multipart/alternative';
00393 }
00394
00395 $this->error_count = 0;
00396 $this->SetMessageType();
00397 $header .= $this->CreateHeader();
00398 $body = $this->CreateBody();
00399
00400 if($body == '') {
00401 return false;
00402 }
00403
00404
00405 switch($this->Mailer) {
00406 case 'sendmail':
00407 $result = $this->SendmailSend($header, $body);
00408 break;
00409 case 'smtp':
00410 $result = $this->SmtpSend($header, $body);
00411 break;
00412 case 'mail':
00413 $result = $this->MailSend($header, $body);
00414 break;
00415 default:
00416 $result = $this->MailSend($header, $body);
00417 break;
00418
00419
00420
00421 }
00422
00423 return $result;
00424 }
00425
00431 public function SendmailSend($header, $body) {
00432 if ($this->Sender != '') {
00433 $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
00434 } else {
00435 $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
00436 }
00437
00438 if(!@$mail = popen($sendmail, 'w')) {
00439 $this->SetError($this->Lang('execute') . $this->Sendmail);
00440 return false;
00441 }
00442
00443 fputs($mail, $header);
00444 fputs($mail, $body);
00445
00446 $result = pclose($mail);
00447 if (version_compare(phpversion(), '4.2.3') == -1) {
00448 $result = $result >> 8 & 0xFF;
00449 }
00450 if($result != 0) {
00451 $this->SetError($this->Lang('execute') . $this->Sendmail);
00452 return false;
00453 }
00454
00455 return true;
00456 }
00457
00463 public function MailSend($header, $body) {
00464
00465 $to = '';
00466 for($i = 0; $i < count($this->to); $i++) {
00467 if($i != 0) { $to .= ', '; }
00468 $to .= $this->AddrFormat($this->to[$i]);
00469 }
00470
00471 $toArr = split(',', $to);
00472
00473 $params = sprintf("-oi -f %s", $this->Sender);
00474 if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) {
00475 $old_from = ini_get('sendmail_from');
00476 ini_set('sendmail_from', $this->Sender);
00477 if ($this->SingleTo === true && count($toArr) > 1) {
00478 foreach ($toArr as $key => $val) {
00479 $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
00480 }
00481 } else {
00482 $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
00483 }
00484 } else {
00485 if ($this->SingleTo === true && count($toArr) > 1) {
00486 foreach ($toArr as $key => $val) {
00487 $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
00488 }
00489 } else {
00490 $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
00491 }
00492 }
00493
00494 if (isset($old_from)) {
00495 ini_set('sendmail_from', $old_from);
00496 }
00497
00498 if(!$rt) {
00499 $this->SetError($this->Lang('instantiate'));
00500 return false;
00501 }
00502
00503 return true;
00504 }
00505
00513 public function SmtpSend($header, $body) {
00514 include_once($this->PluginDir . 'class.smtp.php');
00515 $error = '';
00516 $bad_rcpt = array();
00517
00518 if(!$this->SmtpConnect()) {
00519 return false;
00520 }
00521
00522 $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
00523 if(!$this->smtp->Mail($smtp_from)) {
00524 $error = $this->Lang('from_failed') . $smtp_from;
00525 $this->SetError($error);
00526 $this->smtp->Reset();
00527 return false;
00528 }
00529
00530
00531 for($i = 0; $i < count($this->to); $i++) {
00532 if(!$this->smtp->Recipient($this->to[$i][0])) {
00533 $bad_rcpt[] = $this->to[$i][0];
00534 }
00535 }
00536 for($i = 0; $i < count($this->cc); $i++) {
00537 if(!$this->smtp->Recipient($this->cc[$i][0])) {
00538 $bad_rcpt[] = $this->cc[$i][0];
00539 }
00540 }
00541 for($i = 0; $i < count($this->bcc); $i++) {
00542 if(!$this->smtp->Recipient($this->bcc[$i][0])) {
00543 $bad_rcpt[] = $this->bcc[$i][0];
00544 }
00545 }
00546
00547 if(count($bad_rcpt) > 0) {
00548 for($i = 0; $i < count($bad_rcpt); $i++) {
00549 if($i != 0) {
00550 $error .= ', ';
00551 }
00552 $error .= $bad_rcpt[$i];
00553 }
00554 $error = $this->Lang('recipients_failed') . $error;
00555 $this->SetError($error);
00556 $this->smtp->Reset();
00557 return false;
00558 }
00559
00560 if(!$this->smtp->Data($header . $body)) {
00561 $this->SetError($this->Lang('data_not_accepted'));
00562 $this->smtp->Reset();
00563 return false;
00564 }
00565 if($this->SMTPKeepAlive == true) {
00566 $this->smtp->Reset();
00567 } else {
00568 $this->SmtpClose();
00569 }
00570
00571 return true;
00572 }
00573
00580 public function SmtpConnect() {
00581 if($this->smtp == NULL) {
00582 $this->smtp = new SMTP();
00583 }
00584
00585 $this->smtp->do_debug = $this->SMTPDebug;
00586 $hosts = explode(';', $this->Host);
00587 $index = 0;
00588 $connection = ($this->smtp->Connected());
00589
00590
00591 while($index < count($hosts) && $connection == false) {
00592 $hostinfo = array();
00593 if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) {
00594 $host = $hostinfo[1];
00595 $port = $hostinfo[2];
00596 } else {
00597 $host = $hosts[$index];
00598 $port = $this->Port;
00599 }
00600
00601 $tls = ($this->SMTPSecure == 'tls');
00602 $ssl = ($this->SMTPSecure == 'ssl');
00603
00604 if($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) {
00605
00606 $hello = ($this->Helo != '' ? $this->Hello : $this->ServerHostname());
00607 $this->smtp->Hello($hello);
00608
00609 if($tls) {
00610 if(!$this->smtp->StartTLS()) {
00611 $this->SetError($this->Lang("tls"));
00612 $this->smtp->Reset();
00613 $connection = false;
00614 }
00615
00616
00617 $this->smtp->Hello($hello);
00618 }
00619
00620 $connection = true;
00621 if($this->SMTPAuth) {
00622 if(!$this->smtp->Authenticate($this->Username, $this->Password)) {
00623 $this->SetError($this->Lang('authenticate'));
00624 $this->smtp->Reset();
00625 $connection = false;
00626 }
00627 }
00628 }
00629 $index++;
00630 }
00631 if(!$connection) {
00632 $this->SetError($this->Lang('connect_host'));
00633 }
00634
00635 return $connection;
00636 }
00637
00642 public function SmtpClose() {
00643 if($this->smtp != NULL) {
00644 if($this->smtp->Connected()) {
00645 $this->smtp->Quit();
00646 $this->smtp->Close();
00647 }
00648 }
00649 }
00650
00660 function SetLanguage($lang_type = 'en', $lang_path = 'language/') {
00661 if( !(@include $lang_path.'phpmailer.lang-'.$lang_type.'.php') ) {
00662 $this->SetError('Could not load language file');
00663 return false;
00664 }
00665 $this->language = $PHPMAILER_LANG;
00666 return true;
00667 }
00668
00670
00672
00678 public function AddrAppend($type, $addr) {
00679 $addr_str = $type . ': ';
00680 $addr_str .= $this->AddrFormat($addr[0]);
00681 if(count($addr) > 1) {
00682 for($i = 1; $i < count($addr); $i++) {
00683 $addr_str .= ', ' . $this->AddrFormat($addr[$i]);
00684 }
00685 }
00686 $addr_str .= $this->LE;
00687
00688 return $addr_str;
00689 }
00690
00696 public function AddrFormat($addr) {
00697 if(empty($addr[1])) {
00698 $formatted = $this->SecureHeader($addr[0]);
00699 } else {
00700 $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
00701 }
00702
00703 return $formatted;
00704 }
00705
00713 public function WrapText($message, $length, $qp_mode = false) {
00714 $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
00715
00716
00717 $is_utf8 = (strtolower($this->CharSet) == "utf-8");
00718
00719 $message = $this->FixEOL($message);
00720 if (substr($message, -1) == $this->LE) {
00721 $message = substr($message, 0, -1);
00722 }
00723
00724 $line = explode($this->LE, $message);
00725 $message = '';
00726 for ($i=0 ;$i < count($line); $i++) {
00727 $line_part = explode(' ', $line[$i]);
00728 $buf = '';
00729 for ($e = 0; $e<count($line_part); $e++) {
00730 $word = $line_part[$e];
00731 if ($qp_mode and (strlen($word) > $length)) {
00732 $space_left = $length - strlen($buf) - 1;
00733 if ($e != 0) {
00734 if ($space_left > 20) {
00735 $len = $space_left;
00736 if ($is_utf8) {
00737 $len = $this->UTF8CharBoundary($word, $len);
00738 } elseif (substr($word, $len - 1, 1) == "=") {
00739 $len--;
00740 } elseif (substr($word, $len - 2, 1) == "=") {
00741 $len -= 2;
00742 }
00743 $part = substr($word, 0, $len);
00744 $word = substr($word, $len);
00745 $buf .= ' ' . $part;
00746 $message .= $buf . sprintf("=%s", $this->LE);
00747 } else {
00748 $message .= $buf . $soft_break;
00749 }
00750 $buf = '';
00751 }
00752 while (strlen($word) > 0) {
00753 $len = $length;
00754 if ($is_utf8) {
00755 $len = $this->UTF8CharBoundary($word, $len);
00756 } elseif (substr($word, $len - 1, 1) == "=") {
00757 $len--;
00758 } elseif (substr($word, $len - 2, 1) == "=") {
00759 $len -= 2;
00760 }
00761 $part = substr($word, 0, $len);
00762 $word = substr($word, $len);
00763
00764 if (strlen($word) > 0) {
00765 $message .= $part . sprintf("=%s", $this->LE);
00766 } else {
00767 $buf = $part;
00768 }
00769 }
00770 } else {
00771 $buf_o = $buf;
00772 $buf .= ($e == 0) ? $word : (' ' . $word);
00773
00774 if (strlen($buf) > $length and $buf_o != '') {
00775 $message .= $buf_o . $soft_break;
00776 $buf = $word;
00777 }
00778 }
00779 }
00780 $message .= $buf . $this->LE;
00781 }
00782
00783 return $message;
00784 }
00785
00795 public function UTF8CharBoundary($encodedText, $maxLength) {
00796 $foundSplitPos = false;
00797 $lookBack = 3;
00798 while (!$foundSplitPos) {
00799 $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
00800 $encodedCharPos = strpos($lastChunk, "=");
00801 if ($encodedCharPos !== false) {
00802
00803
00804 $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
00805 $dec = hexdec($hex);
00806 if ($dec < 128) {
00807
00808
00809 $maxLength = ($encodedCharPos == 0) ? $maxLength :
00810 $maxLength - ($lookBack - $encodedCharPos);
00811 $foundSplitPos = true;
00812 } elseif ($dec >= 192) {
00813
00814 $maxLength = $maxLength - ($lookBack - $encodedCharPos);
00815 $foundSplitPos = true;
00816 } elseif ($dec < 192) {
00817 $lookBack += 3;
00818 }
00819 } else {
00820
00821 $foundSplitPos = true;
00822 }
00823 }
00824 return $maxLength;
00825 }
00826
00827
00833 public function SetWordWrap() {
00834 if($this->WordWrap < 1) {
00835 return;
00836 }
00837
00838 switch($this->message_type) {
00839 case 'alt':
00840
00841 case 'alt_attachments':
00842 $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
00843 break;
00844 default:
00845 $this->Body = $this->WrapText($this->Body, $this->WordWrap);
00846 break;
00847 }
00848 }
00849
00855 public function CreateHeader() {
00856 $result = '';
00857
00858
00859 $uniq_id = md5(uniqid(time()));
00860 $this->boundary[1] = 'b1_' . $uniq_id;
00861 $this->boundary[2] = 'b2_' . $uniq_id;
00862
00863 $result .= $this->HeaderLine('Date', $this->RFCDate());
00864 if($this->Sender == '') {
00865 $result .= $this->HeaderLine('Return-Path', trim($this->From));
00866 } else {
00867 $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
00868 }
00869
00870
00871 if($this->Mailer != 'mail') {
00872 if(count($this->to) > 0) {
00873 $result .= $this->AddrAppend('To', $this->to);
00874 } elseif (count($this->cc) == 0) {
00875 $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');
00876 }
00877 if(count($this->cc) > 0) {
00878 $result .= $this->AddrAppend('Cc', $this->cc);
00879 }
00880 }
00881
00882 $from = array();
00883 $from[0][0] = trim($this->From);
00884 $from[0][1] = $this->FromName;
00885 $result .= $this->AddrAppend('From', $from);
00886
00887
00888 if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) {
00889 $result .= $this->AddrAppend('Cc', $this->cc);
00890 }
00891
00892
00893 if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
00894 $result .= $this->AddrAppend('Bcc', $this->bcc);
00895 }
00896
00897 if(count($this->ReplyTo) > 0) {
00898 $result .= $this->AddrAppend('Reply-to', $this->ReplyTo);
00899 }
00900
00901
00902 if($this->Mailer != 'mail') {
00903 $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));
00904 }
00905
00906 if($this->MessageID != '') {
00907 $result .= $this->HeaderLine('Message-ID',$this->MessageID);
00908 } else {
00909 $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
00910 }
00911 $result .= $this->HeaderLine('X-Priority', $this->Priority);
00912 $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.codeworxtech.com) [version ' . $this->Version . ']');
00913
00914 if($this->ConfirmReadingTo != '') {
00915 $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
00916 }
00917
00918
00919 for($index = 0; $index < count($this->CustomHeader); $index++) {
00920 $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
00921 }
00922
00923 if (!$this->sign_key_file) {
00924 $result .= $this->HeaderLine('MIME-Version', '1.0');
00925 $result .= $this->GetMailMIME();
00926 }
00927
00928 return $result;
00929 }
00930
00936 public function GetMailMIME() {
00937 $result = '';
00938 switch($this->message_type) {
00939 case 'plain':
00940 $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
00941 $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet);
00942 break;
00943 case 'attachments':
00944
00945 case 'alt_attachments':
00946 if($this->InlineImageExists()){
00947 $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE);
00948 } else {
00949 $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');
00950 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
00951 }
00952 break;
00953 case 'alt':
00954 $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
00955 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
00956 break;
00957 }
00958
00959 if($this->Mailer != 'mail') {
00960 $result .= $this->LE.$this->LE;
00961 }
00962
00963 return $result;
00964 }
00965
00971 public function CreateBody() {
00972 $result = '';
00973
00974 if ($this->sign_key_file) {
00975 $result .= $this->GetMailMIME();
00976 }
00977
00978 $this->SetWordWrap();
00979
00980 switch($this->message_type) {
00981 case 'alt':
00982 $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
00983 $result .= $this->EncodeString($this->AltBody, $this->Encoding);
00984 $result .= $this->LE.$this->LE;
00985 $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
00986 $result .= $this->EncodeString($this->Body, $this->Encoding);
00987 $result .= $this->LE.$this->LE;
00988 $result .= $this->EndBoundary($this->boundary[1]);
00989 break;
00990 case 'plain':
00991 $result .= $this->EncodeString($this->Body, $this->Encoding);
00992 break;
00993 case 'attachments':
00994 $result .= $this->GetBoundary($this->boundary[1], '', '', '');
00995 $result .= $this->EncodeString($this->Body, $this->Encoding);
00996 $result .= $this->LE;
00997 $result .= $this->AttachAll();
00998 break;
00999 case 'alt_attachments':
01000 $result .= sprintf("--%s%s", $this->boundary[1], $this->LE);
01001 $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE);
01002 $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE;
01003 $result .= $this->EncodeString($this->AltBody, $this->Encoding);
01004 $result .= $this->LE.$this->LE;
01005 $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE;
01006 $result .= $this->EncodeString($this->Body, $this->Encoding);
01007 $result .= $this->LE.$this->LE;
01008 $result .= $this->EndBoundary($this->boundary[2]);
01009 $result .= $this->AttachAll();
01010 break;
01011 }
01012
01013 if($this->IsError()) {
01014 $result = '';
01015 } else if ($this->sign_key_file) {
01016 $file = tempnam("", "mail");
01017 $fp = fopen($file, "w");
01018 fwrite($fp, $result);
01019 fclose($fp);
01020 $signed = tempnam("", "signed");
01021
01022 if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_key_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) {
01023 $fp = fopen($signed, "r");
01024 $result = fread($fp, filesize($this->sign_key_file));
01025 fclose($fp);
01026 } else {
01027 $this->SetError($this->Lang("signing").openssl_error_string());
01028 $result = '';
01029 }
01030
01031 unlink($file);
01032 unlink($signed);
01033 }
01034
01035 return $result;
01036 }
01037
01042 public function GetBoundary($boundary, $charSet, $contentType, $encoding) {
01043 $result = '';
01044 if($charSet == '') {
01045 $charSet = $this->CharSet;
01046 }
01047 if($contentType == '') {
01048 $contentType = $this->ContentType;
01049 }
01050 if($encoding == '') {
01051 $encoding = $this->Encoding;
01052 }
01053 $result .= $this->TextLine('--' . $boundary);
01054 $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet);
01055 $result .= $this->LE;
01056 $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
01057 $result .= $this->LE;
01058
01059 return $result;
01060 }
01061
01066 public function EndBoundary($boundary) {
01067 return $this->LE . '--' . $boundary . '--' . $this->LE;
01068 }
01069
01075 public function SetMessageType() {
01076 if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) {
01077 $this->message_type = 'plain';
01078 } else {
01079 if(count($this->attachment) > 0) {
01080 $this->message_type = 'attachments';
01081 }
01082 if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) {
01083 $this->message_type = 'alt';
01084 }
01085 if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) {
01086 $this->message_type = 'alt_attachments';
01087 }
01088 }
01089 }
01090
01091
01092
01093
01094
01095 public function HeaderLine($name, $value) {
01096 return $name . ': ' . $value . $this->LE;
01097 }
01098
01104 public function TextLine($value) {
01105 return $value . $this->LE;
01106 }
01107
01109
01111
01122 public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
01123 if(!@is_file($path)) {
01124 $this->SetError($this->Lang('file_access') . $path);
01125 return false;
01126 }
01127
01128 $filename = basename($path);
01129 if($name == '') {
01130 $name = $filename;
01131 }
01132
01133 $cur = count($this->attachment);
01134 $this->attachment[$cur][0] = $path;
01135 $this->attachment[$cur][1] = $filename;
01136 $this->attachment[$cur][2] = $name;
01137 $this->attachment[$cur][3] = $encoding;
01138 $this->attachment[$cur][4] = $type;
01139 $this->attachment[$cur][5] = false;
01140 $this->attachment[$cur][6] = 'attachment';
01141 $this->attachment[$cur][7] = 0;
01142
01143 return true;
01144 }
01145
01152 public function AttachAll() {
01153
01154 $mime = array();
01155
01156
01157 for($i = 0; $i < count($this->attachment); $i++) {
01158
01159 $bString = $this->attachment[$i][5];
01160 if ($bString) {
01161 $string = $this->attachment[$i][0];
01162 } else {
01163 $path = $this->attachment[$i][0];
01164 }
01165
01166 $filename = $this->attachment[$i][1];
01167 $name = $this->attachment[$i][2];
01168 $encoding = $this->attachment[$i][3];
01169 $type = $this->attachment[$i][4];
01170 $disposition = $this->attachment[$i][6];
01171 $cid = $this->attachment[$i][7];
01172
01173 $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
01174 $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE);
01175 $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
01176
01177 if($disposition == 'inline') {
01178 $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
01179 }
01180
01181 $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $name, $this->LE.$this->LE);
01182
01183
01184 if($bString) {
01185 $mime[] = $this->EncodeString($string, $encoding);
01186 if($this->IsError()) {
01187 return '';
01188 }
01189 $mime[] = $this->LE.$this->LE;
01190 } else {
01191 $mime[] = $this->EncodeFile($path, $encoding);
01192 if($this->IsError()) {
01193 return '';
01194 }
01195 $mime[] = $this->LE.$this->LE;
01196 }
01197 }
01198
01199 $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
01200
01201 return join('', $mime);
01202 }
01203
01210 public function EncodeFile ($path, $encoding = 'base64') {
01211 if(!@$fd = fopen($path, 'rb')) {
01212 $this->SetError($this->Lang('file_open') . $path);
01213 return '';
01214 }
01215 $magic_quotes = get_magic_quotes_runtime();
01216 set_magic_quotes_runtime(0);
01217 $file_buffer = file_get_contents($path);
01218 $file_buffer = $this->EncodeString($file_buffer, $encoding);
01219 fclose($fd);
01220 set_magic_quotes_runtime($magic_quotes);
01221
01222 return $file_buffer;
01223 }
01224
01231 public function EncodeString ($str, $encoding = 'base64') {
01232 $encoded = '';
01233 switch(strtolower($encoding)) {
01234 case 'base64':
01235 $encoded = chunk_split(base64_encode($str), 76, $this->LE);
01236 break;
01237 case '7bit':
01238 case '8bit':
01239 $encoded = $this->FixEOL($str);
01240 if (substr($encoded, -(strlen($this->LE))) != $this->LE)
01241 $encoded .= $this->LE;
01242 break;
01243 case 'binary':
01244 $encoded = $str;
01245 break;
01246 case 'quoted-printable':
01247 $encoded = $this->EncodeQP($str);
01248 break;
01249 default:
01250 $this->SetError($this->Lang('encoding') . $encoding);
01251 break;
01252 }
01253 return $encoded;
01254 }
01255
01261 public function EncodeHeader ($str, $position = 'text') {
01262 $x = 0;
01263
01264 switch (strtolower($position)) {
01265 case 'phrase':
01266 if (!preg_match('/[\200-\377]/', $str)) {
01267
01268 $encoded = addcslashes($str, "\0..\37\177\\\"");
01269 if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
01270 return ($encoded);
01271 } else {
01272 return ("\"$encoded\"");
01273 }
01274 }
01275 $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
01276 break;
01277 case 'comment':
01278 $x = preg_match_all('/[()"]/', $str, $matches);
01279
01280 case 'text':
01281 default:
01282 $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
01283 break;
01284 }
01285
01286 if ($x == 0) {
01287 return ($str);
01288 }
01289
01290 $maxlen = 75 - 7 - strlen($this->CharSet);
01291
01292 if (strlen($str)/3 < $x) {
01293 $encoding = 'B';
01294 if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {
01295
01296
01297 $encoded = $this->Base64EncodeWrapMB($str);
01298 } else {
01299 $encoded = base64_encode($str);
01300 $maxlen -= $maxlen % 4;
01301 $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
01302 }
01303 } else {
01304 $encoding = 'Q';
01305 $encoded = $this->EncodeQ($str, $position);
01306 $encoded = $this->WrapText($encoded, $maxlen, true);
01307 $encoded = str_replace('='.$this->LE, "\n", trim($encoded));
01308 }
01309
01310 $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
01311 $encoded = trim(str_replace("\n", $this->LE, $encoded));
01312
01313 return $encoded;
01314 }
01315
01322 public function HasMultiBytes($str) {
01323 if (function_exists('mb_strlen')) {
01324 return (strlen($str) > mb_strlen($str, $this->CharSet));
01325 } else {
01326 return False;
01327 }
01328 }
01329
01338 public function Base64EncodeWrapMB($str) {
01339 $start = "=?".$this->CharSet."?B?";
01340 $end = "?=";
01341 $encoded = "";
01342
01343 $mb_length = mb_strlen($str, $this->CharSet);
01344
01345 $length = 75 - strlen($start) - strlen($end);
01346
01347 $ratio = $mb_length / strlen($str);
01348
01349 $offset = $avgLength = floor($length * $ratio * .75);
01350
01351 for ($i = 0; $i < $mb_length; $i += $offset) {
01352 $lookBack = 0;
01353
01354 do {
01355 $offset = $avgLength - $lookBack;
01356 $chunk = mb_substr($str, $i, $offset, $this->CharSet);
01357 $chunk = base64_encode($chunk);
01358 $lookBack++;
01359 }
01360 while (strlen($chunk) > $length);
01361
01362 $encoded .= $chunk . $this->LE;
01363 }
01364
01365
01366 $encoded = substr($encoded, 0, -strlen($this->LE));
01367 return $encoded;
01368 }
01369
01377 public function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) {
01378 $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
01379 $lines = preg_split('/(?:\r\n|\r|\n)/', $input);
01380 $eol = "\r\n";
01381 $escape = '=';
01382 $output = '';
01383 while( list(, $line) = each($lines) ) {
01384 $linlen = strlen($line);
01385 $newline = '';
01386 for($i = 0; $i < $linlen; $i++) {
01387 $c = substr( $line, $i, 1 );
01388 $dec = ord( $c );
01389 if ( ( $i == 0 ) && ( $dec == 46 ) ) {
01390 $c = '=2E';
01391 }
01392 if ( $dec == 32 ) {
01393 if ( $i == ( $linlen - 1 ) ) {
01394 $c = '=20';
01395 } else if ( $space_conv ) {
01396 $c = '=20';
01397 }
01398 } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) {
01399 $h2 = floor($dec/16);
01400 $h1 = floor($dec%16);
01401 $c = $escape.$hex[$h2].$hex[$h1];
01402 }
01403 if ( (strlen($newline) + strlen($c)) >= $line_max ) {
01404 $output .= $newline.$escape.$eol;
01405 $newline = '';
01406
01407 if ( $dec == 46 ) {
01408 $c = '=2E';
01409 }
01410 }
01411 $newline .= $c;
01412 }
01413 $output .= $newline.$eol;
01414 }
01415 return trim($output);
01416 }
01417
01423 public function EncodeQ ($str, $position = 'text') {
01424
01425 $encoded = preg_replace("[\r\n]", '', $str);
01426
01427 switch (strtolower($position)) {
01428 case 'phrase':
01429 $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
01430 break;
01431 case 'comment':
01432 $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
01433 case 'text':
01434 default:
01435
01436 $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
01437 "'='.sprintf('%02X', ord('\\1'))", $encoded);
01438 break;
01439 }
01440
01441
01442 $encoded = str_replace(' ', '_', $encoded);
01443
01444 return $encoded;
01445 }
01446
01457 public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
01458
01459 $cur = count($this->attachment);
01460 $this->attachment[$cur][0] = $string;
01461 $this->attachment[$cur][1] = $filename;
01462 $this->attachment[$cur][2] = $filename;
01463 $this->attachment[$cur][3] = $encoding;
01464 $this->attachment[$cur][4] = $type;
01465 $this->attachment[$cur][5] = true;
01466 $this->attachment[$cur][6] = 'attachment';
01467 $this->attachment[$cur][7] = 0;
01468 }
01469
01483 public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
01484
01485 if(!@is_file($path)) {
01486 $this->SetError($this->Lang('file_access') . $path);
01487 return false;
01488 }
01489
01490 $filename = basename($path);
01491 if($name == '') {
01492 $name = $filename;
01493 }
01494
01495
01496 $cur = count($this->attachment);
01497 $this->attachment[$cur][0] = $path;
01498 $this->attachment[$cur][1] = $filename;
01499 $this->attachment[$cur][2] = $name;
01500 $this->attachment[$cur][3] = $encoding;
01501 $this->attachment[$cur][4] = $type;
01502 $this->attachment[$cur][5] = false;
01503 $this->attachment[$cur][6] = 'inline';
01504 $this->attachment[$cur][7] = $cid;
01505
01506 return true;
01507 }
01508
01514 public function InlineImageExists() {
01515 $result = false;
01516 for($i = 0; $i < count($this->attachment); $i++) {
01517 if($this->attachment[$i][6] == 'inline') {
01518 $result = true;
01519 break;
01520 }
01521 }
01522
01523 return $result;
01524 }
01525
01527
01529
01534 public function ClearAddresses() {
01535 $this->to = array();
01536 }
01537
01542 public function ClearCCs() {
01543 $this->cc = array();
01544 }
01545
01550 public function ClearBCCs() {
01551 $this->bcc = array();
01552 }
01553
01558 public function ClearReplyTos() {
01559 $this->ReplyTo = array();
01560 }
01561
01567 public function ClearAllRecipients() {
01568 $this->to = array();
01569 $this->cc = array();
01570 $this->bcc = array();
01571 }
01572
01578 public function ClearAttachments() {
01579 $this->attachment = array();
01580 }
01581
01586 public function ClearCustomHeaders() {
01587 $this->CustomHeader = array();
01588 }
01589
01591
01593
01600 private function SetError($msg) {
01601 $this->error_count++;
01602 $this->ErrorInfo = $msg;
01603 }
01604
01610 private static function RFCDate() {
01611 $tz = date('Z');
01612 $tzs = ($tz < 0) ? '-' : '+';
01613 $tz = abs($tz);
01614 $tz = (int)($tz/3600)*100 + ($tz%3600)/60;
01615 $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz);
01616
01617 return $result;
01618 }
01619
01625 private function ServerHostname() {
01626 if (!empty($this->Hostname)) {
01627 $result = $this->Hostname;
01628 } elseif (isset($_SERVER['SERVER_NAME'])) {
01629 $result = $_SERVER['SERVER_NAME'];
01630 } else {
01631 $result = "localhost.localdomain";
01632 }
01633
01634 return $result;
01635 }
01636
01642 private function Lang($key) {
01643 if(count($this->language) < 1) {
01644 $this->SetLanguage('en');
01645 }
01646
01647 if(isset($this->language[$key])) {
01648 return $this->language[$key];
01649 } else {
01650 return 'Language string failed to load: ' . $key;
01651 }
01652 }
01653
01659 public function IsError() {
01660 return ($this->error_count > 0);
01661 }
01662
01668 private function FixEOL($str) {
01669 $str = str_replace("\r\n", "\n", $str);
01670 $str = str_replace("\r", "\n", $str);
01671 $str = str_replace("\n", $this->LE, $str);
01672 return $str;
01673 }
01674
01680 public function AddCustomHeader($custom_header) {
01681 $this->CustomHeader[] = explode(':', $custom_header, 2);
01682 }
01683
01689 public function MsgHTML($message,$basedir='') {
01690 preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images);
01691 if(isset($images[2])) {
01692 foreach($images[2] as $i => $url) {
01693
01694 if (!preg_match('/^[A-z][A-z]*:\/\//',$url)) {
01695 $filename = basename($url);
01696 $directory = dirname($url);
01697 ($directory == '.')?$directory='':'';
01698 $cid = 'cid:' . md5($filename);
01699 $fileParts = split("\.", $filename);
01700 $ext = $fileParts[1];
01701 $mimeType = $this->_mime_types($ext);
01702 if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; }
01703 if ( strlen($directory) > 1 && substr($basedir,-1) != '/') { $directory .= '/'; }
01704 $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64', $mimeType);
01705 if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) {
01706 $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message);
01707 }
01708 }
01709 }
01710 }
01711 $this->IsHTML(true);
01712 $this->Body = $message;
01713 $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message)));
01714 if ( !empty($textMsg) && empty($this->AltBody) ) {
01715 $this->AltBody = $textMsg;
01716 }
01717 if ( empty($this->AltBody) ) {
01718 $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . "\n\n";
01719 }
01720 }
01721
01727 public function _mime_types($ext = '') {
01728 $mimes = array(
01729 'hqx' => 'application/mac-binhex40',
01730 'cpt' => 'application/mac-compactpro',
01731 'doc' => 'application/msword',
01732 'bin' => 'application/macbinary',
01733 'dms' => 'application/octet-stream',
01734 'lha' => 'application/octet-stream',
01735 'lzh' => 'application/octet-stream',
01736 'exe' => 'application/octet-stream',
01737 'class' => 'application/octet-stream',
01738 'psd' => 'application/octet-stream',
01739 'so' => 'application/octet-stream',
01740 'sea' => 'application/octet-stream',
01741 'dll' => 'application/octet-stream',
01742 'oda' => 'application/oda',
01743 'pdf' => 'application/pdf',
01744 'ai' => 'application/postscript',
01745 'eps' => 'application/postscript',
01746 'ps' => 'application/postscript',
01747 'smi' => 'application/smil',
01748 'smil' => 'application/smil',
01749 'mif' => 'application/vnd.mif',
01750 'xls' => 'application/vnd.ms-excel',
01751 'ppt' => 'application/vnd.ms-powerpoint',
01752 'wbxml' => 'application/vnd.wap.wbxml',
01753 'wmlc' => 'application/vnd.wap.wmlc',
01754 'dcr' => 'application/x-director',
01755 'dir' => 'application/x-director',
01756 'dxr' => 'application/x-director',
01757 'dvi' => 'application/x-dvi',
01758 'gtar' => 'application/x-gtar',
01759 'php' => 'application/x-httpd-php',
01760 'php4' => 'application/x-httpd-php',
01761 'php3' => 'application/x-httpd-php',
01762 'phtml' => 'application/x-httpd-php',
01763 'phps' => 'application/x-httpd-php-source',
01764 'js' => 'application/x-javascript',
01765 'swf' => 'application/x-shockwave-flash',
01766 'sit' => 'application/x-stuffit',
01767 'tar' => 'application/x-tar',
01768 'tgz' => 'application/x-tar',
01769 'xhtml' => 'application/xhtml+xml',
01770 'xht' => 'application/xhtml+xml',
01771 'zip' => 'application/zip',
01772 'mid' => 'audio/midi',
01773 'midi' => 'audio/midi',
01774 'mpga' => 'audio/mpeg',
01775 'mp2' => 'audio/mpeg',
01776 'mp3' => 'audio/mpeg',
01777 'aif' => 'audio/x-aiff',
01778 'aiff' => 'audio/x-aiff',
01779 'aifc' => 'audio/x-aiff',
01780 'ram' => 'audio/x-pn-realaudio',
01781 'rm' => 'audio/x-pn-realaudio',
01782 'rpm' => 'audio/x-pn-realaudio-plugin',
01783 'ra' => 'audio/x-realaudio',
01784 'rv' => 'video/vnd.rn-realvideo',
01785 'wav' => 'audio/x-wav',
01786 'bmp' => 'image/bmp',
01787 'gif' => 'image/gif',
01788 'jpeg' => 'image/jpeg',
01789 'jpg' => 'image/jpeg',
01790 'jpe' => 'image/jpeg',
01791 'png' => 'image/png',
01792 'tiff' => 'image/tiff',
01793 'tif' => 'image/tiff',
01794 'css' => 'text/css',
01795 'html' => 'text/html',
01796 'htm' => 'text/html',
01797 'shtml' => 'text/html',
01798 'txt' => 'text/plain',
01799 'text' => 'text/plain',
01800 'log' => 'text/plain',
01801 'rtx' => 'text/richtext',
01802 'rtf' => 'text/rtf',
01803 'xml' => 'text/xml',
01804 'xsl' => 'text/xml',
01805 'mpeg' => 'video/mpeg',
01806 'mpg' => 'video/mpeg',
01807 'mpe' => 'video/mpeg',
01808 'qt' => 'video/quicktime',
01809 'mov' => 'video/quicktime',
01810 'avi' => 'video/x-msvideo',
01811 'movie' => 'video/x-sgi-movie',
01812 'doc' => 'application/msword',
01813 'word' => 'application/msword',
01814 'xl' => 'application/excel',
01815 'eml' => 'message/rfc822'
01816 );
01817 return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
01818 }
01819
01831 public function set ( $name, $value = '' ) {
01832 if ( isset($this->$name) ) {
01833 $this->$name = $value;
01834 } else {
01835 $this->SetError('Cannot set or reset variable ' . $name);
01836 return false;
01837 }
01838 }
01839
01846 public function getFile($filename) {
01847 $return = '';
01848 if ($fp = fopen($filename, 'rb')) {
01849 while (!feof($fp)) {
01850 $return .= fread($fp, 1024);
01851 }
01852 fclose($fp);
01853 return $return;
01854 } else {
01855 return false;
01856 }
01857 }
01858
01865 public function SecureHeader($str) {
01866 $str = trim($str);
01867 $str = str_replace("\r", "", $str);
01868 $str = str_replace("\n", "", $str);
01869 return $str;
01870 }
01871
01879 public function Sign($key_filename, $key_pass) {
01880 $this->sign_key_file = $key_filename;
01881 $this->sign_key_pass = $key_pass;
01882 }
01883
01884 }
01885
01886 ?>