Oppaitime's version of Gazelle
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

forums.class.php 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. <?
  2. class Forums {
  3. /**
  4. * Get information on a thread.
  5. *
  6. * @param int $ThreadID
  7. * the thread ID.
  8. * @param boolean $Return
  9. * indicates whether thread info should be returned.
  10. * @param Boolean $SelectiveCache
  11. * cache thread info/
  12. * @return array holding thread information.
  13. */
  14. public static function get_thread_info($ThreadID, $Return = true, $SelectiveCache = false) {
  15. if ((!$ThreadInfo = G::$Cache->get_value('thread_' . $ThreadID . '_info')) || !isset($ThreadInfo['Ranking'])) {
  16. $QueryID = G::$DB->get_query_id();
  17. G::$DB->query("
  18. SELECT
  19. t.Title,
  20. t.ForumID,
  21. t.IsLocked,
  22. t.IsSticky,
  23. COUNT(fp.id) AS Posts,
  24. t.LastPostAuthorID,
  25. ISNULL(p.TopicID) AS NoPoll,
  26. t.StickyPostID,
  27. t.AuthorID as OP,
  28. t.Ranking
  29. FROM forums_topics AS t
  30. JOIN forums_posts AS fp ON fp.TopicID = t.ID
  31. LEFT JOIN forums_polls AS p ON p.TopicID = t.ID
  32. WHERE t.ID = '$ThreadID'
  33. GROUP BY fp.TopicID");
  34. if (!G::$DB->has_results()) {
  35. G::$DB->set_query_id($QueryID);
  36. return null;
  37. }
  38. $ThreadInfo = G::$DB->next_record(MYSQLI_ASSOC, false);
  39. if ($ThreadInfo['StickyPostID']) {
  40. $ThreadInfo['Posts']--;
  41. G::$DB->query(
  42. "SELECT
  43. p.ID,
  44. p.AuthorID,
  45. p.AddedTime,
  46. p.Body,
  47. p.EditedUserID,
  48. p.EditedTime,
  49. ed.Username
  50. FROM forums_posts AS p
  51. LEFT JOIN users_main AS ed ON ed.ID = p.EditedUserID
  52. WHERE p.TopicID = '$ThreadID'
  53. AND p.ID = '" . $ThreadInfo['StickyPostID'] . "'");
  54. list ($ThreadInfo['StickyPost']) = G::$DB->to_array(false, MYSQLI_ASSOC);
  55. }
  56. G::$DB->set_query_id($QueryID);
  57. if (!$SelectiveCache || !$ThreadInfo['IsLocked'] || $ThreadInfo['IsSticky']) {
  58. G::$Cache->cache_value('thread_' . $ThreadID . '_info', $ThreadInfo, 0);
  59. }
  60. }
  61. if ($Return) {
  62. return $ThreadInfo;
  63. }
  64. }
  65. /**
  66. * Checks whether user has permissions on a forum.
  67. *
  68. * @param int $ForumID
  69. * the forum ID.
  70. * @param string $Perm
  71. * the permissision to check, defaults to 'Read'
  72. * @return boolean true if user has permission
  73. */
  74. public static function check_forumperm($ForumID, $Perm = 'Read') {
  75. $Forums = self::get_forums();
  76. if (isset(G::$LoggedUser['CustomForums'][$ForumID]) && G::$LoggedUser['CustomForums'][$ForumID] == 1) {
  77. return true;
  78. }
  79. if ($ForumID == DONOR_FORUM && Donations::has_donor_forum(G::$LoggedUser['ID'])) {
  80. return true;
  81. }
  82. if ($Forums[$ForumID]['MinClass' . $Perm] > G::$LoggedUser['Class'] && (!isset(G::$LoggedUser['CustomForums'][$ForumID]) || G::$LoggedUser['CustomForums'][$ForumID] == 0)) {
  83. return false;
  84. }
  85. if (isset(G::$LoggedUser['CustomForums'][$ForumID]) && G::$LoggedUser['CustomForums'][$ForumID] == 0) {
  86. return false;
  87. }
  88. return true;
  89. }
  90. /**
  91. * Gets basic info on a forum.
  92. *
  93. * @param int $ForumID
  94. * the forum ID.
  95. */
  96. public static function get_forum_info($ForumID) {
  97. $Forum = G::$Cache->get_value("ForumInfo_$ForumID");
  98. if (!$Forum) {
  99. $QueryID = G::$DB->get_query_id();
  100. G::$DB->query("
  101. SELECT
  102. Name,
  103. MinClassRead,
  104. MinClassWrite,
  105. MinClassCreate,
  106. COUNT(forums_topics.ID) AS Topics
  107. FROM forums
  108. LEFT JOIN forums_topics ON forums_topics.ForumID = forums.ID
  109. WHERE forums.ID = '$ForumID'
  110. GROUP BY ForumID");
  111. if (!G::$DB->has_results()) {
  112. return false;
  113. }
  114. // Makes an array, with $Forum['Name'], etc.
  115. $Forum = G::$DB->next_record(MYSQLI_ASSOC);
  116. G::$DB->set_query_id($QueryID);
  117. G::$Cache->cache_value("ForumInfo_$ForumID", $Forum, 86400);
  118. }
  119. return $Forum;
  120. }
  121. /**
  122. * Get the forum categories
  123. * @return array ForumCategoryID => Name
  124. */
  125. public static function get_forum_categories() {
  126. $ForumCats = G::$Cache->get_value('forums_categories');
  127. if ($ForumCats === false) {
  128. $QueryID = G::$DB->get_query_id();
  129. G::$DB->query("
  130. SELECT ID, Name
  131. FROM forums_categories");
  132. $ForumCats = array();
  133. while (list ($ID, $Name) = G::$DB->next_record()) {
  134. $ForumCats[$ID] = $Name;
  135. }
  136. G::$DB->set_query_id($QueryID);
  137. G::$Cache->cache_value('forums_categories', $ForumCats, 0);
  138. }
  139. return $ForumCats;
  140. }
  141. /**
  142. * Get the forums
  143. * @return array ForumID => (various information about the forum)
  144. */
  145. public static function get_forums() {
  146. if (!$Forums = G::$Cache->get_value('forums_list')) {
  147. $QueryID = G::$DB->get_query_id();
  148. G::$DB->query("
  149. SELECT
  150. f.ID,
  151. f.CategoryID,
  152. f.Name,
  153. f.Description,
  154. f.MinClassRead AS MinClassRead,
  155. f.MinClassWrite AS MinClassWrite,
  156. f.MinClassCreate AS MinClassCreate,
  157. f.NumTopics,
  158. f.NumPosts,
  159. f.LastPostID,
  160. f.LastPostAuthorID,
  161. f.LastPostTopicID,
  162. f.LastPostTime,
  163. 0 AS SpecificRules,
  164. t.Title,
  165. t.IsLocked AS Locked,
  166. t.IsSticky AS Sticky
  167. FROM forums AS f
  168. JOIN forums_categories AS fc ON fc.ID = f.CategoryID
  169. LEFT JOIN forums_topics AS t ON t.ID = f.LastPostTopicID
  170. GROUP BY f.ID
  171. ORDER BY fc.Sort, fc.Name, f.CategoryID, f.Sort");
  172. $Forums = G::$DB->to_array('ID', MYSQLI_ASSOC, false);
  173. G::$DB->query("
  174. SELECT ForumID, ThreadID
  175. FROM forums_specific_rules");
  176. $SpecificRules = array();
  177. while (list($ForumID, $ThreadID) = G::$DB->next_record(MYSQLI_NUM, false)) {
  178. $SpecificRules[$ForumID][] = $ThreadID;
  179. }
  180. G::$DB->set_query_id($QueryID);
  181. foreach ($Forums as $ForumID => &$Forum) {
  182. if (isset($SpecificRules[$ForumID])) {
  183. $Forum['SpecificRules'] = $SpecificRules[$ForumID];
  184. } else {
  185. $Forum['SpecificRules'] = array();
  186. }
  187. }
  188. G::$Cache->cache_value('forums_list', $Forums, 0);
  189. }
  190. return $Forums;
  191. }
  192. /**
  193. * Get all forums that the current user has special access to ("Extra forums" in the profile)
  194. * @return array Array of ForumIDs
  195. */
  196. public static function get_permitted_forums() {
  197. if (isset(G::$LoggedUser['CustomForums'])) {
  198. return (array)array_keys(G::$LoggedUser['CustomForums'], 1);
  199. } else {
  200. return array();
  201. }
  202. }
  203. /**
  204. * Get all forums that the current user does not have access to ("Restricted forums" in the profile)
  205. * @return array Array of ForumIDs
  206. */
  207. public static function get_restricted_forums() {
  208. if (isset(G::$LoggedUser['CustomForums'])) {
  209. return (array)array_keys(G::$LoggedUser['CustomForums'], 0);
  210. } else {
  211. return array();
  212. }
  213. }
  214. /**
  215. * Get the last read posts for the current user
  216. * @param array $Forums Array of forums as returned by self::get_forums()
  217. * @return array TopicID => array(TopicID, PostID, Page) where PostID is the ID of the last read post and Page is the page on which that post is
  218. */
  219. public static function get_last_read($Forums) {
  220. if (isset(G::$LoggedUser['PostsPerPage'])) {
  221. $PerPage = G::$LoggedUser['PostsPerPage'];
  222. } else {
  223. $PerPage = POSTS_PER_PAGE;
  224. }
  225. $TopicIDs = array();
  226. foreach ($Forums as $Forum) {
  227. if (!empty($Forum['LastPostTopicID'])) {
  228. $TopicIDs[] = $Forum['LastPostTopicID'];
  229. }
  230. }
  231. if (!empty($TopicIDs)) {
  232. $QueryID = G::$DB->get_query_id();
  233. G::$DB->query("
  234. SELECT
  235. l.TopicID,
  236. l.PostID,
  237. CEIL(
  238. (
  239. SELECT
  240. COUNT(p.ID)
  241. FROM forums_posts AS p
  242. WHERE p.TopicID = l.TopicID
  243. AND p.ID <= l.PostID
  244. ) / $PerPage
  245. ) AS Page
  246. FROM forums_last_read_topics AS l
  247. WHERE l.TopicID IN(" . implode(',', $TopicIDs) . ") AND
  248. l.UserID = '" . G::$LoggedUser['ID'] . "'");
  249. $LastRead = G::$DB->to_array('TopicID', MYSQLI_ASSOC);
  250. G::$DB->set_query_id($QueryID);
  251. } else {
  252. $LastRead = array();
  253. }
  254. return $LastRead;
  255. }
  256. /**
  257. * Add a note to a topic.
  258. * @param int $TopicID
  259. * @param string $Note
  260. * @param int|null $UserID
  261. * @return boolean
  262. */
  263. public static function add_topic_note($TopicID, $Note, $UserID = null) {
  264. if ($UserID === null) {
  265. $UserID = G::$LoggedUser['ID'];
  266. }
  267. $QueryID = G::$DB->get_query_id();
  268. G::$DB->query("
  269. INSERT INTO forums_topic_notes
  270. (TopicID, AuthorID, AddedTime, Body)
  271. VALUES
  272. ($TopicID, $UserID, '" . sqltime() . "', '" . db_string($Note) . "')");
  273. G::$DB->set_query_id($QueryID);
  274. return (bool)G::$DB->affected_rows();
  275. }
  276. /**
  277. * Determine if a thread is unread
  278. * @param bool $Locked
  279. * @param bool $Sticky
  280. * @param int $LastPostID
  281. * @param array $LastRead An array as returned by self::get_last_read
  282. * @param int $LastTopicID TopicID of the thread where the most recent post was made
  283. * @param string $LastTime Datetime of the last post
  284. * @return bool
  285. */
  286. public static function is_unread($Locked, $Sticky, $LastPostID, $LastRead, $LastTopicID, $LastTime) {
  287. return (!$Locked || $Sticky) && $LastPostID != 0 && ((empty($LastRead[$LastTopicID]) || $LastRead[$LastTopicID]['PostID'] < $LastPostID) && strtotime($LastTime) > G::$LoggedUser['CatchupTime']);
  288. }
  289. /**
  290. * Create the part of WHERE in the sql queries used to filter forums for a
  291. * specific user (MinClassRead, restricted and permitted forums).
  292. * @return string
  293. */
  294. public static function user_forums_sql() {
  295. // I couldn't come up with a good name, please rename this if you can. -- Y
  296. $RestrictedForums = self::get_restricted_forums();
  297. $PermittedForums = self::get_permitted_forums();
  298. if (Donations::has_donor_forum(G::$LoggedUser['ID']) && !in_array(DONOR_FORUM, $PermittedForums)) {
  299. $PermittedForums[] = DONOR_FORUM;
  300. }
  301. $SQL = "((f.MinClassRead <= '" . G::$LoggedUser['Class'] . "'";
  302. if (count($RestrictedForums)) {
  303. $SQL .= " AND f.ID NOT IN ('" . implode("', '", $RestrictedForums) . "')";
  304. }
  305. $SQL .= ')';
  306. if (count($PermittedForums)) {
  307. $SQL .= " OR f.ID IN ('" . implode("', '", $PermittedForums) . "')";
  308. }
  309. $SQL .= ')';
  310. return $SQL;
  311. }
  312. }