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

raeburn lon-capa-cvs@mail.lon-capa.org
Wed, 21 Jul 2004 23:57:25 -0000


This is a MIME encoded message

--raeburn1090454245
Content-Type: text/plain

raeburn		Wed Jul 21 19:57:25 2004 EDT

  Modified files:              
    /loncom/interface	lonfeedback.pm 
  Log:
  Use filtering to control which posts are displayed.  1. Restrict display of posts to users with specific roles, status, sections OR 2. Select from list of users whoc have posted.  User interface needs more work.
  
  
--raeburn1090454245
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20040721195725.txt"

Index: loncom/interface/lonfeedback.pm
diff -u loncom/interface/lonfeedback.pm:1.100 loncom/interface/lonfeedback.pm:1.101
--- loncom/interface/lonfeedback.pm:1.100	Wed Jul 21 17:47:13 2004
+++ loncom/interface/lonfeedback.pm	Wed Jul 21 19:57:24 2004
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Feedback
 #
-# $Id: lonfeedback.pm,v 1.100 2004/07/21 21:47:13 raeburn Exp $
+# $Id: lonfeedback.pm,v 1.101 2004/07/21 23:57:24 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -72,6 +72,7 @@
     if ($mode eq 'board') { $discussiononly=1; }
     unless ($ENV{'request.course.id'}) { return ''; }
     my $crs='/'.$ENV{'request.course.id'};
+    my $cid=$ENV{'request.course.id'};
     if ($ENV{'request.course.sec'}) {
 	$crs.='_'.$ENV{'request.course.sec'};
     }                 
@@ -96,7 +97,8 @@
     my $showkey = $ressymb.'_showonlyunread';
     my $visitkey = $ressymb.'_visit';
     my $ondispkey = $ressymb.'_markondisp';
-    my %dischash = &Apache::lonnet::get('nohist_'.$ENV{'request.course.id'}.'_discuss',[$lastkey,$showkey,$visitkey,$ondispkey],$ENV{'user.domain'},$ENV{'user.name'});
+    my $userpickkey = $ressymb.'_userpick';
+    my %dischash = &Apache::lonnet::get('nohist_'.$ENV{'request.course.id'}.'_discuss',[$lastkey,$showkey,$visitkey,$ondispkey,$userpickkey],$ENV{'user.domain'},$ENV{'user.name'});
     my %discinfo = ();
     my $showonlyunread = 0;
     my $markondisp = 0;
@@ -104,10 +106,15 @@
     my $previous = 0;
     my $visit = 0;
     my $newpostsflag = 0;
+    my @posters = split/\&/,$dischash{$userpickkey};
 
 # Retain identification of "NEW" posts identified in last display, if continuing 'previous' browsing of posts.
-    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous','sortposts']);
+    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous','sortposts','rolefilter','statusfilter','sectionpick','totposters']);
     my $sortposts = $ENV{'form.sortposts'};
+    my $rolefilter = $ENV{'form.rolefilter'};
+    my $statusfilter = $ENV{'form.statusfilter'};
+    my $sectionpick = $ENV{'form.sectionpick'};
+    my $totposters = $ENV{'form.totposters'};
     $previous = $ENV{'form.previous'};
     if ($previous > 0) {
         $prevread = $previous;
@@ -117,6 +124,34 @@
         }
     }
 
+# Get information about students and non-stundents in course for filtering display of posts
+    my %roleshash = ();
+    my %roleinfo = ();
+    if ($rolefilter) {
+        %roleshash = &Apache::lonnet::dump('nohist_userroles',$ENV{'course.'.$ENV{'request.course.id'}.'.domain'},$ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+        foreach (keys %roleshash) {
+            my ($role,$uname,$udom,$sec) = split/:/,$_;
+            my ($end,$start) = split/:/,$roleshash{$_};
+            my $now = time;
+            my $status = 'Active';
+            if (($now < $start) || ($end > 0 && $now > $end)) {
+                $status = 'Expired';
+            }
+            push @{$roleinfo{$uname.':'.$udom}}, $role.':'.$sec.':'.$status;
+        }
+        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();
+        while (my ($student,$data) = each %$classlist) {
+            my ($section,$status) = ($data->[$sec_index],
+                                 $data->[$status_index]);
+            push @{$roleinfo{$student}}, 'st:'.$section.':'.$status;
+        }
+    }
+
 # Get discussion display default settings for user
     my %userenv = &Apache::lonnet::get('environment',['discdisplay','discmarkread'],$ENV{'user.domain'},$ENV{'user.name'});
     my $discdisplay=$userenv{'discdisplay'};
@@ -149,6 +184,8 @@
     my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
 	&& ($symb=~/\.(problem|exam|quiz|assess|survey|form)$/));
     my @discussionitems=();
+    my %shown = ();
+    my @posteridentity=();
     my %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'},
 			  $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
 			  $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
