PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/phpBB/includes/acp/acp_email.php

http://github.com/phpbb/phpbb
PHP | 351 lines | 250 code | 45 blank | 56 comment | 37 complexity | 8db50558c5a4257d4412b67e8c6dfe18 MD5 | raw file
Possible License(s): GPL-3.0, AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * This file is part of the phpBB Forum Software package.
  5. *
  6. * @copyright (c) phpBB Limited <https://www.phpbb.com>
  7. * @license GNU General Public License, version 2 (GPL-2.0)
  8. *
  9. * For full copyright and license information, please see
  10. * the docs/CREDITS.txt file.
  11. *
  12. */
  13. /**
  14. * @ignore
  15. */
  16. if (!defined('IN_PHPBB'))
  17. {
  18. exit;
  19. }
  20. class acp_email
  21. {
  22. var $u_action;
  23. function main($id, $mode)
  24. {
  25. global $config, $db, $user, $template, $phpbb_log, $request;
  26. global $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_dispatcher;
  27. $user->add_lang('acp/email');
  28. $this->tpl_name = 'acp_email';
  29. $this->page_title = 'ACP_MASS_EMAIL';
  30. $form_key = 'acp_email';
  31. add_form_key($form_key);
  32. // Set some vars
  33. $submit = (isset($_POST['submit'])) ? true : false;
  34. $error = array();
  35. $usernames = $request->variable('usernames', '', true);
  36. $usernames = (!empty($usernames)) ? explode("\n", $usernames) : array();
  37. $group_id = $request->variable('g', 0);
  38. $subject = $request->variable('subject', '', true);
  39. $message = $request->variable('message', '', true);
  40. // Do the job ...
  41. if ($submit)
  42. {
  43. // Error checking needs to go here ... if no subject and/or no message then skip
  44. // over the send and return to the form
  45. $use_queue = (isset($_POST['send_immediately'])) ? false : true;
  46. $priority = $request->variable('mail_priority_flag', MAIL_NORMAL_PRIORITY);
  47. if (!check_form_key($form_key))
  48. {
  49. $error[] = $user->lang['FORM_INVALID'];
  50. }
  51. if (!$subject)
  52. {
  53. $error[] = $user->lang['NO_EMAIL_SUBJECT'];
  54. }
  55. if (!$message)
  56. {
  57. $error[] = $user->lang['NO_EMAIL_MESSAGE'];
  58. }
  59. if (!count($error))
  60. {
  61. if (!empty($usernames))
  62. {
  63. // If giving usernames the admin is able to email inactive users too...
  64. $sql_ary = array(
  65. 'SELECT' => 'username, user_email, user_jabber, user_notify_type, user_lang',
  66. 'FROM' => array(
  67. USERS_TABLE => '',
  68. ),
  69. 'WHERE' => $db->sql_in_set('username_clean', array_map('utf8_clean_string', $usernames)) . '
  70. AND user_allow_massemail = 1',
  71. 'ORDER_BY' => 'user_lang, user_notify_type',
  72. );
  73. }
  74. else
  75. {
  76. if ($group_id)
  77. {
  78. $sql_ary = array(
  79. 'SELECT' => 'u.user_email, u.username, u.username_clean, u.user_lang, u.user_jabber, u.user_notify_type',
  80. 'FROM' => array(
  81. USERS_TABLE => 'u',
  82. USER_GROUP_TABLE => 'ug',
  83. ),
  84. 'WHERE' => 'ug.group_id = ' . $group_id . '
  85. AND ug.user_pending = 0
  86. AND u.user_id = ug.user_id
  87. AND u.user_allow_massemail = 1
  88. AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')',
  89. 'ORDER_BY' => 'u.user_lang, u.user_notify_type',
  90. );
  91. }
  92. else
  93. {
  94. $sql_ary = array(
  95. 'SELECT' => 'u.username, u.username_clean, u.user_email, u.user_jabber, u.user_lang, u.user_notify_type',
  96. 'FROM' => array(
  97. USERS_TABLE => 'u',
  98. ),
  99. 'WHERE' => 'u.user_allow_massemail = 1
  100. AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')',
  101. 'ORDER_BY' => 'u.user_lang, u.user_notify_type',
  102. );
  103. }
  104. // Mail banned or not
  105. if (!isset($_REQUEST['mail_banned_flag']))
  106. {
  107. $sql_ary['WHERE'] .= ' AND (b.ban_id IS NULL
  108. OR b.ban_exclude = 1)';
  109. $sql_ary['LEFT_JOIN'] = array(
  110. array(
  111. 'FROM' => array(
  112. BANLIST_TABLE => 'b',
  113. ),
  114. 'ON' => 'u.user_id = b.ban_userid',
  115. ),
  116. );
  117. }
  118. }
  119. /**
  120. * Modify sql query to change the list of users the email is sent to
  121. *
  122. * @event core.acp_email_modify_sql
  123. * @var array sql_ary Array which is used to build the sql query
  124. * @since 3.1.2-RC1
  125. */
  126. $vars = array('sql_ary');
  127. extract($phpbb_dispatcher->trigger_event('core.acp_email_modify_sql', compact($vars)));
  128. $sql = $db->sql_build_query('SELECT', $sql_ary);
  129. $result = $db->sql_query($sql);
  130. $row = $db->sql_fetchrow($result);
  131. if (!$row)
  132. {
  133. $db->sql_freeresult($result);
  134. trigger_error($user->lang['NO_USER'] . adm_back_link($this->u_action), E_USER_WARNING);
  135. }
  136. $i = $j = 0;
  137. // Send with BCC
  138. // Maximum number of bcc recipients
  139. $max_chunk_size = (int) $config['email_max_chunk_size'];
  140. $email_list = array();
  141. $old_lang = $row['user_lang'];
  142. $old_notify_type = $row['user_notify_type'];
  143. do
  144. {
  145. if (($row['user_notify_type'] == NOTIFY_EMAIL && $row['user_email']) ||
  146. ($row['user_notify_type'] == NOTIFY_IM && $row['user_jabber']) ||
  147. ($row['user_notify_type'] == NOTIFY_BOTH && ($row['user_email'] || $row['user_jabber'])))
  148. {
  149. if ($i == $max_chunk_size || $row['user_lang'] != $old_lang || $row['user_notify_type'] != $old_notify_type)
  150. {
  151. $i = 0;
  152. if (count($email_list))
  153. {
  154. $j++;
  155. }
  156. $old_lang = $row['user_lang'];
  157. $old_notify_type = $row['user_notify_type'];
  158. }
  159. $email_list[$j][$i]['lang'] = $row['user_lang'];
  160. $email_list[$j][$i]['method'] = $row['user_notify_type'];
  161. $email_list[$j][$i]['email'] = $row['user_email'];
  162. $email_list[$j][$i]['name'] = $row['username'];
  163. $email_list[$j][$i]['jabber'] = $row['user_jabber'];
  164. $i++;
  165. }
  166. }
  167. while ($row = $db->sql_fetchrow($result));
  168. $db->sql_freeresult($result);
  169. // Send the messages
  170. if (!class_exists('messenger'))
  171. {
  172. include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
  173. }
  174. if (!function_exists('get_group_name'))
  175. {
  176. include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
  177. }
  178. $messenger = new messenger($use_queue);
  179. $errored = false;
  180. $email_template = 'admin_send_email';
  181. $template_data = array(
  182. 'CONTACT_EMAIL' => phpbb_get_board_contact($config, $phpEx),
  183. 'MESSAGE' => htmlspecialchars_decode($message),
  184. );
  185. $generate_log_entry = true;
  186. /**
  187. * Modify email template data before the emails are sent
  188. *
  189. * @event core.acp_email_send_before
  190. * @var string email_template The template to be used for sending the email
  191. * @var string subject The subject of the email
  192. * @var array template_data Array with template data assigned to email template
  193. * @var bool generate_log_entry If false, no log entry will be created
  194. * @var array usernames Usernames which will be displayed in log entry, if it will be created
  195. * @var int group_id The group this email will be sent to
  196. * @var bool use_queue If true, email queue will be used for sending
  197. * @var int priority Priority of sent emails
  198. * @since 3.1.3-RC1
  199. */
  200. $vars = array(
  201. 'email_template',
  202. 'subject',
  203. 'template_data',
  204. 'generate_log_entry',
  205. 'usernames',
  206. 'group_id',
  207. 'use_queue',
  208. 'priority',
  209. );
  210. extract($phpbb_dispatcher->trigger_event('core.acp_email_send_before', compact($vars)));
  211. for ($i = 0, $size = count($email_list); $i < $size; $i++)
  212. {
  213. $used_lang = $email_list[$i][0]['lang'];
  214. $used_method = $email_list[$i][0]['method'];
  215. for ($j = 0, $list_size = count($email_list[$i]); $j < $list_size; $j++)
  216. {
  217. $email_row = $email_list[$i][$j];
  218. $messenger->{((count($email_list[$i]) == 1) ? 'to' : 'bcc')}($email_row['email'], $email_row['name']);
  219. $messenger->im($email_row['jabber'], $email_row['name']);
  220. }
  221. $messenger->template($email_template, $used_lang);
  222. $messenger->anti_abuse_headers($config, $user);
  223. $messenger->subject(htmlspecialchars_decode($subject));
  224. $messenger->set_mail_priority($priority);
  225. $messenger->assign_vars($template_data);
  226. if (!($messenger->send($used_method)))
  227. {
  228. $errored = true;
  229. }
  230. }
  231. unset($email_list);
  232. $messenger->save_queue();
  233. if ($generate_log_entry)
  234. {
  235. if (!empty($usernames))
  236. {
  237. $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MASS_EMAIL', false, array(implode(', ', utf8_normalize_nfc($usernames))));
  238. }
  239. else
  240. {
  241. if ($group_id)
  242. {
  243. $group_name = get_group_name($group_id);
  244. }
  245. else
  246. {
  247. // Not great but the logging routine doesn't cope well with localising on the fly
  248. $group_name = $user->lang['ALL_USERS'];
  249. }
  250. $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MASS_EMAIL', false, array($group_name));
  251. }
  252. }
  253. if (!$errored)
  254. {
  255. $message = ($use_queue) ? $user->lang['EMAIL_SENT_QUEUE'] : $user->lang['EMAIL_SENT'];
  256. trigger_error($message . adm_back_link($this->u_action));
  257. }
  258. else
  259. {
  260. $message = sprintf($user->lang['EMAIL_SEND_ERROR'], '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=logs&amp;mode=critical') . '">', '</a>');
  261. trigger_error($message . adm_back_link($this->u_action), E_USER_WARNING);
  262. }
  263. }
  264. }
  265. // Exclude bots and guests...
  266. $sql = 'SELECT group_id
  267. FROM ' . GROUPS_TABLE . "
  268. WHERE group_name IN ('BOTS', 'GUESTS')";
  269. $result = $db->sql_query($sql);
  270. $exclude = array();
  271. while ($row = $db->sql_fetchrow($result))
  272. {
  273. $exclude[] = $row['group_id'];
  274. }
  275. $db->sql_freeresult($result);
  276. $select_list = '<option value="0"' . ((!$group_id) ? ' selected="selected"' : '') . '>' . $user->lang['ALL_USERS'] . '</option>';
  277. $select_list .= group_select_options($group_id, $exclude);
  278. $s_priority_options = '<option value="' . MAIL_LOW_PRIORITY . '">' . $user->lang['MAIL_LOW_PRIORITY'] . '</option>';
  279. $s_priority_options .= '<option value="' . MAIL_NORMAL_PRIORITY . '" selected="selected">' . $user->lang['MAIL_NORMAL_PRIORITY'] . '</option>';
  280. $s_priority_options .= '<option value="' . MAIL_HIGH_PRIORITY . '">' . $user->lang['MAIL_HIGH_PRIORITY'] . '</option>';
  281. $template_data = array(
  282. 'S_WARNING' => (count($error)) ? true : false,
  283. 'WARNING_MSG' => (count($error)) ? implode('<br />', $error) : '',
  284. 'U_ACTION' => $this->u_action,
  285. 'S_GROUP_OPTIONS' => $select_list,
  286. 'USERNAMES' => implode("\n", $usernames),
  287. 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&amp;form=acp_email&amp;field=usernames'),
  288. 'SUBJECT' => $subject,
  289. 'MESSAGE' => $message,
  290. 'S_PRIORITY_OPTIONS' => $s_priority_options,
  291. );
  292. /**
  293. * Modify custom email template data before we display the form
  294. *
  295. * @event core.acp_email_display
  296. * @var array template_data Array with template data assigned to email template
  297. * @var array exclude Array with groups which are excluded from group selection
  298. * @var array usernames Usernames which will be displayed in form
  299. *
  300. * @since 3.1.4-RC1
  301. */
  302. $vars = array('template_data', 'exclude', 'usernames');
  303. extract($phpbb_dispatcher->trigger_event('core.acp_email_display', compact($vars)));
  304. $template->assign_vars($template_data);
  305. }
  306. }