[LON-CAPA-cvs] cvs: loncom /interface lonfeedback.pm

raeburn lon-capa-cvs@mail.lon-capa.org
Wed, 21 Jul 2004 21:47:14 -0000


This is a MIME encoded message

--raeburn1090446434
Content-Type: text/plain

raeburn		Wed Jul 21 17:47:14 2004 EDT

  Modified files:              
    /loncom/interface	lonfeedback.pm 
  Log:
  Can choose different sorting mechanism for discussion posts. Interface provided for filtering of posts for display (by poster's role, status -active/inactive, section). Choices currently have no effect (work-in-progress).
  
  
--raeburn1090446434
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20040721174714.txt"

Index: loncom/interface/lonfeedback.pm
diff -u loncom/interface/lonfeedback.pm:1.99 loncom/interface/lonfeedback.pm:1.100
--- loncom/interface/lonfeedback.pm:1.99	Fri Jul  9 19:05:52 2004
+++ loncom/interface/lonfeedback.pm	Wed Jul 21 17:47:13 2004
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Feedback
 #
-# $Id: lonfeedback.pm,v 1.99 2004/07/09 23:05:52 raeburn Exp $
+# $Id: lonfeedback.pm,v 1.100 2004/07/21 21:47:13 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -80,7 +80,9 @@
 	$symb=&Apache::lonnet::symbread();
     }
     unless ($symb) { return ''; }