@@ -357,14 +394,62 @@
 #figure out at what position this needs to print
 		    my $thisindex=$idx;
 		    if ( (($ENV{'environment.threadeddiscussion'}) && (($sortposts eq '') || ($sortposts eq 'ascdate'))) || ($sortposts eq 'thread')) {
-			$thisindex=$origindex.substr('00'.$replies[$depth[$idx]],-2,2);	
+			$thisindex=$origindex.substr('00'.$replies[$depth[$idx]],-2,2);
 		    }
 		    $alldiscussion{$thisindex}=$idx;
-		    $index[$idx]=$thisindex;
+                    $shown{$idx} = 0;
+                    $index[$idx]=$thisindex;
                     my $spansize = 2;
                     if ($showonlyunread && $prevread > $posttime) {
                         $notshown{$idx} = 1;
                     } else {
+                        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 ($skiptest) {
+                                $shown{$idx} = 1;
+                            } else {
+                                foreach my $role (@{$roleinfo{$poster}}) {
+                                    if ($role =~ m/^$rolematch$/) {
+                                        $shown{$idx} = 1;
+                                        last;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    unless ($notshown{$idx} == 1) {
                         if ($prevread > 0 && $prevread <= $posttime) {
                             $newitem{$idx} = 1;
                             $discussionitems[$idx] .= '
@@ -523,7 +608,7 @@
             unless (($sortposts eq 'thread') || ($sortposts eq 'ascdate' && $ENV{'environment.threadeddiscussion'})) {
                 $alldiscussion{$_} = $_;
             }
-            unless ($notshown{$alldiscussion{$_}} eq '1') {
+            unless ( ($notshown{$alldiscussion{$_}} eq '1') || ($shown{$alldiscussion{$_}} == 0) ) {
                 if ($outputtarget ne 'tex') {
 		    $discussion.="\n<tr>";
 		} else {
@@ -935,16 +1020,13 @@
         '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' => '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.'
+        'shal' => 'Show a list of current posters'
     );
     $r->print(<<END);
 <html>
@@ -981,7 +1063,7 @@
   </td>
   <td>&nbsp;</td>
   <td>
-   <select name="filterposts" multiple="true" size="5">
+   <select name="rolefilter" multiple="true" size="5">
     <option value="all" />All users
     <option value="st" />Students
     <option value="cc" />Course Coordinators
@@ -995,8 +1077,8 @@
   <td>
    <select name="statusfilter">
     <option value="all" />Roles of any status
-    <option value="act" />Only active roles
-    <option value="ina" />Only inactive roles
+    <option value="Active" />Only active roles
+    <option value="Expired" />Only inactive roles
    </select>
   </td>
   <td>&nbsp;</td>
@@ -1022,6 +1104,111 @@
 END
 }
 
+sub print_showposters {
+    my ($r,$symb,$previous,$feedurl,$sortposts) = @_;
+ # backward compatibility (bulletin boards used to be 'wrapped')
+    if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {
+        $feedurl=~s|^/adm/wrapper||;
+    }
+# backward compatibility (bulletin boards used to be 'wrapped')
+    my $ressymb=$symb;
+    if ($ressymb =~ /bulletin___\d+___/) {
+        unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
+            $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
+        }
+    }
+    my $crs='/'.$ENV{'request.course.id'};
+    $crs=~s/\_/\//g;
+    my $seeid=&Apache::lonnet::allowed('rin',$crs);
+    my %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'},
+                          $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
+                          $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+    my %namesort = ();
+    my %postcounts = ();
+    my %lt=&Apache::lonlocal::texthash(
+                     'diso' => 'Discussion filtering options',
+    );
+    my $bodytag=&Apache::loncommon::bodytag('Discussion options',
+                                          '','');
+    if ($contrib{'version'}) {
+        for (my $idx=1;$idx<=$contrib{'version'};$idx++) {
+            my $hidden=($contrib{'hidden'}=~/\.$idx\./);
+            my $deleted=($contrib{'deleted'}=~/\.$idx\./);
+            unless ((($hidden) && (!$seeid)) || ($deleted)) {
+                if ((!$contrib{$idx.':anonymous'}) || ($seeid)) {
+                    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}} = ();
+                    }
+                    my $poster =  $contrib{$idx.':sendername'}.':'.$contrib{$idx.':senderdomain'};
+                    $postcounts{$poster} ++;
+                    if (defined($namesort{$lastname}{$firstname})) {
+                        if (!grep/^$poster$/,@{$namesort{$lastname}{$firstname}}) {
+                            push @{$namesort{$lastname}{$firstname}}, $poster;
+                        }
+                    } else {
+                        @{$namesort{$lastname}{$firstname}} = ("$poster");
+                    }
+                }
+            }
+        }
+    }
+    $r->print(<<END);
+<html>
+<head>
+<title>$lt{'diso'}</title>
+<meta http-equiv="pragma" content="no-cache" />
+</head>
+$bodytag
+ <form name="pickpostersform" method="post">
+  <table border="0">
+   <tr>
+    <td bgcolor="#777777">
+     <table border="0" cellpadding="3">
+      <tr bgcolor="#e6ffff">
+       <td><b>No.</b></td>
+       <td><b>Select</b></td>
+       <td><b>Fullname</b><font color="#999999">(Username/domain)</font></td>
+       <td><b>Posts</td>
+      </tr>
+END
+    my $count = 0;
+    foreach my $last (sort keys %namesort) {
+        foreach my $first (sort keys %{$namesort{$last}}) {
+            foreach (sort @{$namesort{$last}{$first}}) {
+                my ($uname,$udom) = split/:/,$_;
+                if (!$uname || !$udom) { 
+                    next;
+                } else {
+                    $count ++;
+                    $r->print('<tr bgcolor="#ffffe6"><td align="right">'.$count.'</td><td align="center"><input name="stuinfo" type="checkbox" value="'.$_.'" /></td><td>'.$last.', '.$first.' ('.$uname.','.$udom.')</td><td>'.$postcounts{$_}.'</td></tr>');
+                }
+            }
+        }
+    }
+    $r->print(<<END);
+     </table>
+    </td>
+   </tr>
+  </table>
+<br />
+<input type="hidden" name="sortposts" value="$sortposts" />
+<input type="hidden" name="userpick" value="$symb" />
+<input type="button" name="store" value="Display posts" onClick="javascript:document.pickpostersform.submit()" />
+</form>
+</body>
+</html>
+END
+}
+
 sub fail_redirect {
   my ($r,$feedurl) = @_;
   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
@@ -1040,10 +1227,14 @@
 }
 
 sub redirect_back {
-  my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous,$sort) = @_;
+  my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous,$sort,$rolefilter,$statusfilter,$secpick,$numpicks) = @_;
   my $sorttag = '';
-  my $prevtag = '';
+  my $roletag = '';
+  my $statustag = '';
+  my $sectag = '';
+  my $userpicktag = '';
   my $qrystr = '';
+  my $prevtag = '';
  # backward compatibility (bulletin boards used to be 'wrapped')
   if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {
       $feedurl=~s|^/adm/wrapper||;
@@ -1066,6 +1257,19 @@
           $feedurl .= '?'.$sortqry;
       }
       $sorttag = '<input type="hidden" name="sortposts" value="'.$sort.'" />';
+      if ( (defined($numpicks)) && ($numpicks > 0) ) {
+          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.'" />';
+          $feedurl .= '&statusfilter='.$statusfilter;
+          $statustag ='<input type="hidden" name="statusfilter" value="'.$statusfilter.'" />';
+          $feedurl .= '&sectionpick='.$secpick;
+          $sectag = '<input type="hidden" name="sectionpick" value="'.$secpick.'" />';
+      }
   }
   $r->print (<<ENDREDIR);
 <html>
@@ -1082,6 +1286,10 @@
 <form name="reldt" action="$feedurl" target="loncapaclient">
 $prevtag
 $sorttag
+$statustag
+$roletag
+$sectag
+$userpicktag
 </form>
 </body>
 </html>
@@ -1398,7 +1606,54 @@
 # --------------------------- 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','sortfilter','sortposts','applysort']);
+         ['hide','unhide','deldisc','postdata','preview','replydisc','threadedon','threadedoff','onlyunread','allposts','previous','markread','markonread','markondisp','modifydisp','changes','navmaps','navurl','sortfilter','sortposts','applysort','rolefilter','statusfilter','sectionpick','posterlist','userpick']);
+  if ($ENV{'form.posterlist'}) {
+      &Apache::loncommon::content_type($r,'text/html');
+      $r->send_http_header;
+      my $symb=$ENV{'form.posterlist'};
+      my $sortposts = $ENV{'form.sortposts'};
+      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_showposters($r,$symb,$previous,$feedurl,$sortposts);
+      return OK;
+  }
+  if ($ENV{'form.userpick'}) {
+      &Apache::loncommon::content_type($r,'text/html');
+      $r->send_http_header;
+      my $symb=$ENV{'form.userpick'};
+      my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
+      my $previous=$ENV{'form.previous'};
+# backward compatibility (bulletin boards used to be 'wrapped')
+      my $ressymb=$symb;
+      unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
+          $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
+      }
+      my $sort=$ENV{'form.sortposts'};
+      my @posters = ();
+      if (ref($ENV{'form.stuinfo'}) eq 'ARRAY') {
+          @posters = $ENV{'form.stuinfo'};
+      } else {
+          $posters[0] = $ENV{'form.stuinfo'};
+      }
+      my $numpicks = @posters;
+      if (defined($ENV{'form.userpick'})) {
+          my %discinfo = ();
+          $discinfo{$ressymb.'_userpick'} = join('&',@posters);
+          &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
+      }
+      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,'','','',$numpicks);
+      return OK;
+  }
   if ($ENV{'form.applysort'}) {
       &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;
@@ -1406,7 +1661,7 @@
       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 $rolefilter = $ENV{'form.rolefilter'};
       my $statusfilter = $ENV{'form.statusfilter'};
       my $secpick = $ENV{'form.sectionpick'};
       my $feedurl = &Apache::lonnet::clutter($url);
@@ -1414,7 +1669,7 @@
       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);
+      &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0','',$previous,$sort,$rolefilter,$statusfilter,$secpick);
       return OK;
   } elsif ($ENV{'form.sortfilter'}) {
       &Apache::loncommon::content_type($r,'text/html');

--raeburn1090454245--