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|

No threads are currently available.

|; } $c->finish; $output .= qq|
|; return($output); }