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

raeburn lon-capa-cvs@mail.lon-capa.org
Sat, 20 Nov 2004 20:40:52 -0000


This is a MIME encoded message

--raeburn1100983252
Content-Type: text/plain

raeburn		Sat Nov 20 15:40:52 2004 EDT

  Modified files:              
    /loncom/interface	lonfeedback.pm 
  Log:
  Fix bug #3607.  Extend filtering to support multiple selections of roles and/or sections.
  
  
--raeburn1100983252
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20041120154052.txt"

Index: loncom/interface/lonfeedback.pm
diff -u loncom/interface/lonfeedback.pm:1.142 loncom/interface/lonfeedback.pm:1.143
--- loncom/interface/lonfeedback.pm:1.142	Fri Nov 19 14:43:05 2004
+++ loncom/interface/lonfeedback.pm	Sat Nov 20 15:40:51 2004
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Feedback
 #
-# $Id: lonfeedback.pm,v 1.142 2004/11/19 19:43:05 albertel Exp $
+# $Id: lonfeedback.pm,v 1.143 2004/11/20 20:40:51 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -84,7 +84,7 @@
     my $cid=$ENV{'request.course.id'};
     if ($ENV{'request.course.sec'}) {
 	$crs.='_'.$ENV{'request.course.sec'};
-    }                 
+    }
     $crs=~s/\_/\//g;
     unless ($ressymb) {	$ressymb=&Apache::lonnet::symbread(); }
     unless ($ressymb) { return ''; }
@@ -122,7 +122,18 @@
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous','sortposts','rolefilter','statusfilter','sectionpick','totposters']);
     my $sortposts = $ENV{'form.sortposts'};
     my $statusfilter = $ENV{'form.statusfilter'};
