PageRenderTime 73ms CodeModel.GetById 31ms 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

Large files files are truncated, but you can click here to view the full file

  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. $P

Large files files are truncated, but you can click here to view the full file