PageRenderTime 66ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/campsite/src/include/phorum/pm.php

https://github.com/joechrysler/Campsite
PHP | 966 lines | 618 code | 183 blank | 165 comment | 151 complexity | 8f7e44f7d93f8f97d4f6c9f6deef7a0b MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, LGPL-2.1, Apache-2.0
  1. <?php
  2. ////////////////////////////////////////////////////////////////////////////////
  3. // //
  4. // Copyright (C) 2006 Phorum Development Team //
  5. // http://www.phorum.org //
  6. // //
  7. // This program is free software. You can redistribute it and/or modify //
  8. // it under the terms of either the current Phorum License (viewable at //
  9. // phorum.org) or the Phorum License that was distributed with this file //
  10. // //
  11. // This program is distributed in the hope that it will be useful, //
  12. // but WITHOUT ANY WARRANTY, without even the implied warranty of //
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. //
  14. // //
  15. // You should have received a copy of the Phorum License //
  16. // along with this program. //
  17. ////////////////////////////////////////////////////////////////////////////////
  18. // These language strings are set dynamically, so the language
  19. // tool won't recognize them automatically. Therefore they are
  20. // mentioned here.
  21. // $PHORUM["DATA"]["LANG"]["PMFolderCreateSuccess"]
  22. // $PHORUM["DATA"]["LANG"]["PMFolderRenameSuccess"]
  23. // $PHORUM["DATA"]["LANG"]["PMFolderDeleteSuccess"]
  24. // $PHORUM["DATA"]["LANG"]["PMSent"]
  25. // PMTODO If reading from a mail notify, lookup the folder_id,
  26. // so the close button will work. Now the folder_id is empty.
  27. // PMTODO implement pm_reply_flag functionality
  28. define('phorum_page','pm');
  29. include_once("./common.php");
  30. phorum_require_login();
  31. // set all our common URL's
  32. phorum_build_common_urls();
  33. include_once("./include/email_functions.php");
  34. include_once("./include/format_functions.php");
  35. // a user has to be logged in to use the private messages system
  36. if (!$PHORUM["DATA"]["LOGGEDIN"]) {
  37. phorum_redirect_by_url(phorum_get_url(PHORUM_LIST_URL));
  38. exit();
  39. }
  40. // if the user is not fully logged in, send him to the login page
  41. if (!$PHORUM["DATA"]["FULLY_LOGGEDIN"]) {
  42. // Construct the URL to redirect to after logging in.
  43. $args = array(PHORUM_PM_URL);
  44. foreach ($PHORUM["args"] as $k => $v) {
  45. if (in_array("$k=$v", $PHORUM["DATA"]["GET_VARS"])) continue;
  46. if(is_numeric($k)) $args[] = $v; else $args[] = "$k=$v";
  47. }
  48. $redir = urlencode(call_user_func_array('phorum_get_url', $args));
  49. phorum_redirect_by_url(phorum_get_url(PHORUM_LOGIN_URL, "redir=$redir"));
  50. exit();
  51. }
  52. // If private messages are disabled, just show a simple error message.
  53. if (! $PHORUM["enable_pm"]) {
  54. $PHORUM["DATA"]["BLOCK_CONTENT"] = $PHORUM["DATA"]["LANG"]["PMDisabled"];
  55. include phorum_get_template("header");
  56. phorum_hook("after_header");
  57. include phorum_get_template("stdblock");
  58. phorum_hook("before_footer");
  59. include phorum_get_template("footer");
  60. return;
  61. }
  62. // ------------------------------------------------------------------------
  63. // Parameter handling
  64. // ------------------------------------------------------------------------
  65. // Retrieve a parameter from either the args-list or $_POST.
  66. function phorum_getparam($name)
  67. {
  68. $PHORUM = $GLOBALS["PHORUM"];
  69. $ret = NULL;
  70. if (isset($PHORUM["args"][$name])) {
  71. $ret = trim($PHORUM["args"][$name]);
  72. }elseif (isset($_POST[$name])) {
  73. $ret = trim($_POST[$name]);
  74. }
  75. return $ret;
  76. }
  77. // Get basic parameters.
  78. $action = phorum_getparam('action');
  79. $page = phorum_getparam('page');
  80. $folder_id = phorum_getparam('folder_id');
  81. $pm_id = phorum_getparam('pm_id');
  82. $forum_id = $PHORUM["forum_id"];
  83. $user_id = $PHORUM["user"]["user_id"];
  84. $hide_userselect = phorum_getparam('hide_userselect');
  85. // Get recipients from the form and create a valid list of recipients.
  86. $recipients = array();
  87. if (isset($_POST["recipients"]) && is_array($_POST["recipients"])) {
  88. foreach ($_POST["recipients"] as $id => $username) {
  89. $user = phorum_user_get($id, false);
  90. if ($user) {
  91. $recipients[$id] = $user;
  92. }
  93. }
  94. }
  95. // init error var
  96. $error_msg = "";
  97. // ------------------------------------------------------------------------
  98. // Banlist checking
  99. // ------------------------------------------------------------------------
  100. // Start editor Post message Post reply
  101. if ($page == 'send' || $action == 'post' || ($action == 'list' && isset($pm_id)))
  102. {
  103. include_once("./include/profile_functions.php");
  104. $error = phorum_check_bans(array(
  105. array($PHORUM["user"]["username"], PHORUM_BAD_NAMES),
  106. array($PHORUM["user"]["email"], PHORUM_BAD_EMAILS),
  107. array($user_id, PHORUM_BAD_USERID),
  108. array(NULL, PHORUM_BAD_IPS),
  109. ));
  110. // Show an error in case we encountered a ban.
  111. if (! empty($error)) {
  112. $PHORUM["DATA"]["ERROR"] = $error;
  113. include phorum_get_template("header");
  114. phorum_hook("after_header");
  115. include phorum_get_template("message");
  116. phorum_hook("before_footer");
  117. include phorum_get_template("footer");
  118. return;
  119. }
  120. }
  121. // ------------------------------------------------------------------------
  122. // Perform actions
  123. // ------------------------------------------------------------------------
  124. // Initialize error and ok message.
  125. $error = '';
  126. $okmsg = '';
  127. // init folder list
  128. $pm_folders = phorum_db_pm_getfolders(NULL, true);
  129. // Translate button clicks from the read page to appropriate actions.
  130. if (isset($_POST['close_message'])) {
  131. $page = 'list';
  132. } elseif (isset($_POST['delete_message'])) {
  133. $page = 'list';
  134. $_POST['delete'] = 1;
  135. $_POST['checked'] = array($pm_id);
  136. $action = 'list';
  137. } elseif (isset($_POST['move_message'])) {
  138. $page = 'list';
  139. $_POST['move'] = 1;
  140. $_POST['checked'] = array($pm_id);
  141. $action = 'list';
  142. } elseif (isset($_POST['reply']) || isset($_POST['reply_to_all'])) {
  143. $page = 'send';
  144. $action = '';
  145. }
  146. if (!empty($action)) {
  147. // Utility function to check if a foldername already exists.
  148. // No extreme checking with locking here. Technically
  149. // speaking duplicate foldernames will work. It's just
  150. // confusing for the user.
  151. function phorum_pm_folder_exists($foldername)
  152. {
  153. global $pm_folders;
  154. foreach ($pm_folders as $id => $data) {
  155. if (strcasecmp($foldername, $data["name"]) == 0) {
  156. return true;
  157. }
  158. }
  159. return false;
  160. }
  161. // Redirect will be set to a true value if after performing
  162. // the action we want to use a redirect to get to the
  163. // result page. This is done for two reasons:
  164. // 1) Let the result page use refreshed PM data;
  165. // 2) Prevent reloading of the action page (which could for
  166. // example result in duplicate message sending).
  167. // The variable $redirect_message can be set to a language
  168. // key string to have a message displayed after redirection.
  169. $redirect = false;
  170. $redirect_message = '';
  171. switch($action) {
  172. // Actions which are triggered from the folder management interface.
  173. case "folders":
  174. $redirect = false;
  175. $page = "folders";
  176. // Create folder.
  177. if (!empty($_POST['create_folder']))
  178. {
  179. $foldername = trim($_POST["create_folder_name"]);
  180. if ($foldername != '')
  181. {
  182. if (phorum_pm_folder_exists($foldername)) {
  183. $error = $PHORUM["DATA"]["LANG"]["PMFolderExistsError"];
  184. } else {
  185. phorum_db_pm_create_folder($foldername);
  186. $redirect_message = "PMFolderCreateSuccess";
  187. $redirect = true;
  188. }
  189. }
  190. }
  191. // Rename a folder.
  192. elseif (!empty($_POST['rename_folder']))
  193. {
  194. $from = $_POST['rename_folder_from'];
  195. $to = trim($_POST['rename_folder_to']);
  196. if (!empty($from) && $to != '') {
  197. if (phorum_pm_folder_exists($to)) {
  198. $error = $PHORUM["DATA"]["LANG"]["PMFolderExistsError"];
  199. } else {
  200. phorum_db_pm_rename_folder($from, $to);
  201. $redirect_message = "PMFolderRenameSuccess";
  202. $redirect = true;
  203. }
  204. }
  205. }
  206. // Delete a folder.
  207. elseif (!empty($_POST['delete_folder']))
  208. {
  209. $folder_id = $_POST["delete_folder_target"];
  210. if (!empty($folder_id)) {
  211. phorum_db_pm_delete_folder($folder_id);
  212. $redirect_message = "PMFolderDeleteSuccess";
  213. $redirect = true;
  214. // Invalidate user cache, to update message counts.
  215. phorum_cache_remove('user',$user_id);
  216. }
  217. }
  218. break;
  219. // Actions which are triggered from the list interface.
  220. case "list":
  221. // Delete all checked messages.
  222. if (isset($_POST["delete"]) && isset($_POST["checked"])) {
  223. foreach($_POST["checked"] as $pm_id) {
  224. if (phorum_db_pm_get($pm_id, $folder_id)) {
  225. phorum_db_pm_delete($pm_id, $folder_id);
  226. }
  227. }
  228. // Invalidate user cache, to update message counts.
  229. phorum_cache_remove('user',$user_id);
  230. }
  231. // Move checked messages to another folder.
  232. elseif (isset($_POST["move"]) && isset($_POST["checked"])) {
  233. $to = $_POST['target_folder'];
  234. if (! empty($to)) {
  235. foreach($_POST["checked"] as $pm_id) {
  236. if (phorum_db_pm_get($pm_id, $folder_id)) {
  237. phorum_db_pm_move($pm_id, $folder_id, $to);
  238. }
  239. }
  240. }
  241. }
  242. $page = "list";
  243. $redirect = true;
  244. break;
  245. // Actions which are triggered from the post form.
  246. case "post":
  247. // Parse clicks on the image buttons that we use for
  248. // deleting recipients from the list of recipients.
  249. // These are not sent as name=value, but instead
  250. // name_x=xclickoffset and name_y=yclickoffset are sent.
  251. // Also accept normal button clicks with name="del_rcpt::<id>",
  252. // so template builders can use that.
  253. $del_rcpt = NULL;
  254. foreach ($_POST as $key => $val) {
  255. if (preg_match('/^del_rcpt::(\d+)(_x)?$/', $key, $m)) {
  256. $del_rcpt = $m[1];
  257. break;
  258. }
  259. }
  260. // Determine what action to perform.
  261. $action = "post";
  262. if (isset($_POST["preview"])) $action = "preview";
  263. if (isset($_POST["rcpt_add"])) $action = "rcpt_add";
  264. if (!is_null($del_rcpt)) $action = "del_rcpt";
  265. // Adding a recipient.
  266. if ($action == "rcpt_add" || $action == "preview" || $action == "post") {
  267. // Convert adding a recipient by name to adding by user id.
  268. if (isset($_POST["to_name"])) {
  269. $to_name = trim($_POST["to_name"]);
  270. if ($to_name != '') {
  271. $to_user_id = phorum_db_user_check_field('username', $to_name);
  272. if ($to_user_id) {
  273. $_POST["to_id"] = $to_user_id;
  274. unset($_POST["to_name"]);
  275. } else {
  276. $error = $PHORUM["DATA"]["LANG"]["UserNotFound"];
  277. }
  278. }
  279. }
  280. // Add a recipient by id.
  281. if (isset($_POST["to_id"]) && is_numeric($_POST["to_id"])) {
  282. $user = phorum_user_get($_POST["to_id"], false);
  283. if ($user) {
  284. $recipients[$user["user_id"]] = $user;
  285. }
  286. }
  287. $page = "send";
  288. // Deleting a recipient.
  289. } elseif ($action == "del_rcpt") {
  290. unset($recipients[$del_rcpt]);
  291. $page = "send";
  292. // When deleting a recipient, we always have to
  293. // show the user selection. Put it back in, for
  294. // situations where we had the user selection
  295. // hidden intentionally.
  296. $hide_userselect = 0;
  297. }
  298. // For previewing the message, no action has to be taken.
  299. if ($action == "preview") {
  300. $page = "send";
  301. }
  302. // Posting the message.
  303. elseif ($action == "post") {
  304. // Only send the message if we have at least one recipient.
  305. if (count($recipients)) {
  306. $_POST["subject"] = trim($_POST["subject"]);
  307. $_POST["message"] = trim($_POST["message"]);
  308. // Only send the message if all required message data is filled in.
  309. if ($_POST["subject"] == '' || $_POST["message"] == '') {
  310. $error = $PHORUM["DATA"]["LANG"]["PMRequiredFields"];
  311. // Message data is okay. Post the message.
  312. } else {
  313. if (empty($_POST["keep"])) $_POST["keep"] = 0;
  314. // Check if sender and recipients have not yet reached the
  315. // maximum number of messages that may be stored on the server.
  316. // Administrators may always send PM.
  317. if (!$PHORUM['user']['admin'] && $PHORUM['max_pm_messagecount'])
  318. {
  319. // Build a list of users to check.
  320. $checkusers = $recipients;
  321. if ($_POST['keep']) $checkusers[] = $PHORUM['user'];
  322. // Check all users.
  323. foreach ($checkusers as $user)
  324. {
  325. if ($user['admin']) continue; // No limits for admins
  326. $current_count = phorum_db_pm_messagecount(PHORUM_PM_ALLFOLDERS, $user["user_id"]);
  327. if ($current_count['total'] >= $PHORUM['max_pm_messagecount']) {
  328. if ($user['user_id'] == $PHORUM["user"]["user_id"]) {
  329. $error = $PHORUM["DATA"]["LANG"]["PMFromMailboxFull"];
  330. } else {
  331. $error = $PHORUM["DATA"]["LANG"]["PMToMailboxFull"];
  332. $error = str_replace('%recipient%', htmlspecialchars($user["username"]), $error);
  333. }
  334. }
  335. }
  336. }
  337. // Send the private message if no errors occurred.
  338. if (empty($error)) {
  339. $pm_message_id = phorum_db_pm_send($_POST["subject"], $_POST["message"], array_keys($recipients), NULL, $_POST["keep"]);
  340. // Show an error in case of problems.
  341. if (! $pm_message_id) {
  342. $error = $PHORUM["DATA"]["LANG"]["PMNotSent"];
  343. // Do e-mail notifications on successful sending.
  344. } else {
  345. include_once("./include/email_functions.php");
  346. $pm_message = array(
  347. 'pm_message_id' => $pm_message_id,
  348. 'subject' => $_POST['subject'],
  349. 'message' => $_POST['message'],
  350. 'from_username' => $PHORUM['user']['username'],
  351. 'from_user_id' => $user_id,
  352. );
  353. // Sort all recipients that want a notify by language.
  354. $langrcpts = array();
  355. foreach ($recipients as $rcpt_id => $rcpt) {
  356. if ($rcpt["pm_email_notify"]) {
  357. if (!isset($langrcpts[$rcpt["user_language"]])) {
  358. $langrcpts[$rcpt["user_language"]] = array($rcpt);
  359. } else {
  360. $langrcpts[$rcpt["user_language"]][] = $rcpt;
  361. }
  362. }
  363. }
  364. phorum_email_pm_notice($pm_message, $langrcpts);
  365. phorum_hook("pm_sent", $pm_message);
  366. }
  367. }
  368. // Invalidate user cache, to update message counts.
  369. phorum_cache_remove('user', $user_id);
  370. foreach ($recipients as $rcpt) {
  371. phorum_cache_remove('user', $rcpt["user_id"]);
  372. }
  373. $redirect_message = "PMSent";
  374. }
  375. } else {
  376. $error = $PHORUM["DATA"]["LANG"]["PMNoRecipients"];
  377. }
  378. // Stay on the post page in case of errors. Redirect on success.
  379. if ($error) {
  380. $page = "send";
  381. } else {
  382. $redirect = true;
  383. }
  384. }
  385. break;
  386. // Actions that are triggered from the buddy list.
  387. case "buddies":
  388. // Delete all checked buddies.
  389. if (isset($_POST["delete"]) && isset($_POST["checked"])) {
  390. foreach($_POST["checked"] as $buddy_user_id) {
  391. phorum_db_pm_buddy_delete($buddy_user_id);
  392. phorum_hook("buddy_delete", $buddy_user_id);
  393. }
  394. }
  395. // Send a PM to the checked buddies.
  396. if (isset($_POST["send_pm"]) && isset($_POST["checked"])) {
  397. $pm_rcpts = $_POST["checked"];
  398. if (count($pm_rcpts)) {
  399. $redirect = true;
  400. $page = "send";
  401. } else {
  402. unset($pm_rcpts);
  403. }
  404. }
  405. break;
  406. // Add a user to this user's buddy list.
  407. case "addbuddy":
  408. $buddy_user_id = $PHORUM["args"]["addbuddy_id"];
  409. if (!empty($buddy_user_id)) {
  410. if (phorum_db_pm_buddy_add($buddy_user_id)) {
  411. $okmsg = $PHORUM["DATA"]["LANG"]["BuddyAddSuccess"];
  412. phorum_hook("buddy_add", $buddy_user_id);
  413. } else {
  414. $error = $PHORUM["DATA"]["LANG"]["BuddyAddFail"];
  415. }
  416. }
  417. break;
  418. default:
  419. die("Unhandled action for pm.php: " . htmlspecialchars($action));
  420. }
  421. // The action has been completed successfully.
  422. // Redirect the user to the result page.
  423. if ($redirect)
  424. {
  425. $args = array(
  426. PHORUM_PM_URL,
  427. "page=" . $page,
  428. "folder_id=" . $folder_id,
  429. );
  430. if (isset($pm_rcpts)) $args[] = "to_id=" . implode(':', $pm_rcpts);
  431. if (!empty($pm_id)) $args[] = "pm_id=" . $pm_id;
  432. if (!empty($redirect_message)) $args[] = "okmsg=" . $redirect_message;
  433. $redir_url = call_user_func_array('phorum_get_url', $args);
  434. phorum_redirect_by_url($redir_url);
  435. exit();
  436. }
  437. }
  438. // ------------------------------------------------------------------------
  439. // Display a PM page
  440. // ------------------------------------------------------------------------
  441. // Use the message list as the default page.
  442. if (!$page){
  443. $page = "list";
  444. $folder_id = PHORUM_PM_INBOX;
  445. }
  446. // Show an OK message for a redirected page?
  447. $okmsg_id = phorum_getparam('okmsg');
  448. if ($okmsg_id && isset($PHORUM["DATA"]["LANG"][$okmsg_id])) {
  449. $okmsg = $PHORUM["DATA"]["LANG"][$okmsg_id];
  450. }
  451. // Make error and OK messages available in the template.
  452. $PHORUM["DATA"]["ERROR"] = (empty($error)) ? "" : $error;
  453. $PHORUM["DATA"]["OKMSG"] = (empty($okmsg)) ? "" : $okmsg;
  454. switch ($page) {
  455. // Manage the PM folders.
  456. case "folders":
  457. $PHORUM["DATA"]["CREATE_FOLDER_NAME"] = isset($_POST["create_folder_name"]) ? htmlspecialchars($_POST["create_folder_name"]) : '';
  458. $PHORUM["DATA"]["RENAME_FOLDER_NAME"] = isset($_POST["rename_folder_name"]) ? htmlspecialchars($_POST["rename_folder_name"]) : '';
  459. $template = "pm_folders";
  460. break;
  461. // Manage the buddies.
  462. case "buddies":
  463. // Retrieve a list of users that are buddies for the current user.
  464. $buddy_list = phorum_db_pm_buddy_list(NULL, true);
  465. if (count($buddy_list)) {
  466. $buddy_users = phorum_user_get(array_keys($buddy_list), false);
  467. $buddy_users = phorum_hook("read_user_info", $buddy_users);
  468. } else {
  469. $buddy_users = array();
  470. }
  471. // Sort the buddies by username.
  472. function phorum_sort_buddy_list($a,$b) {
  473. return strcasecmp($a["username"], $b["username"]);
  474. }
  475. uasort($buddy_users, 'phorum_sort_buddy_list');
  476. $buddies = array();
  477. foreach ($buddy_users as $id => $buddy_user) {
  478. $buddy = array(
  479. 'user_id' => $id,
  480. 'profile_url' => phorum_get_url(PHORUM_PROFILE_URL, $buddy_user["user_id"]),
  481. 'username' => htmlspecialchars($buddy_user["username"]),
  482. 'real_name' => isset($buddy_user["real_name"]) ? htmlspecialchars($buddy_user["real_name"]) : '',
  483. 'mutual' => $buddy_list[$id]["mutual"],
  484. );
  485. if (!$buddy_user['hide_activity']) {
  486. $buddy["date_last_active"] = phorum_date($PHORUM["short_date"], $buddy_user["date_last_active"]);
  487. } else {
  488. $buddy["date_last_active"] = "-";
  489. }
  490. $buddies[$id] = $buddy;
  491. }
  492. $PHORUM["DATA"]["USERTRACK"] = $PHORUM["track_user_activity"];
  493. $PHORUM["DATA"]["BUDDIES"] = $buddies;
  494. $PHORUM["DATA"]["BUDDYCOUNT"] = count($buddies);
  495. $PHORUM["DATA"]["PMLOCATION"] = $PHORUM["DATA"]["LANG"]["Buddies"];
  496. $template = "pm_buddies";
  497. break;
  498. // Show a listing of messages in a folder.
  499. case "list":
  500. // Check if the folder exists for the user.
  501. if (! isset($pm_folders[$folder_id])) {
  502. $PHORUM["DATA"]["BLOCK_CONTENT"] = $PHORUM["DATA"]["LANG"]["PMFolderNotAvailable"];
  503. $template = "stdblock";
  504. } else {
  505. $list = phorum_db_pm_list($folder_id);
  506. // Prepare data for the templates (formatting and XSS prevention).
  507. $list = phorum_pm_format($list);
  508. foreach ($list as $message_id => $message)
  509. {
  510. $list[$message_id]["from_profile_url"] = phorum_get_url(PHORUM_PROFILE_URL, $message["from_user_id"]);
  511. $list[$message_id]["read_url"]=phorum_get_url(PHORUM_PM_URL, "page=read", "folder_id=$folder_id", "pm_id=$message_id");
  512. $list[$message_id]["date"] = phorum_date($PHORUM["short_date"], $message["datestamp"]);
  513. $list[$message_id]["recipient_count"] = count($message["recipients"]);
  514. $receive_count = 0;
  515. foreach ($message["recipients"] as $rcpt_id => $rcpt) {
  516. if ($rcpt["read_flag"]) $receive_count++;
  517. $list[$message_id]["recipients"][$rcpt_id]["username"] = htmlspecialchars($rcpt["username"]);
  518. $list[$message_id]["recipients"][$rcpt_id]["to_profile_url"] = phorum_get_url(PHORUM_PROFILE_URL, $rcpt_id);
  519. }
  520. $list[$message_id]["receive_count"] = $receive_count;
  521. }
  522. // Setup template variables.
  523. $PHORUM["DATA"]["MESSAGECOUNT"] = count($list);
  524. $PHORUM["DATA"]["MESSAGES"] = $list;
  525. $PHORUM["DATA"]["PMLOCATION"] = $pm_folders[$folder_id]["name"];
  526. $template = "pm_list";
  527. }
  528. break;
  529. // Read a single private message.
  530. case "read":
  531. if (($message=phorum_db_pm_get($pm_id, $folder_id))) {
  532. // Mark the message read.
  533. if (! $message['read_flag']) {
  534. phorum_db_pm_setflag($message["pm_message_id"], PHORUM_PM_READ_FLAG, true);
  535. // Invalidate user cache, to update message counts.
  536. phorum_cache_remove('user',$user_id);
  537. }
  538. // Run the message through the default message formatting.
  539. list($message) = phorum_pm_format(array($message));
  540. // Setup data for recipients.
  541. foreach ($message["recipients"] as $rcpt_id => $rcpt) {
  542. $message["recipients"][$rcpt_id]["username"] = htmlspecialchars($rcpt["username"]);
  543. $message["recipients"][$rcpt_id]["to_profile_url"] = phorum_get_url(PHORUM_PROFILE_URL, $rcpt_id);
  544. }
  545. $message["recipient_count"] = count($message["recipients"]);
  546. // Setup URL's and format date.
  547. $message["from_profile_url"]=phorum_get_url(PHORUM_PROFILE_URL, $message["from_user_id"]);
  548. $message["date"]=phorum_date($PHORUM["short_date"], $message["datestamp"]);
  549. $PHORUM["DATA"]["MESSAGE"] = $message;
  550. $PHORUM["DATA"]["PMLOCATION"] = $PHORUM["DATA"]["LANG"]["PMRead"];
  551. // re-init folder list to account for change in read flags
  552. $pm_folders = phorum_db_pm_getfolders(NULL, true);
  553. // Set folder id to the right folder for this message.
  554. $folder_id = $message["pm_folder_id"];
  555. if ($folder_id == 0) {
  556. $folder_id = $message["special_folder"];
  557. }
  558. $template = "pm_read";
  559. } else {
  560. // The message was not found. Show an error.
  561. $PHORUM["DATA"]["BLOCK_CONTENT"] = $PHORUM["DATA"]["LANG"]["PMNotAvailable"];
  562. $template = "stdblock";
  563. }
  564. break;
  565. // Post a new private message.
  566. case "send":
  567. // Setup the default array with the message data.
  568. $msg = array(
  569. "from_username" => $PHORUM["user"]["username"],
  570. "keep" => isset($_POST["keep"]) && $_POST["keep"] ? 1 : 0,
  571. "subject" => isset($_POST["subject"]) ? $_POST["subject"] : '',
  572. "message" => isset($_POST["message"]) ? $_POST["message"] : '',
  573. "preview" => isset($_POST["preview"]) ? 1 : 0,
  574. "recipients" => $recipients,
  575. );
  576. // Data initialization for posting messages on first request.
  577. if ($action == NULL || $action != 'post')
  578. {
  579. // Setup data for sending a private message to specified recipients.
  580. // Recipients are passed on as a standard phorum argument "to_id"
  581. // containing a colon separated list of users.
  582. if (isset($PHORUM["args"]["to_id"])) {
  583. foreach (explode(":", $PHORUM["args"]["to_id"]) as $rcpt_id) {
  584. settype($rcpt_id, "int");
  585. $user = phorum_user_get($rcpt_id, false);
  586. if ($user) {
  587. $msg["recipients"][$rcpt_id] = array(
  588. "username" => $user["username"],
  589. "user_id" => $user["user_id"]
  590. );
  591. }
  592. }
  593. $hide_userselect = 1;
  594. // Setup data for replying to a private message.
  595. } elseif (isset($pm_id)) {
  596. $message = phorum_db_pm_get($pm_id);
  597. $msg["subject"] = $message["subject"];
  598. $msg["message"] = $message["message"];
  599. $msg["recipients"][$message["from_user_id"]] = array(
  600. "username" => $message["from_username"],
  601. "user_id" => $message["from_user_id"]
  602. );
  603. $msg = phorum_pm_quoteformat($message["from_username"], $msg);
  604. // Include the other recipient, excecpt the active
  605. // user himself, when replying to all.
  606. if (isset($_POST["reply_to_all"])) {
  607. foreach($message["recipients"] as $rcpt) {
  608. if ($user_id == $rcpt["user_id"]) continue;
  609. $msg["recipients"][$rcpt["user_id"]] = array(
  610. "username" => $rcpt["username"],
  611. "user_id" => $rcpt["user_id"],
  612. );
  613. }
  614. }
  615. $hide_userselect = 1;
  616. // Setup data for replying privately to a forum post.
  617. } elseif (isset($PHORUM["args"]["message_id"])) {
  618. $message = phorum_db_get_message($PHORUM["args"]["message_id"], "message_id", true);
  619. if (phorum_user_access_allowed(PHORUM_USER_ALLOW_READ) && ($PHORUM["forum_id"]==$message["forum_id"] || $message["forum_id"] == 0)) {
  620. // get url to the message board thread
  621. $origurl = phorum_get_url(PHORUM_READ_URL, $message["thread"], $message["message_id"]);
  622. // Find the real username, because some mods rewrite the
  623. // username in the message table. There will be a better solution
  624. // for selecting recipients, but for now this will fix some
  625. // of the problems.
  626. $user = phorum_user_get($message["user_id"], false);
  627. $msg["subject"] = $message["subject"];
  628. $msg["message"] = $message["body"];
  629. $msg["recipients"][$message["user_id"]] = array(
  630. 'username' => $user["username"],
  631. 'user_id' => $user["user_id"]
  632. );
  633. $msg = phorum_pm_quoteformat($user["username"], $msg, $origurl);
  634. }
  635. $hide_userselect = 1;
  636. }
  637. }
  638. // Setup data for previewing a message.
  639. if ($msg["preview"]) {
  640. list($preview) = phorum_pm_format(array($msg));
  641. $PHORUM["DATA"]["PREVIEW"] = $preview;
  642. }
  643. // XSS prevention.
  644. foreach ($msg as $key => $val) {
  645. switch ($key) {
  646. case "recipients": {
  647. foreach ($val as $id => $data) {
  648. $msg[$key][$id]["username"] = htmlspecialchars($data["username"]);
  649. }
  650. break;
  651. }
  652. default: {
  653. $msg[$key] = htmlspecialchars($val);
  654. break;
  655. }
  656. }
  657. }
  658. $PHORUM["DATA"]["MESSAGE"] = $msg;
  659. $PHORUM["DATA"]["RECIPIENT_COUNT"] = count($msg["recipients"]);
  660. $PHORUM["DATA"]["SHOW_USERSELECTION"] = true;
  661. // Determine what input element gets the focus.
  662. $focus_id = 'userselection';
  663. if ($PHORUM["DATA"]["RECIPIENT_COUNT"]) $focus_id = 'subject';
  664. if (!empty($msg["subject"])) $focus_id = 'message';
  665. $PHORUM["DATA"]["FOCUS_TO_ID"] = $focus_id;
  666. // Create data for a user dropdown list, if configured.
  667. if ($PHORUM["DATA"]["SHOW_USERSELECTION"] && $PHORUM["enable_dropdown_userlist"])
  668. {
  669. $allusers = array();
  670. $userlist = phorum_user_get_list();
  671. foreach ($userlist as $user_id => $userinfo){
  672. if (isset($msg["recipients"][$user_id])) continue;
  673. $userinfo["displayname"] = htmlspecialchars($userinfo["displayname"]);
  674. $userinfo["username"] = htmlspecialchars($userinfo["username"]);
  675. $userinfo["user_id"] = $user_id;
  676. $allusers[] = $userinfo;
  677. }
  678. $PHORUM["DATA"]["USERS"] = $allusers;
  679. if (count($allusers) == 0) $PHORUM["DATA"]["SHOW_USERSELECTION"] = false;
  680. }
  681. $PHORUM["DATA"]["PMLOCATION"] = $PHORUM["DATA"]["LANG"]["SendPM"];
  682. $template = "pm_post";
  683. break;
  684. }
  685. if ($hide_userselect) {
  686. $PHORUM["DATA"]["SHOW_USERSELECTION"] = 0;
  687. }
  688. // Make message count and quota information available in the templates.
  689. $PHORUM['DATA']['MAX_PM_MESSAGECOUNT'] = 0;
  690. if (! $PHORUM['user']['admin']) {
  691. $PHORUM['DATA']['MAX_PM_MESSAGECOUNT'] = $PHORUM['SETTINGS']['max_pm_messagecount'];
  692. if ($PHORUM['SETTINGS']['max_pm_messagecount'])
  693. {
  694. $current_count = phorum_db_pm_messagecount(PHORUM_PM_ALLFOLDERS);
  695. $PHORUM['DATA']['PM_MESSAGECOUNT'] = $current_count['total'];
  696. $space_left = $PHORUM['SETTINGS']['max_pm_messagecount'] - $current_count['total'];
  697. if ($space_left < 0) $space_left = 0;
  698. $PHORUM['DATA']['PM_SPACE_LEFT'] = $space_left;
  699. $PHORUM['DATA']['LANG']['PMSpaceLeft'] = str_replace('%pm_space_left%', $space_left, $PHORUM['DATA']['LANG']['PMSpaceLeft']);
  700. }
  701. }
  702. // Make a list of folders for use in the menu and a list of folders that
  703. // the user created. The latter will be set to zero if no user folders
  704. // are available.
  705. $pm_userfolders = array();
  706. foreach($pm_folders as $id => $data)
  707. {
  708. $pm_folders[$id]["is_special"] = is_numeric($id) ? 0 : 1;
  709. $pm_folders[$id]["is_outgoing"] = $id == PHORUM_PM_OUTBOX;
  710. $pm_folders[$id]["id"] = $id;
  711. $pm_folders[$id]["name"] = htmlspecialchars($data["name"]);
  712. $pm_folders[$id]["url"] = phorum_get_url(PHORUM_PM_URL, "page=list", "folder_id=$id");
  713. if (!$pm_folders[$id]["is_special"]) {
  714. $pm_userfolders[$id] = $pm_folders[$id];
  715. }
  716. }
  717. $PHORUM["DATA"]["URL"]["PM_FOLDERS"] = phorum_get_url(PHORUM_PM_URL, "page=folders");
  718. $PHORUM["DATA"]["URL"]["PM_SEND"] = phorum_get_url(PHORUM_PM_URL, "page=send");
  719. $PHORUM["DATA"]["URL"]["BUDDIES"] = phorum_get_url(PHORUM_PM_URL, "page=buddies");
  720. $PHORUM["DATA"]["PM_FOLDERS"] = $pm_folders;
  721. $PHORUM["DATA"]["PM_USERFOLDERS"] = count($pm_userfolders) ? $pm_userfolders : 0;
  722. // Set some default template data.
  723. $PHORUM["DATA"]["ACTION"]=phorum_get_url( PHORUM_PM_ACTION_URL );
  724. $PHORUM["DATA"]["FOLDER_ID"] = $folder_id;
  725. $PHORUM["DATA"]["FOLDER_IS_INCOMING"] = $folder_id == PHORUM_PM_OUTBOX ? 0 : 1;
  726. $PHORUM["DATA"]["PM_PAGE"] = $page;
  727. $PHORUM["DATA"]["HIDE_USERSELECT"] = $hide_userselect;
  728. include phorum_get_template("header");
  729. phorum_hook("after_header");
  730. if ($error_msg) {
  731. $PHORUM["DATA"]["ERROR"] = $error_msg;
  732. unset($PHORUM["DATA"]["MESSAGE"]);
  733. include phorum_get_template("message");
  734. } else {
  735. include phorum_get_template("pm");
  736. }
  737. phorum_hook("before_footer");
  738. include phorum_get_template("footer");
  739. // ------------------------------------------------------------------------
  740. // Utility functions
  741. // ------------------------------------------------------------------------
  742. // Apply the default forum message formatting to a private message.
  743. function phorum_pm_format($messages)
  744. {
  745. include_once("./include/format_functions.php");
  746. // Reformat message so it looks like a forum message.
  747. foreach ($messages as $id => $message)
  748. {
  749. $messages[$id]["author"] = $message["from_username"];
  750. $messages[$id]["body"] = isset($message["message"]) ? $message["message"] : "";
  751. $messages[$id]["email"] = "";
  752. }
  753. // Run the messages through the formatting code.
  754. $messages = phorum_format_messages($messages);
  755. // Reformat message back to a private message.
  756. foreach ($messages as $id => $message)
  757. {
  758. $messages[$id]["message"] = $message["body"];
  759. $messages[$id]["from_username"] = $message["author"];
  760. unset($messages[$id]["body"]);
  761. unset($messages[$id]["author"]);
  762. }
  763. return $messages;
  764. }
  765. // Apply message reply quoting to a private message.
  766. function phorum_pm_quoteformat($orig_author, $message, $inreplyto = NULL)
  767. {
  768. $PHORUM = $GLOBALS["PHORUM"];
  769. // Build the reply subject.
  770. if (substr($message["subject"], 0, 3) != "Re:") {
  771. $message["subject"] = "Re: ".$message["subject"];
  772. }
  773. // Build a quoted version of the message body.
  774. $quote = phorum_strip_body($message["message"]);
  775. $quote = str_replace("\n", "\n> ", $quote);
  776. $quote = wordwrap(trim($quote), 50, "\n> ", true);
  777. $quote = ($inreplyto != NULL ? "{$PHORUM['DATA']['LANG']['InReplyTo']} {$inreplyto}\n" : '') .
  778. "$orig_author {$PHORUM['DATA']['LANG']['Wrote']}:\n" .
  779. str_repeat("-", 55)."\n> {$quote}\n\n\n";
  780. $message["message"] = $quote;
  781. return $message;
  782. }
  783. ?>