# The LearningOnline Network with CAPA
#
# $Id: grouproster.pm,v 1.11 2020/09/08 23:54:40 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
package Apache::grouproster;
use strict;
use Apache::lonnet;
use Apache::loncommon;
use Apache::lonhtmlcommon;
use Apache::lonlocal;
use Apache::longroup;
use Apache::lonnavmaps;
use LONCAPA;
use Apache::Constants qw(:common :http);
use lib '/home/httpd/lib/perl/';
sub handler {
my ($r) = @_;
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
if ($r->header_only) {
return OK;
}
# Needs to be in a course
if (! ($env{'request.course.fn'})) {
# Not in a course
$env{'user.error.msg'}=
"/adm/coursegroups:mdg:0:0:Cannot edit or view course groups";
return HTTP_NOT_ACCEPTABLE;
}
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
['group','ref','status']);
my $gpterm = &Apache::loncommon::group_term();
my $ucgpterm = $gpterm;
$ucgpterm =~ s/^(\w)/uc($1)/e;
my $crstype = &Apache::loncommon::course_type();
my $group;
my %curr_groups;
# Validating group input.
my $badinput;
if ((!defined($env{'form.group'})) || ($env{'form.group'} eq '')) {
$r->print(&mt('No group name provided.').'<br />');
$badinput = 1;
} else {
$group = $env{'form.group'};
$group =~ s/\W//g;
}
if (!$badinput && $group eq '') {
$r->print(&mt('Invalid group name provided.').'<br />');
$badinput = 1;
}
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
if ($cdom eq '' || $cnum eq '') {
$r->print(&mt('Invalid [_1]',$crstype).'<br />');
$badinput = 1;
}
if (!$badinput) {
%curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
if (!defined($curr_groups{$group})) {
$r->print(&mt('"[_1]" is not the name of a valid group in this [_2].',
$group,lc($crstype)));
$badinput = 1;
}
}
if ($badinput) {
return OK;
}
&Apache::lonhtmlcommon::clear_breadcrumbs();
my $can_view = &Apache::lonnet::allowed('vgm',$env{'request.course.id'}.
'/'.$group);
my $view_details = &Apache::lonnet::allowed('vmd',$env{'request.course.id'}.'/'.$group);
my $viewgrps = &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
my $editgrps = &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
if ((!$can_view) && (!$view_details) && (!$viewgrps) && (!$editgrps)) {
$r->print(&mt('You do not have privileges to view the membership roster in this '.$gpterm.'.'));
return OK;
}
my %content = &Apache::longroup::get_group_settings($curr_groups{$group});
my $description = &unescape($content{'description'});
$r->print(&roster_header($cdom,$cnum,$group,$description,$gpterm,$ucgpterm));
my $available;
foreach my $tool (sort(keys(%{$content{'functions'}}))) {
if ($content{functions}{$tool} eq 'on') {
push(@{$available},$tool);
}
}
&roster_table($r,$cdom,$cnum,$group,$can_view,$view_details,$viewgrps,
$editgrps,$available,$gpterm,$ucgpterm);
$r->print(&Apache::loncommon::end_page());
return OK;
}
sub roster_header {
my ($cdom,$cnum,$group,$description,$gpterm,$ucgpterm) = @_;
my $refarg;
if (exists($env{'form.ref'}) && $env{'form.ref'} ne 'popup') {
$refarg = 'ref='.$env{'form.ref'};
&Apache::lonhtmlcommon::add_breadcrumb
({href=>"/adm/coursegroups",
text=>"Groups",
title=>"View course groups"});
}
my $args;
if ($env{'form.ref'} eq 'popup') {
$args = { 'no_nav_bar' => 1, };
}
my $jscript = qq|
function changeSort(caller) {
document.grouproster.sortby.value = caller;
document.grouproster.submit();
}\n|;
my $itemtitle = &mt('Group membership status - [_1]',$description);
my $output =
&Apache::loncommon::start_page('Group Membership',
'<script type="text/javascript">'.
$jscript.'</script>',$args);
if ($env{'form.ref'} eq 'popup') {
$output .= '<h3>'.&mt('Group membership status - [_1]',$description).
'</h3>';
} else {
my $view_permission =
&Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
my $navmap=Apache::lonnavmaps::navmap->new();
my $grouppagelink = &Apache::longroup::get_group_link($cdom,$cnum,$group,$navmap,$view_permission,$refarg);
if ($grouppagelink) {
&Apache::lonhtmlcommon::add_breadcrumb
({href=>$grouppagelink,
text=>&mt('Group').": $description",
title=>&mt("Go to group's home page"),
no_mt=>1},);
} else {
&Apache::lonhtmlcommon::add_breadcrumb
({text=>&mt('Group').": $description",
no_mt=>1});
}
&Apache::lonhtmlcommon::add_breadcrumb
({href=>'/adm/grouproster?group='.$group.'&'.$refarg,
text=>"Membership Roster",
title=>"Display group membership"},);
$output .= &Apache::lonhtmlcommon::breadcrumbs(&mt('Group membership status - [_1]',$description),
undef,undef,undef,undef,1);
}
return $output;
}
sub roster_table {
my ($r,$cdom,$cnum,$group,$can_view,$view_details,$viewgrps,$editgrps,
$available,$gpterm,$ucgpterm) = @_;
my $fixedprivs = &Apache::longroup::get_fixed_privs();
my ($memberinfo,$numitems,$hastools,$addtools) =
&Apache::longroup::group_memberlist($cdom,$cnum,$group,$fixedprivs,
$available);
my (%tooltype,$toolprivs);
if ($hastools) {
$toolprivs = &Apache::longroup::get_tool_privs($gpterm);
foreach my $tool (sort(keys(%{$toolprivs}))) {
foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
$tooltype{$priv} = $tool;
}
}
}
my %lt = &Apache::lonlocal::texthash(
'name' => 'Name',
'usnm' => 'Username',
'doma' => 'Domain',
'stid' => 'ID',
'stda' => 'Start Date',
'enda' => 'End Date',
'func' => 'Functionality',
'priv' => 'Privileges',
'all' => 'Any Membership status',
'active' => 'Active Member',
'previous' => 'Former Member',
'future' => 'Future Member',
'updi' => 'Update Display',
);
my $status = $env{'form.status'};
if (!defined($status)) {
$status = 'active';
}
if (($viewgrps) || ($editgrps) ||
(&Apache::lonnet::allowed('vmd',$env{'request.course.id'}.'/'.$group))) {
if (keys(%{$memberinfo}) == 0) {
$r->print(&mt('There are no membership data to display for this '.$gpterm.'.'));
return;
}
$r->print('<br /><form name="rosterstatus" method="post" action="/adm/grouproster">'.&mt('Membership status: ').'<select name="status">');
foreach my $type ('active','previous','future','all') {
$r->print('<option value="'.$type.'" ');
if ($status eq $type) {
$r->print('selected="selected"');
}
$r->print('>'.$lt{$type}.'</option>');
}
$r->print('</select>'."\n".
'<input type="submit" name="statusbutton" value="'.
$lt{'updi'}.'"><input type="hidden" name="sortby" value="'.
$env{'form.sortby'}.'"/>'.
'<input type="hidden" name="group" value="'.$group.'"/>');
if (exists($env{'form.ref'})) {
$r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
'" />');
}
$r->print('</form><br />');
}
$r->print('<br />');
if (ref($numitems) eq 'HASH') {
foreach my $key (keys(%{$numitems})) {
if ($status eq $key && !$$numitems{$key}) {
$r->print(&mt('There are no '.$gpterm.'s to display in this [_1].',
lc($lt{$key})));
return;
}
}
}
$r->print('
<form name="grouproster" action="/adm/grouproster" method="post">
<input type="hidden" name="group" value="'.$group.'" />
<input type="hidden" name="sortby" value="'.$env{'form.sortby'}.'" />
<input type="hidden" name="status" value="'.$status.'" />
');
if (exists($env{'form.ref'})) {
$r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
'" />');
}
my %Sortby = ();
my $usercount = 0;
foreach my $user (sort(keys(%{$memberinfo}))) {
if ($env{'form.sortby'} eq 'fullname') {
push(@{$Sortby{$$memberinfo{$user}{fullname}}},$user);
} elsif ($env{'form.sortby'} eq 'username') {
push(@{$Sortby{$$memberinfo{$user}{uname}}},$user);
} elsif ($env{'form.sortby'} eq 'domain') {
push(@{$Sortby{$$memberinfo{$user}{udom}}},$user);
} elsif ($env{'form.sortby'} eq 'id') {
push(@{$Sortby{$$memberinfo{$user}{id}}},$user);
} else {
push(@{$Sortby{$$memberinfo{$user}{fullname}}},$user);
}
}
$r->print(&Apache::loncommon::start_data_table());
$r->print(&members_table_header_row(\%lt,$viewgrps,$editgrps,$view_details,
$hastools));
foreach my $key (sort(keys(%Sortby))) {
foreach my $user (@{$Sortby{$key}}) {
if (($status eq 'all') ||
($status eq $$memberinfo{$user}{status})) {
$r->print(&members_table_row($viewgrps,$editgrps,$view_details,
$hastools,\%tooltype,$toolprivs,$$memberinfo{$user}));
}
}
}
$r->print(&Apache::loncommon::end_data_table());
$r->print('</form>');
return;
}
sub members_table_header_row {
my ($lt,$viewgrps,$editgrps,$view_details,$hastools) = @_;
my $output = &Apache::loncommon::start_data_table_header_row();
$output .= "<th><a href=\"javascript:changeSort('fullname')\">".
"$$lt{'name'}</a></th>";
if ($viewgrps || $editgrps || $view_details ) {
$output .= "<th><a href=\"javascript:changeSort('username')\">$$lt{'usnm'}</a></th>";
$output .= "<th><a href=\"javascript:changeSort('domain')\">$$lt{'doma'}</a></th>";
}
if ($viewgrps || $editgrps) {
$output .= "<th><a href=\"javascript:changeSort('id')\">$$lt{'stid'}</a></th>";
}
if ($viewgrps || $editgrps || $view_details ) {
$output .= "<th><a href=\"javascript:changeSort('start')\">$$lt{'stda'}</a></th>";
$output .= "<th><a href=\"javascript:changeSort('end')\">$$lt{'enda'}</a></th>";
if ($hastools) {
if ($viewgrps || $editgrps) {
$output .= '<th><b>'.$$lt{'priv'}.'</b></th>';
} elsif ($view_details) {
$output .= '<th><b>'.$$lt{'func'}.'</b></th>';
}
}
}
$output .= &Apache::loncommon::end_data_table_header_row();
return $output;
}
sub members_table_row {
my ($viewgrps,$editgrps,$view_details,$hastools,$tooltype,$toolprivs,
$userinfo) = @_;
my $output = &Apache::loncommon::start_data_table_row();
$output .= '<td>'.&Apache::loncommon::aboutmewrapper($$userinfo{'fullname'},
$$userinfo{'uname'},$$userinfo{'udom'} ).
'</td>';
if ($viewgrps || $editgrps || $view_details ) {
$output .= '<td>'.$$userinfo{'uname'}.'</td>';
$output .= '<td>'.$$userinfo{'udom'}.'</td>';
}
if ($viewgrps || $editgrps) {
$output .= '<td>'.$$userinfo{'id'}.'</td>';
}
if ($viewgrps || $editgrps || $view_details) {
$output .= '<td>'.$$userinfo{'start'}.'</td>';
$output .= '<td>'.$$userinfo{'end'}.'</td>';
}
if ($hastools) {
if ($viewgrps || $editgrps) {
my $curr_tool;
my $privlist;
foreach my $priv (@{$$userinfo{'privs'}}) {
if (defined($$tooltype{$priv})) {
if ($curr_tool ne $$tooltype{$priv}) {
$curr_tool = $$tooltype{$priv};
$privlist .= '<b>'.$curr_tool.'</b>: ';
}
$privlist .= $$toolprivs{$curr_tool}{$priv}.', ';
}
}
$privlist =~ s/, $//;
$output .= '<td>'.$privlist.'</td>';
} elsif ($view_details) {
$output .= '<td><span class="LC_nobreak">'.join(' ',
@{$$userinfo{'currtools'}}).'</span></td>';
}
}
$output .= &Apache::loncommon::end_data_table_row();
return $output;
}
1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>