-
+    my %usernamesort = ();
+    my %namesort =();
+    my %subjectsort = ();
 # backward compatibility (bulletin boards used to be 'wrapped')
     my $ressymb=$symb;
     if ($mode eq 'board') {
@@ -104,7 +106,8 @@
     my $newpostsflag = 0;
 
 # Retain identification of "NEW" posts identified in last display, if continuing 'previous' browsing of posts.
-    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous']);
+    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous','sortposts']);
+    my $sortposts = $ENV{'form.sortposts'};
     $previous = $ENV{'form.previous'};
     if ($previous > 0) {
         $prevread = $previous;
@@ -184,12 +187,17 @@
 	    my $hidden=($contrib{'hidden'}=~/\.$idx\./);
 	    my $deleted=($contrib{'deleted'}=~/\.$idx\./);
 	    my $origindex='0.';
-	    if (($contrib{$idx.':replyto'}) && ($ENV{'environment.threadeddiscussion'})) {
+	    if ($contrib{$idx.':replyto'}) {
+                if ( (($ENV{'environment.threadeddiscussion'}) && (($sortposts eq '') || ($sortposts eq 'ascdate'))) || ($sortposts eq 'thread')) {
 # this is a follow-up message
-		$original[$idx]=$original[$contrib{$idx.':replyto'}];
-		$depth[$idx]=$depth[$contrib{$idx.':replyto'}]+1;
-		$origindex=$index[$contrib{$idx.':replyto'}];
-		if ($depth[$idx]>$maxdepth) { $maxdepth=$depth[$idx]; }
+		    $original[$idx]=$original[$contrib{$idx.':replyto'}];
+		    $depth[$idx]=$depth[$contrib{$idx.':replyto'}]+1;
+		    $origindex=$index[$contrib{$idx.':replyto'}];
+		    if ($depth[$idx]>$maxdepth) { $maxdepth=$depth[$idx]; }
+                } else {
+                    $original[$idx]=0;
+                    $depth[$idx]=0;
+                }
 	    } else {
 # this is an original message
 		$original[$idx]=0;
@@ -231,6 +239,20 @@
 					    $contrib{$idx.':senderdomain'});
 		    
 		    my $sender=&mt('Anonymous');
+# Set up for sorting by subject
+                    if ($contrib{$idx.':subject'} eq '') {
+                        if (defined($subjectsort{'__No subject'})) {
+                            push @{$subjectsort{'__No subject'}}, $idx;
+                        } else {
+                            @{$subjectsort{'__No subject'}} = ("$idx");
+                        }
+                    } else {
+                        if (defined($subjectsort{$contrib{$idx.':subject'}})) {
+                            push @{$subjectsort{$contrib{$idx.':subject'}}}, $idx;
+                        } else {
+                            @{$subjectsort{$contrib{$idx.':subject'}}} = ("$idx");
+                        }
+                    }
 		    if ((!$contrib{$idx.':anonymous'}) || ($seeid)) {
 			$sender=&Apache::loncommon::aboutmewrapper(
 					 $plainname,
@@ -242,6 +264,34 @@
 			    $sender.=' ['.&mt('anonymous').'] '.
 				$screenname;
 			}
+# Set up for sorting by domain, then username
+                        unless (defined($usernamesort{$contrib{$idx.':senderdomain'}})) {
+                            %{$usernamesort{$contrib{$idx.':senderdomain'}}} = ();
+                        }
+                        if (defined($usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}})) {
+                            push @{$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}}}, $idx;
+                        } else {
+                            @{$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}}} = ("$idx");
+                        }
+# Set up for sorting by last name, then first name
+                        my %names = &Apache::lonnet::get('environment',['firstname','lastname'],
+                                  $contrib{$idx.':senderdomain'},$contrib{$idx.':sendername'});
+                        my $lastname = $names{'lastname'};
+                        my $firstname = $names{'firstname'};
+                        if ($lastname eq '') {
+                            $lastname = '_';
+                        }
+                        if ($firstname eq '') {
+                            $firstname = '_';
+                        }
+                        unless (defined($namesort{$lastname})) {
+                            %{$namesort{$lastname}} = ();
+                        }
+                        if (defined($namesort{$lastname}{$firstname})) {
+                            push @{$namesort{$lastname}{$firstname}}, $idx;
+                        } else {
+                            @{$namesort{$lastname}{$firstname}} = ("$idx");
+                        }
 			if ($seeid) {
 			    if ($hidden) {
 				$sender.=' <a href="/adm/feedback?unhide='.
@@ -260,15 +310,33 @@
 			    }                     
 			    $sender.=' <a href="/adm/feedback?deldisc='.
 				$ressymb.':::'.$idx;
-                                if ($newpostsflag) {
-                                    $sender .= '&previous='.$prevread;
-                                }
-                                $sender .= '">'.&mt('Delete').'</a>';
+                            if ($newpostsflag) {
+                                $sender .= '&previous='.$prevread;
+                            }
+                            $sender .= '">'.&mt('Delete').'</a>';
 			}
 		    } else {
 			if ($screenname) {
 			    $sender='<i>'.$screenname.'</i>';
 			}
+# Set up for sorting by domain, then username for anonymous
+                        unless (defined($usernamesort{'__anon'})) {
+                            %{$usernamesort{'__anon'}} = ();
+                        }
+                        if (defined($usernamesort{'__anon'}{'__anon'})) {
+                            push @{$usernamesort{'__anon'}{'__anon'}}, $idx;
+                        } else {
+                            @{$usernamesort{'__anon'}{'__anon'}} = ("$idx");
+                        }
+# Set up for sorting by last name, then first name for anonymous
+                        unless (defined($namesort{'__anon'})) {
+                            %{$namesort{'__anon'}} = ();
+                        }
+                        if (defined($namesort{'__anon'}{'__anon'})) {
+                            push @{$namesort{'__anon'}{'__anon'}}, $idx;
+                        } else {
+                            @{$namesort{'__anon'}{'__anon'}} = ("$idx");
+                        }
 		    }
 		    if (&discussion_open($status) &&
 			&Apache::lonnet::allowed('pch',
@@ -288,7 +356,7 @@
 		    }
 #figure out at what position this needs to print
 		    my $thisindex=$idx;
-		    if ($ENV{'environment.threadeddiscussion'}) {
+		    if ( (($ENV{'environment.threadeddiscussion'}) && (($sortposts eq '') || ($sortposts eq 'ascdate'))) || ($sortposts eq 'thread')) {
 			$thisindex=$origindex.substr('00'.$replies[$depth[$idx]],-2,2);	
 		    }
 		    $alldiscussion{$thisindex}=$idx;
@@ -381,8 +449,20 @@
 		if ($newpostsflag) {
 		    $discussion .= '&previous='.$prevread;
 		}
-		$discussion .='">'.&mt('Chronological View').'</a>&nbsp;&nbsp;</td>';
-	    }
+		$discussion .='">'.&mt('Chronological View').'</a>&nbsp;&nbsp;
+                              <a href= "/adm/feedback?sortfilter='.$ressymb;
+                if ($newpostsflag) {
+                    $discussion .= '&previous='.$prevread;
+                }
+                $discussion .='">'.&mt('Sorting/Filtering options').'</a>&nbsp;&nbsp';
+            } else {
+                $discussion .= '<td align="left">';
+            }
+            $discussion .='<a href= "/adm/feedback?export='.$ressymb;
+            if ($newpostsflag) {
+                $discussion .= '&previous='.$prevread;
+            }
+            $discussion .= '">'.&mt('Export').'?</a>&nbsp;&nbsp;</td>';
 	    if ($newpostsflag) {
 		if (!$markondisp) {
 		    $discussion .='<td align="right"><a href="/adm/feedback?markread='.$ressymb.'">'.&mt('Mark new posts as read').'</a>&nbsp;&nbsp;';
@@ -412,7 +492,37 @@
                          $numhidden.' '.&mt('previously viewed posts').
                          '<br/></td></tr>';
         }
-	foreach (sort { $a <=> $b } keys %alldiscussion) {
+
+# Choose sort mechanism
+        my @showposts = ();
+        if ($sortposts eq 'descdate') {
+            @showposts = (sort { $b <=> $a } keys %alldiscussion);
+        } elsif ($sortposts eq 'thread') {
+            @showposts = (sort { $a <=> $b } keys %alldiscussion);
+        } elsif ($sortposts eq 'subject') {
+            foreach (sort keys %subjectsort) {
+                push @showposts, @{$subjectsort{$_}};
+            }
+        } elsif ($sortposts eq 'username') {
+            foreach my $domain (sort keys %usernamesort) {
+                foreach (sort keys %{$usernamesort{$domain}}) {
+                    push @showposts, @{$usernamesort{$domain}{$_}};
+                }
+            }
+        } elsif ($sortposts eq 'lastfirst') {
+            foreach my $last (sort keys %namesort) {
+                 foreach (sort keys %{$namesort{$last}}) {
+                     push @showposts, @{$namesort{$last}{$_}};
+                 }
+            }
+        } else {
+            $sortposts = 'ascdate';
+            @showposts =  (sort { $a <=> $b } keys %alldiscussion);
+        }
+        foreach (@showposts) {
+            unless (($sortposts eq 'thread') || ($sortposts eq 'ascdate' && $ENV{'environment.threadeddiscussion'})) {
+                $alldiscussion{$_} = $_;
+            }
             unless ($notshown{$alldiscussion{$_}} eq '1') {
                 if ($outputtarget ne 'tex') {
 		    $discussion.="\n<tr>";
@@ -519,7 +629,7 @@
 		    '<img src="/adm/lonMisc/chat.gif" border="0" />'.
 		    &mt('Post Discussion').'</a></td></tr></table>';
 	    }
-			}
+	}
     }
    return $discussion;
 }
