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.

thread.php 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. <?php
  2. #declare(strict_types = 1);
  3. // todo: Normalize thread_*_info don't need to waste all that ram on things that are already in other caches
  4. /**********|| Page to show individual threads || ********************************\
  5. Things to expect in $_GET:
  6. ThreadID: ID of the forum curently being browsed
  7. page: The page the user's on.
  8. page = 1 is the same as no page
  9. ********************************************************************************/
  10. //---------- Things to sort out before it can start printing/generating content
  11. // Enable TOC
  12. Text::$TOC = true;
  13. // Check for lame SQL injection attempts
  14. if (!isset($_GET['threadid']) || !is_number($_GET['threadid'])) {
  15. if (isset($_GET['topicid']) && is_number($_GET['topicid'])) {
  16. $ThreadID = $_GET['topicid'];
  17. } elseif (isset($_GET['postid']) && is_number($_GET['postid'])) {
  18. $DB->query("
  19. SELECT TopicID
  20. FROM forums_posts
  21. WHERE ID = $_GET[postid]");
  22. list($ThreadID) = $DB->next_record();
  23. if ($ThreadID) {
  24. header("Location: forums.php?action=viewthread&threadid=$ThreadID&postid=$_GET[postid]#post$_GET[postid]");
  25. error();
  26. } else {
  27. error(404);
  28. }
  29. } else {
  30. error(404);
  31. }
  32. } else {
  33. $ThreadID = $_GET['threadid'];
  34. }
  35. if (isset($LoggedUser['PostsPerPage'])) {
  36. $PerPage = $LoggedUser['PostsPerPage'];
  37. } else {
  38. $PerPage = POSTS_PER_PAGE;
  39. }
  40. //---------- Get some data to start processing
  41. // Thread information, constant across all pages
  42. $ThreadInfo = Forums::get_thread_info($ThreadID, true, true);
  43. if ($ThreadInfo === null) {
  44. error(404);
  45. }
  46. $ForumID = $ThreadInfo['ForumID'];
  47. $IsDonorForum = ($ForumID == DONOR_FORUM);
  48. // Make sure they're allowed to look at the page
  49. if (!Forums::check_forumperm($ForumID)) {
  50. error(403);
  51. }
  52. //Escape strings for later display
  53. $ThreadTitle = display_str($ThreadInfo['Title']);
  54. $ForumName = display_str($Forums[$ForumID]['Name']);
  55. //Post links utilize the catalogue & key params to prevent issues with custom posts per page
  56. if ($ThreadInfo['Posts'] > $PerPage) {
  57. if (isset($_GET['post']) && is_number($_GET['post'])) {
  58. $PostNum = $_GET['post'];
  59. } elseif (isset($_GET['postid']) && is_number($_GET['postid']) && $_GET['postid'] != $ThreadInfo['StickyPostID']) {
  60. $SQL = "
  61. SELECT COUNT(ID)
  62. FROM forums_posts
  63. WHERE TopicID = $ThreadID
  64. AND ID <= $_GET[postid]";
  65. if ($ThreadInfo['StickyPostID'] < $_GET['postid']) {
  66. $SQL .= " AND ID != $ThreadInfo[StickyPostID]";
  67. }
  68. $DB->query($SQL);
  69. list($PostNum) = $DB->next_record();
  70. } else {
  71. $PostNum = 1;
  72. }
  73. } else {
  74. $PostNum = 1;
  75. }
  76. list($Page, $Limit) = Format::page_limit($PerPage, min($ThreadInfo['Posts'], $PostNum));
  77. if (($Page - 1) * $PerPage > $ThreadInfo['Posts']) {
  78. $Page = ceil($ThreadInfo['Posts'] / $PerPage);
  79. }
  80. list($CatalogueID, $CatalogueLimit) = Format::catalogue_limit($Page, $PerPage, THREAD_CATALOGUE);
  81. // Cache catalogue from which the page is selected, allows block caches and future ability to specify posts per page
  82. if (!$Catalogue = $Cache->get_value("thread_{$ThreadID}_catalogue_$CatalogueID")) {
  83. $DB->query("
  84. SELECT
  85. p.ID,
  86. p.AuthorID,
  87. p.AddedTime,
  88. p.Body,
  89. p.EditedUserID,
  90. p.EditedTime,
  91. ed.Username
  92. FROM forums_posts AS p
  93. LEFT JOIN users_main AS ed ON ed.ID = p.EditedUserID
  94. WHERE p.TopicID = '$ThreadID'
  95. AND p.ID != '".$ThreadInfo['StickyPostID']."'
  96. LIMIT $CatalogueLimit");
  97. $Catalogue = $DB->to_array(false, MYSQLI_ASSOC);
  98. if (!$ThreadInfo['IsLocked'] || $ThreadInfo['IsSticky']) {
  99. $Cache->cache_value("thread_{$ThreadID}_catalogue_$CatalogueID", $Catalogue, 0);
  100. }
  101. }
  102. $Thread = Format::catalogue_select($Catalogue, $Page, $PerPage, THREAD_CATALOGUE);
  103. $LastPost = end($Thread);
  104. $LastPost = $LastPost['ID'];
  105. $FirstPost = reset($Thread);
  106. $FirstPost = $FirstPost['ID'];
  107. if ($ThreadInfo['Posts'] <= $PerPage*$Page && $ThreadInfo['StickyPostID'] > $LastPost) {
  108. $LastPost = $ThreadInfo['StickyPostID'];
  109. }
  110. //Handle last read
  111. //Why would we skip this on locked or stickied threads?
  112. //if (!$ThreadInfo['IsLocked'] || $ThreadInfo['IsSticky']) {
  113. $DB->query("
  114. SELECT PostID
  115. FROM forums_last_read_topics
  116. WHERE UserID = '$LoggedUser[ID]'
  117. AND TopicID = '$ThreadID'");
  118. list($LastRead) = $DB->next_record();
  119. if ($LastRead < $LastPost) {
  120. $DB->query("
  121. INSERT INTO forums_last_read_topics
  122. (UserID, TopicID, PostID)
  123. VALUES
  124. ('$LoggedUser[ID]', '$ThreadID', '".db_string($LastPost)."')
  125. ON DUPLICATE KEY UPDATE
  126. PostID = '$LastPost'");
  127. }
  128. //}
  129. //Handle subscriptions
  130. $UserSubscriptions = Subscriptions::get_subscriptions();
  131. if (empty($UserSubscriptions)) {
  132. $UserSubscriptions = [];
  133. }
  134. if (in_array($ThreadID, $UserSubscriptions)) {
  135. $Cache->delete_value('subscriptions_user_new_'.$LoggedUser['ID']);
  136. }
  137. $QuoteNotificationsCount = $Cache->get_value('notify_quoted_' . $LoggedUser['ID']);
  138. if ($QuoteNotificationsCount === false || $QuoteNotificationsCount > 0) {
  139. $DB->query("
  140. UPDATE users_notify_quoted
  141. SET UnRead = false
  142. WHERE UserID = '$LoggedUser[ID]'
  143. AND Page = 'forums'
  144. AND PageID = '$ThreadID'
  145. AND PostID >= '$FirstPost'
  146. AND PostID <= '$LastPost'");
  147. $Cache->delete_value('notify_quoted_' . $LoggedUser['ID']);
  148. }
  149. // Start printing
  150. View::show_header(
  151. $ThreadInfo['Title'].' &rsaquo; '.$Forums[$ForumID]['Name'].' &rsaquo; Forums',
  152. 'comments,subscriptions,bbcode,vendor/easymde.min',
  153. ($IsDonorForum ?? 'donor,').'vendor/easymde.min'
  154. );
  155. ?>
  156. <div class="header">
  157. <h2>
  158. <a href="forums.php">Forums</a> &rsaquo;
  159. <a
  160. href="forums.php?action=viewforum&amp;forumid=<?=$ThreadInfo['ForumID']?>"><?=$ForumName?></a> &rsaquo;
  161. <?=$ThreadTitle?>
  162. </h2>
  163. <div class="linkbox">
  164. <div class="center">
  165. <a href="reports.php?action=report&amp;type=thread&amp;id=<?=$ThreadID?>"
  166. class="brackets">Report thread</a>
  167. <a href="#" onclick="Subscribe(<?=$ThreadID?>);return false;"
  168. id="subscribelink<?=$ThreadID?>" class="brackets"><?=(in_array($ThreadID, $UserSubscriptions) ? 'Unsubscribe' : 'Subscribe')?></a>
  169. <a data-toggle-target="#searchthread" data-toggle-replace="Hide search" class="brackets">Search this thread</a>
  170. </div>
  171. <div id="searchthread" class="hidden center">
  172. <div style="display: inline-block;">
  173. <h3>
  174. Search This Thread
  175. </h3>
  176. <form class="search_form" name="forum_thread" action="forums.php" method="get">
  177. <input type="hidden" name="action" value="search" />
  178. <input type="hidden" name="threadid"
  179. value="<?=$ThreadID?>" />
  180. <table class="layout border">
  181. <tr>
  182. <td></td>
  183. <td>
  184. <input type="search" id="searchbox" name="search" size="70" placeholder="Search Terms" />
  185. </td>
  186. </tr>
  187. <tr>
  188. <td>
  189. </td>
  190. <td>
  191. <input type="search" id="username" name="user" size="70" placeholder="Posted By" />
  192. </td>
  193. </tr>
  194. <tr>
  195. <td colspan="2" style="text-align: center;">
  196. <input type="submit" name="submit" value="Search" />
  197. </td>
  198. </tr>
  199. </table>
  200. </form>
  201. </div>
  202. </div>
  203. </div>
  204. </div>
  205. <?php
  206. $Pages = Format::get_pages($Page, $ThreadInfo['Posts'], $PerPage, 9);
  207. echo $Pages;
  208. if ($ThreadInfo['NoPoll'] == 0) {
  209. if (!list($Question, $Answers, $Votes, $Featured, $Closed) = $Cache->get_value("polls_$ThreadID")) {
  210. $DB->query("
  211. SELECT Question, Answers, Featured, Closed
  212. FROM forums_polls
  213. WHERE TopicID = '$ThreadID'");
  214. list($Question, $Answers, $Featured, $Closed) = $DB->next_record(MYSQLI_NUM, array(1));
  215. $Answers = unserialize($Answers);
  216. $DB->query("
  217. SELECT Vote, COUNT(UserID)
  218. FROM forums_polls_votes
  219. WHERE TopicID = '$ThreadID'
  220. GROUP BY Vote");
  221. $VoteArray = $DB->to_array(false, MYSQLI_NUM);
  222. $Votes = [];
  223. foreach ($VoteArray as $VoteSet) {
  224. list($Key, $Value) = $VoteSet;
  225. $Votes[$Key] = $Value;
  226. }
  227. foreach (array_keys($Answers) as $i) {
  228. if (!isset($Votes[$i])) {
  229. $Votes[$i] = 0;
  230. }
  231. }
  232. $Cache->cache_value("polls_$ThreadID", array($Question, $Answers, $Votes, $Featured, $Closed), 0);
  233. }
  234. if (!empty($Votes)) {
  235. $TotalVotes = array_sum($Votes);
  236. $MaxVotes = max($Votes);
  237. } else {
  238. $TotalVotes = 0;
  239. $MaxVotes = 0;
  240. }
  241. #$RevealVoters = in_array($ForumID, FORUMS_TO_REVEAL_VOTERS);
  242. // Polls lose the you voted arrow thingy
  243. $DB->query("
  244. SELECT Vote
  245. FROM forums_polls_votes
  246. WHERE UserID = '".$LoggedUser['ID']."'
  247. AND TopicID = '$ThreadID'");
  248. list($UserResponse) = $DB->next_record(); ?>
  249. <div class="box thin clear">
  250. <div class="head colhead_dark"><strong>Poll<?php if ($Closed) {
  251. echo ' [Closed]';
  252. } ?><?php if ($Featured) {
  253. echo ' [Featured]';
  254. } ?>
  255. </strong>
  256. <a href="#" onclick="$('#threadpoll').gtoggle(); log_hit(); return false;" class="brackets">View</a>
  257. </div>
  258. <div class="pad<?php if (/*$LastRead !== null || */$ThreadInfo['IsLocked']) {
  259. echo ' hidden';
  260. } ?>" id="threadpoll">
  261. <p><strong><?=display_str($Question)?></strong></p>
  262. <?php if ($UserResponse !== null || $Closed || $ThreadInfo['IsLocked'] || !Forums::check_forumperm($ForumID)) { ?>
  263. <ul class="poll nobullet">
  264. <?php
  265. if (!$RevealVoters) {
  266. foreach ($Answers as $i => $Answer) {
  267. if (!empty($Votes[$i]) && $TotalVotes > 0) {
  268. $Ratio = $Votes[$i] / $MaxVotes;
  269. $Percent = $Votes[$i] / $TotalVotes;
  270. } else {
  271. $Ratio = 0;
  272. $Percent = 0;
  273. } ?>
  274. <li<?=((!empty($UserResponse)&&($UserResponse == $i))?' class="poll_your_answer"':'')?>><?=display_str($Answer)?> (<?=number_format($Percent * 100, 2)?>%)</li>
  275. <li class="graph">
  276. <span class="center_poll"
  277. style="width: <?=round($Ratio * 750)?>px;"></span>
  278. </li>
  279. <?php
  280. }
  281. if ($Votes[0] > 0) {
  282. ?>
  283. <li>
  284. <?= ($UserResponse == '0' ? '&raquo;&nbsp;' : '') ?>
  285. (Blank)
  286. (<?= number_format((float) ($Votes[0] / $TotalVotes * 100), 2) ?>%)
  287. </li>
  288. <li class="graph">
  289. <span class="center_poll"
  290. style="width: <?=round(($Votes[0] / $MaxVotes) * 750)?>px;"></span>
  291. <span class="right_poll"></span>
  292. </li>
  293. <?php
  294. } ?>
  295. </ul>
  296. <br />
  297. <strong>Votes:</strong> <?=number_format($TotalVotes)?><br /><br />
  298. <?php
  299. } else {
  300. //Staff forum, output voters, not percentages
  301. include(SERVER_ROOT.'/sections/staff/functions.php');
  302. $Staff = get_staff();
  303. $StaffNames = [];
  304. foreach ($Staff as $Staffer) {
  305. $StaffNames[] = $Staffer['Username'];
  306. }
  307. $DB->query("
  308. SELECT
  309. fpv.Vote AS Vote,
  310. GROUP_CONCAT(um.Username SEPARATOR ', ')
  311. FROM users_main AS um
  312. LEFT JOIN forums_polls_votes AS fpv ON um.ID = fpv.UserID
  313. WHERE TopicID = $ThreadID
  314. GROUP BY fpv.Vote");
  315. $StaffVotesTmp = $DB->to_array();
  316. $StaffCount = count($StaffNames);
  317. $StaffVotes = [];
  318. foreach ($StaffVotesTmp as $StaffVote) {
  319. list($Vote, $Names) = $StaffVote;
  320. $StaffVotes[$Vote] = $Names;
  321. $Names = explode(', ', $Names);
  322. $StaffNames = array_diff($StaffNames, $Names);
  323. } ?>
  324. <ul style="list-style: none;" id="poll_options">
  325. <?php
  326. foreach ($Answers as $i => $Answer) {
  327. ?>
  328. <li>
  329. <a
  330. href="forums.php?action=change_vote&amp;threadid=<?=$ThreadID?>&amp;auth=<?=$LoggedUser['AuthKey']?>&amp;vote=<?=(int)$i?>"><?=display_str($Answer == '' ? 'Blank' : $Answer)?></a>
  331. - <?=$StaffVotes[$i]?>&nbsp;(<?=number_format(((float)$Votes[$i] / $TotalVotes) * 100, 2)?>%)
  332. <a href="forums.php?action=delete_poll_option&amp;threadid=<?=$ThreadID?>&amp;auth=<?=$LoggedUser['AuthKey']?>&amp;vote=<?=(int)$i?>"
  333. class="brackets tooltip" title="Delete poll option">X</a>
  334. </li>
  335. <?php
  336. } ?>
  337. <li>
  338. <a
  339. href="forums.php?action=change_vote&amp;threadid=<?=$ThreadID?>&amp;auth=<?=$LoggedUser['AuthKey']?>&amp;vote=0"><?=($UserResponse == '0' ? '&raquo;&nbsp;' : '')?>Blank</a>
  340. - <?=$StaffVotes[0]?>&nbsp;(<?=number_format(((float)$Votes[0] / $TotalVotes) * 100, 2)?>%)
  341. </li>
  342. </ul>
  343. <?php
  344. if ($ForumID == STAFF_FORUM) {
  345. ?>
  346. <br />
  347. <strong>Votes:</strong> <?=number_format($StaffCount - count($StaffNames))?> / <?=$StaffCount?> current staff, <?=number_format($TotalVotes)?> total
  348. <br />
  349. <strong>Missing votes:</strong> <?=implode(", ", $StaffNames);
  350. echo "\n"; ?>
  351. <br /><br />
  352. <?php
  353. } ?>
  354. <a href="#"
  355. onclick="AddPollOption(<?=$ThreadID?>); return false;"
  356. class="brackets">+</a>
  357. <?php
  358. }
  359. } else {
  360. //User has not voted
  361. ?>
  362. <div id="poll_container">
  363. <form class="vote_form" name="poll" id="poll">
  364. <input type="hidden" name="action" value="poll" />
  365. <input type="hidden" name="auth"
  366. value="<?=$LoggedUser['AuthKey']?>" />
  367. <input type="hidden" name="large" value="1" />
  368. <input type="hidden" name="topicid" value="<?=$ThreadID?>" />
  369. <ul style="list-style: none;" id="poll_options">
  370. <?php foreach ($Answers as $i => $Answer) { //for ($i = 1, $il = count($Answers); $i <= $il; $i++) {?>
  371. <li>
  372. <input type="radio" name="vote" id="answer_<?=$i?>"
  373. value="<?=$i?>" />
  374. <label for="answer_<?=$i?>"><?=display_str($Answer)?></label>
  375. </li>
  376. <?php } ?>
  377. <li>
  378. <br />
  379. <input type="radio" name="vote" id="answer_0" value="0" /> <label
  380. for="answer_0">Blank&#8202;&mdash;&#8202;Show the results!</label><br />
  381. </li>
  382. </ul>
  383. <?php if ($ForumID == STAFF_FORUM) { ?>
  384. <a href="#"
  385. onclick="AddPollOption(<?=$ThreadID?>); return false;"
  386. class="brackets">+</a>
  387. <br />
  388. <br />
  389. <?php } ?>
  390. <input type="button"
  391. onclick="ajax.post('index.php','poll',function(response) { $('#poll_container').raw().innerHTML = response});"
  392. value="Vote" />
  393. </form>
  394. </div>
  395. <?php
  396. }
  397. if (check_perms('forums_polls_moderate')) {
  398. #if (check_perms('forums_polls_moderate') && !$RevealVoters) {
  399. if (!$Featured) {
  400. ?>
  401. <form class="manage_form" name="poll" action="forums.php" method="post">
  402. <input type="hidden" name="action" value="poll_mod" />
  403. <input type="hidden" name="auth"
  404. value="<?=$LoggedUser['AuthKey']?>" />
  405. <input type="hidden" name="topicid" value="<?=$ThreadID?>" />
  406. <input type="hidden" name="feature" value="1" />
  407. <input type="submit" onclick="return confirm('Are you sure you want to feature this poll?');" value="Feature" />
  408. </form>
  409. <?php
  410. } ?>
  411. <form class="manage_form" name="poll" action="forums.php" method="post">
  412. <input type="hidden" name="action" value="poll_mod" />
  413. <input type="hidden" name="auth"
  414. value="<?=$LoggedUser['AuthKey']?>" />
  415. <input type="hidden" name="topicid" value="<?=$ThreadID?>" />
  416. <input type="hidden" name="close" value="1" />
  417. <input type="submit"
  418. value="<?=(!$Closed ? 'Close' : 'Open')?>" />
  419. </form>
  420. <?php
  421. } ?>
  422. </div>
  423. </div>
  424. <?php
  425. } //End Polls
  426. //Sqeeze in stickypost
  427. if ($ThreadInfo['StickyPostID']) {
  428. if ($ThreadInfo['StickyPostID'] != $Thread[0]['ID']) {
  429. array_unshift($Thread, $ThreadInfo['StickyPost']);
  430. }
  431. if ($ThreadInfo['StickyPostID'] != $Thread[count($Thread) - 1]['ID']) {
  432. $Thread[] = $ThreadInfo['StickyPost'];
  433. }
  434. }
  435. foreach ($Thread as $Key => $Post) {
  436. list($PostID, $AuthorID, $AddedTime, $Body, $EditedUserID, $EditedTime, $EditedUsername) = array_values($Post);
  437. list($AuthorID, $Username, $PermissionID, $Paranoia, $Artist, $Donor, $Warned, $Avatar, $Enabled, $UserTitle) = array_values(Users::user_info($AuthorID)); ?>
  438. <table class="forum_post wrap_overflow box vertical_margin<?php
  439. if ((
  440. (!$ThreadInfo['IsLocked'] || $ThreadInfo['IsSticky'])
  441. && $PostID > $LastRead
  442. && strtotime($AddedTime) > $LoggedUser['CatchupTime']
  443. ) || (isset($RequestKey) && $Key == $RequestKey)
  444. ) {
  445. echo ' forum_unread';
  446. }
  447. if (!Users::has_avatars_enabled()) {
  448. echo ' noavatar';
  449. }
  450. if ($ThreadInfo['OP'] == $AuthorID) {
  451. echo ' important_user';
  452. }
  453. if ($PostID == $ThreadInfo['StickyPostID']) {
  454. echo ' sticky_post';
  455. }
  456. if (Permissions::is_mod($AuthorID)) {
  457. echo ' staff_post';
  458. } ?>" id="post<?=$PostID?>">
  459. <colgroup>
  460. <?php if (Users::has_avatars_enabled()) { ?>
  461. <col class="col_avatar" />
  462. <?php } ?>
  463. <col class="col_post_body" />
  464. </colgroup>
  465. <tr class="colhead_dark">
  466. <td colspan="<?=Users::has_avatars_enabled() ? 2 : 1?>">
  467. <div class="float_left"><a class="post_id"
  468. href="forums.php?action=viewthread&amp;threadid=<?=$ThreadID?>&amp;postid=<?=$PostID?>#post<?=$PostID?>">#<?=$PostID?></a>
  469. <?=Users::format_username($AuthorID, true, true, true, true, true, $IsDonorForum);
  470. echo "\n"; ?>
  471. <?=time_diff($AddedTime, 2);
  472. echo "\n"; ?>
  473. - <a href="#quickpost" id="quote_<?=$PostID?>"
  474. onclick="Quote('<?=$PostID?>', '<?=$Username?>', true);"
  475. class="brackets">Quote</a>
  476. <?php if ((!$ThreadInfo['IsLocked'] && Forums::check_forumperm($ForumID, 'Write') && $AuthorID == $LoggedUser['ID']) || check_perms('site_moderate_forums')) { ?>
  477. - <a href="#post<?=$PostID?>"
  478. onclick="Edit_Form('<?=$PostID?>', '<?=$Key?>');"
  479. class="brackets">Edit</a>
  480. <?php
  481. }
  482. if (check_perms('site_admin_forums') && $ThreadInfo['Posts'] > 1) { ?>
  483. - <a href="#post<?=$PostID?>"
  484. onclick="Delete('<?=$PostID?>');"
  485. class="brackets">Delete</a>
  486. <?php
  487. }
  488. if ($PostID == $ThreadInfo['StickyPostID']) { ?>
  489. <strong><span class="sticky_post_label brackets">Sticky</span></strong>
  490. <?php if (check_perms('site_moderate_forums')) { ?>
  491. - <a
  492. href="forums.php?action=sticky_post&amp;threadid=<?=$ThreadID?>&amp;postid=<?=$PostID?>&amp;remove=true&amp;auth=<?=$LoggedUser['AuthKey']?>"
  493. title="Unsticky this post" class="brackets tooltip">X</a>
  494. <?php
  495. }
  496. } else {
  497. if (check_perms('site_moderate_forums')) {
  498. ?>
  499. - <a
  500. href="forums.php?action=sticky_post&amp;threadid=<?=$ThreadID?>&amp;postid=<?=$PostID?>&amp;auth=<?=$LoggedUser['AuthKey']?>"
  501. title="Sticky this post" class="brackets tooltip">&#x21d5;</a>
  502. <?php
  503. }
  504. } ?>
  505. </div>
  506. <div id="bar<?=$PostID?>" class="float_right">
  507. <a href="reports.php?action=report&amp;type=post&amp;id=<?=$PostID?>"
  508. class="brackets">Report</a>
  509. <?php
  510. if (check_perms('users_warn') && $AuthorID != $LoggedUser['ID']) {
  511. $AuthorInfo = Users::user_info($AuthorID);
  512. if ($LoggedUser['Class'] >= $AuthorInfo['Class']) {
  513. ?>
  514. <form class="manage_form hidden" name="user"
  515. id="warn<?=$PostID?>" method="post">
  516. <input type="hidden" name="action" value="warn" />
  517. <input type="hidden" name="postid" value="<?=$PostID?>" />
  518. <input type="hidden" name="userid"
  519. value="<?=$AuthorID?>" />
  520. <input type="hidden" name="key" value="<?=$Key?>" />
  521. </form>
  522. - <a href="#"
  523. onclick="$('#warn<?=$PostID?>').raw().submit(); return false;"
  524. class="brackets">Warn</a>
  525. <?php
  526. }
  527. } ?>
  528. </div>
  529. </td>
  530. </tr>
  531. <tr>
  532. <?php if (Users::has_avatars_enabled()) { ?>
  533. <td class="avatar valign_top">
  534. <?=Users::show_avatar($Avatar, $AuthorID, $Username, $HeavyInfo['DisableAvatars'], 150, true)?>
  535. </td>
  536. <?php } ?>
  537. <td class="body valign_top" <?php if (!Users::has_avatars_enabled()) {
  538. echo ' colspan="2"';
  539. } ?>>
  540. <div id="content<?=$PostID?>">
  541. <?=Text::full_format($Body) ?>
  542. <?php if ($EditedUserID) { ?>
  543. <br />
  544. <br />
  545. <div class="last_edited">
  546. <?php if (check_perms('site_admin_forums')) { ?>
  547. <a href="#content<?=$PostID?>"
  548. onclick="LoadEdit('forums', <?=$PostID?>, 1); return false;">&laquo;</a>
  549. <?php } ?>
  550. Last edited by
  551. <?=Users::format_username($EditedUserID, false, false, false, false, false, $IsDonorForum) ?>
  552. <?=time_diff($EditedTime, 2, true, true)?>
  553. </div>
  554. <?php } ?>
  555. </div>
  556. </td>
  557. </tr>
  558. </table>
  559. <?php
  560. } ?>
  561. <div class="breadcrumbs">
  562. <p>
  563. <a href="forums.php">Forums</a> &rsaquo;
  564. <a
  565. href="forums.php?action=viewforum&amp;forumid=<?=$ThreadInfo['ForumID']?>"><?=$ForumName?></a> &rsaquo;
  566. <?=$ThreadTitle?>
  567. </p>
  568. </div>
  569. <div class="linkbox">
  570. <?= $Pages ?>
  571. </div>
  572. <?php
  573. if (!$ThreadInfo['IsLocked'] || check_perms('site_moderate_forums')) {
  574. if (Forums::check_forumperm($ForumID, 'Write') && !$LoggedUser['DisablePosting']) {
  575. View::parse('generic/reply/quickreply.php', array(
  576. 'InputTitle' => 'Reply',
  577. 'InputName' => 'thread',
  578. 'InputID' => $ThreadID,
  579. 'ForumID' => $ForumID,
  580. 'TextareaCols' => 90
  581. ));
  582. }
  583. }
  584. if (check_perms('site_moderate_forums')) {
  585. G::$DB->query("
  586. SELECT ID, AuthorID, AddedTime, Body
  587. FROM forums_topic_notes
  588. WHERE TopicID = $ThreadID
  589. ORDER BY ID ASC");
  590. $Notes = G::$DB->to_array(); ?>
  591. <br />
  592. <h3 id="thread_notes">Notes</h3> <a data-toggle-target="#thread_notes_table" class="brackets">Toggle</a>
  593. <form action="forums.php" method="post">
  594. <input type="hidden" name="action" value="take_topic_notes" />
  595. <input type="hidden" name="auth"
  596. value="<?=$LoggedUser['AuthKey']?>" />
  597. <input type="hidden" name="topicid" value="<?=$ThreadID?>" />
  598. <table class="layout border hidden" id="thread_notes_table">
  599. <?php
  600. foreach ($Notes as $Note) {
  601. ?>
  602. <tr>
  603. <td><?=Users::format_username($Note['AuthorID'])?>
  604. (<?=time_diff($Note['AddedTime'], 2, true, true)?>)
  605. </td>
  606. <td><?=Text::full_format($Note['Body'])?>
  607. </td>
  608. </tr>
  609. <?php
  610. } ?>
  611. <tr>
  612. <td>
  613. <div class="textarea_wrap">
  614. <?php
  615. new TEXTAREA_PREVIEW(
  616. $Name = 'body',
  617. $ID = 'topic_notes',
  618. ); ?>
  619. </div>
  620. <input type="submit" value="Save" />
  621. </td>
  622. </tr>
  623. </table>
  624. </form>
  625. <br />
  626. <h3>Edit</h3>
  627. <form class="edit_form" name="forum_thread" action="forums.php" method="post">
  628. <div>
  629. <input type="hidden" name="action" value="mod_thread" />
  630. <input type="hidden" name="auth"
  631. value="<?=$LoggedUser['AuthKey']?>" />
  632. <input type="hidden" name="threadid" value="<?=$ThreadID?>" />
  633. <input type="hidden" name="page" value="<?=$Page?>" />
  634. </div>
  635. <table class="layout border slight_margin">
  636. <tr>
  637. <td class="label"><label for="sticky_thread_checkbox">Sticky</label></td>
  638. <td>
  639. <input type="checkbox" id="sticky_thread_checkbox" data-toggle-target="#ranking_row" name="sticky" <?php if ($ThreadInfo['IsSticky']) {
  640. echo ' checked="checked"';
  641. } ?>
  642. tabindex="2" />
  643. </td>
  644. </tr>
  645. <tr id="ranking_row" <?=!$ThreadInfo['IsSticky'] ? ' class="hidden"' : ''?>>
  646. <td class="label"><label for="thread_ranking_textbox">Ranking</label></td>
  647. <td>
  648. <input type="text" id="thread_ranking_textbox" name="ranking"
  649. value="<?=$ThreadInfo['Ranking']?>"
  650. tabindex="2" />
  651. </td>
  652. </tr>
  653. <tr>
  654. <td class="label"><label for="locked_thread_checkbox">Locked</label></td>
  655. <td>
  656. <input type="checkbox" id="locked_thread_checkbox" name="locked" <?php if ($ThreadInfo['IsLocked']) {
  657. echo ' checked="checked"';
  658. } ?>
  659. tabindex="2" />
  660. </td>
  661. </tr>
  662. <tr>
  663. <td class="label"><label for="thread_title_textbox">Title</label></td>
  664. <td>
  665. <input type="text" id="thread_title_textbox" name="title" style="width: 75%;"
  666. value="<?=display_str($ThreadInfo['Title'])?>"
  667. tabindex="2" />
  668. </td>
  669. </tr>
  670. <tr>
  671. <td class="label"><label for="move_thread_selector">Move</label></td>
  672. <td>
  673. <select name="forumid" id="move_thread_selector" tabindex="2">
  674. <?php
  675. $OpenGroup = false;
  676. $LastCategoryID = -1;
  677. foreach ($Forums as $Forum) {
  678. if ($Forum['MinClassRead'] > $LoggedUser['Class']) {
  679. continue;
  680. }
  681. if ($Forum['CategoryID'] != $LastCategoryID) {
  682. $LastCategoryID = $Forum['CategoryID'];
  683. if ($OpenGroup) { ?>
  684. </optgroup>
  685. <?php } ?>
  686. <optgroup
  687. label="<?=$ForumCats[$Forum['CategoryID']]?>">
  688. <?php $OpenGroup = true;
  689. } ?>
  690. <option value="<?=$Forum['ID']?>" <i>
  691. </i>
  692. <!-- %pcs-comment-start#<?php if ($ThreadInfo['ForumID'] == $Forum['ID']) {
  693. echo ' selected="selected"';
  694. } ?>><?=display_str($Forum['Name'])?>
  695. </option>
  696. <?php
  697. } ?>
  698. </optgroup>
  699. </select>
  700. </td>
  701. </tr>
  702. <?php if (check_perms('site_admin_forums')) { ?>
  703. <tr>
  704. <td class="label"><label for="delete_thread_checkbox">Delete</label></td>
  705. <td>
  706. <input type="checkbox" id="delete_thread_checkbox" name="delete" tabindex="2" />
  707. </td>
  708. </tr>
  709. <?php } ?>
  710. <tr>
  711. <td colspan="2" class="center">
  712. <input type="submit" value="Edit" tabindex="2" />
  713. <span class="float_right">
  714. <input type="submit" name="trash" value="Trash" tabindex="2" />
  715. </span>
  716. </td>
  717. </tr>
  718. </table>
  719. </form>
  720. <?php
  721. } // If user is moderator
  722. ?>
  723. </div>
  724. <?php View::show_footer();