72 public $From =
'root@localhost';
586 if ($this->Mailer ==
'smtp') {
607 if (ini_get(
'mbstring.func_overload') & 1) {
612 if (ini_get(
'safe_mode') || !($this->UseSendmailOptions)) {
613 $result = @mail(
$to, $subject, $body, $header);
615 $result = @mail(
$to, $subject, $body, $header, $params);
629 if ($this->SMTPDebug <= 0) {
632 if (is_callable($this->Debugoutput)) {
633 call_user_func($this->Debugoutput, $str, $this->SMTPDebug);
636 switch ($this->Debugoutput) {
644 preg_replace(
'/[\r\n]+/',
'', $str),
653 $str = preg_replace(
'/(\r\n|\r|\n)/ms',
"\n", $str);
654 echo gmdate(
'Y-m-d H:i:s') .
"\t" . str_replace(
670 $this->ContentType =
'text/html';
672 $this->ContentType =
'text/plain';
682 $this->Mailer =
'smtp';
691 $this->Mailer =
'mail';
700 $ini_sendmail_path = ini_get(
'sendmail_path');
702 if (!stristr($ini_sendmail_path,
'sendmail')) {
703 $this->Sendmail =
'/usr/sbin/sendmail';
705 $this->Sendmail = $ini_sendmail_path;
707 $this->Mailer =
'sendmail';
716 $ini_sendmail_path = ini_get(
'sendmail_path');
718 if (!stristr($ini_sendmail_path,
'qmail')) {
719 $this->Sendmail =
'/var/qmail/bin/qmail-inject';
721 $this->Sendmail = $ini_sendmail_path;
723 $this->Mailer =
'qmail';
744 public function addCC($address, $name =
'')
756 public function addBCC($address, $name =
'')
769 return $this->
addAnAddress(
'Reply-To', $address, $name);
784 if (!preg_match(
'/^(to|cc|bcc|Reply-To)$/', $kind)) {
785 $this->
setError($this->
lang(
'Invalid recipient array') .
': ' . $kind);
786 $this->
edebug($this->
lang(
'Invalid recipient array') .
': ' . $kind);
787 if ($this->exceptions) {
792 $address = trim($address);
793 $name = trim(preg_replace(
'/[\r\n]+/',
'', $name));
795 $this->
setError($this->
lang(
'invalid_address') .
': ' . $address);
796 $this->
edebug($this->
lang(
'invalid_address') .
': ' . $address);
797 if ($this->exceptions) {
802 if ($kind !=
'Reply-To') {
803 if (!isset($this->all_recipients[strtolower($address)])) {
804 array_push($this->$kind, array($address, $name));
805 $this->all_recipients[strtolower($address)] =
true;
809 if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
810 $this->ReplyTo[strtolower($address)] = array($address, $name);
825 public function setFrom($address, $name =
'', $auto =
true)
827 $address = trim($address);
828 $name = trim(preg_replace(
'/[\r\n]+/',
'', $name));
830 $this->
setError($this->
lang(
'invalid_address') .
': ' . $address);
831 $this->
edebug($this->
lang(
'invalid_address') .
': ' . $address);
832 if ($this->exceptions) {
837 $this->From = $address;
838 $this->FromName = $name;
840 if (empty($this->Sender)) {
841 $this->Sender = $address;
875 if (!$patternselect or $patternselect ==
'auto') {
878 if (defined(
'PCRE_VERSION')) {
880 if (version_compare(PCRE_VERSION,
'8.0.3') >= 0) {
881 $patternselect =
'pcre8';
883 $patternselect =
'pcre';
885 } elseif (function_exists(
'extension_loaded') and extension_loaded(
'pcre')) {
887 $patternselect =
'pcre';
890 if (version_compare(PHP_VERSION,
'5.2.0') >= 0) {
891 $patternselect =
'php';
893 $patternselect =
'noregex';
897 switch ($patternselect) {
905 return (
boolean)preg_match(
906 '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
907 '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
908 '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
909 '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
910 '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
911 '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
912 '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
913 '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
914 '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
919 return (
boolean)preg_match(
920 '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' .
921 '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' .
922 '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' .
923 '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' .
924 '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' .
925 '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' .
926 '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' .
927 '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' .
928 '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
929 '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD',
937 return (
boolean)preg_match(
938 '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .
939 '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
945 return (strlen($address) >= 3
946 and strpos($address,
'@') >= 1
947 and strpos($address,
'@') != strlen($address) - 1);
950 return (
boolean)filter_var($address, FILTER_VALIDATE_EMAIL);
968 $this->mailHeader =
'';
969 $this->
setError($exc->getMessage());
970 if ($this->exceptions) {
985 $this->mailHeader =
'';
986 if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
991 if (!empty($this->AltBody)) {
992 $this->ContentType =
'multipart/alternative';
995 $this->error_count = 0;
998 if (!$this->AllowEmpty and empty($this->Body)) {
1007 if ($this->Mailer ==
'mail') {
1008 if (count($this->to) > 0) {
1009 $this->mailHeader .= $this->
addrAppend(
'To', $this->to);
1011 $this->mailHeader .= $this->
headerLine(
'To',
'undisclosed-recipients:;');
1020 if (!empty($this->DKIM_domain)
1021 && !empty($this->DKIM_private)
1022 && !empty($this->DKIM_selector)
1023 && !empty($this->DKIM_domain)
1024 && file_exists($this->DKIM_private)) {
1026 $this->MIMEHeader . $this->mailHeader,
1030 $this->MIMEHeader = rtrim($this->MIMEHeader,
"\r\n ") . self::CRLF .
1031 str_replace(
"\r\n",
"\n", $header_dkim) . self::CRLF;
1036 $this->
setError($exc->getMessage());
1037 if ($this->exceptions) {
1054 switch ($this->Mailer) {
1057 return $this->
sendmailSend($this->MIMEHeader, $this->MIMEBody);
1059 return $this->
smtpSend($this->MIMEHeader, $this->MIMEBody);
1061 return $this->
mailSend($this->MIMEHeader, $this->MIMEBody);
1063 $sendMethod = $this->Mailer.
'Send';
1064 if (method_exists($this, $sendMethod)) {
1065 return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
1068 return $this->
mailSend($this->MIMEHeader, $this->MIMEBody);
1071 $this->
setError($exc->getMessage());
1072 $this->
edebug($exc->getMessage());
1073 if ($this->exceptions) {
1091 if ($this->Sender !=
'') {
1092 if ($this->Mailer ==
'qmail') {
1093 $sendmail = sprintf(
'%s -f%s', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
1095 $sendmail = sprintf(
'%s -oi -f%s -t', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
1098 if ($this->Mailer ==
'qmail') {
1099 $sendmail = sprintf(
'%s', escapeshellcmd($this->Sendmail));
1101 $sendmail = sprintf(
'%s -oi -t', escapeshellcmd($this->Sendmail));
1104 if ($this->SingleTo ===
true) {
1105 foreach ($this->SingleToArray as $toAddr) {
1106 if (!@$mail = popen($sendmail,
'w')) {
1109 fputs($mail,
'To: ' . $toAddr .
"\n");
1110 fputs($mail, $header);
1111 fputs($mail, $body);
1112 $result = pclose($mail);
1127 if (!@$mail = popen($sendmail,
'w')) {
1130 fputs($mail, $header);
1131 fputs($mail, $body);
1132 $result = pclose($mail);
1133 $this->
doCallback(($result == 0), $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
1153 foreach ($this->to as $toaddr) {
1156 $to = implode(
', ', $toArr);
1158 if (empty($this->Sender)) {
1161 $params = sprintf(
'-f%s', $this->Sender);
1163 if ($this->Sender !=
'' and !ini_get(
'safe_mode')) {
1164 $old_from = ini_get(
'sendmail_from');
1165 ini_set(
'sendmail_from', $this->Sender);
1168 if ($this->SingleTo ===
true && count($toArr) > 1) {
1169 foreach ($toArr as $toAddr) {
1170 $result = $this->
mailPassthru($toAddr, $this->Subject, $body, $header, $params);
1171 $this->
doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From);
1174 $result = $this->
mailPassthru(
$to, $this->Subject, $body, $header, $params);
1175 $this->
doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
1177 if (isset($old_from)) {
1178 ini_set(
'sendmail_from', $old_from);
1193 if (!is_object($this->smtp)) {
1194 $this->smtp =
new SMTP;
1213 $bad_rcpt = array();
1218 $smtp_from = ($this->Sender ==
'') ? $this->From : $this->Sender;
1219 if (!$this->smtp->mail($smtp_from)) {
1220 $this->
setError($this->
lang(
'from_failed') . $smtp_from .
' : ' . implode(
',', $this->smtp->getError()));
1225 foreach ($this->to as
$to) {
1226 if (!$this->smtp->recipient($to[0])) {
1227 $bad_rcpt[] = $to[0];
1232 $this->
doCallback($isSent, array($to[0]), array(), array(), $this->Subject, $body, $this->From);
1234 foreach ($this->cc as
$cc) {
1235 if (!$this->smtp->recipient($cc[0])) {
1236 $bad_rcpt[] = $cc[0];
1241 $this->
doCallback($isSent, array(), array($cc[0]), array(), $this->Subject, $body, $this->From);
1243 foreach ($this->bcc as
$bcc) {
1244 if (!$this->smtp->recipient($bcc[0])) {
1245 $bad_rcpt[] = $bcc[0];
1250 $this->
doCallback($isSent, array(), array(), array($bcc[0]), $this->Subject, $body, $this->From);
1254 if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) {
1257 if ($this->SMTPKeepAlive ==
true) {
1258 $this->smtp->reset();
1260 $this->smtp->quit();
1261 $this->smtp->close();
1263 if (count($bad_rcpt) > 0) {
1265 $this->
lang(
'recipients_failed') . implode(
', ', $bad_rcpt),
1283 if (is_null($this->smtp)) {
1288 if ($this->smtp->connected()) {
1292 $this->smtp->setTimeout($this->Timeout);
1293 $this->smtp->setDebugLevel($this->SMTPDebug);
1294 $this->smtp->setDebugOutput($this->Debugoutput);
1295 $this->smtp->setVerp($this->do_verp);
1296 $hosts = explode(
';', $this->Host);
1297 $lastexception = null;
1299 foreach ($hosts as $hostentry) {
1300 $hostinfo = array();
1301 if (!preg_match(
'/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
1311 $tls = ($this->SMTPSecure ==
'tls');
1312 if ($hostinfo[2] ==
'ssl' or ($hostinfo[2] ==
'' and $this->SMTPSecure ==
'ssl')) {
1315 } elseif ($hostinfo[2] ==
'tls') {
1319 $host = $hostinfo[3];
1321 $tport = (integer)$hostinfo[4];
1322 if ($tport > 0 and $tport < 65536) {
1325 if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
1332 $this->smtp->hello($hello);
1335 if (!$this->smtp->startTLS()) {
1339 $this->smtp->hello($hello);
1341 if ($this->SMTPAuth) {
1342 if (!$this->smtp->authenticate(
1355 $lastexception = $exc;
1357 $this->smtp->quit();
1362 $this->smtp->close();
1364 if ($this->exceptions and !is_null($lastexception)) {
1365 throw $lastexception;
1376 if ($this->smtp !== null) {
1377 if ($this->smtp->connected()) {
1378 $this->smtp->quit();
1379 $this->smtp->close();
1397 'authenticate' =>
'SMTP Error: Could not authenticate.',
1398 'connect_host' =>
'SMTP Error: Could not connect to SMTP host.',
1399 'data_not_accepted' =>
'SMTP Error: data not accepted.',
1400 'empty_message' =>
'Message body empty',
1401 'encoding' =>
'Unknown encoding: ',
1402 'execute' =>
'Could not execute: ',
1403 'file_access' =>
'Could not access file: ',
1404 'file_open' =>
'File Error: Could not open file: ',
1405 'from_failed' =>
'The following From address failed: ',
1406 'instantiate' =>
'Could not instantiate mail function.',
1407 'invalid_address' =>
'Invalid address',
1408 'mailer_not_supported' =>
' mailer is not supported.',
1409 'provide_address' =>
'You must provide at least one recipient email address.',
1410 'recipients_failed' =>
'SMTP Error: The following recipients failed: ',
1411 'signing' =>
'Signing Error: ',
1412 'smtp_connect_failed' =>
'SMTP connect() failed.',
1413 'smtp_error' =>
'SMTP server error: ',
1414 'variable_set' =>
'Cannot set or reset variable: '
1416 if (empty($lang_path)) {
1418 $lang_path = dirname(__FILE__). DIRECTORY_SEPARATOR .
'language'. DIRECTORY_SEPARATOR;
1421 $lang_file = $lang_path .
'phpmailer.lang-' . $langcode .
'.php';
1422 if ($langcode !=
'en') {
1424 if (!is_readable($lang_file)) {
1429 $foundlang = include $lang_file;
1433 return ($foundlang ==
true);
1457 $addresses = array();
1458 foreach ($addr as $address) {
1461 return $type .
': ' . implode(
', ', $addresses) .
$this->LE;
1473 if (empty($addr[1])) {
1493 public function wrapText($message, $length, $qp_mode =
false)
1495 $soft_break = ($qp_mode) ? sprintf(
' =%s', $this->LE) :
$this->LE;
1498 $is_utf8 = (strtolower($this->CharSet) ==
'utf-8');
1499 $lelen = strlen($this->LE);
1500 $crlflen = strlen(self::CRLF);
1502 $message = $this->
fixEOL($message);
1503 if (substr($message, -$lelen) == $this->LE) {
1504 $message = substr($message, 0, -$lelen);
1507 $line = explode($this->LE, $message);
1509 for ($i = 0; $i < count($line); $i++) {
1510 $line_part = explode(
' ', $line[$i]);
1512 for ($e = 0; $e < count($line_part); $e++) {
1513 $word = $line_part[$e];
1514 if ($qp_mode and (strlen($word) > $length)) {
1515 $space_left = $length - strlen($buf) - $crlflen;
1517 if ($space_left > 20) {
1521 } elseif (substr($word, $len - 1, 1) ==
'=') {
1523 } elseif (substr($word, $len - 2, 1) ==
'=') {
1526 $part = substr($word, 0, $len);
1527 $word = substr($word, $len);
1528 $buf .=
' ' . $part;
1529 $message .= $buf . sprintf(
'=%s', self::CRLF);
1531 $message .= $buf . $soft_break;
1535 while (strlen($word) > 0) {
1542 } elseif (substr($word, $len - 1, 1) ==
'=') {
1544 } elseif (substr($word, $len - 2, 1) ==
'=') {
1547 $part = substr($word, 0, $len);
1548 $word = substr($word, $len);
1550 if (strlen($word) > 0) {
1551 $message .= $part . sprintf(
'=%s', self::CRLF);
1558 $buf .= ($e == 0) ? $word : (
' ' . $word);
1560 if (strlen($buf) > $length and $buf_o !=
'') {
1561 $message .= $buf_o . $soft_break;
1566 $message .= $buf . self::CRLF;
1583 $foundSplitPos =
false;
1585 while (!$foundSplitPos) {
1586 $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
1587 $encodedCharPos = strpos($lastChunk,
'=');
1588 if ($encodedCharPos !==
false) {
1591 $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
1592 $dec = hexdec($hex);
1596 $maxLength = ($encodedCharPos == 0) ? $maxLength :
1597 $maxLength - ($lookBack - $encodedCharPos);
1598 $foundSplitPos =
true;
1599 } elseif ($dec >= 192) {
1601 $maxLength = $maxLength - ($lookBack - $encodedCharPos);
1602 $foundSplitPos =
true;
1603 } elseif ($dec < 192) {
1608 $foundSplitPos =
true;
1621 if ($this->WordWrap < 1) {
1625 switch ($this->message_type) {
1629 case 'alt_inline_attach':
1630 $this->AltBody = $this->
wrapText($this->AltBody, $this->WordWrap);
1633 $this->Body = $this->
wrapText($this->Body, $this->WordWrap);
1648 $uniq_id = md5(uniqid(time()));
1649 $this->boundary[1] =
'b1_' . $uniq_id;
1650 $this->boundary[2] =
'b2_' . $uniq_id;
1651 $this->boundary[3] =
'b3_' . $uniq_id;
1653 if ($this->MessageDate ==
'') {
1654 $this->MessageDate = self::rfcDate();
1656 $result .= $this->
headerLine(
'Date', $this->MessageDate);
1660 if ($this->SingleTo ===
true) {
1661 if ($this->Mailer !=
'mail') {
1662 foreach ($this->to as $toaddr) {
1663 $this->SingleToArray[] = $this->
addrFormat($toaddr);
1667 if (count($this->to) > 0) {
1668 if ($this->Mailer !=
'mail') {
1669 $result .= $this->
addrAppend(
'To', $this->to);
1671 } elseif (count($this->cc) == 0) {
1672 $result .= $this->
headerLine(
'To',
'undisclosed-recipients:;');
1676 $result .= $this->
addrAppend(
'From', array(array(trim($this->From), $this->FromName)));
1679 if (count($this->cc) > 0) {
1680 $result .= $this->
addrAppend(
'Cc', $this->cc);
1685 $this->Mailer ==
'sendmail' or $this->Mailer ==
'qmail' or $this->Mailer ==
'mail'
1687 and count($this->bcc) > 0
1689 $result .= $this->
addrAppend(
'Bcc', $this->bcc);
1692 if (count($this->ReplyTo) > 0) {
1693 $result .= $this->
addrAppend(
'Reply-To', $this->ReplyTo);
1697 if ($this->Mailer !=
'mail') {
1701 if ($this->MessageID !=
'') {
1704 $this->lastMessageID = sprintf(
'<%s@%s>', $uniq_id, $this->ServerHostname());
1706 $result .= $this->HeaderLine(
'Message-ID', $this->lastMessageID);
1707 $result .= $this->
headerLine(
'X-Priority', $this->Priority);
1708 if ($this->XMailer ==
'') {
1711 'PHPMailer ' . $this->Version .
' (https://github.com/PHPMailer/PHPMailer/)'
1714 $myXmailer = trim($this->XMailer);
1716 $result .= $this->
headerLine(
'X-Mailer', $myXmailer);
1720 if ($this->ConfirmReadingTo !=
'') {
1721 $result .= $this->
headerLine(
'Disposition-Notification-To',
'<' . trim($this->ConfirmReadingTo) .
'>');
1725 for ($index = 0; $index < count($this->CustomHeader); $index++) {
1727 trim($this->CustomHeader[$index][0]),
1728 $this->
encodeHeader(trim($this->CustomHeader[$index][1]))
1731 if (!$this->sign_key_file) {
1732 $result .= $this->
headerLine(
'MIME-Version',
'1.0');
1747 $ismultipart =
true;
1748 switch ($this->message_type) {
1750 $result .= $this->
headerLine(
'Content-Type',
'multipart/related;');
1751 $result .= $this->
textLine(
"\tboundary=\"" . $this->boundary[1] .
'"');
1754 case 'inline_attach':
1756 case 'alt_inline_attach':
1757 $result .= $this->
headerLine(
'Content-Type',
'multipart/mixed;');
1758 $result .= $this->
textLine(
"\tboundary=\"" . $this->boundary[1] .
'"');
1762 $result .= $this->
headerLine(
'Content-Type',
'multipart/alternative;');
1763 $result .= $this->
textLine(
"\tboundary=\"" . $this->boundary[1] .
'"');
1767 $result .= $this->
textLine(
'Content-Type: ' . $this->ContentType .
'; charset=' . $this->CharSet);
1768 $ismultipart =
false;
1772 if ($this->Encoding !=
'7bit') {
1775 if ($this->Encoding ==
'8bit') {
1776 $result .= $this->
headerLine(
'Content-Transfer-Encoding',
'8bit');
1780 $result .= $this->
headerLine(
'Content-Transfer-Encoding', $this->Encoding);
1784 if ($this->Mailer !=
'mail') {
1801 return $this->MIMEHeader . $this->mailHeader . self::CRLF .
$this->MIMEBody;
1816 if ($this->sign_key_file) {
1824 if ($bodyEncoding ==
'8bit' and !$this->
has8bitChars($this->Body)) {
1825 $bodyEncoding =
'7bit';
1826 $bodyCharSet =
'us-ascii';
1830 if ($altBodyEncoding ==
'8bit' and !$this->
has8bitChars($this->AltBody)) {
1831 $altBodyEncoding =
'7bit';
1832 $altBodyCharSet =
'us-ascii';
1834 switch ($this->message_type) {
1836 $body .= $this->
getBoundary($this->boundary[1], $bodyCharSet,
'', $bodyEncoding);
1837 $body .= $this->
encodeString($this->Body, $bodyEncoding);
1839 $body .= $this->
attachAll(
'inline', $this->boundary[1]);
1842 $body .= $this->
getBoundary($this->boundary[1], $bodyCharSet,
'', $bodyEncoding);
1843 $body .= $this->
encodeString($this->Body, $bodyEncoding);
1845 $body .= $this->
attachAll(
'attachment', $this->boundary[1]);
1847 case 'inline_attach':
1848 $body .= $this->
textLine(
'--' . $this->boundary[1]);
1849 $body .= $this->
headerLine(
'Content-Type',
'multipart/related;');
1850 $body .= $this->
textLine(
"\tboundary=\"" . $this->boundary[2] .
'"');
1852 $body .= $this->
getBoundary($this->boundary[2], $bodyCharSet,
'', $bodyEncoding);
1853 $body .= $this->
encodeString($this->Body, $bodyEncoding);
1855 $body .= $this->
attachAll(
'inline', $this->boundary[2]);
1857 $body .= $this->
attachAll(
'attachment', $this->boundary[1]);
1860 $body .= $this->
getBoundary($this->boundary[1], $altBodyCharSet,
'text/plain', $altBodyEncoding);
1861 $body .= $this->
encodeString($this->AltBody, $altBodyEncoding);
1863 $body .= $this->
getBoundary($this->boundary[1], $bodyCharSet,
'text/html', $bodyEncoding);
1864 $body .= $this->
encodeString($this->Body, $bodyEncoding);
1866 if (!empty($this->Ical)) {
1867 $body .= $this->
getBoundary($this->boundary[1],
'',
'text/calendar; method=REQUEST',
'');
1868 $body .= $this->
encodeString($this->Ical, $this->Encoding);
1874 $body .= $this->
getBoundary($this->boundary[1], $altBodyCharSet,
'text/plain', $altBodyEncoding);
1875 $body .= $this->
encodeString($this->AltBody, $altBodyEncoding);
1877 $body .= $this->
textLine(
'--' . $this->boundary[1]);
1878 $body .= $this->
headerLine(
'Content-Type',
'multipart/related;');
1879 $body .= $this->
textLine(
"\tboundary=\"" . $this->boundary[2] .
'"');
1881 $body .= $this->
getBoundary($this->boundary[2], $bodyCharSet,
'text/html', $bodyEncoding);
1882 $body .= $this->
encodeString($this->Body, $bodyEncoding);
1884 $body .= $this->
attachAll(
'inline', $this->boundary[2]);
1889 $body .= $this->
textLine(
'--' . $this->boundary[1]);
1890 $body .= $this->
headerLine(
'Content-Type',
'multipart/alternative;');
1891 $body .= $this->
textLine(
"\tboundary=\"" . $this->boundary[2] .
'"');
1893 $body .= $this->
getBoundary($this->boundary[2], $altBodyCharSet,
'text/plain', $altBodyEncoding);
1894 $body .= $this->
encodeString($this->AltBody, $altBodyEncoding);
1896 $body .= $this->
getBoundary($this->boundary[2], $bodyCharSet,
'text/html', $bodyEncoding);
1897 $body .= $this->
encodeString($this->Body, $bodyEncoding);
1901 $body .= $this->
attachAll(
'attachment', $this->boundary[1]);
1903 case 'alt_inline_attach':
1904 $body .= $this->
textLine(
'--' . $this->boundary[1]);
1905 $body .= $this->
headerLine(
'Content-Type',
'multipart/alternative;');
1906 $body .= $this->
textLine(
"\tboundary=\"" . $this->boundary[2] .
'"');
1908 $body .= $this->
getBoundary($this->boundary[2], $altBodyCharSet,
'text/plain', $altBodyEncoding);
1909 $body .= $this->
encodeString($this->AltBody, $altBodyEncoding);
1911 $body .= $this->
textLine(
'--' . $this->boundary[2]);
1912 $body .= $this->
headerLine(
'Content-Type',
'multipart/related;');
1913 $body .= $this->
textLine(
"\tboundary=\"" . $this->boundary[3] .
'"');
1915 $body .= $this->
getBoundary($this->boundary[3], $bodyCharSet,
'text/html', $bodyEncoding);
1916 $body .= $this->
encodeString($this->Body, $bodyEncoding);
1918 $body .= $this->
attachAll(
'inline', $this->boundary[3]);
1922 $body .= $this->
attachAll(
'attachment', $this->boundary[1]);
1926 $body .= $this->
encodeString($this->Body, $bodyEncoding);
1932 } elseif ($this->sign_key_file) {
1934 if (!defined(
'PKCS7_TEXT')) {
1938 $file = tempnam(sys_get_temp_dir(),
'mail');
1939 file_put_contents($file, $body);
1940 $signed = tempnam(sys_get_temp_dir(),
'signed');
1941 if (@openssl_pkcs7_sign(
1944 'file://' . realpath($this->sign_cert_file),
1945 array(
'file://' . realpath($this->sign_key_file), $this->sign_key_pass),
1950 $body = file_get_contents($signed);
1959 if ($this->exceptions) {
1979 if ($charSet ==
'') {
1982 if ($contentType ==
'') {
1985 if ($encoding ==
'') {
1989 $result .= sprintf(
'Content-Type: %s; charset=%s', $contentType, $charSet);
1992 if ($encoding !=
'7bit') {
1993 $result .= $this->
headerLine(
'Content-Transfer-Encoding', $encoding);
2030 $this->message_type = implode(
'_', $type);
2031 if ($this->message_type ==
'') {
2032 $this->message_type =
'plain';
2045 return $name .
': ' . $value .
$this->LE;
2070 public function addAttachment($path, $name =
'', $encoding =
'base64', $type =
'', $disposition =
'attachment')
2073 if (!@is_file($path)) {
2079 $type = self::filenameToType($path);
2082 $filename = basename($path);
2087 $this->attachment[] = array(
2099 $this->
setError($exc->getMessage());
2100 $this->
edebug($exc->getMessage());
2101 if ($this->exceptions) {
2136 if ($attachment[6] == $disposition_type) {
2140 $bString = $attachment[5];
2142 $string = $attachment[0];
2144 $path = $attachment[0];
2147 $inclhash = md5(serialize($attachment));
2148 if (in_array($inclhash, $incl)) {
2151 $incl[] = $inclhash;
2152 $name = $attachment[2];
2153 $encoding = $attachment[3];
2154 $type = $attachment[4];
2155 $disposition = $attachment[6];
2156 $cid = $attachment[7];
2157 if ($disposition ==
'inline' && isset($cidUniq[$cid])) {
2160 $cidUniq[$cid] =
true;
2162 $mime[] = sprintf(
'--%s%s',
$boundary, $this->LE);
2164 'Content-Type: %s; name="%s"%s',
2170 if ($encoding !=
'7bit') {
2171 $mime[] = sprintf(
'Content-Transfer-Encoding: %s%s', $encoding, $this->LE);
2174 if ($disposition ==
'inline') {
2175 $mime[] = sprintf(
'Content-ID: <%s>%s', $cid, $this->LE);
2182 if (!(empty($disposition))) {
2184 if (preg_match(
'/[ \(\)<>@,;:\\"\/\[\]\?=]/', $encoded_name)) {
2186 'Content-Disposition: %s; filename="%s"%s',
2189 $this->LE . $this->LE
2193 'Content-Disposition: %s; filename=%s%s',
2196 $this->LE . $this->LE
2211 $mime[] = $this->
encodeFile($path, $encoding);
2220 $mime[] = sprintf(
'--%s--%s',
$boundary, $this->LE);
2222 return implode(
'', $mime);
2238 if (!is_readable($path)) {
2241 $magic_quotes = get_magic_quotes_runtime();
2242 if ($magic_quotes) {
2243 if (version_compare(PHP_VERSION,
'5.3.0',
'<')) {
2244 set_magic_quotes_runtime(
false);
2249 ini_set(
'magic_quotes_runtime', 0);
2252 $file_buffer = file_get_contents($path);
2253 $file_buffer = $this->
encodeString($file_buffer, $encoding);
2254 if ($magic_quotes) {
2255 if (version_compare(PHP_VERSION,
'5.3.0',
'<')) {
2256 set_magic_quotes_runtime($magic_quotes);
2258 ini_set(
'magic_quotes_runtime', ($magic_quotes?
'1':
'0'));
2261 return $file_buffer;
2262 }
catch (Exception $exc) {
2263 $this->
setError($exc->getMessage());
2279 switch (strtolower($encoding)) {
2281 $encoded = chunk_split(base64_encode($str), 76, $this->LE);
2285 $encoded = $this->
fixEOL($str);
2287 if (substr($encoded, -(strlen($this->LE))) != $this->LE) {
2294 case 'quoted-printable':
2315 switch (strtolower($position)) {
2317 if (!preg_match(
'/[\200-\377]/', $str)) {
2319 $encoded = addcslashes($str,
"\0..\37\177\\\"");
2320 if (($str == $encoded) && !preg_match(
'/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
2323 return (
"\"$encoded\"");
2326 $matchcount = preg_match_all(
'/[^\040\041\043-\133\135-\176]/', $str, $matches);
2330 $matchcount = preg_match_all(
'/[()"]/', $str, $matches);
2334 $matchcount += preg_match_all(
'/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
2338 if ($matchcount == 0) {
2342 $maxlen = 75 - 7 - strlen($this->CharSet);
2344 if ($matchcount > strlen($str) / 3) {
2347 if (function_exists(
'mb_strlen') && $this->
hasMultiBytes($str)) {
2352 $encoded = base64_encode($str);
2353 $maxlen -= $maxlen % 4;
2354 $encoded = trim(chunk_split($encoded, $maxlen,
"\n"));
2358 $encoded = $this->
encodeQ($str, $position);
2359 $encoded = $this->
wrapText($encoded, $maxlen,
true);
2360 $encoded = str_replace(
'=' . self::CRLF,
"\n", trim($encoded));
2363 $encoded = preg_replace(
'/^(.*)$/m',
' =?' . $this->CharSet .
"?$encoding?\\1?=", $encoded);
2364 $encoded = trim(str_replace(
"\n", $this->LE, $encoded));
2377 if (function_exists(
'mb_strlen')) {
2378 return (strlen($str) > mb_strlen($str, $this->CharSet));
2391 return (
boolean)preg_match(
'/[\x80-\xFF]/', $text);
2406 $start =
'=?' . $this->CharSet .
'?B?';
2409 if ($linebreak === null) {
2413 $mb_length = mb_strlen($str, $this->CharSet);
2415 $length = 75 - strlen($start) - strlen($end);
2417 $ratio = $mb_length / strlen($str);
2419 $avgLength = floor($length * $ratio * .75);
2421 for ($i = 0; $i < $mb_length; $i += $offset) {
2424 $offset = $avgLength - $lookBack;
2425 $chunk = mb_substr($str, $i, $offset, $this->CharSet);
2426 $chunk = base64_encode($chunk);
2428 }
while (strlen($chunk) > $length);
2429 $encoded .= $chunk . $linebreak;
2433 $encoded = substr($encoded, 0, -strlen($linebreak));
2448 if (function_exists(
'quoted_printable_encode')) {
2449 return $this->
fixEOL(quoted_printable_encode($string));
2452 $string = str_replace(
2453 array(
'%20',
'%0D%0A.',
'%0D%0A',
'%'),
2454 array(
' ',
"\r\n=2E",
"\r\n",
'='),
2455 rawurlencode($string)
2457 $string = preg_replace(
'/[^\r\n]{' . ($line_max - 3) .
'}[^=\r\n]{2}/',
"$0=\r\n", $string);
2458 return $this->
fixEOL($string);
2473 $line_max = 76, $space_conv =
false
2476 return $this->
encodeQP($string, $line_max);
2491 $encoded = str_replace(array(
"\r",
"\n"),
'', $str);
2492 switch (strtolower($position)) {
2495 $pattern =
'^A-Za-z0-9!*+\/ -';
2507 $pattern =
'\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
2511 if (preg_match_all(
"/[{$pattern}]/", $encoded, $matches)) {
2514 $eqkey = array_search(
'=', $matches[0]);
2515 if ($eqkey !==
false) {
2516 unset($matches[0][$eqkey]);
2517 array_unshift($matches[0],
'=');
2519 foreach (array_unique($matches[0]) as $char) {
2520 $encoded = str_replace($char,
'=' . sprintf(
'%02X', ord($char)), $encoded);
2524 return str_replace(
' ',
'_', $encoded);
2542 $encoding =
'base64',
2544 $disposition =
'attachment'
2548 $type = self::filenameToType($filename);
2551 $this->attachment[] = array(
2554 2 => basename($filename),
2579 public function addEmbeddedImage($path, $cid, $name =
'', $encoding =
'base64', $type =
'', $disposition =
'inline')
2581 if (!@is_file($path)) {
2588 $type = self::filenameToType($path);
2591 $filename = basename($path);
2597 $this->attachment[] = array(
2628 $encoding =
'base64',
2630 $disposition =
'inline'
2634 $type = self::filenameToType($name);
2638 $this->attachment[] = array(
2659 if ($attachment[6] ==
'inline') {
2673 if ($attachment[6] ==
'attachment') {
2686 return !empty($this->AltBody);
2695 foreach ($this->to as
$to) {
2696 unset($this->all_recipients[strtolower($to[0])]);
2698 $this->to = array();
2707 foreach ($this->cc as
$cc) {
2708 unset($this->all_recipients[strtolower($cc[0])]);
2710 $this->cc = array();
2719 foreach ($this->bcc as
$bcc) {
2720 unset($this->all_recipients[strtolower($bcc[0])]);
2722 $this->bcc = array();
2731 $this->ReplyTo = array();
2740 $this->to = array();
2741 $this->cc = array();
2742 $this->bcc = array();
2743 $this->all_recipients = array();
2752 $this->attachment = array();
2761 $this->CustomHeader = array();
2772 $this->error_count++;
2773 if ($this->Mailer ==
'smtp' and !is_null($this->smtp)) {
2774 $lasterror = $this->smtp->getError();
2775 if (!empty($lasterror) and array_key_exists(
'smtp_msg', $lasterror)) {
2776 $msg .=
'<p>' . $this->
lang(
'smtp_error') . $lasterror[
'smtp_msg'] .
"</p>\n";
2779 $this->ErrorInfo = $msg;
2792 date_default_timezone_set(@date_default_timezone_get());
2793 return date(
'D, j M Y H:i:s O');
2804 $result =
'localhost.localdomain';
2805 if (!empty($this->Hostname)) {
2807 } elseif (isset($_SERVER) and array_key_exists(
'SERVER_NAME', $_SERVER) and !empty($_SERVER[
'SERVER_NAME'])) {
2808 $result = $_SERVER[
'SERVER_NAME'];
2809 } elseif (function_exists(
'gethostname') && gethostname() !==
false) {
2810 $result = gethostname();
2811 } elseif (php_uname(
'n') !==
false) {
2812 $result = php_uname(
'n');
2825 if (count($this->language) < 1) {
2829 if (isset($this->language[$key])) {
2830 return $this->language[$key];
2832 return 'Language string failed to load: ' . $key;
2843 return ($this->error_count > 0);
2856 $nstr = str_replace(array(
"\r\n",
"\r"),
"\n", $str);
2858 if ($this->LE !==
"\n") {
2859 $nstr = str_replace(
"\n", $this->LE, $nstr);
2875 if ($value === null) {
2877 $this->CustomHeader[] = explode(
':', $name, 2);
2879 $this->CustomHeader[] = array($name, $value);
2894 public function msgHTML($message, $basedir =
'', $advanced =
false)
2896 preg_match_all(
'/(src|background)=["\'](.*)["\']/Ui', $message, $images);
2897 if (isset($images[2])) {
2898 foreach ($images[2] as $imgindex => $url) {
2900 if (preg_match(
'#^data:(image[^;,]*)(;base64)?,#', $url, $match)) {
2901 $data = substr($url, strpos($url,
','));
2903 $data = base64_decode($data);
2905 $data = rawurldecode($data);
2907 $cid = md5($url) .
'@phpmailer.0';
2909 $message = preg_replace(
2910 '/' . $images[1][$imgindex] .
'=["\']' . preg_quote($url,
'/') .
'["\']/Ui',
2911 $images[1][$imgindex] .
'="cid:' . $cid .
'"',
2915 } elseif (!preg_match(
'#^[A-z]+://#', $url)) {
2917 $filename = basename($url);
2918 $directory = dirname($url);
2919 if ($directory ==
'.') {
2922 $cid = md5($url) .
'@phpmailer.0';
2923 if (strlen($basedir) > 1 && substr($basedir, -1) !=
'/') {
2926 if (strlen($directory) > 1 && substr($directory, -1) !=
'/') {
2930 $basedir . $directory . $filename,
2934 self::_mime_types(self::mb_pathinfo($filename, PATHINFO_EXTENSION))
2937 $message = preg_replace(
2938 '/' . $images[1][$imgindex] .
'=["\']' . preg_quote($url,
'/') .
'["\']/Ui',
2939 $images[1][$imgindex] .
'="cid:' . $cid .
'"',
2950 if (empty($this->AltBody)) {
2951 $this->AltBody =
'To view this email message, open it in a program that understands HTML!' .
2952 self::CRLF . self::CRLF;
2966 require_once
'extras/class.html2text.php';
2968 return $htmlconverter->get_text();
2970 return html_entity_decode(
2971 trim(strip_tags(preg_replace(
'/<(head|title|style|script)[^>]*>.*?<\/\\1>/si',
'', $html))),
2987 'xl' =>
'application/excel',
2988 'hqx' =>
'application/mac-binhex40',
2989 'cpt' =>
'application/mac-compactpro',
2990 'bin' =>
'application/macbinary',
2991 'doc' =>
'application/msword',
2992 'word' =>
'application/msword',
2993 'class' =>
'application/octet-stream',
2994 'dll' =>
'application/octet-stream',
2995 'dms' =>
'application/octet-stream',
2996 'exe' =>
'application/octet-stream',
2997 'lha' =>
'application/octet-stream',
2998 'lzh' =>
'application/octet-stream',
2999 'psd' =>
'application/octet-stream',
3000 'sea' =>
'application/octet-stream',
3001 'so' =>
'application/octet-stream',
3002 'oda' =>
'application/oda',
3003 'pdf' =>
'application/pdf',
3004 'ai' =>
'application/postscript',
3005 'eps' =>
'application/postscript',
3006 'ps' =>
'application/postscript',
3007 'smi' =>
'application/smil',
3008 'smil' =>
'application/smil',
3009 'mif' =>
'application/vnd.mif',
3010 'xls' =>
'application/vnd.ms-excel',
3011 'ppt' =>
'application/vnd.ms-powerpoint',
3012 'wbxml' =>
'application/vnd.wap.wbxml',
3013 'wmlc' =>
'application/vnd.wap.wmlc',
3014 'dcr' =>
'application/x-director',
3015 'dir' =>
'application/x-director',
3016 'dxr' =>
'application/x-director',
3017 'dvi' =>
'application/x-dvi',
3018 'gtar' =>
'application/x-gtar',
3019 'php3' =>
'application/x-httpd-php',
3020 'php4' =>
'application/x-httpd-php',
3021 'php' =>
'application/x-httpd-php',
3022 'phtml' =>
'application/x-httpd-php',
3023 'phps' =>
'application/x-httpd-php-source',
3024 'js' =>
'application/x-javascript',
3025 'swf' =>
'application/x-shockwave-flash',
3026 'sit' =>
'application/x-stuffit',
3027 'tar' =>
'application/x-tar',
3028 'tgz' =>
'application/x-tar',
3029 'xht' =>
'application/xhtml+xml',
3030 'xhtml' =>
'application/xhtml+xml',
3031 'zip' =>
'application/zip',
3032 'mid' =>
'audio/midi',
3033 'midi' =>
'audio/midi',
3034 'mp2' =>
'audio/mpeg',
3035 'mp3' =>
'audio/mpeg',
3036 'mpga' =>
'audio/mpeg',
3037 'aif' =>
'audio/x-aiff',
3038 'aifc' =>
'audio/x-aiff',
3039 'aiff' =>
'audio/x-aiff',
3040 'ram' =>
'audio/x-pn-realaudio',
3041 'rm' =>
'audio/x-pn-realaudio',
3042 'rpm' =>
'audio/x-pn-realaudio-plugin',
3043 'ra' =>
'audio/x-realaudio',
3044 'wav' =>
'audio/x-wav',
3045 'bmp' =>
'image/bmp',
3046 'gif' =>
'image/gif',
3047 'jpeg' =>
'image/jpeg',
3048 'jpe' =>
'image/jpeg',
3049 'jpg' =>
'image/jpeg',
3050 'png' =>
'image/png',
3051 'tiff' =>
'image/tiff',
3052 'tif' =>
'image/tiff',
3053 'eml' =>
'message/rfc822',
3054 'css' =>
'text/css',
3055 'html' =>
'text/html',
3056 'htm' =>
'text/html',
3057 'shtml' =>
'text/html',
3058 'log' =>
'text/plain',
3059 'text' =>
'text/plain',
3060 'txt' =>
'text/plain',
3061 'rtx' =>
'text/richtext',
3062 'rtf' =>
'text/rtf',
3063 'vcf' =>
'text/vcard',
3064 'vcard' =>
'text/vcard',
3065 'xml' =>
'text/xml',
3066 'xsl' =>
'text/xml',
3067 'mpeg' =>
'video/mpeg',
3068 'mpe' =>
'video/mpeg',
3069 'mpg' =>
'video/mpeg',
3070 'mov' =>
'video/quicktime',
3071 'qt' =>
'video/quicktime',
3072 'rv' =>
'video/vnd.rn-realvideo',
3073 'avi' =>
'video/x-msvideo',
3074 'movie' =>
'video/x-sgi-movie'
3076 return (array_key_exists(strtolower($ext), $mimes) ? $mimes[strtolower($ext)]:
'application/octet-stream');
3089 $qpos = strpos($filename,
'?');
3090 if ($qpos !==
false) {
3091 $filename = substr($filename, 0, $qpos);
3093 $pathinfo = self::mb_pathinfo($filename);
3094 return self::_mime_types($pathinfo[
'extension']);
3110 $ret = array(
'dirname' =>
'',
'basename' =>
'',
'extension' =>
'',
'filename' =>
'');
3111 $pathinfo = array();
3112 if (preg_match(
'%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $pathinfo)) {
3113 if (array_key_exists(1, $pathinfo)) {
3114 $ret[
'dirname'] = $pathinfo[1];
3116 if (array_key_exists(2, $pathinfo)) {
3117 $ret[
'basename'] = $pathinfo[2];
3119 if (array_key_exists(5, $pathinfo)) {
3120 $ret[
'extension'] = $pathinfo[5];
3122 if (array_key_exists(3, $pathinfo)) {
3123 $ret[
'filename'] = $pathinfo[3];
3127 case PATHINFO_DIRNAME:
3129 return $ret[
'dirname'];
3130 case PATHINFO_BASENAME:
3132 return $ret[
'basename'];
3133 case PATHINFO_EXTENSION:
3135 return $ret[
'extension'];
3136 case PATHINFO_FILENAME:
3138 return $ret[
'filename'];
3158 public function set($name, $value =
'')
3161 if (isset($this->$name)) {
3162 $this->$name = $value;
3166 }
catch (Exception $exc) {
3167 $this->
setError($exc->getMessage());
3168 if ($exc->getCode() == self::STOP_CRITICAL) {
3183 return trim(str_replace(array(
"\r",
"\n"),
'', $str));
3198 return preg_replace(
'/(\r\n|\r|\n)/ms', $breaktype, $text);
3209 public function sign($cert_filename, $key_filename, $key_pass)
3211 $this->sign_cert_file = $cert_filename;
3212 $this->sign_key_file = $key_filename;
3213 $this->sign_key_pass = $key_pass;
3225 for ($i = 0; $i < strlen($txt); $i++) {
3226 $ord = ord($txt[$i]);
3227 if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
3230 $line .=
'=' . sprintf(
'%02X', $ord);
3245 if (!defined(
'PKCS7_TEXT')) {
3246 if ($this->exceptions) {
3251 $privKeyStr = file_get_contents($this->DKIM_private);
3252 if ($this->DKIM_passphrase !=
'') {
3253 $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
3255 $privKey = $privKeyStr;
3257 if (openssl_sign($signHeader, $signature, $privKey)) {
3258 return base64_encode($signature);
3271 $signHeader = preg_replace(
'/\r\n\s+/',
' ', $signHeader);
3272 $lines = explode(
"\r\n", $signHeader);
3273 foreach ($lines as $key => $line) {
3274 list($heading, $value) = explode(
':', $line, 2);
3275 $heading = strtolower($heading);
3276 $value = preg_replace(
'/\s+/',
' ', $value);
3277 $lines[$key] = $heading .
':' . trim($value);
3279 $signHeader = implode(
"\r\n", $lines);
3295 $body = str_replace(
"\r\n",
"\n", $body);
3296 $body = str_replace(
"\n",
"\r\n", $body);
3298 while (substr($body, strlen($body) - 4, 4) ==
"\r\n\r\n") {
3299 $body = substr($body, 0, strlen($body) - 2);
3312 public function DKIM_Add($headers_line, $subject, $body)
3314 $DKIMsignatureType =
'rsa-sha1';
3315 $DKIMcanonicalization =
'relaxed/simple';
3316 $DKIMquery =
'dns/txt';
3318 $subject_header =
"Subject: $subject";
3319 $headers = explode($this->LE, $headers_line);
3323 foreach ($headers as $header) {
3324 if (strpos($header,
'From:') === 0) {
3325 $from_header = $header;
3326 $current =
'from_header';
3327 } elseif (strpos($header,
'To:') === 0) {
3328 $to_header = $header;
3329 $current =
'to_header';
3331 if ($current && strpos($header,
' =?') === 0) {
3332 $current .= $header;
3338 $from = str_replace(
'|',
'=7C', $this->
DKIM_QP($from_header));
3339 $to = str_replace(
'|',
'=7C', $this->
DKIM_QP($to_header));
3340 $subject = str_replace(
3343 $this->
DKIM_QP($subject_header)
3346 $DKIMlen = strlen($body);
3347 $DKIMb64 = base64_encode(pack(
'H*', sha1($body)));
3348 $ident = ($this->DKIM_identity ==
'') ?
'' :
' i=' . $this->DKIM_identity .
';';
3349 $dkimhdrs =
'DKIM-Signature: v=1; a=' .
3350 $DKIMsignatureType .
'; q=' .
3351 $DKIMquery .
'; l=' .
3353 $this->DKIM_selector .
3355 "\tt=" . $DKIMtime .
'; c=' . $DKIMcanonicalization .
";\r\n" .
3356 "\th=From:To:Subject;\r\n" .
3357 "\td=" . $this->DKIM_domain .
';' . $ident .
"\r\n" .
3360 "\t|$subject;\r\n" .
3361 "\tbh=" . $DKIMb64 .
";\r\n" .
3364 $from_header .
"\r\n" . $to_header .
"\r\n" . $subject_header .
"\r\n" . $dkimhdrs
3367 return $dkimhdrs . $signed .
"\r\n";
3432 if (!empty($this->action_function) && is_callable($this->action_function)) {
3433 $params = array($isSent,
$to,
$cc,
$bcc, $subject, $body, $from);
3434 call_user_func_array($this->action_function, $params);
3451 $errorMsg =
'<strong>' . $this->getMessage() .
"</strong><br />\n";