PageRenderTime 61ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://github.com/joechrysler/Campsite
PHP | 4826 lines | 2735 code | 952 blank | 1139 comment | 641 complexity | 59bf8d53d9cc8b3908053949cfff1479 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: mysql.php 1039 2006-05-10 16:01:56Z brian $
  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. * Get the visible messages for a given page offset. The main Phorum code
  62. * handles actually sorting the threads into a threaded list if needed.
  63. *
  64. * By default, the message body is not included in the fetch queries.
  65. * If the body is needed in the thread list, $PHORUM['TMP']['bodies_in_list']
  66. * must be set to "1" (for example using setting.tpl).
  67. *
  68. * NOTE: ALL dates should be returned as Unix timestamps
  69. *
  70. * @param int $offset - the index of the page to return, starting with 0
  71. *
  72. * @return array
  73. */
  74. function phorum_db_get_thread_list($offset)
  75. {
  76. $PHORUM = $GLOBALS["PHORUM"];
  77. settype($offset, "int");
  78. $conn = phorum_db_mysql_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\n,$table.ip";
  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 = mysql_query($sql, $conn);
  176. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  177. $rows = mysql_num_rows($res);
  178. if($rows > 0){
  179. while ($rec = mysql_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. * Get the recent messages for all forums the user can read, a particular
  196. * forum, or a particular thread, and returns an array of the messages
  197. * order by message_id. You can optionally retrieve only new threads.
  198. *
  199. * The original version of this function came from Jim Winstead of mysql.com
  200. *
  201. * @param int $count
  202. * Limit the number of returned messages to this number.
  203. * @param int $forum_id
  204. * @param int $thread
  205. * @param boolean $threads_only
  206. * If set to TRUE, only get the top message from each thread.
  207. *
  208. * @return array
  209. */
  210. function phorum_db_get_recent_messages($count, $forum_id = 0, $thread = 0, $threads_only = 0)
  211. {
  212. $PHORUM = $GLOBALS["PHORUM"];
  213. settype($count, "int");
  214. settype($thread, "int");
  215. $arr = array();
  216. $allowed_forums = array();
  217. $conn = phorum_db_mysql_connect();
  218. // we need to differentiate on which key to use
  219. if($thread) {
  220. $use_key='thread_message';
  221. } else {
  222. $use_key='forum_max_message';
  223. }
  224. $sql = "SELECT {$PHORUM['message_table']}.* FROM {$PHORUM['message_table']} USE KEY($use_key) WHERE status=".PHORUM_STATUS_APPROVED;
  225. // have to check what forums they can read first.
  226. // even if $thread is passed, we have to make sure
  227. // the user can read the forum
  228. if($forum_id <= 0) {
  229. $allowed_forums=phorum_user_access_list(PHORUM_USER_ALLOW_READ);
  230. // if they are not allowed to see any forums, return the emtpy $arr;
  231. if(empty($allowed_forums))
  232. return $arr;
  233. } elseif(is_array($forum_id)) {
  234. // for an array, check each one and return if none are allowed
  235. foreach($forum_id as $id){
  236. if(phorum_user_access_allowed(PHORUM_USER_ALLOW_READ,$id)) {
  237. $allowed_forums[]=$id;
  238. }
  239. }
  240. // if they are not allowed to see any forums, return the emtpy $arr;
  241. if(empty($allowed_forums))
  242. return $arr;
  243. } else {
  244. // only single forum, *much* fast this way
  245. if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_READ,$forum_id)) {
  246. return $arr;
  247. }
  248. settype($forum_id, "int");
  249. }
  250. if(count($allowed_forums)){
  251. $sql.=" and forum_id in (".implode(",", $allowed_forums).")";
  252. } else {
  253. $sql.=" and forum_id=$forum_id";
  254. }
  255. if($thread){
  256. $sql.=" and thread=$thread";
  257. }
  258. if($threads_only) {
  259. $sql.= " and parent_id = 0";
  260. $sql.= " ORDER BY thread DESC";
  261. } else {
  262. $sql.= " ORDER BY message_id DESC";
  263. }
  264. if($count){
  265. $sql.= " LIMIT $count";
  266. }
  267. $res = mysql_query($sql, $conn);
  268. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  269. while ($rec = mysql_fetch_assoc($res)){
  270. $arr[$rec["message_id"]] = $rec;
  271. // convert meta field
  272. if(empty($rec["meta"])){
  273. $arr[$rec["message_id"]]["meta"]=array();
  274. } else {
  275. $arr[$rec["message_id"]]["meta"]=unserialize($rec["meta"]);
  276. }
  277. if(empty($arr['users'])) $arr['users']=array();
  278. if($rec["user_id"]){
  279. $arr['users'][]=$rec["user_id"];
  280. }
  281. }
  282. return $arr;
  283. }
  284. /**
  285. * Get messages which have not yet been approved by a moderator.
  286. * The main Phorum code handles actually sorting the threads into
  287. * a threaded list if needed.
  288. *
  289. * NOTE: ALL dates should be returned as Unix timestamps
  290. * @param mixed $forum
  291. * The forum id to work with.
  292. * Set to NULL if you want to search all forums.
  293. * You can also pass an array of forum id's.
  294. * @param boolean $waiting_only
  295. * Only take into account messages which have to
  296. * be approved directly after posting. Do not include
  297. * messages which are hidden by a moderator.
  298. * @param int $moddays
  299. * Limit the search to the last $moddays number of days.
  300. * @return array
  301. * An array of messages, indexed by message ID.
  302. */
  303. function phorum_db_get_unapproved_list($forum = NULL, $waiting_only=false,$moddays=0)
  304. {
  305. $PHORUM = $GLOBALS["PHORUM"];
  306. $conn = phorum_db_mysql_connect();
  307. $table = $PHORUM["message_table"];
  308. $arr = array();
  309. $sql = "select
  310. $table.*
  311. from
  312. $table ";
  313. if (is_array($forum)){
  314. $sql .= "where forum_id in (" . implode(",", $forum) . ") and ";
  315. } elseif (! is_null($forum)){
  316. settype($forum, "int");
  317. $sql .= "where forum_id = $forum and ";
  318. } else {
  319. $sql .= "where ";
  320. }
  321. if($moddays > 0) {
  322. $checktime=time()-(86400*$moddays);
  323. $sql .=" datestamp > $checktime AND";
  324. }
  325. if($waiting_only){
  326. $sql.=" status=".PHORUM_STATUS_HOLD;
  327. } else {
  328. $sql="($sql status=".PHORUM_STATUS_HOLD.") " .
  329. "union ($sql status=".PHORUM_STATUS_HIDDEN.")";
  330. }
  331. $sql .=" order by thread, message_id";
  332. $res = mysql_query($sql, $conn);
  333. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  334. while ($rec = mysql_fetch_assoc($res)){
  335. $arr[$rec["message_id"]] = $rec;
  336. $arr[$rec["message_id"]]["meta"] = array();
  337. if(!empty($rec["meta"])){
  338. $arr[$rec["message_id"]]["meta"] = unserialize($rec["meta"]);
  339. }
  340. }
  341. return $arr;
  342. }
  343. /**
  344. * Add a message. The message will not be posted if it is a duplicate
  345. * and $PHORUM['check_duplicate'] is set.
  346. *
  347. * The $message is passed by reference and when the function completes
  348. * successfully, the "message_id" index will be set to the new value.
  349. * If the "thread" index is set to zero, a new thread will be started and the
  350. * "thread" index will be filled with the new thread ID upon return.
  351. *
  352. * @param array $message
  353. * The $message array must contain the following indexes:
  354. * forum_id, thread, parent_id, author, subject, email, ip,
  355. * user_id, moderator_post, status, sort, msgid, body, closed
  356. *
  357. * @param boolean $convert
  358. *
  359. * @return boolean
  360. * TRUE on success, FALSE on failure.
  361. *
  362. */
  363. function phorum_db_post_message(&$message,$convert=false){
  364. $PHORUM = $GLOBALS["PHORUM"];
  365. $table = $PHORUM["message_table"];
  366. $conn = phorum_db_mysql_connect();
  367. $success = false;
  368. foreach($message as $key => $value){
  369. if (is_numeric($value) && !in_array($key,$PHORUM['string_fields'])){
  370. $message[$key] = (int)$value;
  371. } elseif(is_array($value)) {
  372. $message[$key] = mysql_escape_string(serialize($value));
  373. } else{
  374. $message[$key] = mysql_escape_string($value);
  375. }
  376. }
  377. if(!$convert) {
  378. $NOW = time();
  379. } else {
  380. $NOW = $message['datestamp'];
  381. }
  382. // duplicate-check
  383. if(isset($PHORUM['check_duplicate']) && $PHORUM['check_duplicate'] && !$convert) {
  384. // we check for dupes in that number of minutes
  385. $check_minutes=60;
  386. $check_timestamp =$NOW - ($check_minutes*60);
  387. // check_query
  388. $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";
  389. $res = mysql_query($chk_query, $conn);
  390. if ($err = mysql_error()) phorum_db_mysql_error("$err: $chk_query");
  391. if(mysql_num_rows($res))
  392. return 0;
  393. }
  394. if(isset($message['meta'])){
  395. $metaval=",meta='{$message['meta']}'";
  396. } else {
  397. $metaval="";
  398. }
  399. $sql = "Insert into $table set
  400. forum_id = {$message['forum_id']},
  401. datestamp=$NOW,
  402. thread={$message['thread']},
  403. parent_id={$message['parent_id']},
  404. author='{$message['author']}',
  405. subject='{$message['subject']}',
  406. email='{$message['email']}',
  407. ip='{$message['ip']}',
  408. user_id={$message['user_id']},
  409. moderator_post={$message['moderator_post']},
  410. status={$message['status']},
  411. sort={$message['sort']},
  412. msgid='{$message['msgid']}',
  413. body='{$message['body']}',
  414. closed={$message['closed']}
  415. $metaval";
  416. // if in conversion we need the message-id too
  417. if($convert && isset($message['message_id'])) {
  418. $sql.=",message_id=".$message['message_id'];
  419. }
  420. if(isset($message['modifystamp'])) {
  421. $sql.=",modifystamp=".$message['modifystamp'];
  422. }
  423. if(isset($message['viewcount'])) {
  424. $sql.=",viewcount=".$message['viewcount'];
  425. }
  426. $res = mysql_query($sql, $conn);
  427. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  428. if ($res){
  429. $message["message_id"] = mysql_insert_id($conn);
  430. if(!empty($message["message_id"])){
  431. $message["datestamp"]=$NOW;
  432. if ($message["thread"] == 0){
  433. $message["thread"] = $message["message_id"];
  434. $sql = "update $table set thread={$message['message_id']} where message_id={$message['message_id']}";
  435. $res = mysql_query($sql, $conn);
  436. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  437. }
  438. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  439. // start ft-search stuff
  440. if($PHORUM["DBCONFIG"]["mysql_use_ft"]){
  441. $search_text="$message[author] | $message[subject] | $message[body]";
  442. $sql="insert delayed into {$PHORUM['search_table']} set message_id={$message['message_id']}, forum_id={$message['forum_id']}, search_text='$search_text'";
  443. $res = mysql_query($sql, $conn);
  444. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  445. }
  446. // end ft-search stuff
  447. $success = true;
  448. // some data for later use, i.e. email-notification
  449. $GLOBALS['PHORUM']['post_returns']['message_id']=$message["message_id"];
  450. $GLOBALS['PHORUM']['post_returns']['thread_id']=$message["thread"];
  451. }
  452. }
  453. return $success;
  454. }
  455. /**
  456. * Relate a message to Campsite.
  457. *
  458. * It affects campsite.ArticleComments
  459. *
  460. * @param array $message
  461. * The $message array must contain the following indexes:
  462. * thread, message_id
  463. *
  464. * @return boolean
  465. * TRUE on success, FALSE on failure.
  466. *
  467. */
  468. function phorum_db_relate_message_to_campsite($message)
  469. {
  470. $PHORUM = $GLOBALS["PHORUM"];
  471. $conn = phorum_db_mysql_connect();
  472. $success = false;
  473. $sql = "SELECT fk_article_number, fk_language_id
  474. FROM ArticleComments
  475. WHERE fk_comment_id = '".$message['thread']."'";
  476. $res = mysql_query($sql, $conn);
  477. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  478. if ($res) {
  479. $data = mysql_fetch_array($res);
  480. if (!empty($data['fk_article_number'])) {
  481. $article_number = $data['fk_article_number'];
  482. $article_language = $data['fk_language_id'];
  483. $sql = "INSERT INTO ArticleComments
  484. (fk_article_number, fk_language_id, fk_comment_id, is_first)
  485. VALUES ('".$article_number."', '".$article_language."', '".
  486. $message['message_id']."', '0')";
  487. $res = mysql_query($sql, $conn);
  488. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  489. if ($res) {
  490. $success = true;
  491. }
  492. }
  493. }
  494. return $success;
  495. }
  496. /**
  497. * Delete a message.
  498. *
  499. * @param int $message_id The id of the message which should be deleted
  500. * @param int $mode The mode of deletion,
  501. * PHORUM_DELETE_MESSAGE for reconnecting the children,
  502. * PHORUM_DELETE_TREE for deleting the children
  503. */
  504. function phorum_db_delete_message($message_id, $mode = PHORUM_DELETE_MESSAGE)
  505. {
  506. $PHORUM = $GLOBALS["PHORUM"];
  507. $conn = phorum_db_mysql_connect();
  508. settype($message_id, "int");
  509. $threadset = 0;
  510. // get the parents of the message to delete.
  511. $sql = "select forum_id, message_id, thread, parent_id from {$PHORUM['message_table']} where message_id = $message_id ";
  512. $res = mysql_query($sql, $conn);
  513. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  514. $rec = mysql_fetch_assoc($res);
  515. if($mode == PHORUM_DELETE_TREE){
  516. $mids = phorum_db_get_messagetree($message_id, $rec['forum_id']);
  517. }else{
  518. $mids = $message_id;
  519. }
  520. // unapprove the messages first so replies will not get posted
  521. $sql = "update {$PHORUM['message_table']} set status=".PHORUM_STATUS_HOLD." where message_id in ($mids)";
  522. $res = mysql_query($sql, $conn);
  523. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  524. $thread = $rec['thread'];
  525. if($thread == $message_id && $mode == PHORUM_DELETE_TREE){
  526. $threadset = 1;
  527. }else{
  528. $threadset = 0;
  529. }
  530. if($mode == PHORUM_DELETE_MESSAGE){
  531. $count = 1;
  532. // change the children to point to their parent's parent
  533. // forum_id is in here for speed by using a key only
  534. $sql = "update {$PHORUM['message_table']} set parent_id=$rec[parent_id] where forum_id=$rec[forum_id] and parent_id=$rec[message_id]";
  535. mysql_query($sql, $conn);
  536. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  537. }else{
  538. $count = count(explode(",", $mids));
  539. }
  540. // delete the messages
  541. $sql = "delete from {$PHORUM['message_table']} where message_id in ($mids)";
  542. mysql_query($sql, $conn);
  543. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  544. // start ft-search stuff
  545. $sql="delete from {$PHORUM['search_table']} where message_id in ($mids)";
  546. $res = mysql_query($sql, $conn);
  547. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  548. // end ft-search stuff
  549. // it kind of sucks to have this here, but it is the best way
  550. // to ensure that it gets done if stuff is deleted.
  551. // leave this include here, it needs to be conditional
  552. include_once("./include/thread_info.php");
  553. phorum_update_thread_info($thread);
  554. // we need to delete the subscriptions for that thread too
  555. $sql = "DELETE FROM {$PHORUM['subscribers_table']} WHERE forum_id > 0 AND thread=$thread";
  556. $res = mysql_query($sql, $conn);
  557. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  558. // this function will be slow with a lot of messages.
  559. phorum_db_update_forum_stats(true);
  560. return explode(",", $mids);
  561. }
  562. /**
  563. * Get all attached messages to a message.
  564. *
  565. * @param int $parent_id
  566. * @param int $forum_id
  567. *
  568. * @return string
  569. */
  570. function phorum_db_get_messagetree($parent_id, $forum_id){
  571. $PHORUM = $GLOBALS["PHORUM"];
  572. settype($parent_id, "int");
  573. settype($forum_id, "int");
  574. $conn = phorum_db_mysql_connect();
  575. $sql = "Select message_id from {$PHORUM['message_table']} where forum_id=$forum_id and parent_id=$parent_id";
  576. $res = mysql_query($sql, $conn);
  577. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  578. $tree = "$parent_id";
  579. while($rec = mysql_fetch_row($res)){
  580. $tree .= "," . phorum_db_get_messagetree($rec[0],$forum_id);
  581. }
  582. return $tree;
  583. }
  584. /**
  585. * Update a message with new data.
  586. *
  587. * @param int $message_id
  588. * @param array $message
  589. * See phorum_db_post_message() for a list of available fields.
  590. * You can pass in as many or as few fields as you wish to update.
  591. *
  592. * @return boolean
  593. * TRUE on success, FALSE on failure.
  594. */
  595. function phorum_db_update_message($message_id, $message)
  596. {
  597. $PHORUM = $GLOBALS["PHORUM"];
  598. settype($message_id, "int");
  599. if (count($message) > 0){
  600. $conn = phorum_db_mysql_connect();
  601. foreach($message as $field => $value){
  602. if (is_numeric($value) && !in_array($field,$PHORUM['string_fields'])){
  603. $fields[] = "$field=$value";
  604. }elseif (is_array($value)){
  605. $value = mysql_escape_string(serialize($value));
  606. $message[$field] = $value;
  607. $fields[] = "$field='$value'";
  608. }else{
  609. $value = mysql_escape_string($value);
  610. $message[$field] = $value;
  611. $fields[] = "$field='$value'";
  612. }
  613. }
  614. $sql = "update {$PHORUM['message_table']} set " . implode(", ", $fields) . " where message_id=$message_id";
  615. $res = mysql_query($sql, $conn);
  616. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  617. if($res){
  618. // start ft-search stuff
  619. if(isset($message["author"]) && isset($message["subject"]) && isset($message["body"])){
  620. $search_text="$message[author] | $message[subject] | $message[body]";
  621. $sql="replace delayed into {$PHORUM['search_table']} set message_id={$message_id}, forum_id={$message['forum_id']}, search_text='$search_text'";
  622. $res = mysql_query($sql, $conn);
  623. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  624. }
  625. // end ft-search stuff
  626. }
  627. return ($res > 0) ? true : false;
  628. }else{
  629. trigger_error("\$message cannot be empty in phorum_update_message()", E_USER_ERROR);
  630. }
  631. }
  632. /**
  633. * Get the first message that matches the search parameters. If
  634. * you pass in multiple matches targets, this will return an array
  635. * of messages. Otherwise it will return a single message.
  636. *
  637. * @param mixed $value
  638. * The value in the database column that you want to match.
  639. * This can be an array, in which case this will return the messages
  640. * that match any of the given values in the array.
  641. * @param string $field
  642. * The database column you are searching to find $value.
  643. * @param boolean $ignore_forum_id
  644. * @return array
  645. */
  646. function phorum_db_get_message($value, $field="message_id", $ignore_forum_id=false)
  647. {
  648. $PHORUM = $GLOBALS["PHORUM"];
  649. $field=mysql_escape_string($field);
  650. $multiple=false;
  651. $conn = phorum_db_mysql_connect();
  652. $forum_id_check = "";
  653. if (!$ignore_forum_id && !empty($PHORUM["forum_id"])){
  654. $forum_id_check = "(forum_id = {$PHORUM['forum_id']} OR forum_id={$PHORUM['vroot']}) and";
  655. }
  656. if(is_array($value)) {
  657. $checkvar="$field IN('".implode("','",$value)."')";
  658. $multiple=true;
  659. } else {
  660. $value=mysql_escape_string($value);
  661. $checkvar="$field='$value'";
  662. }
  663. $sql = "select {$PHORUM['message_table']}.* from {$PHORUM['message_table']} where $forum_id_check $checkvar";
  664. $res = mysql_query($sql, $conn);
  665. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  666. $ret = $multiple ? array() : NULL;
  667. if(mysql_num_rows($res)){
  668. if($multiple) {
  669. while($rec=mysql_fetch_assoc($res)) {
  670. // convert meta field
  671. if(empty($rec["meta"])){
  672. $rec["meta"]=array();
  673. } else {
  674. $rec["meta"]=unserialize($rec["meta"]);
  675. }
  676. $ret[$rec['message_id']]=$rec;
  677. }
  678. } else {
  679. $rec = mysql_fetch_assoc($res);
  680. // convert meta field
  681. if(empty($rec["meta"])){
  682. $rec["meta"]=array();
  683. } else {
  684. $rec["meta"]=unserialize($rec["meta"]);
  685. }
  686. $ret=$rec;
  687. }
  688. }
  689. return $ret;
  690. }
  691. /**
  692. * Get messages with the given thread id. Returns an array of messages.
  693. *
  694. * @param int $thread
  695. * @param int $page
  696. * @return array
  697. */
  698. function phorum_db_get_messages($thread,$page=0)
  699. {
  700. $PHORUM = $GLOBALS["PHORUM"];
  701. settype($thread, "int");
  702. $conn = phorum_db_mysql_connect();
  703. $forum_id_check = "";
  704. if (!empty($PHORUM["forum_id"])){
  705. $forum_id_check = "(forum_id = {$PHORUM['forum_id']} OR forum_id={$PHORUM['vroot']}) and";
  706. }
  707. // are we really allowed to show this thread/message?
  708. $approvedval = "";
  709. if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES)) {
  710. $approvedval="AND {$PHORUM['message_table']}.status =".PHORUM_STATUS_APPROVED;
  711. }
  712. if($page > 0) {
  713. $start=$PHORUM["read_length"]*($page-1);
  714. $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"];
  715. } else {
  716. $sql = "select {$PHORUM['message_table']}.* from {$PHORUM['message_table']} where $forum_id_check thread=$thread $approvedval order by message_id";
  717. if(isset($PHORUM["reverse_threading"]) && $PHORUM["reverse_threading"]) $sql.=" desc";
  718. }
  719. $res = mysql_query($sql, $conn);
  720. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  721. $arr = array();
  722. while ($rec = mysql_fetch_assoc($res)){
  723. $arr[$rec["message_id"]] = $rec;
  724. // convert meta field
  725. if(empty($rec["meta"])){
  726. $arr[$rec["message_id"]]["meta"]=array();
  727. } else {
  728. $arr[$rec["message_id"]]["meta"]=unserialize($rec["meta"]);
  729. }
  730. if(empty($arr['users'])) $arr['users']=array();
  731. if($rec["user_id"]){
  732. $arr['users'][]=$rec["user_id"];
  733. }
  734. }
  735. if(count($arr) && $page != 0) {
  736. // selecting the thread-starter
  737. $sql = "select {$PHORUM['message_table']}.* from {$PHORUM['message_table']} where $forum_id_check message_id=$thread $approvedval";
  738. $res = mysql_query($sql, $conn);
  739. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  740. if(mysql_num_rows($res) > 0) {
  741. $rec = mysql_fetch_assoc($res);
  742. $arr[$rec["message_id"]] = $rec;
  743. $arr[$rec["message_id"]]["meta"]=unserialize($rec["meta"]);
  744. }
  745. }
  746. return $arr;
  747. }
  748. /**
  749. * Return the index of a message in a thread.
  750. * @param int $thread
  751. * @param int $message_id
  752. * @return int
  753. */
  754. function phorum_db_get_message_index($thread=0,$message_id=0) {
  755. $PHORUM = $GLOBALS["PHORUM"];
  756. // check for valid values
  757. if(empty($message_id) || empty($message_id)) {
  758. return 0;
  759. }
  760. settype($thread, "int");
  761. settype($message_id, "int");
  762. $approvedval="";
  763. $forum_id_check="";
  764. $conn = phorum_db_mysql_connect();
  765. if (!empty($PHORUM["forum_id"])){
  766. $forum_id_check = "(forum_id = {$PHORUM['forum_id']} OR forum_id={$PHORUM['vroot']}) AND";
  767. }
  768. if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES)) {
  769. $approvedval="AND {$PHORUM['message_table']}.status =".PHORUM_STATUS_APPROVED;
  770. }
  771. $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";
  772. $res = mysql_query($sql, $conn);
  773. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  774. $rec = mysql_fetch_assoc($res);
  775. return $rec['msg_index'];
  776. }
  777. /**
  778. * Search the database for the supplied search criteria and returns
  779. * an array with two elements. One is the count of total messages that
  780. * matched, the second is an array of the messages from the results
  781. * based on the $start (0 base) given and the $length given.
  782. *
  783. * @param string $search
  784. * @param int $offset
  785. * @param int $length
  786. * @param string $match_type
  787. * @param int $match_date
  788. * @param string $match_forum
  789. *
  790. * @return array
  791. */
  792. function phorum_db_search($search, $offset, $length, $match_type, $match_date, $match_forum)
  793. {
  794. $PHORUM = $GLOBALS["PHORUM"];
  795. $start = $offset * $PHORUM["list_length"];
  796. $arr = array("count" => 0, "rows" => array());
  797. $conn = phorum_db_mysql_connect();
  798. // have to check what forums they can read first.
  799. $allowed_forums=phorum_user_access_list(PHORUM_USER_ALLOW_READ);
  800. // if they are not allowed to search any forums, return the emtpy $arr;
  801. if(empty($allowed_forums) || ($PHORUM['forum_id']>0 && !in_array($PHORUM['forum_id'], $allowed_forums)) ) return $arr;
  802. // Add forum 0 (for announcements) to the allowed forums.
  803. $allowed_forums[] = 0;
  804. if($PHORUM['forum_id']!=0 && $match_forum!="ALL"){
  805. $forum_where=" and forum_id={$PHORUM['forum_id']}";
  806. } else {
  807. $forum_where=" and forum_id in (".implode(",", $allowed_forums).")";
  808. }
  809. // prepare terms
  810. if($match_type=="PHRASE"){
  811. $terms = array('"'.$search.'"');
  812. } elseif($match_type=="AUTHOR"){
  813. $terms = mysql_escape_string($search);
  814. } else {
  815. $quote_terms=array();
  816. if ( strstr( $search, '"' ) ){
  817. //first pull out all the double quoted strings (e.g. '"iMac DV" or -"iMac DV"')
  818. preg_match_all( '/-*"(.*?)"/', $search, $match );
  819. $search = preg_replace( '/-*".*?"/', '', $search );
  820. $quote_terms = $match[0];
  821. }
  822. //finally pull out the rest words in the string
  823. $terms = preg_split( "/\s+/", $search, 0, PREG_SPLIT_NO_EMPTY );
  824. //merge them all together and return
  825. $terms = array_merge($terms, $quote_terms);
  826. }
  827. if($PHORUM["DBCONFIG"]["mysql_use_ft"]){
  828. if($match_type=="AUTHOR"){
  829. $id_table=$PHORUM['search_table']."_auth_".md5(microtime());
  830. $sql = "create temporary table $id_table (key(message_id)) ENGINE=HEAP select message_id from {$PHORUM['message_table']} where author='$terms' $forum_where";
  831. if($match_date>0){
  832. $ts=time()-86400*$match_date;
  833. $sql.=" and datestamp>=$ts";
  834. }
  835. $res = mysql_query($sql, $conn);
  836. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  837. } else {
  838. if(count($terms)){
  839. $use_key="";
  840. $extra_where="";
  841. /* using this code on larger forums has shown to make the search faster.
  842. However, on smaller forums, it does not appear to help and in fact
  843. appears to slow down searches.
  844. if($match_date){
  845. $min_time=time()-86400*$match_date;
  846. $sql="select min(message_id) as min_id from {$PHORUM['message_table']} where datestamp>=$min_time";
  847. $res=mysql_query($sql, $conn);
  848. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  849. $min_id=mysql_result($res, 0, "min_id");
  850. $use_key=" use key (primary)";
  851. $extra_where="and message_id>=$min_id";
  852. }
  853. */
  854. $id_table=$PHORUM['search_table']."_ft_".md5(microtime());
  855. if($PHORUM["DBCONFIG"]["mysql_use_ft"]){
  856. if($match_type=="ALL" && count($terms)>1){
  857. $against="+".mysql_escape_string(implode(" +", $terms));
  858. } else {
  859. $against=mysql_escape_string(implode(" ", $terms));
  860. }
  861. $clause="MATCH (search_text) AGAINST ('$against' IN BOOLEAN MODE)";
  862. } else {
  863. if($match_type=="ALL"){
  864. $conj="and";
  865. } else {
  866. $conj="or";
  867. }
  868. // quote strings correctly
  869. foreach ($terms as $id => $term) {
  870. $terms[$id] = mysql_escape_string($term);
  871. }
  872. $clause = "( search_text like '%".implode("%' $conj search_text like '%", $terms)."%' )";
  873. }
  874. $sql = "create temporary table $id_table (key(message_id)) ENGINE=HEAP select message_id from {$PHORUM['search_table']} $use_key where $clause $extra_where";
  875. $res = mysql_unbuffered_query($sql, $conn);
  876. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  877. }
  878. }
  879. if(isset($id_table)){
  880. // create a temporary table of the messages we want
  881. $table=$PHORUM['search_table']."_".md5(microtime());
  882. $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";
  883. if($match_date>0){
  884. $ts=time()-86400*$match_date;
  885. $sql.=" and datestamp>=$ts";
  886. }
  887. $res=mysql_query($sql, $conn);
  888. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  889. $sql="select count(*) as count from $table";
  890. $res = mysql_query($sql, $conn);
  891. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  892. $total_count=mysql_result($res, 0, 0);
  893. $sql="select message_id from $table order by datestamp desc limit $start, $length";
  894. $res = mysql_unbuffered_query($sql, $conn);
  895. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  896. $idstring="";
  897. while ($rec = mysql_fetch_row($res)){
  898. $idstring.="$rec[0],";
  899. }
  900. $idstring=substr($idstring, 0, -1);
  901. }
  902. } else { // not using full text matching
  903. if($match_type=="AUTHOR"){
  904. $sql_core = "from {$PHORUM['message_table']} where author='$terms' $forum_where";
  905. if($match_date>0){
  906. $ts=time()-86400*$match_date;
  907. $sql_core.=" and datestamp>=$ts";
  908. }
  909. $sql = "select count(*) $sql_core";
  910. $res = mysql_query($sql, $conn);
  911. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  912. $total_count=mysql_result($res, 0, 0);
  913. $sql = "select message_id $sql_core order by datestamp desc limit $start, $length";
  914. $res = mysql_unbuffered_query($sql, $conn);
  915. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  916. $idstring="";
  917. while ($rec = mysql_fetch_row($res)){
  918. $idstring.="$rec[0],";
  919. }
  920. $idstring=substr($idstring, 0, -1);
  921. } else {
  922. if(count($terms)){
  923. $id_table=$PHORUM['search_table']."_ft_".md5(microtime());
  924. if($match_type=="ALL"){
  925. $conj="and";
  926. } else {
  927. $conj="or";
  928. }
  929. // quote strings correctly
  930. foreach ($terms as $id => $term) {
  931. $terms[$id] = mysql_escape_string($term);
  932. }
  933. $clause = "( concat(author, ' | ', subject, ' | ', body) like '%".implode("%' $conj concat(author, ' | ', subject, ' | ', body) like '%", $terms)."%' )";
  934. $sql = "select count(*) from {$PHORUM['message_table']} where status=".PHORUM_STATUS_APPROVED." and $clause $forum_where";
  935. $res = mysql_query($sql, $conn);
  936. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  937. $total_count=mysql_result($res, 0, 0);
  938. $sql = "select message_id from {$PHORUM['message_table']} where status=".PHORUM_STATUS_APPROVED." and $clause $forum_where order by datestamp desc limit $start, $length";
  939. $res = mysql_unbuffered_query($sql, $conn);
  940. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  941. $idstring="";
  942. while ($rec = mysql_fetch_row($res)){
  943. $idstring.="$rec[0],";
  944. }
  945. $idstring=substr($idstring, 0, -1);
  946. }
  947. }
  948. }
  949. if($idstring){
  950. $sql="select * from {$PHORUM['message_table']} where message_id in ($idstring) order by datestamp desc";
  951. $res = mysql_unbuffered_query($sql, $conn);
  952. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  953. $rows = array();
  954. while ($rec = mysql_fetch_assoc($res)){
  955. $rows[$rec["message_id"]] = $rec;
  956. }
  957. $arr = array("count" => $total_count, "rows" => $rows);
  958. }
  959. return $arr;
  960. }
  961. /**
  962. * Return the closest thread that is greater than $key.
  963. * @param int $key
  964. * @return mixed
  965. */
  966. function phorum_db_get_newer_thread($key){
  967. $PHORUM = $GLOBALS["PHORUM"];
  968. settype($key, "int");
  969. $conn = phorum_db_mysql_connect();
  970. $keyfield = ($PHORUM["float_to_top"]) ? "modifystamp" : "thread";
  971. // are we really allowed to show this thread/message?
  972. $approvedval = "";
  973. if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES) && $PHORUM["moderation"] == PHORUM_MODERATE_ON) {
  974. $approvedval="AND {$PHORUM['message_table']}.status =".PHORUM_STATUS_APPROVED;
  975. } else {
  976. $approvedval="AND {$PHORUM['message_table']}.parent_id = 0";
  977. }
  978. $sql = "select thread from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} $approvedval and $keyfield>$key order by $keyfield limit 1";
  979. $res = mysql_query($sql, $conn);
  980. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  981. return (mysql_num_rows($res)) ? mysql_result($res, 0, "thread") : 0;
  982. }
  983. /**
  984. * Returns the closest thread that is less than $key.
  985. * @param int $key
  986. * @return mixed
  987. */
  988. function phorum_db_get_older_thread($key){
  989. $PHORUM = $GLOBALS["PHORUM"];
  990. settype($key, "int");
  991. $conn = phorum_db_mysql_connect();
  992. $keyfield = ($PHORUM["float_to_top"]) ? "modifystamp" : "thread";
  993. // are we really allowed to show this thread/message?
  994. $approvedval = "";
  995. if(!phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES) && $PHORUM["moderation"] == PHORUM_MODERATE_ON) {
  996. $approvedval="AND {$PHORUM['message_table']}.status=".PHORUM_STATUS_APPROVED;
  997. } else {
  998. $approvedval="AND {$PHORUM['message_table']}.parent_id = 0";
  999. }
  1000. $sql = "select thread from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} $approvedval and $keyfield<$key order by $keyfield desc limit 1";
  1001. $res = mysql_query($sql, $conn);
  1002. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  1003. return (mysql_num_rows($res)) ? mysql_result($res, 0, "thread") : 0;
  1004. }
  1005. /**
  1006. * Load the settings in the global $PHORUM['SETTINGS'] variable.
  1007. *
  1008. * @return void
  1009. */
  1010. function phorum_db_load_settings(){
  1011. global $PHORUM;
  1012. $conn = phorum_db_mysql_connect();
  1013. $sql = "select * from {$PHORUM['settings_table']}";
  1014. $res = mysql_query($sql, $conn);
  1015. if(!$res && !defined("PHORUM_ADMIN")){
  1016. if (mysql_errno($conn)==1146){
  1017. // settings table does not exist
  1018. return;
  1019. } elseif(($err = mysql_error())){
  1020. phorum_db_mysql_error("$err: $sql");
  1021. }
  1022. }
  1023. if (empty($err) && $res){
  1024. while ($rec = mysql_fetch_assoc($res)){
  1025. // only load the default forum options in the admin
  1026. if($rec["name"]=="default_forum_options" && !defined("PHORUM_ADMIN")) continue;
  1027. if ($rec["type"] == "V"){
  1028. if ($rec["data"] == 'true'){
  1029. $val = true;
  1030. }elseif ($rec["data"] == 'false'){
  1031. $val = false;
  1032. }elseif (is_numeric($rec["data"])){
  1033. $val = $rec["data"];
  1034. }else{
  1035. $val = "$rec[data]";
  1036. }
  1037. }else{
  1038. $val = unserialize($rec["data"]);
  1039. }
  1040. $PHORUM[$rec['name']]=$val;
  1041. $PHORUM['SETTINGS'][$rec['name']]=$val;
  1042. }
  1043. }
  1044. }
  1045. /**
  1046. * Update Phorum settings.
  1047. *
  1048. * @param array $settings
  1049. *
  1050. * @return boolean
  1051. */
  1052. function phorum_db_update_settings($settings){
  1053. global $PHORUM;
  1054. if (count($settings) > 0){
  1055. $conn = phorum_db_mysql_connect();
  1056. foreach($settings as $field => $value){
  1057. if (is_numeric($value)){
  1058. $type = 'V';
  1059. }elseif (is_string($value)){
  1060. $value = mysql_escape_string($value);
  1061. $type = 'V';
  1062. }else{
  1063. $value = mysql_escape_string(serialize($value));
  1064. $type = 'S';
  1065. }
  1066. $sql = "replace into {$PHORUM['settings_table']} set data='$value', type='$type', name='$field'";
  1067. $res = mysql_query($sql, $conn);
  1068. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  1069. }
  1070. return ($res > 0) ? true : false;
  1071. }else{
  1072. trigger_error("\$settings cannot be empty in phorum_db_update_settings()", E_USER_ERROR);
  1073. }
  1074. }
  1075. /**
  1076. * Get all forums for a flat/collapsed display and return the data in
  1077. * an array.
  1078. *
  1079. * @param mixed $forum_ids
  1080. * Can be an array of forum IDs or an int for one forum ID.
  1081. * @param int $parent_id
  1082. * @param unknown $vroot
  1083. * @param unknown $inherit_id
  1084. *
  1085. * @return array
  1086. */
  1087. function phorum_db_get_forums($forum_ids = 0, $parent_id = -1, $vroot = null, $inherit_id = null){
  1088. $PHORUM = $GLOBALS["PHORUM"];
  1089. settype($parent_id, "int");
  1090. $conn = phorum_db_mysql_connect();
  1091. if (is_array($forum_ids)) {
  1092. $int_ids = array();
  1093. foreach ($forum_ids as $id) {
  1094. settype($id, "int");
  1095. $int_ids[] = $id;
  1096. }
  1097. $forum_ids = implode(",", $int_ids);
  1098. } else {
  1099. settype($forum_ids, "int");
  1100. }
  1101. $sql = "select * from {$PHORUM['forums_table']} ";
  1102. if ($forum_ids){
  1103. $sql .= " where forum_id in ($forum_ids)";
  1104. } elseif ($inherit_id !== null) {
  1105. $sql .= " where inherit_id = $inherit_id";
  1106. if(!defined("PHORUM_ADMIN")) $sql.=" and active=1";
  1107. } elseif ($parent_id >= 0) {
  1108. $sql .= " where parent_id = $parent_id";
  1109. if(!defined("PHORUM_ADMIN")) $sql.=" and active=1";
  1110. } elseif($vroot !== null) {
  1111. $sql .= " where vroot = $vroot";
  1112. } else {
  1113. $sql .= " where forum_id <> 0";
  1114. }
  1115. $sql .= " order by display_order ASC, name";
  1116. $res = mysql_query($sql, $conn);
  1117. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  1118. $forums = array();
  1119. while ($row = mysql_fetch_assoc($res)){
  1120. $forums[$row["forum_id"]] = $row;
  1121. }
  1122. return $forums;
  1123. }
  1124. /**
  1125. * Update the forums stats.
  1126. *
  1127. * @param boolean $refresh
  1128. * If true, it pulls the numbers from the table.
  1129. * @param int $msg_count_change
  1130. * @param int $timestamp
  1131. * @param int $thread_count_change
  1132. * @param int $sticky_count_change
  1133. *
  1134. * @return void
  1135. */
  1136. function phorum_db_update_forum_stats($refresh=false, $msg_count_change=0, $timestamp=0, $thread_count_change=0, $sticky_count_change=0)
  1137. {
  1138. $PHORUM = $GLOBALS["PHORUM"];
  1139. $conn = phorum_db_mysql_connect();
  1140. // always refresh on small forums
  1141. if (isset($PHORUM["message_count"]) && $PHORUM["message_count"]<1000) {
  1142. $refresh=true;
  1143. }
  1144. if($refresh || empty($msg_count_change)){
  1145. $sql = "select count(*) as message_count from {$PHORUM['message_table']} where forum_id={$PHORUM['forum_id']} and status=".PHORUM_STATUS_APPROVED;
  1146. $res = mysql_query($sql, $conn);
  1147. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  1148. $message_count = (int)mysql_result($res, 0, "message_count");
  1149. } else {
  1150. $message_count="message_count+$msg_count_change";
  1151. }
  1152. if($refresh || empty($timestamp)){
  1153. $sql = "select max(modifystamp) as last_post_time from {$PHORUM['message_table']} where status=".PHORUM_STATUS_APPROVED." and forum_id={$PHORUM['forum_id']}";
  1154. $res = mysql_query($sql, $conn);
  1155. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  1156. $last_post_time = (int)mysql_result($res, 0, "last_post_time");
  1157. } else {
  1158. $last_post_time = $timestamp;
  1159. }
  1160. if($refresh || empty($thread_count_change)){
  1161. $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;
  1162. $res = mysql_query($sql, $conn);
  1163. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  1164. $thread_count = (int)mysql_result($res, 0, "thread_count");
  1165. } else {
  1166. $thread_count="thread_count+$thread_count_change";
  1167. }
  1168. if($refresh || empty($sticky_count_change)){
  1169. $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;
  1170. $res = mysql_query($sql, $conn);
  1171. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  1172. $sticky_count = (int)mysql_result($res, 0, "sticky_count");
  1173. } else {
  1174. $sticky_count="sticky_count+$sticky_count_change";
  1175. }
  1176. $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']}";
  1177. mysql_query($sql, $conn);
  1178. if ($err = mysql_error()) phorum_db_mysql_error("$err: $sql");
  1179. }
  1180. /**
  1181. * Move a thread to the given forum.
  1182. *
  1183. * @param in…

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