-    my $sectionpick = $ENV{'form.sectionpick'};
+    my @sectionpick = ();
+    if ($ENV{'form.sectionpick'} =~ /,/) {
+        @sectionpick = split/,/,$ENV{'form.sectionpick'};
+    } else {
+        $sectionpick[0] = $ENV{'form.sectionpick'};
+    }
+    my @rolefilter = ();
+    if ($ENV{'form.rolefilter'} =~ /,/) {
+        @rolefilter = split/,/,$ENV{'form.rolefilter'};
+    } else {
+        $rolefilter[0] = $ENV{'form.rolefilter'};
+    }
     my $totposters = $ENV{'form.totposters'};
     $previous = $ENV{'form.previous'};
     if ($previous > 0) {
@@ -224,7 +235,7 @@
     $discinfo{$visitkey} = $visit;
 
     &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
-    &build_posting_display(\%usernamesort,\%subjectsort,\%namesort,\%notshown,\%newitem,\%dischash,\%shown,\%alldiscussion,\%imsitems,\%imsfiles,\%roleinfo,\@discussionitems,\@replies,\@depth,\@posters,\$maxdepth,\$visible,\$newpostsflag,\$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$encsymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,$ENV{'form.rolefilter'},$sectionpick,$statusfilter,$toggkey,$outputtarget);
+    &build_posting_display(\%usernamesort,\%subjectsort,\%namesort,\%notshown,\%newitem,\%dischash,\%shown,\%alldiscussion,\%imsitems,\%imsfiles,\%roleinfo,\@discussionitems,\@replies,\@depth,\@posters,\$maxdepth,\$visible,\$newpostsflag,\$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$encsymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,\@rolefilter,\@sectionpick,$statusfilter,$toggkey,$outputtarget);
 
     my $discussion='';
     my $manifestfile;
@@ -546,6 +557,46 @@
                  </table>
                 </td>
 END
+            if ($sortposts) {
+                my %sort_types = ();
+                my %role_types = ();
+                my %status_types = ();
+                &sort_filter_names(\%sort_types,\%role_types,\%status_types);
+
+                $discussion .= '<td><font size="-1"><b>'.&mt('Sorted by').'</b>: '.$sort_types{$sortposts}.'<br />';
+                if (defined($ENV{'form.totposters'})) {
+                    $discussion .= &mt('Posts by').': ';
+                    if ($totposters > 0) {
+                        foreach my $poster (@posters) {
+                            $poster =~ s/:/\@/;
+                            $discussion .= $poster.',';
+                        }
+                        $discussion =~ s/,//;
+                    } else {
+                        $discussion .= &mt('None selected');
+                    }
+                } else {
+                    my $filterchoice ='';
+                    if (@sectionpick > 0) {
+                        $filterchoice = '<i>'.&mt('sections').'</i>-&nbsp;'.$ENV{'form.sectionpick'};
+                        $filterchoice .= '&nbsp;&nbsp;&nbsp; ';
+                    }
+                    if (@rolefilter > 0) {
+                        $filterchoice .= '<i>'.&mt('roles').'</i>-&nbsp;';
+                        foreach (@rolefilter) {
+                            $filterchoice .= $role_types{$_}.',&nbsp;';
+                        }
+                        $filterchoice .= '&nbsp;&nbsp;&nbsp; ';
+                    }
+                    if ($statusfilter) {
+                        $filterchoice .= '<i>'.&mt('status').'</i>-&nbsp;'.$status_types{$statusfilter};
+                    }
+                    if ($filterchoice) {
+                        $discussion .= '<b>'.&mt('Filters').'</b>:&nbsp;'.$filterchoice;
+                    }
+                    $discussion .= '</font></td>';
+                }
+            }
             if ($dischash{$toggkey}) {
                 my $storebutton = &mt('Store read/unread changes');
                 $discussion.='<td align="right">'.
@@ -683,7 +734,6 @@
 
 sub build_posting_display {
     my ($usernamesort,$subjectsort,$namesort,$notshown,$newitem,$dischash,$shown,$alldiscussion,$imsitems,$imsfiles,$roleinfo,$discussionitems,$replies,$depth,$posters,$maxdepth,$visible,$newpostsflag,$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$ressymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,$rolefilter,$sectionpick,$statusfilter,$toggkey,$outputtarget) = @_;
-
     my @original=();
     my @index=();
     my $symb=&Apache::lonenc::check_decrypt($ressymb);
@@ -696,6 +746,11 @@
         if ($prevread eq '0') {
             $prevread = $oldest-1;
         }
+        my ($skiptest,$rolematch,$roleregexp,$secregexp,$statusregexp);
+        if ($sortposts) {
+            ($skiptest,$roleregexp,$secregexp,$statusregexp) = &filter_regexp($rolefilter,$sectionpick,$statusfilter);
+            $rolematch = $roleregexp.':'.$secregexp.':'.$statusregexp;
+        } 
 	for (my $id=1;$id<=$contrib{'version'};$id++) {
 	    my $idx=$id;
             my $posttime = $contrib{$idx.':timestamp'};
@@ -944,47 +999,32 @@
                             my $uname = $contrib{$idx.':sendername'};
                             my $udom = $contrib{$idx.':senderdomain'};
                             my $poster = $uname.':'.$udom;
-                            my $rolematch = '';
-                            my $skiptest = 1;
-                            if ($totposters > 0) {
-                                if (grep/^$poster$/,@{$posters}) {
-                                    $$shown{$idx} = 1;
-                                }
-                            } else {
-                                if ($rolefilter) {
-                                    if ($rolefilter eq 'all') {
-                                        $rolematch = '([^:]+)';
-                                    } else {
-                                        $rolematch = $rolefilter;
-                                        $skiptest = 0;
-                                    }
-                                }
-                                if ($sectionpick) {
-                                    if ($sectionpick eq 'all') {
-                                        $rolematch .= ':([^:]*)';
-                                    } else {
-                                        $rolematch .= ':'.$sectionpick;
-                                        $skiptest = 0;
-				    }
-                                }
-                                if ($statusfilter) {
-                                    if ($statusfilter eq 'all') {
-                                        $rolematch .= ':([^:]+)';
-                                    } else {
-                                        $rolematch .= ':'.$statusfilter;
-                                        $skiptest = 0;
+                            if (defined($ENV{'form.totposters'})) {
+                                if ($totposters == 0) {
+                                    $$shown{$idx} = 0;
+                                } elsif ($totposters > 0) {
+                                    if (grep/^$poster$/,@{$posters}) {
+                                        $$shown{$idx} = 1;
                                     }
                                 }
+                            } elsif ($sortposts) {
                                 if ($skiptest) {
                                     $$shown{$idx} = 1;
                                 } else {
                                     foreach my $role (@{$$roleinfo{$poster}}) {
-                                        if ($role =~ m/^$rolematch$/) {
+                                        if ($role =~ /^cc:/) {
+                                            my $cc_regexp = $roleregexp.':[^:]*:'.$statusregexp;
+                                            if ($role =~ /$cc_regexp/) {
+                                                $$shown{$idx} = 1;
+                                            }
+                                        } elsif ($role =~ /^$rolematch$/) {
                                             $$shown{$idx} = 1;
                                             last;
                                         }
                                     }
                                 }
+                            } else {
+                                $$shown{$idx} = 1;
                             }
                         }
                         unless ($$notshown{$idx} == 1) {
@@ -1034,6 +1074,60 @@
     }
 }
 
+sub filter_regexp {
+    my ($rolefilter,$sectionpick,$statusfilter) = @_;
+    my ($roleregexp,$secregexp,$statusregexp);
+    my $skiptest = 1;
+    if (@{$rolefilter} > 0) {
+        my @okrolefilter = ();
+        foreach (@{$rolefilter}) {
+            unless ($_ eq '') {
+                push @okrolefilter, $_;
+            }
+        }
+        if (@okrolefilter > 0) {
+            if (grep/^all$/,@okrolefilter) {
+                $roleregexp='[^:]+';
+            } else {
+                if (@okrolefilter == 1) {
+                    $roleregexp=$okrolefilter[0];
+                } else {
+                    $roleregexp='('.join('|',@okrolefilter).')';
+                }
+                $skiptest = 0;
+            }
+        }
+    }
+    if (@{$sectionpick} > 0) {
+        my @oksectionpick = ();
+        foreach (@{$sectionpick}) {
+            unless ($_ eq '') {
+                 push @oksectionpick, $_;
+            }
+        }
+        if ((@oksectionpick > 0) && (!grep/^all$/,@oksectionpick)) {
+            if (@oksectionpick == 1) {
+                $secregexp = $oksectionpick[0];
+            } else {
+                $secregexp .= '('.join('|',@oksectionpick).')';
+            }
+            $skiptest = 0;
+        } else {
+            $secregexp .= '[^:]*';
+        }
+    }
+    if (defined($statusfilter) && $statusfilter ne '') {
+        if ($statusfilter eq 'all') {
+            $statusregexp = '[^:]+';
+        } else {
+            $statusregexp = $statusfilter;
+            $skiptest = 0;
+        }
+    }
+    return ($skiptest,$roleregexp,$secregexp,$statusregexp);
+}
+
+
 sub get_post_contents {
     my ($contrib,$idx,$seeid,$type,$messages,$subjects,$allattachments,$attachtxt,$imsfiles,$screenname,$plainname,$numver) = @_;
     my $discussion = '';
@@ -1727,14 +1821,20 @@
         '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.',
+        'prca' => 'Set options that control the sort order of posts, and/or which posts are displayed.',
         'soor' => 'Sort order',
-        'disp' => 'Specific user roles',
-        'actv' => 'Specific role status',
+        'spur' => 'Specific user roles',
+        'sprs' => 'Specific role status',
         'spse' => 'Specific sections',
         'psub' => 'Pick specific users (by name)',
         'shal' => 'Show a list of current posters'
     );
+
+    my %sort_types = ();
+    my %role_types = ();
+    my %status_types = ();
+    &sort_filter_names(\%sort_types,\%role_types,\%status_types);
+
     $r->print(<<END);
 <html>
 <head>
@@ -1749,47 +1849,48 @@
  <tr>
   <td><b>$lt{'soor'}</b></td>
   <td>&nbsp;</td>
-  <td><b>$lt{'disp'}</b></td>
+  <td><b>$lt{'sprs'}</b></td>
   <td>&nbsp;</td>
-  <td><b>$lt{'actv'}</b></td>
+  <td><b>$lt{'spur'}</b></td>
   <td>&nbsp;</td>
   <td><b>$lt{'spse'}</b></td>
   <td>&nbsp;</td>
   <td><b>$lt{'psub'}</b></td>
  </tr>
  <tr>
-  <td>
+  <td align="center">
    <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
+    <option value="ascdate" />$sort_types{'ascdate'}
+    <option value="descdate" />$sort_types{'descdate'}
+    <option value="thread" />$sort_types{'thread'}
+    <option value="subject" />$sort_types{'subject'}
+    <option value="username" />$sort_types{'username'}
+    <option value="lastfirst" />$sort_types{'lastfirst'}
    </select>
   </td>
   <td>&nbsp;</td>
-  <td>
-   <select name="rolefilter" 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
+  <td align="center">
+   <select name="statusfilter">
+    <option value="all" />$status_types{'all'}
+    <option value="Active" />$status_types{'Active'}
+    <option value="Expired" />$status_types{'Expired'}
    </select>
   </td>
   <td>&nbsp;</td>
-  <td>
-   <select name="statusfilter">
-    <option value="all" />Roles of any status
-    <option value="Active" />Only active roles
-    <option value="Expired" />Only inactive roles
+  <td align="center">
+   <select name="rolefilter" multiple="true" size="5">
+    <option value="all" />$role_types{'all'}
+    <option value="st" />$role_types{'st'}
+    <option value="cc" />$role_types{'cc'}
+    <option value="in" />$role_types{'in'}
+    <option value="ta" />$role_types{'ta'}
+    <option value="ep" />$role_types{'ep'}
+    <option value="ad" />$role_types{'ad'}
+    <option value="cr" />$role_types{'cr'}
    </select>
   </td>
   <td>&nbsp;</td>
-  <td>
+  <td align="center">
    <select name="sectionpick" multiple="true" size="$numvisible">
     $section_sel
    </select>
@@ -1990,7 +2091,7 @@
 }
 
 sub redirect_back {
-  my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous,$sort,$rolefilter,$statusfilter,$secpick,$numpicks) = @_;
+  my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous,$sort,$rolefilter,$statusfilter,$sectionpick,$numpicks) = @_;
   my $sorttag = '';
   my $roletag = '';
   my $statustag = '';
@@ -2021,18 +2122,41 @@
           $feedurl .= '?'.$sortqry;
       }
       $sorttag = '<input type="hidden" name="sortposts" value="'.$sort.'" />';
-      if ( (defined($numpicks)) && ($numpicks > 0) ) {
+      if (defined($numpicks)) {
           my $userpickqry = 'totposters='.$numpicks;
           $feedurl .= '&'.$userpickqry;
           $userpicktag = '<input type="hidden" name="totposters" value="'.$numpicks.'" />';
       } else {
-          my $roleqry = 'rolefilter='.$rolefilter;
-          $feedurl .= '&'.$roleqry;
-          $roletag = '<input type="hidden" name="rolefilter" value="'.$rolefilter.'" />';
+          if (ref($sectionpick) eq 'ARRAY') {
+              $feedurl .= '&sectionpick=';
+              $sectag .=  '<input type="hidden" name="sectionpick" value="';
+              foreach (@{$sectionpick}) {
+                  $feedurl .= $_.',';
+                  $sectag .= $_.',';
+              }
+              $feedurl =~ s/,$//;
+              $sectag =~ s/,$//;
+              $sectag .= '" />';
+          } else {
+              $feedurl .= '&sectionpick='.$sectionpick;
+              $sectag = '<input type="hidden" name="sectionpick" value="'.$sectionpick.'" />';
+          }
+          if (ref($rolefilter) eq 'ARRAY') {
+              $feedurl .= '&rolefilter=';
+              $roletag .=  '<input type="hidden" name="rolefilter" value="';
+              foreach (@{$rolefilter}) {
+                  $feedurl .= $_.',';
+                  $roletag .= $_.',';
+              }
+              $feedurl =~ s/,$//;
+              $roletag =~ s/,$//;
+              $roletag .= '" />';
+          } else {
+              $feedurl .= '&rolefilter='.$rolefilter;
+              $roletag = '<input type="hidden" name="rolefilter" value="'.$rolefilter.'" />';
+          }
           $feedurl .= '&statusfilter='.$statusfilter;
           $statustag ='<input type="hidden" name="statusfilter" value="'.$statusfilter.'" />';
-          $feedurl .= '&sectionpick='.$secpick;
-          $sectag = '<input type="hidden" name="sectionpick" value="'.$secpick.'" />';
       }
   }
   $feedurl=&Apache::lonenc::check_encrypt($feedurl);
@@ -2724,7 +2848,34 @@
         }
     }
     return;
-} 
+}
+
+sub sort_filter_names {
+    my ($sort_types,$role_types,$status_types) = @_;
+    %{$sort_types} = (
+                     ascdate => 'Date order - oldest first',
+                     descdate => 'Date order - newest first',
+                     thread => 'Threaded',
+                     subject => 'By subject',
+                     username => 'By domain and username',
+                     lastfirst => 'By last name, first name'
+                   );
+    %{$role_types} = (
+                     all => 'All roles',
+                     st  => 'Students',
+                     cc  => 'Course Coordinators',
+                     in  => 'Instructors',
+                     ta  => 'TAs',
+                     ep  => 'Exam proctors',
+                     ad  => 'Administrators',
+                     cr  => 'Custom roles'
+                   );
+    %{$status_types} = (
+                     all     => 'Roles of any status',
+                     Active => 'Only active roles',
+                     Expired => 'Only inactive roles'
+                   );
+}
   
 sub handler {
   my $r = shift;
@@ -2738,6 +2889,7 @@
 
   &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
          ['hide','unhide','deldisc','postdata','preview','replydisc','editdisc','cmd','symb','onlyunread','allposts','onlyunmark','previous','markread','markonread','markondisp','toggoff','toggon','modifydisp','changes','navtime','navmaps','navurl','sortposts','applysort','rolefilter','statusfilter','sectionpick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export']);
+
   if ($ENV{'form.discsymb'}) {
       my ($symb,$feedurl) = &get_feedurl_and_clean_symb($ENV{'form.discsymb'});
       my $readkey = $symb.'_read';
@@ -2768,7 +2920,7 @@
       &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;
       my $bodytag=&Apache::loncommon::bodytag('Discussion Post Versions');
-      $r->print (<<END);
+      $r->print(<<END);
 <html>
 <head>
 <title>Post Versions</title>
@@ -2822,7 +2974,7 @@
       &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0',
 		     '',$ENV{'form.previous'},$ENV{'form.sortposts'},
 		     $ENV{'form.rolefilter'},$ENV{'form.statusfilter'},
-		     $ENV{'form.secpick'});
+		     $ENV{'form.sectionpick'});
       return OK;
   } elsif ($ENV{'form.cmd'} eq 'sortfilter') {
       my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.symb'});

--raeburn1100983252--