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.

thread.php 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  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 = array();
  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'] . ' &lt; '.$Forums[$ForumID]['Name'].' &lt; Forums','comments,subscriptions,bbcode', $IsDonorForum ? 'donor' : '');
  150. ?>
  151. <div class="thin">
  152. <h2>
  153. <a href="forums.php">Forums</a> &gt;
  154. <a href="forums.php?action=viewforum&amp;forumid=<?=$ThreadInfo['ForumID']?>"><?=$ForumName?></a> &gt;
  155. <?=$ThreadTitle?>
  156. </h2>
  157. <div class="linkbox">
  158. <div class="center">
  159. <a href="reports.php?action=report&amp;type=thread&amp;id=<?=$ThreadID?>" class="brackets">Report thread</a>
  160. <a href="#" onclick="Subscribe(<?=$ThreadID?>);return false;" id="subscribelink<?=$ThreadID?>" class="brackets"><?=(in_array($ThreadID, $UserSubscriptions) ? 'Unsubscribe' : 'Subscribe')?></a>
  161. <a href="#" onclick="$('#searchthread').gtoggle(); this.innerHTML = (this.innerHTML == 'Search this thread' ? 'Hide search' : 'Search this thread'); return false;" class="brackets">Search this thread</a>
  162. </div>
  163. <div id="searchthread" class="hidden center">
  164. <div style="display: inline-block;">
  165. <h3>Search this thread:</h3>
  166. <form class="search_form" name="forum_thread" action="forums.php" method="get">
  167. <input type="hidden" name="action" value="search" />
  168. <input type="hidden" name="threadid" value="<?=$ThreadID?>" />
  169. <table cellpadding="6" cellspacing="1" border="0" class="layout border">
  170. <tr>
  171. <td><strong>Search for:</strong></td>
  172. <td><input type="search" id="searchbox" name="search" size="70" /></td>
  173. </tr>
  174. <tr>
  175. <td><strong>Posted by:</strong></td>
  176. <td><input type="search" id="username" name="user" placeholder="Username" size="70" /></td>
  177. </tr>
  178. <tr>
  179. <td colspan="2" style="text-align: center;">
  180. <input type="submit" name="submit" value="Search" />
  181. </td>
  182. </tr>
  183. </table>
  184. </form>
  185. <br />
  186. </div>
  187. </div>
  188. <?
  189. $Pages = Format::get_pages($Page, $ThreadInfo['Posts'], $PerPage, 9);
  190. echo $Pages;
  191. ?>
  192. </div>
  193. <?
  194. if ($ThreadInfo['NoPoll'] == 0) {
  195. if (!list($Question, $Answers, $Votes, $Featured, $Closed) = $Cache->get_value("polls_$ThreadID")) {
  196. $DB->query("
  197. SELECT Question, Answers, Featured, Closed
  198. FROM forums_polls
  199. WHERE TopicID = '$ThreadID'");
  200. list($Question, $Answers, $Featured, $Closed) = $DB->next_record(MYSQLI_NUM, array(1));
  201. $Answers = unserialize($Answers);
  202. $DB->query("
  203. SELECT Vote, COUNT(UserID)
  204. FROM forums_polls_votes
  205. WHERE TopicID = '$ThreadID'
  206. GROUP BY Vote");
  207. $VoteArray = $DB->to_array(false, MYSQLI_NUM);
  208. $Votes = array();
  209. foreach ($VoteArray as $VoteSet) {
  210. list($Key,$Value) = $VoteSet;
  211. $Votes[$Key] = $Value;
  212. }
  213. foreach (array_keys($Answers) as $i) {
  214. if (!isset($Votes[$i])) {
  215. $Votes[$i] = 0;
  216. }
  217. }
  218. $Cache->cache_value("polls_$ThreadID", array($Question, $Answers, $Votes, $Featured, $Closed), 0);
  219. }
  220. if (!empty($Votes)) {
  221. $TotalVotes = array_sum($Votes);
  222. $MaxVotes = max($Votes);
  223. } else {
  224. $TotalVotes = 0;
  225. $MaxVotes = 0;
  226. }
  227. $RevealVoters = in_array($ForumID, FORUMS_TO_REVEAL_VOTERS);
  228. //Polls lose the you voted arrow thingy
  229. $DB->query("
  230. SELECT Vote
  231. FROM forums_polls_votes
  232. WHERE UserID = '".$LoggedUser['ID']."'
  233. AND TopicID = '$ThreadID'");
  234. list($UserResponse) = $DB->next_record();
  235. ?>
  236. <div class="box thin clear">
  237. <div class="head colhead_dark"><strong>Poll<? if ($Closed) { echo ' [Closed]'; } ?><? if ($Featured && $Featured !== '0000-00-00 00:00:00') { echo ' [Featured]'; } ?></strong> <a href="#" onclick="$('#threadpoll').gtoggle(); log_hit(); return false;" class="brackets">View</a></div>
  238. <div class="pad<? if (/*$LastRead !== null || */$ThreadInfo['IsLocked']) { echo ' hidden'; } ?>" id="threadpoll">
  239. <p><strong><?=display_str($Question)?></strong></p>
  240. <? if ($UserResponse !== null || $Closed || $ThreadInfo['IsLocked'] || !Forums::check_forumperm($ForumID)) { ?>
  241. <ul class="poll nobullet">
  242. <?
  243. if (!$RevealVoters) {
  244. foreach ($Answers as $i => $Answer) {
  245. if (!empty($Votes[$i]) && $TotalVotes > 0) {
  246. $Ratio = $Votes[$i] / $MaxVotes;
  247. $Percent = $Votes[$i] / $TotalVotes;
  248. } else {
  249. $Ratio = 0;
  250. $Percent = 0;
  251. }
  252. ?>
  253. <li<?=((!empty($UserResponse)&&($UserResponse == $i))?' class="poll_your_answer"':'')?>><?=display_str($Answer)?> (<?=number_format($Percent * 100, 2)?>%)</li>
  254. <li class="graph">
  255. <span class="center_poll" style="width: <?=round($Ratio * 750)?>px;"></span>
  256. </li>
  257. <? }
  258. if ($Votes[0] > 0) {
  259. ?>
  260. <li><?=($UserResponse == '0' ? '&raquo; ' : '')?>(Blank) (<?=number_format((float)($Votes[0] / $TotalVotes * 100), 2)?>%)</li>
  261. <li class="graph">
  262. <span class="left_poll"></span>
  263. <span class="center_poll" style="width: <?=round(($Votes[0] / $MaxVotes) * 750)?>px;"></span>
  264. <span class="right_poll"></span>
  265. </li>
  266. <? } ?>
  267. </ul>
  268. <br />
  269. <strong>Votes:</strong> <?=number_format($TotalVotes)?><br /><br />
  270. <?
  271. } else {
  272. //Staff forum, output voters, not percentages
  273. include(SERVER_ROOT.'/sections/staff/functions.php');
  274. $Staff = get_staff();
  275. $StaffNames = array();
  276. foreach ($Staff as $Staffer) {
  277. $StaffNames[] = $Staffer['Username'];
  278. }
  279. $DB->query("
  280. SELECT
  281. fpv.Vote AS Vote,
  282. GROUP_CONCAT(um.Username SEPARATOR ', ')
  283. FROM users_main AS um
  284. LEFT JOIN forums_polls_votes AS fpv ON um.ID = fpv.UserID
  285. WHERE TopicID = $ThreadID
  286. GROUP BY fpv.Vote");
  287. $StaffVotesTmp = $DB->to_array();
  288. $StaffCount = count($StaffNames);
  289. $StaffVotes = array();
  290. foreach ($StaffVotesTmp as $StaffVote) {
  291. list($Vote, $Names) = $StaffVote;
  292. $StaffVotes[$Vote] = $Names;
  293. $Names = explode(', ', $Names);
  294. $StaffNames = array_diff($StaffNames, $Names);
  295. }
  296. ?> <ul style="list-style: none;" id="poll_options">
  297. <?
  298. foreach ($Answers as $i => $Answer) {
  299. ?>
  300. <li>
  301. <a href="forums.php?action=change_vote&amp;threadid=<?=$ThreadID?>&amp;auth=<?=$LoggedUser['AuthKey']?>&amp;vote=<?=(int)$i?>"><?=display_str($Answer == '' ? 'Blank' : $Answer)?></a>
  302. - <?=$StaffVotes[$i]?>&nbsp;(<?=number_format(((float)$Votes[$i] / $TotalVotes) * 100, 2)?>%)
  303. <a href="forums.php?action=delete_poll_option&amp;threadid=<?=$ThreadID?>&amp;auth=<?=$LoggedUser['AuthKey']?>&amp;vote=<?=(int)$i?>" class="brackets tooltip" title="Delete poll option">X</a>
  304. </li>
  305. <? } ?>
  306. <li>
  307. <a href="forums.php?action=change_vote&amp;threadid=<?=$ThreadID?>&amp;auth=<?=$LoggedUser['AuthKey']?>&amp;vote=0"><?=($UserResponse == '0' ? '&raquo; ' : '')?>Blank</a> - <?=$StaffVotes[0]?>&nbsp;(<?=number_format(((float)$Votes[0] / $TotalVotes) * 100, 2)?>%)
  308. </li>
  309. </ul>
  310. <?
  311. if ($ForumID == STAFF_FORUM) {
  312. ?>
  313. <br />
  314. <strong>Votes:</strong> <?=number_format($StaffCount - count($StaffNames))?> / <?=$StaffCount?> current staff, <?=number_format($TotalVotes)?> total
  315. <br />
  316. <strong>Missing votes:</strong> <?=implode(", ", $StaffNames); echo "\n";?>
  317. <br /><br />
  318. <?
  319. }
  320. ?>
  321. <a href="#" onclick="AddPollOption(<?=$ThreadID?>); return false;" class="brackets">+</a>
  322. <?
  323. }
  324. } else {
  325. //User has not voted
  326. ?>
  327. <div id="poll_container">
  328. <form class="vote_form" name="poll" id="poll" action="">
  329. <input type="hidden" name="action" value="poll" />
  330. <input type="hidden" name="auth" value="<?=$LoggedUser['AuthKey']?>" />
  331. <input type="hidden" name="large" value="1" />
  332. <input type="hidden" name="topicid" value="<?=$ThreadID?>" />
  333. <ul style="list-style: none;" id="poll_options">
  334. <? foreach ($Answers as $i => $Answer) { //for ($i = 1, $il = count($Answers); $i <= $il; $i++) { ?>
  335. <li>
  336. <input type="radio" name="vote" id="answer_<?=$i?>" value="<?=$i?>" />
  337. <label for="answer_<?=$i?>"><?=display_str($Answer)?></label>
  338. </li>
  339. <? } ?>
  340. <li>
  341. <br />
  342. <input type="radio" name="vote" id="answer_0" value="0" /> <label for="answer_0">Blank&#8202;&mdash;&#8202;Show the results!</label><br />
  343. </li>
  344. </ul>
  345. <? if ($ForumID == STAFF_FORUM) { ?>
  346. <a href="#" onclick="AddPollOption(<?=$ThreadID?>); return false;" class="brackets">+</a>
  347. <br />
  348. <br />
  349. <? } ?>
  350. <input type="button" style="float: left;" onclick="ajax.post('index.php','poll',function(response) { $('#poll_container').raw().innerHTML = response});" value="Vote" />
  351. </form>
  352. </div>
  353. <? }
  354. if (check_perms('forums_polls_moderate') && !$RevealVoters) {
  355. if (!$Featured || $Featured == '0000-00-00 00:00:00') {
  356. ?>
  357. <form class="manage_form" name="poll" action="forums.php" method="post">
  358. <input type="hidden" name="action" value="poll_mod" />
  359. <input type="hidden" name="auth" value="<?=$LoggedUser['AuthKey']?>" />
  360. <input type="hidden" name="topicid" value="<?=$ThreadID?>" />
  361. <input type="hidden" name="feature" value="1" />
  362. <input type="submit" style="float: left;" onclick="return confirm('Are you sure you want to feature this poll?');" value="Feature" />
  363. </form>
  364. <? } ?>
  365. <form class="manage_form" name="poll" action="forums.php" method="post">
  366. <input type="hidden" name="action" value="poll_mod" />
  367. <input type="hidden" name="auth" value="<?=$LoggedUser['AuthKey']?>" />
  368. <input type="hidden" name="topicid" value="<?=$ThreadID?>" />
  369. <input type="hidden" name="close" value="1" />
  370. <input type="submit" style="float: left;" value="<?=(!$Closed ? 'Close' : 'Open')?>" />
  371. </form>
  372. <? } ?>
  373. </div>
  374. </div>
  375. <?
  376. } //End Polls
  377. //Sqeeze in stickypost
  378. if ($ThreadInfo['StickyPostID']) {
  379. if ($ThreadInfo['StickyPostID'] != $Thread[0]['ID']) {
  380. array_unshift($Thread, $ThreadInfo['StickyPost']);
  381. }
  382. if ($ThreadInfo['StickyPostID'] != $Thread[count($Thread) - 1]['ID']) {
  383. $Thread[] = $ThreadInfo['StickyPost'];
  384. }
  385. }
  386. foreach ($Thread as $Key => $Post) {
  387. list($PostID, $AuthorID, $AddedTime, $Body, $EditedUserID, $EditedTime, $EditedUsername) = array_values($Post);
  388. list($AuthorID, $Username, $PermissionID, $Paranoia, $Artist, $Donor, $Warned, $Avatar, $Enabled, $UserTitle) = array_values(Users::user_info($AuthorID));
  389. ?>
  390. <table class="forum_post wrap_overflow box vertical_margin<?
  391. if (((!$ThreadInfo['IsLocked'] || $ThreadInfo['IsSticky'])
  392. && $PostID > $LastRead
  393. && strtotime($AddedTime) > $LoggedUser['CatchupTime']
  394. ) || (isset($RequestKey) && $Key == $RequestKey)
  395. ) {
  396. echo ' forum_unread';
  397. }
  398. if (!Users::has_avatars_enabled()) {
  399. echo ' noavatar';
  400. }
  401. if ($ThreadInfo['OP'] == $AuthorID) {
  402. echo ' important_user';
  403. }
  404. if ($PostID == $ThreadInfo['StickyPostID']) {
  405. echo ' sticky_post';
  406. } ?>" id="post<?=$PostID?>">
  407. <colgroup>
  408. <? if (Users::has_avatars_enabled()) { ?>
  409. <col class="col_avatar" />
  410. <? } ?>
  411. <col class="col_post_body" />
  412. </colgroup>
  413. <tr class="colhead_dark<?=(Permissions::is_mod($AuthorID)) ? " staff_post" : ""?>">
  414. <td colspan="<?=Users::has_avatars_enabled() ? 2 : 1?>">
  415. <div style="float: left;"><a class="post_id" href="forums.php?action=viewthread&amp;threadid=<?=$ThreadID?>&amp;postid=<?=$PostID?>#post<?=$PostID?>">#<?=$PostID?></a>
  416. <?=Users::format_username($AuthorID, true, true, true, true, true, $IsDonorForum); echo "\n";?>
  417. <?=time_diff($AddedTime, 2); echo "\n";?>
  418. - <a href="#quickpost" id="quote_<?=$PostID?>" onclick="Quote('<?=$PostID?>', '<?=$Username?>', true);" class="brackets">Quote</a>
  419. <? if ((!$ThreadInfo['IsLocked'] && Forums::check_forumperm($ForumID, 'Write') && $AuthorID == $LoggedUser['ID']) || check_perms('site_moderate_forums')) { ?>
  420. - <a href="#post<?=$PostID?>" onclick="Edit_Form('<?=$PostID?>', '<?=$Key?>');" class="brackets">Edit</a>
  421. <?
  422. }
  423. if (check_perms('site_admin_forums') && $ThreadInfo['Posts'] > 1) { ?>
  424. - <a href="#post<?=$PostID?>" onclick="Delete('<?=$PostID?>');" class="brackets">Delete</a>
  425. <?
  426. }
  427. if ($PostID == $ThreadInfo['StickyPostID']) { ?>
  428. <strong><span class="sticky_post_label" class="brackets">Sticky</span></strong>
  429. <? if (check_perms('site_moderate_forums')) { ?>
  430. - <a href="forums.php?action=sticky_post&amp;threadid=<?=$ThreadID?>&amp;postid=<?=$PostID?>&amp;remove=true&amp;auth=<?=$LoggedUser['AuthKey']?>" title="Unsticky this post" class="brackets tooltip">X</a>
  431. <?
  432. }
  433. } else {
  434. if (check_perms('site_moderate_forums')) {
  435. ?>
  436. - <a href="forums.php?action=sticky_post&amp;threadid=<?=$ThreadID?>&amp;postid=<?=$PostID?>&amp;auth=<?=$LoggedUser['AuthKey']?>" title="Sticky this post" class="brackets tooltip">&#x21d5;</a>
  437. <?
  438. }
  439. }
  440. ?>
  441. </div>
  442. <div id="bar<?=$PostID?>" style="float: right;">
  443. <a href="reports.php?action=report&amp;type=post&amp;id=<?=$PostID?>" class="brackets">Report</a>
  444. <?
  445. if (check_perms('users_warn') && $AuthorID != $LoggedUser['ID']) {
  446. $AuthorInfo = Users::user_info($AuthorID);
  447. if ($LoggedUser['Class'] >= $AuthorInfo['Class']) {
  448. ?>
  449. <form class="manage_form hidden" name="user" id="warn<?=$PostID?>" action="" method="post">
  450. <input type="hidden" name="action" value="warn" />
  451. <input type="hidden" name="postid" value="<?=$PostID?>" />
  452. <input type="hidden" name="userid" value="<?=$AuthorID?>" />
  453. <input type="hidden" name="key" value="<?=$Key?>" />
  454. </form>
  455. - <a href="#" onclick="$('#warn<?=$PostID?>').raw().submit(); return false;" class="brackets">Warn</a>
  456. <? }
  457. }
  458. ?>
  459. &nbsp;
  460. <a href="#">&uarr;</a>
  461. </div>
  462. </td>
  463. </tr>
  464. <tr>
  465. <? if (Users::has_avatars_enabled()) { ?>
  466. <td class="avatar" valign="top">
  467. <?=Users::show_avatar($Avatar, $AuthorID, $Username, $HeavyInfo['DisableAvatars'], 150, true)?>
  468. </td>
  469. <? } ?>
  470. <td class="body" valign="top"<? if (!Users::has_avatars_enabled()) { echo ' colspan="2"'; } ?>>
  471. <div id="content<?=$PostID?>">
  472. <?=Text::full_format($Body) ?>
  473. <? if ($EditedUserID) { ?>
  474. <br />
  475. <br />
  476. <div class="last_edited">
  477. <? if (check_perms('site_admin_forums')) { ?>
  478. <a href="#content<?=$PostID?>" onclick="LoadEdit('forums', <?=$PostID?>, 1); return false;">&laquo;</a>
  479. <? } ?>
  480. Last edited by
  481. <?=Users::format_username($EditedUserID, false, false, false, false, false, $IsDonorForum) ?> <?=time_diff($EditedTime, 2, true, true)?>
  482. <? } ?>
  483. </div>
  484. </div>
  485. </td>
  486. </tr>
  487. </table>
  488. <? } ?>
  489. <div class="breadcrumbs">
  490. <a href="forums.php">Forums</a> &gt;
  491. <a href="forums.php?action=viewforum&amp;forumid=<?=$ThreadInfo['ForumID']?>"><?=$ForumName?></a> &gt;
  492. <?=$ThreadTitle?>
  493. </div>
  494. <div class="linkbox">
  495. <?=$Pages?>
  496. </div>
  497. <?
  498. if (!$ThreadInfo['IsLocked'] || check_perms('site_moderate_forums')) {
  499. if (Forums::check_forumperm($ForumID, 'Write') && !$LoggedUser['DisablePosting']) {
  500. View::parse('generic/reply/quickreply.php', array(
  501. 'InputTitle' => 'Post reply',
  502. 'InputName' => 'thread',
  503. 'InputID' => $ThreadID,
  504. 'ForumID' => $ForumID,
  505. 'TextareaCols' => 90
  506. ));
  507. }
  508. }
  509. if (check_perms('site_moderate_forums')) {
  510. G::$DB->query("
  511. SELECT ID, AuthorID, AddedTime, Body
  512. FROM forums_topic_notes
  513. WHERE TopicID = $ThreadID
  514. ORDER BY ID ASC");
  515. $Notes = G::$DB->to_array();
  516. ?>
  517. <br />
  518. <h3 id="thread_notes">Thread notes</h3> <a href="#" onclick="$('#thread_notes_table').gtoggle(); return false;" class="brackets">Toggle</a>
  519. <form action="forums.php" method="post">
  520. <input type="hidden" name="action" value="take_topic_notes" />
  521. <input type="hidden" name="auth" value="<?=$LoggedUser['AuthKey']?>" />
  522. <input type="hidden" name="topicid" value="<?=$ThreadID?>" />
  523. <table cellpadding="6" cellspacing="1" border="0" width="100%" class="layout border hidden" id="thread_notes_table">
  524. <?
  525. foreach ($Notes as $Note) {
  526. ?>
  527. <tr><td><?=Users::format_username($Note['AuthorID'])?> (<?=time_diff($Note['AddedTime'], 2, true, true)?>)</td><td><?=Text::full_format($Note['Body'])?></td></tr>
  528. <?
  529. }
  530. ?>
  531. <tr>
  532. <td colspan="2" class="center">
  533. <div class="field_div textarea_wrap"><textarea id="topic_notes" name="body" cols="90" rows="3" onkeyup="resize('threadnotes');" style=" margin: 0px; width: 735px;"></textarea></div>
  534. <input type="submit" value="Save" />
  535. </td>
  536. </tr>
  537. </table>
  538. </form>
  539. <br />
  540. <h3>Edit thread</h3>
  541. <form class="edit_form" name="forum_thread" action="forums.php" method="post">
  542. <div>
  543. <input type="hidden" name="action" value="mod_thread" />
  544. <input type="hidden" name="auth" value="<?=$LoggedUser['AuthKey']?>" />
  545. <input type="hidden" name="threadid" value="<?=$ThreadID?>" />
  546. <input type="hidden" name="page" value="<?=$Page?>" />
  547. </div>
  548. <table cellpadding="6" cellspacing="1" border="0" width="100%" class="layout border slight_margin">
  549. <tr>
  550. <td class="label"><label for="sticky_thread_checkbox">Sticky</label></td>
  551. <td>
  552. <input type="checkbox" id="sticky_thread_checkbox" onclick="$('#ranking_row').gtoggle();" name="sticky"<? if ($ThreadInfo['IsSticky']) { echo ' checked="checked"'; } ?> tabindex="2" />
  553. </td>
  554. </tr>
  555. <tr id="ranking_row"<?=!$ThreadInfo['IsSticky'] ? ' class="hidden"' : ''?>>
  556. <td class="label"><label for="thread_ranking_textbox">Ranking</label></td>
  557. <td>
  558. <input type="text" id="thread_ranking_textbox" name="ranking" value="<?=$ThreadInfo['Ranking']?>" tabindex="2" />
  559. </td>
  560. </tr>
  561. <tr>
  562. <td class="label"><label for="locked_thread_checkbox">Locked</label></td>
  563. <td>
  564. <input type="checkbox" id="locked_thread_checkbox" name="locked"<? if ($ThreadInfo['IsLocked']) { echo ' checked="checked"'; } ?> tabindex="2" />
  565. </td>
  566. </tr>
  567. <tr>
  568. <td class="label"><label for="thread_title_textbox">Title</label></td>
  569. <td>
  570. <input type="text" id="thread_title_textbox" name="title" style="width: 75%;" value="<?=display_str($ThreadInfo['Title'])?>" tabindex="2" />
  571. </td>
  572. </tr>
  573. <tr>
  574. <td class="label"><label for="move_thread_selector">Move thread</label></td>
  575. <td>
  576. <select name="forumid" id="move_thread_selector" tabindex="2">
  577. <?
  578. $OpenGroup = false;
  579. $LastCategoryID = -1;
  580. foreach ($Forums as $Forum) {
  581. if ($Forum['MinClassRead'] > $LoggedUser['Class']) {
  582. continue;
  583. }
  584. if ($Forum['CategoryID'] != $LastCategoryID) {
  585. $LastCategoryID = $Forum['CategoryID'];
  586. if ($OpenGroup) { ?>
  587. </optgroup>
  588. <? } ?>
  589. <optgroup label="<?=$ForumCats[$Forum['CategoryID']]?>">
  590. <? $OpenGroup = true;
  591. }
  592. ?>
  593. <option value="<?=$Forum['ID']?>"<? if ($ThreadInfo['ForumID'] == $Forum['ID']) { echo ' selected="selected"';} ?>><?=display_str($Forum['Name'])?></option>
  594. <? } ?>
  595. </optgroup>
  596. </select>
  597. </td>
  598. </tr>
  599. <? if (check_perms('site_admin_forums')) { ?>
  600. <tr>
  601. <td class="label"><label for="delete_thread_checkbox">Delete thread</label></td>
  602. <td>
  603. <input type="checkbox" id="delete_thread_checkbox" name="delete" tabindex="2" />
  604. </td>
  605. </tr>
  606. <? } ?>
  607. <tr>
  608. <td colspan="2" class="center">
  609. <input type="submit" value="Edit thread" tabindex="2" />
  610. <span style="float: right;">
  611. <input type="submit" name="trash" value="Trash" tabindex="2" />
  612. </span>
  613. </td>
  614. </tr>
  615. </table>
  616. </form>
  617. <?
  618. } // If user is moderator
  619. ?>
  620. </div>
  621. <? View::show_footer();