@@ -770,6 +880,148 @@
     return;
 }
 
+sub print_sortfilter_options {
+    my ($r,$symb,$previous,$feedurl) = @_;
+ # backward compatibility (bulletin boards used to be 'wrapped')
+    if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {
+        $feedurl=~s|^/adm/wrapper||;
+    }
+    my @sections = ();
+    my $section_sel = '';
+    my $numsections = 0;
+    my $numvisible = 5;
+    my ($classlist) = &Apache::loncoursedata::get_classlist(
+                              $ENV{'request.course.id'},
+                              $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
+                              $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+                                                                                   
+    my $sec_index = &Apache::loncoursedata::CL_SECTION();
+    my $status_index = &Apache::loncoursedata::CL_STATUS();
+    my %sectioncount = ();
+    while (my ($student,$data) = each %$classlist) {
+        my ($section,$status) = ($data->[$sec_index],
+                                 $data->[$status_index]);
+        unless ($section eq '' || $section =~ /^\s*$/) {
+            if (!defined($sectioncount{$section})) {
+                $sectioncount{$section} = 1;
+                $numsections ++;
+            } else {
+                $sectioncount{$section} ++;
+            }
+        }
+    }
+                                                                                   
+    if ($ENV{'request.course.sec'} !~ /^\s*$/) {
+        @sections = ($ENV{'request.course.sec'});
+        $numvisible = 1;
+    } else {
+        @sections = sort {$a cmp $b} keys(%sectioncount);
+        unshift(@sections,'all'); # Put 'all' at the front of the list
+        if ($numsections < 4) {
+            $numvisible = $numsections + 1;
+        }
+    }
+    foreach (@sections) {
+        $section_sel .= "  <option value=\"$_\" />$_\n";
+    }
+                                                                                   
+    my $function = &Apache::loncommon::get_users_function();
+    my $tabcolor = &Apache::loncommon::designparm($function.'.tabbg',
+                                                    $ENV{'user.domain'});
+    my $bodytag=&Apache::loncommon::bodytag('Discussion options',
+                                          '','');
+    my %lt = &Apache::lonlocal::texthash(
+        'diso' => 'Discussion sorting and filtering options',
+        'diop' => 'Display Options',
+        'curr' => 'Current setting ',
+        'actn' => 'Action',
+        'prca' => 'Options can be set that control the sort order of the posts, in
+addition to which posts are displayed.',
+        'soor' => 'Sort order',
+        'disp' => 'Specific user roles',
+        'actv' => 'Specific role status',
+        'spse' => 'Specific sections',
+        'psub' => 'Pick specific users (by name)',
+        'shal' => 'Show a list of current posters',
+        'yhni' => 'You have not indicated that you do not wish to change any of the discussion settings',
+        'ywbr' => 'You will be returned to the previous page if you click OK.'
+    );
+    $r->print(<<END);
+<html>
+<head>
+<title>$lt{'diso'}</title>
+<meta http-equiv="pragma" content="no-cache" />
+</head>
+$bodytag
+<form name="modifyshown" method="post" action="/adm/feedback">
+<b>$lt{'diso'}</b><br/> $lt{'prca'}
+<br /><br />
+<table border="0">
+ <tr>
+  <td><b>$lt{'soor'}</b></td>
+  <td>&nbsp;</td>
+  <td><b>$lt{'disp'}</b></td>
+  <td>&nbsp;</td>
+  <td><b>$lt{'actv'}</b></td>
+  <td>&nbsp;</td>
+  <td><b>$lt{'spse'}</b></td>
+  <td>&nbsp;</td>
+  <td><b>$lt{'psub'}</b></td>
+ </tr>
+ <tr>
+  <td>
+   <select name="sortposts">
+    <option value="ascdate" />Date order - oldest first
+    <option value="descdate" />Date order - newest first
+    <option value="thread" />Threaded
+    <option value="subject" />By subject
+    <option value="username" />By domain and username
+    <option value="lastfirst" />By last name, first name
+   </select>
+  </td>
+  <td>&nbsp;</td>
+  <td>
+   <select name="filterposts" multiple="true" size="5">
+    <option value="all" />All users
+    <option value="st" />Students
+    <option value="cc" />Course Coordinators
+    <option value="in" />Instructors
+    <option value="ta" />TAs
+    <option value="pr" />Exam proctors
+    <option value="cr" />Custom roles
+   </select>
+  </td>
+  <td>&nbsp;</td>
+  <td>
+   <select name="statusfilter">
+    <option value="all" />Roles of any status
+    <option value="act" />Only active roles
+    <option value="ina" />Only inactive roles
+   </select>
+  </td>
+  <td>&nbsp;</td>
+  <td>
+   <select name="sectionpick" multiple="true" size="$numvisible">
+    $section_sel
+   </select>
+  </td>
+  <td>&nbsp;</td>
+  <td><input type="checkbox" name="posterlist" value="$symb" />$lt{'shal'}</td>
+ </tr>
+</table>
+<br />
+<br />
+<input type="hidden" name="previous" value="$previous" />
+<input type="hidden" name="applysort" value="$symb" />
+<input type="button" name="sub" value="Store Changes" onClick="javascript:document.modifyshown.submit()" />
+<br />
+<br />
+</form>
+</body>
+</html>
+END
+}
+
 sub fail_redirect {
   my ($r,$feedurl) = @_;
   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
@@ -788,14 +1040,14 @@
 }
 
 sub redirect_back {
-  my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous) = @_;
+  my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous,$sort) = @_;
+  my $sorttag = '';
   my $prevtag = '';
   my $qrystr = '';
  # backward compatibility (bulletin boards used to be 'wrapped')
   if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {
       $feedurl=~s|^/adm/wrapper||;
   }
