PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/libraries/phpmailer/phpmailer.php

https://github.com/MilkZoft/zan
PHP | 969 lines | 850 code | 117 blank | 2 comment | 137 complexity | b9778437a1094b4d1494ff3859e69843 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. class PHPMailer
  3. {
  4. public $Priority = 3;
  5. public $CharSet = "iso-8859-1";
  6. public $ContentType = "text/plain";
  7. public $Encoding = "8bit";
  8. public $ErrorInfo = "";
  9. public $From = "root@localhost";
  10. public $FromName = "Root User";
  11. public $Sender = "";
  12. public $Subject = "";
  13. public $Body = "";
  14. public $AltBody = "";
  15. public $WordWrap = 0;
  16. public $Mailer = "mail";
  17. public $Sendmail = "/usr/sbin/sendmail";
  18. public $PluginDir = "";
  19. public $Version = "1.73";
  20. public $ConfirmReadingTo = "";
  21. public $Hostname = "";
  22. public $Host = "localhost";
  23. public $Port = 25;
  24. public $Helo = "";
  25. public $SMTPAuth = false;
  26. public $Username = "";
  27. public $Password = "";
  28. public $Timeout = 10;
  29. public $SMTPDebug = false;
  30. public $SMTPKeepAlive = false;
  31. public $smtp = null;
  32. public $to = array();
  33. public $cc = array();
  34. public $bcc = array();
  35. public $ReplyTo = array();
  36. public $attachment = array();
  37. public $CustomHeader = array();
  38. public $message_type = "";
  39. public $boundary = array();
  40. public $language = array();
  41. public $error_count = 0;
  42. public $LE = "\n";
  43. public function IsHTML($bool) {
  44. if($bool == true)
  45. $this->ContentType = "text/html";
  46. else
  47. $this->ContentType = "text/plain";
  48. }
  49. public function IsSMTP() {
  50. $this->Mailer = "smtp";
  51. }
  52. public function IsMail() {
  53. $this->Mailer = "mail";
  54. }
  55. public function IsSendmail() {
  56. $this->Mailer = "sendmail";
  57. }
  58. public function IsQmail() {
  59. $this->Sendmail = "/var/qmail/bin/sendmail";
  60. $this->Mailer = "sendmail";
  61. }
  62. public function AddAddress($address, $name = "") {
  63. $cur = count($this->to);
  64. $this->to[$cur][0] = trim($address);
  65. $this->to[$cur][1] = $name;
  66. }
  67. public function AddCC($address, $name = "") {
  68. $cur = count($this->cc);
  69. $this->cc[$cur][0] = trim($address);
  70. $this->cc[$cur][1] = $name;
  71. }
  72. public function AddBCC($address, $name = "") {
  73. $cur = count($this->bcc);
  74. $this->bcc[$cur][0] = trim($address);
  75. $this->bcc[$cur][1] = $name;
  76. }
  77. public function AddReplyTo($address, $name = "") {
  78. $cur = count($this->ReplyTo);
  79. $this->ReplyTo[$cur][0] = trim($address);
  80. $this->ReplyTo[$cur][1] = $name;
  81. }
  82. public function Send() {
  83. $header = "";
  84. $body = "";
  85. $result = true;
  86. if((count($this->to) + count($this->cc) + count($this->bcc)) < 1)
  87. {
  88. $this->SetError($this->Lang("provide_address"));
  89. return false;
  90. }
  91. if(!empty($this->AltBody))
  92. $this->ContentType = "multipart/alternative";
  93. $this->error_count = 0;
  94. $this->SetMessageType();
  95. $header .= $this->CreateHeader();
  96. $body = $this->CreateBody();
  97. if($body == "") { return false; }
  98. switch($this->Mailer)
  99. {
  100. case "sendmail":
  101. $result = $this->SendmailSend($header, $body);
  102. break;
  103. case "mail":
  104. $result = $this->MailSend($header, $body);
  105. break;
  106. case "smtp":
  107. $result = $this->SmtpSend($header, $body);
  108. break;
  109. default:
  110. $this->SetError($this->Mailer . $this->Lang("mailer_not_supported"));
  111. $result = false;
  112. break;
  113. }
  114. return $result;
  115. }
  116. public function SendmailSend($header, $body) {
  117. if ($this->Sender != "")
  118. $sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, $this->Sender);
  119. else
  120. $sendmail = sprintf("%s -oi -t", $this->Sendmail);
  121. if(!@$mail = popen($sendmail, "w"))
  122. {
  123. $this->SetError($this->Lang("execute") . $this->Sendmail);
  124. return false;
  125. }
  126. fputs($mail, $header);
  127. fputs($mail, $body);
  128. $result = pclose($mail) >> 8 & 0xFF;
  129. if($result != 0)
  130. {
  131. $this->SetError($this->Lang("execute") . $this->Sendmail);
  132. return false;
  133. }
  134. return true;
  135. }
  136. public function MailSend($header, $body) {
  137. $to = "";
  138. for($i = 0; $i < count($this->to); $i++)
  139. {
  140. if($i != 0) { $to .= ", "; }
  141. $to .= $this->to[$i][0];
  142. }
  143. if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1)
  144. {
  145. $old_from = ini_get("sendmail_from");
  146. ini_set("sendmail_from", $this->Sender);
  147. $params = sprintf("-oi -f %s", $this->Sender);
  148. $rt = @mail($to, $this->EncodeHeader($this->Subject), $body,
  149. $header, $params);
  150. }
  151. else
  152. $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header);
  153. if (isset($old_from))
  154. ini_set("sendmail_from", $old_from);
  155. if(!$rt)
  156. {
  157. $this->SetError($this->Lang("instantiate"));
  158. return false;
  159. }
  160. return true;
  161. }
  162. public function SmtpSend($header, $body) {
  163. include_once($this->PluginDir . "smtp.php");
  164. $error = "";
  165. $bad_rcpt = array();
  166. if(!$this->SmtpConnect())
  167. return false;
  168. $smtp_from = ($this->Sender == "") ? $this->From : $this->Sender;
  169. if(!$this->smtp->Mail($smtp_from))
  170. {
  171. $error = $this->Lang("from_failed") . $smtp_from;
  172. $this->SetError($error);
  173. $this->smtp->Reset();
  174. return false;
  175. }
  176. for($i = 0; $i < count($this->to); $i++)
  177. {
  178. if(!$this->smtp->Recipient($this->to[$i][0]))
  179. $bad_rcpt[] = $this->to[$i][0];
  180. }
  181. for($i = 0; $i < count($this->cc); $i++)
  182. {
  183. if(!$this->smtp->Recipient($this->cc[$i][0]))
  184. $bad_rcpt[] = $this->cc[$i][0];
  185. }
  186. for($i = 0; $i < count($this->bcc); $i++)
  187. {
  188. if(!$this->smtp->Recipient($this->bcc[$i][0]))
  189. $bad_rcpt[] = $this->bcc[$i][0];
  190. }
  191. if(count($bad_rcpt) > 0) // Create error message
  192. {
  193. for($i = 0; $i < count($bad_rcpt); $i++)
  194. {
  195. if($i != 0) { $error .= ", "; }
  196. $error .= $bad_rcpt[$i];
  197. }
  198. $error = $this->Lang("recipients_failed") . $error;
  199. $this->SetError($error);
  200. $this->smtp->Reset();
  201. return false;
  202. }
  203. if(!$this->smtp->Data($header . $body))
  204. {
  205. $this->SetError($this->Lang("data_not_accepted"));
  206. $this->smtp->Reset();
  207. return false;
  208. }
  209. if($this->SMTPKeepAlive == true)
  210. $this->smtp->Reset();
  211. else
  212. $this->SmtpClose();
  213. return true;
  214. }
  215. public function SmtpConnect() {
  216. if($this->smtp == null) { $this->smtp = new SMTP(); }
  217. $this->smtp->do_debug = $this->SMTPDebug;
  218. $hosts = explode(";", $this->Host);
  219. $index = 0;
  220. $connection = ($this->smtp->Connected());
  221. // Retry while there is no connection
  222. while($index < count($hosts) && $connection == false)
  223. {
  224. if (preg_match('#(([a-z]+://)?[^:]+):(\d+)#i', $hosts[$index], $match))
  225. {
  226. $host = $match[1];
  227. $port = $match[3];
  228. }
  229. else
  230. {
  231. $host = $hosts[$index];
  232. $port = $this->Port;
  233. }
  234. if($this->smtp->Connect($host, $port, $this->Timeout))
  235. {
  236. if ($this->Helo != '')
  237. $this->smtp->Hello($this->Helo);
  238. else
  239. $this->smtp->Hello($this->ServerHostname());
  240. if($this->SMTPAuth)
  241. {
  242. if(!$this->smtp->Authenticate($this->Username,
  243. $this->Password))
  244. {
  245. $this->SetError($this->Lang("authenticate"));
  246. $this->smtp->Reset();
  247. $connection = false;
  248. }
  249. }
  250. $connection = true;
  251. }
  252. $index++;
  253. }
  254. if(!$connection)
  255. $this->SetError($this->Lang("connect_host"));
  256. return $connection;
  257. }
  258. public function SmtpClose() {
  259. if($this->smtp != null)
  260. {
  261. if($this->smtp->Connected())
  262. {
  263. $this->smtp->Quit();
  264. $this->smtp->Close();
  265. }
  266. }
  267. }
  268. public function SetLanguage($lang_type, $lang_path = "language/") {
  269. if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php'))
  270. include($lang_path.'phpmailer.lang-'.$lang_type.'.php');
  271. else if(file_exists($lang_path.'phpmailer.lang-en.php'))
  272. include($lang_path.'phpmailer.lang-en.php');
  273. else
  274. {
  275. $this->SetError("Could not load language file");
  276. return false;
  277. }
  278. $this->language = $PHPMAILER_LANG;
  279. return true;
  280. }
  281. public function AddrAppend($type, $addr) {
  282. $addr_str = $type . ": ";
  283. $addr_str .= $this->AddrFormat($addr[0]);
  284. if(count($addr) > 1)
  285. {
  286. for($i = 1; $i < count($addr); $i++)
  287. $addr_str .= ", " . $this->AddrFormat($addr[$i]);
  288. }
  289. $addr_str .= $this->LE;
  290. return $addr_str;
  291. }
  292. public function AddrFormat($addr) {
  293. if(empty($addr[1]))
  294. $formatted = $addr[0];
  295. else
  296. {
  297. $formatted = $this->EncodeHeader($addr[1], 'phrase') . " <" .
  298. $addr[0] . ">";
  299. }
  300. return $formatted;
  301. }
  302. public function WrapText($message, $length, $qp_mode = false) {
  303. $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
  304. $message = $this->FixEOL($message);
  305. if (substr($message, -1) == $this->LE)
  306. $message = substr($message, 0, -1);
  307. $line = explode($this->LE, $message);
  308. $message = "";
  309. for ($i=0 ;$i < count($line); $i++)
  310. {
  311. $line_part = explode(" ", $line[$i]);
  312. $buf = "";
  313. for ($e = 0; $e<count($line_part); $e++)
  314. {
  315. $word = $line_part[$e];
  316. if ($qp_mode and (strlen($word) > $length))
  317. {
  318. $space_left = $length - strlen($buf) - 1;
  319. if ($e != 0)
  320. {
  321. if ($space_left > 20)
  322. {
  323. $len = $space_left;
  324. if (substr($word, $len - 1, 1) == "=")
  325. $len--;
  326. elseif (substr($word, $len - 2, 1) == "=")
  327. $len -= 2;
  328. $part = substr($word, 0, $len);
  329. $word = substr($word, $len);
  330. $buf .= " " . $part;
  331. $message .= $buf . sprintf("=%s", $this->LE);
  332. }
  333. else
  334. {
  335. $message .= $buf . $soft_break;
  336. }
  337. $buf = "";
  338. }
  339. while (strlen($word) > 0)
  340. {
  341. $len = $length;
  342. if (substr($word, $len - 1, 1) == "=")
  343. $len--;
  344. elseif (substr($word, $len - 2, 1) == "=")
  345. $len -= 2;
  346. $part = substr($word, 0, $len);
  347. $word = substr($word, $len);
  348. if (strlen($word) > 0)
  349. $message .= $part . sprintf("=%s", $this->LE);
  350. else
  351. $buf = $part;
  352. }
  353. }
  354. else
  355. {
  356. $buf_o = $buf;
  357. $buf .= ($e == 0) ? $word : (" " . $word);
  358. if (strlen($buf) > $length and $buf_o != "")
  359. {
  360. $message .= $buf_o . $soft_break;
  361. $buf = $word;
  362. }
  363. }
  364. }
  365. $message .= $buf . $this->LE;
  366. }
  367. return $message;
  368. }
  369. public function SetWordWrap() {
  370. if($this->WordWrap < 1)
  371. return;
  372. switch($this->message_type)
  373. {
  374. case "alt":
  375. // fall through
  376. case "alt_attachments":
  377. $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
  378. break;
  379. default:
  380. $this->Body = $this->WrapText($this->Body, $this->WordWrap);
  381. break;
  382. }
  383. }
  384. public function CreateHeader() {
  385. $result = "";
  386. $uniq_id = md5(uniqid(time()));
  387. $this->boundary[1] = "b1_" . $uniq_id;
  388. $this->boundary[2] = "b2_" . $uniq_id;
  389. $result .= $this->HeaderLine("Date", $this->RFCDate());
  390. if($this->Sender == "")
  391. $result .= $this->HeaderLine("Return-Path", trim($this->From));
  392. else
  393. $result .= $this->HeaderLine("Return-Path", trim($this->Sender));
  394. if($this->Mailer != "mail")
  395. {
  396. if(count($this->to) > 0)
  397. $result .= $this->AddrAppend("To", $this->to);
  398. else if (count($this->cc) == 0)
  399. $result .= $this->HeaderLine("To", "undisclosed-recipients:;");
  400. if(count($this->cc) > 0)
  401. $result .= $this->AddrAppend("Cc", $this->cc);
  402. }
  403. $from = array();
  404. $from[0][0] = trim($this->From);
  405. $from[0][1] = $this->FromName;
  406. $result .= $this->AddrAppend("From", $from);
  407. if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0))
  408. $result .= $this->AddrAppend("Bcc", $this->bcc);
  409. if(count($this->ReplyTo) > 0)
  410. $result .= $this->AddrAppend("Reply-to", $this->ReplyTo);
  411. if($this->Mailer != "mail")
  412. $result .= $this->HeaderLine("Subject", $this->EncodeHeader(trim($this->Subject)));
  413. $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
  414. $result .= $this->HeaderLine("X-Priority", $this->Priority);
  415. $result .= $this->HeaderLine("X-Mailer", "PHPMailer [version " . $this->Version . "]");
  416. if($this->ConfirmReadingTo != "")
  417. {
  418. $result .= $this->HeaderLine("Disposition-Notification-To",
  419. "<" . trim($this->ConfirmReadingTo) . ">");
  420. }
  421. for($index = 0; $index < count($this->CustomHeader); $index++)
  422. {
  423. $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]),
  424. $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
  425. }
  426. $result .= $this->HeaderLine("MIME-Version", "1.0");
  427. switch($this->message_type)
  428. {
  429. case "plain":
  430. $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding);
  431. $result .= sprintf("Content-Type: %s; charset=\"%s\"",
  432. $this->ContentType, $this->CharSet);
  433. break;
  434. case "attachments":
  435. case "alt_attachments":
  436. if($this->InlineImageExists())
  437. {
  438. $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s",
  439. "multipart/related", $this->LE, $this->LE,
  440. $this->boundary[1], $this->LE);
  441. }
  442. else
  443. {
  444. $result .= $this->HeaderLine("Content-Type", "multipart/mixed;");
  445. $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
  446. }
  447. break;
  448. case "alt":
  449. $result .= $this->HeaderLine("Content-Type", "multipart/alternative;");
  450. $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
  451. break;
  452. }
  453. if($this->Mailer != "mail")
  454. $result .= $this->LE.$this->LE;
  455. return $result;
  456. }
  457. public function CreateBody() {
  458. $result = "";
  459. $this->SetWordWrap();
  460. switch($this->message_type)
  461. {
  462. case "alt":
  463. $result .= $this->GetBoundary($this->boundary[1], "",
  464. "text/plain", "");
  465. $result .= $this->EncodeString($this->AltBody, $this->Encoding);
  466. $result .= $this->LE.$this->LE;
  467. $result .= $this->GetBoundary($this->boundary[1], "",
  468. "text/html", "");
  469. $result .= $this->EncodeString($this->Body, $this->Encoding);
  470. $result .= $this->LE.$this->LE;
  471. $result .= $this->EndBoundary($this->boundary[1]);
  472. break;
  473. case "plain":
  474. $result .= $this->EncodeString($this->Body, $this->Encoding);
  475. break;
  476. case "attachments":
  477. $result .= $this->GetBoundary($this->boundary[1], "", "", "");
  478. $result .= $this->EncodeString($this->Body, $this->Encoding);
  479. $result .= $this->LE;
  480. $result .= $this->AttachAll();
  481. break;
  482. case "alt_attachments":
  483. $result .= sprintf("--%s%s", $this->boundary[1], $this->LE);
  484. $result .= sprintf("Content-Type: %s;%s" .
  485. "\tboundary=\"%s\"%s",
  486. "multipart/alternative", $this->LE,
  487. $this->boundary[2], $this->LE.$this->LE);
  488. $result .= $this->GetBoundary($this->boundary[2], "",
  489. "text/plain", "") . $this->LE;
  490. $result .= $this->EncodeString($this->AltBody, $this->Encoding);
  491. $result .= $this->LE.$this->LE;
  492. $result .= $this->GetBoundary($this->boundary[2], "",
  493. "text/html", "") . $this->LE;
  494. $result .= $this->EncodeString($this->Body, $this->Encoding);
  495. $result .= $this->LE.$this->LE;
  496. $result .= $this->EndBoundary($this->boundary[2]);
  497. $result .= $this->AttachAll();
  498. break;
  499. }
  500. if($this->IsError())
  501. $result = "";
  502. return $result;
  503. }
  504. public function GetBoundary($boundary, $charSet, $contentType, $encoding) {
  505. $result = "";
  506. if($charSet == "") { $charSet = $this->CharSet; }
  507. if($contentType == "") { $contentType = $this->ContentType; }
  508. if($encoding == "") { $encoding = $this->Encoding; }
  509. $result .= $this->TextLine("--" . $boundary);
  510. $result .= sprintf("Content-Type: %s; charset = \"%s\"",
  511. $contentType, $charSet);
  512. $result .= $this->LE;
  513. $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding);
  514. $result .= $this->LE;
  515. return $result;
  516. }
  517. public function EndBoundary($boundary) {
  518. return $this->LE . "--" . $boundary . "--" . $this->LE;
  519. }
  520. public function SetMessageType() {
  521. if(count($this->attachment) < 1 && strlen($this->AltBody) < 1)
  522. $this->message_type = "plain";
  523. else
  524. {
  525. if(count($this->attachment) > 0)
  526. $this->message_type = "attachments";
  527. if(strlen($this->AltBody) > 0 && count($this->attachment) < 1)
  528. $this->message_type = "alt";
  529. if(strlen($this->AltBody) > 0 && count($this->attachment) > 0)
  530. $this->message_type = "alt_attachments";
  531. }
  532. }
  533. public function HeaderLine($name, $value) {
  534. return $name . ": " . $value . $this->LE;
  535. }
  536. public function TextLine($value) {
  537. return $value . $this->LE;
  538. }
  539. public function AddAttachment($path, $name = "", $encoding = "base64",
  540. $type = "application/octet-stream") {
  541. if(!@is_file($path))
  542. {
  543. $this->SetError($this->Lang("file_access") . $path);
  544. return false;
  545. }
  546. $filename = basename($path);
  547. if($name == "")
  548. $name = $filename;
  549. $cur = count($this->attachment);
  550. $this->attachment[$cur][0] = $path;
  551. $this->attachment[$cur][1] = $filename;
  552. $this->attachment[$cur][2] = $name;
  553. $this->attachment[$cur][3] = $encoding;
  554. $this->attachment[$cur][4] = $type;
  555. $this->attachment[$cur][5] = false;
  556. $this->attachment[$cur][6] = "attachment";
  557. $this->attachment[$cur][7] = 0;
  558. return true;
  559. }
  560. public function AttachAll() {
  561. $mime = array();
  562. for($i = 0; $i < count($this->attachment); $i++)
  563. {
  564. $bString = $this->attachment[$i][5];
  565. if ($bString)
  566. $string = $this->attachment[$i][0];
  567. else
  568. $path = $this->attachment[$i][0];
  569. $filename = $this->attachment[$i][1];
  570. $name = $this->attachment[$i][2];
  571. $encoding = $this->attachment[$i][3];
  572. $type = $this->attachment[$i][4];
  573. $disposition = $this->attachment[$i][6];
  574. $cid = $this->attachment[$i][7];
  575. $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
  576. $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE);
  577. $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
  578. if($disposition == "inline")
  579. $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
  580. $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s",
  581. $disposition, $name, $this->LE.$this->LE);
  582. if($bString)
  583. {
  584. $mime[] = $this->EncodeString($string, $encoding);
  585. if($this->IsError()) { return ""; }
  586. $mime[] = $this->LE.$this->LE;
  587. }
  588. else
  589. {
  590. $mime[] = $this->EncodeFile($path, $encoding);
  591. if($this->IsError()) { return ""; }
  592. $mime[] = $this->LE.$this->LE;
  593. }
  594. }
  595. $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
  596. return join("", $mime);
  597. }
  598. public function EncodeFile ($path, $encoding = "base64") {
  599. if(!@$fd = fopen($path, "rb"))
  600. {
  601. $this->SetError($this->Lang("file_open") . $path);
  602. return "";
  603. }
  604. $magic_quotes = get_magic_quotes_runtime();
  605. set_magic_quotes_runtime(0);
  606. $file_buffer = fread($fd, filesize($path));
  607. $file_buffer = $this->EncodeString($file_buffer, $encoding);
  608. fclose($fd);
  609. set_magic_quotes_runtime($magic_quotes);
  610. return $file_buffer;
  611. }
  612. public function EncodeString ($str, $encoding = "base64") {
  613. $encoded = "";
  614. switch(strtolower($encoding)) {
  615. case "base64":
  616. $encoded = chunk_split(base64_encode($str), 76, $this->LE);
  617. break;
  618. case "7bit":
  619. case "8bit":
  620. $encoded = $this->FixEOL($str);
  621. if (substr($encoded, -(strlen($this->LE))) != $this->LE)
  622. $encoded .= $this->LE;
  623. break;
  624. case "binary":
  625. $encoded = $str;
  626. break;
  627. case "quoted-printable":
  628. $encoded = $this->EncodeQP($str);
  629. break;
  630. default:
  631. $this->SetError($this->Lang("encoding") . $encoding);
  632. break;
  633. }
  634. return $encoded;
  635. }
  636. public function EncodeHeader ($str, $position = 'text') {
  637. $x = 0;
  638. switch (strtolower($position)) {
  639. case 'phrase':
  640. if (!preg_match('/[\200-\377]/', $str)) {
  641. $encoded = addcslashes($str, "\0..\37\177\\\"");
  642. if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str))
  643. return ($encoded);
  644. else
  645. return ("\"$encoded\"");
  646. }
  647. $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
  648. break;
  649. case 'comment':
  650. $x = preg_match_all('/[()"]/', $str, $matches);
  651. case 'text':
  652. default:
  653. $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
  654. break;
  655. }
  656. if ($x == 0)
  657. return ($str);
  658. $maxlen = 75 - 7 - strlen($this->CharSet);
  659. if (strlen($str)/3 < $x) {
  660. $encoding = 'B';
  661. $encoded = base64_encode($str);
  662. $maxlen -= $maxlen % 4;
  663. $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
  664. } else {
  665. $encoding = 'Q';
  666. $encoded = $this->EncodeQ($str, $position);
  667. $encoded = $this->WrapText($encoded, $maxlen, true);
  668. $encoded = str_replace("=".$this->LE, "\n", trim($encoded));
  669. }
  670. $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
  671. $encoded = trim(str_replace("\n", $this->LE, $encoded));
  672. return $encoded;
  673. }
  674. public function EncodeQP ($str) {
  675. $encoded = $this->FixEOL($str);
  676. if (substr($encoded, -(strlen($this->LE))) != $this->LE)
  677. $encoded .= $this->LE;
  678. $encoded = preg_replace('/([\000-\010\013\014\016-\037\075\177-\377])/e', "'='.sprintf('%02X', ord('\\1'))", $encoded);
  679. $encoded = preg_replace("/([\011\040])".$this->LE."/e", "'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded);
  680. $encoded = $this->WrapText($encoded, 74, true);
  681. return $encoded;
  682. }
  683. public function EncodeQ ($str, $position = "text") {
  684. $encoded = preg_replace("[\r\n]", "", $str);
  685. switch (strtolower($position)) {
  686. case "phrase":
  687. $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
  688. break;
  689. case "comment":
  690. $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
  691. case "text":
  692. default:
  693. $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
  694. "'='.sprintf('%02X', ord('\\1'))", $encoded);
  695. break;
  696. }
  697. $encoded = str_replace(" ", "_", $encoded);
  698. return $encoded;
  699. }
  700. public function AddStringAttachment($string, $filename, $encoding = "base64", $type = "application/octet-stream") {
  701. $cur = count($this->attachment);
  702. $this->attachment[$cur][0] = $string;
  703. $this->attachment[$cur][1] = $filename;
  704. $this->attachment[$cur][2] = $filename;
  705. $this->attachment[$cur][3] = $encoding;
  706. $this->attachment[$cur][4] = $type;
  707. $this->attachment[$cur][5] = true; // isString
  708. $this->attachment[$cur][6] = "attachment";
  709. $this->attachment[$cur][7] = 0;
  710. }
  711. public function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64",
  712. $type = "application/octet-stream") {
  713. if(!@is_file($path))
  714. {
  715. $this->SetError($this->Lang("file_access") . $path);
  716. return false;
  717. }
  718. $filename = basename($path);
  719. if($name == "")
  720. $name = $filename;
  721. $cur = count($this->attachment);
  722. $this->attachment[$cur][0] = $path;
  723. $this->attachment[$cur][1] = $filename;
  724. $this->attachment[$cur][2] = $name;
  725. $this->attachment[$cur][3] = $encoding;
  726. $this->attachment[$cur][4] = $type;
  727. $this->attachment[$cur][5] = false;
  728. $this->attachment[$cur][6] = "inline";
  729. $this->attachment[$cur][7] = $cid;
  730. return true;
  731. }
  732. public function InlineImageExists() {
  733. $result = false;
  734. for($i = 0; $i < count($this->attachment); $i++)
  735. {
  736. if($this->attachment[$i][6] == "inline")
  737. {
  738. $result = true;
  739. break;
  740. }
  741. }
  742. return $result;
  743. }
  744. public function ClearAddresses() {
  745. $this->to = array();
  746. }
  747. public function ClearCCs() {
  748. $this->cc = array();
  749. }
  750. public function ClearBCCs() {
  751. $this->bcc = array();
  752. }
  753. public function ClearReplyTos() {
  754. $this->ReplyTo = array();
  755. }
  756. public function ClearAllRecipients() {
  757. $this->to = array();
  758. $this->cc = array();
  759. $this->bcc = array();
  760. }
  761. public function ClearAttachments() {
  762. $this->attachment = array();
  763. }
  764. public function ClearCustomHeaders() {
  765. $this->CustomHeader = array();
  766. }
  767. public function SetError($msg) {
  768. $this->error_count++;
  769. $this->ErrorInfo = $msg;
  770. }
  771. public function RFCDate() {
  772. $tz = date("Z");
  773. $tzs = ($tz < 0) ? "-" : "+";
  774. $tz = abs($tz);
  775. $tz = ($tz/3600)*100 + ($tz%3600)/60;
  776. $result = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz);
  777. return $result;
  778. }
  779. public function ServerVar($varName) {
  780. global $HTTP_SERVER_VARS;
  781. global $HTTP_ENV_VARS;
  782. if(!isset($_SERVER))
  783. {
  784. $_SERVER = $HTTP_SERVER_VARS;
  785. if(!isset($_SERVER["REMOTE_ADDR"]))
  786. $_SERVER = $HTTP_ENV_VARS;
  787. }
  788. if(isset($_SERVER[$varName]))
  789. return $_SERVER[$varName];
  790. else
  791. return "";
  792. }
  793. public function ServerHostname() {
  794. if ($this->Hostname != "")
  795. $result = $this->Hostname;
  796. elseif ($this->ServerVar('SERVER_NAME') != "")
  797. $result = $this->ServerVar('SERVER_NAME');
  798. else
  799. $result = "localhost.localdomain";
  800. return $result;
  801. }
  802. public function Lang($key) {
  803. if(count($this->language) < 1)
  804. $this->SetLanguage("en");
  805. if(isset($this->language[$key]))
  806. return $this->language[$key];
  807. else
  808. return "Language string failed to load: " . $key;
  809. }
  810. public function IsError() {
  811. return ($this->error_count > 0);
  812. }
  813. public function FixEOL($str) {
  814. $str = str_replace("\r\n", "\n", $str);
  815. $str = str_replace("\r", "\n", $str);
  816. $str = str_replace("\n", $this->LE, $str);
  817. return $str;
  818. }
  819. public function AddCustomHeader($custom_header) {
  820. $this->CustomHeader[] = explode(":", $custom_header, 2);
  821. }
  822. }