PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/upload/system/library/mail.php

https://github.com/fabiocarneiro/opencart
PHP | 406 lines | 313 code | 92 blank | 1 comment | 103 complexity | 87eb90dca417b70b7b24a98f443139c5 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, GPL-3.0
  1. <?php
  2. class Mail {
  3. protected $to;
  4. protected $from;
  5. protected $sender;
  6. protected $subject;
  7. protected $text;
  8. protected $html;
  9. protected $attachments = array();
  10. public $protocol = 'mail';
  11. public $hostname;
  12. public $username;
  13. public $password;
  14. public $port = 25;
  15. public $timeout = 5;
  16. public $newline = "\n";
  17. public $crlf = "\r\n";
  18. public $verp = false;
  19. public $parameter = '';
  20. public function setTo($to) {
  21. $this->to = $to;
  22. }
  23. public function setFrom($from) {
  24. $this->from = $from;
  25. }
  26. public function setSender($sender) {
  27. $this->sender = $sender;
  28. }
  29. public function setSubject($subject) {
  30. $this->subject = $subject;
  31. }
  32. public function setText($text) {
  33. $this->text = $text;
  34. }
  35. public function setHtml($html) {
  36. $this->html = $html;
  37. }
  38. public function addAttachment($filename) {
  39. $this->attachments[] = $filename;
  40. }
  41. public function send() {
  42. if (!$this->to) {
  43. trigger_error('Error: E-Mail to required!');
  44. exit();
  45. }
  46. if (!$this->from) {
  47. trigger_error('Error: E-Mail from required!');
  48. exit();
  49. }
  50. if (!$this->sender) {
  51. trigger_error('Error: E-Mail sender required!');
  52. exit();
  53. }
  54. if (!$this->subject) {
  55. trigger_error('Error: E-Mail subject required!');
  56. exit();
  57. }
  58. if ((!$this->text) && (!$this->html)) {
  59. trigger_error('Error: E-Mail message required!');
  60. exit();
  61. }
  62. if (is_array($this->to)) {
  63. $to = implode(',', $this->to);
  64. } else {
  65. $to = $this->to;
  66. }
  67. $boundary = '----=_NextPart_' . md5(time());
  68. $header = '';
  69. $header .= 'MIME-Version: 1.0' . $this->newline;
  70. if ($this->protocol != 'mail') {
  71. $header .= 'To: ' . $to . $this->newline;
  72. $header .= 'Subject: ' . '=?UTF-8?B?' . base64_encode($this->subject) . '?=' . $this->newline;
  73. }
  74. $header .= 'Date: ' . date('D, d M Y H:i:s O') . $this->newline;
  75. $header .= 'From: ' . '=?UTF-8?B?' . base64_encode($this->sender) . '?=' . '<' . $this->from . '>' . $this->newline;
  76. $header .= 'Reply-To: ' . '=?UTF-8?B?' . base64_encode($this->sender) . '?=' . '<' . $this->from . '>' . $this->newline;
  77. $header .= 'Return-Path: ' . $this->from . $this->newline;
  78. $header .= 'X-Mailer: PHP/' . phpversion() . $this->newline;
  79. $header .= 'Content-Type: multipart/related; boundary="' . $boundary . '"' . $this->newline . $this->newline;
  80. if (!$this->html) {
  81. $message = '--' . $boundary . $this->newline;
  82. $message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
  83. $message .= 'Content-Transfer-Encoding: 8bit' . $this->newline;
  84. $message .= $this->text . $this->newline;
  85. } else {
  86. $message = '--' . $boundary . $this->newline;
  87. $message .= 'Content-Type: multipart/alternative; boundary="' . $boundary . '_alt"' . $this->newline . $this->newline;
  88. $message .= '--' . $boundary . '_alt' . $this->newline;
  89. $message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
  90. $message .= 'Content-Transfer-Encoding: 8bit' . $this->newline;
  91. if ($this->text) {
  92. $message .= $this->text . $this->newline;
  93. } else {
  94. $message .= 'This is a HTML email and your email client software does not support HTML email!' . $this->newline;
  95. }
  96. $message .= '--' . $boundary . '_alt' . $this->newline;
  97. $message .= 'Content-Type: text/html; charset="utf-8"' . $this->newline;
  98. $message .= 'Content-Transfer-Encoding: 8bit' . $this->newline;
  99. $message .= $this->html . $this->newline;
  100. $message .= '--' . $boundary . '_alt--' . $this->newline;
  101. }
  102. foreach ($this->attachments as $attachment) {
  103. if (file_exists($attachment)) {
  104. $handle = fopen($attachment, 'r');
  105. $content = fread($handle, filesize($attachment));
  106. fclose($handle);
  107. $message .= '--' . $boundary . $this->newline;
  108. $message .= 'Content-Type: application/octet-stream; name="' . basename($attachment) . '"' . $this->newline;
  109. $message .= 'Content-Transfer-Encoding: base64' . $this->newline;
  110. $message .= 'Content-Disposition: attachment; filename="' . basename($attachment) . '"' . $this->newline;
  111. $message .= 'Content-ID: <' . basename(urlencode($attachment)) . '>' . $this->newline;
  112. $message .= 'X-Attachment-Id: ' . basename(urlencode($attachment)) . $this->newline . $this->newline;
  113. $message .= chunk_split(base64_encode($content));
  114. }
  115. }
  116. $message .= '--' . $boundary . '--' . $this->newline;
  117. if ($this->protocol == 'mail') {
  118. ini_set('sendmail_from', $this->from);
  119. if ($this->parameter) {
  120. mail($to, '=?UTF-8?B?' . base64_encode($this->subject) . '?=', $message, $header, $this->parameter);
  121. } else {
  122. mail($to, '=?UTF-8?B?' . base64_encode($this->subject) . '?=', $message, $header);
  123. }
  124. } elseif ($this->protocol == 'smtp') {
  125. $handle = fsockopen($this->hostname, $this->port, $errno, $errstr, $this->timeout);
  126. if (!$handle) {
  127. trigger_error('Error: ' . $errstr . ' (' . $errno . ')');
  128. exit();
  129. } else {
  130. if (substr(PHP_OS, 0, 3) != 'WIN') {
  131. socket_set_timeout($handle, $this->timeout, 0);
  132. }
  133. while ($line = fgets($handle, 515)) {
  134. if (substr($line, 3, 1) == ' ') {
  135. break;
  136. }
  137. }
  138. if (substr($this->hostname, 0, 3) == 'tls') {
  139. fputs($handle, 'STARTTLS' . $this->crlf);
  140. while ($line = fgets($handle, 515)) {
  141. $reply .= $line;
  142. if (substr($line, 3, 1) == ' ') {
  143. break;
  144. }
  145. }
  146. if (substr($reply, 0, 3) != 220) {
  147. trigger_error('Error: STARTTLS not accepted from server!');
  148. exit();
  149. }
  150. }
  151. if (!empty($this->username) && !empty($this->password)) {
  152. fputs($handle, 'EHLO ' . getenv('SERVER_NAME') . $this->crlf);
  153. $reply = '';
  154. while ($line = fgets($handle, 515)) {
  155. $reply .= $line;
  156. if (substr($line, 3, 1) == ' ') {
  157. break;
  158. }
  159. }
  160. if (substr($reply, 0, 3) != 250) {
  161. trigger_error('Error: EHLO not accepted from server!');
  162. exit();
  163. }
  164. fputs($handle, 'AUTH LOGIN' . $this->crlf);
  165. $reply = '';
  166. while ($line = fgets($handle, 515)) {
  167. $reply .= $line;
  168. if (substr($line, 3, 1) == ' ') {
  169. break;
  170. }
  171. }
  172. if (substr($reply, 0, 3) != 334) {
  173. trigger_error('Error: AUTH LOGIN not accepted from server!');
  174. exit();
  175. }
  176. fputs($handle, base64_encode($this->username) . $this->crlf);
  177. $reply = '';
  178. while ($line = fgets($handle, 515)) {
  179. $reply .= $line;
  180. if (substr($line, 3, 1) == ' ') {
  181. break;
  182. }
  183. }
  184. if (substr($reply, 0, 3) != 334) {
  185. trigger_error('Error: Username not accepted from server!');
  186. exit();
  187. }
  188. fputs($handle, base64_encode($this->password) . $this->crlf);
  189. $reply = '';
  190. while ($line = fgets($handle, 515)) {
  191. $reply .= $line;
  192. if (substr($line, 3, 1) == ' ') {
  193. break;
  194. }
  195. }
  196. if (substr($reply, 0, 3) != 235) {
  197. trigger_error('Error: Password not accepted from server!');
  198. exit();
  199. }
  200. } else {
  201. fputs($handle, 'HELO ' . getenv('SERVER_NAME') . $this->crlf);
  202. $reply = '';
  203. while ($line = fgets($handle, 515)) {
  204. $reply .= $line;
  205. if (substr($line, 3, 1) == ' ') {
  206. break;
  207. }
  208. }
  209. if (substr($reply, 0, 3) != 250) {
  210. trigger_error('Error: HELO not accepted from server!');
  211. exit();
  212. }
  213. }
  214. if ($this->verp) {
  215. fputs($handle, 'MAIL FROM: <' . $this->from . '>XVERP' . $this->crlf);
  216. } else {
  217. fputs($handle, 'MAIL FROM: <' . $this->from . '>' . $this->crlf);
  218. }
  219. $reply = '';
  220. while ($line = fgets($handle, 515)) {
  221. $reply .= $line;
  222. if (substr($line, 3, 1) == ' ') {
  223. break;
  224. }
  225. }
  226. if (substr($reply, 0, 3) != 250) {
  227. trigger_error('Error: MAIL FROM not accepted from server!');
  228. exit();
  229. }
  230. if (!is_array($this->to)) {
  231. fputs($handle, 'RCPT TO: <' . $this->to . '>' . $this->crlf);
  232. $reply = '';
  233. while ($line = fgets($handle, 515)) {
  234. $reply .= $line;
  235. if (substr($line, 3, 1) == ' ') {
  236. break;
  237. }
  238. }
  239. if ((substr($reply, 0, 3) != 250) && (substr($reply, 0, 3) != 251)) {
  240. trigger_error('Error: RCPT TO not accepted from server!');
  241. exit();
  242. }
  243. } else {
  244. foreach ($this->to as $recipient) {
  245. fputs($handle, 'RCPT TO: <' . $recipient . '>' . $this->crlf);
  246. $reply = '';
  247. while ($line = fgets($handle, 515)) {
  248. $reply .= $line;
  249. if (substr($line, 3, 1) == ' ') {
  250. break;
  251. }
  252. }
  253. if ((substr($reply, 0, 3) != 250) && (substr($reply, 0, 3) != 251)) {
  254. trigger_error('Error: RCPT TO not accepted from server!');
  255. exit();
  256. }
  257. }
  258. }
  259. fputs($handle, 'DATA' . $this->crlf);
  260. $reply = '';
  261. while ($line = fgets($handle, 515)) {
  262. $reply .= $line;
  263. if (substr($line, 3, 1) == ' ') {
  264. break;
  265. }
  266. }
  267. if (substr($reply, 0, 3) != 354) {
  268. trigger_error('Error: DATA not accepted from server!');
  269. exit();
  270. }
  271. // According to rfc 821 we should not send more than 1000 including the CRLF
  272. $message = str_replace("\r\n", "\n", $header . $message);
  273. $message = str_replace("\r", "\n", $message);
  274. $lines = explode("\n", $message);
  275. foreach ($lines as $line) {
  276. $results = str_split($line, 998);
  277. foreach ($results as $result) {
  278. if (substr(PHP_OS, 0, 3) != 'WIN') {
  279. fputs($handle, $result . $this->crlf);
  280. } else {
  281. fputs($handle, str_replace("\n", "\r\n", $result) . $this->crlf);
  282. }
  283. }
  284. }
  285. fputs($handle, '.' . $this->crlf);
  286. $reply = '';
  287. while ($line = fgets($handle, 515)) {
  288. $reply .= $line;
  289. if (substr($line, 3, 1) == ' ') {
  290. break;
  291. }
  292. }
  293. if (substr($reply, 0, 3) != 250) {
  294. trigger_error('Error: DATA not accepted from server!');
  295. exit();
  296. }
  297. fputs($handle, 'QUIT' . $this->crlf);
  298. $reply = '';
  299. while ($line = fgets($handle, 515)) {
  300. $reply .= $line;
  301. if (substr($line, 3, 1) == ' ') {
  302. break;
  303. }
  304. }
  305. if (substr($reply, 0, 3) != 221) {
  306. trigger_error('Error: QUIT not accepted from server!');
  307. exit();
  308. }
  309. fclose($handle);
  310. }
  311. }
  312. }
  313. }
  314. ?>