73 public $From =
'root@localhost';
689 if (ini_get(
'mbstring.func_overload') & 1) {
695 if(0 == strlen(
$to) && strpos(
$header,
'To: undisclosed-recipients:;') !==
false)
697 $to =
'undisclosed-recipients:;';
698 $header = preg_replace(
'/To: undisclosed-recipients:;(\s*)/',
'',
$header);
703 if (ini_get(
'safe_mode') or !$this->UseSendmailOptions or is_null(
$params)) {
719 if ($this->SMTPDebug <= 0) {
723 if (!in_array($this->Debugoutput,
array(
'error_log',
'html',
'echo')) and is_callable($this->Debugoutput)) {
724 call_user_func($this->Debugoutput, $str, $this->SMTPDebug);
727 switch ($this->Debugoutput) {
735 preg_replace(
'/[\r\n]+/',
'', $str),
744 $str = preg_replace(
'/\r\n?/ms',
"\n", $str);
745 echo gmdate(
'Y-m-d H:i:s') .
"\t" . str_replace(
761 $this->ContentType =
'text/html';
763 $this->ContentType =
'text/plain';
773 $this->Mailer =
'smtp';
782 $this->Mailer =
'mail';
791 $ini_sendmail_path = ini_get(
'sendmail_path');
793 if (!stristr($ini_sendmail_path,
'sendmail')) {
794 $this->Sendmail =
'/usr/sbin/sendmail';
796 $this->Sendmail = $ini_sendmail_path;
798 $this->Mailer =
'sendmail';
807 $ini_sendmail_path = ini_get(
'sendmail_path');
809 if (!stristr($ini_sendmail_path,
'qmail')) {
810 $this->Sendmail =
'/var/qmail/bin/qmail-inject';
812 $this->Sendmail = $ini_sendmail_path;
814 $this->Mailer =
'qmail';
877 $address = trim($address);
878 $name = trim(preg_replace(
'/[\r\n]+/',
'',
$name));
879 if (($pos = strrpos($address,
'@')) ===
false) {
881 $error_message = $this->
lang(
'invalid_address') .
" (addAnAddress $kind): $address";
883 $this->
edebug($error_message);
884 if ($this->exceptions) {
892 if ($kind !=
'Reply-To') {
893 if (!array_key_exists($address, $this->RecipientsQueue)) {
894 $this->RecipientsQueue[$address] =
$params;
898 if (!array_key_exists($address, $this->ReplyToQueue)) {
899 $this->ReplyToQueue[$address] =
$params;
906 return call_user_func_array(
array($this,
'addAnAddress'),
$params);
921 if (!in_array($kind,
array(
'to',
'cc',
'bcc',
'Reply-To'))) {
922 $error_message = $this->
lang(
'Invalid recipient kind: ') . $kind;
924 $this->
edebug($error_message);
925 if ($this->exceptions) {
931 $error_message = $this->
lang(
'invalid_address') .
" (addAnAddress $kind): $address";
933 $this->
edebug($error_message);
934 if ($this->exceptions) {
939 if ($kind !=
'Reply-To') {
940 if (!array_key_exists(strtolower($address), $this->all_recipients)) {
941 array_push($this->$kind,
array($address,
$name));
942 $this->all_recipients[strtolower($address)] =
true;
946 if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
947 $this->ReplyTo[strtolower($address)] =
array($address,
$name);
966 $addresses =
array();
967 if ($useimap and function_exists(
'imap_rfc822_parse_adrlist')) {
969 $list = imap_rfc822_parse_adrlist($addrstr,
'');
970 foreach (
$list as $address) {
971 if ($address->host !=
'.SYNTAX-ERROR.') {
972 if ($this->
validateAddress($address->mailbox .
'@' . $address->host)) {
973 $addresses[] =
array(
974 'name' => (property_exists($address,
'personal') ? $address->personal :
''),
975 'address' => $address->mailbox .
'@' . $address->host
982 $list = explode(
',', $addrstr);
983 foreach (
$list as $address) {
984 $address = trim($address);
986 if (strpos($address,
'<') ===
false) {
989 $addresses[] =
array(
991 'address' => $address
998 $addresses[] =
array(
999 'name' => trim(str_replace(
array(
'"',
"'"),
'',
$name)),
1019 $address = trim($address);
1020 $name = trim(preg_replace(
'/[\r\n]+/',
'',
$name));
1022 if (($pos = strrpos($address,
'@')) ===
false or
1025 $error_message = $this->
lang(
'invalid_address') .
" (setFrom) $address";
1027 $this->
edebug($error_message);
1028 if ($this->exceptions) {
1033 $this->From = $address;
1034 $this->FromName =
$name;
1036 if (empty($this->Sender)) {
1037 $this->Sender = $address;
1076 if (is_null($patternselect)) {
1077 $patternselect = self::$validator;
1079 if (is_callable($patternselect)) {
1080 return call_user_func($patternselect, $address);
1083 if (strpos($address,
"\n") !==
false or strpos($address,
"\r") !==
false) {
1086 if (!$patternselect or $patternselect ==
'auto') {
1089 if (
defined(
'PCRE_VERSION')) {
1091 if (version_compare(PCRE_VERSION,
'8.0.3') >= 0) {
1092 $patternselect =
'pcre8';
1094 $patternselect =
'pcre';
1096 } elseif (function_exists(
'extension_loaded') and extension_loaded(
'pcre')) {
1098 $patternselect =
'pcre';
1101 if (version_compare(PHP_VERSION,
'5.2.0') >= 0) {
1102 $patternselect =
'php';
1104 $patternselect =
'noregex';
1108 switch ($patternselect) {
1116 return (
boolean)preg_match(
1117 '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
1118 '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
1119 '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
1120 '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
1121 '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
1122 '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
1123 '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
1124 '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
1125 '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
1130 return (
boolean)preg_match(
1131 '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' .
1132 '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' .
1133 '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' .
1134 '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' .
1135 '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' .
1136 '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' .
1137 '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' .
1138 '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' .
1139 '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
1140 '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD',
1148 return (
boolean)preg_match(
1149 '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .
1150 '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
1156 return (strlen($address) >= 3
1157 and strpos($address,
'@') >= 1
1158 and strpos($address,
'@') != strlen($address) - 1);
1161 return (
boolean)filter_var($address, FILTER_VALIDATE_EMAIL);
1173 return function_exists(
'idn_to_ascii') and function_exists(
'mb_convert_encoding');
1191 !empty($this->CharSet) and
1192 ($pos = strrpos($address,
'@')) !==
false) {
1193 $domain = substr($address, ++$pos);
1197 if (($punycode =
defined(
'INTL_IDNA_VARIANT_UTS46') ?
1198 idn_to_ascii(
$domain, 0, INTL_IDNA_VARIANT_UTS46) :
1199 idn_to_ascii(
$domain)) !==
false) {
1200 return substr($address, 0, $pos) . $punycode;
1221 $this->mailHeader =
'';
1222 $this->
setError($exc->getMessage());
1223 if ($this->exceptions) {
1238 $this->error_count = 0;
1239 $this->mailHeader =
'';
1242 foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as
$params) {
1244 call_user_func_array(
array($this,
'addAnAddress'), $params);
1246 if ((count($this->
to) + count($this->cc) + count($this->bcc)) < 1) {
1251 foreach (
array(
'From',
'Sender',
'ConfirmReadingTo') as $address_kind) {
1252 $this->$address_kind = trim($this->$address_kind);
1253 if (empty($this->$address_kind)) {
1258 $error_message = $this->
lang(
'invalid_address') .
' (punyEncode) ' . $this->$address_kind;
1260 $this->
edebug($error_message);
1261 if ($this->exceptions) {
1270 $this->ContentType =
'multipart/alternative';
1275 if (!$this->AllowEmpty and empty($this->Body)) {
1280 $this->MIMEHeader =
'';
1285 $this->MIMEHeader .= $tempheaders;
1289 if ($this->Mailer ==
'mail') {
1290 if (count($this->
to) > 0) {
1291 $this->mailHeader .= $this->
addrAppend(
'To', $this->
to);
1293 $this->mailHeader .= $this->
headerLine(
'To',
'undisclosed-recipients:;');
1302 if (!empty($this->DKIM_domain)
1303 && !empty($this->DKIM_selector)
1304 && (!empty($this->DKIM_private_string)
1305 || (!empty($this->DKIM_private) && file_exists($this->DKIM_private))
1309 $this->MIMEHeader . $this->mailHeader,
1313 $this->MIMEHeader = rtrim($this->MIMEHeader,
"\r\n ") . self::CRLF .
1314 str_replace(
"\r\n",
"\n", $header_dkim) . self::CRLF;
1318 $this->
setError($exc->getMessage());
1319 if ($this->exceptions) {
1336 switch ($this->Mailer) {
1339 return $this->
sendmailSend($this->MIMEHeader, $this->MIMEBody);
1341 return $this->
smtpSend($this->MIMEHeader, $this->MIMEBody);
1343 return $this->
mailSend($this->MIMEHeader, $this->MIMEBody);
1345 $sendMethod = $this->Mailer.
'Send';
1346 if (method_exists($this, $sendMethod)) {
1347 return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
1350 return $this->
mailSend($this->MIMEHeader, $this->MIMEBody);
1353 $this->
setError($exc->getMessage());
1354 $this->
edebug($exc->getMessage());
1355 if ($this->exceptions) {
1374 if (!empty($this->Sender) and self::isShellSafe($this->Sender)) {
1375 if ($this->Mailer ==
'qmail') {
1376 $sendmailFmt =
'%s -f%s';
1378 $sendmailFmt =
'%s -oi -f%s -t';
1381 if ($this->Mailer ==
'qmail') {
1382 $sendmailFmt =
'%s';
1384 $sendmailFmt =
'%s -oi -t';
1389 $sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender);
1391 if ($this->SingleTo) {
1392 foreach ($this->SingleToArray as $toAddr) {
1393 if (!@$mail = popen($sendmail,
'w')) {
1396 fputs($mail,
'To: ' . $toAddr .
"\n");
1398 fputs($mail, $body);
1414 if (!@$mail = popen($sendmail,
'w')) {
1418 fputs($mail, $body);
1448 if (escapeshellcmd($string) !== $string
1449 or !in_array(escapeshellarg($string),
array(
"'$string'",
"\"$string\""))
1454 $length = strlen($string);
1456 for (
$i = 0;
$i < $length;
$i++) {
1462 if (!ctype_alnum($c) && strpos(
'@_-.', $c) ===
false) {
1482 foreach ($this->
to as $toaddr) {
1485 $to = implode(
', ', $toArr);
1489 if (!empty($this->Sender) and $this->
validateAddress($this->Sender)) {
1491 if (self::isShellSafe($this->Sender)) {
1492 $params = sprintf(
'-f%s', $this->Sender);
1495 if (!empty($this->Sender) and !ini_get(
'safe_mode') and $this->
validateAddress($this->Sender)) {
1496 $old_from = ini_get(
'sendmail_from');
1497 ini_set(
'sendmail_from', $this->Sender);
1500 if ($this->SingleTo and count($toArr) > 1) {
1501 foreach ($toArr as $toAddr) {
1507 $this->
doCallback(
$result, $this->
to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
1509 if (isset($old_from)) {
1510 ini_set(
'sendmail_from', $old_from);
1525 if (!is_object($this->smtp)) {
1526 $this->smtp =
new SMTP;
1545 $bad_rcpt =
array();
1549 if (!empty($this->Sender) and $this->
validateAddress($this->Sender)) {
1554 if (!$this->smtp->mail($smtp_from)) {
1555 $this->
setError($this->
lang(
'from_failed') . $smtp_from .
' : ' . implode(
',', $this->smtp->getError()));
1560 foreach (
array($this->
to, $this->cc, $this->bcc) as $togroup) {
1561 foreach ($togroup as
$to) {
1562 if (!$this->smtp->recipient($to[0])) {
1563 $error = $this->smtp->getError();
1564 $bad_rcpt[] =
array(
'to' => $to[0],
'error' =>
$error[
'detail']);
1574 if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data(
$header . $body)) {
1577 if ($this->SMTPKeepAlive) {
1578 $this->smtp->reset();
1580 $this->smtp->quit();
1581 $this->smtp->close();
1584 if (count($bad_rcpt) > 0) {
1586 foreach ($bad_rcpt as $bad) {
1587 $errstr .= $bad[
'to'] .
': ' . $bad[
'error'];
1590 $this->
lang(
'recipients_failed') . $errstr,
1608 if (is_null($this->smtp)) {
1618 if ($this->smtp->connected()) {
1622 $this->smtp->setTimeout($this->Timeout);
1623 $this->smtp->setDebugLevel($this->SMTPDebug);
1624 $this->smtp->setDebugOutput($this->Debugoutput);
1625 $this->smtp->setVerp($this->do_verp);
1626 $hosts = explode(
';', $this->Host);
1627 $lastexception = null;
1629 foreach ($hosts as $hostentry) {
1630 $hostinfo =
array();
1632 '/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*|\[[a-fA-F0-9:]+\]):?([0-9]*)$/',
1637 $this->
edebug(
'Ignoring invalid host: ' . $hostentry);
1647 $tls = ($this->SMTPSecure ==
'tls');
1648 if (
'ssl' == $hostinfo[2] or (
'' == $hostinfo[2] and
'ssl' == $this->SMTPSecure)) {
1652 } elseif ($hostinfo[2] ==
'tls') {
1658 $sslext =
defined(
'OPENSSL_ALGO_SHA1');
1659 if (
'tls' === $secure or
'ssl' === $secure) {
1665 $host = $hostinfo[3];
1667 $tport = (integer)$hostinfo[4];
1668 if ($tport > 0 and $tport < 65536) {
1671 if ($this->smtp->connect($prefix . $host, $port, $this->Timeout,
$options)) {
1678 $this->smtp->hello($hello);
1684 if ($this->SMTPAutoTLS and $sslext and $secure !=
'ssl' and $this->smtp->getServerExt(
'STARTTLS')) {
1688 if (!$this->smtp->startTLS()) {
1692 $this->smtp->hello($hello);
1694 if ($this->SMTPAuth) {
1695 if (!$this->smtp->authenticate(
1708 $lastexception = $exc;
1709 $this->
edebug($exc->getMessage());
1711 $this->smtp->quit();
1716 $this->smtp->close();
1718 if ($this->exceptions and !is_null($lastexception)) {
1719 throw $lastexception;
1730 if (is_a($this->smtp,
'SMTP')) {
1731 if ($this->smtp->connected()) {
1732 $this->smtp->quit();
1733 $this->smtp->close();
1750 $renamed_langcodes =
array(
1759 if (isset($renamed_langcodes[$langcode])) {
1760 $langcode = $renamed_langcodes[$langcode];
1765 'authenticate' =>
'SMTP Error: Could not authenticate.',
1766 'connect_host' =>
'SMTP Error: Could not connect to SMTP host.',
1767 'data_not_accepted' =>
'SMTP Error: data not accepted.',
1768 'empty_message' =>
'Message body empty',
1769 'encoding' =>
'Unknown encoding: ',
1770 'execute' =>
'Could not execute: ',
1771 'file_access' =>
'Could not access file: ',
1772 'file_open' =>
'File Error: Could not open file: ',
1773 'from_failed' =>
'The following From address failed: ',
1774 'instantiate' =>
'Could not instantiate mail function.',
1775 'invalid_address' =>
'Invalid address: ',
1776 'mailer_not_supported' =>
' mailer is not supported.',
1777 'provide_address' =>
'You must provide at least one recipient email address.',
1778 'recipients_failed' =>
'SMTP Error: The following recipients failed: ',
1779 'signing' =>
'Signing Error: ',
1780 'smtp_connect_failed' =>
'SMTP connect() failed.',
1781 'smtp_error' =>
'SMTP server error: ',
1782 'variable_set' =>
'Cannot set or reset variable: ',
1783 'extension_missing' =>
'Extension missing: ' 1785 if (empty($lang_path)) {
1787 $lang_path = dirname(__FILE__). DIRECTORY_SEPARATOR .
'language'. DIRECTORY_SEPARATOR;
1790 if (!preg_match(
'/^[a-z]{2}(?:_[a-zA-Z]{2})?$/', $langcode)) {
1794 $lang_file = $lang_path .
'phpmailer.lang-' . $langcode .
'.php';
1796 if ($langcode !=
'en') {
1798 if (!is_readable($lang_file)) {
1803 $foundlang = include $lang_file;
1807 return (
boolean)$foundlang;
1831 $addresses =
array();
1832 foreach ($addr as $address) {
1847 if (empty($addr[1])) {
1870 $soft_break = sprintf(
' =%s', $this->LE);
1876 $is_utf8 = (strtolower($this->CharSet) ==
'utf-8');
1877 $lelen = strlen($this->LE);
1878 $crlflen = strlen(self::CRLF);
1882 if (substr(
$message, -$lelen) == $this->LE) {
1887 $lines = explode($this->LE,
$message);
1890 foreach ($lines as $line) {
1891 $words = explode(
' ', $line);
1894 foreach ($words as $word) {
1895 if ($qp_mode and (strlen($word) > $length)) {
1896 $space_left = $length - strlen($buf) - $crlflen;
1898 if ($space_left > 20) {
1902 } elseif (substr($word, $len - 1, 1) ==
'=') {
1904 } elseif (substr($word, $len - 2, 1) ==
'=') {
1907 $part = substr($word, 0, $len);
1908 $word = substr($word, $len);
1909 $buf .=
' ' . $part;
1910 $message .= $buf . sprintf(
'=%s', self::CRLF);
1916 while (strlen($word) > 0) {
1923 } elseif (substr($word, $len - 1, 1) ==
'=') {
1925 } elseif (substr($word, $len - 2, 1) ==
'=') {
1928 $part = substr($word, 0, $len);
1929 $word = substr($word, $len);
1931 if (strlen($word) > 0) {
1932 $message .= $part . sprintf(
'=%s', self::CRLF);
1944 if (strlen($buf) > $length and $buf_o !=
'') {
1968 $foundSplitPos =
false;
1970 while (!$foundSplitPos) {
1971 $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
1972 $encodedCharPos = strpos($lastChunk,
'=');
1973 if (
false !== $encodedCharPos) {
1976 $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
1977 $dec = hexdec($hex);
1982 if ($encodedCharPos > 0) {
1983 $maxLength = $maxLength - ($lookBack - $encodedCharPos);
1985 $foundSplitPos =
true;
1986 } elseif ($dec >= 192) {
1989 $maxLength = $maxLength - ($lookBack - $encodedCharPos);
1990 $foundSplitPos =
true;
1991 } elseif ($dec < 192) {
1997 $foundSplitPos =
true;
2013 if ($this->WordWrap < 1) {
2017 switch ($this->message_type) {
2021 case 'alt_inline_attach':
2022 $this->AltBody = $this->
wrapText($this->AltBody, $this->WordWrap);
2025 $this->Body = $this->
wrapText($this->Body, $this->WordWrap);
2039 $result .= $this->
headerLine(
'Date', $this->MessageDate ==
'' ? self::rfcDate() : $this->MessageDate);
2042 if ($this->SingleTo) {
2043 if ($this->Mailer !=
'mail') {
2044 foreach ($this->
to as $toaddr) {
2045 $this->SingleToArray[] = $this->
addrFormat($toaddr);
2049 if (count($this->
to) > 0) {
2050 if ($this->Mailer !=
'mail') {
2053 } elseif (count($this->cc) == 0) {
2061 if (count($this->cc) > 0) {
2067 $this->Mailer ==
'sendmail' or $this->Mailer ==
'qmail' or $this->Mailer ==
'mail' 2069 and count($this->bcc) > 0
2074 if (count($this->ReplyTo) > 0) {
2079 if ($this->Mailer !=
'mail') {
2085 if (
'' != $this->MessageID and preg_match(
'/^<.*@.*>$/', $this->MessageID)) {
2088 $this->lastMessageID = sprintf(
'<%s@%s>', $this->uniqueid, $this->
serverHostname());
2091 if (!is_null($this->Priority)) {
2094 if ($this->XMailer ==
'') {
2097 'PHPMailer ' . $this->Version .
' (https://github.com/PHPMailer/PHPMailer)' 2100 $myXmailer = trim($this->XMailer);
2106 if ($this->ConfirmReadingTo !=
'') {
2107 $result .= $this->
headerLine(
'Disposition-Notification-To',
'<' . $this->ConfirmReadingTo .
'>');
2111 foreach ($this->CustomHeader as
$header) {
2117 if (!$this->sign_key_file) {
2133 $ismultipart =
true;
2134 switch ($this->message_type) {
2137 $result .= $this->
textLine(
"\tboundary=\"" . $this->boundary[1] .
'"');
2140 case 'inline_attach':
2142 case 'alt_inline_attach':
2144 $result .= $this->
textLine(
"\tboundary=\"" . $this->boundary[1] .
'"');
2149 $result .= $this->
textLine(
"\tboundary=\"" . $this->boundary[1] .
'"');
2153 $result .= $this->
textLine(
'Content-Type: ' . $this->ContentType .
'; charset=' . $this->CharSet);
2154 $ismultipart =
false;
2158 if ($this->Encoding !=
'7bit') {
2161 if ($this->Encoding ==
'8bit') {
2170 if ($this->Mailer !=
'mail') {
2187 return rtrim($this->MIMEHeader . $this->mailHeader,
"\n\r") . self::CRLF . self::CRLF .
$this->MIMEBody;
2195 return md5(uniqid(
time()));
2214 if ($this->sign_key_file) {
2223 if ($bodyEncoding ==
'8bit' and !$this->
has8bitChars($this->Body)) {
2224 $bodyEncoding =
'7bit';
2226 $bodyCharSet =
'us-ascii';
2230 if (
'base64' != $this->Encoding and self::hasLineLongerThanMax($this->Body)) {
2231 $bodyEncoding =
'quoted-printable';
2237 if ($altBodyEncoding ==
'8bit' and !$this->
has8bitChars($this->AltBody)) {
2238 $altBodyEncoding =
'7bit';
2240 $altBodyCharSet =
'us-ascii';
2244 if (
'base64' != $altBodyEncoding and self::hasLineLongerThanMax($this->AltBody)) {
2245 $altBodyEncoding =
'quoted-printable';
2248 $mimepre =
"This is a multi-part message in MIME format." . $this->LE .
$this->LE;
2249 switch ($this->message_type) {
2252 $body .= $this->
getBoundary($this->boundary[1], $bodyCharSet,
'', $bodyEncoding);
2253 $body .= $this->
encodeString($this->Body, $bodyEncoding);
2255 $body .= $this->
attachAll(
'inline', $this->boundary[1]);
2259 $body .= $this->
getBoundary($this->boundary[1], $bodyCharSet,
'', $bodyEncoding);
2260 $body .= $this->
encodeString($this->Body, $bodyEncoding);
2262 $body .= $this->
attachAll(
'attachment', $this->boundary[1]);
2264 case 'inline_attach':
2266 $body .= $this->
textLine(
'--' . $this->boundary[1]);
2267 $body .= $this->
headerLine(
'Content-Type',
'multipart/related;');
2268 $body .= $this->
textLine(
"\tboundary=\"" . $this->boundary[2] .
'"');
2270 $body .= $this->
getBoundary($this->boundary[2], $bodyCharSet,
'', $bodyEncoding);
2271 $body .= $this->
encodeString($this->Body, $bodyEncoding);
2273 $body .= $this->
attachAll(
'inline', $this->boundary[2]);
2275 $body .= $this->
attachAll(
'attachment', $this->boundary[1]);
2279 $body .= $this->
getBoundary($this->boundary[1], $altBodyCharSet,
'text/plain', $altBodyEncoding);
2280 $body .= $this->
encodeString($this->AltBody, $altBodyEncoding);
2282 $body .= $this->
getBoundary($this->boundary[1], $bodyCharSet,
'text/html', $bodyEncoding);
2283 $body .= $this->
encodeString($this->Body, $bodyEncoding);
2285 if (!empty($this->Ical)) {
2286 $body .= $this->
getBoundary($this->boundary[1],
'',
'text/calendar; method=REQUEST',
'');
2287 $body .= $this->
encodeString($this->Ical, $this->Encoding);
2294 $body .= $this->
getBoundary($this->boundary[1], $altBodyCharSet,
'text/plain', $altBodyEncoding);
2295 $body .= $this->
encodeString($this->AltBody, $altBodyEncoding);
2297 $body .= $this->
textLine(
'--' . $this->boundary[1]);
2298 $body .= $this->
headerLine(
'Content-Type',
'multipart/related;');
2299 $body .= $this->
textLine(
"\tboundary=\"" . $this->boundary[2] .
'"');
2301 $body .= $this->
getBoundary($this->boundary[2], $bodyCharSet,
'text/html', $bodyEncoding);
2302 $body .= $this->
encodeString($this->Body, $bodyEncoding);
2304 $body .= $this->
attachAll(
'inline', $this->boundary[2]);
2310 $body .= $this->
textLine(
'--' . $this->boundary[1]);
2311 $body .= $this->
headerLine(
'Content-Type',
'multipart/alternative;');
2312 $body .= $this->
textLine(
"\tboundary=\"" . $this->boundary[2] .
'"');
2314 $body .= $this->
getBoundary($this->boundary[2], $altBodyCharSet,
'text/plain', $altBodyEncoding);
2315 $body .= $this->
encodeString($this->AltBody, $altBodyEncoding);
2317 $body .= $this->
getBoundary($this->boundary[2], $bodyCharSet,
'text/html', $bodyEncoding);
2318 $body .= $this->
encodeString($this->Body, $bodyEncoding);
2322 $body .= $this->
attachAll(
'attachment', $this->boundary[1]);
2324 case 'alt_inline_attach':
2326 $body .= $this->
textLine(
'--' . $this->boundary[1]);
2327 $body .= $this->
headerLine(
'Content-Type',
'multipart/alternative;');
2328 $body .= $this->
textLine(
"\tboundary=\"" . $this->boundary[2] .
'"');
2330 $body .= $this->
getBoundary($this->boundary[2], $altBodyCharSet,
'text/plain', $altBodyEncoding);
2331 $body .= $this->
encodeString($this->AltBody, $altBodyEncoding);
2333 $body .= $this->
textLine(
'--' . $this->boundary[2]);
2334 $body .= $this->
headerLine(
'Content-Type',
'multipart/related;');
2335 $body .= $this->
textLine(
"\tboundary=\"" . $this->boundary[3] .
'"');
2337 $body .= $this->
getBoundary($this->boundary[3], $bodyCharSet,
'text/html', $bodyEncoding);
2338 $body .= $this->
encodeString($this->Body, $bodyEncoding);
2340 $body .= $this->
attachAll(
'inline', $this->boundary[3]);
2344 $body .= $this->
attachAll(
'attachment', $this->boundary[1]);
2349 $this->Encoding = $bodyEncoding;
2350 $body .= $this->
encodeString($this->Body, $this->Encoding);
2356 } elseif ($this->sign_key_file) {
2362 $file = tempnam(sys_get_temp_dir(),
'mail');
2363 if (
false === file_put_contents(
$file, $body)) {
2366 $signed = tempnam(sys_get_temp_dir(),
'signed');
2368 if (empty($this->sign_extracerts_file)) {
2369 $sign = @openssl_pkcs7_sign(
2372 'file://' . realpath($this->sign_cert_file),
2373 array(
'file://' . realpath($this->sign_key_file), $this->sign_key_pass),
2377 $sign = @openssl_pkcs7_sign(
2380 'file://' . realpath($this->sign_cert_file),
2381 array(
'file://' . realpath($this->sign_key_file), $this->sign_key_pass),
2384 $this->sign_extracerts_file
2389 $body = file_get_contents($signed);
2392 $parts = explode(
"\n\n", $body, 2);
2393 $this->MIMEHeader .= $parts[0] . $this->LE .
$this->LE;
2402 if ($this->exceptions) {
2422 if ($charSet ==
'') {
2428 if ($encoding ==
'') {
2435 if ($encoding !=
'7bit') {
2472 $this->message_type = implode(
'_',
$type);
2473 if ($this->message_type ==
'') {
2475 $this->message_type =
'plain';
2517 if (!@is_file(
$path)) {
2531 $this->attachment[] =
array(
2543 $this->
setError($exc->getMessage());
2544 $this->
edebug($exc->getMessage());
2545 if ($this->exceptions) {
2580 if ($attachment[6] == $disposition_type) {
2584 $bString = $attachment[5];
2586 $string = $attachment[0];
2588 $path = $attachment[0];
2591 $inclhash = md5(serialize($attachment));
2592 if (in_array($inclhash, $incl)) {
2595 $incl[] = $inclhash;
2596 $name = $attachment[2];
2597 $encoding = $attachment[3];
2598 $type = $attachment[4];
2599 $disposition = $attachment[6];
2600 $cid = $attachment[7];
2601 if ($disposition ==
'inline' && array_key_exists($cid, $cidUniq)) {
2604 $cidUniq[$cid] =
true;
2606 $mime[] = sprintf(
'--%s%s',
$boundary, $this->LE);
2608 if (!empty(
$name)) {
2610 'Content-Type: %s; name="%s"%s',
2617 'Content-Type: %s%s',
2623 if ($encoding !=
'7bit') {
2624 $mime[] = sprintf(
'Content-Transfer-Encoding: %s%s', $encoding, $this->LE);
2627 if ($disposition ==
'inline') {
2628 $mime[] = sprintf(
'Content-ID: <%s>%s', $cid, $this->LE);
2635 if (!(empty($disposition))) {
2637 if (preg_match(
'/[ \(\)<>@,;:\\"\/\[\]\?=]/', $encoded_name)) {
2639 'Content-Disposition: %s; filename="%s"%s',
2642 $this->LE . $this->LE
2645 if (!empty($encoded_name)) {
2647 'Content-Disposition: %s; filename=%s%s',
2650 $this->LE . $this->LE
2654 'Content-Disposition: %s%s',
2656 $this->LE . $this->LE
2681 $mime[] = sprintf(
'--%s--%s',
$boundary, $this->LE);
2683 return implode(
'', $mime);
2698 if (!is_readable(
$path)) {
2701 $magic_quotes = get_magic_quotes_runtime();
2702 if ($magic_quotes) {
2703 if (version_compare(PHP_VERSION,
'5.3.0',
'<')) {
2704 set_magic_quotes_runtime(
false);
2709 ini_set(
'magic_quotes_runtime',
false);
2712 $file_buffer = file_get_contents(
$path);
2713 $file_buffer = $this->
encodeString($file_buffer, $encoding);
2714 if ($magic_quotes) {
2715 if (version_compare(PHP_VERSION,
'5.3.0',
'<')) {
2716 set_magic_quotes_runtime($magic_quotes);
2718 ini_set(
'magic_quotes_runtime', $magic_quotes);
2721 return $file_buffer;
2723 $this->
setError($exc->getMessage());
2739 switch (strtolower($encoding)) {
2741 $encoded = chunk_split(base64_encode($str), 76, $this->LE);
2745 $encoded = $this->
fixEOL($str);
2747 if (substr($encoded, -(strlen($this->LE))) != $this->LE) {
2754 case 'quoted-printable':
2775 switch (strtolower($position)) {
2777 if (!preg_match(
'/[\200-\377]/', $str)) {
2779 $encoded = addcslashes($str,
"\0..\37\177\\\"");
2780 if (($str == $encoded) && !preg_match(
'/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
2783 return (
"\"$encoded\"");
2786 $matchcount = preg_match_all(
'/[^\040\041\043-\133\135-\176]/', $str, $matches);
2790 $matchcount = preg_match_all(
'/[()"]/', $str, $matches);
2794 $matchcount += preg_match_all(
'/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
2799 if ($matchcount == 0) {
2803 $maxlen = 75 - 7 - strlen($this->CharSet);
2805 if ($matchcount > strlen($str) / 3) {
2808 if (function_exists(
'mb_strlen') && $this->
hasMultiBytes($str)) {
2813 $encoded = base64_encode($str);
2814 $maxlen -= $maxlen % 4;
2815 $encoded = trim(chunk_split($encoded, $maxlen,
"\n"));
2819 $encoded = $this->
encodeQ($str, $position);
2820 $encoded = $this->
wrapText($encoded, $maxlen,
true);
2821 $encoded = str_replace(
'=' . self::CRLF,
"\n", trim($encoded));
2824 $encoded = preg_replace(
'/^(.*)$/m',
' =?' . $this->CharSet .
"?$encoding?\\1?=", $encoded);
2825 $encoded = trim(str_replace(
"\n", $this->LE, $encoded));
2838 if (function_exists(
'mb_strlen')) {
2839 return (strlen($str) > mb_strlen($str, $this->CharSet));
2852 return (
boolean)preg_match(
'/[\x80-\xFF]/',
$text);
2867 $start =
'=?' . $this->CharSet .
'?B?';
2870 if ($linebreak === null) {
2874 $mb_length = mb_strlen($str, $this->CharSet);
2876 $length = 75 - strlen($start) - strlen(
$end);
2878 $ratio = $mb_length / strlen($str);
2880 $avgLength = floor($length * $ratio * .75);
2882 for (
$i = 0;
$i < $mb_length;
$i += $offset) {
2885 $offset = $avgLength - $lookBack;
2886 $chunk = mb_substr($str,
$i, $offset, $this->CharSet);
2887 $chunk = base64_encode($chunk);
2889 }
while (strlen($chunk) > $length);
2890 $encoded .= $chunk . $linebreak;
2894 $encoded = substr($encoded, 0, -strlen($linebreak));
2910 if (function_exists(
'quoted_printable_encode')) {
2911 return quoted_printable_encode($string);
2914 $string = str_replace(
2915 array(
'%20',
'%0D%0A.',
'%0D%0A',
'%'),
2916 array(
' ',
"\r\n=2E",
"\r\n",
'='),
2917 rawurlencode($string)
2919 return preg_replace(
'/[^\r\n]{' . ($line_max - 3) .
'}[^=\r\n]{2}/',
"$0=\r\n", $string);
2934 $line_max = 76, $space_conv =
false 2937 return $this->
encodeQP($string, $line_max);
2952 $encoded = str_replace(
array(
"\r",
"\n"),
'', $str);
2953 switch (strtolower($position)) {
2956 $pattern =
'^A-Za-z0-9!*+\/ -';
2968 $pattern =
'\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
2972 if (preg_match_all(
"/[{$pattern}]/", $encoded, $matches)) {
2975 $eqkey = array_search(
'=', $matches[0]);
2976 if (
false !== $eqkey) {
2977 unset($matches[0][$eqkey]);
2978 array_unshift($matches[0],
'=');
2980 foreach (array_unique($matches[0]) as $char) {
2981 $encoded = str_replace($char,
'=' . sprintf(
'%02X', ord($char)), $encoded);
2985 return str_replace(
' ',
'_', $encoded);
3002 $encoding =
'base64',
3004 $disposition =
'attachment' 3011 $this->attachment[] =
array(
3042 if (!@is_file(
$path)) {
3058 $this->attachment[] =
array(
3089 $encoding =
'base64',
3091 $disposition =
'inline' 3099 $this->attachment[] =
array(
3120 if ($attachment[6] ==
'inline') {
3134 if ($attachment[6] ==
'attachment') {
3147 return !empty($this->AltBody);
3161 unset($this->RecipientsQueue[$address]);
3172 foreach ($this->
to as
$to) {
3173 unset($this->all_recipients[strtolower($to[0])]);
3185 foreach ($this->cc as
$cc) {
3186 unset($this->all_recipients[strtolower($cc[0])]);
3188 $this->cc =
array();
3198 foreach ($this->bcc as
$bcc) {
3199 unset($this->all_recipients[strtolower($bcc[0])]);
3201 $this->bcc =
array();
3211 $this->ReplyTo =
array();
3212 $this->ReplyToQueue =
array();
3222 $this->cc =
array();
3223 $this->bcc =
array();
3224 $this->all_recipients =
array();
3225 $this->RecipientsQueue =
array();
3234 $this->attachment =
array();
3243 $this->CustomHeader =
array();
3254 $this->error_count++;
3255 if ($this->Mailer ==
'smtp' and !is_null($this->smtp)) {
3256 $lasterror = $this->smtp->getError();
3257 if (!empty($lasterror[
'error'])) {
3258 $msg .= $this->
lang(
'smtp_error') . $lasterror[
'error'];
3259 if (!empty($lasterror[
'detail'])) {
3260 $msg .=
' Detail: '. $lasterror[
'detail'];
3262 if (!empty($lasterror[
'smtp_code'])) {
3263 $msg .=
' SMTP code: ' . $lasterror[
'smtp_code'];
3265 if (!empty($lasterror[
'smtp_code_ex'])) {
3266 $msg .=
' Additional SMTP info: ' . $lasterror[
'smtp_code_ex'];
3270 $this->ErrorInfo = $msg;
3283 date_default_timezone_set(@date_default_timezone_get());
3284 return date(
'D, j M Y H:i:s O');
3295 $result =
'localhost.localdomain';
3296 if (!empty($this->Hostname)) {
3300 } elseif (function_exists(
'gethostname') && gethostname() !==
false) {
3302 } elseif (php_uname(
'n') !==
false) {
3316 if (count($this->language) < 1) {
3320 if (array_key_exists(
$key, $this->language)) {
3321 if (
$key ==
'smtp_connect_failed') {
3325 return $this->language[
$key] .
' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting';
3327 return $this->language[
$key];
3341 return ($this->error_count > 0);
3354 $nstr = str_replace(
array(
"\r\n",
"\r"),
"\n", $str);
3356 if ($this->LE !==
"\n") {
3357 $nstr = str_replace(
"\n", $this->LE, $nstr);
3373 if ($value === null) {
3375 $this->CustomHeader[] = explode(
':',
$name, 2);
3377 $this->CustomHeader[] =
array(
$name, $value);
3408 preg_match_all(
'/(src|background)=["\'](.*)["\']/Ui',
$message, $images);
3409 if (array_key_exists(2, $images)) {
3410 if (strlen($basedir) > 1 && substr($basedir, -1) !=
'/') {
3414 foreach ($images[2] as $imgindex =>
$url) {
3416 if (preg_match(
'#^data:(image[^;,]*)(;base64)?,#',
$url, $match)) {
3423 $cid = md5(
$url) .
'@phpmailer.0';
3426 $images[0][$imgindex],
3427 $images[1][$imgindex] .
'="cid:' . $cid .
'"',
3437 && (strpos(
$url,
'..') ===
false)
3439 && substr(
$url, 0, 4) !==
'cid:' 3441 && !preg_match(
'#^[a-z][a-z0-9+.-]*:?//#i',
$url)
3444 $directory = dirname(
$url);
3445 if ($directory ==
'.') {
3448 $cid = md5(
$url) .
'@phpmailer.0';
3449 if (strlen($directory) > 1 && substr($directory, -1) !=
'/') {
3457 self::_mime_types((
string)self::mb_pathinfo($filename, PATHINFO_EXTENSION))
3461 '/' . $images[1][$imgindex] .
'=["\']' . preg_quote(
$url,
'/') .
'["\']/Ui',
3462 $images[1][$imgindex] .
'="cid:' . $cid .
'"',
3474 $this->AltBody =
'To view this email message, open it in a program that understands HTML!' .
3475 self::CRLF . self::CRLF;
3502 if (is_callable($advanced)) {
3503 return call_user_func($advanced,
$html);
3505 return html_entity_decode(
3506 trim(strip_tags(preg_replace(
'/<(head|title|style|script)[^>]*>.*?<\/\\1>/si',
'',
$html))),
3522 'xl' =>
'application/excel',
3523 'js' =>
'application/javascript',
3524 'hqx' =>
'application/mac-binhex40',
3525 'cpt' =>
'application/mac-compactpro',
3526 'bin' =>
'application/macbinary',
3527 'doc' =>
'application/msword',
3528 'word' =>
'application/msword',
3529 'xlsx' =>
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
3530 'xltx' =>
'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
3531 'potx' =>
'application/vnd.openxmlformats-officedocument.presentationml.template',
3532 'ppsx' =>
'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
3533 'pptx' =>
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
3534 'sldx' =>
'application/vnd.openxmlformats-officedocument.presentationml.slide',
3535 'docx' =>
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
3536 'dotx' =>
'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
3537 'xlam' =>
'application/vnd.ms-excel.addin.macroEnabled.12',
3538 'xlsb' =>
'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
3539 'class' =>
'application/octet-stream',
3540 'dll' =>
'application/octet-stream',
3541 'dms' =>
'application/octet-stream',
3542 'exe' =>
'application/octet-stream',
3543 'lha' =>
'application/octet-stream',
3544 'lzh' =>
'application/octet-stream',
3545 'psd' =>
'application/octet-stream',
3546 'sea' =>
'application/octet-stream',
3547 'so' =>
'application/octet-stream',
3548 'oda' =>
'application/oda',
3549 'pdf' =>
'application/pdf',
3550 'ai' =>
'application/postscript',
3551 'eps' =>
'application/postscript',
3552 'ps' =>
'application/postscript',
3553 'smi' =>
'application/smil',
3554 'smil' =>
'application/smil',
3555 'mif' =>
'application/vnd.mif',
3556 'xls' =>
'application/vnd.ms-excel',
3557 'ppt' =>
'application/vnd.ms-powerpoint',
3558 'wbxml' =>
'application/vnd.wap.wbxml',
3559 'wmlc' =>
'application/vnd.wap.wmlc',
3560 'dcr' =>
'application/x-director',
3561 'dir' =>
'application/x-director',
3562 'dxr' =>
'application/x-director',
3563 'dvi' =>
'application/x-dvi',
3564 'gtar' =>
'application/x-gtar',
3565 'php3' =>
'application/x-httpd-php',
3566 'php4' =>
'application/x-httpd-php',
3567 'php' =>
'application/x-httpd-php',
3568 'phtml' =>
'application/x-httpd-php',
3569 'phps' =>
'application/x-httpd-php-source',
3570 'swf' =>
'application/x-shockwave-flash',
3571 'sit' =>
'application/x-stuffit',
3572 'tar' =>
'application/x-tar',
3573 'tgz' =>
'application/x-tar',
3574 'xht' =>
'application/xhtml+xml',
3575 'xhtml' =>
'application/xhtml+xml',
3576 'zip' =>
'application/zip',
3577 'mid' =>
'audio/midi',
3578 'midi' =>
'audio/midi',
3579 'mp2' =>
'audio/mpeg',
3580 'mp3' =>
'audio/mpeg',
3581 'mpga' =>
'audio/mpeg',
3582 'aif' =>
'audio/x-aiff',
3583 'aifc' =>
'audio/x-aiff',
3584 'aiff' =>
'audio/x-aiff',
3585 'ram' =>
'audio/x-pn-realaudio',
3586 'rm' =>
'audio/x-pn-realaudio',
3587 'rpm' =>
'audio/x-pn-realaudio-plugin',
3588 'ra' =>
'audio/x-realaudio',
3589 'wav' =>
'audio/x-wav',
3590 'bmp' =>
'image/bmp',
3591 'gif' =>
'image/gif',
3592 'jpeg' =>
'image/jpeg',
3593 'jpe' =>
'image/jpeg',
3594 'jpg' =>
'image/jpeg',
3595 'png' =>
'image/png',
3596 'tiff' =>
'image/tiff',
3597 'tif' =>
'image/tiff',
3598 'eml' =>
'message/rfc822',
3599 'css' =>
'text/css',
3600 'html' =>
'text/html',
3601 'htm' =>
'text/html',
3602 'shtml' =>
'text/html',
3603 'log' =>
'text/plain',
3604 'text' =>
'text/plain',
3605 'txt' =>
'text/plain',
3606 'rtx' =>
'text/richtext',
3607 'rtf' =>
'text/rtf',
3608 'vcf' =>
'text/vcard',
3609 'vcard' =>
'text/vcard',
3610 'xml' =>
'text/xml',
3611 'xsl' =>
'text/xml',
3612 'mpeg' =>
'video/mpeg',
3613 'mpe' =>
'video/mpeg',
3614 'mpg' =>
'video/mpeg',
3615 'mov' =>
'video/quicktime',
3616 'qt' =>
'video/quicktime',
3617 'rv' =>
'video/vnd.rn-realvideo',
3618 'avi' =>
'video/x-msvideo',
3619 'movie' =>
'video/x-sgi-movie' 3621 if (array_key_exists(strtolower($ext), $mimes)) {
3622 return $mimes[strtolower($ext)];
3624 return 'application/octet-stream';
3638 if (
false !== $qpos) {
3641 $pathinfo = self::mb_pathinfo(
$filename);
3642 return self::_mime_types($pathinfo[
'extension']);
3658 $ret =
array(
'dirname' =>
'',
'basename' =>
'',
'extension' =>
'',
'filename' =>
'');
3659 $pathinfo =
array();
3660 if (preg_match(
'%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im',
$path, $pathinfo)) {
3661 if (array_key_exists(1, $pathinfo)) {
3662 $ret[
'dirname'] = $pathinfo[1];
3664 if (array_key_exists(2, $pathinfo)) {
3665 $ret[
'basename'] = $pathinfo[2];
3667 if (array_key_exists(5, $pathinfo)) {
3668 $ret[
'extension'] = $pathinfo[5];
3670 if (array_key_exists(3, $pathinfo)) {
3671 $ret[
'filename'] = $pathinfo[3];
3675 case PATHINFO_DIRNAME:
3677 return $ret[
'dirname'];
3678 case PATHINFO_BASENAME:
3680 return $ret[
'basename'];
3681 case PATHINFO_EXTENSION:
3683 return $ret[
'extension'];
3684 case PATHINFO_FILENAME:
3686 return $ret[
'filename'];
3708 if (property_exists($this,
$name)) {
3709 $this->
$name = $value;
3725 return trim(str_replace(
array(
"\r",
"\n"),
'', $str));
3740 return preg_replace(
'/(\r\n|\r|\n)/ms', $breaktype,
$text);
3751 public function sign($cert_filename, $key_filename, $key_pass, $extracerts_filename =
'')
3753 $this->sign_cert_file = $cert_filename;
3754 $this->sign_key_file = $key_filename;
3755 $this->sign_key_pass = $key_pass;
3756 $this->sign_extracerts_file = $extracerts_filename;
3770 if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
3773 $line .=
'=' . sprintf(
'%02X', $ord);
3789 if ($this->exceptions) {
3794 $privKeyStr = !empty($this->DKIM_private_string) ? $this->DKIM_private_string : file_get_contents($this->DKIM_private);
3795 if (
'' != $this->DKIM_passphrase) {
3796 $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
3798 $privKey = openssl_pkey_get_private($privKeyStr);
3802 if (version_compare(PHP_VERSION,
'5.3.0') >= 0 and
3803 in_array(
'sha256WithRSAEncryption', openssl_get_md_methods(
true))) {
3804 if (openssl_sign($signHeader, $signature, $privKey,
'sha256WithRSAEncryption')) {
3805 openssl_pkey_free($privKey);
3806 return base64_encode($signature);
3809 $pinfo = openssl_pkey_get_details($privKey);
3810 $hash =
hash(
'sha256', $signHeader);
3813 $t =
'3031300d060960864801650304020105000420' . $hash;
3814 $pslen = $pinfo[
'bits'] / 8 - (strlen(
$t) / 2 + 3);
3815 $eb = pack(
'H*',
'0001' . str_repeat(
'FF', $pslen) .
'00' .
$t);
3817 if (openssl_private_encrypt($eb, $signature, $privKey, OPENSSL_NO_PADDING)) {
3818 openssl_pkey_free($privKey);
3819 return base64_encode($signature);
3822 openssl_pkey_free($privKey);
3834 $signHeader = preg_replace(
'/\r\n\s+/',
' ', $signHeader);
3835 $lines = explode(
"\r\n", $signHeader);
3836 foreach ($lines as
$key => $line) {
3837 list($heading, $value) = explode(
':', $line, 2);
3838 $heading = strtolower($heading);
3839 $value = preg_replace(
'/\s{2,}/',
' ', $value);
3840 $lines[
$key] = $heading .
':' . trim($value);
3842 $signHeader = implode(
"\r\n", $lines);
3858 $body = str_replace(
"\r\n",
"\n", $body);
3859 $body = str_replace(
"\n",
"\r\n", $body);
3861 while (substr($body, strlen($body) - 4, 4) ==
"\r\n\r\n") {
3862 $body = substr($body, 0, strlen($body) - 2);
3875 public function DKIM_Add($headers_line, $subject, $body)
3877 $DKIMsignatureType =
'rsa-sha256';
3878 $DKIMcanonicalization =
'relaxed/simple';
3879 $DKIMquery =
'dns/txt';
3881 $subject_header =
"Subject: $subject";
3882 $headers = explode($this->LE, $headers_line);
3887 foreach ($headers as
$header) {
3888 if (strpos($header,
'From:') === 0) {
3891 } elseif (strpos($header,
'To:') === 0) {
3894 } elseif (strpos($header,
'Date:') === 0) {
3898 if (!empty($
$current) && strpos($header,
' =?') === 0) {
3905 $from = str_replace(
'|',
'=7C', $this->
DKIM_QP($from_header));
3906 $to = str_replace(
'|',
'=7C', $this->
DKIM_QP($to_header));
3907 $date = str_replace(
'|',
'=7C', $this->
DKIM_QP($date_header));
3908 $subject = str_replace(
3911 $this->
DKIM_QP($subject_header)
3914 $DKIMlen = strlen($body);
3915 $DKIMb64 = base64_encode(pack(
'H*',
hash(
'sha256', $body)));
3916 if (
'' == $this->DKIM_identity) {
3919 $ident =
' i=' . $this->DKIM_identity .
';';
3921 $dkimhdrs =
'DKIM-Signature: v=1; a=' .
3922 $DKIMsignatureType .
'; q=' .
3923 $DKIMquery .
'; l=' .
3925 $this->DKIM_selector .
3927 "\tt=" . $DKIMtime .
'; c=' . $DKIMcanonicalization .
";\r\n" .
3928 "\th=From:To:Date:Subject;\r\n" .
3929 "\td=" . $this->DKIM_domain .
';' . $ident .
"\r\n" .
3933 "\t|$subject;\r\n" .
3934 "\tbh=" . $DKIMb64 .
";\r\n" .
3937 $from_header .
"\r\n" .
3938 $to_header .
"\r\n" .
3939 $date_header .
"\r\n" .
3940 $subject_header .
"\r\n" .
3944 return $dkimhdrs . $signed .
"\r\n";
3956 return (
boolean)preg_match(
'/^(.{'.(self::MAX_LINE_LENGTH + 2).
',})/m', $str);
4026 if (!empty($this->action_function) && is_callable($this->action_function)) {
4028 call_user_func_array($this->action_function,
$params);
4045 $errorMsg =
'<strong>' . htmlspecialchars($this->getMessage()) .
"</strong><br />\n";
addAnAddress($kind, $address, $name='')
Add an address to one of the recipient arrays or to the ReplyTo array.
static validateAddress($address, $patternselect=null)
Check that a string looks like an email address.
generateId()
Create unique ID.
setError($msg)
Add an error message to the error container.
getSentMIMEMessage()
Returns the whole MIME message.
attachmentExists()
Check if an attachment (non-inline) is present.
addCustomHeader($name, $value=null)
Add a custom header.
addOrEnqueueAnAddress($kind, $address, $name)
Add an address to one of the recipient arrays or to the ReplyTo array.
headerLine($name, $value)
Format a header line.
if(isset($_REQUEST['delete'])) $list
clearQueuedAddresses($kind)
Clear queued addresses of given kind.
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
addEmbeddedImage($path, $cid, $name='', $encoding='base64', $type='', $disposition='inline')
Add an embedded (inline) attachment from a file.
getAllRecipientAddresses()
Allows for public read access to 'all_recipients' property.
idnSupported()
Tells whether IDNs (Internationalized Domain Names) are supported or not.
postSend()
Actually send a message.
__construct($exceptions=null)
Constructor.
base64EncodeWrapMB($str, $linebreak=null)
Encode and wrap long multibyte strings for mail headers without breaking lines within a character...
createBody()
Assemble the message body.
setMessageType()
Set the message type.
errorMessage()
Prettify error message output.
clearAddresses()
Clear all To recipients.
isSMTP()
Send messages using SMTP.
static rfcDate()
Return an RFC 822 formatted date.
addAddress($address, $name='')
Add a "To" address.
static mb_pathinfo($path, $options=null)
Multi-byte-safe pathinfo replacement.
const STOP_CRITICAL
Error severity: message, plus full stop, critical error reached.
setLanguage($langcode='en', $lang_path='')
Set the language for error messages.
encodeQ($str, $position='text')
Encode a string using Q encoding.
static filenameToType($filename)
Map a file name to a MIME type.
addStringAttachment( $string, $filename, $encoding='base64', $type='', $disposition='attachment')
Add a string or binary attachment (non-filesystem).
getTranslations()
Get the array of strings for the current language.
has8bitChars($text)
Does a string contain any 8-bit chars (in any charset)?
smtpClose()
Close the active SMTP session if one exists.
wrapText($message, $length, $qp_mode=false)
Word-wrap message.
msgHTML($message, $basedir='', $advanced=false)
Create a message body from an HTML string.
getCustomHeaders()
Returns all custom headers.
DKIM_Sign($signHeader)
Generate a DKIM signature.
addBCC($address, $name='')
Add a "BCC" address.
isHTML($isHtml=true)
Sets message type to HTML or plain.
getReplyToAddresses()
Allows for public read access to 'ReplyTo' property.
mail($to, $subject, $message, $additional_headers=null, $additional_parameters=null)
setFrom($address, $name='', $auto=true)
Set the From and FromName properties.
clearCustomHeaders()
Clear all custom headers.
static hasLineLongerThanMax($str)
Detect if a string contains a line longer than the maximum line length allowed.
sign($cert_filename, $key_filename, $key_pass, $extracerts_filename='')
Set the public and private key files and password for S/MIME signing.
addAttachment($path, $name='', $encoding='base64', $type='', $disposition='attachment')
Add an attachment from a path on the filesystem.
doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from)
Perform a callback.
clearBCCs()
Clear all BCC recipients.
PHPMailer - PHP email creation and transport class.
edebug($str)
Output debugging info via user-defined method.
createHeader()
Assemble message headers.
DKIM_BodyC($body)
Generate a DKIM canonicalization body.
parseAddresses($addrstr, $useimap=true)
Parse and validate a string containing one or more RFC822-style comma-separated email addresses of th...
getCcAddresses()
Allows for public read access to 'cc' property.
catch(Exception $e) $message
isError()
Check if an error occurred.
attachAll($disposition_type, $boundary)
Attach all file, string, and binary attachments to the message.
utf8CharBoundary($encodedText, $maxLength)
Find the last character boundary prior to $maxLength in a utf-8 quoted-printable encoded string...
smtpSend($header, $body)
Send mail via SMTP.
clearAllRecipients()
Clear all recipient types.
serverHostname()
Get the server hostname.
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
isMail()
Send messages using PHP's mail() function.
const CRLF
SMTP RFC standard line ending.
DKIM_QP($txt)
Quoted-Printable-encode a DKIM header.
send()
Create a message and send it.
preSend()
Prepare a message for sending.
inlineImageExists()
Check if an inline attachment is present.
secureHeader($str)
Strip newlines to prevent header injection.
isQmail()
Send messages using qmail.
endBoundary($boundary)
Return the end of a message boundary.
const STOP_MESSAGE
Error severity: message only, continue processing.
addReplyTo($address, $name='')
Add a "Reply-To" address.
Create styles array
The data for the language used.
addrFormat($addr)
Format an address for use in a message header.
encodeFile($path, $encoding='base64')
Encode a file attachment in requested format.
addCC($address, $name='')
Add a "CC" address.
addrAppend($type, $addr)
Create recipient headers.
$PHPMAILER_LANG['authenticate']
getBccAddresses()
Allows for public read access to 'bcc' property.
encodeQP($string, $line_max=76)
Encode a string in quoted-printable format.
textLine($value)
Return a formatted mail line.
static normalizeBreaks($text, $breaktype="\")
Normalize line breaks in a string.
mailPassthru($to, $subject, $body, $header, $params)
Call mail() in a safe_mode-aware fashion.
isSendmail()
Send messages using $Sendmail.
hasMultiBytes($str)
Check if a string contains multi-byte characters.
fixEOL($str)
Ensure consistent line endings in a string.
clearCCs()
Clear all CC recipients.
static _mime_types($ext='')
Get the MIME type for a file extension.
encodeString($str, $encoding='base64')
Encode a string in requested format.
getBoundary($boundary, $charSet, $contentType, $encoding)
Return the start of a message boundary.
encodeQPphp( $string, $line_max=76, $space_conv=false)
Backward compatibility wrapper for an old QP encoding function that was removed.
clearReplyTos()
Clear all ReplyTo recipients.
getLastMessageID()
Return the Message-ID header of the last email.
if($path[strlen($path) - 1]==='/') if(is_dir($path)) if(!file_exists($path)) if(preg_match('#\.php$#D', $path)) $contentType
getSMTPInstance()
Get an instance to use for SMTP operations.
smtpConnect($options=null)
Initiate a connection to an SMTP server.
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
clearAttachments()
Clear all filesystem, string, and binary attachments.
html2text($html, $advanced=false)
Convert an HTML string into plain text.
encodeHeader($str, $position='text')
Encode a header string optimally.
const STOP_CONTINUE
Error severity: message, likely ok to continue processing.
if(!array_key_exists('domain', $_REQUEST)) $domain
sendmailSend($header, $body)
Send mail using the $Sendmail program.
addStringEmbeddedImage( $string, $cid, $name='', $encoding='base64', $type='', $disposition='inline')
Add an embedded stringified attachment.
defined( 'APPLICATION_ENV')||define( 'APPLICATION_ENV'
mailSend($header, $body)
Send mail using the PHP mail() function.
setWordWrap()
Apply word wrapping to the message body.
getToAddresses()
Allows for public read access to 'to' property.
DKIM_HeaderC($signHeader)
Generate a DKIM canonicalization header.
DKIM_Add($headers_line, $subject, $body)
Create the DKIM header and body in a new message header.
hash(StreamInterface $stream, $algo, $rawOutput=false)
Calculate a hash of a Stream.
punyencodeAddress($address)
Converts IDN in given email address to its ASCII form, also known as punycode, if possible...
alternativeExists()
Check if this message has an alternative body set.
lang($key)
Get an error message in the current language.
getAttachments()
Return the array of attachments.
if(!isset($_REQUEST['ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
static isShellSafe($string)
Fix CVE-2016-10033 and CVE-2016-10045 by disallowing potentially unsafe shell characters.
getMailMIME()
Get the message MIME type headers.