Mail.Class.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <?php
  2. namespace Mall\Framework\Mail;
  3. class Mail
  4. {
  5. const PHP_QPRINT_MAXL=75;
  6. public $mailer,
  7. $delimiter,
  8. $charset,
  9. $from,
  10. $sign,
  11. $smtp_host,
  12. $smtp_port,
  13. $smtp_auth,
  14. $smtp_username,
  15. $smtp_password;
  16. protected $errno;
  17. protected $error;
  18. function __construct($mailer = 1, $delimiter = 1, $charset = 'utf-8', $from = null, $sign = null, $smtp_host = null, $smtp_port = 25, $smtp_auth = true, $smtp_username = null, $smtp_password = null)
  19. {
  20. $this->mailer = $mailer;
  21. $this->delimiter = $delimiter == 1 ? "\r\n" : ($delimiter == 2 ? "\r" : "\n");
  22. $this->charset = $charset;
  23. $this->from = $from;
  24. $this->sign = $sign;
  25. $this->smtp_host = $smtp_host;
  26. $this->smtp_port = $smtp_port ? $smtp_port : 25;
  27. $this->smtp_auth = $smtp_auth;
  28. $this->smtp_username = $smtp_username;
  29. $this->smtp_password = $smtp_password;
  30. }
  31. function execute($to, $subject, $message, $from = null)
  32. {
  33. $subject = '=?'.$this->charset.'?B?'.base64_encode(str_replace("\r", '', str_replace("\n", '', $subject))).'?=';
  34. $message .= $this->sign;
  35. $message = str_replace("\r\n.", " \r\n..", str_replace("\n", "\r\n", str_replace("\r", "\n", str_replace("\r\n", "\n", str_replace("\n\r", "\r", $message)))));
  36. $message = $this->leading_dot_fixed_php_quot_print_encode($message);
  37. $from = is_null($from) ? '=?'.$this->charset.'?B?'.base64_encode('MailGuang')."?= <$this->from>" : (preg_match('/^(.+?) \<(.+?)\>$/', $from, $m) ? '=?'.$this->charset.'?B?'.base64_encode($m[1])."?= <$m[2]>" : $from);
  38. if (strpos($to, ','))
  39. {
  40. foreach(explode(',', $to) as $touser)
  41. {
  42. $tousers[] = preg_match('/^(.+?) \<(.+?)\>$/', $touser, $m) ? '=?'.$this->charset.'?B?'.base64_encode($m[1])."?= <$m[2]>" : $touser;
  43. }
  44. $to = implode(',', $tousers);
  45. }
  46. $headers = "From: $from{$this->delimiter}X-Priority: 3{$this->delimiter}X-Mailer: MailGuang mcloud{$this->delimiter}MIME-Version: 1.0{$this->delimiter}Content-type: text/html; charset=$this->charset{$this->delimiter}";
  47. $headers .= "Content-Transfer-Encoding: quoted-printable{$this->delimiter}";
  48. if ($this->mailer == 1)
  49. {
  50. return mail($to, $subject, $message, $headers);
  51. }
  52. elseif ($this->mailer == 2)
  53. {
  54. return $this->smtp($to, $subject, $message, $headers, $from);
  55. }
  56. else
  57. {
  58. return $this->mail($to, $subject, $message, $headers, $from);
  59. }
  60. }
  61. function leading_dot_fixed_php_quot_print_encode($str)
  62. {
  63. $lp = 0;
  64. $ret = '';
  65. $hex = "0123456789ABCDEF";
  66. $length = strlen($str);
  67. $str_index = 0;
  68. while ($length--) {
  69. if ((($c = $str[$str_index++]) == "\015") && ($str[$str_index] == "\012") && $length > 0) {
  70. $ret .= "\015";
  71. $ret .= $str[$str_index++];
  72. $length--;
  73. $lp = 0;
  74. } else {
  75. if (ctype_cntrl($c)
  76. || (ord($c) == 0x7f)
  77. || (ord($c) & 0x80)
  78. || ($c == '=')
  79. || (($c == ' ') && ($str[$str_index] == "\015")))
  80. {
  81. if (($lp += 3) > self::PHP_QPRINT_MAXL)
  82. {
  83. $ret .= '=';
  84. $ret .= "\015";
  85. $ret .= "\012";
  86. $lp = 3;
  87. }
  88. $ret .= '=';
  89. $ret .= $hex[ord($c) >> 4];
  90. $ret .= $hex[ord($c) & 0xf];
  91. }
  92. else
  93. {
  94. if ((++$lp) > self::PHP_QPRINT_MAXL)
  95. {
  96. $ret .= '=';
  97. $ret .= "\015";
  98. $ret .= "\012";
  99. $lp = 1;
  100. }
  101. $ret .= $c;
  102. if($lp == 1 && $c == '.') {
  103. $ret .= '.';
  104. $lp++;
  105. }
  106. }
  107. }
  108. }
  109. return $ret;
  110. }
  111. function mail($to, $subject, $message, $headers, $from)
  112. {
  113. ini_set('SMTP', $this->smtp_host);
  114. ini_set('smtp_port', $this->smtp_port);
  115. ini_set('sendmail_from', $from);
  116. return mail($to, $subject, $message, $headers);
  117. }
  118. function smtp($to, $subject, $message, $headers, $from)
  119. {
  120. if(!$fp = fsockopen($this->smtp_host, $this->smtp_port, $errno, $errstr, 30))
  121. {
  122. $this->errno = $errno;
  123. $this->error = $errstr;
  124. return false;
  125. }
  126. stream_set_blocking($fp, true);
  127. $lastmessage = fgets($fp, 512);
  128. if(substr($lastmessage, 0, 3) != '220')
  129. {
  130. $this->errno = substr($lastmessage, 0, 3);
  131. $this->error = $lastmessage;
  132. return false;
  133. }
  134. fputs($fp, ($this->smtp_auth ? 'EHLO' : 'HELO')." MailGuang\r\n");
  135. $lastmessage = fgets($fp, 512);
  136. if(substr($lastmessage, 0, 3) != 220 && substr($lastmessage, 0, 3) != 250)
  137. {
  138. $this->errno = substr($lastmessage, 0, 3);
  139. $this->error = $lastmessage;
  140. return false;
  141. }
  142. while(1)
  143. {
  144. if((substr($lastmessage,0, 3) != 220 && substr($lastmessage, 3, 1) != '-') || empty($lastmessage)) break;
  145. $lastmessage = fgets($fp, 512);
  146. }
  147. if($this->smtp_auth)
  148. {
  149. fputs($fp, "AUTH LOGIN\r\n");
  150. $lastmessage = fgets($fp, 512);
  151. if(substr($lastmessage, 0, 3) != 334)
  152. {
  153. $this->errno = substr($lastmessage, 0, 3);
  154. $this->error = $lastmessage;
  155. return false;
  156. }
  157. fputs($fp, base64_encode($this->smtp_username)."\r\n");
  158. $lastmessage = fgets($fp, 512);
  159. if(substr($lastmessage, 0, 3) != 334)
  160. {
  161. $this->errno = substr($lastmessage, 0, 3);
  162. $this->error = $lastmessage;
  163. return false;
  164. }
  165. fputs($fp, base64_encode($this->smtp_password)."\r\n");
  166. $lastmessage = fgets($fp, 512);
  167. if(substr($lastmessage, 0, 3) != 235)
  168. {
  169. $this->errno = substr($lastmessage, 0, 3);
  170. $this->error = $lastmessage;
  171. return false;
  172. }
  173. }
  174. fputs($fp, "MAIL FROM: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $from).">\r\n");
  175. $lastmessage = fgets($fp, 512);
  176. if(substr($lastmessage, 0, 3) != 250)
  177. {
  178. fputs($fp, "MAIL FROM: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $from).">\r\n");
  179. $lastmessage = fgets($fp, 512);
  180. if(substr($lastmessage, 0, 3) != 250)
  181. {
  182. $this->errno = substr($lastmessage, 0, 3);
  183. $this->error = $lastmessage;
  184. return false;
  185. }
  186. }
  187. $email_tos = array();
  188. foreach(explode(',', $to) as $touser)
  189. {
  190. $touser = trim($touser);
  191. if($touser)
  192. {
  193. fputs($fp, "RCPT TO: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $touser).">\r\n");
  194. $lastmessage = fgets($fp, 512);
  195. if(substr($lastmessage, 0, 3) != 250)
  196. {
  197. fputs($fp, "RCPT TO: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $touser).">\r\n");
  198. $lastmessage = fgets($fp, 512);
  199. $this->errno = substr($lastmessage, 0, 3);
  200. $this->error = $lastmessage;
  201. return false;
  202. }
  203. }
  204. }
  205. fputs($fp, "DATA\r\n");
  206. $lastmessage = fgets($fp, 512);
  207. if(substr($lastmessage, 0, 3) != 354)
  208. {
  209. $this->errno = substr($lastmessage, 0, 3);
  210. $this->error = $lastmessage;
  211. return false;
  212. }
  213. if (isset($_SERVER['HTTP_HOST'])) {
  214. $host = $_SERVER['HTTP_HOST'];
  215. } else if (isset($_SERVER['HOSTNAME'])) {
  216. $host = $_SERVER['HOSTNAME'];
  217. } else {
  218. $host = '';
  219. }
  220. $headers .= 'Message-ID: <'.gmdate('YmdHs').'.'.substr(md5($message.microtime()), 0, 6).rand(100000, 999999).'@'.$host.">{$this->delimiter}";
  221. fputs($fp, "Date: ".gmdate('r')."\r\n");
  222. fputs($fp, "To: ".$to."\r\n");
  223. fputs($fp, "Subject: ".$subject."\r\n");
  224. fputs($fp, $headers."\r\n");
  225. fputs($fp, "\r\n\r\n");
  226. fputs($fp, "$message\r\n.\r\n");
  227. $lastmessage = fgets($fp, 512);
  228. if(substr($lastmessage, 0, 3) != 250)
  229. {
  230. $this->errno = substr($lastmessage, 0, 3);
  231. $this->error = $lastmessage;
  232. return false;
  233. }
  234. fputs($fp, "QUIT\r\n");
  235. return true;
  236. }
  237. function error()
  238. {
  239. return $this->error;
  240. }
  241. function errno()
  242. {
  243. return $this->errno;
  244. }
  245. }