BioTorrents.de’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.

take_reply.php 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <?php
  2. #declare(strict_types=1);
  3. authorize();
  4. $ENV = ENV::go();
  5. // todo: Remove all the stupid queries that could get their information just as easily from the cache
  6. /*********************************************************************\
  7. //--------------Take Post--------------------------------------------//
  8. This page takes a forum post submission, validates it, and
  9. enters it into the database. The user is then redirected to their
  10. post.
  11. $_POST['action'] is what the user is trying to do. It can be:
  12. 'reply' if the user is replying to a thread
  13. It will be accompanied with:
  14. $_POST['thread']
  15. $_POST['body']
  16. \*********************************************************************/
  17. // If you're not sending anything, go back
  18. if (empty($_POST['body']) || !isset($_POST['body'])) {
  19. #if ($_POST['body'] === '' || !isset($_POST['body'])) {
  20. header('Location: '.$_SERVER['HTTP_REFERER']);
  21. error();
  22. }
  23. if (!empty($LoggedUser['DisablePosting'])) {
  24. error('Your posting privileges have been removed.');
  25. }
  26. $PerPage = $LoggedUser['PostsPerPage'] ?? POSTS_PER_PAGE;
  27. $Body = $_POST['body'];
  28. $TopicID = $_POST['thread'];
  29. $ThreadInfo = Forums::get_thread_info($TopicID);
  30. if ($ThreadInfo === null) {
  31. error(404);
  32. }
  33. $ForumID = $ThreadInfo['ForumID'];
  34. $SQLTime = sqltime();
  35. if (!Forums::check_forumperm($ForumID)) {
  36. error(403);
  37. }
  38. if (!Forums::check_forumperm($ForumID, 'Write') || $LoggedUser['DisablePosting'] || $ThreadInfo['IsLocked'] == '1' && !check_perms('site_moderate_forums')) {
  39. error(403);
  40. }
  41. if (strlen($Body) > 500000) {
  42. error('Your post is too large');
  43. }
  44. if (isset($_POST['subscribe']) && Subscriptions::has_subscribed($TopicID) === false) {
  45. Subscriptions::subscribe($TopicID);
  46. }
  47. // Now lets handle the special case of merging posts, we can skip bumping the thread and all that fun
  48. if ($ThreadInfo['LastPostAuthorID'] == $LoggedUser['ID'] && ((!check_perms('site_forums_double_post') || isset($_POST['merge'])))) {
  49. // Get the id for this post in the database to append
  50. $DB->query("
  51. SELECT ID, Body
  52. FROM forums_posts
  53. WHERE TopicID = ?
  54. AND AuthorID = ?
  55. ORDER BY ID DESC
  56. LIMIT 1", $TopicID, $LoggedUser['ID']);
  57. list($PostID, $OldBody) = $DB->next_record(MYSQLI_NUM, false);
  58. //Edit the post
  59. $DB->query("
  60. UPDATE forums_posts
  61. SET
  62. Body = CONCAT(Body, '\n\n', ?),
  63. EditedUserID = ?,
  64. EditedTime = ?
  65. WHERE ID = ?", $Body, $LoggedUser['ID'], $SQLTime, $PostID);
  66. //Store edit history
  67. $DB->query("
  68. INSERT INTO comments_edits
  69. (Page, PostID, EditUser, EditTime, Body)
  70. VALUES
  71. ('forums', ?, ?, ?, ?)", $PostID, $LoggedUser['ID'], $SQLTime, $OldBody);
  72. $Cache->delete_value("forums_edits_$PostID");
  73. //Get the catalogue it is in
  74. $CatalogueID = floor((POSTS_PER_PAGE * ceil($ThreadInfo['Posts'] / POSTS_PER_PAGE) - POSTS_PER_PAGE) / THREAD_CATALOGUE);
  75. //Get the catalogue value for the post we're appending to
  76. if ($ThreadInfo['Posts'] % THREAD_CATALOGUE == 0) {
  77. $Key = THREAD_CATALOGUE - 1;
  78. } else {
  79. $Key = ($ThreadInfo['Posts'] % THREAD_CATALOGUE) - 1;
  80. }
  81. if ($ThreadInfo['StickyPostID'] == $PostID) {
  82. $ThreadInfo['StickyPost']['Body'] .= "\n\n".$Body;
  83. $ThreadInfo['StickyPost']['EditedUserID'] = $LoggedUser['ID'];
  84. $ThreadInfo['StickyPost']['EditedTime'] = $SQLTime;
  85. $Cache->cache_value("thread_$TopicID".'_info', $ThreadInfo, 0);
  86. }
  87. //Edit the post in the cache
  88. $Cache->begin_transaction("thread_$TopicID"."_catalogue_$CatalogueID");
  89. $Cache->update_row($Key, [
  90. 'Body' => $Cache->MemcacheDBArray[$Key]['Body']."\n\n$Body",
  91. 'EditedUserID' => $LoggedUser['ID'],
  92. 'EditedTime' => $SQLTime,
  93. 'Username' => $LoggedUser['Username']
  94. ]);
  95. $Cache->commit_transaction(0);
  96. //Now we're dealing with a normal post
  97. } else {
  98. //Insert the post into the posts database
  99. $DB->query(
  100. "
  101. INSERT INTO forums_posts (TopicID, AuthorID, AddedTime, Body)
  102. VALUES (?, ?, ?, ?)",
  103. $TopicID,
  104. $LoggedUser['ID'],
  105. $SQLTime,
  106. $Body
  107. );
  108. $PostID = $DB->inserted_id();
  109. //This updates the root index
  110. $DB->query("
  111. UPDATE forums
  112. SET
  113. NumPosts = NumPosts + 1,
  114. LastPostID = ?,
  115. LastPostAuthorID = ?,
  116. LastPostTopicID = ?,
  117. LastPostTime = ?
  118. WHERE ID = ?", $PostID, $LoggedUser['ID'], $TopicID, $SQLTime, $ForumID);
  119. //Update the topic
  120. $DB->query("
  121. UPDATE forums_topics
  122. SET
  123. NumPosts = NumPosts + 1,
  124. LastPostID = ?,
  125. LastPostAuthorID = ?,
  126. LastPostTime = ?
  127. WHERE ID = ?", $PostID, $LoggedUser['ID'], $SQLTime, $TopicID);
  128. // if cache exists modify it, if not, then it will be correct when selected next, and we can skip this block
  129. if ($Forum = $Cache->get_value("forums_$ForumID")) {
  130. list($Forum, , , $Stickies) = $Forum;
  131. // if the topic is already on this page
  132. if (array_key_exists($TopicID, $Forum)) {
  133. $Thread = $Forum[$TopicID];
  134. unset($Forum[$TopicID]);
  135. $Thread['NumPosts'] = $Thread['NumPosts'] + 1; // Increment post count
  136. $Thread['LastPostID'] = $PostID; // Set post ID for read/unread
  137. $Thread['LastPostTime'] = $SQLTime; // Time of last post
  138. $Thread['LastPostAuthorID'] = $LoggedUser['ID']; // Last poster ID
  139. $Part2 = [$TopicID => $Thread]; // Bumped thread
  140. // if we're bumping from an older page
  141. } else {
  142. // Remove the last thread from the index
  143. if (count($Forum) == TOPICS_PER_PAGE && $Stickies < TOPICS_PER_PAGE) {
  144. array_pop($Forum);
  145. }
  146. // Never know if we get a page full of stickies...
  147. if ($Stickies < TOPICS_PER_PAGE || $ThreadInfo['IsSticky'] == 1) {
  148. //Pull the data for the thread we're bumping
  149. $DB->query("
  150. SELECT
  151. f.AuthorID,
  152. f.IsLocked,
  153. f.IsSticky,
  154. f.NumPosts,
  155. ISNULL(p.TopicID) AS NoPoll
  156. FROM forums_topics AS f
  157. LEFT JOIN forums_polls AS p ON p.TopicID = f.ID
  158. WHERE f.ID = ?", $TopicID);
  159. list($AuthorID, $IsLocked, $IsSticky, $NumPosts, $NoPoll) = $DB->next_record();
  160. $Part2 = [
  161. $TopicID => [
  162. 'ID' => $TopicID,
  163. 'Title' => $ThreadInfo['Title'],
  164. 'AuthorID' => $AuthorID,
  165. 'IsLocked' => $IsLocked,
  166. 'IsSticky' => $IsSticky,
  167. 'NumPosts' => $NumPosts,
  168. 'LastPostID' => $PostID,
  169. 'LastPostTime' => $SQLTime,
  170. 'LastPostAuthorID' => $LoggedUser['ID'],
  171. 'NoPoll' => $NoPoll
  172. ]
  173. ]; //Bumped
  174. } else {
  175. $Part2 = [];
  176. }
  177. }
  178. if ($Stickies > 0) {
  179. $Part1 = array_slice($Forum, 0, $Stickies, true); //Stickies
  180. $Part3 = array_slice($Forum, $Stickies, TOPICS_PER_PAGE - $Stickies - 1, true); //Rest of page
  181. } else {
  182. $Part1 = [];
  183. $Part3 = $Forum;
  184. }
  185. if (is_null($Part1)) {
  186. $Part1 = [];
  187. }
  188. if (is_null($Part3)) {
  189. $Part3 = [];
  190. }
  191. if ($ThreadInfo['IsSticky'] == 1) {
  192. $Forum = $Part2 + $Part1 + $Part3; //Merge it
  193. } else {
  194. $Forum = $Part1 + $Part2 + $Part3; //Merge it
  195. }
  196. $Cache->cache_value("forums_$ForumID", [$Forum, '', 0, $Stickies], 0);
  197. //Update the forum root
  198. $Cache->begin_transaction('forums_list');
  199. $Cache->update_row($ForumID, [
  200. 'NumPosts' => '+1',
  201. 'LastPostID' => $PostID,
  202. 'LastPostAuthorID' => $LoggedUser['ID'],
  203. 'LastPostTopicID' => $TopicID,
  204. 'LastPostTime' => $SQLTime,
  205. 'Title' => $ThreadInfo['Title'],
  206. 'IsLocked' => $ThreadInfo['IsLocked'],
  207. 'IsSticky' => $ThreadInfo['IsSticky']
  208. ]);
  209. $Cache->commit_transaction(0);
  210. } else {
  211. //If there's no cache, we have no data, and if there's no data
  212. $Cache->delete_value('forums_list');
  213. }
  214. //This calculates the block of 500 posts that this one will fall under
  215. $CatalogueID = floor((POSTS_PER_PAGE * ceil($ThreadInfo['Posts'] / POSTS_PER_PAGE) - POSTS_PER_PAGE) / THREAD_CATALOGUE);
  216. //Insert the post into the thread catalogue (block of 500 posts)
  217. $Cache->begin_transaction("thread_$TopicID"."_catalogue_$CatalogueID");
  218. $Cache->insert('', [
  219. 'ID' => $PostID,
  220. 'AuthorID' => $LoggedUser['ID'],
  221. 'AddedTime' => $SQLTime,
  222. 'Body' => $Body,
  223. 'EditedUserID' => 0,
  224. 'EditedTime' => null,
  225. 'Username' => $LoggedUser['Username'] // todo: Remove, it's never used?
  226. ]);
  227. $Cache->commit_transaction(0);
  228. //Update the thread info
  229. $Cache->begin_transaction("thread_$TopicID".'_info');
  230. $Cache->update_row(false, ['Posts' => '+1', 'LastPostAuthorID' => $LoggedUser['ID']]);
  231. $Cache->commit_transaction(0);
  232. //Increment this now to make sure we redirect to the correct page
  233. $ThreadInfo['Posts']++;
  234. //Award a badge if necessary
  235. $DB->query("
  236. SELECT COUNT(ID)
  237. FROM forums_posts
  238. WHERE AuthorID = '$LoggedUser[ID]'");
  239. list($UserPosts) = $DB->next_record(MYSQLI_NUM, false);
  240. foreach ($ENV->AUTOMATED_BADGE_IDS->Posts as $Count => $Badge) {
  241. if ((int) $UserPosts >= $Count) {
  242. $Success = Badges::award_badge($LoggedUser['ID'], $Badge);
  243. if ($Success) {
  244. 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.");
  245. }
  246. }
  247. }
  248. }
  249. Subscriptions::flush_subscriptions('forums', $TopicID);
  250. Subscriptions::quote_notify($Body, $PostID, 'forums', $TopicID);
  251. header("Location: forums.php?action=viewthread&threadid=$TopicID&page=".ceil($ThreadInfo['Posts'] / $PerPage));
  252. die();