#!perl #------------------------------------------------------------------------------ # mwForum - Web-based discussion forum # Copyright (c) 1999-2005 Markus Wichitill # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. #------------------------------------------------------------------------------ use strict; use warnings; no warnings qw(uninitialized redefine); # Imports use MwfMain; #------------------------------------------------------------------------------ # Init my ($m, $cfg, $lng, $user) = MwfMain->new(@_); my $userId = $user->{id}; # Check if access should be denied $m->checkBan($userId) if $cfg->{banViewing}; $m->checkBlock(); # Get CGI parameters my $boardId = $m->paramStr('bid'); # int() later my $jumpTopicId = $m->paramInt('tid'); my $page = $m->paramInt('pg') || 1; # Redirect to main page if board ID is special $m->redirect('forum_show', tgt => $boardId) if $boardId =~ /^cid/; $m->redirect('forum_show') if $boardId eq '0'; $boardId = int($boardId || 0); $m->redirect('blog_show', bid => $boardId, tgt => "tid$jumpTopicId") if $boardId <0 && $jumpTopicId; $m->redirect('blog_show', bid => $boardId) if $boardId < 0; # Get missing boardId from topic $boardId = $m->fetchArray(" SELECT boardId FROM $cfg->{dbPrefix}topics WHERE id = $jumpTopicId") if !$boardId && $jumpTopicId; $boardId or $m->paramError($lng->{errBrdIdMiss}); # Get board/category my $board = $m->fetchHash(" SELECT boards.*, categories.id AS categId, categories.title AS categTitle FROM $cfg->{dbPrefix}boards AS boards INNER JOIN $cfg->{dbPrefix}categories AS categories ON categories.id = boards.categoryId WHERE boards.id = $boardId"); $board or $m->entryError($lng->{errBrdNotFnd}); # Check if user can see and write to board my $boardAdmin = $user->{admin} || $m->boardAdmin($userId, $board->{id}); $boardAdmin || $m->boardVisible($board) or $m->entryError($lng->{errBrdNotFnd}); my $boardWritable = $boardAdmin || $m->boardWritable($board); # Print header $m->printHeader($board->{title}); # Set current page to a requested topics's page my $topicsPP = $m->min($user->{topicsPP}, $cfg->{maxTopicsPP}) || $cfg->{maxTopicsPP}; if ($jumpTopicId) { my $jumpTopicTime = $m->fetchArray(" SELECT lastPostTime FROM $cfg->{dbPrefix}topics WHERE id = $jumpTopicId"); $page = $m->fetchArray(" SELECT COUNT(*) / $topicsPP + 1 FROM $cfg->{dbPrefix}topics WHERE boardId = $boardId AND (sticky OR lastPostTime > $jumpTopicTime)") if $jumpTopicTime; $page = int($page); } # Determine page buttons my @pageButtons = (); my $topicNum = $m->fetchArray(" SELECT COUNT(*) FROM $cfg->{dbPrefix}topics WHERE boardId = $boardId"); my $pageNum = int($topicNum / $topicsPP) + ($topicNum % $topicsPP != 0); if ($pageNum > 1) { my $prevPage = $page - 1; my $nextPage = $page + 1; my $maxPageNum = $m->min($pageNum, 8); for my $i (1 .. $maxPageNum) { push @pageButtons, $m->url('board_show', bid => $boardId, pg => $i), $i, $i == $page ? 0 : 1; } push @pageButtons, undef, "...", 0, $m->url('board_show', bid => $boardId, pg => $pageNum), $pageNum, $pageNum == $page ? 0 : 1 if $maxPageNum + 1 < $pageNum; push @pageButtons, $m->url('board_show', bid => $boardId, pg => $prevPage), 'comPgPrev', $page == 1 ? 0 : 1, $m->url('board_show', bid => $boardId, pg => $nextPage), 'comPgNext', $page == $pageNum ? 0 : 1; } # Print page bar my @bar = (); push @bar, $m->url('topic_add', bid => $boardId), 'brdNewTpc', 1 if $boardWritable; push @bar, $m->url('forum_overview', act => 'new', bid => $boardId), 'comShowNew', 1 if $userId; push @bar, $m->url('forum_overview', act => 'unread', bid => $boardId), 'comShowUnr', 1 if $userId; push @bar, $m->url('forum_overview', act => 'replies', bid => $boardId), 'comShowRpl', 1 if $userId; push @bar, $m->url('forum_overview', act => 'todo', bid => $boardId), 'comShowTdo', 1 if $userId; push @bar, $m->url('board_feeds', bid => $boardId), 'comFeeds', 1 if $cfg->{rssLink} && !$board->{private}; push @bar, $m->url('board_info', bid => $boardId), 'brdInfo', 1; push @bar, $m->url('prevnext', bid => $boardId, dir => 'prev'), 'brdPrev', 1; push @bar, $m->url('prevnext', bid => $boardId, dir => 'next'), 'brdNext', 1; push @bar, $m->url('forum_show', bid => $boardId, tgt => "bid$boardId"), 'comUp', 1; if ($boardAdmin) { my $reportNum = $m->fetchArray(" SELECT COUNT(*) FROM $cfg->{dbPrefix}postReports AS postReports INNER JOIN $cfg->{dbPrefix}posts AS posts ON posts.id = postReports.postId INNER JOIN $cfg->{dbPrefix}boards AS boards ON boards.id = posts.boardId WHERE boards.id = $boardId"); push @bar, undef, undef, 0; if ($user->{admin}) { push @bar, $m->url('board_options', bid => $boardId, ori => 1), 'Options', 1; push @bar, $m->url('board_member', bid => $boardId), 'Members', 1; push @bar, $m->url('board_groups', bid => $boardId, ori => 1), 'Groups', 1; push @bar, $m->url('user_confirm', bid => $boardId, script => 'board_delete', name => $board->{title}), 'Delete', 1; push @bar, $m->url('report_list', bid => $boardId), "Reports ($reportNum)", 1 if $reportNum; } else { push @bar, $m->url('board_member', bid => $boardId, ori => 1), 'brdAdmMbr', 1; push @bar, $m->url('report_list', bid => $boardId), "$lng->{brdAdmRep} ($reportNum)", 1 if $reportNum; } } my $url = $m->url('forum_show', bid => $boardId, tgt => "bid$boardId"); my $categStr = "$board->{categTitle} / "; $url = $m->url('board_show', bid => $boardId, pg => $page); my $boardStr = "$board->{title}"; my $pageStr = $page > 1 ? " ($lng->{comPgTtl} $page)" : ""; my $title = $categStr . $boardStr . $pageStr; $m->printBar($lng->{brdTitle}, $title, \@bar, 0, $page, \@pageButtons); # Get topics including base post user and approval my $offset = ($page - 1) * $topicsPP; my $topics = $m->fetchAllHash(" SELECT topics.*, posts.userId, posts.approved, posts.userNameBak, users.userName FROM $cfg->{dbPrefix}topics AS topics INNER JOIN $cfg->{dbPrefix}posts AS posts ON posts.id = topics.basePostId LEFT JOIN $cfg->{dbPrefix}users AS users ON users.id = posts.userId WHERE topics.boardId = $boardId ORDER BY sticky DESC, lastPostTime DESC LIMIT $offset, $topicsPP"); # Put topics in by-id lookup table and concat their IDs for the next query my %topics = (); my $topicIds = "0"; for my $topic (@$topics) { $topics{$topic->{id}} = $topic; $topicIds .= "," . $topic->{id}; } # Get new post and unread numbers my $lowestUnreadTime = $m->max($user->{fakeReadTime}, $m->{now} - $cfg->{maxUnreadDays} * 86400); if ($userId) { my $topicStats = $m->fetchAllHash(" SELECT topics.id, SUM(posts.postTime > $user->{prevOnTime}) AS newNum, SUM(topics.lastPostTime > $lowestUnreadTime AND (topics.lastPostTime > topicReadTimes.lastReadTime OR topicReadTimes.topicId IS NULL)) AS unreadNum FROM $cfg->{dbPrefix}topics AS topics INNER JOIN $cfg->{dbPrefix}posts AS posts ON posts.topicId = topics.id LEFT JOIN $cfg->{dbPrefix}topicReadTimes AS topicReadTimes ON topicReadTimes.userId = $userId AND topicReadTimes.topicId = topics.id WHERE topics.id IN ($topicIds) AND posts.approved = 1 GROUP BY topics.id"); for my $topic (@$topicStats) { $topics{$topic->{id}}{newNum} = $topic->{newNum}; $topics{$topic->{id}}{unreadNum} = $topic->{unreadNum}; } } # Print long description print "
| $lng->{brdTopic} | \n", "$lng->{brdPoster} | \n", "$lng->{brdPosts} | \n", "$lng->{brdLastPost} | \n", "
|---|---|---|---|
| \n",
"\n",
" | \n",
"$userNameStr | \n", "$topic->{postNum} $newNumStr | \n", "$lastPostTimeStr | \n", "