PageRenderTime 29ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/QFW/lib/Email.php

https://github.com/ivan1986/quickfw
PHP | 320 lines | 182 code | 41 blank | 97 comment | 10 complexity | 193b73a1b3c27ce7ee65ae10a471331d MD5 | raw file
  1. <?php
  2. /**
  3. * Отправка Email c аттачами и в html формате
  4. *
  5. * @author ivan1986
  6. */
  7. class Email
  8. {
  9. /** @var string Поле от кого */
  10. private $from = '';
  11. /** @var string Поле скрытая копия */
  12. private $cc = '';
  13. /** @var string Поле Replay */
  14. private $replay = '';
  15. /** @var string Тема письма */
  16. private $subject = '';
  17. /** @var string Простой текст */
  18. private $plain = '';
  19. /** @var string Html текст */
  20. private $html = '';
  21. /** @var array[string]mixed Прикрепленные файлы */
  22. private $files = array();
  23. /** @var string Сообщение (заполняется функцией build) */
  24. private $message = '';
  25. /** @var string Заголовки (заполняется функцией build) */
  26. private $headers = '';
  27. /**
  28. * Устанавливает поле From
  29. *
  30. * @param string $email e-mail
  31. * @param string $name Имя в utf8, которое будет закодировано в base64 или пусто
  32. * @return Email Указатель на себя
  33. */
  34. public function setFrom($email, $name='')
  35. {
  36. $this->message = $this->headers = '';
  37. $this->from = empty($name) ? $email : mb_encode_mimeheader($name, 'utf-8').' <'.$email.'>';
  38. return $this;
  39. }
  40. /**
  41. * Устанавливает поле Cc
  42. *
  43. * @param string $email e-mail
  44. * @param string $name Имя в utf8, которое будет закодировано в base64 или пусто
  45. * @return Email Указатель на себя
  46. */
  47. public function setCc($email, $name='')
  48. {
  49. $this->message = $this->headers = '';
  50. $this->cc = empty($name) ? $email : mb_encode_mimeheader($name, 'utf-8').' <'.$email.'>';
  51. return $this;
  52. }
  53. /**
  54. * Устанавливает поле Subject
  55. *
  56. * @param string $subject Тема письма в utf8
  57. * @return Email Указатель на себя
  58. */
  59. public function setSubject($subject)
  60. {
  61. $this->message = $this->headers = '';
  62. $this->subject = mb_encode_mimeheader($subject, 'utf-8');
  63. return $this;
  64. }
  65. /**
  66. * Устанавливает поле Replay To
  67. *
  68. * @param string $email e-mail
  69. * @param string $name Имя в utf8, которое будет закодировано в base64 или пусто
  70. * @return Email Указатель на себя
  71. */
  72. public function setReplay($email, $name='')
  73. {
  74. $this->message = $this->headers = '';
  75. $this->replay = empty($name) ? $email : mb_encode_mimeheader($name, 'utf-8').' <'.$email.'>';
  76. return $this;
  77. }
  78. /**
  79. * Устанавливает Текст письма в формате html
  80. *
  81. * @param string $html Верстка письма в utf8
  82. * @return Email Указатель на себя
  83. */
  84. public function setHtml($html)
  85. {
  86. $this->message = $this->headers = '';
  87. $this->html = $html;
  88. return $this;
  89. }
  90. /**
  91. * Устанавливает Текст письма в plain text формате
  92. *
  93. * @param string $plain Простой текст письма в utf8
  94. * @return Email Указатель на себя
  95. */
  96. public function setPlain($plain)
  97. {
  98. $this->message = $this->headers = '';
  99. $this->plain = $plain;
  100. return $this;
  101. }
  102. /**
  103. * Добавляет файл к письму с указанным идентификатором
  104. *
  105. * @param string $name Идентификатор файла
  106. * @param mixed $data Содержимое файла
  107. * @param string $type mime-type содержимого
  108. * @return Email Указатель на себя
  109. */
  110. public function addFile($name, $data, $type)
  111. {
  112. $this->message = $this->headers = '';
  113. $this->files[$name] = array(
  114. 'data' => $data,
  115. 'type' => $type,
  116. );
  117. return $this;
  118. }
  119. /**
  120. * Отправка письма на указанный адрес или список адресов
  121. *
  122. * @param string|array[]string|array[string]string $to Адреса получателей<br>
  123. * Строка - email | Хеш (Ключ - email, значение - имя) или
  124. * (ключ - число, значение email) | Массив хешей
  125. * @param boolean $join Одно письмо с множеством адресов в to
  126. * @return Email Указатель на себя
  127. */
  128. public function send($to, $join = false)
  129. {
  130. $this->build();
  131. if(!is_array($to))
  132. $to = array($to);
  133. foreach($to as $k=>$v)
  134. if (!is_int($k))
  135. $to[$k] = mb_encode_mimeheader($v, 'utf-8').' <'.$k.'>';
  136. $to = array_values($to);
  137. if ($join)
  138. {
  139. $to = join($to, ', ');
  140. mail($to, $this->subject, $this->message, $this->headers);
  141. }
  142. else
  143. foreach($to as $mail)
  144. mail($mail, $this->subject, $this->message, $this->headers);
  145. return $this;
  146. }
  147. /**
  148. * Возвращает массив из raw данных, которые подставляются в mail
  149. *
  150. * @return array Хеш subject, message, headers
  151. */
  152. public function getRaw()
  153. {
  154. $this->build();
  155. return array(
  156. 'subject' => $this->subject,
  157. 'message' => $this->message,
  158. 'headers' => $this->headers,
  159. );
  160. }
  161. /**
  162. * Переформирует сообщение, если оно изменилось
  163. */
  164. private function build()
  165. {
  166. if (!empty($this->message))
  167. return;
  168. //Сообщение изменилось - переформируем
  169. $headers = '';
  170. if ($this->from) $headers.='From: '.$this->from."\r\n";
  171. if ($this->cc) $headers.='Cc: '.$this->cc."\r\n";
  172. if ($this->replay) $headers.='Reply-To: '.$this->replay."\r\n";
  173. $headers.='Date: '.date('r')."\r\n";
  174. $headers.="X-Mailer: php script\r\n";
  175. $headers.="MIME-Version: 1.0\r\n";
  176. $this->headers = $headers;
  177. if (!empty($this->html))
  178. $this->prepareHtml();
  179. elseif(!empty($this->files))
  180. $this->prepareWithAttache();
  181. else
  182. $this->prepare();
  183. }
  184. /**
  185. * Собирает сообщение в html формате
  186. *
  187. * @uses headers
  188. * @uses message
  189. */
  190. private function prepareHtml()
  191. {
  192. $baseboundary = "------------".strtoupper(md5(uniqid('base')));
  193. $newboundary = "------------".strtoupper(md5(uniqid('new')));
  194. $headers = '';
  195. $message = '';
  196. $headers.="Content-Type: multipart/alternative;\r\n";
  197. $headers.=" boundary=\"".$baseboundary."\"\r\n";
  198. $headers.="This is a multi-part message in MIME format.\r\n";
  199. $message.="--".$baseboundary."\r\n";
  200. $message.="Content-Type: text/plain; charset=utf-8\r\n";
  201. $message.="Content-Transfer-Encoding: 8bit\r\n\r\n";
  202. $message.=$this->plain."\r\n\r\n";
  203. $message.="--".$baseboundary."\r\n";
  204. $message.="Content-Type: multipart/related;\r\n";
  205. $message.=" boundary=\"$newboundary\"\r\n\r\n\r\n";
  206. $message.="--$newboundary\r\n";
  207. $message.="Content-Type: text/html; charset=utf-8\r\n";
  208. $message.="Content-Transfer-Encoding: 8bit\r\n\r\n";
  209. $message.=$this->html."\r\n\r\n";
  210. if (count($this->files))
  211. foreach($this->files as $name => $file)
  212. {
  213. $message.="--".$newboundary."\r\n";
  214. $message.="Content-Type: ".$file['type'].";\r\n";
  215. $message.=" name=\"".$name."\"\r\n";
  216. $message.="Content-Transfer-Encoding: base64\r\n";
  217. $message.="Content-ID: <".$name.">\r\n";
  218. $message.="Content-Disposition: inline;\r\n";
  219. $message.=" filename=\"".$name."\"\r\n\r\n";
  220. $message.=chunk_split(base64_encode($file['data']));
  221. }
  222. $message.="--".$newboundary."--\r\n\r\n";
  223. $message.="--".$baseboundary."--\r\n";
  224. $this->headers.= $headers;
  225. $this->message = $message;
  226. }
  227. /**
  228. * Собирает сообщение в текстовом формате с аттачами
  229. *
  230. * @uses headers
  231. * @uses message
  232. */
  233. private function prepareWithAttache()
  234. {
  235. $boundary = "------------".strtoupper(md5(uniqid('file')));
  236. $headers = '';
  237. $message = '';
  238. $headers.="Content-Type: multipart/mixed;\r\n";
  239. $headers.=" boundary=\"".$boundary."\"\r\n";
  240. $headers.="This is a multi-part message in MIME format.\r\n";
  241. $message.="--".$boundary."\r\n";
  242. $message.="Content-Type: text/plain; charset=utf-8\r\n";
  243. $message.="Content-Transfer-Encoding: 8bit\r\n\r\n";
  244. $message.=$this->plain."\r\n\r\n";
  245. $message.="--".$boundary."\r\n";
  246. if (count($this->files))
  247. foreach($this->files as $name => $file)
  248. {
  249. $message.="--".$boundary."\r\n";
  250. $message.="Content-Type: ".$file['type'].";\r\n";
  251. $message.=" name=\"".$name."\"\r\n";
  252. $message.="Content-Transfer-Encoding: base64\r\n";
  253. $message.="Content-ID: <".$name.">\r\n";
  254. $message.="Content-Disposition: inline;\r\n";
  255. $message.=" filename=\"".$name."\"\r\n\r\n";
  256. $message.=chunk_split(base64_encode($file['data']));
  257. }
  258. $message.="--".$boundary."--\r\n\r\n";
  259. $this->headers.= $headers;
  260. $this->message = $message;
  261. }
  262. /**
  263. * Собирает сообщение в текстовом формате
  264. *
  265. * @uses headers
  266. * @uses message
  267. */
  268. private function prepare()
  269. {
  270. $headers = '';
  271. $message = '';
  272. $headers.="Content-Type: text/plain; charset=utf-8\r\n";
  273. $headers.="Content-Transfer-Encoding: 8bit\r\n\r\n";
  274. $message.=$this->plain."\r\n\r\n";
  275. $this->headers.= $headers;
  276. $this->message = $message;
  277. }
  278. }
  279. ?>