sub getThreads {
# main code section for comment display
# here's where all the deep magic happens.
# The algorithm is simple, but has a speed issue.
# 1. select all comments from the db
# 2. store the comment contents in %text, keyed by ID
# 3. Put the id of the parent posting of a given posting in %parent, keyed by ID
# By nature of the way comments are entered,
# we know that a given reply to a comment will always
# have a larger ID than its parent,
# 4. read %parent in reverse order
# take the current posting and append it to the parent
# since we're in reverse order, parent will always exist. and the
# text will appear after the parent, with the newest replies first on the page
# if parent is this post, leave alone -> is a top level post
# reply comments are thus added to the top level post
# 5. read %text in reverse order as well
# append the text to the output data
# this will give a reverse order thread, but with the rather
# cool side effect of putting the latest thread at the top.
# so the latest discussion comes first on the page.
# so less scrolling for most posters.
#
my ($table,$id,$mode,$dirc,$type,$path,$modmode) = @_;
if($id !~ /^\d{1,10}$/) {
return &readfile("$doc_root/templates/badvar.html");
}
my ($output,$comment,$thread, $indent, $full, $sort, $cursor);
if($mode eq 'flat') {
$indent = 0;
$full = 1;
} elsif($mode eq 'thread') {
$indent = 1;
$full = 0;
} elsif($mode eq 'nested') {
$indent = 1;
$full = 1;
} elsif($mode eq 'in-order') {
$indent = 0;
$full = 0;
$sort = "ID $dirc";
} elsif($mode eq 'indexed' || $mode eq '') {
$indent = 1;
$full = 1;
}
# select all from the table
my ($c) = &sqlSelectMany("$table.ID,$table.USERNAME,$table.SUBJECT,$table.MESSAGE,$table.TIMESTAMP,$table.STATUS,$table.PARENT,$table.SUB_PARENT,$table.LEVEL,USERS.EMAIL as EMAIL",
"$table,USERS",
"ITEM='$id' && STATUS != 'dead' && USERS.USERNAME=$table.USERNAME",
"order by ID");
my %parent;
my %text;
if($c->rows >= 1) {
while($cursor=$c->fetchrow_hashref) {
my $tid = $cursor->{'ID'};
my $username = $cursor->{'USERNAME'};
my $subject = $cursor->{'SUBJECT'};
my $message = $cursor->{'MESSAGE'};
$message =~ s/\n/
/g;
my $timestamp = &post_date($cursor->{'TIMESTAMP'});
my $status = $cursor->{'STATUS'};
my $parent = $cursor->{'PARENT'};
my $sub_parent = $cursor->{'SUB_PARENT'};
my $level = $cursor->{'LEVEL'};
my $email = $cursor->{'EMAIL'};
$parent{$tid}=$sub_parent;
if($status eq "active" || ($modmode eq 'yes' && $status ne 'kthread')) {
if($modmode eq 'yes' && $status ne 'active') {
$subject .= " <MODERATED>";
}
if(length($email) <= 4) { $email=""; }
# parent is hash containing the parent of this posting
}
elsif ($status eq 'dthread') {
$subject = "<Deleted>";
$message = "This message has been moderated down, score -1 :)";
$username = "<Deleted>";
$email = "";
}
elsif($status eq 'inactive' || $status eq 'kthread') {
my ($leafchk) = &sqlSelectMany("PARENT,ID", $table,
"PARENT = $tid");
my $leafrows = $leafchk->rows;
my $lfr = $leafchk->fetchrow_hashref;
$leafchk->finish;
if($leafrows > 1 ||
($leafrows == 1 &&
$lfr->{'PARENT'} == $lfr->{'ID'})) {
$subject = "<Deleted>";
$message = "This message has been moderated down, score -1";
$username = "<Deleted>";
$email = "";
}
else {
next;
}
}
else {
$subject = "<Error>";
$message = "This is an Error and is being looked into.";
$username = "lt;Error>";
$email = "";
}
$text{$tid}=&posting($indent,$full,$level,$mode,
$id,$tid,$level,$subject,$message,'Yes',
$email,$username,$timestamp,$type,$path);
# $message is the comment text of this posting
}
foreach $node (sort reverse_number (keys (%text)) ) {
# for every posting numbered $node
# start at the last posting
# and go backwards
if ( $node == $parent{$node}) {
# this is parented by itself.
# leave it alone, because its a top level posting
}
else {
$text{$parent{$node}}.=$text{$node};
$text{$node}="";
# attach this text to its parent's text
# delete it from the text hash
# so that we can just run thru the hash to display
# the entire posting contents
}
}
foreach $node ( sort reverse_number (keys %text )) {
$output.=$text{$node};
# finally , add all the output reverse sequentially
}
} else {
$output = qq|