File:  [LON-CAPA] / loncom / interface / grouproster.pm
Revision 1.10: download - view: text, annotated - select for diffs
Fri Feb 26 21:44:39 2016 UTC (8 years, 2 months ago) by raeburn
Branches: MAIN
CVS tags: version_2_11_X, HEAD
- Bug 6780. No "Groups" item in inline menu for users with unprivileged
  course roles if all group home pages are hidden, and no group tools
  enabled.

  Move &display_group_links() from lonsimplepage.pm to longroup.pm to
  facilitate re-use.

    1: # The LearningOnline Network with CAPA
    2: #
    3: # $Id: grouproster.pm,v 1.10 2016/02/26 21:44:39 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 = { 'no_nav_bar'    => 1, };
  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:         my $view_permission =
  162:             &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
  163:         my $navmap=Apache::lonnavmaps::navmap->new();
  164:         my $grouppagelink = &Apache::longroup::get_group_link($cdom,$cnum,$group,$navmap,$view_permission,$refarg);
  165:         if ($grouppagelink) {
  166:             &Apache::lonhtmlcommon::add_breadcrumb
  167:             ({href=>$grouppagelink,
  168:               text=>"$ucgpterm: $description",
  169:               title=>"Go to group's home page"},);
  170:         } else {
  171:             &Apache::lonhtmlcommon::add_breadcrumb
  172:             ({text=>"$ucgpterm: $description",});
  173:         }
  174:         &Apache::lonhtmlcommon::add_breadcrumb
  175:              ({href=>'/adm/grouproster?group='.$group.'&amp;'.$refarg,
  176:               text=>"Membership Roster",
  177:               title=>"Display group membership"},);
  178:         $output .= &Apache::lonhtmlcommon::breadcrumbs(&mt($gpterm.' membership status - [_1]',$description));
  179:     }
  180:     return $output;
  181: }
  182: 
  183: sub roster_table {
  184:     my ($r,$cdom,$cnum,$group,$can_view,$view_details,$viewgrps,$editgrps,
  185:         $available,$gpterm,$ucgpterm) = @_;
  186: 
  187:     my $fixedprivs = &Apache::longroup::get_fixed_privs();
  188: 
  189:     my ($memberinfo,$numitems,$hastools,$addtools) = 
  190:         &Apache::longroup::group_memberlist($cdom,$cnum,$group,$fixedprivs,
  191:                                             $available);
  192:     my (%tooltype,$toolprivs);
  193: 
  194:     if ($hastools) {
  195:         $toolprivs = &Apache::longroup::get_tool_privs($gpterm);
  196:         foreach my $tool (sort(keys(%{$toolprivs}))) {
  197:             foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
  198:                 $tooltype{$priv} = $tool;
  199:             }
  200:         }
  201:     }
  202:  
  203:     my %lt = &Apache::lonlocal::texthash(
  204:                                          'name'     => 'Name',
  205:                                          'usnm'     => 'Username',
  206:                                          'doma'     => 'Domain',
  207:                                          'stid'     => 'ID',
  208:                                          'stda'     => 'Start Date',
  209:                                          'enda'     => 'End Date',
  210:                                          'func'     => 'Functionality',
  211:                                          'priv'     => 'Privileges', 
  212:                                          'all'      => 'Any Membership status',
  213:                                          'active'   => 'Active Member',
  214:                                          'previous' => 'Former Member',
  215:                                          'future'   => 'Future Member',
  216:                                          'updi'     => 'Update Display',
  217:                                         );
  218:     my $status = $env{'form.status'};
  219:     if (!defined($status)) {
  220:         $status = 'active';
  221:     }
  222:     if (($viewgrps) || ($editgrps) || 
  223:         (&Apache::lonnet::allowed('vmd',$env{'request.course.id'}.'/'.$group))) {
  224:         if (keys(%{$memberinfo}) == 0) {
  225:             $r->print(&mt('There are no membership data to display for this '.$gpterm.'.'));  
  226:             return;  
  227:         }  
  228:         $r->print('<br /><form name="rosterstatus" method="post" action="/adm/grouproster">'.&mt('Membership status: ').'<select name="status">');
  229:         foreach my $type ('active','previous','future','all') {
  230:             $r->print('<option value="'.$type.'" ');
  231:             if ($status eq $type) {
  232:                 $r->print('selected="selected"');
  233:             }
  234:             $r->print('>'.$lt{$type}.'</option>');
  235:         }
  236:         $r->print('</select>'."\n".
  237:                   '<input type="submit" name="statusbutton" value="'.
  238:                   $lt{'updi'}.'"><input type="hidden" name="sortby" value="'.
  239:                   $env{'form.sortby'}.'"/>'.
  240:                   '<input type="hidden" name="group" value="'.$group.'"/>');
  241:         if (exists($env{'form.ref'})) {
  242:             $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
  243:                       '" />');
  244:         }
  245:         $r->print('</form><br />');
  246: 
  247:     }
  248:     $r->print('<br />');
  249:     if (ref($numitems) eq 'HASH') {
  250:         foreach my $key (keys(%{$numitems})) {
  251:             if ($status eq $key && !$$numitems{$key}) {
  252:                 $r->print(&mt('There are no '.$gpterm.'s to display in this [_1].',
  253:                               lc($lt{$key})));
  254:                 return;
  255:             }
  256:         }
  257:     }
  258:     $r->print('
  259: <form name="grouproster" action="/adm/grouproster" method="post">
  260:  <input type="hidden" name="group" value="'.$group.'" />
  261:  <input type="hidden" name="sortby" value="'.$env{'form.sortby'}.'" />
  262:  <input type="hidden" name="status" value="'.$status.'" />
  263: ');
  264:     if (exists($env{'form.ref'})) {
  265:         $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
  266:                   '" />');
  267:     }
  268:     my %Sortby = ();
  269:     my $usercount = 0;
  270:     foreach my $user (sort(keys(%{$memberinfo}))) {
  271:         if ($env{'form.sortby'} eq 'fullname') {
  272:             push(@{$Sortby{$$memberinfo{$user}{fullname}}},$user);
  273:         } elsif ($env{'form.sortby'} eq 'username') {
  274:             push(@{$Sortby{$$memberinfo{$user}{uname}}},$user);
  275:         } elsif ($env{'form.sortby'} eq 'domain') {
  276:             push(@{$Sortby{$$memberinfo{$user}{udom}}},$user);
  277:         } elsif ($env{'form.sortby'} eq 'id') {
  278:             push(@{$Sortby{$$memberinfo{$user}{id}}},$user);
  279:         } else {
  280:             push(@{$Sortby{$$memberinfo{$user}{fullname}}},$user);
  281:         }
  282:     }
  283:     $r->print(&Apache::loncommon::start_data_table());
  284:     $r->print(&members_table_header_row(\%lt,$viewgrps,$editgrps,$view_details,
  285:                                         $hastools));
  286:     foreach my $key (sort(keys(%Sortby))) {
  287:         foreach my $user (@{$Sortby{$key}}) {
  288:             if (($status eq 'all') || 
  289:                 ($status eq $$memberinfo{$user}{status})) {
  290:                 $r->print(&members_table_row($viewgrps,$editgrps,$view_details,
  291:                           $hastools,\%tooltype,$toolprivs,$$memberinfo{$user}));
  292:             }
  293:         }
  294:     }
  295:     $r->print(&Apache::loncommon::end_data_table());
  296:     $r->print('</form>');
  297:     return;
  298: }
  299: 
  300: sub members_table_header_row {
  301:     my ($lt,$viewgrps,$editgrps,$view_details,$hastools) = @_; 
  302:     my $output = &Apache::loncommon::start_data_table_header_row();
  303:     $output .= "<th><a href=\"javascript:changeSort('fullname')\">".
  304:               "$$lt{'name'}</a></th>";
  305:     if ($viewgrps || $editgrps || $view_details ) {
  306:         $output .= "<th><a href=\"javascript:changeSort('username')\">$$lt{'usnm'}</a></th>";
  307:         $output .= "<th><a href=\"javascript:changeSort('domain')\">$$lt{'doma'}</a></th>";
  308:     }
  309:     if ($viewgrps || $editgrps) {
  310:         $output .= "<th><a href=\"javascript:changeSort('id')\">$$lt{'stid'}</a></th>";
  311:     }
  312:     if ($viewgrps || $editgrps || $view_details ) {
  313:         $output .= "<th><a href=\"javascript:changeSort('start')\">$$lt{'stda'}</a></th>";
  314:         $output .= "<th><a href=\"javascript:changeSort('end')\">$$lt{'enda'}</a></th>";
  315:         if ($hastools) {
  316:             if ($viewgrps || $editgrps) {
  317:                 $output .= '<th><b>'.$$lt{'priv'}.'</b></th>';
  318:             } elsif ($view_details) {
  319:                 $output .= '<th><b>'.$$lt{'func'}.'</b></th>';
  320:             }
  321:         }
  322:     }
  323:     $output .= &Apache::loncommon::end_data_table_header_row();
  324:     return $output;
  325: }
  326: 
  327: sub members_table_row {
  328:     my ($viewgrps,$editgrps,$view_details,$hastools,$tooltype,$toolprivs,
  329:         $userinfo) = @_;
  330:     my $output = &Apache::loncommon::start_data_table_row();
  331:     $output .= '<td>'.&Apache::loncommon::aboutmewrapper($$userinfo{'fullname'},
  332:                       $$userinfo{'uname'},$$userinfo{'udom'}  ).
  333:                '</td>';
  334:     if ($viewgrps || $editgrps || $view_details ) {
  335:         $output .= '<td>'.$$userinfo{'uname'}.'</td>';
  336:         $output .= '<td>'.$$userinfo{'udom'}.'</td>';
  337:     }
  338:     if ($viewgrps || $editgrps) {
  339:         $output .= '<td>'.$$userinfo{'id'}.'</td>';
  340:     }
  341:     if ($viewgrps || $editgrps || $view_details) {
  342:         $output .= '<td>'.$$userinfo{'start'}.'</td>';
  343:         $output .= '<td>'.$$userinfo{'end'}.'</td>';
  344:     }
  345:     if ($hastools) {
  346:         if ($viewgrps || $editgrps) {
  347:             my $curr_tool;
  348:             my $privlist;
  349:             foreach my $priv (@{$$userinfo{'privs'}}) {
  350:                 if (defined($$tooltype{$priv})) {
  351:                     if ($curr_tool ne $$tooltype{$priv}) {
  352:                         $curr_tool = $$tooltype{$priv};
  353:                         $privlist .= '<b>'.$curr_tool.'</b>: ';
  354:                     }
  355:                     $privlist .= $$toolprivs{$curr_tool}{$priv}.', ';
  356:                 }
  357:             }
  358:             $privlist =~ s/, $//;
  359:             $output .= '<td>'.$privlist.'</td>';
  360:         } elsif ($view_details) {
  361:             $output .= '<td><span class="LC_nobreak">'.join('&nbsp;&nbsp;&nbsp;',
  362:                       @{$$userinfo{'currtools'}}).'</span></td>';
  363:         }
  364:     }
  365:     $output .= &Apache::loncommon::end_data_table_row();
  366:     return $output;
  367: }
  368: 
  369: 1;
  370: 

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