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.

take_reply.php 9.4KB

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