File:  [LON-CAPA] / loncom / interface / grouproster.pm
Revision 1.10.2.2: download - view: text, annotated - select for diffs
Wed Sep 9 00:18:04 2020 UTC (3 years, 8 months ago) by raeburn
Branches: version_2_11_X
CVS tags: version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3
- For 2.11
  Backport 1.11

    1: # The LearningOnline Network with CAPA
    2: #
    3: # $Id: grouproster.pm,v 1.10.2.2 2020/09/09 00:18:04 raeburn Exp $
    4: #
    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;
   36: use Apache::lonnavmaps;
   37: use LONCAPA;
   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: 
   58:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
   59:                                             ['group','ref','status']); 
   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;
   66:     my %curr_groups;
   67: 
   68:     # Validating group input.
   69:     my $badinput; 
   70:     if ((!defined($env{'form.group'})) || ($env{'form.group'} eq '')) {
   71:         $r->print(&mt('No group name provided.').'<br />');
   72:         $badinput = 1;
   73:     } else {
   74:         $group = $env{'form.group'};
   75:         $group =~ s/\W//g;
   76:     }
   77:     if (!$badinput && $group eq '') {
   78:         $r->print(&mt('Invalid group name provided.').'<br />');
   79:         $badinput = 1;
   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 '') {
   86:         $r->print(&mt('Invalid [_1]',$crstype).'<br />');
   87:         $badinput = 1;
   88:     }
   89: 
   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) {
   99:         return OK;
  100:     }
  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: 
  108:     my $viewgrps = &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
  109:     my $editgrps = &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
  110: 
  111:     if ((!$can_view) && (!$view_details) && (!$viewgrps) && (!$editgrps)) {
  112:         $r->print(&mt('You do not have privileges to view the membership roster in this '.$gpterm.'.'));
  113:         return OK;
  114:     }
  115:     my %content = &Apache::longroup::get_group_settings($curr_groups{$group});
  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) = @_;
  135:     my $refarg;
  136:     if (exists($env{'form.ref'}) && $env{'form.ref'} ne 'popup') {
  137:         $refarg = 'ref='.$env{'form.ref'};
  138:         &Apache::lonhtmlcommon::add_breadcrumb
  139:             ({href=>"/adm/coursegroups",
  140:               text=>"Groups",
  141:               title=>"View course groups"});
  142:     }
  143:     my $args;
  144:     if ($env{'form.ref'} eq 'popup') {
  145:         $args = { 
  146:                   'no_nav_bar'    => 1,
  147:                   'no_inline_link' => 1,
  148:                 };
  149:     }
  150:     my $jscript = qq|
  151: function changeSort(caller) {
  152:     document.grouproster.sortby.value = caller;
  153:     document.grouproster.submit();
  154: }\n|;
  155:     my $itemtitle = &mt('Group membership status - [_1]',$description);
  156:     my $output =
  157:         &Apache::loncommon::start_page('Group Membership',
  158:                                        '<script type="text/javascript">'.
  159:                                        $jscript.'</script>',$args);
  160:     if ($env{'form.ref'} eq 'popup') {
  161:         $output .= '<h3>'.&mt('Group membership status - [_1]',$description).
  162:                    '</h3>';
  163:     } else {
  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,
  171:               text=>&mt('Group').": $description",
  172:               title=>&mt("Go to group's home page"),
  173:               no_mt=>1},);
  174:         } else {
  175:             &Apache::lonhtmlcommon::add_breadcrumb
  176:             ({text=>&mt('Group').": $description",
  177:               no_mt=>1});
  178:         }
  179:         &Apache::lonhtmlcommon::add_breadcrumb
  180:              ({href=>'/adm/grouproster?group='.$group.'&amp;'.$refarg,
  181:               text=>"Membership Roster",
  182:               title=>"Display group membership"},);
  183:         $output .= &Apache::lonhtmlcommon::breadcrumbs(&mt('Group membership status - [_1]',$description),
  184:                                                        undef,undef,undef,undef,1);
  185:     }
  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: 
  195:     my ($memberinfo,$numitems,$hastools,$addtools) = 
  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) {
  231:             $r->print(&mt('There are no membership data to display for this '.$gpterm.'.'));  
  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'}.'"/>'.
  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:         }
  251:         $r->print('</form><br />');
  252: 
  253:     }
  254:     $r->print('<br />');
  255:     if (ref($numitems) eq 'HASH') {
  256:         foreach my $key (keys(%{$numitems})) {
  257:             if ($status eq $key && !$$numitems{$key}) {
  258:                 $r->print(&mt('There are no '.$gpterm.'s to display in this [_1].',
  259:                               lc($lt{$key})));
  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'}.'" />
  268:  <input type="hidden" name="status" value="'.$status.'" />
  269: ');
  270:     if (exists($env{'form.ref'})) {
  271:         $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
  272:                   '" />');
  273:     }
  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'}}) {
  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}.', ';
  362:                 }
  363:             }
  364:             $privlist =~ s/, $//;
  365:             $output .= '<td>'.$privlist.'</td>';
  366:         } elsif ($view_details) {
  367:             $output .= '<td><span class="LC_nobreak">'.join('&nbsp;&nbsp;&nbsp;',
  368:                       @{$$userinfo{'currtools'}}).'</span></td>';
  369:         }
  370:     }
  371:     $output .= &Apache::loncommon::end_data_table_row();
  372:     return $output;
  373: }
  374: 
  375: 1;
  376: 

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