123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 |
- <?php
-
- class Forums
- {
- /**
- * Get information on a thread.
- *
- * @param int $ThreadID the thread ID.
- * @param boolean $Return indicates whether thread info should be returned.
- * @param Boolean $SelectiveCache cache thread info.
- * @return array holding thread information.
- */
- public static function get_thread_info($ThreadID, $Return = true, $SelectiveCache = false)
- {
- if ((!$ThreadInfo = G::$Cache->get_value('thread_' . $ThreadID . '_info')) || !isset($ThreadInfo['Ranking'])) {
- $QueryID = G::$DB->get_query_id();
- G::$DB->query(
- "
- SELECT
- t.`Title`,
- t.`ForumID`,
- t.`IsLocked`,
- t.`IsSticky`,
- COUNT(fp.`id`) AS Posts,
- t.`LastPostAuthorID`,
- ISNULL(p.`TopicID`) AS NoPoll,
- t.`StickyPostID`,
- t.`AuthorID` AS OP,
- t.`Ranking`
- FROM
- `forums_topics` AS t
- JOIN `forums_posts` AS fp
- ON
- fp.`TopicID` = t.`ID`
- LEFT JOIN `forums_polls` AS p
- ON
- p.`TopicID` = t.`ID`
- WHERE
- t.`ID` = ?
- GROUP BY
- fp.TopicID
- ",
- $ThreadID
- );
-
- if (!G::$DB->has_results()) {
- G::$DB->set_query_id($QueryID);
- return null;
- }
-
- $ThreadInfo = G::$DB->next_record(MYSQLI_ASSOC, false);
- if ($ThreadInfo['StickyPostID']) {
- $ThreadInfo['Posts']--;
- G::$DB->query(
- "
- SELECT
- p.`ID`,
- p.`AuthorID`,
- p.`AddedTime`,
- p.`Body`,
- p.`EditedUserID`,
- p.`EditedTime`,
- ed.`Username`
- FROM
- `forums_posts` AS p
- LEFT JOIN `users_main` AS ed
- ON
- ed.`ID` = p.`EditedUserID`
- WHERE
- p.`TopicID` = ? AND p.`ID` = ? ",
- $ThreadID,
- $ThreadInfo['StickyPostID']
- );
- list($ThreadInfo['StickyPost']) = G::$DB->to_array(false, MYSQLI_ASSOC);
- }
-
- G::$DB->set_query_id($QueryID);
- if (!$SelectiveCache || !$ThreadInfo['IsLocked'] || $ThreadInfo['IsSticky']) {
- G::$Cache->cache_value('thread_'.$ThreadID.'_info', $ThreadInfo, 0);
- }
- }
-
- if ($Return) {
- return $ThreadInfo;
- }
- }
-
- /**
- * Checks whether user has permissions on a forum.
- *
- * @param int $ForumID the forum ID.
- * @param string $Perm the permissision to check, defaults to 'Read'
- * @return boolean true if user has permission
- */
- public static function check_forumperm($ForumID, $Perm = 'Read')
- {
- $Forums = self::get_forums();
- if (isset(G::$LoggedUser['CustomForums'][$ForumID]) && G::$LoggedUser['CustomForums'][$ForumID] === 1) {
- return true;
- }
-
- if ($ForumID === DONOR_FORUM && Donations::has_donor_forum(G::$LoggedUser['ID'])) {
- return true;
- }
-
- if ($Forums[$ForumID]['MinClass' . $Perm] > G::$LoggedUser['Class'] && (!isset(G::$LoggedUser['CustomForums'][$ForumID]) || G::$LoggedUser['CustomForums'][$ForumID] == 0)) {
- return false;
- }
-
- if (isset(G::$LoggedUser['CustomForums'][$ForumID]) && G::$LoggedUser['CustomForums'][$ForumID] === 0) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Gets basic info on a forum.
- *
- * @param int $ForumID the forum ID.
- */
- public static function get_forum_info($ForumID)
- {
- $Forum = G::$Cache->get_value("ForumInfo_$ForumID");
- if (!$Forum) {
- $QueryID = G::$DB->get_query_id();
- G::$DB->query(
- "
- SELECT
- `Name`,
- `MinClassRead`,
- `MinClassWrite`,
- `MinClassCreate`,
- COUNT(`forums_topics`.`ID`) AS Topics
- FROM
- `forums`
- LEFT JOIN `forums_topics` ON `forums_topics`.`ForumID` = `forums`.`ID`
- WHERE
- `forums`.`ID` = ?
- GROUP BY
- `ForumID`
- ",
- $ForumID
- );
-
- if (!G::$DB->has_results()) {
- return false;
- }
-
- // Makes an array, with $Forum['Name'], etc.
- $Forum = G::$DB->next_record(MYSQLI_ASSOC);
- G::$DB->set_query_id($QueryID);
- G::$Cache->cache_value("ForumInfo_$ForumID", $Forum, 86400);
- }
- return $Forum;
- }
-
- /**
- * Get the forum categories
- * @return array ForumCategoryID => Name
- */
- public static function get_forum_categories()
- {
- $ForumCats = G::$Cache->get_value('forums_categories');
- if ($ForumCats === false) {
- $QueryID = G::$DB->get_query_id();
- G::$DB->query("
- SELECT
- `ID`,
- `Name`
- FROM
- `forums_categories`
- ");
-
- $ForumCats = [];
- while (list($ID, $Name) = G::$DB->next_record()) {
- $ForumCats[$ID] = $Name;
- }
-
- G::$DB->set_query_id($QueryID);
- G::$Cache->cache_value('forums_categories', $ForumCats, 0);
- }
- return $ForumCats;
- }
-
- /**
- * Get the forums
- * @return array ForumID => (various information about the forum)
- */
- public static function get_forums()
- {
- if (!$Forums = G::$Cache->get_value('forums_list')) {
- $QueryID = G::$DB->get_query_id();
- G::$DB->query("
- SELECT
- f.`ID`,
- f.`CategoryID`,
- f.`Name`,
- f.`Description`,
- f.`MinClassRead` AS MinClassRead,
- f.`MinClassWrite` AS MinClassWrite,
- f.`MinClassCreate` AS MinClassCreate,
- f.`NumTopics`,
- f.`NumPosts`,
- f.`LastPostID`,
- f.`LastPostAuthorID`,
- f.`LastPostTopicID`,
- f.`LastPostTime`,
- 0 AS SpecificRules,
- t.`Title`,
- t.`IsLocked` AS Locked,
- t.`IsSticky` AS Sticky
- FROM
- `forums` AS f
- JOIN `forums_categories` AS fc
- ON
- fc.`ID` = f.`CategoryID`
- LEFT JOIN `forums_topics` AS t
- ON
- t.`ID` = f.`LastPostTopicID`
- GROUP BY
- f.`ID`
- ORDER BY
- fc.`Sort`,
- fc.`Name`,
- f.`CategoryID`,
- f.`Sort`
- ");
- $Forums = G::$DB->to_array('ID', MYSQLI_ASSOC, false);
-
- G::$DB->query("
- SELECT
- `ForumID`,
- `ThreadID`
- FROM
- `forums_specific_rules`
- ");
-
- $SpecificRules = [];
- while (list($ForumID, $ThreadID) = G::$DB->next_record(MYSQLI_NUM, false)) {
- $SpecificRules[$ForumID][] = $ThreadID;
- }
-
- G::$DB->set_query_id($QueryID);
- foreach ($Forums as $ForumID => &$Forum) {
- if (isset($SpecificRules[$ForumID])) {
- $Forum['SpecificRules'] = $SpecificRules[$ForumID];
- } else {
- $Forum['SpecificRules'] = [];
- }
- }
- G::$Cache->cache_value('forums_list', $Forums, 0);
- }
- return $Forums;
- }
-
- /**
- * Get all forums that the current user has special access to ("Extra forums" in the profile)
- * @return array Array of ForumIDs
- */
- public static function get_permitted_forums()
- {
- if (isset(G::$LoggedUser['CustomForums'])) {
- return (array)array_keys(G::$LoggedUser['CustomForums'], 1);
- } else {
- return [];
- }
- }
-
- /**
- * Get all forums that the current user does not have access to ("Restricted forums" in the profile)
- * @return array Array of ForumIDs
- */
- public static function get_restricted_forums()
- {
- if (isset(G::$LoggedUser['CustomForums'])) {
- return (array)array_keys(G::$LoggedUser['CustomForums'], 0);
- } else {
- return [];
- }
- }
-
- /**
- * Get the last read posts for the current user
- * @param array $Forums Array of forums as returned by self::get_forums()
- * @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
- */
- public static function get_last_read($Forums)
- {
- if (isset(G::$LoggedUser['PostsPerPage'])) {
- $PerPage = G::$LoggedUser['PostsPerPage'];
- } else {
- $PerPage = POSTS_PER_PAGE;
- }
-
- $TopicIDs = [];
- foreach ($Forums as $Forum) {
- if (!empty($Forum['LastPostTopicID'])) {
- $TopicIDs[] = $Forum['LastPostTopicID'];
- }
- }
-
- if (!empty($TopicIDs)) {
- $QueryID = G::$DB->get_query_id();
- G::$DB->query(
- "
- SELECT
- l.`TopicID`,
- l.`PostID`,
- CEIL(
- (
- SELECT
- COUNT(p.`ID`)
- FROM
- `forums_posts` AS p
- WHERE
- p.`TopicID` = l.`TopicID` AND p.`ID` <= l.`PostID`
- ) / ?
- ) AS Page
- FROM
- `forums_last_read_topics` AS l
- WHERE
- l.`TopicID` IN(".implode(',', $TopicIDs).") AND l.`UserID` = ? ",
- $PerPage,
- G::$LoggedUser['ID']
- );
-
- $LastRead = G::$DB->to_array('TopicID', MYSQLI_ASSOC);
- G::$DB->set_query_id($QueryID);
- } else {
- $LastRead = [];
- }
- return $LastRead;
- }
-
- /**
- * Add a note to a topic.
- * @param int $TopicID
- * @param string $Note
- * @param int|null $UserID
- * @return boolean
- */
- public static function add_topic_note($TopicID, $Note, $UserID = null)
- {
- if ($UserID === null) {
- $UserID = G::$LoggedUser['ID'];
- }
-
- $QueryID = G::$DB->get_query_id();
- G::$DB->query("
- INSERT INTO `forums_topic_notes`(
- `TopicID`,
- `AuthorID`,
- `AddedTime`,
- `Body`
- )
- VALUES(
- '$TopicID',
- '$UserID',
- NOW(),
- '$Note'
- )
- ");
-
- G::$DB->set_query_id($QueryID);
- return (bool) G::$DB->affected_rows();
- }
-
- /**
- * Determine if a thread is unread
- * @param bool $Locked
- * @param bool $Sticky
- * @param int $LastPostID
- * @param array $LastRead An array as returned by self::get_last_read
- * @param int $LastTopicID TopicID of the thread where the most recent post was made
- * @param string $LastTime Datetime of the last post
- * @return bool
- */
- public static function is_unread($Locked, $Sticky, $LastPostID, $LastRead, $LastTopicID, $LastTime)
- {
- return (!$Locked || $Sticky)
- && $LastPostID !== 0
- && (
- (empty($LastRead[$LastTopicID]) || $LastRead[$LastTopicID]['PostID'] < $LastPostID)
- && strtotime($LastTime) > G::$LoggedUser['CatchupTime']
- );
- }
-
- /**
- * Create the part of WHERE in the sql queries used to filter forums for a
- * specific user (MinClassRead, restricted and permitted forums).
- * @return string
- */
- public static function user_forums_sql()
- {
- // I couldn't come up with a good name, please rename this if you can. -- Y
- $RestrictedForums = self::get_restricted_forums();
- $PermittedForums = self::get_permitted_forums();
-
- if (Donations::has_donor_forum(G::$LoggedUser['ID']) && !in_array(DONOR_FORUM, $PermittedForums)) {
- $PermittedForums[] = DONOR_FORUM;
- }
-
- $SQL = "((f.`MinClassRead` <= '" . G::$LoggedUser['Class'] . "'";
- if (count($RestrictedForums)) {
- $SQL .= " AND f.`ID` NOT IN ('" . implode("', '", $RestrictedForums) . "')";
- }
-
- $SQL .= ')';
- if (count($PermittedForums)) {
- $SQL .= " OR f.`ID` IN ('" . implode("', '", $PermittedForums) . "')";
- }
-
- $SQL .= ')';
- return $SQL;
- }
- }
|