500000) { error('Your post is too large'); } if (isset($_POST['subscribe']) && Subscriptions::has_subscribed($TopicID) === false) { Subscriptions::subscribe($TopicID); } //Now lets handle the special case of merging posts, we can skip bumping the thread and all that fun if ($ThreadInfo['LastPostAuthorID'] == $LoggedUser['ID'] && ((!check_perms('site_forums_double_post') && !in_array($ForumID, FORUMS_TO_ALLOW_DOUBLE_POST)) || isset($_POST['merge']))) { //Get the id for this post in the database to append $DB->query(" SELECT ID, Body FROM forums_posts WHERE TopicID = ? AND AuthorID = ? ORDER BY ID DESC LIMIT 1", $TopicID, $LoggedUser['ID']); list($PostID, $OldBody) = $DB->next_record(MYSQLI_NUM, false); //Edit the post $DB->query(" UPDATE forums_posts SET Body = CONCAT(Body, '\n\n', ?), EditedUserID = ?, EditedTime = ? WHERE ID = ?", $Body, $LoggedUser['ID'], $SQLTime, $PostID); //Store edit history $DB->query(" INSERT INTO comments_edits (Page, PostID, EditUser, EditTime, Body) VALUES ('forums', ?, ?, ?, ?)", $PostID, $LoggedUser['ID'], $SQLTime, $OldBody); $Cache->delete_value("forums_edits_$PostID"); //Get the catalogue it is in $CatalogueID = floor((POSTS_PER_PAGE * ceil($ThreadInfo['Posts'] / POSTS_PER_PAGE) - POSTS_PER_PAGE) / THREAD_CATALOGUE); //Get the catalogue value for the post we're appending to if ($ThreadInfo['Posts'] % THREAD_CATALOGUE == 0) { $Key = THREAD_CATALOGUE - 1; } else { $Key = ($ThreadInfo['Posts'] % THREAD_CATALOGUE) - 1; } if ($ThreadInfo['StickyPostID'] == $PostID) { $ThreadInfo['StickyPost']['Body'] .= "\n\n".$Body; $ThreadInfo['StickyPost']['EditedUserID'] = $LoggedUser['ID']; $ThreadInfo['StickyPost']['EditedTime'] = $SQLTime; $Cache->cache_value("thread_$TopicID".'_info', $ThreadInfo, 0); } //Edit the post in the cache $Cache->begin_transaction("thread_$TopicID"."_catalogue_$CatalogueID"); $Cache->update_row($Key, [ 'Body' => $Cache->MemcacheDBArray[$Key]['Body']."\n\n$Body", 'EditedUserID' => $LoggedUser['ID'], 'EditedTime' => $SQLTime, 'Username' => $LoggedUser['Username'] ]); $Cache->commit_transaction(0); //Now we're dealing with a normal post } else { //Insert the post into the posts database $DB->query(" INSERT INTO forums_posts (TopicID, AuthorID, AddedTime, Body) VALUES (?, ?, ?, ?)", $TopicID, $LoggedUser['ID'], $SQLTime, $Body); $PostID = $DB->inserted_id(); //This updates the root index $DB->query(" UPDATE forums SET NumPosts = NumPosts + 1, LastPostID = ?, LastPostAuthorID = ?, LastPostTopicID = ?, LastPostTime = ? WHERE ID = ?", $PostID, $LoggedUser['ID'], $TopicID, $SQLTime, $ForumID); //Update the topic $DB->query(" UPDATE forums_topics SET NumPosts = NumPosts + 1, LastPostID = ?, LastPostAuthorID = ?, LastPostTime = ? WHERE ID = ?", $PostID, $LoggedUser['ID'], $SQLTime, $TopicID); // if cache exists modify it, if not, then it will be correct when selected next, and we can skip this block if ($Forum = $Cache->get_value("forums_$ForumID")) { list($Forum,,,$Stickies) = $Forum; // if the topic is already on this page if (array_key_exists($TopicID, $Forum)) { $Thread = $Forum[$TopicID]; unset($Forum[$TopicID]); $Thread['NumPosts'] = $Thread['NumPosts'] + 1; // Increment post count $Thread['LastPostID'] = $PostID; // Set post ID for read/unread $Thread['LastPostTime'] = $SQLTime; // Time of last post $Thread['LastPostAuthorID'] = $LoggedUser['ID']; // Last poster ID $Part2 = [$TopicID => $Thread]; // Bumped thread // if we're bumping from an older page } else { // Remove the last thread from the index if (count($Forum) == TOPICS_PER_PAGE && $Stickies < TOPICS_PER_PAGE) { array_pop($Forum); } // Never know if we get a page full of stickies... if ($Stickies < TOPICS_PER_PAGE || $ThreadInfo['IsSticky'] == 1) { //Pull the data for the thread we're bumping $DB->query(" SELECT f.AuthorID, f.IsLocked, f.IsSticky, f.NumPosts, ISNULL(p.TopicID) AS NoPoll FROM forums_topics AS f LEFT JOIN forums_polls AS p ON p.TopicID = f.ID WHERE f.ID = ?", $TopicID); list($AuthorID, $IsLocked, $IsSticky, $NumPosts, $NoPoll) = $DB->next_record(); $Part2 = [ $TopicID => [ 'ID' => $TopicID, 'Title' => $ThreadInfo['Title'], 'AuthorID' => $AuthorID, 'IsLocked' => $IsLocked, 'IsSticky' => $IsSticky, 'NumPosts' => $NumPosts, 'LastPostID' => $PostID, 'LastPostTime' => $SQLTime, 'LastPostAuthorID' => $LoggedUser['ID'], 'NoPoll' => $NoPoll ] ]; //Bumped } else { $Part2 = []; } } if ($Stickies > 0) { $Part1 = array_slice($Forum, 0, $Stickies, true); //Stickies $Part3 = array_slice($Forum, $Stickies, TOPICS_PER_PAGE - $Stickies - 1, true); //Rest of page } else { $Part1 = []; $Part3 = $Forum; } if (is_null($Part1)) { $Part1 = []; } if (is_null($Part3)) { $Part3 = []; } if ($ThreadInfo['IsSticky'] == 1) { $Forum = $Part2 + $Part1 + $Part3; //Merge it } else { $Forum = $Part1 + $Part2 + $Part3; //Merge it } $Cache->cache_value("forums_$ForumID", [$Forum, '', 0, $Stickies], 0); //Update the forum root $Cache->begin_transaction('forums_list'); $Cache->update_row($ForumID, [ 'NumPosts' => '+1', 'LastPostID' => $PostID, 'LastPostAuthorID' => $LoggedUser['ID'], 'LastPostTopicID' => $TopicID, 'LastPostTime' => $SQLTime, 'Title' => $ThreadInfo['Title'], 'IsLocked' => $ThreadInfo['IsLocked'], 'IsSticky' => $ThreadInfo['IsSticky'] ]); $Cache->commit_transaction(0); } else { //If there's no cache, we have no data, and if there's no data $Cache->delete_value('forums_list'); } //This calculates the block of 500 posts that this one will fall under $CatalogueID = floor((POSTS_PER_PAGE * ceil($ThreadInfo['Posts'] / POSTS_PER_PAGE) - POSTS_PER_PAGE) / THREAD_CATALOGUE); //Insert the post into the thread catalogue (block of 500 posts) $Cache->begin_transaction("thread_$TopicID"."_catalogue_$CatalogueID"); $Cache->insert('', [ 'ID' => $PostID, 'AuthorID' => $LoggedUser['ID'], 'AddedTime' => $SQLTime, 'Body' => $Body, 'EditedUserID' => 0, 'EditedTime' => NULL, 'Username' => $LoggedUser['Username'] //TODO: Remove, it's never used? ]); $Cache->commit_transaction(0); //Update the thread info $Cache->begin_transaction("thread_$TopicID".'_info'); $Cache->update_row(false, ['Posts' => '+1', 'LastPostAuthorID' => $LoggedUser['ID']]); $Cache->commit_transaction(0); //Increment this now to make sure we redirect to the correct page $ThreadInfo['Posts']++; //Award a badge if necessary $DB->query(" SELECT COUNT(ID) FROM forums_posts WHERE AuthorID = '$LoggedUser[ID]'"); list($UserPosts) = $DB->next_record(MYSQLI_NUM, false); foreach (AUTOMATED_BADGE_IDS['Posts'] AS $Count => $Badge) { if ((int) $UserPosts >= $Count) { $Success = Badges::award_badge($LoggedUser['ID'], $Badge); if ($Success) { Misc::send_pm($LoggedUser['ID'], 0, 'You have received a badge!', "You have received a badge for making ".$Count." forum posts.\n\nIt can be enabled from your user settings."); } } } } Subscriptions::flush_subscriptions('forums', $TopicID); Subscriptions::quote_notify($Body, $PostID, 'forums', $TopicID); header("Location: forums.php?action=viewthread&threadid=$TopicID&page=".ceil($ThreadInfo['Posts'] / $PerPage)); die();