PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/e107_handlers/phpmailer/mailout_process.php

https://github.com/CasperGemini/e107
PHP | 509 lines | 384 code | 72 blank | 53 comment | 34 complexity | 719344987133938a388eab84f33fef57 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /*
  3. * e107 website system
  4. *
  5. * Copyright (C) 2008-2009 e107 Inc (e107.org)
  6. * Released under the terms and conditions of the
  7. * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
  8. *
  9. *
  10. *
  11. * $Source: /cvs_backup/e107_0.8/e107_handlers/phpmailer/mailout_process.php,v $
  12. * $Revision$
  13. * $Date$
  14. * $Author$
  15. |
  16. | Modifications in hand to work with most recent mailout.php
  17. To do:
  18. 1. Admin log entries?
  19. 2. Option to add user name in subject line - support |...| and {...} - done; test
  20. 3. Strip bbcode from plain text emails (ideally needs updated parser).
  21. 4. Support phpmailer 2.0 options
  22. 5. Log cancellation of email run
  23. |
  24. +----------------------------------------------------------------------------+
  25. */
  26. require_once("../../class2.php");
  27. if(!getperms("W")){ header("location:".e_BASE."index.php"); exit; }
  28. include_lan(e_LANGUAGEDIR.e_LANGUAGE."/admin/lan_mailout.php");
  29. // Directory for log (if enabled)
  30. //FIXME need another name
  31. define('MAIL_LOG_PATH',e_LOG);
  32. $HEADER = "";
  33. $FOOTER = "";
  34. define("e_PAGETITLE",LAN_MAILOUT_60);
  35. require_once(HEADERF);
  36. set_time_limit(18000);
  37. session_write_close();
  38. // $logenable - 0 = log disabled, 1 = 'dry run' (debug and log, no send). 2 = 'log all' (send, and log result). 3 = 'dry run' with failures
  39. // $add_email - 1 includes email detail in log
  40. list($logenable,$add_email) = explode(',',varset($pref['mail_log_options'],'0,0'));
  41. if($_POST['cancel_emails'])
  42. {
  43. $sql -> db_Delete("generic", "gen_datestamp='".intval($_POST['mail_id'])."' ");
  44. $text = "<div style='text-align:center;width:220px'><br />".LAN_MAILOUT_66; // Cancelled Successfully;
  45. $text .= "<div style='text-align:center;margin-left:auto;margin-right:auto;position:absolute;left:10px;top:110px'>
  46. <br /><input type='button' class='btn btn-primary button' name='close' value='Close' onclick=\"window.close()\" />
  47. </div></div>";
  48. $ns -> tablerender(LAN_MAILOUT_59, $text);
  49. echo "</body></html>";
  50. exit;
  51. }
  52. ob_implicit_flush();
  53. if (e_QUERY)
  54. {
  55. $tmp = explode('.',e_QUERY);
  56. $mail_id = intval(varset($tmp[0],0)); // ID in 'generic' table corresponding to the recipient entries
  57. $mail_text_id = intval(varset($tmp[1],0)); // Record number in 'generic' table corresponding to the email data
  58. }
  59. else
  60. {
  61. $mail_id = intval(varset($_POST['mail_id'],0)); // ID in 'generic' table corresponding to the recipient entries
  62. $mail_text_id = intval(varset($_POST['mail_text_id'],0)); // ID in 'generic' table corresponding to the recipient entries
  63. }
  64. if (($mail_id == 0) || ($mail_text_id == 0))
  65. {
  66. echo "Invalid parameters: {$mail_id}, {$mail_text_id}!<br />";
  67. exit;
  68. }
  69. // Get the email itself from the 'generic' table
  70. $qry = "SELECT * FROM #generic WHERE `gen_id` = {$mail_text_id} AND gen_type='savemail' and gen_datestamp = '".$mail_id."' ";
  71. if (!$sql -> db_Select_gen($qry))
  72. {
  73. echo "Email not found<br />";
  74. exit;
  75. }
  76. if (!$row = $sql->db_Fetch())
  77. {
  78. echo "Can't read email<br />";
  79. exit;
  80. }
  81. $email_info = unserialize($row['gen_chardata']); // Gives us sender_name, sender_email, email_body
  82. //--------------------------------------------------
  83. // Configure mailout handler (PHPMailer or other)
  84. //--------------------------------------------------
  85. require(e_HANDLER."phpmailer/class.phpmailer.php");
  86. $mail = new PHPMailer();
  87. $mail->From = varsettrue($email_info['sender_email'],$pref['siteadminemail']);
  88. $mail->FromName = varsettrue($email_info['sender_name'], $pref['siteadmin']);
  89. // $mail->Host = "smtp1.site.com;smtp2.site.com";
  90. if ($pref['mailer']== 'smtp')
  91. {
  92. $mail->Mailer = "smtp";
  93. $mail->SMTPKeepAlive = varsettrue($pref['smtp_keepalive']) ? TRUE : FALSE;
  94. if($pref['smtp_server'])
  95. {
  96. $mail->Host = $pref['smtp_server'];
  97. }
  98. if($pref['smtp_username'] && $pref['smtp_password'])
  99. {
  100. $mail->SMTPAuth = TRUE;
  101. $mail->Username = $pref['smtp_username'];
  102. $mail->Password = $pref['smtp_password'];
  103. $mail->PluginDir = e_HANDLER."phpmailer/";
  104. }
  105. }
  106. elseif ($pref['mailer']== 'sendmail')
  107. {
  108. $mail->Mailer = "sendmail";
  109. $mail->Sendmail = ($pref['sendmail']) ? $pref['sendmail'] : "/usr/sbin/sendmail -t -i -r ".$pref['siteadminemail'];
  110. }
  111. else
  112. {
  113. $mail->Mailer = "mail";
  114. }
  115. $message_subject = stripslashes($tp -> toHTML($email_info['email_subject'],FALSE,RAWTEXT));
  116. $mail->WordWrap = 50;
  117. $mail->CharSet = CHARSET;
  118. $mail->IsHTML(TRUE);
  119. $mail->SMTPDebug = (e_MENU == "debug") ? TRUE : FALSE;
  120. if($email_info['copy_to'])
  121. {
  122. $tmp = explode(",",$email_info['copy_to']);
  123. foreach($tmp as $addc)
  124. {
  125. $mail->AddCC(trim($addc));
  126. }
  127. }
  128. if($email_info['bcopy_to'])
  129. {
  130. $tmp = explode(",",$email_info['bcopy_to']);
  131. foreach($tmp as $addc)
  132. {
  133. $mail->AddBCC(trim($addc));
  134. }
  135. }
  136. if($pref['mail_bounce_email'] !='')
  137. {
  138. $mail->Sender = $pref['mail_bounce_email'];
  139. }
  140. $attach = trim($email_info['attach']);
  141. if(is_readable(e_DOWNLOAD.$attach))
  142. {
  143. $attach_link = e_DOWNLOAD.$attach;
  144. }
  145. else
  146. {
  147. $attach_link = e_UPLOAD.$attach;
  148. }
  149. if (($temp = strrchr($attach,'/')) !== FALSE)
  150. { // Just specify filename as attachment - no path
  151. $attach = substr($temp,1);
  152. }
  153. if ($attach != "" && !$mail->AddAttachment($attach_link, $attach))
  154. {
  155. $mss = LAN_MAILOUT_58."<br />{$attach_link}->{$attach}"; // problem with attachment.
  156. $ns->tablerender("Error", $mss);
  157. exit;
  158. }
  159. // ---------------------------- Setup the Email ----------------------------->
  160. $mail_head = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n";
  161. $mail_head .= "<html xmlns='http://www.w3.org/1999/xhtml' >\n";
  162. $mail_head .= "<head><meta http-equiv='content-type' content='text/html; charset=".CHARSET."' />\n";
  163. if (varsettrue($email_info['use_theme']))
  164. {
  165. $theme = $THEMES_DIRECTORY.$pref['sitetheme']."/";
  166. $style_css = file_get_contents(e_THEME.$pref['sitetheme']."/style.css");
  167. $mail_head .= "<style>\n".$style_css."\n</style>";
  168. $message_body = $mail_head;
  169. $message_body .= "</head>\n<body>\n";
  170. $message_body .= "<div style='padding:10px;width:97%'><div class='forumheader3'>\n";
  171. $message_body .= $tp -> toEmail($email_info['email_body'])."</div></div></body></html>";
  172. }
  173. else
  174. {
  175. $message_body = $mail_head;
  176. $message_body .= "</head>\n<body>\n";
  177. $message_body .= $tp -> toEmail($email_info['email_body'])."</body></html>";
  178. $message_body = str_replace("&quot;", '"', $message_body);
  179. $message_body = str_replace('src="', 'src="'.SITEURL, $message_body);
  180. }
  181. $message_body = stripslashes($message_body);
  182. // ---------------- Display Progress and Send Emails. ----------------------->
  183. echo "<div class='fcaption'>&nbsp;".LAN_MAILOUT_59."</div>";
  184. // $qry = "SELECT g.*,u.* FROM #generic AS g LEFT JOIN #user AS u ON g.gen_user_id = u.user_id WHERE g.gen_type='sendmail' and g.gen_datestamp = '".intval($_POST['mail_id'])."' ";
  185. // All the user info is in the generic table now - simplifies the query a bit
  186. $qry = "SELECT g.* FROM #generic AS g WHERE g.gen_type='sendmail' and g.gen_datestamp = '".$mail_id."' ";
  187. $count = $sql -> db_Select_gen($qry);
  188. // echo date("H:i:s d.m.y")." Start of mail run by ".USERNAME." - {$count} emails to go. ID: {$mail_id}. Subject: ".$mail_subject."<br />";
  189. if(!$count)
  190. {
  191. echo "<div style='text-align:center;width:200px'><br />".LAN_MAILOUT_61."</div>";
  192. echo "</body></html>";
  193. echo "<div style='text-align:center;margin-left:auto;margin-right:auto;position:absolute;left:10px;top:110px'>
  194. <input type='button' class='btn btn-default button' name='close' value='Close' onclick=\"window.close()\" />
  195. </div>";
  196. exit;
  197. }
  198. $c = 0; $d=0;
  199. $cur = 0;
  200. $send_ok = 0; $send_fail = 0;
  201. $pause_count = 1;
  202. $pause_amount = ($pref['mail_pause']) ? $pref['mail_pause'] : 10;
  203. $pause_time = ($pref['mail_pausetime']) ? $pref['mail_pausetime'] : 1;
  204. $unit = (1/$count)* 100; // Percentage 'weight' of each email
  205. echo "<div class='blocks' style='text-align:left;width:199px'><div id='bar' class='bar' style='border:0px;width:".$cur."%' >&nbsp;</div></div>";
  206. echo "<div class='percents'><span id='numbers'>".($c+1)." / ".$count." (" . $cur . "</span>%) &nbsp;".LAN_MAILOUT_117."</div>";
  207. stopwatch();
  208. // Debug/mailout log
  209. if ($logenable)
  210. {
  211. $logfilename = MAIL_LOG_PATH.'mailoutlog.txt';
  212. $loghandle = fopen($logfilename, 'a'); // Always append to file
  213. fwrite($loghandle,"=====----------------------------------------------------------------------------------=====\r\n");
  214. fwrite($loghandle,date("H:i:s d.m.y")." Start of mail run by ".USERNAME." - {$count} emails to go. ID: {$mail_id}. Subject: ".$mail_subject."\r\n");
  215. if ($add_email)
  216. {
  217. fwrite($loghandle, "From: ".$mail->From.' ('.$mail->FromName.")\r\n");
  218. fwrite($loghandle, "Subject: ".$mail->Subject."\r\n");
  219. fwrite($loghandle, "CC: ".$email_info['copy_to']."\r\n");
  220. fwrite($loghandle, "BCC: ".$email_info['bcopy_to']."\r\n");
  221. fwrite($loghandle, "Attach: ".$attach."\r\n");
  222. fwrite($loghandle, "Body: ".$email_info['email_body']."\r\n");
  223. fwrite($loghandle,"-----------------------------------------------------------\r\n");
  224. }
  225. }
  226. while($row = $sql-> db_Fetch())
  227. {
  228. //-------------------------------
  229. // Send one email
  230. //-------------------------------
  231. $mail_info = unserialize($row['gen_chardata']); // Has most of the info needed
  232. $activator = (substr(SITEURL, -1) == "/" ? SITEURL."signup.php?activate.".$row['gen_user_id'].".".$mail_info['user_signup'] : SITEURL."/signup.php?activate.".$row['gen_user_id'].".".$mail_info['user_signup']);
  233. $signup_link = ($mail_info['user_signup']) ? "<a href='{$activator}'>{$activator}</a>" : "";
  234. // Allow username in subject
  235. $mail_subject = str_replace(array('|USERNAME|','{USERNAME}'),$mail_info['user_name'],$message_subject);
  236. $mail->Subject = $mail_subject;
  237. // Allow username, userID, signup link in body
  238. $search = array('|USERNAME|','|USERID|','|SIGNUP_LINK|');
  239. $replace = array($mail_info['user_name'],$row['gen_user_id'],$signup_link);
  240. $mes_body = str_replace($search,$replace,$message_body);
  241. $alt_body = str_replace($search,$replace,stripslashes($tp->toText($email_info['email_body'])));
  242. $mail->Body = $mes_body;
  243. $mail->AltBody = $alt_body;
  244. $mail->AddAddress($mail_info['user_email'], $mail_info['user_name']);
  245. if ($row['gen_user_id'])
  246. {
  247. $mail_custom = $row['gen_user_id'];
  248. }
  249. else
  250. {
  251. $mail_custom = md5($mail_info['user_name'].$mail_info['user_email']);
  252. }
  253. $mail_custom = "X-e107-id: ".$mail_id.'/'.$mail_custom;
  254. $mail->AddCustomHeader($mail_custom);
  255. $debug_message = '';
  256. if (($logenable == 0) || ($logenable == 2))
  257. { // Actually send email
  258. $mail_result = $mail->Send();
  259. }
  260. else
  261. { // Debug mode - decide result of email here
  262. $mail_result = TRUE;
  263. if (($logenable == 3) && (($c % 7) == 4)) $mail_result = FALSE; // Fail one email in 7 for testing
  264. $debug_message = 'Debug';
  265. }
  266. if ($mail_result)
  267. {
  268. $send_ok++;
  269. $sql2->db_Delete('generic',"gen_id={$row['gen_id']}"); // Mail sent - delete from database
  270. }
  271. else
  272. {
  273. $send_fail++;
  274. $mail_info['send_result'] = 'Fail: '.$mail->ErrorInfo.$debug_message;
  275. $temp = serialize($mail_info);
  276. // Log any error info we can
  277. $sql2->db_Update('generic',"`gen_chardata`='{$temp}' WHERE gen_id={$row['gen_id']}");
  278. }
  279. if ($logenable)
  280. {
  281. fwrite($loghandle,date("H:i:s d.m.y")." Send to {$mail_info['user_name']} at {$mail_info['user_email']} Mail-ID={$mail_custom} - {$mail_result}\r\n");
  282. }
  283. $mail->ClearAddresses();
  284. $mail->ClearCustomHeaders();
  285. // --------- One email sent
  286. $cur = round((($c / $count) * 100) + $unit);
  287. // Do we need next line?
  288. // echo str_pad(' ',4096)."<br />\n"; // Put out lots of spaces and a newline - works wonders for XHTML compliance!
  289. // $d = ($c==0) ? 10 : round($width + $d); // Line doesn't do anything
  290. // echo "<div class='percents'>".($c+1)." / ".$count." (" . $cur . "%) &nbsp;".LAN_MAILOUT_117."</div>";
  291. echo "<script type='text/javascript'>setnum('".($c+1)."','{$count}','{$cur}');</script>\n";
  292. /* if($cur != $prev)
  293. { // Update 'completed' segment of progress bar
  294. echo "<script type='text/javascript'>inc('".$cur."%');</script>\n";
  295. }
  296. $prev = $cur;
  297. */ ob_flush();
  298. flush();
  299. if($pause_count > $pause_amount)
  300. {
  301. sleep($pause_time);
  302. $pause_count = 1;
  303. }
  304. // Default sleep to reduce server-load: 1 second.
  305. sleep(1);
  306. $c++;
  307. $pause_count++;
  308. }
  309. ob_end_flush();
  310. echo "<div style='position:absolute;left:10px;top:50px'><br />";
  311. echo LAN_MAILOUT_62." ".$send_ok."<br />";
  312. echo LAN_MAILOUT_63." ".$send_fail."<br />";
  313. echo LAN_MAILOUT_64." ".stopwatch()." ".LAN_MAILOUT_65."<br />";
  314. echo "</div>";
  315. // Complete - need to log something against the mailshot entry, and maybe write an admin log entry.
  316. $log_string = date("H:i:s d.m.y")." End of ".($logenable == 1 ? 'debug ' : '')."mail run by ".USERNAME." - {$send_ok} succeeded, {$send_fail} failed. Subject: ".$mail_subject;
  317. if (!is_array($email_info['send_results'])) $email_info['send_results'] = array();
  318. $email_info['send_results'][] = $log_string;
  319. $sql->db_Update('generic',"`gen_chardata`='".serialize($email_info)."' WHERE `gen_id` = {$mail_text_id} AND `gen_type`='savemail' and `gen_datestamp` = '".$mail_id."' ");
  320. $mail->ClearAttachments();
  321. if ($pref['mailer']== 'smtp')
  322. {
  323. $mail->SmtpClose();
  324. }
  325. echo "<div style='text-align:center;margin-left:auto;margin-right:auto;position:absolute;left:10px;top:110px'>
  326. <br /><input type='button' class='btn btn-default button' name='close' value='Close' onclick=\"window.close()\" />
  327. </div>";
  328. echo "</body></html>";
  329. if ($logenable)
  330. {
  331. fwrite($loghandle,$log_string."\r\n");
  332. fclose($loghandle);
  333. }
  334. function headerjs(){
  335. $text = "
  336. <style type='text/css'><!--
  337. div.percents div.blocks img.blocks{
  338. margin: 1px;
  339. height: 20px;
  340. padding: 1px;
  341. border: 1px solid #000;
  342. width: 199px;
  343. background: #fff;
  344. color: #000;
  345. float: left;
  346. clear: right;
  347. z-index: 9;
  348. position:relative;
  349. }
  350. .percents {
  351. background: #FFF;
  352. border: 1px solid #CCC;
  353. margin: 1px;
  354. height: 20px;
  355. position:absolute;
  356. vertical-align:middle;
  357. width:199px;
  358. z-index:10;
  359. left: 10px;
  360. top: 38px;
  361. text-align: center;
  362. color:black;
  363. }
  364. .blocks {
  365. margin-top: 1px;
  366. height: 21px;
  367. position: absolute;
  368. z-index:11;
  369. left: 12px;
  370. top: 38px;
  371. }
  372. .bar {
  373. background: #EEE;
  374. background-color:red;
  375. filter: alpha(opacity=50);
  376. height:21px;
  377. -moz-opacity: 0.5;
  378. opacity: 0.5;
  379. -khtml-opacity: .5
  380. }
  381. -->
  382. </style>";
  383. $text .= "
  384. <script type='text/javascript'>
  385. function inc(amount)
  386. {
  387. document.getElementById('bar').style.width= amount;
  388. }
  389. function setnum(v1,v2,v3)
  390. {
  391. this_el = document.getElementById('numbers');
  392. if (this_el) this_el.innerHTML = v1+' / '+v2+' ('+v3;
  393. document.getElementById('bar').style.width= v3+'%';
  394. }
  395. </script>";
  396. return $text;
  397. }
  398. function stopwatch(){
  399. static $mt_previous = 0;
  400. list($usec, $sec) = explode(" ",microtime());
  401. $mt_current = (float)$usec + (float)$sec;
  402. if (!$mt_previous) {
  403. $mt_previous = $mt_current;
  404. return "";
  405. } else {
  406. $mt_diff = ($mt_current - $mt_previous);
  407. $mt_previous = $mt_current;
  408. return round(sprintf('%.16f',$mt_diff),2);
  409. }
  410. }
  411. ?>