Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: Graphical Hierarchical Tree

by Yohimbe (Pilgrim)
on Mar 05, 2001 at 07:51 UTC ( [id://62179]=note: print w/replies, xml ) Need Help??


in reply to Graphical Hierarchical Tree

And in the spirit of TIMTOWTDI: This is from UF's soon to be overhauled forum system.

That being said, this code is linear to the number of posts, and does not suffer from problems from extra deeply nested structures.

It also handles moderation and some other things. Please understand, it has some serious issues, and it is being re-vamped.

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 %p +arent, 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 rep +lies 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 ra +ther # cool side effect of putting the latest thread at the t +op. # 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.SUB +JECT,$table.MESSAGE,$table.TIMESTAMP,$table.STATUS,$table.PARENT,$tab +le.SUB_PARENT,$table.LEVEL,USERS.EMAIL as EMAIL", "$table,USERS", "ITEM='$id' && STATUS != 'dead' && USERS.USERNAME=$tab +le.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/<br>/g; my $timestamp = &post_date($cursor->{'TIMEST +AMP'}); 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 'ac +tive') { $subject .= " &lt;MODERATED& +gt;"; } if(length($email) <= 4) { $email=""; } # parent is hash containing the parent + of this posting } elsif ($status eq 'dthread') { $subject = "&lt;Deleted&gt;"; $message = "This message has been mode +rated down, score -1 :)"; $username = "&lt;Deleted&gt;"; $email = ""; } elsif($status eq 'inactive' || $status eq 'kth +read') { 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->{'I +D'})) { $subject = "&lt;Deleted&gt;"; $message = "This message has b +een moderated down, score -1"; $username = "&lt;Deleted&gt;"; $email = ""; } else { next; } } else { $subject = "&lt;Error&gt;"; $message = "This is an Error and is be +ing looked into."; $username = "lt;Error&gt;"; $email = ""; } $text{$tid}=&posting($indent,$full,$level,$mod +e, $id,$tid,$level,$subject,$message,'Yes +', $email,$username,$timestamp,$type,$pat +h); # $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 le +vel posting } else { $text{$parent{$node}}.=$text{$node}; $text{$node}=""; # attach this text to its parent's tex +t # delete it from the text hash # so that we can just run thru the has +h to display # the entire posting contents } } foreach $node ( sort reverse_number (keys %text )) { $output.=$text{$node}; # finally , add all the output reverse sequent +ially } } else { $output = qq| <tr bgcolor="#FFFFFF"> <td align=\"cente +r\"> <font face="Verdana, Arial, Helvetica, sans-se +rif"> <br><br> <b>No threads are currently available +.</b><br><br>|; } $c->finish; $output .= qq|</font></td></tr>|; return($output); }

--
Jay "Yohimbe" Thorne, alpha geek for UserFriendly

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://62179]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (1)
As of 2024-04-24 14:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found