-
   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
   if ($previous > 0) {
       $qrystr = 'previous='.$previous;
@@ -806,6 +1058,15 @@
       }
       $prevtag = '<input type="hidden" name="previous" value="'.$previous.'" />';
   }
+  if (defined($sort)) {
+      my $sortqry = 'sortposts='.$sort;
+      if (($feedurl =~ /\?register=1/) || ($feedurl =~ /\?previous=/)) {
+          $feedurl .= '&'.$sortqry;
+      } else {
+          $feedurl .= '?'.$sortqry;
+      }
+      $sorttag = '<input type="hidden" name="sortposts" value="'.$sort.'" />';
+  }
   $r->print (<<ENDREDIR);
 <html>
 <head>
@@ -820,6 +1081,7 @@
 <font color="red">$status</font>
 <form name="reldt" action="$feedurl" target="loncapaclient">
 $prevtag
+$sorttag
 </form>
 </body>
 </html>
@@ -1136,8 +1398,38 @@
 # --------------------------- Get query string for limited number of parameters
 
   &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
-         ['hide','unhide','deldisc','postdata','preview','replydisc','threadedon','threadedoff','onlyunread','allposts','previous','markread','markonread','markondisp','modifydisp','changes','navmaps','navurl']);
-  if ($ENV{'form.navmaps'}) {
+         ['hide','unhide','deldisc','postdata','preview','replydisc','threadedon','threadedoff','onlyunread','allposts','previous','markread','markonread','markondisp','modifydisp','changes','navmaps','navurl','sortfilter','sortposts','applysort']);
+  if ($ENV{'form.applysort'}) {
+      &Apache::loncommon::content_type($r,'text/html');
+      $r->send_http_header;
+      my $symb=$ENV{'form.applysort'};
+      my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
+      my $previous=$ENV{'form.previous'};
+      my $sort = $ENV{'form.sortposts'};
+      my $filter = $ENV{'form.filterposts'};
+      my $statusfilter = $ENV{'form.statusfilter'};
+      my $secpick = $ENV{'form.sectionpick'};
+      my $feedurl = &Apache::lonnet::clutter($url);
+ # backward compatibility (bulletin boards used to be 'wrapped')
+      if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {
+          $feedurl=~s|^/adm/wrapper||;
+      }
+      &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0','',$previous,$sort,$filter,$secpick);
+      return OK;
+  } elsif ($ENV{'form.sortfilter'}) {
+      &Apache::loncommon::content_type($r,'text/html');
+      $r->send_http_header;
+      my $symb=$ENV{'form.sortfilter'};
+      my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
+      my $previous=$ENV{'form.previous'};
+      my $feedurl = &Apache::lonnet::clutter($url);
+ # backward compatibility (bulletin boards used to be 'wrapped')
+      if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {
+          $feedurl=~s|^/adm/wrapper||;
+      }
+      &print_sortfilter_options($r,$symb,$previous,$feedurl);
+      return OK;
+  } elsif ($ENV{'form.navmaps'}) {
       my %discinfo = ();
       my @resources = ();
       if ($ENV{'form.navmaps'} =~ /:/) {

--raeburn1090446434--