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

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