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.

mod_thread.php 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. <?php
  2. declare(strict_types=1);
  3. /*********************************************************************\
  4. //--------------Mod thread-------------------------------------------//
  5. This page gets called if we're editing a thread.
  6. Known issues:
  7. If multiple threads are moved before forum activity occurs then
  8. threads will linger with the 'Moved' flag until they're knocked off
  9. the front page.
  10. \*********************************************************************/
  11. $ENV = ENV::go();
  12. # omfg
  13. #define('TRASH_FORUM_ID', 4);
  14. // Quick SQL injection check
  15. if (!is_number($_POST['threadid'])) {
  16. error(404);
  17. }
  18. if ($_POST['title'] === '') {
  19. error(0);
  20. }
  21. // End injection check
  22. // Make sure they are moderators
  23. if (!check_perms('site_moderate_forums')) {
  24. error(403);
  25. }
  26. authorize();
  27. // Variables for database input
  28. $TopicID = (int)$_POST['threadid'];
  29. $Sticky = isset($_POST['sticky']) ? 1 : 0;
  30. $Locked = isset($_POST['locked']) ? 1 : 0;
  31. $Ranking = (int)$_POST['ranking'];
  32. if (!$Sticky && $Ranking > 0) {
  33. $Ranking = 0;
  34. } elseif (0 > $Ranking) {
  35. error('Ranking cannot be a negative value');
  36. }
  37. $Title = db_string($_POST['title']);
  38. $RawTitle = $_POST['title'];
  39. $ForumID = (int)$_POST['forumid'];
  40. $Page = (int)$_POST['page'];
  41. $Action = '';
  42. if ($Locked === 1) {
  43. $DB->query("
  44. DELETE FROM forums_last_read_topics
  45. WHERE TopicID = '$TopicID'");
  46. }
  47. $DB->query("
  48. SELECT
  49. t.ForumID,
  50. f.Name,
  51. f.MinClassWrite,
  52. COUNT(p.ID) AS Posts,
  53. t.AuthorID,
  54. t.Title,
  55. t.IsLocked,
  56. t.IsSticky,
  57. t.Ranking
  58. FROM forums_topics AS t
  59. LEFT JOIN forums_posts AS p ON p.TopicID = t.ID
  60. LEFT JOIN forums AS f ON f.ID = t.ForumID
  61. WHERE t.ID = '$TopicID'
  62. GROUP BY p.TopicID");
  63. list($OldForumID, $OldForumName, $MinClassWrite, $Posts, $ThreadAuthorID, $OldTitle, $OldLocked, $OldSticky, $OldRanking) = $DB->next_record(MYSQLI_BOTH, false);
  64. if ($MinClassWrite > $LoggedUser['Class']) {
  65. error(403);
  66. }
  67. // If we're deleting a thread
  68. if (isset($_POST['delete'])) {
  69. if (!check_perms('site_admin_forums')) {
  70. error(403);
  71. }
  72. $DB->query("
  73. DELETE FROM forums_posts
  74. WHERE TopicID = '$TopicID'");
  75. $DB->query("
  76. DELETE FROM forums_topics
  77. WHERE ID = '$TopicID'");
  78. $DB->query("
  79. SELECT
  80. t.ID,
  81. t.LastPostID,
  82. t.Title,
  83. p.AuthorID,
  84. um.Username,
  85. p.AddedTime,
  86. (
  87. SELECT COUNT(pp.ID)
  88. FROM forums_posts AS pp
  89. JOIN forums_topics AS tt ON pp.TopicID = tt.ID
  90. WHERE tt.ForumID = '$ForumID'
  91. ),
  92. t.IsLocked,
  93. t.IsSticky
  94. FROM forums_topics AS t
  95. JOIN forums_posts AS p ON p.ID = t.LastPostID
  96. LEFT JOIN users_main AS um ON um.ID = p.AuthorID
  97. WHERE t.ForumID = '$ForumID'
  98. GROUP BY t.ID
  99. ORDER BY t.LastPostID DESC
  100. LIMIT 1");
  101. list($NewLastTopic, $NewLastPostID, $NewLastTitle, $NewLastAuthorID, $NewLastAuthorName, $NewLastAddedTime, $NumPosts, $NewLocked, $NewSticky) = $DB->next_record(MYSQLI_NUM, false);
  102. $DB->query("
  103. UPDATE forums
  104. SET
  105. NumTopics = NumTopics - 1,
  106. NumPosts = NumPosts - '$Posts',
  107. LastPostTopicID = '$NewLastTopic',
  108. LastPostID = '$NewLastPostID',
  109. LastPostAuthorID = '$NewLastAuthorID',
  110. LastPostTime = '$NewLastAddedTime'
  111. WHERE ID = '$ForumID'");
  112. $Cache->delete_value("forums_$ForumID");
  113. $Cache->delete_value("thread_$TopicID");
  114. $Cache->begin_transaction('forums_list');
  115. $UpdateArray = array(
  116. 'NumPosts' => $NumPosts,
  117. 'NumTopics' => '-1',
  118. 'LastPostID' => $NewLastPostID,
  119. 'LastPostAuthorID' => $NewLastAuthorID,
  120. 'LastPostTopicID' => $NewLastTopic,
  121. 'LastPostTime' => $NewLastAddedTime,
  122. 'Title' => $NewLastTitle,
  123. 'IsLocked' => $NewLocked,
  124. 'IsSticky' => $NewSticky
  125. );
  126. $Cache->update_row($ForumID, $UpdateArray);
  127. $Cache->commit_transaction(0);
  128. $Cache->delete_value("thread_{$TopicID}_info");
  129. // subscriptions
  130. Subscriptions::move_subscriptions('forums', $TopicID, null);
  131. // quote notifications
  132. Subscriptions::flush_quote_notifications('forums', $TopicID);
  133. $DB->query("
  134. DELETE FROM users_notify_quoted
  135. WHERE Page = 'forums'
  136. AND PageID = '$TopicID'");
  137. header("Location: forums.php?action=viewforum&forumid=$ForumID");
  138. } else { // If we're just editing it
  139. $Action = 'editing';
  140. if (isset($_POST['trash'])) {
  141. $ForumID = $ENV->TRASH_FORUM;
  142. $Action = 'trashing';
  143. }
  144. $Cache->begin_transaction("thread_{$TopicID}_info");
  145. $UpdateArray = array(
  146. 'IsSticky' => $Sticky,
  147. 'Ranking' => $Ranking,
  148. 'IsLocked' => $Locked,
  149. 'Title' => Format::cut_string($RawTitle, 150, 1, 0),
  150. 'ForumID' => $ForumID
  151. );
  152. $Cache->update_row(false, $UpdateArray);
  153. $Cache->commit_transaction(0);
  154. $DB->query("
  155. UPDATE forums_topics
  156. SET
  157. IsSticky = '$Sticky',
  158. Ranking = '$Ranking',
  159. IsLocked = '$Locked',
  160. Title = '$Title',
  161. ForumID = '$ForumID'
  162. WHERE ID = '$TopicID'");
  163. // always clear cache when editing a thread.
  164. // if a thread title, etc. is changed, this cache key must be cleared so the thread listing
  165. // properly shows the new thread title.
  166. $Cache->delete_value("forums_$ForumID");
  167. if ($ForumID != $OldForumID) { // If we're moving a thread, change the forum stats
  168. $Cache->delete_value("forums_$OldForumID");
  169. $DB->query("
  170. SELECT MinClassRead, MinClassWrite, Name
  171. FROM forums
  172. WHERE ID = '$ForumID'");
  173. list($MinClassRead, $MinClassWrite, $ForumName) = $DB->next_record(MYSQLI_NUM, false);
  174. $Cache->begin_transaction("thread_{$TopicID}_info");
  175. $UpdateArray = array(
  176. 'ForumName' => $ForumName,
  177. 'MinClassRead' => $MinClassRead,
  178. 'MinClassWrite' => $MinClassWrite
  179. );
  180. $Cache->update_row(false, $UpdateArray);
  181. $Cache->commit_transaction(3600 * 24 * 5);
  182. $Cache->begin_transaction('forums_list');
  183. // Forum we're moving from
  184. $DB->query("
  185. SELECT
  186. t.ID,
  187. t.LastPostID,
  188. t.Title,
  189. p.AuthorID,
  190. um.Username,
  191. p.AddedTime,
  192. (
  193. SELECT COUNT(pp.ID)
  194. FROM forums_posts AS pp
  195. JOIN forums_topics AS tt ON pp.TopicID = tt.ID
  196. WHERE tt.ForumID = '$OldForumID'
  197. ),
  198. t.IsLocked,
  199. t.IsSticky,
  200. t.Ranking
  201. FROM forums_topics AS t
  202. JOIN forums_posts AS p ON p.ID = t.LastPostID
  203. LEFT JOIN users_main AS um ON um.ID = p.AuthorID
  204. WHERE t.ForumID = '$OldForumID'
  205. ORDER BY t.LastPostID DESC
  206. LIMIT 1");
  207. list($NewLastTopic, $NewLastPostID, $NewLastTitle, $NewLastAuthorID, $NewLastAuthorName, $NewLastAddedTime, $NumPosts, $NewLocked, $NewSticky, $NewRanking) = $DB->next_record(MYSQLI_NUM, false);
  208. $DB->query("
  209. UPDATE forums
  210. SET
  211. NumTopics = NumTopics - 1,
  212. NumPosts = NumPosts - '$Posts',
  213. LastPostTopicID = '$NewLastTopic',
  214. LastPostID = '$NewLastPostID',
  215. LastPostAuthorID = '$NewLastAuthorID',
  216. LastPostTime = '$NewLastAddedTime'
  217. WHERE ID = '$OldForumID'");
  218. $UpdateArray = array(
  219. 'NumPosts' => $NumPosts,
  220. 'NumTopics' => '-1',
  221. 'LastPostID' => $NewLastPostID,
  222. 'LastPostAuthorID' => $NewLastAuthorID,
  223. 'LastPostTopicID' => $NewLastTopic,
  224. 'LastPostTime' => $NewLastAddedTime,
  225. 'Title' => $NewLastTitle,
  226. 'IsLocked' => $NewLocked,
  227. 'IsSticky' => $NewSticky,
  228. 'Ranking' => $NewRanking
  229. );
  230. $Cache->update_row($OldForumID, $UpdateArray);
  231. // Forum we're moving to
  232. $DB->query("
  233. SELECT
  234. t.ID,
  235. t.LastPostID,
  236. t.Title,
  237. p.AuthorID,
  238. um.Username,
  239. p.AddedTime,
  240. (
  241. SELECT COUNT(pp.ID)
  242. FROM forums_posts AS pp
  243. JOIN forums_topics AS tt ON pp.TopicID = tt.ID
  244. WHERE tt.ForumID = '$ForumID'
  245. )
  246. FROM forums_topics AS t
  247. JOIN forums_posts AS p ON p.ID = t.LastPostID
  248. LEFT JOIN users_main AS um ON um.ID = p.AuthorID
  249. WHERE t.ForumID = '$ForumID'
  250. ORDER BY t.LastPostID DESC
  251. LIMIT 1");
  252. list($NewLastTopic, $NewLastPostID, $NewLastTitle, $NewLastAuthorID, $NewLastAuthorName, $NewLastAddedTime, $NumPosts) = $DB->next_record(MYSQLI_NUM, false);
  253. $DB->query("
  254. UPDATE forums
  255. SET
  256. NumTopics = NumTopics + 1,
  257. NumPosts = NumPosts + '$Posts',
  258. LastPostTopicID = '$NewLastTopic',
  259. LastPostID = '$NewLastPostID',
  260. LastPostAuthorID = '$NewLastAuthorID',
  261. LastPostTime = '$NewLastAddedTime'
  262. WHERE ID = '$ForumID'");
  263. $UpdateArray = array(
  264. 'NumPosts' => ($NumPosts + $Posts),
  265. 'NumTopics' => '+1',
  266. 'LastPostID' => $NewLastPostID,
  267. 'LastPostAuthorID' => $NewLastAuthorID,
  268. 'LastPostTopicID' => $NewLastTopic,
  269. 'LastPostTime' => $NewLastAddedTime,
  270. 'Title' => $NewLastTitle
  271. );
  272. $Cache->update_row($ForumID, $UpdateArray);
  273. $Cache->commit_transaction(0);
  274. if ($ForumID === $ENV->TRASH_FORUM) {
  275. $Action = 'trashing';
  276. }
  277. } else { // Editing
  278. $DB->query("
  279. SELECT LastPostTopicID
  280. FROM forums
  281. WHERE ID = '$ForumID'");
  282. list($LastTopicID) = $DB->next_record();
  283. if ($LastTopicID === $TopicID) {
  284. $UpdateArray = array(
  285. 'Title' => $RawTitle,
  286. 'IsLocked' => $Locked,
  287. 'IsSticky' => $Sticky,
  288. 'Ranking' => $Ranking
  289. );
  290. $Cache->begin_transaction('forums_list');
  291. $Cache->update_row($ForumID, $UpdateArray);
  292. $Cache->commit_transaction(0);
  293. }
  294. }
  295. if ($Locked) {
  296. $CatalogueID = floor($NumPosts / THREAD_CATALOGUE);
  297. for ($i = 0; $i <= $CatalogueID; $i++) {
  298. $Cache->expire_value("thread_{$TopicID}_catalogue_$i", 3600 * 24 * 7); // 7 days
  299. }
  300. $Cache->expire_value("thread_{$TopicID}_info", 3600 * 24 * 7); // 7 days
  301. $DB->query("
  302. UPDATE forums_polls
  303. SET Closed = '0'
  304. WHERE TopicID = '$TopicID'");
  305. $Cache->delete_value("polls_$TopicID");
  306. }
  307. // topic notes and notifications
  308. $TopicNotes = [];
  309. switch ($Action) {
  310. case 'editing':
  311. if ($OldTitle != $RawTitle) {
  312. // title edited
  313. $TopicNotes[] = "Title edited from \"$OldTitle\" to \"$RawTitle\"";
  314. }
  315. if ($OldLocked != $Locked) {
  316. if (!$OldLocked) {
  317. $TopicNotes[] = 'Locked';
  318. } else {
  319. $TopicNotes[] = 'Unlocked';
  320. }
  321. }
  322. if ($OldSticky != $Sticky) {
  323. if (!$OldSticky) {
  324. $TopicNotes[] = 'Stickied';
  325. } else {
  326. $TopicNotes[] = 'Unstickied';
  327. }
  328. }
  329. if ($OldRanking != $Ranking) {
  330. $TopicNotes[] = "Ranking changed from \"$OldRanking\" to \"$Ranking\"";
  331. }
  332. if ($ForumID != $OldForumID) {
  333. $TopicNotes[] = "Moved from [url=" . site_url() . "forums.php?action=viewforum&forumid=$OldForumID]{$OldForumName}[/url] to [url=" . site_url() . "forums.php?action=viewforum&forumid=$ForumID]{$ForumName}[/url]";
  334. }
  335. break;
  336. case 'trashing':
  337. $TopicNotes[] = "Trashed (moved from [url=" . site_url() . "forums.php?action=viewforum&forumid=$OldForumID]{$OldForumName}[/url] to [url=" . site_url() . "forums.php?action=viewforum&forumid=$ForumID]{$ForumName}[/url])";
  338. $Notification = "Your thread \"$NewLastTitle\" has been trashed";
  339. break;
  340. default:
  341. break;
  342. }
  343. if (isset($Notification)) {
  344. NotificationsManager::notify_user($ThreadAuthorID, NotificationsManager::FORUMALERTS, $Notification, "forums.php?action=viewthread&threadid=$TopicID");
  345. }
  346. if (count($TopicNotes) > 0) {
  347. Forums::add_topic_note($TopicID, implode("\n", $TopicNotes));
  348. }
  349. header("Location: forums.php?action=viewthread&threadid=$TopicID&page=$Page");
  350. }