PageRenderTime 77ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/campsite/src/include/phorum/include/db/mysqli.php

https://github.com/joechrysler/Campsite
PHP | 4365 lines | 2669 code | 989 blank | 707 comment | 616 complexity | babc86766229084e746e4fdc4908e6b7 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. // cvs-info: $Id: mysqli.php 952 2006-03-23 22:08:59Z ts77 $
  19. if (!defined("PHORUM")) return;
  20. /**
  21. * The other Phorum code does not care how the messages are stored.
  22. * The only requirement is that they are returned from these functions
  23. * in the right way. This means each database can use as many or as
  24. * few tables as it likes. It can store the fields anyway it wants.
  25. * The only thing to worry about is the table_prefix for the tables.
  26. * all tables for a Phorum install should be prefixed with the
  27. * table_prefix that will be entered in include/db/config.php. This
  28. * will allow multiple Phorum installations to use the same database.
  29. */
  30. /**
  31. * These are the table names used for this database system.
  32. */
  33. // tables needed to be "partitioned"
  34. $PHORUM["message_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_messages";
  35. $PHORUM["user_newflags_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_user_newflags";
  36. $PHORUM["subscribers_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_subscribers";
  37. $PHORUM["files_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_files";
  38. $PHORUM["search_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_search";
  39. // tables common to all "partitions"
  40. $PHORUM["settings_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_settings";
  41. $PHORUM["forums_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_forums";
  42. $PHORUM["user_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_users";
  43. $PHORUM["user_permissions_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_user_permissions";
  44. $PHORUM["groups_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_groups";
  45. $PHORUM["forum_group_xref_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_forum_group_xref";
  46. $PHORUM["user_group_xref_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_user_group_xref";
  47. $PHORUM['user_custom_fields_table'] = "{$PHORUM['DBCONFIG']['table_prefix']}_user_custom_fields";
  48. $PHORUM["banlist_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_banlists";
  49. $PHORUM["pm_messages_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_pm_messages";
  50. $PHORUM["pm_folders_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_pm_folders";
  51. $PHORUM["pm_xref_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_pm_xref";
  52. $PHORUM["pm_buddies_table"] = "{$PHORUM['DBCONFIG']['table_prefix']}_pm_buddies";
  53. /*
  54. * fields which are always strings, even if they contain only numbers
  55. * used in post-message and update-message, otherwise strange things happen
  56. */
  57. $PHORUM['string_fields']= array('author', 'subject', 'body', 'email');
  58. /* A piece of SQL code that can be used for identifying moved messages. */
  59. define('PHORUM_SQL_MOVEDMESSAGES', '(parent_id = 0 and thread != message_id)');
  60. /**
  61. * This function executes a query to select the visible messages from
  62. * the database for a given page offset. The main Phorum code handles
  63. * actually sorting the threads into a threaded list if needed.
  64. *
  65. * By default, the message body is not included in the fetch queries.
  66. * If the body is needed in the thread list, $PHORUM['TMP']['bodies_in_list']
  67. * must be set to "1" (for example using setting.tpl).
  68. *
  69. * NOTE: ALL dates should be returned as Unix timestamps
  70. *
  71. * @param offset - the index of the page to return, starting with 0
  72. * @param messages - an array containing forum messages
  73. */
  74. function phorum_db_get_thread_list($offset)
  75. {
  76. $PHORUM = $GLOBALS["PHORUM"];
  77. settype($offset, "int");
  78. $conn = phorum_db_mysqli_connect();
  79. $table = $PHORUM["message_table"];
  80. // The messagefields that we want to fetch from the database.
  81. $messagefields =
  82. "$table.author,
  83. $table.datestamp,
  84. $table.email,
  85. $table.message_id,
  86. $table.meta,
  87. $table.moderator_post,
  88. $table.modifystamp,
  89. $table.parent_id,
  90. $table.sort,
  91. $table.status,
  92. $table.subject,
  93. $table.thread,
  94. $table.thread_count,
  95. $table.user_id,
  96. $table.viewcount,
  97. $table.closed";
  98. if(isset($PHORUM['TMP']['bodies_in_list']) && $PHORUM['TMP']['bodies_in_list'] == 1) {
  99. $messagefields .= "\n,$table.body";
  100. }
  101. // The sort mechanism to use.
  102. if($PHORUM["float_to_top"]){
  103. $sortfield = "modifystamp";
  104. $index = "list_page_float";
  105. } else{
  106. $sortfield = "thread";
  107. $index = "list_page_flat";
  108. }
  109. // Initialize the return array.
  110. $messages = array();
  111. // The groups of messages we want to fetch from the database.
  112. $groups = array();
  113. if ($offset == 0) $groups[] = "specials";
  114. $groups[] = "threads";
  115. if ($PHORUM["threaded_list"]) $groups[] = "replies";
  116. // for remembering message ids for which we want to fetch the replies.
  117. $replymsgids = array();
  118. // Process all groups.
  119. foreach ($groups as $group) {
  120. $sql = NULL;
  121. switch ($group) {
  122. // Announcements and stickies.
  123. case "specials":
  124. $sql = "select $messagefields
  125. from $table
  126. where
  127. status=".PHORUM_STATUS_APPROVED." and
  128. ((parent_id=0 and sort=".PHORUM_SORT_ANNOUNCEMENT."
  129. and forum_id={$PHORUM['vroot']})
  130. or
  131. (parent_id=0 and sort=".PHORUM_SORT_STICKY."
  132. and forum_id={$PHORUM['forum_id']}))
  133. order by
  134. sort, $sortfield desc";
  135. break;
  136. // Threads.
  137. case "threads":
  138. if ($PHORUM["threaded_list"]) {
  139. $limit = $PHORUM['list_length_threaded'];
  140. $extrasql = '';
  141. } else {
  142. $limit = $PHORUM['list_length_flat'];
  143. }
  144. $start = $offset * $limit;
  145. $sql = "select $messagefields
  146. from $table use index ($index)
  147. where
  148. $sortfield > 0 and
  149. forum_id = {$PHORUM["forum_id"]} and
  150. status = ".PHORUM_STATUS_APPROVED." and
  151. parent_id = 0 and
  152. sort > 1
  153. order by
  154. $sortfield desc
  155. limit $start, $limit";
  156. break;
  157. // Reply messages.
  158. case "replies":
  159. // We're done if we did not collect any messages with replies.
  160. if (! count($replymsgids)) break;
  161. $sortorder = "sort, $sortfield desc, message_id";
  162. if(isset($PHORUM["reverse_threading"]) && $PHORUM["reverse_threading"])
  163. $sortorder.=" desc";
  164. $sql = "select $messagefields
  165. from $table
  166. where
  167. status = ".PHORUM_STATUS_APPROVED." and
  168. thread in (" . implode(",",$replymsgids) .")
  169. order by $sortorder";
  170. break;
  171. } // End of switch ($group)
  172. // Continue with the next group if no SQL query was formulated.
  173. if (is_null($sql)) continue;
  174. // Fetch the messages for the current group.
  175. $res = mysqli_query($conn, $sql);
  176. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  177. $rows = mysqli_num_rows($res);
  178. if($rows > 0){
  179. while ($rec = mysqli_fetch_assoc($res)){
  180. $messages[$rec["message_id"]] = $rec;
  181. $messages[$rec["message_id"]]["meta"] = array();
  182. if(!empty($rec["meta"])){
  183. $messages[$rec["message_id"]]["meta"] = unserialize($rec["meta"]);
  184. }
  185. // We need the message ids for fetching reply messages.
  186. if ($group == 'threads' && $rec["thread_count"] > 1) {
  187. $replymsgids[] = $rec["message_id"];
  188. }
  189. }
  190. }
  191. }
  192. return $messages;
  193. }
  194. /**
  195. * This function executes a query to get the recent messages for
  196. * all forums the user can read, a particular forum, or a particular
  197. * thread, and and returns an array of the messages order by message_id.
  198. *
  199. * In reality, this function is not used in the Phorum core as of the time
  200. * of its creationg. However, several modules have been written that created
  201. * a function like this. Therefore, it has been added to aid in module development
  202. *
  203. * The bulk of this function came from Jim Winstead of mysql.com
  204. */
  205. function phorum_db_get_recent_messages($count, $forum_id = 0, $thread = 0, $threads_only = 0)
  206. {
  207. $PHORUM = $GLOBALS["PHORUM"];
  208. settype($count, "int");
  209. settype($forum_id, "int");
  210. settype($thread, "int");
  211. $arr = array();
  212. $conn = phorum_db_mysqli_connect();
  213. // we need to differentiate on which key to use
  214. // last_post_time is for sort by modifystamp
  215. // forum_max_message is for sort by message-id
  216. if($threads_only) {
  217. $use_key='last_post_time';
  218. } else {
  219. $use_key='post_count';
  220. }
  221. $sql = "SELECT {$PHORUM['message_table']}.* FROM {$PHORUM['message_table']} USE KEY($use_key) WHERE status=".PHORUM_STATUS_APPROVED;
  222. // have to check what forums they can read first.
  223. // even if $thread is passed, we have to make sure
  224. // the user can read the forum
  225. if($forum_id <= 0) {
  226. $allowed_forums=phorum_user_access_list(PHORUM_USER_ALLOW_READ);
  227. // if they are not allowed to see any forums, return the emtpy $arr;
  228. if(empty($allowed_forums))
  229. return $arr;
  230. } else {
  231. // only single forum, *much* fast this way
  232. if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_READ,$forum_id)) {
  233. return $arr;
  234. }
  235. }
  236. if($forum_id > 0){
  237. $sql.=" and forum_id=$forum_id";
  238. } else {
  239. $sql.=" and forum_id in (".implode(",", $allowed_forums).")";
  240. }
  241. if($thread){
  242. $sql.=" and thread=$thread";
  243. }
  244. if($threads_only) {
  245. $sql.= " and parent_id = 0";
  246. $sql.= " ORDER BY thread DESC";
  247. } else {
  248. $sql.= " ORDER BY message_id DESC";
  249. }
  250. if($count){
  251. $sql.= " LIMIT $count";
  252. }
  253. $res = mysqli_query($conn, $sql);
  254. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  255. while ($rec = mysqli_fetch_assoc($res)){
  256. $arr[$rec["message_id"]] = $rec;
  257. // convert meta field
  258. if(empty($rec["meta"])){
  259. $arr[$rec["message_id"]]["meta"]=array();
  260. } else {
  261. $arr[$rec["message_id"]]["meta"]=unserialize($rec["meta"]);
  262. }
  263. if(empty($arr['users'])) $arr['users']=array();
  264. if($rec["user_id"]){
  265. $arr['users'][]=$rec["user_id"];
  266. }
  267. }
  268. return $arr;
  269. }
  270. /**
  271. * This function executes a query to select messages from the database
  272. * and returns an array. The main Phorum code handles actually sorting
  273. * the threads into a threaded list if needed.
  274. *
  275. * NOTE: ALL dates should be returned as Unix timestamps
  276. * @param forum - the forum id to work with. Omit or NULL for all forums.
  277. * You can also pass an array of forum_id's.
  278. * @param waiting_only - only take into account messages which have to
  279. * be approved directly after posting. Do not include
  280. * messages which are hidden by a moderator.
  281. */
  282. function phorum_db_get_unapproved_list($forum = NULL, $waiting_only=false,$moddays=0)
  283. {
  284. $PHORUM = $GLOBALS["PHORUM"];
  285. $conn = phorum_db_mysqli_connect();
  286. $table = $PHORUM["message_table"];
  287. $arr = array();
  288. $sql = "select
  289. $table.*
  290. from
  291. $table ";
  292. if (is_array($forum)){
  293. $sql .= "where forum_id in (" . implode(",", $forum) . ") and ";
  294. } elseif (! is_null($forum)){
  295. settype($forum, "int");
  296. $sql .= "where forum_id = $forum and ";
  297. } else {
  298. $sql .= "where ";
  299. }
  300. if($moddays > 0) {
  301. $checktime=time()-(86400*$moddays);
  302. $sql .=" datestamp > $checktime AND";
  303. }
  304. if($waiting_only){
  305. $sql.=" status=".PHORUM_STATUS_HOLD;
  306. } else {
  307. $sql="($sql status=".PHORUM_STATUS_HOLD.") " .
  308. "union ($sql status=".PHORUM_STATUS_HIDDEN.")";
  309. }
  310. $sql .=" order by thread, message_id";
  311. $res = mysqli_query($conn, $sql);
  312. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  313. while ($rec = mysqli_fetch_assoc($res)){
  314. $arr[$rec["message_id"]] = $rec;
  315. $arr[$rec["message_id"]]["meta"] = array();
  316. if(!empty($rec["meta"])){
  317. $arr[$rec["message_id"]]["meta"] = unserialize($rec["meta"]);
  318. }
  319. }
  320. return $arr;
  321. }
  322. /**
  323. * This function posts a message to the tables.
  324. * The message is passed by reference and message_id and thread are filled
  325. */
  326. function phorum_db_post_message(&$message,$convert=false){
  327. $PHORUM = $GLOBALS["PHORUM"];
  328. $table = $PHORUM["message_table"];
  329. $conn = phorum_db_mysqli_connect();
  330. $success = false;
  331. foreach($message as $key => $value){
  332. if (is_numeric($value) && !in_array($key,$PHORUM['string_fields'])){
  333. $message[$key] = (int)$value;
  334. } elseif(is_array($value)) {
  335. $message[$key] = mysqli_real_escape_string ($conn, serialize($value));
  336. } else{
  337. $message[$key] = mysqli_real_escape_string ($conn, $value);
  338. }
  339. }
  340. if(!$convert) {
  341. $NOW = time();
  342. } else {
  343. $NOW = $message['datestamp'];
  344. }
  345. // duplicate-check
  346. if(isset($PHORUM['check_duplicate']) && $PHORUM['check_duplicate'] && !$convert) {
  347. // we check for dupes in that number of minutes
  348. $check_minutes=60;
  349. $check_timestamp =$NOW - ($check_minutes*60);
  350. // check_query
  351. $chk_query="SELECT message_id FROM $table WHERE forum_id = {$message['forum_id']} AND author='{$message['author']}' AND subject='{$message['subject']}' AND body='{$message['body']}' AND datestamp > $check_timestamp";
  352. $res = mysqli_query($conn, $chk_query);
  353. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $chk_query");
  354. if(mysqli_num_rows($res))
  355. return 0;
  356. }
  357. if(isset($message['meta'])){
  358. $metaval=",meta='{$message['meta']}'";
  359. } else {
  360. $metaval="";
  361. }
  362. $sql = "Insert into $table set
  363. forum_id = {$message['forum_id']},
  364. datestamp=$NOW,
  365. thread={$message['thread']},
  366. parent_id={$message['parent_id']},
  367. author='{$message['author']}',
  368. subject='{$message['subject']}',
  369. email='{$message['email']}',
  370. ip='{$message['ip']}',
  371. user_id={$message['user_id']},
  372. moderator_post={$message['moderator_post']},
  373. status={$message['status']},
  374. sort={$message['sort']},
  375. msgid='{$message['msgid']}',
  376. body='{$message['body']}',
  377. closed={$message['closed']}
  378. $metaval";
  379. // if in conversion we need the message-id too
  380. if($convert && isset($message['message_id'])) {
  381. $sql.=",message_id=".$message['message_id'];
  382. }
  383. if(isset($message['modifystamp'])) {
  384. $sql.=",modifystamp=".$message['modifystamp'];
  385. }
  386. if(isset($message['viewcount'])) {
  387. $sql.=",viewcount=".$message['viewcount'];
  388. }
  389. $res = mysqli_query($conn, $sql);
  390. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  391. if ($res){
  392. $message["message_id"] = mysqli_insert_id($conn);
  393. if(!empty($message["message_id"])){
  394. $message["datestamp"]=$NOW;
  395. if ($message["thread"] == 0){
  396. $message["thread"] = $message["message_id"];
  397. $sql = "update $table set thread={$message['message_id']} where message_id={$message['message_id']}";
  398. $res = mysqli_query($conn, $sql);
  399. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  400. }
  401. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  402. // start ft-search stuff
  403. $search_text="$message[author] | $message[subject] | $message[body]";
  404. $sql="insert delayed into {$PHORUM['search_table']} set message_id={$message['message_id']}, forum_id={$message['forum_id']}, search_text='$search_text'";
  405. $res = mysqli_query($conn, $sql);
  406. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  407. // end ft-search stuff
  408. $success = true;
  409. // some data for later use, i.e. email-notification
  410. $GLOBALS['PHORUM']['post_returns']['message_id']=$message["message_id"];
  411. $GLOBALS['PHORUM']['post_returns']['thread_id']=$message["thread"];
  412. }
  413. }
  414. return $success;
  415. }
  416. /**
  417. * This function deletes messages from the messages table.
  418. *
  419. * @param message $ _id the id of the message which should be deleted
  420. * mode the mode of deletion, PHORUM_DELETE_MESSAGE for reconnecting the children, PHORUM_DELETE_TREE for deleting the children
  421. */
  422. function phorum_db_delete_message($message_id, $mode = PHORUM_DELETE_MESSAGE)
  423. {
  424. $PHORUM = $GLOBALS["PHORUM"];
  425. $conn = phorum_db_mysqli_connect();
  426. settype($message_id, "int");
  427. $threadset = 0;
  428. // get the parents of the message to delete.
  429. $sql = "select forum_id, message_id, thread, parent_id from {$PHORUM['message_table']} where message_id = $message_id ";
  430. $res = mysqli_query( $conn, $sql);
  431. $rec = mysqli_fetch_assoc($res);
  432. if($mode == PHORUM_DELETE_TREE){
  433. $mids = phorum_db_get_messagetree($message_id, $rec['forum_id']);
  434. }else{
  435. $mids = $message_id;
  436. }
  437. // unapprove the messages first so replies will not get posted
  438. $sql = "update {$PHORUM['message_table']} set status=".PHORUM_STATUS_HOLD." where message_id in ($mids)";
  439. $res = mysqli_query($conn, $sql);
  440. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  441. $thread = $rec['thread'];
  442. if($thread == $message_id && $mode == PHORUM_DELETE_TREE){
  443. $threadset = 1;
  444. }else{
  445. $threadset = 0;
  446. }
  447. if($mode == PHORUM_DELETE_MESSAGE){
  448. $count = 1;
  449. // change the children to point to their parent's parent
  450. // forum_id is in here for speed by using a key only
  451. $sql = "update {$PHORUM['message_table']} set parent_id=$rec[parent_id] where forum_id=$rec[forum_id] and parent_id=$rec[message_id]";
  452. mysqli_query( $conn, $sql);
  453. }else{
  454. $count = count(explode(",", $mids));
  455. }
  456. // delete the messages
  457. $sql = "delete from {$PHORUM['message_table']} where message_id in ($mids)";
  458. mysqli_query( $conn, $sql);
  459. // start ft-search stuff
  460. $sql="delete from {$PHORUM['search_table']} where message_id in ($mids)";
  461. $res = mysqli_query( $conn, $sql);
  462. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  463. // end ft-search stuff
  464. // it kind of sucks to have this here, but it is the best way
  465. // to ensure that it gets done if stuff is deleted.
  466. // leave this include here, it needs to be conditional
  467. include_once("./include/thread_info.php");
  468. phorum_update_thread_info($thread);
  469. // we need to delete the subscriptions for that thread too
  470. $sql = "DELETE FROM {$PHORUM['subscribers_table']} WHERE forum_id > 0 AND thread=$thread";
  471. $res = mysqli_query( $conn, $sql);
  472. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  473. // this function will be slow with a lot of messages.
  474. phorum_db_update_forum_stats(true);
  475. return explode(",", $mids);
  476. }
  477. /**
  478. * gets all attached messages to a message
  479. *
  480. * @param id $ id of the message
  481. */
  482. function phorum_db_get_messagetree($parent_id, $forum_id){
  483. $PHORUM = $GLOBALS["PHORUM"];
  484. settype($parent_id, "int");
  485. settype($forum_id, "int");
  486. $conn = phorum_db_mysqli_connect();
  487. $sql = "Select message_id from {$PHORUM['message_table']} where forum_id=$forum_id and parent_id=$parent_id";
  488. $res = mysqli_query( $conn, $sql);
  489. $tree = "$parent_id";
  490. while($rec = mysqli_fetch_row($res)){
  491. $tree .= "," . phorum_db_get_messagetree($rec[0],$forum_id);
  492. }
  493. return $tree;
  494. }
  495. /**
  496. * This function updates the message given in the $message array for
  497. * the row with the given message id. It returns non 0 on success.
  498. */
  499. function phorum_db_update_message($message_id, $message)
  500. {
  501. $PHORUM = $GLOBALS["PHORUM"];
  502. settype($message_id, "int");
  503. if (count($message) > 0){
  504. $conn = phorum_db_mysqli_connect();
  505. foreach($message as $field => $value){
  506. if (is_numeric($value) && !in_array($field,$PHORUM['string_fields'])){
  507. $fields[] = "$field=$value";
  508. }elseif (is_array($value)){
  509. $value = mysqli_real_escape_string ($conn, serialize($value));
  510. $fields[] = "$field='$value'";
  511. $message[$field] = $value;
  512. }else{
  513. $value = mysqli_real_escape_string ($conn, $value);
  514. $fields[] = "$field='$value'";
  515. $message[$field] = $value;
  516. }
  517. }
  518. $sql = "update {$PHORUM['message_table']} set " . implode(", ", $fields) . " where message_id=$message_id";
  519. $res = mysqli_query( $conn, $sql);
  520. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  521. if($res){
  522. // start ft-search stuff
  523. if(isset($message["author"]) && isset($message["subject"]) && isset($message["body"])){
  524. $search_text="$message[author] | $message[subject] | $message[body]";
  525. $sql="replace delayed into {$PHORUM['search_table']} set message_id={$message_id}, forum_id={$message['forum_id']}, search_text='$search_text'";
  526. $res = mysqli_query( $conn, $sql);
  527. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  528. }
  529. // end ft-search stuff
  530. }
  531. return ($res > 0) ? true : false;
  532. }else{
  533. trigger_error("\$message cannot be empty in phorum_update_message()", E_USER_ERROR);
  534. }
  535. }
  536. /**
  537. * This function executes a query to get the row with the given value
  538. * in the given field and returns the message in an array.
  539. */
  540. function phorum_db_get_message($value, $field="message_id", $ignore_forum_id=false)
  541. {
  542. $PHORUM = $GLOBALS["PHORUM"];
  543. $conn = phorum_db_mysqli_connect();
  544. $field=mysqli_real_escape_string($conn, $field);
  545. $multiple=false;
  546. $forum_id_check = "";
  547. if (!$ignore_forum_id && !empty($PHORUM["forum_id"])){
  548. $forum_id_check = "(forum_id = {$PHORUM['forum_id']} OR forum_id={$PHORUM['vroot']}) and";
  549. }
  550. if(is_array($value)) {
  551. $checkvar="$field IN('".implode("','",$value)."')";
  552. $multiple=true;
  553. } else {
  554. $value=mysqli_real_escape_string( $conn, $value);
  555. $checkvar="$field='$value'";
  556. }
  557. $sql = "select {$PHORUM['message_table']}.* from {$PHORUM['message_table']} where $forum_id_check $checkvar";
  558. $res = mysqli_query( $conn, $sql);
  559. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  560. $ret = $multiple ? array() : NULL;
  561. if(mysqli_num_rows($res)){
  562. if($multiple) {
  563. while($rec=mysqli_fetch_assoc($res)) {
  564. // convert meta field
  565. if(empty($rec["meta"])){
  566. $rec["meta"]=array();
  567. } else {
  568. $rec["meta"]=unserialize($rec["meta"]);
  569. }
  570. $ret[$rec['message_id']]=$rec;
  571. }
  572. } else {
  573. $rec = mysqli_fetch_assoc($res);
  574. // convert meta field
  575. if(empty($rec["meta"])){
  576. $rec["meta"]=array();
  577. } else {
  578. $rec["meta"]=unserialize($rec["meta"]);
  579. }
  580. $ret=$rec;
  581. }
  582. }
  583. return $ret;
  584. }
  585. /**
  586. * This function executes a query to get the rows with the given thread
  587. * id and returns an array of the message.
  588. */
  589. function phorum_db_get_messages($thread,$page=0)
  590. {
  591. $PHORUM = $GLOBALS["PHORUM"];
  592. settype($thread, "int");
  593. $conn = phorum_db_mysqli_connect();
  594. $forum_id_check = "";
  595. if (!empty($PHORUM["forum_id"])){
  596. $forum_id_check = "(forum_id = {$PHORUM['forum_id']} OR forum_id={$PHORUM['vroot']}) and";
  597. }
  598. // are we really allowed to show this thread/message?
  599. $approvedval = "";
  600. if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES)) {
  601. $approvedval="AND {$PHORUM['message_table']}.status =".PHORUM_STATUS_APPROVED;
  602. }
  603. if($page > 0) {
  604. $start=$PHORUM["read_length"]*($page-1);
  605. $sql = "select {$PHORUM['message_table']}.* from {$PHORUM['message_table']} where $forum_id_check thread=$thread $approvedval order by message_id LIMIT $start,".$PHORUM["read_length"];
  606. } else {
  607. $sql = "select {$PHORUM['message_table']}.* from {$PHORUM['message_table']} where $forum_id_check thread=$thread $approvedval order by message_id";
  608. if(isset($PHORUM["reverse_threading"]) && $PHORUM["reverse_threading"]) $sql.=" desc";
  609. }
  610. $res = mysqli_query( $conn, $sql);
  611. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  612. $arr = array();
  613. while ($rec = mysqli_fetch_assoc($res)){
  614. $arr[$rec["message_id"]] = $rec;
  615. // convert meta field
  616. if(empty($rec["meta"])){
  617. $arr[$rec["message_id"]]["meta"]=array();
  618. } else {
  619. $arr[$rec["message_id"]]["meta"]=unserialize($rec["meta"]);
  620. }
  621. if(empty($arr['users'])) $arr['users']=array();
  622. if($rec["user_id"]){
  623. $arr['users'][]=$rec["user_id"];
  624. }
  625. }
  626. if(count($arr) && $page != 0) {
  627. // selecting the thread-starter
  628. $sql = "select {$PHORUM['message_table']}.* from {$PHORUM['message_table']} where $forum_id_check message_id=$thread $approvedval";
  629. $res = mysqli_query( $conn, $sql);
  630. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  631. if(mysqli_num_rows($res) > 0) {
  632. $rec = mysqli_fetch_assoc($res);
  633. $arr[$rec["message_id"]] = $rec;
  634. $arr[$rec["message_id"]]["meta"]=unserialize($rec["meta"]);
  635. }
  636. }
  637. return $arr;
  638. }
  639. /**
  640. * this function returns the index of a message in a thread
  641. */
  642. function phorum_db_get_message_index($thread=0,$message_id=0) {
  643. $PHORUM = $GLOBALS["PHORUM"];
  644. // check for valid values
  645. if(empty($message_id) || empty($message_id)) {
  646. return 0;
  647. }
  648. settype($thread, "int");
  649. settype($message_id, "int");
  650. $approvedval="";
  651. $forum_id_check="";
  652. $conn = phorum_db_mysqli_connect();
  653. if (!empty($PHORUM["forum_id"])){
  654. $forum_id_check = "(forum_id = {$PHORUM['forum_id']} OR forum_id={$PHORUM['vroot']}) AND";
  655. }
  656. if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES)) {
  657. $approvedval="AND {$PHORUM['message_table']}.status =".PHORUM_STATUS_APPROVED;
  658. }
  659. $sql = "select count(*) as msg_index from {$PHORUM['message_table']} where $forum_id_check thread=$thread $approvedval AND message_id <= $message_id order by message_id";
  660. $res = mysqli_query( $conn, $sql);
  661. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  662. $rec = mysqli_fetch_assoc($res);
  663. return $rec['msg_index'];
  664. }
  665. /**
  666. * This function searches the database for the supplied search
  667. * criteria and returns an array with two elements. One is the count
  668. * of total messages that matched, the second is an array of the
  669. * messages from the results based on the $start (0 base) given and
  670. * the $length given.
  671. */
  672. function phorum_db_search($search, $offset, $length, $match_type, $match_date, $match_forum)
  673. {
  674. $PHORUM = $GLOBALS["PHORUM"];
  675. $start = $offset * $PHORUM["list_length"];
  676. $arr = array("count" => 0, "rows" => array());
  677. $conn = phorum_db_mysqli_connect();
  678. // have to check what forums they can read first.
  679. $allowed_forums=phorum_user_access_list(PHORUM_USER_ALLOW_READ);
  680. // if they are not allowed to search any forums, return the emtpy $arr;
  681. if(empty($allowed_forums) || ($PHORUM['forum_id']>0 && !in_array($PHORUM['forum_id'], $allowed_forums)) ) return $arr;
  682. // Add forum 0 (for announcements) to the allowed forums.
  683. $allowed_forums[] = 0;
  684. if($PHORUM['forum_id']!=0 && $match_forum!="ALL"){
  685. $forum_where=" and forum_id={$PHORUM['forum_id']}";
  686. } else {
  687. $forum_where=" and forum_id in (".implode(",", $allowed_forums).")";
  688. }
  689. if($match_type=="AUTHOR"){
  690. $id_table=$PHORUM['search_table']."_auth_".md5(microtime());
  691. $search = mysqli_real_escape_string($conn,$search);
  692. $sql = "create temporary table $id_table (key(message_id)) ENGINE=HEAP select message_id from {$PHORUM['message_table']} where author='$search' $forum_where";
  693. if($match_date>0){
  694. $ts=time()-86400*$match_date;
  695. $sql.=" and datestamp>=$ts";
  696. }
  697. $res = mysqli_query( $conn, $sql);
  698. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  699. } else {
  700. if($match_type=="PHRASE"){
  701. $terms = array('"'.$search.'"');
  702. } else {
  703. $quote_terms=array();
  704. if ( strstr( $search, '"' ) ){
  705. //first pull out all the double quoted strings (e.g. '"iMac DV" or -"iMac DV"')
  706. preg_match_all( '/-*"(.*?)"/', $search, $match );
  707. $search = preg_replace( '/-*".*?"/', '', $search );
  708. $quote_terms = $match[0];
  709. }
  710. //finally pull out the rest words in the string
  711. $terms = preg_split( "/\s+/", $search, 0, PREG_SPLIT_NO_EMPTY );
  712. //merge them all together and return
  713. $terms = array_merge( $terms, $quote_terms);
  714. }
  715. if(count($terms)){
  716. $use_key="";
  717. $extra_where="";
  718. /* using this code on larger forums has shown to make the search faster.
  719. However, on smaller forums, it does not appear to help and in fact
  720. appears to slow down searches.
  721. if($match_date){
  722. $min_time=time()-86400*$match_date;
  723. $sql="select min(message_id) as min_id from {$PHORUM['message_table']} where datestamp>=$min_time";
  724. $res=mysqli_query( $conn, $sql);
  725. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  726. $min_id=mysql_result($res, 0, "min_id");
  727. $use_key=" use key (primary)";
  728. $extra_where="and message_id>=$min_id";
  729. }
  730. */
  731. $id_table=$PHORUM['search_table']."_ft_".md5(microtime());
  732. if($PHORUM["DBCONFIG"]["mysql_use_ft"]){
  733. if($match_type=="ALL" && count($terms)>1){
  734. $against="+".mysqli_real_escape_string($conn, implode(" +", $terms));
  735. } else {
  736. $against=mysqli_real_escape_string($conn, implode(" ", $terms));
  737. }
  738. $clause="MATCH (search_text) AGAINST ('$against' IN BOOLEAN MODE)";
  739. } else {
  740. if($match_type=="ALL"){
  741. $conj="and";
  742. } else {
  743. $conj="or";
  744. }
  745. // quote strings correctly
  746. foreach ($terms as $id => $term) {
  747. $terms[$id] = mysqli_real_escape_string($conn,$term);
  748. }
  749. $clause = "( search_text like '%".implode("%' $conj search_text like '%", $terms)."%' )";
  750. }
  751. $sql = "create temporary table $id_table (key(message_id)) ENGINE=HEAP select message_id from {$PHORUM['search_table']} $use_key where $clause $extra_where";
  752. $res = mysqli_query($conn, $sql);
  753. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  754. }
  755. }
  756. if(isset($id_table)){
  757. // create a temporary table of the messages we want
  758. $table=$PHORUM['search_table']."_".md5(microtime());
  759. $sql="create temporary table $table (key (forum_id, status, datestamp)) ENGINE=HEAP select {$PHORUM['message_table']}.message_id, {$PHORUM['message_table']}.datestamp, status, forum_id from {$PHORUM['message_table']} inner join $id_table using (message_id) where status=".PHORUM_STATUS_APPROVED." $forum_where";
  760. if($match_date>0){
  761. $ts=time()-86400*$match_date;
  762. $sql.=" and datestamp>=$ts";
  763. }
  764. $res=mysqli_query( $conn, $sql);
  765. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  766. $sql="select count(*) as count from $table";
  767. $res = mysqli_query( $conn, $sql);
  768. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  769. $tmp_row=mysqli_fetch_row($res);
  770. $total_count=$tmp_row[0];
  771. $sql="select message_id from $table order by datestamp desc limit $start, $length";
  772. $res = mysqli_query($conn, $sql, MYSQLI_USE_RESULT );
  773. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  774. $idstring="";
  775. while ($rec = mysqli_fetch_row($res)){
  776. $idstring.="$rec[0],";
  777. }
  778. mysqli_free_result ( $res );
  779. $idstring=substr($idstring, 0, -1);
  780. if($idstring){
  781. $sql="select * from {$PHORUM['message_table']} where message_id in ($idstring) order by datestamp desc";
  782. $res = mysqli_query($conn, $sql, MYSQLI_USE_RESULT);
  783. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  784. $rows = array();
  785. while ($rec = mysqli_fetch_assoc($res)){
  786. $rows[$rec["message_id"]] = $rec;
  787. }
  788. mysqli_free_result ( $res );
  789. $arr = array("count" => $total_count, "rows" => $rows);
  790. }
  791. }
  792. return $arr;
  793. }
  794. /**
  795. * This function returns the closest thread that is greater than $thread
  796. */
  797. function phorum_db_get_newer_thread($key){
  798. $PHORUM = $GLOBALS["PHORUM"];
  799. settype($key, "int");
  800. $conn = phorum_db_mysqli_connect();
  801. $keyfield = ($PHORUM["float_to_top"]) ? "modifystamp" : "thread";
  802. // are we really allowed to show this thread/message?
  803. $approvedval = "";
  804. if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES) && $PHORUM["moderation"] == PHORUM_MODERATE_ON) {
  805. $approvedval="AND {$PHORUM['message_table']}.status =".PHORUM_STATUS_APPROVED;
  806. } else {
  807. $approvedval="AND {$PHORUM['message_table']}.parent_id = 0";
  808. }
  809. $sql = "select thread from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} $approvedval and $keyfield>$key order by $keyfield limit 1";
  810. $res = mysqli_query( $conn, $sql);
  811. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  812. if (mysqli_num_rows($res)) {
  813. $tmp_row=mysqli_fetch_row($res);
  814. $retid=$tmp_row[0];
  815. } else {
  816. $retid=0;
  817. }
  818. return $retid;
  819. }
  820. /**
  821. * This function returns the closest thread that is less than $thread
  822. */
  823. function phorum_db_get_older_thread($key){
  824. $PHORUM = $GLOBALS["PHORUM"];
  825. settype($key, "int");
  826. $conn = phorum_db_mysqli_connect();
  827. $keyfield = ($PHORUM["float_to_top"]) ? "modifystamp" : "thread";
  828. // are we really allowed to show this thread/message?
  829. $approvedval = "";
  830. if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES) && $PHORUM["moderation"] == PHORUM_MODERATE_ON) {
  831. $approvedval="AND {$PHORUM['message_table']}.status=".PHORUM_STATUS_APPROVED;
  832. } else {
  833. $approvedval="AND {$PHORUM['message_table']}.parent_id = 0";
  834. }
  835. $sql = "select thread from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} $approvedval and $keyfield<$key order by $keyfield desc limit 1";
  836. $res = mysqli_query( $conn, $sql);
  837. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  838. if (mysqli_num_rows($res)) {
  839. $tmp_row=mysqli_fetch_row($res);
  840. $retid=$tmp_row[0];
  841. } else {
  842. $retid=0;
  843. }
  844. return $retid;
  845. }
  846. /**
  847. * This function executes a query to get bad items of type $type and
  848. * returns an array of the results.
  849. */
  850. function phorum_db_load_settings(){
  851. global $PHORUM;
  852. $conn = phorum_db_mysqli_connect();
  853. $sql = "select * from {$PHORUM['settings_table']}";
  854. $res = mysqli_query( $conn, $sql);
  855. if(!$res && !defined("PHORUM_ADMIN")){
  856. if (mysqli_errno($conn)==1146){
  857. // settings table does not exist
  858. return;
  859. } elseif(($err = mysqli_error($conn))){
  860. phorum_db_mysqli_error("$err: $sql");
  861. }
  862. }
  863. if (empty($err) && $res){
  864. while ($rec = mysqli_fetch_assoc($res)){
  865. // only load the default forum options in the admin
  866. if($rec["name"]=="default_forum_options" && !defined("PHORUM_ADMIN")) continue;
  867. if ($rec["type"] == "V"){
  868. if ($rec["data"] == 'true'){
  869. $val = true;
  870. }elseif ($rec["data"] == 'false'){
  871. $val = false;
  872. }elseif (is_numeric($rec["data"])){
  873. $val = $rec["data"];
  874. }else{
  875. $val = "$rec[data]";
  876. }
  877. }else{
  878. $val = unserialize($rec["data"]);
  879. }
  880. $PHORUM[$rec['name']]=$val;
  881. $PHORUM['SETTINGS'][$rec['name']]=$val;
  882. }
  883. }
  884. }
  885. /**
  886. * This function executes a query to get bad items of type $type and
  887. * returns an array of the results.
  888. */
  889. function phorum_db_update_settings($settings){
  890. global $PHORUM;
  891. if (count($settings) > 0){
  892. $conn = phorum_db_mysqli_connect();
  893. foreach($settings as $field => $value){
  894. if (is_numeric($value)){
  895. $type = 'V';
  896. }elseif (is_string($value)){
  897. $value = mysqli_real_escape_string ( $conn, $value);
  898. $type = 'V';
  899. }else{
  900. $value = mysqli_real_escape_string ( $conn, serialize($value));
  901. $type = 'S';
  902. }
  903. $sql = "replace into {$PHORUM['settings_table']} set data='$value', type='$type', name='$field'";
  904. $res = mysqli_query( $conn, $sql);
  905. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  906. }
  907. return ($res > 0) ? true : false;
  908. }else{
  909. trigger_error("\$settings cannot be empty in phorum_db_update_settings()", E_USER_ERROR);
  910. }
  911. }
  912. /**
  913. * This function executes a query to select all forum data from
  914. * the database for a flat/collapsed display and returns the data in
  915. * an array.
  916. */
  917. function phorum_db_get_forums($forum_ids = 0, $parent_id = -1, $vroot = null, $inherit_id = null){
  918. $PHORUM = $GLOBALS["PHORUM"];
  919. settype($parent_id, "int");
  920. $conn = phorum_db_mysqli_connect();
  921. if (is_array($forum_ids)) {
  922. $int_ids = array();
  923. foreach ($forum_ids as $id) {
  924. settype($id, "int");
  925. $int_ids[] = $id;
  926. }
  927. $forum_ids = implode(",", $int_ids);
  928. } else {
  929. settype($forum_ids, "int");
  930. }
  931. $sql = "select * from {$PHORUM['forums_table']} ";
  932. if ($forum_ids){
  933. $sql .= " where forum_id in ($forum_ids)";
  934. } elseif ($inherit_id !== null) {
  935. $sql .= " where inherit_id = $inherit_id";
  936. if(!defined("PHORUM_ADMIN")) $sql.=" and active=1";
  937. } elseif ($parent_id >= 0) {
  938. $sql .= " where parent_id = $parent_id";
  939. if(!defined("PHORUM_ADMIN")) $sql.=" and active=1";
  940. } elseif($vroot !== null) {
  941. $sql .= " where vroot = $vroot";
  942. } else {
  943. $sql .= " where forum_id <> 0";
  944. }
  945. $sql .= " order by display_order ASC, name";
  946. $res = mysqli_query( $conn, $sql);
  947. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  948. $forums = array();
  949. while ($row = mysqli_fetch_assoc($res)){
  950. $forums[$row["forum_id"]] = $row;
  951. }
  952. return $forums;
  953. }
  954. /**
  955. * This function updates the forums stats. If refresh is true, it pulls the
  956. * numbers from the table.
  957. */
  958. function phorum_db_update_forum_stats($refresh=false, $msg_count_change=0, $timestamp=0, $thread_count_change=0, $sticky_count_change=0)
  959. {
  960. $PHORUM = $GLOBALS["PHORUM"];
  961. $conn = phorum_db_mysqli_connect();
  962. // always refresh on small forums
  963. if (isset($PHORUM["message_count"]) && $PHORUM["message_count"]<1000) {
  964. $refresh=true;
  965. }
  966. if($refresh || empty($msg_count_change)){
  967. $sql = "select count(*) as message_count from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} and status=".PHORUM_STATUS_APPROVED;
  968. $res = mysqli_query( $conn, $sql);
  969. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  970. $tmp_row=mysqli_fetch_row($res);
  971. $message_count = (int)$tmp_row[0];
  972. } else {
  973. $message_count="message_count+$msg_count_change";
  974. }
  975. if($refresh || empty($timestamp)){
  976. $sql = "select max(modifystamp) as last_post_time from {$PHORUM['message_table']} where status=".PHORUM_STATUS_APPROVED." and forum_id={$PHORUM['forum_id']}";
  977. $res = mysqli_query( $conn, $sql);
  978. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  979. $tmp_row=mysqli_fetch_row($res);
  980. $last_post_time = (int)$tmp_row[0];
  981. } else {
  982. $last_post_time = $timestamp;
  983. }
  984. if($refresh || empty($thread_count_change)){
  985. $sql = "select count(*) as thread_count from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} and parent_id=0 and status=".PHORUM_STATUS_APPROVED;
  986. $res = mysqli_query( $conn, $sql);
  987. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  988. $tmp_row=mysqli_fetch_row($res);
  989. $thread_count = (int)$tmp_row[0];
  990. } else {
  991. $thread_count="thread_count+$thread_count_change";
  992. }
  993. if($refresh || empty($sticky_count_change)){
  994. $sql = "select count(*) as sticky_count from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} and sort=".PHORUM_SORT_STICKY." and parent_id=0 and status=".PHORUM_STATUS_APPROVED;
  995. $res = mysqli_query( $conn, $sql);
  996. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  997. $tmp_row=mysqli_fetch_row($res);
  998. $sticky_count = (int)$tmp_row[0];
  999. } else {
  1000. $sticky_count="sticky_count+$sticky_count_change";
  1001. }
  1002. $sql = "update {$PHORUM['forums_table']} set thread_count=$thread_count, message_count=$message_count, sticky_count=$sticky_count, last_post_time=$last_post_time where forum_id={$PHORUM['forum_id']}";
  1003. mysqli_query( $conn, $sql);
  1004. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1005. }
  1006. /**
  1007. * actually moves a thread to the given forum
  1008. */
  1009. function phorum_db_move_thread($thread_id, $toforum)
  1010. {
  1011. $PHORUM = $GLOBALS["PHORUM"];
  1012. settype($thread_id, "int");
  1013. settype($toforum, "int");
  1014. if($toforum > 0 && $thread_id > 0){
  1015. $conn = phorum_db_mysqli_connect();
  1016. // retrieving the messages for the newflags and search updates below
  1017. $thread_messages=phorum_db_get_messages($thread_id);
  1018. // just changing the forum-id, simple isn't it?
  1019. $sql = "UPDATE {$PHORUM['message_table']} SET forum_id=$toforum where thread=$thread_id";
  1020. $res = mysqli_query( $conn, $sql);
  1021. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1022. // we need to update the number of posts in the current forum
  1023. phorum_db_update_forum_stats(true);
  1024. // and of the new forum
  1025. $old_id=$GLOBALS["PHORUM"]["forum_id"];
  1026. $GLOBALS["PHORUM"]["forum_id"]=$toforum;
  1027. phorum_db_update_forum_stats(true);
  1028. $GLOBALS["PHORUM"]["forum_id"]=$old_id;
  1029. // move the new-flags and the search records for this thread
  1030. // to the new forum too
  1031. unset($thread_messages['users']);
  1032. $new_newflags=phorum_db_newflag_get_flags($toforum);
  1033. $message_ids = array();
  1034. $delete_ids = array();
  1035. $search_ids = array();
  1036. foreach($thread_messages as $mid => $data) {
  1037. // gather information for updating the newflags
  1038. if($mid > $new_newflags['min_id']) { // only using it if its higher than min_id
  1039. $message_ids[]=$mid;
  1040. } else { // newflags to delete
  1041. $delete_ids[]=$mid;
  1042. }
  1043. // gather the information for updating the search table
  1044. $search_ids[] = $mid;
  1045. }
  1046. if(count($message_ids)) { // we only go in if there are messages ... otherwise an error occured
  1047. $ids_str=implode(",",$message_ids);
  1048. // then doing the update to newflags
  1049. $sql="UPDATE IGNORE {$PHORUM['user_newflags_table']} SET forum_id = $toforum where message_id IN($ids_str)";
  1050. $res = mysqli_query( $conn, $sql);
  1051. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1052. // then doing the update to subscriptions
  1053. $sql="UPDATE {$PHORUM['subscribers_table']} SET forum_id = $toforum where thread IN($ids_str)";
  1054. $res = mysqli_query( $conn, $sql);
  1055. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1056. }
  1057. if(count($delete_ids)) {
  1058. $ids_str=implode(",",$delete_ids);
  1059. // then doing the delete
  1060. $sql="DELETE FROM {$PHORUM['user_newflags_table']} where message_id IN($ids_str)";
  1061. mysqli_query( $conn, $sql);
  1062. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1063. }
  1064. if (count($search_ids)) {
  1065. $ids_str = implode(",",$search_ids);
  1066. // then doing the search table update
  1067. $sql = "UPDATE {$PHORUM['search_table']} set forum_id = $toforum where message_id in ($ids_str)";
  1068. mysqli_query( $conn, $sql);
  1069. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1070. }
  1071. }
  1072. }
  1073. /**
  1074. * closes the given thread
  1075. */
  1076. function phorum_db_close_thread($thread_id){
  1077. $PHORUM = $GLOBALS["PHORUM"];
  1078. settype($thread_id, "int");
  1079. if($thread_id > 0){
  1080. $conn = phorum_db_mysqli_connect();
  1081. $sql = "UPDATE {$PHORUM['message_table']} SET closed=1 where thread=$thread_id";
  1082. $res = mysqli_query( $conn, $sql);
  1083. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1084. }
  1085. }
  1086. /**
  1087. * (re)opens the given thread
  1088. */
  1089. function phorum_db_reopen_thread($thread_id){
  1090. $PHORUM = $GLOBALS["PHORUM"];
  1091. settype($thread_id, "int");
  1092. if($thread_id > 0){
  1093. $conn = phorum_db_mysqli_connect();
  1094. $sql = "UPDATE {$PHORUM['message_table']} SET closed=0 where thread=$thread_id";
  1095. $res = mysqli_query( $conn, $sql);
  1096. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1097. }
  1098. }
  1099. /**
  1100. * This function executes a query to insert a forum into the forums
  1101. * table and returns the forums id on success or 0 on failure.
  1102. */
  1103. function phorum_db_add_forum($forum)
  1104. {
  1105. $PHORUM = $GLOBALS["PHORUM"];
  1106. $conn = phorum_db_mysqli_connect();
  1107. foreach($forum as $key => $value){
  1108. if (is_numeric($value)){
  1109. $value = (int)$value;
  1110. $fields[] = "$key=$value";
  1111. } elseif($value=="NULL") {
  1112. $fields[] = "$key=$value";
  1113. }else{
  1114. $value = mysqli_real_escape_string($conn, $value);
  1115. $fields[] = "$key='$value'";
  1116. }
  1117. }
  1118. $sql = "insert into {$PHORUM['forums_table']} set " . implode(", ", $fields);
  1119. $res = mysqli_query( $conn, $sql);
  1120. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1121. $forum_id = 0;
  1122. if ($res){
  1123. $forum_id = mysqli_insert_id($conn);
  1124. }
  1125. return $forum_id;
  1126. }
  1127. /**
  1128. * This function executes a query to remove a forum from the forums
  1129. * table and its messages.
  1130. */
  1131. function phorum_db_drop_forum($forum_id)
  1132. {
  1133. $PHORUM = $GLOBALS["PHORUM"];
  1134. settype($forum_id, "int");
  1135. $conn = phorum_db_mysqli_connect();
  1136. $tables = array (
  1137. $PHORUM['message_table'],
  1138. $PHORUM['user_permissions_table'],
  1139. $PHORUM['user_newflags_table'],
  1140. $PHORUM['subscribers_table'],
  1141. $PHORUM['forum_group_xref_table'],
  1142. $PHORUM['forums_table'],
  1143. $PHORUM['banlist_table'],
  1144. $PHORUM['search_table']
  1145. );
  1146. foreach($tables as $table){
  1147. $sql = "delete from $table where forum_id=$forum_id";
  1148. $res = mysqli_query( $conn, $sql);
  1149. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1150. }
  1151. $sql = "select file_id from {$PHORUM['files_table']} left join {$PHORUM['message_table']} using (message_id) where {$PHORUM['files_table']}.message_id > 0 AND link='" . PHORUM_LINK_MESSAGE . "' AND {$PHORUM['message_table']}.message_id is NULL";
  1152. $res = mysqli_query( $conn, $sql);
  1153. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1154. while($rec=mysqli_fetch_assoc($res)){
  1155. $files[]=$rec["file_id"];
  1156. }
  1157. if(isset($files)){
  1158. $sql = "delete from {$PHORUM['files_table']} where file_id in (".implode(",", $files).")";
  1159. $res = mysqli_query( $conn, $sql);
  1160. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1161. }
  1162. }
  1163. /**
  1164. * This function executes a query to remove a folder from the forums
  1165. * table and change the parent of its children.
  1166. */
  1167. function phorum_db_drop_folder($forum_id)
  1168. {
  1169. $PHORUM = $GLOBALS["PHORUM"];
  1170. settype($forum_id, "int");
  1171. $conn = phorum_db_mysqli_connect();
  1172. $sql = "select parent_id from {$PHORUM['forums_table']} where forum_id=$forum_id";
  1173. $res = mysqli_query( $conn, $sql);
  1174. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1175. $tmp_row=mysqli_fetch_row($res);
  1176. $new_parent_id = $tmp_row[0];
  1177. $sql = "update {$PHORUM['forums_table']} set parent_id=$new_parent_id where parent_id=$forum_id";
  1178. $res = mysqli_query( $conn, $sql);
  1179. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1180. $sql = "delete from {$PHORUM['forums_table']} where forum_id=$forum_id";
  1181. $res = mysqli_query( $conn, $sql);
  1182. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1183. }
  1184. /**
  1185. * This function executes a query to update a forum in the forums
  1186. * table and returns non zero on success or 0 on failure.
  1187. */
  1188. function phorum_db_update_forum($forum){
  1189. $PHORUM = $GLOBALS["PHORUM"];
  1190. $res = 0;
  1191. if (!empty($forum["forum_id"])){
  1192. // this way we can also update multiple forums at once
  1193. if(is_array($forum["forum_id"])) {
  1194. $forumwhere="forum_id IN (".implode(",",$forum["forum_id"]).")";
  1195. } else {
  1196. $forumwhere="forum_id=".$forum["forum_id"];
  1197. }
  1198. unset($forum["forum_id"]);
  1199. $conn = phorum_db_mysqli_connect();
  1200. foreach($forum as $key => $value){
  1201. if (is_numeric($value)){
  1202. $value = (int)$value;
  1203. $fields[] = "$key=$value";
  1204. } elseif($value=="NULL") {
  1205. $fields[] = "$key=$value";
  1206. } else {
  1207. $value = mysqli_real_escape_string($conn, $value);
  1208. $fields[] = "$key='$value'";
  1209. }
  1210. }
  1211. $sql = "update {$PHORUM['forums_table']} set " . implode(", ", $fields) . " where $forumwhere";
  1212. $res = mysqli_query( $conn, $sql);
  1213. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1214. }else{
  1215. trigger_error("\$forum[forum_id] cannot be empty in phorum_update_forum()", E_USER_ERROR);
  1216. }
  1217. return $res;
  1218. }
  1219. /**
  1220. *
  1221. */
  1222. function phorum_db_get_groups($group_id=0)
  1223. {
  1224. $PHORUM = $GLOBALS["PHORUM"];
  1225. $conn = phorum_db_mysqli_connect();
  1226. settype($group_id, "integer");
  1227. $sql="select * from {$PHORUM['groups_table']}";
  1228. if($group_id!=0) $sql.=" where group_id=$group_id";
  1229. $res = mysqli_query( $conn, $sql);
  1230. $groups=array();
  1231. while($rec=mysqli_fetch_assoc($res)){
  1232. $groups[$rec["group_id"]]=$rec;
  1233. $groups[$rec["group_id"]]["permissions"]=array();
  1234. }
  1235. $sql="select * from {$PHORUM['forum_group_xref_table']}";
  1236. if($group_id!=0) $sql.=" where group_id=$group_id";
  1237. $res = mysqli_query( $conn, $sql);
  1238. while($rec=mysqli_fetch_assoc($res)){
  1239. $groups[$rec["group_id"]]["permissions"][$rec["forum_id"]]=$rec["permission"];
  1240. }
  1241. return $groups;
  1242. }
  1243. /**
  1244. * Get the members of a group.
  1245. * @param group_id - can be an integer (single group), or an array of groups
  1246. * @param status - a specific status to look for, defaults to all
  1247. * @return array - users (key is userid, value is group membership status)
  1248. */
  1249. function phorum_db_get_group_members($group_id, $status = PHORUM_USER_GROUP_REMOVE)
  1250. {
  1251. $PHORUM = $GLOBALS["PHORUM"];
  1252. $conn = phorum_db_mysqli_connect();
  1253. if(is_array($group_id)){
  1254. $group_id=implode(",", $group_id);
  1255. } else {
  1256. settype($group_id, "int");
  1257. }
  1258. // this join is only here so that the list of users comes out sorted
  1259. // if phorum_db_user_get() sorts results itself, this join can go away
  1260. $sql="select {$PHORUM['user_group_xref_table']}.user_id, {$PHORUM['user_group_xref_table']}.status from {$PHORUM['user_table']}, {$PHORUM['user_group_xref_table']} where {$PHORUM['user_table']}.user_id = {$PHORUM['user_group_xref_table']}.user_id and group_id in ($group_id)";
  1261. if ($status != PHORUM_USER_GROUP_REMOVE) $sql.=" and {$PHORUM['user_group_xref_table']}.status = $status";
  1262. $sql .=" order by username asc";
  1263. $res = mysqli_query( $conn, $sql);
  1264. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1265. $users=array();
  1266. while($rec=mysqli_fetch_assoc($res)){
  1267. $users[$rec["user_id"]]=$rec["status"];
  1268. }
  1269. return $users;
  1270. }
  1271. /**
  1272. *
  1273. */
  1274. function phorum_db_save_group($group)
  1275. {
  1276. $PHORUM = $GLOBALS["PHORUM"];
  1277. $conn = phorum_db_mysqli_connect();
  1278. $ret=false;
  1279. if(isset($group["name"])){
  1280. $sql="update {$PHORUM['groups_table']} set name='{$group['name']}', open={$group['open']} where group_id={$group['group_id']}";
  1281. $res=mysqli_query( $conn, $sql);
  1282. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1283. }
  1284. if(!$err){
  1285. if(isset($group["permissions"])){
  1286. $sql="delete from {$PHORUM['forum_group_xref_table']} where group_id={$group['group_id']}";
  1287. $res=mysqli_query( $conn, $sql);
  1288. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1289. foreach($group["permissions"] as $forum_id=>$permission){
  1290. $sql="insert into {$PHORUM['forum_group_xref_table']} set group_id={$group['group_id']}, permission=$permission, forum_id=$forum_id";
  1291. $res=mysqli_query( $conn, $sql);
  1292. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1293. if(!$res) break;
  1294. }
  1295. }
  1296. }
  1297. if($res>0) $ret=true;
  1298. return $ret;
  1299. }
  1300. function phorum_db_delete_group($group_id)
  1301. {
  1302. $PHORUM = $GLOBALS["PHORUM"];
  1303. $conn = phorum_db_mysqli_connect();
  1304. settype($group_id, "int");
  1305. $sql = "delete from {$PHORUM['groups_table']} where group_id = $group_id";
  1306. $res = mysqli_query( $conn, $sql);
  1307. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1308. // delete things associated with groups
  1309. $sql = "delete from {$PHORUM['user_group_xref_table']} where group_id = $group_id";
  1310. $res = mysqli_query( $conn, $sql);
  1311. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1312. $sql = "delete from {$PHORUM['forum_group_xref_table']} where group_id = $group_id";
  1313. $res = mysqli_query( $conn, $sql);
  1314. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1315. }
  1316. /**
  1317. * phorum_db_add_group()
  1318. *
  1319. * @param $group_name $group_id
  1320. * @return
  1321. **/
  1322. function phorum_db_add_group($group_name,$group_id=0)
  1323. {
  1324. $PHORUM = $GLOBALS["PHORUM"];
  1325. $conn = phorum_db_mysqli_connect();
  1326. settype($group_id, "int");
  1327. if($group_id > 0) { // only used in conversion
  1328. $sql="insert into {$PHORUM['groups_table']} (group_id,name) values ($group_id,'$group_name')";
  1329. } else {
  1330. $sql="insert into {$PHORUM['groups_table']} (name) values ('$group_name')";
  1331. }
  1332. $res = mysqli_query( $conn, $sql);
  1333. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1334. $group_id = 0;
  1335. if ($res) {
  1336. $group_id = mysqli_insert_id($conn);
  1337. }
  1338. return $group_id;
  1339. }
  1340. /**
  1341. * This function returns all moderators for a particular forum
  1342. */
  1343. function phorum_db_user_get_moderators($forum_id,$ignore_user_perms=false,$for_email=false) {
  1344. $PHORUM = $GLOBALS["PHORUM"];
  1345. $userinfo=array();
  1346. $conn = phorum_db_mysqli_connect();
  1347. settype($forum_id, "int");
  1348. if(!$ignore_user_perms) { // sometimes we just don't need them
  1349. if(!$PHORUM['email_ignore_admin']) {
  1350. $admincheck=" OR user.admin=1";
  1351. } else {
  1352. $admincheck="";
  1353. }
  1354. $sql="SELECT DISTINCT user.user_id, user.email, user.moderation_email FROM {$PHORUM['user_table']} as user LEFT JOIN {$PHORUM['user_permissions_table']} as perm ON perm.user_id=user.user_id WHERE (perm.permission >= ".PHORUM_USER_ALLOW_MODERATE_MESSAGES." AND (perm.permission & ".PHORUM_USER_ALLOW_MODERATE_MESSAGES." > 0) AND perm.forum_id=$forum_id)$admincheck";
  1355. $res = mysqli_query( $conn, $sql);
  1356. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1357. while ($row = mysqli_fetch_row($res)){
  1358. if(!$for_email || $row[2] == 1)
  1359. $userinfo[$row[0]]=$row[1];
  1360. }
  1361. }
  1362. // get users who belong to groups that have moderator access
  1363. $sql = "SELECT DISTINCT user.user_id, user.email, user.moderation_email FROM {$PHORUM['user_table']} AS user, {$PHORUM['groups_table']} AS groups, {$PHORUM['user_group_xref_table']} AS usergroup, {$PHORUM['forum_group_xref_table']} AS forumgroup WHERE user.user_id = usergroup.user_id AND usergroup.group_id = groups.group_id AND groups.group_id = forumgroup.group_id AND forum_id = $forum_id AND permission & ".PHORUM_USER_ALLOW_MODERATE_MESSAGES." > 0 AND usergroup.status >= ".PHORUM_USER_GROUP_APPROVED;
  1364. $res = mysqli_query( $conn, $sql);
  1365. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1366. while ($row = mysqli_fetch_row($res)){
  1367. if(!$for_email || $row[2] == 1)
  1368. $userinfo[$row[0]]=$row[1];
  1369. }
  1370. return $userinfo;
  1371. }
  1372. /**
  1373. * This function executes a query to select data about a user including
  1374. * his permission data and returns that in an array.
  1375. */
  1376. function phorum_db_user_get($user_id, $detailed)
  1377. {
  1378. $PHORUM = $GLOBALS["PHORUM"];
  1379. $conn = phorum_db_mysqli_connect();
  1380. if(is_array($user_id)){
  1381. $user_ids=implode(",", $user_id);
  1382. } else {
  1383. $user_ids=(int)$user_id;
  1384. }
  1385. $users = array();
  1386. $sql = "select * from {$PHORUM['user_table']} where user_id in ($user_ids)";
  1387. $res = mysqli_query( $conn, $sql);
  1388. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1389. if (mysqli_num_rows($res)){
  1390. while($rec=mysqli_fetch_assoc($res)){
  1391. $users[$rec["user_id"]] = $rec;
  1392. }
  1393. if ($detailed){
  1394. // get the users' permissions
  1395. $sql = "select * from {$PHORUM['user_permissions_table']} where user_id in ($user_ids)";
  1396. $res = mysqli_query( $conn, $sql);
  1397. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1398. while ($row = mysqli_fetch_assoc($res)){
  1399. $users[$row["user_id"]]["forum_permissions"][$row["forum_id"]] = $row["permission"];
  1400. }
  1401. // get the users' groups and forum permissions through those groups
  1402. $sql = "select user_id, {$PHORUM['user_group_xref_table']}.group_id, forum_id, permission from {$PHORUM['user_group_xref_table']} left join {$PHORUM['forum_group_xref_table']} using (group_id) where user_id in ($user_ids) AND {$PHORUM['user_group_xref_table']}.status >= ".PHORUM_USER_GROUP_APPROVED;
  1403. $res = mysqli_query( $conn, $sql);
  1404. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1405. while ($row = mysqli_fetch_assoc($res)){
  1406. $users[$row["user_id"]]["groups"][$row["group_id"]] = $row["group_id"];
  1407. if(!empty($row["forum_id"])){
  1408. if(!isset($users[$row["user_id"]]["group_permissions"][$row["forum_id"]])) {
  1409. $users[$row["user_id"]]["group_permissions"][$row["forum_id"]] = 0;
  1410. }
  1411. $users[$row["user_id"]]["group_permissions"][$row["forum_id"]] = $users[$row["user_id"]]["group_permissions"][$row["forum_id"]] | $row["permission"];
  1412. }
  1413. }
  1414. }
  1415. $sql = "select * from {$PHORUM['user_custom_fields_table']} where user_id in ($user_ids)";
  1416. $res = mysqli_query( $conn, $sql);
  1417. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1418. while ($row = mysqli_fetch_assoc($res)){
  1419. if(isset($PHORUM["PROFILE_FIELDS"][$row['type']])) {
  1420. if($PHORUM["PROFILE_FIELDS"][$row['type']]['html_disabled']) {
  1421. $users[$row["user_id"]][$PHORUM["PROFILE_FIELDS"][$row['type']]['name']] = htmlspecialchars($row["data"]);
  1422. } else { // not html-disabled
  1423. if(substr($row["data"],0,6) == 'P_SER:') {
  1424. // P_SER (PHORUM_SERIALIZED) is our marker telling this field is serialized
  1425. $users[$row["user_id"]][$PHORUM["PROFILE_FIELDS"][$row['type']]['name']] = unserialize(substr($row["data"],6));
  1426. } else {
  1427. $users[$row["user_id"]][$PHORUM["PROFILE_FIELDS"][$row['type']]['name']] = $row["data"];
  1428. }
  1429. }
  1430. }
  1431. }
  1432. }
  1433. if(is_array($user_id)){
  1434. return $users;
  1435. } else {
  1436. return isset($users[$user_id]) ? $users[$user_id] : NULL;
  1437. }
  1438. }
  1439. /*
  1440. * Generic function to retrieve a couple of fields from the user-table
  1441. * for a couple of users or only one of them
  1442. *
  1443. * result is always an array with one or more users in it
  1444. */
  1445. function phorum_db_user_get_fields($user_id, $fields)
  1446. {
  1447. $PHORUM = $GLOBALS["PHORUM"];
  1448. $conn = phorum_db_mysqli_connect();
  1449. // input could be either array or string
  1450. if(is_array($user_id)){
  1451. $user_ids=implode(",", $user_id);
  1452. } else {
  1453. $user_ids=(int)$user_id;
  1454. }
  1455. if(is_array($fields)) {
  1456. $fields_str=implode(",",$fields);
  1457. } else {
  1458. $fields_str=$fields;
  1459. }
  1460. $users = array();
  1461. $sql = "select user_id,$fields_str from {$PHORUM['user_table']} where user_id in ($user_ids)";
  1462. $res = mysqli_query( $conn, $sql);
  1463. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1464. if (mysqli_num_rows($res)){
  1465. while($rec=mysqli_fetch_assoc($res)){
  1466. $users[$rec["user_id"]] = $rec;
  1467. }
  1468. }
  1469. return $users;
  1470. }
  1471. /**
  1472. * This function gets a list of all the active users.
  1473. * @return array - (key: userid, value: array (username, displayname)
  1474. */
  1475. function phorum_db_user_get_list(){
  1476. $PHORUM = $GLOBALS["PHORUM"];
  1477. $conn = phorum_db_mysqli_connect();
  1478. $users = array();
  1479. $sql = "select user_id, username from {$PHORUM['user_table']} order by username asc";
  1480. $res = mysqli_query( $conn, $sql);
  1481. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1482. while ($row = mysqli_fetch_assoc($res)){
  1483. $users[$row["user_id"]] = array("username" => $row["username"], "displayname" => $row["username"]);
  1484. }
  1485. return $users;
  1486. }
  1487. /**
  1488. * This function executes a query to select data about a user including
  1489. * his permission data and returns that in an array.
  1490. */
  1491. function phorum_db_user_check_pass($username, $password, $temp_password=false){
  1492. $PHORUM = $GLOBALS["PHORUM"];
  1493. $conn = phorum_db_mysqli_connect();
  1494. $username = mysqli_real_escape_string($conn, $username);
  1495. $password = mysqli_real_escape_string($conn, $password);
  1496. $pass_field = ($temp_password) ? "password_temp" : "password";
  1497. $sql = "select user_id from {$PHORUM['user_table']} where username='$username' and $pass_field='$password'";
  1498. $res = mysqli_query( $conn, $sql);
  1499. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1500. if($res && mysqli_num_rows($res)) {
  1501. $tmp_row=mysqli_fetch_row($res);
  1502. $retval=$tmp_row[0];
  1503. } else {
  1504. $retval=0;
  1505. }
  1506. return $retval;
  1507. }
  1508. /**
  1509. * This function executes a query to check for the given field in the
  1510. * user tableusername and return the user_id of the user it matches or 0
  1511. * if no match is found.
  1512. *
  1513. * The parameters can be arrays. If they are, all must be passed and all
  1514. * must have the same number of values.
  1515. *
  1516. * If $return_array is true, an array of all matching rows will be returned.
  1517. * Otherwise, only the first user_id from the results will be returned.
  1518. */
  1519. function phorum_db_user_check_field($field, $value, $operator="=", $return_array=false){
  1520. $PHORUM = $GLOBALS["PHORUM"];
  1521. $ret = 0;
  1522. $conn = phorum_db_mysqli_connect();
  1523. if(!is_array($field)){
  1524. $field=array($field);
  1525. }
  1526. if(!is_array($value)){
  1527. $value=array($value);
  1528. }
  1529. if(!is_array($operator)){
  1530. $operator=array($operator);
  1531. }
  1532. foreach($field as $key=>$name){
  1533. $value[$key] = mysqli_real_escape_string($conn, $value[$key]);
  1534. $clauses[]="$name $operator[$key] '$value[$key]'";
  1535. }
  1536. $sql = "select user_id from {$PHORUM['user_table']} where ".implode(" and ", $clauses);
  1537. $res = mysqli_query( $conn, $sql);
  1538. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1539. if ($res && mysqli_num_rows($res)){
  1540. if($return_array){
  1541. $ret=array();
  1542. while($row=mysqli_fetch_assoc($res)){
  1543. $ret[$row["user_id"]]=$row["user_id"];
  1544. }
  1545. } else {
  1546. $tmp_row=mysqli_fetch_row($res);
  1547. $ret = $tmp_row[0];
  1548. }
  1549. }
  1550. return $ret;
  1551. }
  1552. /**
  1553. * This function executes a query to add the given user data to the
  1554. * database and returns the userid or 0
  1555. */
  1556. function phorum_db_user_add($userdata){
  1557. $PHORUM = $GLOBALS["PHORUM"];
  1558. $conn = phorum_db_mysqli_connect();
  1559. if (isset($userdata["forum_permissions"]) && !empty($userdata["forum_permissions"])){
  1560. $forum_perms = $userdata["forum_permissions"];
  1561. unset($userdata["forum_permissions"]);
  1562. }
  1563. if (isset($userdata["user_data"]) && !empty($userdata["user_data"])){
  1564. $user_data = $userdata["user_data"];
  1565. unset($userdata["user_data"]);
  1566. }
  1567. $sql = "insert into {$PHORUM['user_table']} set ";
  1568. $values = array();
  1569. foreach($userdata as $key => $value){
  1570. if (!is_numeric($value)){
  1571. $value = mysqli_real_escape_string($conn, $value);
  1572. $values[] = "$key='$value'";
  1573. }else{
  1574. $values[] = "$key=$value";
  1575. }
  1576. }
  1577. $sql .= implode(", ", $values);
  1578. $res = mysqli_query( $conn, $sql);
  1579. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1580. $user_id = 0;
  1581. if ($res){
  1582. $user_id = mysqli_insert_id($conn);
  1583. }
  1584. if ($res){
  1585. if(isset($forum_perms)) {
  1586. // storing forum-permissions
  1587. foreach($forum_perms as $fid => $p){
  1588. $sql = "insert into {$PHORUM['user_permissions_table']} set user_id=$user_id, forum_id=$fid, permission=$p";
  1589. $res = mysqli_query( $conn, $sql);
  1590. if ($err = mysqli_error($conn)){
  1591. phorum_db_mysqli_error("$err: $sql");
  1592. break;
  1593. }
  1594. }
  1595. }
  1596. if(isset($user_data)) {
  1597. /* storing custom-fields */
  1598. foreach($user_data as $key => $val){
  1599. if(is_array($val)) { /* arrays need to be serialized */
  1600. $val = 'P_SER:'.serialize($val);
  1601. /* P_SER: (PHORUM_SERIALIZED is our marker telling this Field is serialized */
  1602. } else { /* other vars need to be escaped */
  1603. $val = mysqli_real_escape_string($conn, $val);
  1604. }
  1605. $sql = "insert into {$PHORUM['user_custom_fields_table']} (user_id,type,data) VALUES($user_id,$key,'$val')";
  1606. $res = mysqli_query( $conn, $sql);
  1607. if ($err = mysqli_error($conn)){
  1608. phorum_db_mysqli_error("$err: $sql");
  1609. break;
  1610. }
  1611. }
  1612. }
  1613. }
  1614. return $user_id;
  1615. }
  1616. /**
  1617. * This function executes a query to update the given user data in the
  1618. * database and returns the true or false
  1619. */
  1620. function phorum_db_user_save($userdata){
  1621. $PHORUM = $GLOBALS["PHORUM"];
  1622. $conn = phorum_db_mysqli_connect();
  1623. if(isset($userdata["permissions"])){
  1624. unset($userdata["permissions"]);
  1625. }
  1626. if (isset($userdata["forum_permissions"])){
  1627. $forum_perms = $userdata["forum_permissions"];
  1628. unset($userdata["forum_permissions"]);
  1629. }
  1630. if (isset($userdata["groups"])){
  1631. $groups = $userdata["groups"];
  1632. unset($userdata["groups"]);
  1633. unset($userdata["group_permissions"]);
  1634. }
  1635. if (isset($userdata["user_data"])){
  1636. $user_data = $userdata["user_data"];
  1637. unset($userdata["user_data"]);
  1638. }
  1639. $user_id = $userdata["user_id"];
  1640. unset($userdata["user_id"]);
  1641. if(count($userdata)){
  1642. $sql = "update {$PHORUM['user_table']} set ";
  1643. $values = array();
  1644. foreach($userdata as $key => $value){
  1645. $values[] = "$key='".mysqli_real_escape_string($conn, $value)."'";
  1646. }
  1647. $sql .= implode(", ", $values);
  1648. $sql .= " where user_id=$user_id";
  1649. $res = mysqli_query( $conn, $sql);
  1650. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1651. }
  1652. if (isset($forum_perms)){
  1653. $sql = "delete from {$PHORUM['user_permissions_table']} where user_id = $user_id";
  1654. $res=mysqli_query( $conn, $sql);
  1655. foreach($forum_perms as $fid=>$perms){
  1656. $sql = "insert into {$PHORUM['user_permissions_table']} set user_id=$user_id, forum_id=$fid, permission=$perms";
  1657. $res = mysqli_query( $conn, $sql);
  1658. if ($err = mysqli_error($conn)){
  1659. phorum_db_mysqli_error("$err: $sql");
  1660. }
  1661. }
  1662. }
  1663. if(isset($user_data)) {
  1664. // storing custom-fields
  1665. $sql = "delete from {$PHORUM['user_custom_fields_table']} where user_id = $user_id";
  1666. $res=mysqli_query( $conn, $sql);
  1667. if(is_array($user_data)) {
  1668. foreach($user_data as $key => $val){
  1669. if(is_array($val)) { /* arrays need to be serialized */
  1670. $val = 'P_SER:'.serialize($val);
  1671. /* P_SER: (PHORUM_SERIALIZED is our marker telling this Field is serialized */
  1672. } else { /* other vars need to be escaped */
  1673. $val = mysqli_real_escape_string($conn, $val);
  1674. }
  1675. $sql = "insert into {$PHORUM['user_custom_fields_table']} (user_id,type,data) VALUES($user_id,$key,'$val')";
  1676. $res = mysqli_query( $conn, $sql);
  1677. if ($err = mysqli_error($conn)){
  1678. phorum_db_mysqli_error("$err: $sql");
  1679. break;
  1680. }
  1681. }
  1682. }
  1683. }
  1684. return (bool)$res;
  1685. }
  1686. /**
  1687. * This function saves a users group permissions.
  1688. */
  1689. function phorum_db_user_save_groups($user_id, $groups)
  1690. {
  1691. $PHORUM = $GLOBALS["PHORUM"];
  1692. if (!$user_id > 0){
  1693. return false;
  1694. }
  1695. settype($user_id, "int");
  1696. // erase the group memberships they have now
  1697. $conn = phorum_db_mysqli_connect();
  1698. $sql = "delete from {$PHORUM['user_group_xref_table']} where user_id = $user_id";
  1699. $res=mysqli_query( $conn, $sql);
  1700. foreach($groups as $group_id => $group_perm){
  1701. $sql = "insert into {$PHORUM['user_group_xref_table']} set user_id=$user_id, group_id=$group_id, status=$group_perm";
  1702. mysqli_query( $conn, $sql);
  1703. if ($err = mysqli_error($conn)){
  1704. phorum_db_mysqli_error("$err: $sql");
  1705. break;
  1706. }
  1707. }
  1708. return (bool)$res;
  1709. }
  1710. /**
  1711. * This function executes a query to subscribe a user to a forum/thread.
  1712. */
  1713. function phorum_db_user_subscribe($user_id, $forum_id, $thread, $type)
  1714. {
  1715. $PHORUM = $GLOBALS["PHORUM"];
  1716. settype($user_id, "int");
  1717. settype($forum_id, "int");
  1718. settype($thread, "int");
  1719. settype($type, "int");
  1720. $conn = phorum_db_mysqli_connect();
  1721. $sql = "replace into {$PHORUM['subscribers_table']} set user_id=$user_id, forum_id=$forum_id, sub_type=$type, thread=$thread";
  1722. $res = mysqli_query( $conn, $sql);
  1723. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1724. return (bool)$res;
  1725. }
  1726. /**
  1727. * This function increases the post-counter for a user by one
  1728. */
  1729. function phorum_db_user_addpost() {
  1730. $conn = phorum_db_mysqli_connect();
  1731. $sql="UPDATE ".$GLOBALS['PHORUM']['user_table']." SET posts=posts+1 WHERE user_id = ".$GLOBALS['PHORUM']['user']['user_id'];
  1732. $res=mysqli_query( $conn, $sql);
  1733. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1734. return (bool)$res;
  1735. }
  1736. /**
  1737. * This function executes a query to unsubscribe a user to a forum/thread.
  1738. */
  1739. function phorum_db_user_unsubscribe($user_id, $thread, $forum_id=0)
  1740. {
  1741. $PHORUM = $GLOBALS["PHORUM"];
  1742. settype($user_id, "int");
  1743. settype($forum_id, "int");
  1744. settype($thread, "int");
  1745. $conn = phorum_db_mysqli_connect();
  1746. $sql = "DELETE FROM {$PHORUM['subscribers_table']} WHERE user_id=$user_id AND thread=$thread";
  1747. if($forum_id) $sql.=" and forum_id=$forum_id";
  1748. $res = mysqli_query( $conn, $sql);
  1749. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1750. return (bool)$res;
  1751. }
  1752. /**
  1753. * This function will return a list of groups the user
  1754. * is a member of, as well as the users permissions.
  1755. */
  1756. function phorum_db_user_get_groups($user_id)
  1757. {
  1758. $PHORUM = $GLOBALS["PHORUM"];
  1759. $groups = array();
  1760. if (!$user_id > 0){
  1761. return $groups;
  1762. }
  1763. settype($user_id, "int");
  1764. $conn = phorum_db_mysqli_connect();
  1765. $sql = "SELECT group_id, status FROM {$PHORUM['user_group_xref_table']} WHERE user_id = $user_id ORDER BY status DESC";
  1766. $res = mysqli_query( $conn, $sql);
  1767. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1768. while($row = mysqli_fetch_assoc($res)){
  1769. $groups[$row["group_id"]] = $row["status"];
  1770. }
  1771. return $groups;
  1772. }
  1773. /**
  1774. * This function executes a query to select data about a user including
  1775. * his permission data and returns that in an array.
  1776. * If $search is empty, all users should be returned.
  1777. */
  1778. function phorum_db_search_users($search)
  1779. {
  1780. $PHORUM = $GLOBALS["PHORUM"];
  1781. $conn = phorum_db_mysqli_connect();
  1782. $users = array();
  1783. $search = trim($search);
  1784. $sql = "select user_id, username, email, active, posts, date_last_active from {$PHORUM['user_table']} where username like '%$search%' or email like '%$search%'order by username";
  1785. $res = mysqli_query( $conn, $sql);
  1786. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1787. if (mysqli_num_rows($res)){
  1788. while ($user = mysqli_fetch_assoc($res)){
  1789. $users[$user["user_id"]] = $user;
  1790. }
  1791. }
  1792. return $users;
  1793. }
  1794. /**
  1795. * This function gets the users that await approval
  1796. */
  1797. function phorum_db_user_get_unapproved()
  1798. {
  1799. $PHORUM = $GLOBALS["PHORUM"];
  1800. $conn = phorum_db_mysqli_connect();
  1801. $sql="select user_id, username, email from {$PHORUM['user_table']} where active in(".PHORUM_USER_PENDING_BOTH.", ".PHORUM_USER_PENDING_MOD.") order by username";
  1802. $res=mysqli_query( $conn, $sql);
  1803. if ($err = mysqli_error($conn)){
  1804. phorum_db_mysqli_error("$err: $sql");
  1805. }
  1806. $users=array();
  1807. if($res){
  1808. while($rec=mysqli_fetch_assoc($res)){
  1809. $users[$rec["user_id"]]=$rec;
  1810. }
  1811. }
  1812. return $users;
  1813. }
  1814. /**
  1815. * This function deletes a user completely
  1816. * - entry in the users-table
  1817. * - entries in the permissions-table
  1818. * - entries in the newflags-table
  1819. * - entries in the subscribers-table
  1820. * - entries in the group_xref-table
  1821. * - entries in the private-messages-table
  1822. * - entries in the files-table
  1823. * - sets entries in the messages-table to anonymous
  1824. *
  1825. */
  1826. function phorum_db_user_delete($user_id) {
  1827. $PHORUM = $GLOBALS["PHORUM"];
  1828. // how would we check success???
  1829. $ret = true;
  1830. settype($user_id, "int");
  1831. $conn = phorum_db_mysqli_connect();
  1832. // user-table
  1833. $sql = "delete from {$PHORUM['user_table']} where user_id=$user_id";
  1834. $res = mysqli_query( $conn, $sql);
  1835. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1836. // permissions-table
  1837. $sql = "delete from {$PHORUM['user_permissions_table']} where user_id=$user_id";
  1838. $res = mysqli_query( $conn, $sql);
  1839. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1840. // newflags-table
  1841. $sql = "delete from {$PHORUM['user_newflags_table']} where user_id=$user_id";
  1842. $res = mysqli_query( $conn, $sql);
  1843. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1844. // subscribers-table
  1845. $sql = "delete from {$PHORUM['subscribers_table']} where user_id=$user_id";
  1846. $res = mysqli_query( $conn, $sql);
  1847. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1848. // group-xref-table
  1849. $sql = "delete from {$PHORUM['user_group_xref_table']} where user_id=$user_id";
  1850. $res = mysqli_query( $conn, $sql);
  1851. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1852. // private messages
  1853. $sql = "select * from {$PHORUM["pm_xref_table"]} where user_id=$user_id";
  1854. $res = mysqli_query( $conn, $sql);
  1855. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1856. while ($row = mysqli_fetch_assoc($res)) {
  1857. $folder = $row["pm_folder_id"] == 0 ? $row["special_folder"] : $row["pm_folder_id"];
  1858. phorum_db_pm_delete($row["pm_message_id"], $folder, $user_id);
  1859. }
  1860. // pm_buddies
  1861. $sql = "delete from {$PHORUM["pm_buddies_table"]} where user_id=$user_id or buddy_user_id=$user_id";
  1862. $res = mysqli_query( $conn, $sql);
  1863. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1864. // private message folders
  1865. $sql = "delete from {$PHORUM["pm_folders_table"]} where user_id=$user_id";
  1866. $res = mysqli_query( $conn, $sql);
  1867. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1868. // files-table
  1869. $sql = "delete from {$PHORUM['files_table']} where user_id=$user_id and message_id=0 and link='" . PHORUM_LINK_USER . "'";
  1870. $res = mysqli_query( $conn, $sql);
  1871. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1872. // custom-fields-table
  1873. $sql = "delete from {$PHORUM['user_custom_fields_table']} where user_id=$user_id";
  1874. $res = mysqli_query( $conn, $sql);
  1875. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1876. // messages-table
  1877. if(PHORUM_DELETE_CHANGE_AUTHOR) {
  1878. $sql = "update {$PHORUM['message_table']} set user_id=0,email='',author='".mysqli_real_escape_string($conn,$PHORUM['DATA']['LANG']['AnonymousUser'])."' where user_id=$user_id";
  1879. } else {
  1880. $sql = "update {$PHORUM['message_table']} set user_id=0,email='' where user_id=$user_id";
  1881. }
  1882. $res = mysqli_query( $conn, $sql);
  1883. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  1884. return $ret;
  1885. }
  1886. /**
  1887. * This function gets the users file list
  1888. */
  1889. function phorum_db_get_user_file_list($user_id)
  1890. {
  1891. $PHORUM = $GLOBALS["PHORUM"];
  1892. $conn = phorum_db_mysqli_connect();
  1893. settype($user_id, "int");
  1894. $files=array();
  1895. $sql="select file_id, filename, filesize, add_datetime from {$PHORUM['files_table']} where user_id=$user_id and message_id=0 and link='" . PHORUM_LINK_USER . "'";
  1896. $res = mysqli_query( $conn, $sql);
  1897. if ($err = mysqli_error($conn)){
  1898. phorum_db_mysqli_error("$err: $sql");
  1899. }
  1900. if($res){
  1901. while($rec=mysqli_fetch_assoc($res)){
  1902. $files[$rec["file_id"]]=$rec;
  1903. }
  1904. }
  1905. return $files;
  1906. }
  1907. /**
  1908. * This function gets the message's file list
  1909. */
  1910. function phorum_db_get_message_file_list($message_id)
  1911. {
  1912. $PHORUM = $GLOBALS["PHORUM"];
  1913. $conn = phorum_db_mysqli_connect();
  1914. $files=array();
  1915. $sql="select file_id, filename, filesize, add_datetime from {$PHORUM['files_table']} where message_id=$message_id and link='" . PHORUM_LINK_MESSAGE . "'";
  1916. $res = mysqli_query( $conn, $sql);
  1917. if ($err = mysqli_error($conn)){
  1918. phorum_db_mysqli_error("$err: $sql");
  1919. }
  1920. if($res){
  1921. while($rec=mysqli_fetch_assoc($res)){
  1922. $files[$rec["file_id"]]=$rec;
  1923. }
  1924. }
  1925. return $files;
  1926. }
  1927. /**
  1928. * This function retrieves a file from the db
  1929. */
  1930. function phorum_db_file_get($file_id)
  1931. {
  1932. $PHORUM = $GLOBALS["PHORUM"];
  1933. $conn = phorum_db_mysqli_connect();
  1934. settype($file_id, "int");
  1935. $file=array();
  1936. $sql="select * from {$PHORUM['files_table']} where file_id=$file_id";
  1937. $res = mysqli_query( $conn, $sql);
  1938. if ($err = mysqli_error($conn)){
  1939. phorum_db_mysqli_error("$err: $sql");
  1940. }
  1941. if($res){
  1942. $file=mysqli_fetch_assoc($res);
  1943. }
  1944. return $file;
  1945. }
  1946. /**
  1947. * This function saves a file to the db
  1948. */
  1949. function phorum_db_file_save($user_id, $filename, $filesize, $buffer, $message_id=0, $link=null)
  1950. {
  1951. $PHORUM = $GLOBALS["PHORUM"];
  1952. if (is_null($link)) {
  1953. $link = $message_id ? PHORUM_LINK_MESSAGE : PHORUM_LINK_USER;
  1954. } else {
  1955. $link = addslashes($link);
  1956. }
  1957. $conn = phorum_db_mysqli_connect();
  1958. $file_id=0;
  1959. settype($user_id, "int");
  1960. settype($message_id, "int");
  1961. settype($filesize, "int");
  1962. $filename=addslashes($filename);
  1963. $sql="insert into {$PHORUM['files_table']} set user_id=$user_id, message_id=$message_id, link='$link', filename='$filename', filesize=$filesize, file_data='$buffer', add_datetime=".time();
  1964. $res = mysqli_query( $conn, $sql);
  1965. if ($err = mysqli_error($conn)){
  1966. phorum_db_mysqli_error("$err: $sql");
  1967. }
  1968. if($res){
  1969. $file_id=mysqli_insert_id($conn);
  1970. }
  1971. return $file_id;
  1972. }
  1973. /**
  1974. * This function saves a file to the db
  1975. */
  1976. function phorum_db_file_delete($file_id)
  1977. {
  1978. $PHORUM = $GLOBALS["PHORUM"];
  1979. $conn = phorum_db_mysqli_connect();
  1980. settype($file_id, "int");
  1981. $sql="delete from {$PHORUM['files_table']} where file_id=$file_id";
  1982. $res = mysqli_query( $conn, $sql);
  1983. if ($err = mysqli_error($conn)){
  1984. phorum_db_mysqli_error("$err: $sql");
  1985. }
  1986. return $res;
  1987. }
  1988. /**
  1989. * This function links a file to a specific message
  1990. */
  1991. function phorum_db_file_link($file_id, $message_id, $link = null)
  1992. {
  1993. $PHORUM = $GLOBALS["PHORUM"];
  1994. if (is_null($link)) {
  1995. $link = $message_id ? PHORUM_LINK_MESSAGE : PHORUM_LINK_USER;
  1996. } else {
  1997. $link = addslashes($link);
  1998. }
  1999. $conn = phorum_db_mysqli_connect();
  2000. settype($file_id, "int");
  2001. settype($message_id, "int");
  2002. $sql="update {$PHORUM['files_table']} " .
  2003. "set message_id=$message_id, link='$link' " .
  2004. "where file_id=$file_id";
  2005. $res = mysqli_query( $conn, $sql);
  2006. if ($err = mysqli_error($conn)){
  2007. phorum_db_mysqli_error("$err: $sql");
  2008. }
  2009. return $res;
  2010. }
  2011. /**
  2012. * This function reads the current total size of all files for a user
  2013. */
  2014. function phorum_db_get_user_filesize_total($user_id)
  2015. {
  2016. $PHORUM = $GLOBALS["PHORUM"];
  2017. $conn = phorum_db_mysqli_connect();
  2018. settype($user_id, "int");
  2019. $total=0;
  2020. $sql="select sum(filesize) as total from {$PHORUM['files_table']} where user_id=$user_id and message_id=0 and link='" . PHORUM_LINK_USER . "'";
  2021. $res = mysqli_query( $conn, $sql);
  2022. if ($err = mysqli_error($conn)){
  2023. phorum_db_mysqli_error("$err: $sql");
  2024. }
  2025. if($res){
  2026. $tmp_row=mysqli_fetch_row($res);
  2027. $total=$tmp_row[0];
  2028. }
  2029. return $total;
  2030. }
  2031. /**
  2032. * This function is used for cleaning up stale files from the
  2033. * database. Stale files are files that are not linked to
  2034. * anything. These can for example be caused by users that
  2035. * are writing a message with attachments, but never post
  2036. * it.
  2037. * @param live_run - If set to false (default), the function
  2038. * will return a list of files that will
  2039. * be purged. If set to true, files will
  2040. * be purged.
  2041. */
  2042. function phorum_db_file_purge_stale_files($live_run = false)
  2043. {
  2044. $PHORUM = $GLOBALS["PHORUM"];
  2045. $conn = phorum_db_mysqli_connect();
  2046. $where = "link='" . PHORUM_LINK_EDITOR. "' " .
  2047. "and add_datetime<". (time()-PHORUM_MAX_EDIT_TIME);
  2048. // Purge files.
  2049. if ($live_run) {
  2050. // Delete files that are linked to the editor and are
  2051. // added a while ago. These are from abandoned posts.
  2052. $sql = "delete from {$PHORUM['files_table']} " .
  2053. "where $where";
  2054. $res = mysqli_query( $conn, $sql);
  2055. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2056. return true;
  2057. // Only select a list of files that can be purged.
  2058. } else {
  2059. // Select files that are linked to the editor and are
  2060. // added a while ago. These are from abandoned posts.
  2061. $sql = "select file_id, filename, filesize, add_datetime " .
  2062. "from {$PHORUM['files_table']} " .
  2063. "where $where";
  2064. $res = mysqli_query( $conn, $sql);
  2065. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2066. $purge_files = array();
  2067. if (mysqli_num_rows($res) > 0) {
  2068. while ($row = mysqli_fetch_assoc($res)) {
  2069. $row["reason"] = "Stale editor file";
  2070. $purge_files[$row["file_id"]] = $row;
  2071. }
  2072. }
  2073. return $purge_files;
  2074. }
  2075. }
  2076. /**
  2077. * This function returns the newinfo-array for markallread
  2078. */
  2079. function phorum_db_newflag_allread($forum_id=0)
  2080. {
  2081. $PHORUM = $GLOBALS['PHORUM'];
  2082. $conn = phorum_db_mysqli_connect();
  2083. settype($forum_id, "int");
  2084. if(empty($forum_id)) $forum_id=$PHORUM["forum_id"];
  2085. // delete all newflags for this user and forum
  2086. phorum_db_newflag_delete(0,$forum_id);
  2087. // get the maximum message-id in this forum
  2088. $sql = "select max(message_id) from {$PHORUM['message_table']} where forum_id=$forum_id";
  2089. $res = mysqli_query( $conn, $sql);
  2090. if ($err = mysqli_error($conn)){
  2091. phorum_db_mysqli_error("$err: $sql");
  2092. }elseif (mysqli_num_rows($res) > 0){
  2093. $row = mysqli_fetch_row($res);
  2094. if($row[0] > 0) {
  2095. // set this message as min-id
  2096. phorum_db_newflag_add_read(array(0=>array('id'=>$row[0],'forum'=>$forum_id)));
  2097. }
  2098. }
  2099. }
  2100. /**
  2101. * This function returns the read messages for the current user and forum
  2102. * optionally for a given forum (for the index)
  2103. */
  2104. function phorum_db_newflag_get_flags($forum_id=0)
  2105. {
  2106. $PHORUM = $GLOBALS["PHORUM"];
  2107. settype($forum_id, "int");
  2108. $read_msgs=array('min_id'=>0);
  2109. if(empty($forum_id)) $forum_id=$PHORUM["forum_id"];
  2110. $sql="SELECT message_id,forum_id FROM ".$PHORUM['user_newflags_table']." WHERE user_id={$PHORUM['user']['user_id']} AND forum_id IN({$forum_id},{$PHORUM['vroot']})";
  2111. $conn = phorum_db_mysqli_connect();
  2112. $res = mysqli_query( $conn, $sql);
  2113. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2114. while($row=mysqli_fetch_row($res)) {
  2115. // set the min-id if given flag is set
  2116. if($row[1] != $PHORUM['vroot'] && ($read_msgs['min_id']==0 || $row[0] < $read_msgs['min_id'])) {
  2117. $read_msgs['min_id']=$row[0];
  2118. } else {
  2119. $read_msgs[$row[0]]=$row[0];
  2120. }
  2121. }
  2122. return $read_msgs;
  2123. }
  2124. /**
  2125. * This function returns the count of unread messages the current user and forum
  2126. * optionally for a given forum (for the index)
  2127. */
  2128. function phorum_db_newflag_get_unread_count($forum_id=0)
  2129. {
  2130. $PHORUM = $GLOBALS["PHORUM"];
  2131. settype($forum_id, "int");
  2132. if(empty($forum_id)) $forum_id=$PHORUM["forum_id"];
  2133. // get the read message array
  2134. $read_msgs = phorum_db_newflag_get_flags($forum_id);
  2135. if($read_msgs["min_id"]==0) return array(0,0);
  2136. $sql="SELECT count(*) as count FROM ".$PHORUM['message_table']." WHERE message_id NOT in (".implode(",", $read_msgs).") and message_id > {$read_msgs['min_id']} and forum_id in ({$forum_id},0) and status=".PHORUM_STATUS_APPROVED." and not ".PHORUM_SQL_MOVEDMESSAGES;
  2137. $conn = phorum_db_mysqli_connect();
  2138. $res = mysqli_query( $conn, $sql);
  2139. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2140. $tmp_row=mysqli_fetch_row($res);
  2141. $counts[] = $tmp_row[0];
  2142. $sql="SELECT count(*) as count FROM ".$PHORUM['message_table']." WHERE message_id NOT in (".implode(",", $read_msgs).") and message_id > {$read_msgs['min_id']} and forum_id in ({$forum_id},0) and parent_id=0 and status=".PHORUM_STATUS_APPROVED." and not ".PHORUM_SQL_MOVEDMESSAGES;
  2143. $conn = phorum_db_mysqli_connect();
  2144. $res = mysqli_query( $conn, $sql);
  2145. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2146. $tmp_row=mysqli_fetch_row($res);
  2147. $counts[] = $tmp_row[0];
  2148. return $counts;
  2149. }
  2150. /**
  2151. * This function marks a message as read
  2152. */
  2153. function phorum_db_newflag_add_read($message_ids) {
  2154. $PHORUM = $GLOBALS["PHORUM"];
  2155. $num_newflags=phorum_db_newflag_get_count();
  2156. // maybe got just one message
  2157. if(!is_array($message_ids)) {
  2158. $message_ids=array(0=>(int)$message_ids);
  2159. }
  2160. // deleting messages which are too much
  2161. $num_end=$num_newflags+count($message_ids);
  2162. if($num_end > PHORUM_MAX_NEW_INFO) {
  2163. phorum_db_newflag_delete($num_end - PHORUM_MAX_NEW_INFO);
  2164. }
  2165. // building the query
  2166. $values=array();
  2167. $cnt=0;
  2168. foreach($message_ids as $id=>$data) {
  2169. if(is_array($data)) {
  2170. $values[]="({$PHORUM['user']['user_id']},{$data['forum']},{$data['id']})";
  2171. } else {
  2172. $values[]="({$PHORUM['user']['user_id']},{$PHORUM['forum_id']},$data)";
  2173. }
  2174. $cnt++;
  2175. }
  2176. if($cnt) {
  2177. $insert_sql="INSERT IGNORE INTO ".$PHORUM['user_newflags_table']." (user_id,forum_id,message_id) VALUES".join(",",$values);
  2178. // fire away
  2179. $conn = phorum_db_mysqli_connect();
  2180. $res = mysqli_query($conn, $insert_sql);
  2181. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $insert_sql");
  2182. }
  2183. }
  2184. /**
  2185. * This function returns the number of newflags for this user and forum
  2186. */
  2187. function phorum_db_newflag_get_count($forum_id=0)
  2188. {
  2189. $PHORUM = $GLOBALS["PHORUM"];
  2190. settype($forum_id, "int");
  2191. if(empty($forum_id)) $forum_id=$PHORUM["forum_id"];
  2192. $sql="SELECT count(*) FROM ".$PHORUM['user_newflags_table']." WHERE user_id={$PHORUM['user']['user_id']} AND forum_id={$forum_id}";
  2193. // fire away
  2194. $conn = phorum_db_mysqli_connect();
  2195. $res = mysqli_query( $conn, $sql);
  2196. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2197. $row=mysqli_fetch_row($res);
  2198. return $row[0];
  2199. }
  2200. /**
  2201. * This function removes a number of newflags for this user and forum
  2202. */
  2203. function phorum_db_newflag_delete($numdelete=0,$forum_id=0)
  2204. {
  2205. $PHORUM = $GLOBALS["PHORUM"];
  2206. settype($forum_id, "int");
  2207. settype($numdelete, "int");
  2208. if(empty($forum_id)) $forum_id=$PHORUM["forum_id"];
  2209. if($numdelete>0) {
  2210. $lvar=" ORDER BY message_id ASC LIMIT $numdelete";
  2211. } else {
  2212. $lvar="";
  2213. }
  2214. // delete the number of newflags given
  2215. $del_sql="DELETE FROM ".$PHORUM['user_newflags_table']." WHERE user_id={$PHORUM['user']['user_id']} AND forum_id={$forum_id}".$lvar;
  2216. // fire away
  2217. $conn = phorum_db_mysqli_connect();
  2218. $res = mysqli_query($conn, $del_sql);
  2219. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $del_sql");
  2220. }
  2221. /**
  2222. * This function executes a query to get the user ids of the users
  2223. * subscribed to a forum/thread.
  2224. */
  2225. function phorum_db_get_subscribed_users($forum_id, $thread, $type){
  2226. $PHORUM = $GLOBALS["PHORUM"];
  2227. settype($forum_id, "int");
  2228. settype($thread, "int");
  2229. settype($type, "int");
  2230. $conn = phorum_db_mysqli_connect();
  2231. $userignore="";
  2232. if ($PHORUM["DATA"]["LOGGEDIN"])
  2233. $userignore="and b.user_id != {$PHORUM['user']['user_id']}";
  2234. $sql = "select DISTINCT(b.email),user_language from {$PHORUM['subscribers_table']} as a,{$PHORUM['user_table']} as b where a.forum_id=$forum_id and (a.thread=$thread or a.thread=0) and a.sub_type=$type and b.user_id=a.user_id $userignore";
  2235. $res = mysqli_query( $conn, $sql);
  2236. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2237. $arr=array();
  2238. while ($rec = mysqli_fetch_row($res)){
  2239. if(!empty($rec[1])) // user-language is set
  2240. $arr[$rec[1]][] = $rec[0];
  2241. else // no user-language is set
  2242. $arr[$PHORUM['language']][]= $rec[0];
  2243. }
  2244. return $arr;
  2245. }
  2246. /**
  2247. * This function executes a query to get the subscriptions of a user-id,
  2248. * together with the forum-id and subjects of the threads
  2249. */
  2250. function phorum_db_get_message_subscriptions($user_id,$days=2){
  2251. $PHORUM = $GLOBALS["PHORUM"];
  2252. $conn = phorum_db_mysqli_connect();
  2253. $userignore="";
  2254. if ($PHORUM["DATA"]["LOGGEDIN"])
  2255. $userignore="and b.user_id != {$PHORUM['user']['user_id']}";
  2256. if($days > 0) {
  2257. $timestr=" AND (".time()." - b.modifystamp) <= ($days * 86400)";
  2258. } else {
  2259. $timestr="";
  2260. }
  2261. $sql = "select a.thread, a.forum_id, a.sub_type, b.subject,b.modifystamp,b.author,b.user_id,b.email from {$PHORUM['subscribers_table']} as a,{$PHORUM['message_table']} as b where a.user_id=$user_id and b.message_id=a.thread and (a.sub_type=".PHORUM_SUBSCRIPTION_MESSAGE." or a.sub_type=".PHORUM_SUBSCRIPTION_BOOKMARK.")"."$timestr ORDER BY b.modifystamp desc";
  2262. $res = mysqli_query( $conn, $sql);
  2263. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2264. $arr=array();
  2265. $forum_ids=array();
  2266. while ($rec = mysqli_fetch_assoc($res)){
  2267. $unsub_url=phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=".PHORUM_CC_SUBSCRIPTION_THREADS, "unsub_id=".$rec['thread'], "unsub_forum=".$rec['forum_id'], "unsub_type=".$rec['sub_type']);
  2268. $rec['unsubscribe_url']=$unsub_url;
  2269. $arr[] = $rec;
  2270. $forum_ids[]=$rec['forum_id'];
  2271. }
  2272. $arr['forum_ids']=$forum_ids;
  2273. return $arr;
  2274. }
  2275. /**
  2276. * This function executes a query to find out if a user is subscribed to a thread
  2277. */
  2278. function phorum_db_get_if_subscribed($forum_id, $thread, $user_id, $type=PHORUM_SUBSCRIPTION_MESSAGE)
  2279. {
  2280. $PHORUM = $GLOBALS["PHORUM"];
  2281. settype($forum_id, "int");
  2282. settype($thread, "int");
  2283. settype($user_id, "int");
  2284. settype($type, "int");
  2285. $conn = phorum_db_mysqli_connect();
  2286. $sql = "select user_id from {$PHORUM['subscribers_table']} where forum_id=$forum_id and thread=$thread and user_id=$user_id and sub_type=$type";
  2287. $res = mysqli_query( $conn, $sql);
  2288. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2289. if (mysqli_num_rows($res) > 0){
  2290. $retval = true;
  2291. }else{
  2292. $retval = false;
  2293. }
  2294. return $retval;
  2295. }
  2296. /**
  2297. * This function retrieves the banlists for the current forum
  2298. */
  2299. function phorum_db_get_banlists($ordered=false) {
  2300. $PHORUM = $GLOBALS["PHORUM"];
  2301. $retarr = array();
  2302. $forumstr = "";
  2303. $conn = phorum_db_mysqli_connect();
  2304. if(isset($PHORUM['forum_id']) && !empty($PHORUM['forum_id']))
  2305. $forumstr = "WHERE forum_id = {$PHORUM['forum_id']} OR forum_id = 0";
  2306. if(isset($PHORUM['vroot']) && !empty($PHORUM['vroot']))
  2307. $forumstr .= " OR forum_id = {$PHORUM['vroot']}";
  2308. $sql = "SELECT * FROM {$PHORUM['banlist_table']} $forumstr";
  2309. if($ordered) {
  2310. $sql.= " ORDER BY type, string";
  2311. }
  2312. $res = mysqli_query( $conn, $sql);
  2313. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2314. if (mysqli_num_rows($res) > 0){
  2315. while($row = mysqli_fetch_assoc($res)) {
  2316. $retarr[$row['type']][$row['id']]=array('pcre'=>$row['pcre'],'string'=>$row['string'],'forum_id'=>$row['forum_id']);
  2317. }
  2318. }
  2319. return $retarr;
  2320. }
  2321. /**
  2322. * This function retrieves one item from the banlists
  2323. */
  2324. function phorum_db_get_banitem($banid) {
  2325. $PHORUM = $GLOBALS["PHORUM"];
  2326. $retarr = array();
  2327. $conn = phorum_db_mysqli_connect();
  2328. settype($banid, "int");
  2329. $sql = "SELECT * FROM {$PHORUM['banlist_table']} WHERE id = $banid";
  2330. $res = mysqli_query( $conn, $sql);
  2331. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2332. if (mysqli_num_rows($res) > 0){
  2333. while($row = mysqli_fetch_assoc($res)) {
  2334. $retarr=array('pcre'=>$row['pcre'],'string'=>$row['string'],'forumid'=>$row['forum_id'],'type'=>$row['type']);
  2335. }
  2336. }
  2337. return $retarr;
  2338. }
  2339. /**
  2340. * This function deletes one item from the banlists
  2341. */
  2342. function phorum_db_del_banitem($banid) {
  2343. $PHORUM = $GLOBALS["PHORUM"];
  2344. $conn = phorum_db_mysqli_connect();
  2345. $sql = "DELETE FROM {$PHORUM['banlist_table']} WHERE id = $banid";
  2346. $res = mysqli_query( $conn, $sql);
  2347. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2348. if(mysqli_affected_rows($conn) > 0) {
  2349. return true;
  2350. } else {
  2351. return false;
  2352. }
  2353. }
  2354. /**
  2355. * This function adds or modifies a banlist-entry
  2356. */
  2357. function phorum_db_mod_banlists($type,$pcre,$string,$forum_id,$id=0) {
  2358. $PHORUM = $GLOBALS["PHORUM"];
  2359. $retarr = array();
  2360. $conn = phorum_db_mysqli_connect();
  2361. settype($type, "int");
  2362. settype($pcre, "int");
  2363. settype($forum_id, "int");
  2364. settype($id, "int");
  2365. if($id > 0) { // modifying an entry
  2366. $sql = "UPDATE {$PHORUM['banlist_table']} SET forum_id = $forum_id, type = $type, pcre = $pcre, string = '".mysqli_real_escape_string($conn, $string)."' where id = $id";
  2367. } else { // adding an entry
  2368. $sql = "INSERT INTO {$PHORUM['banlist_table']} (forum_id,type,pcre,string) VALUES($forum_id,$type,$pcre,'".mysqli_real_escape_string($conn, $string)."')";
  2369. }
  2370. $res = mysqli_query( $conn, $sql);
  2371. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2372. if(mysqli_affected_rows($conn) > 0) {
  2373. return true;
  2374. } else {
  2375. return false;
  2376. }
  2377. }
  2378. /**
  2379. * This function lists all private messages in a folder.
  2380. * @param folder - The folder to use. Either a special folder
  2381. * (PHORUM_PM_INBOX or PHORUM_PM_OUTBOX) or the
  2382. * id of a user's custom folder.
  2383. * @param user_id - The user to retrieve messages for or NULL
  2384. * to use the current user (default).
  2385. * @param reverse - If set to a true value (default), sorting
  2386. * of messages is done in reverse (newest first).
  2387. */
  2388. function phorum_db_pm_list($folder, $user_id = NULL, $reverse = true)
  2389. {
  2390. $PHORUM = $GLOBALS["PHORUM"];
  2391. $conn = phorum_db_mysqli_connect();
  2392. if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
  2393. settype($user_id, "int");
  2394. $folder_sql = "user_id = $user_id AND ";
  2395. if (is_numeric($folder)) {
  2396. $folder_sql .= "pm_folder_id=$folder";
  2397. } elseif ($folder == PHORUM_PM_INBOX || $folder == PHORUM_PM_OUTBOX) {
  2398. $folder_sql .= "pm_folder_id=0 AND special_folder='$folder'";
  2399. } else {
  2400. die ("Illegal folder '$folder' requested for user id '$user_id'");
  2401. }
  2402. $sql = "SELECT m.pm_message_id, from_user_id, from_username, subject, " .
  2403. "datestamp, meta, pm_xref_id, user_id, pm_folder_id, " .
  2404. "special_folder, read_flag, reply_flag " .
  2405. "FROM {$PHORUM['pm_messages_table']} as m, {$PHORUM['pm_xref_table']} as x " .
  2406. "WHERE $folder_sql " .
  2407. "AND x.pm_message_id = m.pm_message_id " .
  2408. "ORDER BY x.pm_message_id " . ($reverse ? "DESC" : "ASC");
  2409. $res = mysqli_query( $conn, $sql);
  2410. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2411. $list = array();
  2412. if (mysqli_num_rows($res) > 0){
  2413. while($row = mysqli_fetch_assoc($res)) {
  2414. // Add the recipient information unserialized to the message..
  2415. $meta = unserialize($row['meta']);
  2416. $row['recipients'] = $meta['recipients'];
  2417. $list[$row["pm_message_id"]]=$row;
  2418. }
  2419. }
  2420. return $list;
  2421. }
  2422. /**
  2423. * This function retrieves a private message from the database.
  2424. * @param pm_id - The id for the private message to retrieve.
  2425. * @param user_id - The user to retrieve messages for or NULL
  2426. * to use the current user (default).
  2427. * @param folder_id - The folder to retrieve the message from or
  2428. * NULL if the folder does not matter.
  2429. */
  2430. function phorum_db_pm_get($pm_id, $folder = NULL, $user_id = NULL)
  2431. {
  2432. $PHORUM = $GLOBALS["PHORUM"];
  2433. $conn = phorum_db_mysqli_connect();
  2434. if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
  2435. settype($user_id, "int");
  2436. settype($pm_id, "int");
  2437. if (is_null($folder)) {
  2438. $folder_sql = '';
  2439. } elseif (is_numeric($folder)) {
  2440. $folder_sql = "pm_folder_id=$folder AND ";
  2441. } elseif ($folder == PHORUM_PM_INBOX || $folder == PHORUM_PM_OUTBOX) {
  2442. $folder_sql = "pm_folder_id=0 AND special_folder='$folder' AND ";
  2443. } else {
  2444. die ("Illegal folder '$folder' requested for message id '$pm_id'");
  2445. }
  2446. $sql = "SELECT * " .
  2447. "FROM {$PHORUM['pm_messages_table']} as m, {$PHORUM['pm_xref_table']} as x " .
  2448. "WHERE $folder_sql x.pm_message_id = $pm_id AND x.user_id = $user_id " .
  2449. "AND x.pm_message_id = m.pm_message_id";
  2450. $res = mysqli_query( $conn, $sql);
  2451. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2452. if (mysqli_num_rows($res) > 0){
  2453. $row = mysqli_fetch_assoc($res);
  2454. // Add the recipient information unserialized to the message..
  2455. $meta = unserialize($row['meta']);
  2456. $row['recipients'] = $meta['recipients'];
  2457. return $row;
  2458. } else {
  2459. return NULL;
  2460. }
  2461. }
  2462. /**
  2463. * This function creates a new folder for a user.
  2464. * @param foldername - The name of the folder to create.
  2465. * @param user_id - The user to create the folder for or
  2466. * NULL to use the current user (default).
  2467. */
  2468. function phorum_db_pm_create_folder($foldername, $user_id = NULL)
  2469. {
  2470. $PHORUM = $GLOBALS["PHORUM"];
  2471. $conn = phorum_db_mysqli_connect();
  2472. if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
  2473. settype($user_id, "int");
  2474. $sql = "INSERT INTO {$PHORUM['pm_folders_table']} SET " .
  2475. "user_id=$user_id, " .
  2476. "foldername='".mysqli_real_escape_string($conn, $foldername)."'";
  2477. $res = mysqli_query( $conn, $sql);
  2478. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2479. return $res;
  2480. }
  2481. /**
  2482. * This function renames a folder for a user.
  2483. * @param folder_id - The id of the folder to rename.
  2484. * @param newname - The new name for the folder.
  2485. * @param user_id - The user to rename the folder for or
  2486. * NULL to use the current user (default).
  2487. */
  2488. function phorum_db_pm_rename_folder($folder_id, $newname, $user_id = NULL)
  2489. {
  2490. $PHORUM = $GLOBALS["PHORUM"];
  2491. $conn = phorum_db_mysqli_connect();
  2492. if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
  2493. settype($user_id, "int");
  2494. settype($folder_id, "int");
  2495. $sql = "UPDATE {$PHORUM['pm_folders_table']} " .
  2496. "SET foldername = '".mysqli_real_escape_string($conn, $newname)."' " .
  2497. "WHERE pm_folder_id = $folder_id AND user_id = $user_id";
  2498. $res = mysqli_query( $conn, $sql);
  2499. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2500. return $res;
  2501. }
  2502. /**
  2503. * This function deletes a folder for a user. Along with the
  2504. * folder, all contained messages are deleted as well.
  2505. * @param folder_id - The id of the folder to delete.
  2506. * @param user_id - The user to delete the folder for or
  2507. * NULL to use the current user (default).
  2508. */
  2509. function phorum_db_pm_delete_folder($folder_id, $user_id = NULL)
  2510. {
  2511. $PHORUM = $GLOBALS["PHORUM"];
  2512. $conn = phorum_db_mysqli_connect();
  2513. if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
  2514. settype($user_id, "int");
  2515. settype($folder_id, "int");
  2516. // Get messages in this folder and delete them.
  2517. $list = phorum_db_pm_list($folder_id, $user_id);
  2518. foreach ($list as $id => $data) {
  2519. phorum_db_pm_delete($id, $folder_id, $user_id);
  2520. }
  2521. // Delete the folder itself.
  2522. $sql = "DELETE FROM {$PHORUM['pm_folders_table']} " .
  2523. "WHERE pm_folder_id = $folder_id AND user_id = $user_id";
  2524. $res = mysqli_query( $conn, $sql);
  2525. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2526. return $res;
  2527. }
  2528. /**
  2529. * This function retrieves the list of folders for a user.
  2530. * @param user_id - The user to retrieve folders for or NULL
  2531. * to use the current user (default).
  2532. * @param count_messages - Count the number of messages for the
  2533. * folders. Default, this is not done.
  2534. */
  2535. function phorum_db_pm_getfolders($user_id = NULL, $count_messages = false)
  2536. {
  2537. $PHORUM = $GLOBALS["PHORUM"];
  2538. $conn = phorum_db_mysqli_connect();
  2539. if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
  2540. settype($user_id, "int");
  2541. // Setup the list of folders. Our special folders are
  2542. // not in the database, so these are added here.
  2543. $folders = array(
  2544. PHORUM_PM_INBOX => array(
  2545. 'id' => PHORUM_PM_INBOX,
  2546. 'name' => $PHORUM["DATA"]["LANG"]["INBOX"],
  2547. ),
  2548. );
  2549. // Select all custom folders for the user.
  2550. $sql = "SELECT * FROM {$PHORUM['pm_folders_table']} " .
  2551. "WHERE user_id = $user_id ORDER BY foldername";
  2552. $res = mysqli_query( $conn, $sql);
  2553. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2554. // Add them to the folderlist.
  2555. if (mysqli_num_rows($res) > 0){
  2556. while (($row = mysqli_fetch_assoc($res))) {
  2557. $folders[$row["pm_folder_id"]] = array(
  2558. 'id' => $row["pm_folder_id"],
  2559. 'name' => $row["foldername"],
  2560. );
  2561. }
  2562. }
  2563. // Add the outgoing box.
  2564. $folders[PHORUM_PM_OUTBOX] = array(
  2565. 'id' => PHORUM_PM_OUTBOX,
  2566. 'name' => $PHORUM["DATA"]["LANG"]["SentItems"],
  2567. );
  2568. // Count messages if requested.
  2569. if ($count_messages)
  2570. {
  2571. // Initialize counters.
  2572. foreach ($folders as $id => $data) {
  2573. $folders[$id]["total"] = $folders[$id]["new"] = 0;
  2574. }
  2575. // Collect count information.
  2576. $sql = "SELECT pm_folder_id, special_folder, " .
  2577. "count(*) as total, (count(*) - sum(read_flag)) as new " .
  2578. "FROM {$PHORUM['pm_xref_table']} " .
  2579. "WHERE user_id = $user_id " .
  2580. "GROUP BY pm_folder_id, special_folder";
  2581. $res = mysqli_query( $conn, $sql);
  2582. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2583. // Add counters to the folderlist.
  2584. if (mysqli_num_rows($res) > 0){
  2585. while (($row = mysqli_fetch_assoc($res))) {
  2586. $folder_id = $row["pm_folder_id"] ? $row["pm_folder_id"] : $row["special_folder"];
  2587. // If there are stale messages, we do not want them
  2588. // to create non-existant mailboxes in the list.
  2589. if (isset($folders[$folder_id])) {
  2590. $folders[$folder_id]["total"] = $row["total"];
  2591. $folders[$folder_id]["new"] = $row["new"];
  2592. }
  2593. }
  2594. }
  2595. }
  2596. return $folders;
  2597. }
  2598. /**
  2599. * This function computes the number of private messages a user has
  2600. * and returns both the total and the number unread.
  2601. * @param folder - The folder to use. Either a special folder
  2602. * (PHORUM_PM_INBOX or PHORUM_PM_OUTBOX), the
  2603. * id of a user's custom folder or
  2604. * PHORUM_PM_ALLFOLDERS for all folders.
  2605. * @param user_id - The user to retrieve messages for or NULL
  2606. * to use the current user (default).
  2607. */
  2608. function phorum_db_pm_messagecount($folder, $user_id = NULL)
  2609. {
  2610. $PHORUM = $GLOBALS["PHORUM"];
  2611. $conn = phorum_db_mysqli_connect();
  2612. if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
  2613. settype($user_id, "int");
  2614. if (is_numeric($folder)) {
  2615. $folder_sql = "pm_folder_id=$folder AND";
  2616. } elseif ($folder == PHORUM_PM_INBOX || $folder == PHORUM_PM_OUTBOX) {
  2617. $folder_sql = "pm_folder_id=0 AND special_folder='$folder' AND";
  2618. } elseif ($folder == PHORUM_PM_ALLFOLDERS) {
  2619. $folder_sql = '';
  2620. } else {
  2621. die ("Illegal folder '$folder' requested for user id '$user_id'");
  2622. }
  2623. $sql = "SELECT count(*) as total, (count(*) - sum(read_flag)) as new " .
  2624. "FROM {$PHORUM['pm_xref_table']} " .
  2625. "WHERE $folder_sql user_id = $user_id";
  2626. $messagecount=array("total" => 0, "new" => 0);
  2627. $res = mysqli_query( $conn, $sql);
  2628. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2629. if (mysqli_num_rows($res) > 0){
  2630. $row = mysqli_fetch_assoc($res);
  2631. $messagecount["total"] = $row["total"];
  2632. $messagecount["new"] = ($row["new"] >= 1) ? $row["new"] : 0;
  2633. }
  2634. return $messagecount;
  2635. }
  2636. /**
  2637. * This function does a quick check if the user has new private messages.
  2638. * This is useful in case you only want to know whether the user has
  2639. * new messages or not and when you are not interested in the exact amount
  2640. * of new messages.
  2641. *
  2642. * @param user_id - The user to retrieve messages for or NULL
  2643. * to use the current user (default).
  2644. * @return A true value, in case there are new messages available.
  2645. */
  2646. function phorum_db_pm_checknew($user_id = NULL)
  2647. {
  2648. $PHORUM = $GLOBALS["PHORUM"];
  2649. $conn = phorum_db_mysqli_connect();
  2650. if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
  2651. settype($user_id, "int");
  2652. $sql = "SELECT user_id " .
  2653. "FROM {$PHORUM['pm_xref_table']} " .
  2654. "WHERE user_id = $user_id AND read_flag = 0 LIMIT 1";
  2655. $res = mysqli_query( $conn, $sql);
  2656. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2657. return mysqli_num_rows($res);
  2658. }
  2659. /**
  2660. * This function inserts a private message in the database. The return value
  2661. * is the pm_message_id of the created message.
  2662. * @param subject - The subject for the private message.
  2663. * @param message - The message text for the private message.
  2664. * @param to - A single user_id or an array of user_ids for the recipients.
  2665. * @param from - The user_id of the sender. The current user is used in case
  2666. * the parameter is set to NULL (default).
  2667. * @param keepcopy - If set to a true value, a copy of the mail will be put in
  2668. * the outbox of the user. Default value is false.
  2669. */
  2670. function phorum_db_pm_send($subject, $message, $to, $from=NULL, $keepcopy=false)
  2671. {
  2672. $PHORUM = $GLOBALS["PHORUM"];
  2673. $conn = phorum_db_mysqli_connect();
  2674. // Prepare the sender.
  2675. if ($from == NULL) $from = $PHORUM['user']['user_id'];
  2676. settype($from, "int");
  2677. $fromuser = phorum_db_user_get($from, false);
  2678. if (! $fromuser) die("Unknown sender user_id '$from'");
  2679. // This array will be filled with xref database entries.
  2680. $xref_entries = array();
  2681. // Prepare the list of recipients.
  2682. $rcpts = array();
  2683. if (! is_array($to)) $to = array($to);
  2684. foreach ($to as $user_id) {
  2685. settype($user_id, "int");
  2686. $user = phorum_db_user_get($user_id, false);
  2687. if (! $user) die("Unknown recipient user_id '$user_id'");
  2688. $rcpts[$user_id] = array(
  2689. 'user_id' => $user_id,
  2690. 'username' => $user["username"],
  2691. 'read_flag' => 0,
  2692. );
  2693. $xref_entries[] = array(
  2694. 'user_id' => $user_id,
  2695. 'pm_folder_id' => 0,
  2696. 'special_folder' => PHORUM_PM_INBOX,
  2697. 'read_flag' => 0,
  2698. );
  2699. }
  2700. // Keep copy of this message in outbox?
  2701. if ($keepcopy) {
  2702. $xref_entries[] = array(
  2703. 'user_id' => $from,
  2704. 'pm_folder_id' => 0,
  2705. 'special_folder' => PHORUM_PM_OUTBOX,
  2706. 'read_flag' => 1,
  2707. );
  2708. }
  2709. // Prepare message meta data.
  2710. $meta = mysqli_real_escape_string($conn, serialize(array(
  2711. 'recipients' => $rcpts
  2712. )));
  2713. // Create the message.
  2714. $sql = "INSERT INTO {$PHORUM["pm_messages_table"]} SET " .
  2715. "from_user_id = $from, " .
  2716. "from_username = '".mysqli_real_escape_string($conn, $fromuser["username"])."', " .
  2717. "subject = '".mysqli_real_escape_string($conn, $subject)."', " .
  2718. "message = '".mysqli_real_escape_string($conn, $message)."', " .
  2719. "datestamp = '".time()."', " .
  2720. "meta = '$meta'";
  2721. mysqli_query( $conn, $sql);
  2722. if ($err = mysqli_error($conn)) {
  2723. phorum_db_mysqli_error("$err: $sql");
  2724. return;
  2725. }
  2726. // Get the message id.
  2727. $pm_message_id = mysqli_insert_id($conn);
  2728. // Put the message in the recipient inboxes.
  2729. foreach ($xref_entries as $xref) {
  2730. $sql = "INSERT INTO {$PHORUM["pm_xref_table"]} SET " .
  2731. "user_id = {$xref["user_id"]}, " .
  2732. "pm_folder_id={$xref["pm_folder_id"]}, " .
  2733. "special_folder='{$xref["special_folder"]}', " .
  2734. "pm_message_id=$pm_message_id, " .
  2735. "read_flag = {$xref["read_flag"]}, " .
  2736. "reply_flag = 0";
  2737. mysqli_query( $conn, $sql);
  2738. if ($err = mysqli_error($conn)) {
  2739. phorum_db_mysqli_error("$err: $sql");
  2740. return;
  2741. }
  2742. }
  2743. return $pm_message_id;
  2744. }
  2745. /**
  2746. * This function updates a flag for a private message.
  2747. * @param pm_id - The id of the message to update.
  2748. * @param flag - The flag to update. Options are PHORUM_PM_READ_FLAG
  2749. * and PHORUM_PM_REPLY_FLAG.
  2750. * @param value - The value for the flag (true or false).
  2751. * @param user_id - The user to set a flag for or NULL
  2752. * to use the current user (default).
  2753. */
  2754. function phorum_db_pm_setflag($pm_id, $flag, $value, $user_id = NULL)
  2755. {
  2756. $PHORUM = $GLOBALS["PHORUM"];
  2757. $conn = phorum_db_mysqli_connect();
  2758. settype($pm_id, "int");
  2759. if ($flag != PHORUM_PM_READ_FLAG && $flag != PHORUM_PM_REPLY_FLAG) {
  2760. trigger_error("Invalid value for \$flag in function phorum_db_pm_setflag(): $flag", E_USER_WARNING);
  2761. return 0;
  2762. }
  2763. $value = $value ? 1 : 0;
  2764. if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
  2765. settype($user_id, "int");
  2766. // Update the flag in the database.
  2767. $sql = "UPDATE {$PHORUM["pm_xref_table"]} " .
  2768. "SET $flag = $value " .
  2769. "WHERE pm_message_id = $pm_id AND user_id = $user_id";
  2770. $res = mysqli_query( $conn, $sql);
  2771. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2772. // Update message counters.
  2773. if ($flag == PHORUM_PM_READ_FLAG) {
  2774. phorum_db_pm_update_message_info($pm_id);
  2775. }
  2776. return $res;
  2777. }
  2778. /**
  2779. * This function deletes a private message from a folder.
  2780. * @param folder - The folder from which to delete the message
  2781. * @param pm_id - The id of the private message to delete
  2782. * @param user_id - The user to delete the message for or NULL
  2783. * to use the current user (default).
  2784. */
  2785. function phorum_db_pm_delete($pm_id, $folder, $user_id = NULL)
  2786. {
  2787. $PHORUM = $GLOBALS["PHORUM"];
  2788. $conn = phorum_db_mysqli_connect();
  2789. settype($pm_id, "int");
  2790. if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
  2791. settype($user_id, "int");
  2792. if (is_numeric($folder)) {
  2793. $folder_sql = "pm_folder_id=$folder AND";
  2794. } elseif ($folder == PHORUM_PM_INBOX || $folder == PHORUM_PM_OUTBOX) {
  2795. $folder_sql = "pm_folder_id=0 AND special_folder='$folder' AND";
  2796. } else {
  2797. die ("Illegal folder '$folder' requested for user id '$user_id'");
  2798. }
  2799. $sql = "DELETE FROM {$PHORUM["pm_xref_table"]} " .
  2800. "WHERE $folder_sql " .
  2801. "user_id = $user_id AND pm_message_id = $pm_id";
  2802. $res = mysqli_query( $conn, $sql);
  2803. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2804. // Update message counters.
  2805. phorum_db_pm_update_message_info($pm_id);
  2806. return $res;
  2807. }
  2808. /**
  2809. * This function moves a private message to a different folder.
  2810. * @param pm_id - The id of the private message to move.
  2811. * @param from - The folder to move the message from.
  2812. * @param to - The folder to move the message to.
  2813. * @param user_id - The user to move the message for or NULL
  2814. * to use the current user (default).
  2815. */
  2816. function phorum_db_pm_move($pm_id, $from, $to, $user_id = NULL)
  2817. {
  2818. $PHORUM = $GLOBALS["PHORUM"];
  2819. $conn = phorum_db_mysqli_connect();
  2820. settype($pm_id, "int");
  2821. if ($user_id == NULL) $user_id = $PHORUM['user']['user_id'];
  2822. settype($user_id, "int");
  2823. if (is_numeric($from)) {
  2824. $folder_sql = "pm_folder_id=$from AND";
  2825. } elseif ($from == PHORUM_PM_INBOX || $from == PHORUM_PM_OUTBOX) {
  2826. $folder_sql = "pm_folder_id=0 AND special_folder='$from' AND";
  2827. } else {
  2828. die ("Illegal source folder '$from' specified");
  2829. }
  2830. if (is_numeric($to)) {
  2831. $pm_folder_id = $to;
  2832. $special_folder = 'NULL';
  2833. } elseif ($to == PHORUM_PM_INBOX || $to == PHORUM_PM_OUTBOX) {
  2834. $pm_folder_id = 0;
  2835. $special_folder = "'$to'";
  2836. } else {
  2837. die ("Illegal target folder '$to' specified");
  2838. }
  2839. $sql = "UPDATE {$PHORUM["pm_xref_table"]} SET " .
  2840. "pm_folder_id = $pm_folder_id, " .
  2841. "special_folder = $special_folder " .
  2842. "WHERE $folder_sql user_id = $user_id AND pm_message_id = $pm_id";
  2843. $res = mysqli_query( $conn, $sql);
  2844. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2845. return $res;
  2846. }
  2847. /**
  2848. * This function updates the meta information for a message. If it
  2849. * detects that no xrefs are available for the message anymore,
  2850. * the message will be deleted from the database. So this function
  2851. * has to be called after setting the read_flag and after deleting
  2852. * a message.
  2853. * PMTODO maybe we need some locking here to prevent concurrent
  2854. * updates of the message info.
  2855. */
  2856. function phorum_db_pm_update_message_info($pm_id)
  2857. {
  2858. $PHORUM = $GLOBALS['PHORUM'];
  2859. $conn = phorum_db_mysqli_connect();
  2860. settype($pm_id, "int");
  2861. // Find the message record. Return immediately if no message is found.
  2862. $sql = "SELECT * " .
  2863. "FROM {$PHORUM['pm_messages_table']} " .
  2864. "WHERE pm_message_id = $pm_id";
  2865. $res = mysqli_query( $conn, $sql);
  2866. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2867. if (mysqli_num_rows($res) == 0) return $res;
  2868. $pm = mysqli_fetch_assoc($res);
  2869. // Find the xrefs for this message.
  2870. $sql = "SELECT * " .
  2871. "FROM {$PHORUM["pm_xref_table"]} " .
  2872. "WHERE pm_message_id = $pm_id";
  2873. $res = mysqli_query( $conn, $sql);
  2874. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2875. // No xrefs left? Then the message can be fully deleted.
  2876. if (mysqli_num_rows($res) == 0) {
  2877. $sql = "DELETE FROM {$PHORUM['pm_messages_table']} " .
  2878. "WHERE pm_message_id = $pm_id";
  2879. $res = mysqli_query( $conn, $sql);
  2880. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2881. return $res;
  2882. }
  2883. // Update the read flags for the recipients in the meta data.
  2884. $meta = unserialize($pm["meta"]);
  2885. $rcpts = $meta["recipients"];
  2886. while ($row = mysqli_fetch_assoc($res)) {
  2887. // Only update if available. A kept copy in the outbox will
  2888. // not be in the meta list, so if the copy is read, the
  2889. // meta data does not have to be updated here.
  2890. if (isset($rcpts[$row["user_id"]])) {
  2891. $rcpts[$row["user_id"]]["read_flag"] = $row["read_flag"];
  2892. }
  2893. }
  2894. $meta["recipients"] = $rcpts;
  2895. // Store the new meta data.
  2896. $meta = mysqli_real_escape_string($conn, serialize($meta));
  2897. $sql = "UPDATE {$PHORUM['pm_messages_table']} " .
  2898. "SET meta = '$meta' " .
  2899. "WHERE pm_message_id = $pm_id";
  2900. $res = mysqli_query( $conn, $sql);
  2901. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2902. return $res;
  2903. }
  2904. /* Take care of warning about deprecation of the old PM API functions. */
  2905. function phorum_db_get_private_messages($arg1, $arg2) {
  2906. phorum_db_pm_deprecated('phorum_db_get_private_messages'); }
  2907. function phorum_db_get_private_message($arg1) {
  2908. phorum_db_pm_deprecated('phorum_db_get_private_message'); }
  2909. function phorum_db_get_private_message_count($arg1) {
  2910. phorum_db_pm_deprecated('phorum_db_get_private_message_count'); }
  2911. function phorum_db_put_private_messages($arg1, $arg2, $arg3, $arg4, $arg5) {
  2912. phorum_db_pm_deprecated('phorum_db_put_private_messages'); }
  2913. function phorum_db_update_private_message($arg1, $arg2, $arg3){
  2914. phorum_db_pm_deprecated('phorum_db_update_private_message'); }
  2915. function phorum_db_pm_deprecated($func) {
  2916. die("${func}() has been deprecated. Please use the new private message API.");
  2917. }
  2918. /**
  2919. * This function checks if a certain user is buddy of another user.
  2920. * The function return the pm_buddy_id in case the user is a buddy
  2921. * or NULL in case the user isn't.
  2922. * @param buddy_user_id - The user_id to check for if it's a buddy.
  2923. * @param user_id - The user_id for which the buddy list must be
  2924. * checked or NULL to use the current user (default).
  2925. */
  2926. function phorum_db_pm_is_buddy($buddy_user_id, $user_id = NULL)
  2927. {
  2928. $PHORUM = $GLOBALS['PHORUM'];
  2929. $conn = phorum_db_mysqli_connect();
  2930. settype($buddyuser_id, "int");
  2931. if (is_null($user_id)) $user_id = $PHORUM["user"]["user_id"];
  2932. settype($user_id, "int");
  2933. $sql = "SELECT pm_buddy_id FROM {$PHORUM["pm_buddies_table"]} " .
  2934. "WHERE user_id = $user_id AND buddy_user_id = $buddy_user_id";
  2935. $res = mysqli_query( $conn, $sql);
  2936. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2937. if (mysqli_num_rows($res)) {
  2938. $row = mysqli_fetch_array($res);
  2939. return $row[0];
  2940. } else {
  2941. return NULL;
  2942. }
  2943. }
  2944. /**
  2945. * This function adds a buddy for a user. It will return the
  2946. * pm_buddy_id for the new buddy. If the buddy already exists,
  2947. * it will return the existing pm_buddy_id. If a non existant
  2948. * user_id is used for the buddy_user_id, the function will
  2949. * return NULL.
  2950. * @param buddy_user_id - The user_id that has to be added as a buddy.
  2951. * @param user_id - The user_id the buddy has to be added for or
  2952. * NULL to use the current user (default).
  2953. */
  2954. function phorum_db_pm_buddy_add($buddy_user_id, $user_id = NULL)
  2955. {
  2956. $PHORUM = $GLOBALS['PHORUM'];
  2957. $conn = phorum_db_mysqli_connect();
  2958. settype($buddyuser_id, "int");
  2959. if (is_null($user_id)) $user_id = $PHORUM["user"]["user_id"];
  2960. settype($user_id, "int");
  2961. // Check if the buddy_user_id is a valid user_id.
  2962. $valid = phorum_db_user_get($buddy_user_id, false);
  2963. if (! $valid) return NULL;
  2964. $pm_buddy_id = phorum_db_pm_is_buddy($buddy_user_id);
  2965. if (is_null($pm_buddy_id)) {
  2966. $sql = "INSERT INTO {$PHORUM["pm_buddies_table"]} SET " .
  2967. "user_id = $user_id, " .
  2968. "buddy_user_id = $buddy_user_id";
  2969. $res = mysqli_query( $conn, $sql);
  2970. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2971. $pm_buddy_id = mysqli_insert_id($conn);
  2972. }
  2973. return $pm_buddy_id;
  2974. }
  2975. /**
  2976. * This function deletes a buddy for a user.
  2977. * @param buddy_user_id - The user_id that has to be deleted as a buddy.
  2978. * @param user_id - The user_id the buddy has to be delete for or
  2979. * NULL to use the current user (default).
  2980. */
  2981. function phorum_db_pm_buddy_delete($buddy_user_id, $user_id = NULL)
  2982. {
  2983. $PHORUM = $GLOBALS['PHORUM'];
  2984. $conn = phorum_db_mysqli_connect();
  2985. settype($buddyuser_id, "int");
  2986. if (is_null($user_id)) $user_id = $PHORUM["user"]["user_id"];
  2987. settype($user_id, "int");
  2988. $sql = "DELETE FROM {$PHORUM["pm_buddies_table"]} WHERE " .
  2989. "buddy_user_id = $buddy_user_id AND user_id = $user_id";
  2990. $res = mysqli_query( $conn, $sql);
  2991. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  2992. return $res;
  2993. }
  2994. /**
  2995. * This function retrieves a list of buddies for a user.
  2996. * @param user_id - The user_id for which to retrieve the buddies
  2997. * or NULL to user the current user (default).
  2998. * @param find_mutual - Wheter to find mutual buddies or not (default not).
  2999. */
  3000. function phorum_db_pm_buddy_list($user_id = NULL, $find_mutual = false)
  3001. {
  3002. $PHORUM = $GLOBALS['PHORUM'];
  3003. $conn = phorum_db_mysqli_connect();
  3004. if (is_null($user_id)) $user_id = $PHORUM["user"]["user_id"];
  3005. settype($user_id, "int");
  3006. // Get all buddies for this user.
  3007. $sql = "SELECT buddy_user_id FROM {$PHORUM["pm_buddies_table"]} " .
  3008. "WHERE user_id = $user_id";
  3009. $res = mysqli_query( $conn, $sql);
  3010. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  3011. $buddies = array();
  3012. if (mysqli_num_rows($res)) {
  3013. while ($row = mysqli_fetch_array($res)) {
  3014. $buddies[$row[0]] = array (
  3015. 'user_id' => $row[0]
  3016. );
  3017. }
  3018. }
  3019. // If we do not have to lookup mutual buddies, we're done.
  3020. if (! $find_mutual) return $buddies;
  3021. // Initialize mutual buddy value.
  3022. foreach ($buddies as $id => $data) {
  3023. $buddies[$id]["mutual"] = false;
  3024. }
  3025. // Get all mutual buddies.
  3026. $sql = "SELECT DISTINCT a.buddy_user_id " .
  3027. "FROM {$PHORUM["pm_buddies_table"]} as a, {$PHORUM["pm_buddies_table"]} as b " .
  3028. "WHERE a.user_id=$user_id " .
  3029. "AND b.user_id=a.buddy_user_id " .
  3030. "AND b.buddy_user_id=$user_id";
  3031. $res = mysqli_query( $conn, $sql);
  3032. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  3033. if (mysqli_num_rows($res)) {
  3034. while ($row = mysqli_fetch_array($res)) {
  3035. $buddies[$row[0]]["mutual"] = true;
  3036. }
  3037. }
  3038. return $buddies;
  3039. }
  3040. /**
  3041. * This function returns messages or threads which are newer or older
  3042. * than the given timestamp
  3043. *
  3044. * $time - holds the timestamp the comparison is done against
  3045. * $forum - get Threads from this forum
  3046. * $mode - should we compare against datestamp (1) or modifystamp (2)
  3047. *
  3048. */
  3049. function phorum_db_prune_oldThreads($time,$forum=0,$mode=1) {
  3050. $PHORUM = $GLOBALS['PHORUM'];
  3051. $conn = phorum_db_mysqli_connect();
  3052. $numdeleted=0;
  3053. $compare_field = "datestamp";
  3054. if($mode == 2) {
  3055. $compare_field = "modifystamp";
  3056. }
  3057. $forummode="";
  3058. if($forum > 0) {
  3059. $forummode=" AND forum_id = $forum";
  3060. }
  3061. // retrieving which threads to delete
  3062. $sql = "select thread from {$PHORUM['message_table']} where $compare_field < $time AND parent_id=0 $forummode";
  3063. $res = mysqli_query( $conn, $sql);
  3064. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  3065. $ret=array();
  3066. while($row=mysqli_fetch_row($res)) {
  3067. $ret[]=$row[0];
  3068. }
  3069. $thread_ids=implode(",",$ret);
  3070. if(count($ret)) {
  3071. // deleting the messages/threads
  3072. $sql="delete from {$PHORUM['message_table']} where thread IN ($thread_ids)";
  3073. $res = mysqli_query( $conn, $sql);
  3074. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  3075. $numdeleted = mysqli_affected_rows($conn);
  3076. if($numdeleted < 0) {
  3077. $numdeleted=0;
  3078. }
  3079. // deleting the associated notification-entries
  3080. $sql="delete from {$PHORUM['subscribers_table']} where thread IN ($thread_ids)";
  3081. $res = mysqli_query( $conn, $sql);
  3082. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  3083. // optimizing the message-table
  3084. $sql="optimize table {$PHORUM['message_table']}";
  3085. $res = mysqli_query( $conn, $sql);
  3086. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  3087. }
  3088. return $numdeleted;
  3089. }
  3090. /**
  3091. * split thread
  3092. */
  3093. function phorum_db_split_thread($message, $forum_id)
  3094. {
  3095. settype($message, "int");
  3096. settype($forum_id, "int");
  3097. if($message > 0 && $forum_id > 0){
  3098. // get message tree for update thread id
  3099. $tree =phorum_db_get_messagetree($message, $forum_id);
  3100. $queries =array();
  3101. $queries[0]="UPDATE {$GLOBALS['PHORUM']['message_table']} SET thread='$message', parent_id='0' WHERE message_id ='$message'";
  3102. $queries[1]="UPDATE {$GLOBALS['PHORUM']['message_table']} SET thread='$message' WHERE message_id IN ($tree)";
  3103. phorum_db_run_queries($queries);
  3104. }
  3105. }
  3106. /**
  3107. * This function returns the maximum message-id in the database
  3108. */
  3109. function phorum_db_get_max_messageid() {
  3110. $PHORUM = $GLOBALS["PHORUM"];
  3111. $conn = phorum_db_mysqli_connect();
  3112. $maxid = 0;
  3113. $sql="SELECT max(message_id) from ".$PHORUM["message_table"];
  3114. $res = mysqli_query( $conn, $sql);
  3115. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  3116. if (mysqli_num_rows($res) > 0){
  3117. $row = mysqli_fetch_row($res);
  3118. $maxid = $row[0];
  3119. }
  3120. return $maxid;
  3121. }
  3122. /**
  3123. * This function increments the viewcount for a post
  3124. */
  3125. function phorum_db_viewcount_inc($message_id) {
  3126. if($message_id < 1 || !is_numeric($message_id)) {
  3127. return false;
  3128. }
  3129. $conn = phorum_db_mysqli_connect();
  3130. $sql="UPDATE ".$GLOBALS['PHORUM']['message_table']." SET viewcount=viewcount+1 WHERE message_id=$message_id";
  3131. $res = mysqli_query( $conn, $sql);
  3132. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  3133. return true;
  3134. }
  3135. function phorum_db_get_custom_field_users($field_id,$field_content,$match) {
  3136. $conn = phorum_db_mysqli_connect();
  3137. $field_id=(int)$field_id;
  3138. $field_content=mysqli_real_escape_string($conn, $field_content);
  3139. if($match) {
  3140. $compval="LIKE";
  3141. } else {
  3142. $compval="=";
  3143. }
  3144. $sql = "select user_id from {$GLOBALS['PHORUM']['user_custom_fields_table']} where type=$field_id and data $compval '$field_content'";
  3145. $res = mysqli_query( $conn, $sql);
  3146. if ($err = mysqli_error($conn)) phorum_db_mysqli_error("$err: $sql");
  3147. if(mysqli_num_rows($res)) {
  3148. $retval=array();
  3149. while ($row = mysqli_fetch_row($res)){
  3150. $retval[$row[0]]=$row[0];
  3151. }
  3152. } else {
  3153. $retval=NULL;
  3154. }
  3155. return $retval;
  3156. }
  3157. /**
  3158. * This function creates the tables needed in the database.
  3159. */
  3160. function phorum_db_create_tables()
  3161. {
  3162. $PHORUM = $GLOBALS["PHORUM"];
  3163. $conn = phorum_db_mysqli_connect();
  3164. $retmsg = "";
  3165. $queries = array(
  3166. // create tables
  3167. "CREATE TABLE {$PHORUM['forums_table']} ( forum_id int(10) unsigned NOT NULL auto_increment, name varchar(50) NOT NULL default '', active smallint(6) NOT NULL default '0', description text NOT NULL default '', template varchar(50) NOT NULL default '', folder_flag tinyint(1) NOT NULL default '0', parent_id int(10) unsigned NOT NULL default '0', list_length_flat int(10) unsigned NOT NULL default '0', list_length_threaded int(10) unsigned NOT NULL default '0', moderation int(10) unsigned NOT NULL default '0', threaded_list tinyint(4) NOT NULL default '0', threaded_read tinyint(4) NOT NULL default '0', float_to_top tinyint(4) NOT NULL default '0', check_duplicate tinyint(4) NOT NULL default '0', allow_attachment_types varchar(100) NOT NULL default '', max_attachment_size int(10) unsigned NOT NULL default '0', max_totalattachment_size int(10) unsigned NOT NULL default '0', max_attachments int(10) unsigned NOT NULL default '0', pub_perms int(10) unsigned NOT NULL default '0', reg_perms int(10) unsigned NOT NULL default '0', display_ip_address smallint(5) unsigned NOT NULL default '1', allow_email_notify smallint(5) unsigned NOT NULL default '1', language varchar(100) NOT NULL default 'english', email_moderators tinyint(1) NOT NULL default '0', message_count int(10) unsigned NOT NULL default '0', sticky_count int(10) unsigned NOT NULL default '0', thread_count int(10) unsigned NOT NULL default '0', last_post_time int(10) unsigned NOT NULL default '0', display_order int(10) unsigned NOT NULL default '0', read_length int(10) unsigned NOT NULL default '0', vroot int(10) unsigned NOT NULL default '0', edit_post tinyint(1) NOT NULL default '1',template_settings text NOT NULL default '', count_views tinyint(1) unsigned NOT NULL default '0', display_fixed tinyint(1) unsigned NOT NULL default '0', reverse_threading tinyint(1) NOT NULL default '0',inherit_id int(10) unsigned NULL default NULL, PRIMARY KEY (forum_id), KEY name (name), KEY active (active,parent_id), KEY group_id (parent_id)) TYPE=MyISAM",
  3168. "CREATE TABLE {$PHORUM['message_table']} ( message_id int(10) unsigned NOT NULL auto_increment, forum_id int(10) unsigned NOT NULL default '0', thread int(10) unsigned NOT NULL default '0', parent_id int(10) unsigned NOT NULL default '0', author varchar(37) NOT NULL default '', subject varchar(255) NOT NULL default '', body text NOT NULL, email varchar(100) NOT NULL default '', ip varchar(255) NOT NULL default '', status tinyint(4) NOT NULL default '2', msgid varchar(100) NOT NULL default '', modifystamp int(10) unsigned NOT NULL default '0', user_id int(10) unsigned NOT NULL default '0', thread_count int(10) unsigned NOT NULL default '0', moderator_post tinyint(3) unsigned NOT NULL default '0', sort tinyint(4) NOT NULL default '2', datestamp int(10) unsigned NOT NULL default '0', meta mediumtext NOT NULL, viewcount int(10) unsigned NOT NULL default '0', closed tinyint(4) NOT NULL default '0', PRIMARY KEY (message_id), KEY thread_message (thread,message_id), KEY thread_forum (thread,forum_id), KEY special_threads (sort,forum_id), KEY status_forum (status,forum_id), KEY list_page_float (forum_id,parent_id,modifystamp), KEY list_page_flat (forum_id,parent_id,thread), KEY post_count (forum_id,status,parent_id), KEY dup_check (forum_id,author,subject,datestamp), KEY forum_max_message (forum_id,message_id,status,parent_id), KEY last_post_time (forum_id,status,modifystamp), KEY next_prev_thread (forum_id,status,thread), KEY user_id (user_id) ) TYPE=MyISAM",
  3169. "CREATE TABLE {$PHORUM['settings_table']} ( name varchar(255) NOT NULL default '', type enum('V','S') NOT NULL default 'V', data text NOT NULL, PRIMARY KEY (name)) TYPE=MyISAM",
  3170. "CREATE TABLE {$PHORUM['subscribers_table']} ( user_id int(10) unsigned NOT NULL default '0', forum_id int(10) unsigned NOT NULL default '0', sub_type int(10) unsigned NOT NULL default '0', thread int(10) unsigned NOT NULL default '0', PRIMARY KEY (user_id,forum_id,thread), KEY forum_id (forum_id,thread,sub_type)) TYPE=MyISAM",
  3171. "CREATE TABLE {$PHORUM['user_permissions_table']} ( user_id int(10) unsigned NOT NULL default '0', forum_id int(10) unsigned NOT NULL default '0', permission int(10) unsigned NOT NULL default '0', PRIMARY KEY (user_id,forum_id), KEY forum_id (forum_id,permission) ) TYPE=MyISAM",
  3172. "CREATE TABLE {$PHORUM['user_table']} ( user_id int(10) unsigned NOT NULL auto_increment, username varchar(50) NOT NULL default '', password varchar(50) NOT NULL default '',cookie_sessid_lt varchar(50) NOT NULL default '', sessid_st varchar(50) NOT NULL default '', sessid_st_timeout int(10) unsigned NOT NULL default 0, password_temp varchar(50) NOT NULL default '', email varchar(100) NOT NULL default '', email_temp varchar(110) NOT NULL default '', hide_email tinyint(1) NOT NULL default '0', active tinyint(1) NOT NULL default '0', user_data text NOT NULL default '', signature text NOT NULL default '', threaded_list tinyint(4) NOT NULL default '0', posts int(10) NOT NULL default '0', admin tinyint(1) NOT NULL default '0', threaded_read tinyint(4) NOT NULL default '0', date_added int(10) unsigned NOT NULL default '0', date_last_active int(10) unsigned NOT NULL default '0', last_active_forum int(10) unsigned NOT NULL default '0', hide_activity tinyint(1) NOT NULL default '0',show_signature TINYINT( 1 ) DEFAULT '0' NOT NULL, email_notify TINYINT( 1 ) DEFAULT '0' NOT NULL, pm_email_notify TINYINT ( 1 ) DEFAULT '1' NOT NULL, tz_offset TINYINT( 2 ) DEFAULT '-99' NOT NULL,is_dst TINYINT( 1 ) DEFAULT '0' NOT NULL ,user_language VARCHAR( 100 ) NOT NULL default '',user_template VARCHAR( 100 ) NOT NULL default '', moderator_data text NOT NULL default '', moderation_email tinyint(2) unsigned not null default 1, PRIMARY KEY (user_id), UNIQUE KEY username (username), KEY active (active), KEY userpass (username,password), KEY sessid_st (sessid_st), KEY cookie_sessid_lt (cookie_sessid_lt), KEY activity (date_last_active,hide_activity,last_active_forum), KEY date_added (date_added), KEY email_temp (email_temp) ) TYPE=MyISAM",
  3173. "CREATE TABLE {$PHORUM['user_newflags_table']} ( user_id int(11) NOT NULL default '0', forum_id int(11) NOT NULL default '0', message_id int(11) NOT NULL default '0', PRIMARY KEY (user_id,forum_id,message_id) ) TYPE=MyISAM",
  3174. "CREATE TABLE {$PHORUM['groups_table']} ( group_id int(11) NOT NULL auto_increment, name varchar(255) NOT NULL default '0', open tinyint(3) NOT NULL default '0', PRIMARY KEY (group_id) ) TYPE=MyISAM",
  3175. "CREATE TABLE {$PHORUM['forum_group_xref_table']} ( forum_id int(11) NOT NULL default '0', group_id int(11) NOT NULL default '0', permission int(10) unsigned NOT NULL default '0', PRIMARY KEY (forum_id,group_id) ) TYPE=MyISAM",
  3176. "CREATE TABLE {$PHORUM['user_group_xref_table']} ( user_id int(11) NOT NULL default '0', group_id int(11) NOT NULL default '0', status tinyint(3) NOT NULL default '1', PRIMARY KEY (user_id,group_id) ) TYPE=MyISAM",
  3177. "CREATE TABLE {$PHORUM['files_table']} ( file_id int(11) NOT NULL auto_increment, user_id int(11) NOT NULL default '0', filename varchar(255) NOT NULL default '', filesize int(11) NOT NULL default '0', file_data mediumtext NOT NULL default '', add_datetime int(10) unsigned NOT NULL default '0', message_id int(10) unsigned NOT NULL default '0', link varchar(10) NOT NULL default '', PRIMARY KEY (file_id), KEY add_datetime (add_datetime), KEY message_id_link (message_id,link)) TYPE=MyISAM",
  3178. "CREATE TABLE {$PHORUM['banlist_table']} ( id int(11) NOT NULL auto_increment, forum_id int(11) NOT NULL default '0', type tinyint(4) NOT NULL default '0', pcre tinyint(4) NOT NULL default '0', string varchar(255) NOT NULL default '', PRIMARY KEY (id), KEY forum_id (forum_id)) TYPE=MyISAM",
  3179. "CREATE TABLE {$PHORUM['search_table']} ( message_id int(10) unsigned NOT NULL default '0', forum_id int(10) unsigned NOT NULL default '0',search_text mediumtext NOT NULL default '', PRIMARY KEY (message_id), KEY forum_id (forum_id), FULLTEXT KEY search_text (search_text) ) TYPE=MyISAM",
  3180. "CREATE TABLE {$PHORUM['user_custom_fields_table']} ( user_id INT DEFAULT '0' NOT NULL , type INT DEFAULT '0' NOT NULL , data TEXT NOT NULL default '', PRIMARY KEY ( user_id , type )) TYPE=MyISAM",
  3181. "CREATE TABLE {$PHORUM['pm_messages_table']} ( pm_message_id int(10) unsigned NOT NULL auto_increment, from_user_id int(10) unsigned NOT NULL default '0', from_username varchar(50) NOT NULL default '', subject varchar(100) NOT NULL default '', message text NOT NULL default '', datestamp int(10) unsigned NOT NULL default '0', meta mediumtext NOT NULL default '', PRIMARY KEY(pm_message_id)) TYPE=MyISAM",
  3182. "CREATE TABLE {$PHORUM['pm_folders_table']} ( pm_folder_id int(10) unsigned NOT NULL auto_increment, user_id int(10) unsigned NOT NULL default '0', foldername varchar(20) NOT NULL default '', PRIMARY KEY (pm_folder_id)) TYPE=MyISAM",
  3183. "CREATE TABLE {$PHORUM['pm_xref_table']} ( pm_xref_id int(10) unsigned NOT NULL auto_increment, user_id int(10) unsigned NOT NULL default '0', pm_folder_id int(10) unsigned NOT NULL default '0', special_folder varchar(10), pm_message_id int(10) unsigned NOT NULL default '0', read_flag tinyint(1) NOT NULL default '0', reply_flag tinyint(1) NOT NULL default '0', PRIMARY KEY (pm_xref_id), KEY xref (user_id,pm_folder_id,pm_message_id), KEY read_flag (read_flag)) TYPE=MyISAM",
  3184. "CREATE TABLE {$PHORUM['pm_buddies_table']} ( pm_buddy_id int(10) unsigned NOT NULL auto_increment, user_id int(10) unsigned NOT NULL default '0', buddy_user_id int(10) unsigned NOT NULL default '0', PRIMARY KEY pm_buddy_id (pm_buddy_id), UNIQUE KEY userids (user_id, buddy_user_id), KEY buddy_user_id (buddy_user_id)) TYPE=MyISAM",
  3185. );
  3186. foreach($queries as $sql){
  3187. $res = mysqli_query( $conn, $sql);
  3188. if ($err = mysqli_error($conn)){
  3189. $retmsg = "$err<br />";
  3190. phorum_db_mysqli_error("$err: $sql");
  3191. break;
  3192. }
  3193. }
  3194. return $retmsg;
  3195. }
  3196. // uses the database-dependant functions to escape a string
  3197. function phorum_db_escape_string($str) {
  3198. $conn = phorum_db_mysqli_connect();
  3199. $str_tmp=mysqli_real_escape_string($conn, $str);
  3200. return $str_tmp;
  3201. }
  3202. /**
  3203. * This function goes through an array of queries and executes them
  3204. */
  3205. function phorum_db_run_queries($queries){
  3206. $PHORUM = $GLOBALS["PHORUM"];
  3207. $conn = phorum_db_mysqli_connect();
  3208. $retmsg = "";
  3209. foreach($queries as $sql){
  3210. $res = mysqli_query( $conn, $sql);
  3211. if ($err = mysqli_error($conn)){
  3212. // skip duplicate column name errors
  3213. if(!stristr($err, "duplicate column")){
  3214. $retmsg.= "$err<br />";
  3215. phorum_db_mysqli_error("$err: $sql");
  3216. }
  3217. }
  3218. }
  3219. return $retmsg;
  3220. }
  3221. /**
  3222. * This function checks that a database connection can be made.
  3223. */
  3224. function phorum_db_check_connection(){
  3225. $conn = phorum_db_mysqli_connect();
  3226. return ($conn > 0) ? true : false;
  3227. }
  3228. /**
  3229. * handy little connection function. This allows us to not connect to the
  3230. * server until a query is actually run.
  3231. * NOTE: This is not a required part of abstraction
  3232. */
  3233. function phorum_db_mysqli_connect(){
  3234. $PHORUM = $GLOBALS["PHORUM"];
  3235. static $conn;
  3236. if (empty($conn)){
  3237. $conn = mysqli_connect($PHORUM["DBCONFIG"]["server"], $PHORUM["DBCONFIG"]["user"], $PHORUM["DBCONFIG"]["password"], $PHORUM["DBCONFIG"]["name"]);
  3238. }
  3239. mysqli_query($conn, "SET NAMES 'utf8'");
  3240. return $conn;
  3241. }
  3242. /**
  3243. * error handling function
  3244. * NOTE: This is not a required part of abstraction
  3245. */
  3246. function phorum_db_mysqli_error($err){
  3247. if(isset($GLOBALS['PHORUM']['error_logging'])) {
  3248. $logsetting = $GLOBALS['PHORUM']['error_logging'];
  3249. } else {
  3250. $logsetting = "";
  3251. }
  3252. $adminemail = $GLOBALS['PHORUM']['system_email_from_address'];
  3253. $cache_dir = $GLOBALS['PHORUM']['cache'];
  3254. if (!defined("PHORUM_ADMIN")){
  3255. if($logsetting == 'mail') {
  3256. include_once("./include/email_functions.php");
  3257. $data=array('mailmessage'=>"An SQL-error occured in your phorum-installation.\n\nThe error-message was:\n$err\n\n",
  3258. 'mailsubject'=>'Phorum: an SQL-error occured');
  3259. phorum_email_user(array($adminemail),$data);
  3260. } elseif($logsetting == 'file') {
  3261. $fp = fopen($cache_dir."/phorum-sql-errors.log",'a');
  3262. fputs($fp,time().": $err\n");
  3263. fclose($fp);
  3264. } else {
  3265. echo htmlspecialchars($err);
  3266. }
  3267. exit();
  3268. }else{
  3269. echo "<!-- $err -->";
  3270. }
  3271. }
  3272. /**
  3273. * This function is used by the sanity checking system in the
  3274. * admin interface to determine how much data can be transferred
  3275. * in one query. This is used to detect problems with uploads that
  3276. * are larger than the database server can handle.
  3277. * The function returns the size in bytes. For database implementations
  3278. * which do not have this kind of limit, NULL can be returned.
  3279. */
  3280. function phorum_db_maxpacketsize ()
  3281. {
  3282. $conn = phorum_db_mysqli_connect();
  3283. $res = mysqli_query($conn, "SELECT @@global.max_allowed_packet");
  3284. if (! $res) return NULL;
  3285. if (mysqli_num_rows($res)) {
  3286. $row = mysqli_fetch_array($res);
  3287. return $row[0];
  3288. }
  3289. return NULL;
  3290. }
  3291. /**
  3292. * This function is used by the sanity checking system to let the
  3293. * database layer do sanity checks of its own. This function can
  3294. * be used by every database layer to implement specific checks.
  3295. *
  3296. * The return value for this function should be exactly the same
  3297. * as the return value expected for regular sanity checking
  3298. * function (see include/admin/sanity_checks.php for information).
  3299. *
  3300. * There's no need to load the sanity_check.php file for the needed
  3301. * constants, because this function should only be called from the
  3302. * sanity checking system.
  3303. */
  3304. function phorum_db_sanitychecks()
  3305. {
  3306. $PHORUM = $GLOBALS["PHORUM"];
  3307. // Retrieve the MySQL server version.
  3308. $conn = phorum_db_mysqli_connect();
  3309. $res = mysqli_query($conn, "SELECT @@global.version");
  3310. if (!$res) return array(
  3311. PHORUM_SANITY_WARN,
  3312. "The database layer could not retrieve the version of the
  3313. running MySQL server",
  3314. "This probably means that you are running a really old MySQL
  3315. server, which does not support \"SELECT @@global.version\"
  3316. as an SQL command. If you are not running a MySQL server
  3317. with version 4.0.18 or higher, then please upgrade your
  3318. MySQL server. Else, contact the Phorum developers to see
  3319. where this warning is coming from"
  3320. );
  3321. if (mysqli_num_rows($res))
  3322. {
  3323. $row = mysqli_fetch_array($res);
  3324. $ver = explode(".", $row[0]);
  3325. // Version numbering format which is not recognized.
  3326. if (count($ver) != 3) return array(
  3327. PHORUM_SANITY_WARN,
  3328. "The database layer was unable to recognize the MySQL server's
  3329. version number \"" . htmlspecialchars($row[0]) . "\". Therefore,
  3330. checking if the right version of MySQL is used is not possible.",
  3331. "Contact the Phorum developers and report this specific
  3332. version number, so the checking scripts can be updated."
  3333. );
  3334. settype($ver[0], 'int');
  3335. settype($ver[1], 'int');
  3336. settype($ver[2], 'int');
  3337. // MySQL before version 4.
  3338. if ($ver[0] < 4) return array(
  3339. PHORUM_SANITY_CRIT,
  3340. "The MySQL database server that is used is too old. The
  3341. running version is \"" . htmlspecialchars($row[0]) . "\",
  3342. while MySQL version 4.0.18 or higher is recommended.",
  3343. "Upgrade your MySQL server to a newer version. If your
  3344. website is hosted with a service provider, please contact
  3345. the service provider to upgrade your MySQL database."
  3346. );
  3347. // MySQL before version 4.0.18, with full text search enabled.
  3348. if ($PHORUM["DBCONFIG"]["mysql_use_ft"] &&
  3349. $ver[0] == 4 && $ver[1] == 0 && $ver[2] < 18) return array(
  3350. PHORUM_SANITY_WARN,
  3351. "The MySQL database server that is used does not
  3352. support all Phorum features. The running version is
  3353. \"" . htmlspecialchars($row[0]) . "\", while MySQL version
  3354. 4.0.18 or higher is recommended.",
  3355. "Upgrade your MySQL server to a newer version. If your
  3356. website is hosted with a service provider, please contact
  3357. the service provider to upgrade your MySQL database."
  3358. );
  3359. // All checks are okay.
  3360. return array (PHORUM_SANITY_OK, NULL);
  3361. }
  3362. return array(
  3363. PHORUM_SANITY_CRIT,
  3364. "An unexpected problem was found in running the sanity
  3365. check function phorum_db_sanitychecks().",
  3366. "Contact the Phorum developers to find out what the problem is."
  3367. );
  3368. }
  3369. ?>