Annotation of loncom/interface/grouproster.pm, revision 1.10.2.2

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

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