File:  [LON-CAPA] / loncom / interface / grouproster.pm
Revision 1.4: download - view: text, annotated - select for diffs
Thu Aug 17 23:36:05 2006 UTC (17 years, 8 months ago) by raeburn
Branches: MAIN
CVS tags: version_2_6_X, version_2_6_3, version_2_6_2, version_2_6_1, version_2_6_0, version_2_5_X, version_2_5_99_1, version_2_5_99_0, version_2_5_2, version_2_5_1, version_2_5_0, version_2_4_X, version_2_4_99_0, version_2_4_2, version_2_4_1, version_2_4_0, version_2_3_X, version_2_3_99_0, version_2_3_2, version_2_3_1, version_2_3_0, version_2_2_X, version_2_2_99_1, version_2_2_99_0, version_2_2_2, version_2_2_1, version_2_2_0, HEAD
loncommon::start_page() does its own &mt().  Current status type should be retained when changing sorting used in roster display.  Roster can be displayed in a pop-up window.  Links provided to open pop-up window in table listing course groups, where membership > 0. Membership roster now available (via popup) to users with mdg or vcg privilege in cases where membership roster is not enbled in the group.

    1: # The LearningOnline Network with CAPA
    2: #
    3: # Copyright Michigan State University Board of Trustees
    4: #
    5: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    6: #
    7: # LON-CAPA is free software; you can redistribute it and/or modify
    8: # it under the terms of the GNU General Public License as published by
    9: # the Free Software Foundation; either version 2 of the License, or
   10: # (at your option) any later version.
   11: #
   12: # LON-CAPA is distributed in the hope that it will be useful,
   13: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   14: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15: # GNU General Public License for more details.
   16: #
   17: # You should have received a copy of the GNU General Public License
   18: # along with LON-CAPA; if not, write to the Free Software
   19: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   20: #
   21: # /home/httpd/html/adm/gpl.txt
   22: #
   23: # http://www.lon-capa.org/
   24: #
   25: 
   26: package Apache::grouproster;
   27:                                                                                  
   28: use strict;
   29: use Apache::lonnet;
   30: use Apache::loncommon;
   31: use Apache::lonhtmlcommon;
   32: use Apache::lonlocal;
   33: use Apache::longroup;
   34: use LONCAPA;
   35: use Apache::Constants qw(:common :http);
   36: use lib '/home/httpd/lib/perl/';
   37: 
   38: sub handler {
   39:     my ($r) = @_;
   40:     &Apache::loncommon::content_type($r,'text/html');
   41:     $r->send_http_header;
   42:                                                                                  
   43:     if ($r->header_only) {
   44:         return OK;
   45:     }
   46:                                                                                  
   47:     #  Needs to be in a course
   48:     if (! ($env{'request.course.fn'})) {
   49:         # Not in a course
   50:         $env{'user.error.msg'}=
   51:      "/adm/coursegroups:mdg:0:0:Cannot edit or view course groups";
   52:         return HTTP_NOT_ACCEPTABLE;
   53:     }
   54: 
   55:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
   56:                                             ['group','ref','status']); 
   57: 
   58:     my $gpterm  = &Apache::loncommon::group_term();
   59:     my $ucgpterm = $gpterm;
   60:     $ucgpterm =~ s/^(\w)/uc($1)/e;  
   61:     my $crstype = &Apache::loncommon::course_type();
   62:     my $group;
   63:     my %curr_groups;
   64: 
   65:     # Validating group input.
   66:     my $badinput; 
   67:     if ((!defined($env{'form.group'})) || ($env{'form.group'} eq '')) {
   68:         $r->print(&mt('No group name provided.<br />'));
   69:         $badinput = 1;
   70:     } else {
   71:         $group = $env{'form.group'};
   72:         $group =~ s/\W//g;
   73:     }
   74:     if (!$badinput && $group eq '') {
   75:         $r->print(&mt('Invalid group name provided.<br />'));
   76:         $badinput = 1;
   77:     }
   78: 
   79:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
   80:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
   81: 
   82:     if ($cdom eq '' || $cnum eq '') {
   83:         $r->print(&mt('Invalid [_1]<br />',$crstype));
   84:         $badinput = 1;
   85:     }
   86: 
   87:     if (!$badinput) {
   88:         %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
   89:         if (!defined($curr_groups{$group})) {
   90:             $r->print(&mt('"[_1]" is not the name of a valid group in this [_2].',
   91:                           $group,lc($crstype)));
   92:             $badinput = 1;
   93:         }
   94:     }
   95:     if ($badinput) {
   96:         return OK;
   97:     }
   98: 
   99:     &Apache::lonhtmlcommon::clear_breadcrumbs();
  100: 
  101:     my $can_view = &Apache::lonnet::allowed('vgm',$env{'request.course.id'}.
  102:                                             '/'.$group);
  103:     my $view_details = &Apache::lonnet::allowed('vmd',$env{'request.course.id'}.'/'.$group);
  104: 
  105:     my $viewgrps = &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
  106:     my $editgrps = &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
  107: 
  108:     if ((!$can_view) && (!$view_details) && (!$viewgrps) && (!$editgrps)) {
  109:         $r->print(&mt('You do not have privileges to view the membership roster in this [_1]',$gpterm));
  110:         return OK;
  111:     }
  112:     my %content = &Apache::longroup::get_group_settings($curr_groups{$group});
  113:     my $description = &unescape($content{'description'});
  114:     $r->print(&roster_header($cdom,$cnum,$group,$description,$gpterm,$ucgpterm));
  115: 
  116:     my $available;
  117:     foreach my $tool (sort(keys(%{$content{'functions'}}))) {
  118:         if ($content{functions}{$tool} eq 'on') {
  119:             push(@{$available},$tool);
  120:         }
  121:     }
  122: 
  123:     &roster_table($r,$cdom,$cnum,$group,$can_view,$view_details,$viewgrps,
  124:                   $editgrps,$available,$gpterm,$ucgpterm);
  125: 
  126:     $r->print(&Apache::loncommon::end_page());
  127:     return OK;
  128: }
  129: 
  130: sub roster_header {
  131:     my ($cdom,$cnum,$group,$description,$gpterm,$ucgpterm) = @_;
  132:     my $refarg;
  133:     if (exists($env{'form.ref'}) && $env{'form.ref'} ne 'popup') {
  134:         $refarg = 'ref='.$env{'form.ref'};
  135:         &Apache::lonhtmlcommon::add_breadcrumb
  136:             ({href=>"/adm/coursegroups",
  137:               text=>"Groups",
  138:               title=>"View course groups"});
  139:     }
  140:     my $args;
  141:     if ($env{'form.ref'} eq 'popup') {
  142:         $args = { 
  143:                   'no_nav_bar'    => 1,
  144:                   'no_inline_link' => 1,
  145:                 };
  146:     }
  147:     my $jscript = qq|
  148: function changeSort(caller) {
  149:     document.grouproster.sortby.value = caller;
  150:     document.grouproster.submit();
  151: }\n|;
  152:     my $itemtitle = &mt('Group membership status - [_1]',$description);
  153:     my $output =
  154:         &Apache::loncommon::start_page('Group Membership',
  155:                                        '<script type="text/javascript">'.
  156:                                        $jscript.'</script>',$args);
  157:     if ($env{'form.ref'} eq 'popup') {
  158:         $output .= '<h3>'.&mt('Group membership status - [_1]',$description).
  159:                    '</h3>';
  160:     } else {
  161:         &Apache::lonhtmlcommon::add_breadcrumb
  162:             ({href=>"/adm/$cdom/$cnum/$group/smppg?$refarg",
  163:               text=>"$ucgpterm: $description",
  164:               title=>"Go to group's home page"},
  165:              {href=>'/adm/grouproster?group='.$group.'&amp;'.$refarg,
  166:               text=>"Membership roster",
  167:               title=>"Display group membership"},);
  168:         $output .= &Apache::lonhtmlcommon::breadcrumbs(&mt('[_1] membership status - [_2]',$gpterm,$description));
  169:     }
  170:     return $output;
  171: }
  172: 
  173: sub roster_table {
  174:     my ($r,$cdom,$cnum,$group,$can_view,$view_details,$viewgrps,$editgrps,
  175:         $available,$gpterm,$ucgpterm) = @_;
  176: 
  177:     my $fixedprivs = &Apache::longroup::get_fixed_privs();
  178: 
  179:     my ($memberinfo,$numitems,$hastools,$addtools) = 
  180:         &Apache::longroup::group_memberlist($cdom,$cnum,$group,$fixedprivs,
  181:                                             $available);
  182:     my (%tooltype,$toolprivs);
  183: 
  184:     if ($hastools) {
  185:         $toolprivs = &Apache::longroup::get_tool_privs($gpterm);
  186:         foreach my $tool (sort(keys(%{$toolprivs}))) {
  187:             foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
  188:                 $tooltype{$priv} = $tool;
  189:             }
  190:         }
  191:     }
  192:  
  193:     my %lt = &Apache::lonlocal::texthash(
  194:                                          'name'     => 'Name',
  195:                                          'usnm'     => 'Username',
  196:                                          'doma'     => 'Domain',
  197:                                          'stid'     => 'ID',
  198:                                          'stda'     => 'Start Date',
  199:                                          'enda'     => 'End Date',
  200:                                          'func'     => 'Functionality',
  201:                                          'priv'     => 'Privileges', 
  202:                                          'all'      => 'Any Membership status',
  203:                                          'active'   => 'Active Member',
  204:                                          'previous' => 'Former Member',
  205:                                          'future'   => 'Future Member',
  206:                                          'updi'     => 'Update Display',
  207:                                         );
  208:     my $status = $env{'form.status'};
  209:     if (!defined($status)) {
  210:         $status = 'active';
  211:     }
  212:     if (($viewgrps) || ($editgrps) || 
  213:         (&Apache::lonnet::allowed('vmd',$env{'request.course.id'}.'/'.$group))) {
  214:         if (keys(%{$memberinfo}) == 0) {
  215:             $r->print(&mt('There are no membership data to display for this [_1]',
  216:                       $gpterm));  
  217:             return;  
  218:         }  
  219:         $r->print('<br /><form name="rosterstatus" method="post" action="/adm/grouproster">'.&mt('Membership status: ').'<select name="status">');
  220:         foreach my $type ('active','previous','future','all') {
  221:             $r->print('<option value="'.$type.'" ');
  222:             if ($status eq $type) {
  223:                 $r->print('selected="selected"');
  224:             }
  225:             $r->print('>'.$lt{$type}.'</option>');
  226:         }
  227:         $r->print('</select>'."\n".
  228:                   '<input type="submit" name="statusbutton" value="'.
  229:                   $lt{'updi'}.'"><input type="hidden" name="sortby" value="'.
  230:                   $env{'form.sortby'}.'"/>'.
  231:                   '<input type="hidden" name="group" value="'.$group.'"/>');
  232:         if (exists($env{'form.ref'})) {
  233:             $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
  234:                       '" />');
  235:         }
  236:         $r->print('</form><br />');
  237: 
  238:     }
  239:     $r->print('<br />');
  240:     if (ref($numitems) eq 'HASH') {
  241:         foreach my $key (keys(%{$numitems})) {
  242:             if ($status eq $key && !$$numitems{$key}) {
  243:                 $r->print(&mt('There are no [_1]s to display in this [_2].',
  244:                               lc($lt{$key}),$gpterm));
  245:                 return;
  246:             }
  247:         }
  248:     }
  249:     $r->print('
  250: <form name="grouproster" action="/adm/grouproster" method="post">
  251:  <input type="hidden" name="group" value="'.$group.'" />
  252:  <input type="hidden" name="sortby" value="'.$env{'form.sortby'}.'" />
  253:  <input type="hidden" name="status" value="'.$status.'" />
  254: ');
  255:     if (exists($env{'form.ref'})) {
  256:         $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
  257:                   '" />');
  258:     }
  259:     my %Sortby = ();
  260:     my $usercount = 0;
  261:     foreach my $user (sort(keys(%{$memberinfo}))) {
  262:         if ($env{'form.sortby'} eq 'fullname') {
  263:             push(@{$Sortby{$$memberinfo{$user}{fullname}}},$user);
  264:         } elsif ($env{'form.sortby'} eq 'username') {
  265:             push(@{$Sortby{$$memberinfo{$user}{uname}}},$user);
  266:         } elsif ($env{'form.sortby'} eq 'domain') {
  267:             push(@{$Sortby{$$memberinfo{$user}{udom}}},$user);
  268:         } elsif ($env{'form.sortby'} eq 'id') {
  269:             push(@{$Sortby{$$memberinfo{$user}{id}}},$user);
  270:         } else {
  271:             push(@{$Sortby{$$memberinfo{$user}{fullname}}},$user);
  272:         }
  273:     }
  274:     $r->print(&Apache::loncommon::start_data_table());
  275:     $r->print(&members_table_header_row(\%lt,$viewgrps,$editgrps,$view_details,
  276:                                         $hastools));
  277:     foreach my $key (sort(keys(%Sortby))) {
  278:         foreach my $user (@{$Sortby{$key}}) {
  279:             if (($status eq 'all') || 
  280:                 ($status eq $$memberinfo{$user}{status})) {
  281:                 $r->print(&members_table_row($viewgrps,$editgrps,$view_details,
  282:                           $hastools,\%tooltype,$toolprivs,$$memberinfo{$user}));
  283:             }
  284:         }
  285:     }
  286:     $r->print(&Apache::loncommon::end_data_table());
  287:     $r->print('</form>');
  288:     return;
  289: }
  290: 
  291: sub members_table_header_row {
  292:     my ($lt,$viewgrps,$editgrps,$view_details,$hastools) = @_; 
  293:     my $output = &Apache::loncommon::start_data_table_header_row();
  294:     $output .= "<th><a href=\"javascript:changeSort('fullname')\">".
  295:               "$$lt{'name'}</a></th>";
  296:     if ($viewgrps || $editgrps || $view_details ) {
  297:         $output .= "<th><a href=\"javascript:changeSort('username')\">$$lt{'usnm'}</a></th>";
  298:         $output .= "<th><a href=\"javascript:changeSort('domain')\">$$lt{'doma'}</a></th>";
  299:     }
  300:     if ($viewgrps || $editgrps) {
  301:         $output .= "<th><a href=\"javascript:changeSort('id')\">$$lt{'stid'}</a></th>";
  302:     }
  303:     if ($viewgrps || $editgrps || $view_details ) {
  304:         $output .= "<th><a href=\"javascript:changeSort('start')\">$$lt{'stda'}</a></th>";
  305:         $output .= "<th><a href=\"javascript:changeSort('end')\">$$lt{'enda'}</a></th>";
  306:         if ($hastools) {
  307:             if ($viewgrps || $editgrps) {
  308:                 $output .= '<th><b>'.$$lt{'priv'}.'</b></th>';
  309:             } elsif ($view_details) {
  310:                 $output .= '<th><b>'.$$lt{'func'}.'</b></th>';
  311:             }
  312:         }
  313:     }
  314:     $output .= &Apache::loncommon::end_data_table_header_row();
  315:     return $output;
  316: }
  317: 
  318: sub members_table_row {
  319:     my ($viewgrps,$editgrps,$view_details,$hastools,$tooltype,$toolprivs,
  320:         $userinfo) = @_;
  321:     my $output = &Apache::loncommon::start_data_table_row();
  322:     $output .= '<td>'.&Apache::loncommon::aboutmewrapper($$userinfo{'fullname'},
  323:                       $$userinfo{'uname'},$$userinfo{'udom'}  ).
  324:                '</td>';
  325:     if ($viewgrps || $editgrps || $view_details ) {
  326:         $output .= '<td>'.$$userinfo{'uname'}.'</td>';
  327:         $output .= '<td>'.$$userinfo{'udom'}.'</td>';
  328:     }
  329:     if ($viewgrps || $editgrps) {
  330:         $output .= '<td>'.$$userinfo{'id'}.'</td>';
  331:     }
  332:     if ($viewgrps || $editgrps || $view_details) {
  333:         $output .= '<td>'.$$userinfo{'start'}.'</td>';
  334:         $output .= '<td>'.$$userinfo{'end'}.'</td>';
  335:     }
  336:     if ($hastools) {
  337:         if ($viewgrps || $editgrps) {
  338:             my $curr_tool;
  339:             my $privlist;
  340:             foreach my $priv (@{$$userinfo{'privs'}}) {
  341:                 if (defined($$tooltype{$priv})) {
  342:                     if ($curr_tool ne $$tooltype{$priv}) {
  343:                         $curr_tool = $$tooltype{$priv};
  344:                         $privlist .= '<b>'.$curr_tool.'</b>: ';
  345:                     }
  346:                     $privlist .= $$toolprivs{$curr_tool}{$priv}.', ';
  347:                 }
  348:             }
  349:             $privlist =~ s/, $//;
  350:             $output .= '<td>'.$privlist.'</td>';
  351:         } elsif ($view_details) {
  352:             $output .= '<td><nobr>'.join('&nbsp;&nbsp;&nbsp;',
  353:                       @{$$userinfo{'currtools'}}).'</nobr></td>';
  354:         }
  355:     }
  356:     $output .= &Apache::loncommon::end_data_table_row();
  357:     return $output;
  358: }
  359: 
  360: 1;
  361: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>