PageRenderTime 26ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/core/classes/Emailer.php

https://github.com/nopticon/hyd
PHP | 354 lines | 224 code | 74 blank | 56 comment | 37 complexity | 671b28b99682fb877a21e5d10803d9d5 MD5 | raw file
Possible License(s): MIT
  1. <?php namespace App;
  2. use Mailgun\Mailgun;
  3. class emailer {
  4. public $msg;
  5. public $subject;
  6. public $extra_headers;
  7. public $addresses;
  8. public $reply_to;
  9. public $from;
  10. public $tpl_msg = array();
  11. public function __construct() {
  12. $this->reset();
  13. $this->reply_to = $this->from = '';
  14. }
  15. // Resets all the data (address, template file, etc etc to default
  16. public function reset() {
  17. $this->addresses = w();
  18. $this->vars = $this->msg = $this->extra_headers = '';
  19. }
  20. // Sets an email address to send to
  21. public function email_address($address) {
  22. if (strpos($address, '@') === false) {
  23. $format = '%s <%s@%s>';
  24. $address = sprintf($format, config('sitename'), $address, array_key(explode('@', config('board_email')), 1));
  25. }
  26. $this->addresses['to'] = trim($address);
  27. }
  28. public function cc($address) {
  29. if (strpos($address, '@') === false) {
  30. $format = '%s <%s@%s>';
  31. $address = sprintf($format, config('sitename'), $address, array_key(explode('@', config('board_email')), 1));
  32. }
  33. $this->addresses['cc'][] = trim($address);
  34. }
  35. public function bcc($address) {
  36. if (strpos($address, '@') === false) {
  37. $format = '%s <%s@%s>';
  38. $address = sprintf($format, config('sitename'), $address, array_key(explode('@', config('board_email')), 1));
  39. }
  40. $this->addresses['bcc'][] = trim($address);
  41. }
  42. public function replyto($address) {
  43. if (strpos($address, '@') === false) {
  44. $address = $address . '@' . array_key(explode('@', config('board_email')), 1);
  45. }
  46. $this->reply_to = trim($address);
  47. }
  48. public function from($address) {
  49. if (strpos($address, '@') === false) {
  50. $format = '%s <%s@%s>';
  51. $address = sprintf($format, config('sitename'), $address, array_key(explode('@', config('board_email')), 1));
  52. }
  53. $this->from = trim($address);
  54. }
  55. // set up subject for mail
  56. public function set_subject($subject = '') {
  57. $this->subject = trim(preg_replace('#[\n\r]+#s', '', $subject));
  58. }
  59. // set up extra mail headers
  60. public function extra_headers($headers) {
  61. $this->extra_headers .= trim($headers) . nr();
  62. }
  63. public function use_template($template_file, $template_lang = '') {
  64. if (trim($template_file) == '') {
  65. trigger_error('No template file set');
  66. }
  67. if (trim($template_lang) == '') {
  68. $template_lang = config('default_lang');
  69. }
  70. if (empty($this->tpl_msg[$template_lang . $template_file])) {
  71. $tpl_file = ROOT.'language/' . $template_lang . '/email/' . $template_file . '.tpl';
  72. if (!@file_exists(@realpath($tpl_file))) {
  73. $tpl_file = ROOT.'language/' . config('default_lang') . '/email/' . $template_file . '.tpl';
  74. if (!@file_exists(@realpath($tpl_file))) {
  75. trigger_error('Could not find email template file :: ' . $template_file);
  76. }
  77. }
  78. if (!($fd = @fopen($tpl_file, 'r'))) {
  79. trigger_error('Failed opening template file :: ' . $tpl_file);
  80. }
  81. $this->tpl_msg[$template_lang . $template_file] = fread($fd, filesize($tpl_file));
  82. fclose($fd);
  83. }
  84. $this->msg = $this->tpl_msg[$template_lang . $template_file];
  85. return true;
  86. }
  87. // assign variables
  88. public function assign_vars($vars) {
  89. $this->vars = empty($this->vars) ? $vars : $this->vars . $vars;
  90. }
  91. // Send the mail out to the recipients set previously in var $this->address
  92. public function send() {
  93. global $user;
  94. // Escape all quotes, else the eval will fail.
  95. $this->msg = str_replace("'", "\'", $this->msg);
  96. $this->msg = preg_replace('#\{([a-z0-9\-_]*?)\}#is', "' . $\\1 . '", $this->msg);
  97. foreach ($this->vars as $key => $val) {
  98. $$key = $val;
  99. }
  100. eval("\$this->msg = '$this->msg';");
  101. // Clear vars
  102. foreach ($this->vars as $key => $val) {
  103. unset($$key);
  104. }
  105. // We now try and pull a subject from the email body ... if it exists,
  106. // do this here because the subject may contain a variable
  107. $drop_header = '';
  108. $match = w();
  109. if (preg_match('#^(Subject:(.*?))$#m', $this->msg, $match)) {
  110. $this->subject = trim($match[2]) ? trim($match[2]) : ($this->subject ? $this->subject : 'No Subject');
  111. $drop_header .= '[\r\n]*?' . preg_quote($match[1], '#');
  112. } else {
  113. $this->subject = (($this->subject != '') ? $this->subject : 'No Subject');
  114. }
  115. if (preg_match('#^(Charset:(.*?))$#m', $this->msg, $match)) {
  116. $this->encoding = (trim($match[2]) != '') ? trim($match[2]) : trim($lang['ENCODING']);
  117. $drop_header .= '[\r\n]*?' . preg_quote($match[1], '#');
  118. } else {
  119. $this->encoding = lang('encoding');
  120. }
  121. if ($drop_header != '') {
  122. $this->msg = trim(preg_replace('#' . $drop_header . '#s', '', $this->msg));
  123. }
  124. $to = $this->addresses['to'];
  125. $cc = isset($this->addresses['cc']) ? implode(', ', $this->addresses['cc']) : '';
  126. $bcc = isset($this->addresses['bcc']) ? implode(', ', $this->addresses['bcc']) : '';
  127. if (empty($this->from)) {
  128. $this->from('info');
  129. }
  130. // Build header
  131. // $extra_headers = array(
  132. // 'Reply-to' => $this->reply_to,
  133. // 'From' => $this->from,
  134. // 'Return-Path' => config('board_email'),
  135. // 'Message-ID' => '<' . md5(uniqid(time())) . '@rockrepublik.net>',
  136. // 'MIME-Version' => '1.0',
  137. // 'Content-type' => 'text/plain; charset=' . $this->encoding,
  138. // 'Content-transfer-encoding' => '8bit',
  139. // 'Date' => date('r', time()),
  140. // 'X-Priority' => '3',
  141. // 'X-MSMail-Priority' => 'Normal',
  142. // 'Cc' => $cc,
  143. // 'Bcc' => $bcc
  144. // );
  145. //
  146. // $extra_headers = array_filter($extra_headers);
  147. // $this->extra_headers = implode("\n", $extra_headers) . "\n\n" . $this->extra_headers;
  148. // Send message ... removed $this->encode() from subject for time being
  149. // $empty_to_header = ($to == '') ? true : false;
  150. $to = ($to == '') ? (config('sendmail_fix') ? ' ' : 'Undisclosed-recipients:;') : $to;
  151. $this->subject = entity_decode($this->subject);
  152. $this->msg = entity_decode($this->msg);
  153. $message = preg_replace("#(?<!\r)\n#s", "\n", $this->msg);
  154. // $result = @mail($to, $this->subject, $message, $this->extra_headers, "-f" . config('board_email'));
  155. $send_info = array(
  156. 'from' => $this->from,
  157. 'to' => $to,
  158. 'subject' => $this->subject,
  159. 'text' => $message
  160. );
  161. if ($cc) {
  162. $send_info['cc'] = $cc;
  163. }
  164. if ($bcc) {
  165. $send_info['bcc'] = $bcc;
  166. }
  167. $mg = new Mailgun(config('mailgun_key'));
  168. $domain = config('mailgun_domain');
  169. $result = $mg->sendMessage($domain, $send_info);
  170. // if (!$result && !config('sendmail_fix') && $empty_to_header) {
  171. // $to = ' ';
  172. //
  173. // set_config('sendmail_fix', 1);
  174. //
  175. // $result = @mail($to, $this->subject, $message, $this->extra_headers, "-f" . config('board_email'));
  176. // }
  177. if (!$result) {
  178. return false;
  179. }
  180. return true;
  181. }
  182. // Encodes the given string for proper display for this encoding ... nabbed
  183. // from php.net and modified. There is an alternative encoding method which
  184. // may produce lesd output but it's questionable as to its worth in this
  185. // scenario IMO
  186. public function encode($str) {
  187. if ($this->encoding == '') {
  188. return $str;
  189. }
  190. // define start delimimter, end delimiter and spacer
  191. $end = "?=";
  192. $start = "=?$this->encoding?B?";
  193. $spacer = "$end\r\n $start";
  194. // determine length of encoded text within chunks and ensure length is even
  195. $length = 75 - strlen($start) - strlen($end);
  196. $length = floor($length / 2) * 2;
  197. // encode the string and split it into chunks with spacers after each chunk
  198. $str = chunk_split(base64_encode($str), $length, $spacer);
  199. // remove trailing spacer and add start and end delimiters
  200. $str = preg_replace('#' . preg_quote($spacer, '#') . '$#', '', $str);
  201. return $start . $str . $end;
  202. }
  203. //
  204. // Attach files via MIME.
  205. //
  206. public function attachFile($filename, $szFromAddress, $szFilenameToDisplay, $mimetype = 0) {
  207. global $lang;
  208. if (!$mimetype) {
  209. $mimetype = 'application/octet-stream';
  210. }
  211. $mime_boundary = '--==================_846811060==_';
  212. $format = "--%s\nContent-Type: text/plain;\n\tcharset=\"%s\"\n\n%s";
  213. $this->msg = sprintf($format, $mime_boundary, $lang['ENCODING'], $this->msg);
  214. if ($mime_filename) {
  215. $filename = $mime_filename;
  216. $encoded = $this->encode_file($filename);
  217. }
  218. $fd = fopen($filename, "r");
  219. $contents = fread($fd, filesize($filename));
  220. $this->mimeOut = "--" . $mime_boundary . "\n";
  221. $this->mimeOut .= "Content-Type: " . $mimetype . ";\n\tname=\"$szFilenameToDisplay\"\n";
  222. $this->mimeOut .= "Content-Transfer-Encoding: quoted-printable\n";
  223. $this->mimeOut .= "Content-Disposition: attachment;\n\tfilename=\"$szFilenameToDisplay\"\n\n";
  224. if ($mimetype == 'message/rfc822') {
  225. $this->mimeOut .= "From: ".$szFromAddress."\n";
  226. $this->mimeOut .= "To: ".$this->emailAddress."\n";
  227. $this->mimeOut .= "Date: ".date("D, d M Y H:i:s") . " UT\n";
  228. $this->mimeOut .= "Reply-To:".$szFromAddress."\n";
  229. $this->mimeOut .= "Subject: ".$this->mailSubject."\n";
  230. $this->mimeOut .= "MIME-Version: 1.0\n";
  231. }
  232. $this->mimeOut .= $contents."\n";
  233. $this->mimeOut .= "--" . $mime_boundary . "--" . "\n";
  234. return $out;
  235. // added -- to notify email client attachment is done
  236. }
  237. public function getMimeHeaders($filename, $mime_filename = '') {
  238. $mime_boundary = "--==================_846811060==_";
  239. if ($mime_filename) {
  240. $filename = $mime_filename;
  241. }
  242. $out = "MIME-Version: 1.0\n";
  243. $out .= "Content-Type: multipart/mixed;\n\tboundary=\"$mime_boundary\"\n\n";
  244. $out .= "This message is in MIME format. Since your mail reader does not understand\n";
  245. $out .= "this format, some or all of this message may not be legible.";
  246. return $out;
  247. }
  248. //
  249. // Split string by RFC 2045 semantics (76 chars per line, end with \r\n).
  250. //
  251. public function myChunkSplit($str) {
  252. $stmp = $str;
  253. $len = strlen($stmp);
  254. $out = "";
  255. while ($len > 0) {
  256. if ($len >= 76) {
  257. $out .= substr($stmp, 0, 76) . "\r\n";
  258. $stmp = substr($stmp, 76);
  259. $len = $len - 76;
  260. } else {
  261. $out .= $stmp . "\r\n";
  262. $stmp = "";
  263. $len = 0;
  264. }
  265. }
  266. return $out;
  267. }
  268. //
  269. // Split the specified file up into a string and return it
  270. //
  271. public function encode_file($sourcefile) {
  272. if (is_readable(@realpath($sourcefile))) {
  273. $fd = fopen($sourcefile, 'r');
  274. $contents = fread($fd, filesize($sourcefile));
  275. $encoded = $this->myChunkSplit(base64_encode($contents));
  276. fclose($fd);
  277. }
  278. return $encoded;
  279. }
  280. }