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

/includes/ucp/ucp_pm_compose.php

https://github.com/Vexilurz/phpbb_forum
PHP | 1330 lines | 1007 code | 212 blank | 111 comment | 330 complexity | f2b65b56339f5e1597e8e4157b614cfc MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * @package ucp
  5. * @version $Id$
  6. * @copyright (c) 2005 phpBB Group
  7. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  8. *
  9. */
  10. /**
  11. * @ignore
  12. */
  13. if (!defined('IN_PHPBB'))
  14. {
  15. exit;
  16. }
  17. /**
  18. * Compose private message
  19. * Called from ucp_pm with mode == 'compose'
  20. */
  21. function compose_pm($id, $mode, $action, $user_folders = array())
  22. {
  23. global $template, $db, $auth, $user;
  24. global $phpbb_root_path, $phpEx, $config;
  25. // Damn php and globals - i know, this is horrible
  26. // Needed for handle_message_list_actions()
  27. global $refresh, $submit, $preview;
  28. include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
  29. include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
  30. include($phpbb_root_path . 'includes/message_parser.' . $phpEx);
  31. if (!$action)
  32. {
  33. $action = 'post';
  34. }
  35. add_form_key('ucp_pm_compose');
  36. // Grab only parameters needed here
  37. $to_user_id = request_var('u', 0);
  38. $to_group_id = request_var('g', 0);
  39. $msg_id = request_var('p', 0);
  40. $draft_id = request_var('d', 0);
  41. $lastclick = request_var('lastclick', 0);
  42. // Reply to all triggered (quote/reply)
  43. $reply_to_all = request_var('reply_to_all', 0);
  44. // Do NOT use request_var or specialchars here
  45. $address_list = isset($_REQUEST['address_list']) ? $_REQUEST['address_list'] : array();
  46. if (!is_array($address_list))
  47. {
  48. $address_list = array();
  49. }
  50. $submit = (isset($_POST['post'])) ? true : false;
  51. $preview = (isset($_POST['preview'])) ? true : false;
  52. $save = (isset($_POST['save'])) ? true : false;
  53. $load = (isset($_POST['load'])) ? true : false;
  54. $cancel = (isset($_POST['cancel']) && !isset($_POST['save'])) ? true : false;
  55. $delete = (isset($_POST['delete'])) ? true : false;
  56. $remove_u = (isset($_REQUEST['remove_u'])) ? true : false;
  57. $remove_g = (isset($_REQUEST['remove_g'])) ? true : false;
  58. $add_to = (isset($_REQUEST['add_to'])) ? true : false;
  59. $add_bcc = (isset($_REQUEST['add_bcc'])) ? true : false;
  60. $refresh = isset($_POST['add_file']) || isset($_POST['delete_file']) || $save || $load
  61. || $remove_u || $remove_g || $add_to || $add_bcc;
  62. $action = ($delete && !$preview && !$refresh && $submit) ? 'delete' : $action;
  63. $select_single = ($config['allow_mass_pm'] && $auth->acl_get('u_masspm')) ? false : true;
  64. $error = array();
  65. $current_time = time();
  66. // Was cancel pressed? If so then redirect to the appropriate page
  67. if ($cancel || ($current_time - $lastclick < 2 && $submit))
  68. {
  69. if ($msg_id)
  70. {
  71. redirect(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=view&amp;action=view_message&amp;p=' . $msg_id));
  72. }
  73. redirect(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm'));
  74. }
  75. // Since viewtopic.php language entries are used in several modes,
  76. // we include the language file here
  77. $user->add_lang('viewtopic');
  78. // Output PM_TO box if message composing
  79. if ($action != 'edit')
  80. {
  81. // Add groups to PM box
  82. if ($config['allow_mass_pm'] && $auth->acl_get('u_masspm_group'))
  83. {
  84. $sql = 'SELECT g.group_id, g.group_name, g.group_type
  85. FROM ' . GROUPS_TABLE . ' g';
  86. if (!$auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel'))
  87. {
  88. $sql .= ' LEFT JOIN ' . USER_GROUP_TABLE . ' ug
  89. ON (
  90. g.group_id = ug.group_id
  91. AND ug.user_id = ' . $user->data['user_id'] . '
  92. AND ug.user_pending = 0
  93. )
  94. WHERE (g.group_type <> ' . GROUP_HIDDEN . ' OR ug.user_id = ' . $user->data['user_id'] . ')';
  95. }
  96. $sql .= ($auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel')) ? ' WHERE ' : ' AND ';
  97. $sql .= 'g.group_receive_pm = 1
  98. ORDER BY g.group_type DESC, g.group_name ASC';
  99. $result = $db->sql_query($sql);
  100. $group_options = '';
  101. while ($row = $db->sql_fetchrow($result))
  102. {
  103. $group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '">' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>';
  104. }
  105. $db->sql_freeresult($result);
  106. }
  107. $template->assign_vars(array(
  108. 'S_SHOW_PM_BOX' => true,
  109. 'S_ALLOW_MASS_PM' => ($config['allow_mass_pm'] && $auth->acl_get('u_masspm')) ? true : false,
  110. 'S_GROUP_OPTIONS' => ($config['allow_mass_pm'] && $auth->acl_get('u_masspm_group')) ? $group_options : '',
  111. 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=searchuser&amp;form=postform&amp;field=username_list&amp;select_single=$select_single"),
  112. ));
  113. }
  114. $sql = '';
  115. $folder_id = 0;
  116. // What is all this following SQL for? Well, we need to know
  117. // some basic information in all cases before we do anything.
  118. switch ($action)
  119. {
  120. case 'post':
  121. if (!$auth->acl_get('u_sendpm'))
  122. {
  123. trigger_error('NO_AUTH_SEND_MESSAGE');
  124. }
  125. break;
  126. case 'reply':
  127. case 'quote':
  128. case 'forward':
  129. case 'quotepost':
  130. if (!$msg_id)
  131. {
  132. trigger_error('NO_MESSAGE');
  133. }
  134. if (!$auth->acl_get('u_sendpm'))
  135. {
  136. trigger_error('NO_AUTH_SEND_MESSAGE');
  137. }
  138. if ($action == 'quotepost')
  139. {
  140. $sql = 'SELECT p.post_id as msg_id, p.forum_id, p.post_text as message_text, p.poster_id as author_id, p.post_time as message_time, p.bbcode_bitfield, p.bbcode_uid, p.enable_sig, p.enable_smilies, p.enable_magic_url, t.topic_title as message_subject, u.username as quote_username
  141. FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t, ' . USERS_TABLE . " u
  142. WHERE p.post_id = $msg_id
  143. AND t.topic_id = p.topic_id
  144. AND u.user_id = p.poster_id";
  145. }
  146. else
  147. {
  148. $sql = 'SELECT t.folder_id, p.*, u.username as quote_username
  149. FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p, ' . USERS_TABLE . ' u
  150. WHERE t.user_id = ' . $user->data['user_id'] . "
  151. AND p.author_id = u.user_id
  152. AND t.msg_id = p.msg_id
  153. AND p.msg_id = $msg_id";
  154. }
  155. break;
  156. case 'edit':
  157. if (!$msg_id)
  158. {
  159. trigger_error('NO_MESSAGE');
  160. }
  161. // check for outbox (not read) status, we do not allow editing if one user already having the message
  162. $sql = 'SELECT p.*, t.folder_id
  163. FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p
  164. WHERE t.user_id = ' . $user->data['user_id'] . '
  165. AND t.folder_id = ' . PRIVMSGS_OUTBOX . "
  166. AND t.msg_id = $msg_id
  167. AND t.msg_id = p.msg_id";
  168. break;
  169. case 'delete':
  170. if (!$auth->acl_get('u_pm_delete'))
  171. {
  172. trigger_error('NO_AUTH_DELETE_MESSAGE');
  173. }
  174. if (!$msg_id)
  175. {
  176. trigger_error('NO_MESSAGE');
  177. }
  178. $sql = 'SELECT msg_id, pm_unread, pm_new, author_id, folder_id
  179. FROM ' . PRIVMSGS_TO_TABLE . '
  180. WHERE user_id = ' . $user->data['user_id'] . "
  181. AND msg_id = $msg_id";
  182. break;
  183. case 'smilies':
  184. generate_smilies('window', 0);
  185. break;
  186. default:
  187. trigger_error('NO_ACTION_MODE', E_USER_ERROR);
  188. break;
  189. }
  190. if ($action == 'forward' && (!$config['forward_pm'] || !$auth->acl_get('u_pm_forward')))
  191. {
  192. trigger_error('NO_AUTH_FORWARD_MESSAGE');
  193. }
  194. if ($action == 'edit' && !$auth->acl_get('u_pm_edit'))
  195. {
  196. trigger_error('NO_AUTH_EDIT_MESSAGE');
  197. }
  198. if ($sql)
  199. {
  200. $result = $db->sql_query($sql);
  201. $post = $db->sql_fetchrow($result);
  202. $db->sql_freeresult($result);
  203. if (!$post)
  204. {
  205. // If editing it could be the recipient already read the message...
  206. if ($action == 'edit')
  207. {
  208. $sql = 'SELECT p.*, t.folder_id
  209. FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p
  210. WHERE t.user_id = ' . $user->data['user_id'] . "
  211. AND t.msg_id = $msg_id
  212. AND t.msg_id = p.msg_id";
  213. $result = $db->sql_query($sql);
  214. $post = $db->sql_fetchrow($result);
  215. $db->sql_freeresult($result);
  216. if ($post)
  217. {
  218. trigger_error('NO_EDIT_READ_MESSAGE');
  219. }
  220. }
  221. trigger_error('NO_MESSAGE');
  222. }
  223. if ($action == 'quotepost')
  224. {
  225. if (($post['forum_id'] && !$auth->acl_get('f_read', $post['forum_id'])) || (!$post['forum_id'] && !$auth->acl_getf_global('f_read')))
  226. {
  227. trigger_error('NOT_AUTHORISED');
  228. }
  229. // Passworded forum?
  230. if ($post['forum_id'])
  231. {
  232. $sql = 'SELECT forum_password
  233. FROM ' . FORUMS_TABLE . '
  234. WHERE forum_id = ' . (int) $post['forum_id'];
  235. $result = $db->sql_query($sql);
  236. $forum_password = (string) $db->sql_fetchfield('forum_password');
  237. $db->sql_freeresult($result);
  238. if ($forum_password)
  239. {
  240. login_forum_box(array(
  241. 'forum_id' => $post['forum_id'],
  242. 'forum_password' => $forum_password,
  243. ));
  244. }
  245. }
  246. }
  247. $msg_id = (int) $post['msg_id'];
  248. $folder_id = (isset($post['folder_id'])) ? $post['folder_id'] : 0;
  249. $message_text = (isset($post['message_text'])) ? $post['message_text'] : '';
  250. if ((!$post['author_id'] || ($post['author_id'] == ANONYMOUS && $action != 'delete')) && $msg_id)
  251. {
  252. trigger_error('NO_AUTHOR');
  253. }
  254. if ($action == 'quotepost')
  255. {
  256. // Decode text for message display
  257. decode_message($message_text, $post['bbcode_uid']);
  258. }
  259. if ($action != 'delete')
  260. {
  261. $enable_urls = $post['enable_magic_url'];
  262. $enable_sig = (isset($post['enable_sig'])) ? $post['enable_sig'] : 0;
  263. $message_attachment = (isset($post['message_attachment'])) ? $post['message_attachment'] : 0;
  264. $message_subject = $post['message_subject'];
  265. $message_time = $post['message_time'];
  266. $bbcode_uid = $post['bbcode_uid'];
  267. $quote_username = (isset($post['quote_username'])) ? $post['quote_username'] : '';
  268. $icon_id = (isset($post['icon_id'])) ? $post['icon_id'] : 0;
  269. if (($action == 'reply' || $action == 'quote' || $action == 'quotepost') && !sizeof($address_list) && !$refresh && !$submit && !$preview)
  270. {
  271. // Add the original author as the recipient if quoting a post or only replying and not having checked "reply to all"
  272. if ($action == 'quotepost' || !$reply_to_all)
  273. {
  274. $address_list = array('u' => array($post['author_id'] => 'to'));
  275. }
  276. else
  277. {
  278. // We try to include every previously listed member from the TO Header - Reply to all
  279. $address_list = rebuild_header(array('to' => $post['to_address']));
  280. // Add the author (if he is already listed then this is no shame (it will be overwritten))
  281. $address_list['u'][$post['author_id']] = 'to';
  282. // Now, make sure the user itself is not listed. ;)
  283. if (isset($address_list['u'][$user->data['user_id']]))
  284. {
  285. unset($address_list['u'][$user->data['user_id']]);
  286. }
  287. }
  288. }
  289. else if ($action == 'edit' && !sizeof($address_list) && !$refresh && !$submit && !$preview)
  290. {
  291. // Rebuild TO and BCC Header
  292. $address_list = rebuild_header(array('to' => $post['to_address'], 'bcc' => $post['bcc_address']));
  293. }
  294. if ($action == 'quotepost')
  295. {
  296. $check_value = 0;
  297. }
  298. else
  299. {
  300. $check_value = (($post['enable_bbcode']+1) << 8) + (($post['enable_smilies']+1) << 4) + (($enable_urls+1) << 2) + (($post['enable_sig']+1) << 1);
  301. }
  302. }
  303. }
  304. else
  305. {
  306. $message_attachment = 0;
  307. $message_text = $message_subject = '';
  308. if ($to_user_id && $action == 'post')
  309. {
  310. $address_list['u'][$to_user_id] = 'to';
  311. }
  312. else if ($to_group_id && $action == 'post')
  313. {
  314. $address_list['g'][$to_group_id] = 'to';
  315. }
  316. $check_value = 0;
  317. }
  318. if (($to_group_id || isset($address_list['g'])) && (!$config['allow_mass_pm'] || !$auth->acl_get('u_masspm_group')))
  319. {
  320. trigger_error('NO_AUTH_GROUP_MESSAGE');
  321. }
  322. if ($action == 'edit' && !$refresh && !$preview && !$submit)
  323. {
  324. if (!($message_time > time() - ($config['pm_edit_time'] * 60) || !$config['pm_edit_time']))
  325. {
  326. trigger_error('CANNOT_EDIT_MESSAGE_TIME');
  327. }
  328. }
  329. if ($action == 'post')
  330. {
  331. $template->assign_var('S_NEW_MESSAGE', true);
  332. }
  333. if (!isset($icon_id))
  334. {
  335. $icon_id = 0;
  336. }
  337. $message_parser = new parse_message();
  338. $message_parser->message = ($action == 'reply') ? '' : $message_text;
  339. unset($message_text);
  340. $s_action = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&amp;mode=$mode&amp;action=$action", true, $user->session_id);
  341. $s_action .= (($folder_id) ? "&amp;f=$folder_id" : '') . (($msg_id) ? "&amp;p=$msg_id" : '');
  342. // Delete triggered ?
  343. if ($action == 'delete')
  344. {
  345. // Folder id has been determined by the SQL Statement
  346. // $folder_id = request_var('f', PRIVMSGS_NO_BOX);
  347. // Do we need to confirm ?
  348. if (confirm_box(true))
  349. {
  350. delete_pm($user->data['user_id'], $msg_id, $folder_id);
  351. // jump to next message in "history"? nope, not for the moment. But able to be included later.
  352. $meta_info = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&amp;folder=$folder_id");
  353. $message = $user->lang['MESSAGE_DELETED'];
  354. meta_refresh(3, $meta_info);
  355. $message .= '<br /><br />' . sprintf($user->lang['RETURN_FOLDER'], '<a href="' . $meta_info . '">', '</a>');
  356. trigger_error($message);
  357. }
  358. else
  359. {
  360. $s_hidden_fields = array(
  361. 'p' => $msg_id,
  362. 'f' => $folder_id,
  363. 'action' => 'delete'
  364. );
  365. // "{$phpbb_root_path}ucp.$phpEx?i=pm&amp;mode=compose"
  366. confirm_box(false, 'DELETE_MESSAGE', build_hidden_fields($s_hidden_fields));
  367. }
  368. redirect(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=view&amp;action=view_message&amp;p=' . $msg_id));
  369. }
  370. // Get maximum number of allowed recipients
  371. $sql = 'SELECT MAX(g.group_max_recipients) as max_recipients
  372. FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug
  373. WHERE ug.user_id = ' . $user->data['user_id'] . '
  374. AND ug.user_pending = 0
  375. AND ug.group_id = g.group_id';
  376. $result = $db->sql_query($sql);
  377. $max_recipients = (int) $db->sql_fetchfield('max_recipients');
  378. $db->sql_freeresult($result);
  379. $max_recipients = (!$max_recipients) ? $config['pm_max_recipients'] : $max_recipients;
  380. // If this is a quote/reply "to all"... we may increase the max_recpients to the number of original recipients
  381. if (($action == 'reply' || $action == 'quote') && $max_recipients && $reply_to_all)
  382. {
  383. // We try to include every previously listed member from the TO Header
  384. $list = rebuild_header(array('to' => $post['to_address']));
  385. // Can be an empty array too ;)
  386. $list = (!empty($list['u'])) ? $list['u'] : array();
  387. $list[$post['author_id']] = 'to';
  388. if (isset($list[$user->data['user_id']]))
  389. {
  390. unset($list[$user->data['user_id']]);
  391. }
  392. $max_recipients = ($max_recipients < sizeof($list)) ? sizeof($list) : $max_recipients;
  393. unset($list);
  394. }
  395. // Handle User/Group adding/removing
  396. handle_message_list_actions($address_list, $error, $remove_u, $remove_g, $add_to, $add_bcc);
  397. // Check mass pm to group permission
  398. if ((!$config['allow_mass_pm'] || !$auth->acl_get('u_masspm_group')) && !empty($address_list['g']))
  399. {
  400. $address_list = array();
  401. $error[] = $user->lang['NO_AUTH_GROUP_MESSAGE'];
  402. }
  403. // Check mass pm to users permission
  404. if ((!$config['allow_mass_pm'] || !$auth->acl_get('u_masspm')) && num_recipients($address_list) > 1)
  405. {
  406. $address_list = get_recipients($address_list, 1);
  407. $error[] = $user->lang('TOO_MANY_RECIPIENTS', 1);
  408. }
  409. // Check for too many recipients
  410. if (!empty($address_list['u']) && $max_recipients && sizeof($address_list['u']) > $max_recipients)
  411. {
  412. $address_list = get_recipients($address_list, $max_recipients);
  413. $error[] = $user->lang('TOO_MANY_RECIPIENTS', $max_recipients);
  414. }
  415. // Always check if the submitted attachment data is valid and belongs to the user.
  416. // Further down (especially in submit_post()) we do not check this again.
  417. $message_parser->get_submitted_attachment_data();
  418. if ($message_attachment && !$submit && !$refresh && !$preview && $action == 'edit')
  419. {
  420. // Do not change to SELECT *
  421. $sql = 'SELECT attach_id, is_orphan, attach_comment, real_filename
  422. FROM ' . ATTACHMENTS_TABLE . "
  423. WHERE post_msg_id = $msg_id
  424. AND in_message = 1
  425. AND is_orphan = 0
  426. ORDER BY filetime DESC";
  427. $result = $db->sql_query($sql);
  428. $message_parser->attachment_data = array_merge($message_parser->attachment_data, $db->sql_fetchrowset($result));
  429. $db->sql_freeresult($result);
  430. }
  431. if (!in_array($action, array('quote', 'edit', 'delete', 'forward')))
  432. {
  433. $enable_sig = ($config['allow_sig'] && $config['allow_sig_pm'] && $auth->acl_get('u_sig') && $user->optionget('attachsig'));
  434. $enable_smilies = ($config['allow_smilies'] && $auth->acl_get('u_pm_smilies') && $user->optionget('smilies'));
  435. $enable_bbcode = ($config['allow_bbcode'] && $auth->acl_get('u_pm_bbcode') && $user->optionget('bbcode'));
  436. $enable_urls = true;
  437. }
  438. $enable_magic_url = $drafts = false;
  439. // User own some drafts?
  440. if ($auth->acl_get('u_savedrafts') && $action != 'delete')
  441. {
  442. $sql = 'SELECT draft_id
  443. FROM ' . DRAFTS_TABLE . '
  444. WHERE forum_id = 0
  445. AND topic_id = 0
  446. AND user_id = ' . $user->data['user_id'] .
  447. (($draft_id) ? " AND draft_id <> $draft_id" : '');
  448. $result = $db->sql_query_limit($sql, 1);
  449. $row = $db->sql_fetchrow($result);
  450. $db->sql_freeresult($result);
  451. if ($row)
  452. {
  453. $drafts = true;
  454. }
  455. }
  456. if ($action == 'edit')
  457. {
  458. $message_parser->bbcode_uid = $bbcode_uid;
  459. }
  460. $bbcode_status = ($config['allow_bbcode'] && $config['auth_bbcode_pm'] && $auth->acl_get('u_pm_bbcode')) ? true : false;
  461. $smilies_status = ($config['allow_smilies'] && $config['auth_smilies_pm'] && $auth->acl_get('u_pm_smilies')) ? true : false;
  462. $img_status = ($config['auth_img_pm'] && $auth->acl_get('u_pm_img')) ? true : false;
  463. $flash_status = ($config['auth_flash_pm'] && $auth->acl_get('u_pm_flash')) ? true : false;
  464. $url_status = ($config['allow_post_links']) ? true : false;
  465. // Save Draft
  466. if ($save && $auth->acl_get('u_savedrafts'))
  467. {
  468. $subject = utf8_normalize_nfc(request_var('subject', '', true));
  469. $subject = (!$subject && $action != 'post') ? $user->lang['NEW_MESSAGE'] : $subject;
  470. $message = utf8_normalize_nfc(request_var('message', '', true));
  471. if ($subject && $message)
  472. {
  473. if (confirm_box(true))
  474. {
  475. $sql = 'INSERT INTO ' . DRAFTS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
  476. 'user_id' => $user->data['user_id'],
  477. 'topic_id' => 0,
  478. 'forum_id' => 0,
  479. 'save_time' => $current_time,
  480. 'draft_subject' => $subject,
  481. 'draft_message' => $message
  482. )
  483. );
  484. $db->sql_query($sql);
  485. $redirect_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&amp;mode=$mode");
  486. meta_refresh(3, $redirect_url);
  487. $message = $user->lang['DRAFT_SAVED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $redirect_url . '">', '</a>');
  488. trigger_error($message);
  489. }
  490. else
  491. {
  492. $s_hidden_fields = build_hidden_fields(array(
  493. 'mode' => $mode,
  494. 'action' => $action,
  495. 'save' => true,
  496. 'subject' => $subject,
  497. 'message' => $message,
  498. 'u' => $to_user_id,
  499. 'g' => $to_group_id,
  500. 'p' => $msg_id)
  501. );
  502. $s_hidden_fields .= build_address_field($address_list);
  503. confirm_box(false, 'SAVE_DRAFT', $s_hidden_fields);
  504. }
  505. }
  506. else
  507. {
  508. if (utf8_clean_string($subject) === '')
  509. {
  510. $error[] = $user->lang['EMPTY_MESSAGE_SUBJECT'];
  511. }
  512. if (utf8_clean_string($message) === '')
  513. {
  514. $error[] = $user->lang['TOO_FEW_CHARS'];
  515. }
  516. }
  517. unset($subject, $message);
  518. }
  519. // Load Draft
  520. if ($draft_id && $auth->acl_get('u_savedrafts'))
  521. {
  522. $sql = 'SELECT draft_subject, draft_message
  523. FROM ' . DRAFTS_TABLE . "
  524. WHERE draft_id = $draft_id
  525. AND topic_id = 0
  526. AND forum_id = 0
  527. AND user_id = " . $user->data['user_id'];
  528. $result = $db->sql_query_limit($sql, 1);
  529. if ($row = $db->sql_fetchrow($result))
  530. {
  531. $message_parser->message = $row['draft_message'];
  532. $message_subject = $row['draft_subject'];
  533. $template->assign_var('S_DRAFT_LOADED', true);
  534. }
  535. else
  536. {
  537. $draft_id = 0;
  538. }
  539. $db->sql_freeresult($result);
  540. }
  541. // Load Drafts
  542. if ($load && $drafts)
  543. {
  544. load_drafts(0, 0, $id, $action, $msg_id);
  545. }
  546. if ($submit || $preview || $refresh)
  547. {
  548. if (($submit || $preview) && !check_form_key('ucp_pm_compose'))
  549. {
  550. $error[] = $user->lang['FORM_INVALID'];
  551. }
  552. $subject = utf8_normalize_nfc(request_var('subject', '', true));
  553. $message_parser->message = utf8_normalize_nfc(request_var('message', '', true));
  554. $icon_id = request_var('icon', 0);
  555. $enable_bbcode = (!$bbcode_status || isset($_POST['disable_bbcode'])) ? false : true;
  556. $enable_smilies = (!$smilies_status || isset($_POST['disable_smilies'])) ? false : true;
  557. $enable_urls = (isset($_POST['disable_magic_url'])) ? 0 : 1;
  558. $enable_sig = (!$config['allow_sig'] ||!$config['allow_sig_pm']) ? false : ((isset($_POST['attach_sig'])) ? true : false);
  559. if ($submit)
  560. {
  561. $status_switch = (($enable_bbcode+1) << 8) + (($enable_smilies+1) << 4) + (($enable_urls+1) << 2) + (($enable_sig+1) << 1);
  562. $status_switch = ($status_switch != $check_value);
  563. }
  564. else
  565. {
  566. $status_switch = 1;
  567. }
  568. // Parse Attachments - before checksum is calculated
  569. $message_parser->parse_attachments('fileupload', $action, 0, $submit, $preview, $refresh, true);
  570. if (sizeof($message_parser->warn_msg) && !($remove_u || $remove_g || $add_to || $add_bcc))
  571. {
  572. $error[] = implode('<br />', $message_parser->warn_msg);
  573. $message_parser->warn_msg = array();
  574. }
  575. // Parse message
  576. $message_parser->parse($enable_bbcode, ($config['allow_post_links']) ? $enable_urls : false, $enable_smilies, $img_status, $flash_status, true, $config['allow_post_links']);
  577. // On a refresh we do not care about message parsing errors
  578. if (sizeof($message_parser->warn_msg) && !$refresh)
  579. {
  580. $error[] = implode('<br />', $message_parser->warn_msg);
  581. }
  582. if ($action != 'edit' && !$preview && !$refresh && $config['flood_interval'] && !$auth->acl_get('u_ignoreflood'))
  583. {
  584. // Flood check
  585. $last_post_time = $user->data['user_lastpost_time'];
  586. if ($last_post_time)
  587. {
  588. if ($last_post_time && ($current_time - $last_post_time) < intval($config['flood_interval']))
  589. {
  590. $error[] = $user->lang['FLOOD_ERROR'];
  591. }
  592. }
  593. }
  594. // Subject defined
  595. if ($submit)
  596. {
  597. if (utf8_clean_string($subject) === '')
  598. {
  599. $error[] = $user->lang['EMPTY_MESSAGE_SUBJECT'];
  600. }
  601. if (!sizeof($address_list))
  602. {
  603. $error[] = $user->lang['NO_RECIPIENT'];
  604. }
  605. }
  606. // START Anti-Spam ACP
  607. if (!sizeof($error) && $config['asacp_spam_words_pm_action'] && antispam::spam_words(array($subject, $message_parser->message)))
  608. {
  609. $user->add_lang('mods/asacp');
  610. antispam::add_log('LOG_SPAM_PM_DENIED', array($subject, $message_parser->message));
  611. $error[] = $user->lang['SPAM_DENIED'];
  612. }
  613. if (!sizeof($error) && $config['asacp_akismet_pm_action'] && antispam::akismet($message_parser->message))
  614. {
  615. $user->add_lang('mods/asacp');
  616. antispam::add_log('LOG_SPAM_PM_DENIED_AKISMET', array($subject, $message_parser->message));
  617. $error[] = $user->lang['SPAM_DENIED'];
  618. }
  619. if (!sizeof($error) && $submit && $user->data['user_flagged'])
  620. {
  621. antispam::add_log('LOG_SENT_PM', array('pm' => $address_list), 'flag');
  622. }
  623. // END Anti-Spam ACP
  624. // Store message, sync counters
  625. if (!sizeof($error) && $submit)
  626. {
  627. $pm_data = array(
  628. 'msg_id' => (int) $msg_id,
  629. 'from_user_id' => $user->data['user_id'],
  630. 'from_user_ip' => $user->ip,
  631. 'from_username' => $user->data['username'],
  632. 'reply_from_root_level' => (isset($post['root_level'])) ? (int) $post['root_level'] : 0,
  633. 'reply_from_msg_id' => (int) $msg_id,
  634. 'icon_id' => (int) $icon_id,
  635. 'enable_sig' => (bool) $enable_sig,
  636. 'enable_bbcode' => (bool) $enable_bbcode,
  637. 'enable_smilies' => (bool) $enable_smilies,
  638. 'enable_urls' => (bool) $enable_urls,
  639. 'bbcode_bitfield' => $message_parser->bbcode_bitfield,
  640. 'bbcode_uid' => $message_parser->bbcode_uid,
  641. 'message' => $message_parser->message,
  642. 'attachment_data' => $message_parser->attachment_data,
  643. 'filename_data' => $message_parser->filename_data,
  644. 'address_list' => $address_list
  645. );
  646. // ((!$message_subject) ? $subject : $message_subject)
  647. $msg_id = submit_pm($action, $subject, $pm_data);
  648. $return_message_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=view&amp;p=' . $msg_id);
  649. $inbox_folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=inbox');
  650. $outbox_folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=outbox');
  651. $folder_url = '';
  652. if (($folder_id > 0) && isset($user_folders[$folder_id]))
  653. {
  654. $folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=' . $folder_id);
  655. }
  656. $return_box_url = ($action === 'post' || $action === 'edit') ? $outbox_folder_url : $inbox_folder_url;
  657. $return_box_lang = ($action === 'post' || $action === 'edit') ? 'PM_OUTBOX' : 'PM_INBOX';
  658. $message = $user->lang['MESSAGE_STORED'] . '<br /><br />' . sprintf($user->lang['VIEW_PRIVATE_MESSAGE'], '<a href="' . $return_message_url . '">', '</a>');
  659. $last_click_type = 'CLICK_RETURN_FOLDER';
  660. if ($folder_url)
  661. {
  662. $message .= '<br /><br />' . sprintf($user->lang['CLICK_RETURN_FOLDER'], '<a href="' . $folder_url . '">', '</a>', $user_folders[$folder_id]['folder_name']);
  663. $last_click_type = 'CLICK_GOTO_FOLDER';
  664. }
  665. $message .= '<br /><br />' . sprintf($user->lang[$last_click_type], '<a href="' . $return_box_url . '">', '</a>', $user->lang[$return_box_lang]);
  666. meta_refresh(3, $return_message_url);
  667. trigger_error($message);
  668. }
  669. $message_subject = $subject;
  670. }
  671. // Preview
  672. if (!sizeof($error) && $preview)
  673. {
  674. $preview_message = $message_parser->format_display($enable_bbcode, $enable_urls, $enable_smilies, false);
  675. $preview_signature = $user->data['user_sig'];
  676. $preview_signature_uid = $user->data['user_sig_bbcode_uid'];
  677. $preview_signature_bitfield = $user->data['user_sig_bbcode_bitfield'];
  678. // Signature
  679. if ($enable_sig && $config['allow_sig'] && $preview_signature)
  680. {
  681. $parse_sig = new parse_message($preview_signature);
  682. $parse_sig->bbcode_uid = $preview_signature_uid;
  683. $parse_sig->bbcode_bitfield = $preview_signature_bitfield;
  684. $parse_sig->format_display($config['allow_sig_bbcode'], $config['allow_sig_links'], $config['allow_sig_smilies']);
  685. $preview_signature = $parse_sig->message;
  686. unset($parse_sig);
  687. }
  688. else
  689. {
  690. $preview_signature = '';
  691. }
  692. // Attachment Preview
  693. if (sizeof($message_parser->attachment_data))
  694. {
  695. $template->assign_var('S_HAS_ATTACHMENTS', true);
  696. $update_count = array();
  697. $attachment_data = $message_parser->attachment_data;
  698. parse_attachments(false, $preview_message, $attachment_data, $update_count, true);
  699. foreach ($attachment_data as $i => $attachment)
  700. {
  701. $template->assign_block_vars('attachment', array(
  702. 'DISPLAY_ATTACHMENT' => $attachment)
  703. );
  704. }
  705. unset($attachment_data);
  706. }
  707. $preview_subject = censor_text($subject);
  708. if (!sizeof($error))
  709. {
  710. $template->assign_vars(array(
  711. 'PREVIEW_SUBJECT' => $preview_subject,
  712. 'PREVIEW_MESSAGE' => $preview_message,
  713. 'PREVIEW_SIGNATURE' => $preview_signature,
  714. 'S_DISPLAY_PREVIEW' => true)
  715. );
  716. }
  717. unset($message_text);
  718. }
  719. // Decode text for message display
  720. $bbcode_uid = (($action == 'quote' || $action == 'forward') && !$preview && !$refresh && (!sizeof($error) || (sizeof($error) && !$submit))) ? $bbcode_uid : $message_parser->bbcode_uid;
  721. $message_parser->decode_message($bbcode_uid);
  722. if (($action == 'quote' || $action == 'quotepost') && !$preview && !$refresh && !$submit)
  723. {
  724. if ($action == 'quotepost')
  725. {
  726. $post_id = request_var('p', 0);
  727. if ($config['allow_post_links'])
  728. {
  729. $message_link = "[url=" . generate_board_url() . "/viewtopic.$phpEx?p={$post_id}#p{$post_id}]{$user->lang['SUBJECT']}: {$message_subject}[/url]\n\n";
  730. }
  731. else
  732. {
  733. $message_link = $user->lang['SUBJECT'] . ': ' . $message_subject . " (" . generate_board_url() . "/viewtopic.$phpEx?p={$post_id}#p{$post_id})\n\n";
  734. }
  735. }
  736. else
  737. {
  738. $message_link = '';
  739. }
  740. $message_parser->message = $message_link . '[quote=&quot;' . $quote_username . '&quot;]' . censor_text(trim($message_parser->message)) . "[/quote]\n";
  741. }
  742. if (($action == 'reply' || $action == 'quote' || $action == 'quotepost') && !$preview && !$refresh)
  743. {
  744. $message_subject = ((!preg_match('/^Re:/', $message_subject)) ? 'Re: ' : '') . censor_text($message_subject);
  745. }
  746. if ($action == 'forward' && !$preview && !$refresh && !$submit)
  747. {
  748. $fwd_to_field = write_pm_addresses(array('to' => $post['to_address']), 0, true);
  749. if ($config['allow_post_links'])
  750. {
  751. $quote_username_text = '[url=' . generate_board_url() . "/memberlist.$phpEx?mode=viewprofile&amp;u={$post['author_id']}]{$quote_username}[/url]";
  752. }
  753. else
  754. {
  755. $quote_username_text = $quote_username . ' (' . generate_board_url() . "/memberlist.$phpEx?mode=viewprofile&amp;u={$post['author_id']})";
  756. }
  757. $forward_text = array();
  758. $forward_text[] = $user->lang['FWD_ORIGINAL_MESSAGE'];
  759. $forward_text[] = sprintf($user->lang['FWD_SUBJECT'], censor_text($message_subject));
  760. $forward_text[] = sprintf($user->lang['FWD_DATE'], $user->format_date($message_time, false, true));
  761. $forward_text[] = sprintf($user->lang['FWD_FROM'], $quote_username_text);
  762. $forward_text[] = sprintf($user->lang['FWD_TO'], implode(', ', $fwd_to_field['to']));
  763. $message_parser->message = implode("\n", $forward_text) . "\n\n[quote=&quot;{$quote_username}&quot;]\n" . censor_text(trim($message_parser->message)) . "\n[/quote]";
  764. $message_subject = ((!preg_match('/^Fwd:/', $message_subject)) ? 'Fwd: ' : '') . censor_text($message_subject);
  765. }
  766. $attachment_data = $message_parser->attachment_data;
  767. $filename_data = $message_parser->filename_data;
  768. $message_text = $message_parser->message;
  769. // MAIN PM PAGE BEGINS HERE
  770. // Generate smiley listing
  771. generate_smilies('inline', 0);
  772. // Generate PM Icons
  773. $s_pm_icons = false;
  774. if ($config['enable_pm_icons'])
  775. {
  776. $s_pm_icons = posting_gen_topic_icons($action, $icon_id);
  777. }
  778. // Generate inline attachment select box
  779. posting_gen_inline_attachments($attachment_data);
  780. // Build address list for display
  781. // array('u' => array($author_id => 'to'));
  782. if (sizeof($address_list))
  783. {
  784. // Get Usernames and Group Names
  785. $result = array();
  786. if (!empty($address_list['u']))
  787. {
  788. $sql = 'SELECT user_id as id, username as name, user_colour as colour
  789. FROM ' . USERS_TABLE . '
  790. WHERE ' . $db->sql_in_set('user_id', array_map('intval', array_keys($address_list['u']))) . '
  791. ORDER BY username_clean ASC';
  792. $result['u'] = $db->sql_query($sql);
  793. }
  794. if (!empty($address_list['g']))
  795. {
  796. $sql = 'SELECT g.group_id AS id, g.group_name AS name, g.group_colour AS colour, g.group_type
  797. FROM ' . GROUPS_TABLE . ' g';
  798. if (!$auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel'))
  799. {
  800. $sql .= ' LEFT JOIN ' . USER_GROUP_TABLE . ' ug
  801. ON (
  802. g.group_id = ug.group_id
  803. AND ug.user_id = ' . $user->data['user_id'] . '
  804. AND ug.user_pending = 0
  805. )
  806. WHERE (g.group_type <> ' . GROUP_HIDDEN . ' OR ug.user_id = ' . $user->data['user_id'] . ')';
  807. }
  808. $sql .= ($auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel')) ? ' WHERE ' : ' AND ';
  809. $sql .= 'g.group_receive_pm = 1
  810. AND ' . $db->sql_in_set('g.group_id', array_map('intval', array_keys($address_list['g']))) . '
  811. ORDER BY g.group_name ASC';
  812. $result['g'] = $db->sql_query($sql);
  813. }
  814. $u = $g = array();
  815. $_types = array('u', 'g');
  816. foreach ($_types as $type)
  817. {
  818. if (isset($result[$type]) && $result[$type])
  819. {
  820. while ($row = $db->sql_fetchrow($result[$type]))
  821. {
  822. if ($type == 'g')
  823. {
  824. $row['name'] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['name']] : $row['name'];
  825. }
  826. ${$type}[$row['id']] = array('name' => $row['name'], 'colour' => $row['colour']);
  827. }
  828. $db->sql_freeresult($result[$type]);
  829. }
  830. }
  831. // Now Build the address list
  832. $plain_address_field = '';
  833. foreach ($address_list as $type => $adr_ary)
  834. {
  835. foreach ($adr_ary as $id => $field)
  836. {
  837. if (!isset(${$type}[$id]))
  838. {
  839. unset($address_list[$type][$id]);
  840. continue;
  841. }
  842. $field = ($field == 'to') ? 'to' : 'bcc';
  843. $type = ($type == 'u') ? 'u' : 'g';
  844. $id = (int) $id;
  845. $tpl_ary = array(
  846. 'IS_GROUP' => ($type == 'g') ? true : false,
  847. 'IS_USER' => ($type == 'u') ? true : false,
  848. 'UG_ID' => $id,
  849. 'NAME' => ${$type}[$id]['name'],
  850. 'COLOUR' => (${$type}[$id]['colour']) ? '#' . ${$type}[$id]['colour'] : '',
  851. 'TYPE' => $type,
  852. );
  853. if ($type == 'u')
  854. {
  855. $tpl_ary = array_merge($tpl_ary, array(
  856. 'U_VIEW' => get_username_string('profile', $id, ${$type}[$id]['name'], ${$type}[$id]['colour']),
  857. 'NAME_FULL' => get_username_string('full', $id, ${$type}[$id]['name'], ${$type}[$id]['colour']),
  858. ));
  859. }
  860. else
  861. {
  862. $tpl_ary = array_merge($tpl_ary, array(
  863. 'U_VIEW' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group&amp;g=' . $id),
  864. ));
  865. }
  866. $template->assign_block_vars($field . '_recipient', $tpl_ary);
  867. }
  868. }
  869. }
  870. // Build hidden address list
  871. $s_hidden_address_field = build_address_field($address_list);
  872. $bbcode_checked = (isset($enable_bbcode)) ? !$enable_bbcode : (($config['allow_bbcode'] && $auth->acl_get('u_pm_bbcode')) ? !$user->optionget('bbcode') : 1);
  873. $smilies_checked = (isset($enable_smilies)) ? !$enable_smilies : (($config['allow_smilies'] && $auth->acl_get('u_pm_smilies')) ? !$user->optionget('smilies') : 1);
  874. $urls_checked = (isset($enable_urls)) ? !$enable_urls : 0;
  875. $sig_checked = $enable_sig;
  876. switch ($action)
  877. {
  878. case 'post':
  879. $page_title = $user->lang['POST_NEW_PM'];
  880. break;
  881. case 'quote':
  882. $page_title = $user->lang['POST_QUOTE_PM'];
  883. break;
  884. case 'quotepost':
  885. $page_title = $user->lang['POST_PM_POST'];
  886. break;
  887. case 'reply':
  888. $page_title = $user->lang['POST_REPLY_PM'];
  889. break;
  890. case 'edit':
  891. $page_title = $user->lang['POST_EDIT_PM'];
  892. break;
  893. case 'forward':
  894. $page_title = $user->lang['POST_FORWARD_PM'];
  895. break;
  896. default:
  897. trigger_error('NO_ACTION_MODE', E_USER_ERROR);
  898. break;
  899. }
  900. $s_hidden_fields = '<input type="hidden" name="lastclick" value="' . $current_time . '" />';
  901. $s_hidden_fields .= (isset($check_value)) ? '<input type="hidden" name="status_switch" value="' . $check_value . '" />' : '';
  902. $s_hidden_fields .= ($draft_id || isset($_REQUEST['draft_loaded'])) ? '<input type="hidden" name="draft_loaded" value="' . ((isset($_REQUEST['draft_loaded'])) ? intval($_REQUEST['draft_loaded']) : $draft_id) . '" />' : '';
  903. $form_enctype = (@ini_get('file_uploads') == '0' || strtolower(@ini_get('file_uploads')) == 'off' || !$config['allow_pm_attach'] || !$auth->acl_get('u_pm_attach')) ? '' : ' enctype="multipart/form-data"';
  904. // Start assigning vars for main posting page ...
  905. $template->assign_vars(array(
  906. 'L_POST_A' => $page_title,
  907. 'L_ICON' => $user->lang['PM_ICON'],
  908. 'L_MESSAGE_BODY_EXPLAIN' => (intval($config['max_post_chars'])) ? sprintf($user->lang['MESSAGE_BODY_EXPLAIN'], intval($config['max_post_chars'])) : '',
  909. 'SUBJECT' => (isset($message_subject)) ? $message_subject : '',
  910. 'MESSAGE' => $message_text,
  911. 'BBCODE_STATUS' => ($bbcode_status) ? sprintf($user->lang['BBCODE_IS_ON'], '<a href="' . append_sid("{$phpbb_root_path}faq.$phpEx", 'mode=bbcode') . '">', '</a>') : sprintf($user->lang['BBCODE_IS_OFF'], '<a href="' . append_sid("{$phpbb_root_path}faq.$phpEx", 'mode=bbcode') . '">', '</a>'),
  912. 'IMG_STATUS' => ($img_status) ? $user->lang['IMAGES_ARE_ON'] : $user->lang['IMAGES_ARE_OFF'],
  913. 'FLASH_STATUS' => ($flash_status) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'],
  914. 'SMILIES_STATUS' => ($smilies_status) ? $user->lang['SMILIES_ARE_ON'] : $user->lang['SMILIES_ARE_OFF'],
  915. 'URL_STATUS' => ($url_status) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'],
  916. 'MAX_FONT_SIZE' => (int) $config['max_post_font_size'],
  917. 'MINI_POST_IMG' => $user->img('icon_post_target', $user->lang['PM']),
  918. 'ERROR' => (sizeof($error)) ? implode('<br />', $error) : '',
  919. 'MAX_RECIPIENTS' => ($config['allow_mass_pm'] && ($auth->acl_get('u_masspm') || $auth->acl_get('u_masspm_group'))) ? $max_recipients : 0,
  920. 'S_COMPOSE_PM' => true,
  921. 'S_EDIT_POST' => ($action == 'edit'),
  922. 'S_SHOW_PM_ICONS' => $s_pm_icons,
  923. 'S_BBCODE_ALLOWED' => ($bbcode_status) ? 1 : 0,
  924. 'S_BBCODE_CHECKED' => ($bbcode_checked) ? ' checked="checked"' : '',
  925. 'S_SMILIES_ALLOWED' => $smilies_status,
  926. 'S_SMILIES_CHECKED' => ($smilies_checked) ? ' checked="checked"' : '',
  927. 'S_SIG_ALLOWED' => ($config['allow_sig'] && $config['allow_sig_pm'] && $auth->acl_get('u_sig')),
  928. 'S_SIGNATURE_CHECKED' => ($sig_checked) ? ' checked="checked"' : '',
  929. 'S_LINKS_ALLOWED' => $url_status,
  930. 'S_MAGIC_URL_CHECKED' => ($urls_checked) ? ' checked="checked"' : '',
  931. 'S_SAVE_ALLOWED' => ($auth->acl_get('u_savedrafts') && $action != 'edit') ? true : false,
  932. 'S_HAS_DRAFTS' => ($auth->acl_get('u_savedrafts') && $drafts),
  933. 'S_FORM_ENCTYPE' => $form_enctype,
  934. 'S_BBCODE_IMG' => $img_status,
  935. 'S_BBCODE_FLASH' => $flash_status,
  936. 'S_BBCODE_QUOTE' => true,
  937. 'S_BBCODE_URL' => $url_status,
  938. 'S_POST_ACTION' => $s_action,
  939. 'S_HIDDEN_ADDRESS_FIELD' => $s_hidden_address_field,
  940. 'S_HIDDEN_FIELDS' => $s_hidden_fields,
  941. 'S_CLOSE_PROGRESS_WINDOW' => isset($_POST['add_file']),
  942. 'U_PROGRESS_BAR' => append_sid("{$phpbb_root_path}posting.$phpEx", 'f=0&amp;mode=popup'),
  943. 'UA_PROGRESS_BAR' => addslashes(append_sid("{$phpbb_root_path}posting.$phpEx", 'f=0&amp;mode=popup')),
  944. ));
  945. // Build custom bbcodes array
  946. display_custom_bbcodes();
  947. // Show attachment box for adding attachments if true
  948. $allowed = ($auth->acl_get('u_pm_attach') && $config['allow_pm_attach'] && $form_enctype);
  949. // Attachment entry
  950. posting_gen_attachment_entry($attachment_data, $filename_data, $allowed);
  951. // Message History
  952. if ($action == 'reply' || $action == 'quote' || $action == 'forward')
  953. {
  954. if (message_history($msg_id, $user->data['user_id'], $post, array(), true))
  955. {
  956. $template->assign_var('S_DISPLAY_HISTORY', true);
  957. }
  958. }
  959. }
  960. /**
  961. * For composing messages, handle list actions
  962. */
  963. function handle_message_list_actions(&$address_list, &$error, $remove_u, $remove_g, $add_to, $add_bcc)
  964. {
  965. global $auth, $db, $user;
  966. // Delete User [TO/BCC]
  967. if ($remove_u && !empty($_REQUEST['remove_u']) && is_array($_REQUEST['remove_u']))
  968. {
  969. $remove_user_id = array_keys($_REQUEST['remove_u']);
  970. if (isset($remove_user_id[0]))
  971. {
  972. unset($address_list['u'][(int) $remove_user_id[0]]);
  973. }
  974. }
  975. // Delete Group [TO/BCC]
  976. if ($remove_g && !empty($_REQUEST['remove_g']) && is_array($_REQUEST['remove_g']))
  977. {
  978. $remove_group_id = array_keys($_REQUEST['remove_g']);
  979. if (isset($remove_group_id[0]))
  980. {
  981. unset($address_list['g'][(int) $remove_group_id[0]]);
  982. }
  983. }
  984. // Add Selected Groups
  985. $group_list = request_var('group_list', array(0));
  986. // Build usernames to add
  987. $usernames = request_var('username', '', true);
  988. $usernames = (empty($usernames)) ? array() : array($usernames);
  989. $username_list = request_var('username_list', '', true);
  990. if ($username_list)
  991. {
  992. $usernames = array_merge($usernames, explode("\n", $username_list));
  993. }
  994. // If add to or add bcc not pressed, users could still have usernames listed they want to add...
  995. if (!$add_to && !$add_bcc && (sizeof($group_list) || sizeof($usernames)))
  996. {
  997. $add_to = true;
  998. global $refresh, $submit, $preview;
  999. $refresh = true;
  1000. $submit = false;
  1001. // Preview is only true if there was also a message entered
  1002. if (request_var('message', ''))
  1003. {
  1004. $preview = true;
  1005. }
  1006. }
  1007. // Add User/Group [TO]
  1008. if ($add_to || $add_bcc)
  1009. {
  1010. $type = ($add_to) ? 'to' : 'bcc';
  1011. if (sizeof($group_list))
  1012. {
  1013. foreach ($group_list as $group_id)
  1014. {
  1015. $address_list['g'][$group_id] = $type;
  1016. }
  1017. }
  1018. // User ID's to add...
  1019. $user_id_ary = array();
  1020. // Reveal the correct user_ids
  1021. if (sizeof($usernames))
  1022. {
  1023. $user_id_ary = array();
  1024. user_get_id_name($user_id_ary, $usernames, array(USER_NORMAL, USER_FOUNDER, USER_INACTIVE));
  1025. // If there are users not existing, we will at least print a notice...
  1026. if (!sizeof($user_id_ary))
  1027. {
  1028. $error[] = $user->lang['PM_NO_USERS'];
  1029. }
  1030. }
  1031. // Add Friends if specified
  1032. $friend_list = (isset($_REQUEST['add_' . $type]) && is_array($_REQUEST['add_' . $type])) ? array_map('intval', array_keys($_REQUEST['add_' . $type])) : array();
  1033. $user_id_ary = array_merge($user_id_ary, $friend_list);
  1034. foreach ($user_id_ary as $user_id)
  1035. {
  1036. if ($user_id == ANONYMOUS)
  1037. {
  1038. continue;
  1039. }
  1040. $address_list['u'][$user_id] = $type;
  1041. }
  1042. }
  1043. // Check for disallowed recipients
  1044. if (!empty($address_list['u']))
  1045. {
  1046. // We need to check their PM status (do they want to receive PM's?)
  1047. // Only check if not a moderator or admin, since they are allowed to override this user setting
  1048. if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
  1049. {
  1050. $sql = 'SELECT user_id
  1051. FROM ' . USERS_TABLE . '
  1052. WHERE ' . $db->sql_in_set('user_id', array_keys($address_list['u'])) . '
  1053. AND user_allow_pm = 0';
  1054. $result = $db->sql_query($sql);
  1055. $removed = false;
  1056. while ($row = $db->sql_fetchrow($result))
  1057. {
  1058. $removed = true;
  1059. unset($address_list['u'][$row['user_id']]);
  1060. }
  1061. $db->sql_freeresult($result);
  1062. // print a notice about users not being added who do not want to receive pms
  1063. if ($removed)
  1064. {
  1065. $error[] = $user->lang['PM_USERS_REMOVED_NO_PM'];
  1066. }
  1067. }
  1068. }
  1069. }
  1070. /**
  1071. * Build the hidden field for the recipients. Needed, as the variable is not read via request_var.
  1072. */
  1073. function build_address_field($address_list)
  1074. {
  1075. $s_hidden_address_field = '';
  1076. foreach ($address_list as $type => $adr_ary)
  1077. {
  1078. foreach ($adr_ary as $id => $field)
  1079. {
  1080. $s_hidden_address_field .= '<input type="hidden" name="address_list[' . (($type == 'u') ? 'u' : 'g') . '][' . (int) $id . ']" value="' . (($field == 'to') ? 'to' : 'bcc') . '" />';
  1081. }
  1082. }
  1083. return $s_hidden_address_field;
  1084. }
  1085. /**
  1086. * Return number of private message recipients
  1087. */
  1088. function num_recipients($address_list)
  1089. {
  1090. $num_recipients = 0;
  1091. foreach ($address_list as $field => $adr_ary)
  1092. {
  1093. $num_recipients += sizeof($adr_ary);
  1094. }
  1095. return $num_recipients;
  1096. }
  1097. /**
  1098. * Get number of 'num_recipients' recipients from first position
  1099. */
  1100. function get_recipients($address_list, $num_recipients = 1)
  1101. {
  1102. $recipient = array();
  1103. $count = 0;
  1104. foreach ($address_list as $field => $adr_ary)
  1105. {
  1106. foreach ($adr_ary as $id => $type)
  1107. {
  1108. if ($count >= $num_recipients)
  1109. {
  1110. break 2;
  1111. }
  1112. $recipient[$field][$id] = $type;
  1113. $count++;
  1114. }
  1115. }
  1116. return $recipient;
  1117. }
  1118. ?>