File:  [LON-CAPA] / loncom / interface / grouproster.pm
Revision 1.3: download - view: text, annotated - select for diffs
Mon Jul 17 15:07:26 2006 UTC (17 years, 9 months ago) by raeburn
Branches: MAIN
CVS tags: version_2_1_99_3, version_2_1_99_2, version_2_1_99_1, HEAD
Counts for active, future and previous now stored in a hash in longroup. Breadcrumbs includes link to all groups if route to roster page was via the 'Groups' link in inline menu.  Title of a group bulletin board can now be returned from longroup.pm for a specified board.  Priv checking for vcg and mdg for roles which include section specifier.  Group privs allow editing of group board posts by poster, and detailed view of course roster information.

# The LearningOnline Network with CAPA
#
# 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 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']); 

    my $gpterm  = &Apache::loncommon::group_term();
    my $ucgpterm = $gpterm;
    $ucgpterm =~ s/^(\w)/uc($1)/e;  
    my $crstype = &Apache::loncommon::course_type();
    my $group;

    if ((!defined($env{'form.group'})) || ($env{'form.group'} eq '')) {
        $r->print(&mt('No [_1] name provided',$gpterm));
                                                                                   
    } else {
        $group = $env{'form.group'};
        $group =~ s/\W//g;
    }
    if ($group eq '') {
        $r->print(&mt('Invalid [_1] name provided',$gpterm));
    }

    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));
    }

    my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
    if (!defined($curr_groups{$group})) {
        $r->print(&mt('[_1] is not the name of a valid [_2] in this [_3].',
                      $group,$gpterm,lc($crstype)));
        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 [_1]',$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'})) {
        $refarg = 'ref='.$env{'form.ref'};
        &Apache::lonhtmlcommon::add_breadcrumb
            ({href=>"/adm/coursegroups",
              text=>"Groups",
              title=>"View course groups"});
    }
    my $jscript = qq|
function changeSort(caller) {
    document.grouproster.sortby.value = caller;
    document.grouproster.submit();
}\n|;
    my $output =
        &Apache::loncommon::start_page(&mt('[_1] Membership ',$ucgpterm),
                                       '<script type="text/javascript">'.
                                       $jscript.'</script>');
    &Apache::lonhtmlcommon::add_breadcrumb
        ({href=>"/adm/$cdom/$cnum/$group/smppg?$refarg",
          text=>"$ucgpterm: $description",
          title=>"Go to group's home page"},
         {href=>'/adm/grouproster?group='.$group.'&amp;'.$refarg,
          text=>"Membership roster",
          title=>"Display group membership"},);
    $output .= &Apache::lonhtmlcommon::breadcrumbs(&mt('[_1] membership status - [_2]',$gpterm,$description));
    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 [_1]',
                      $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 /><br />');

    }
    if (ref($numitems) eq 'HASH') {
        foreach my $key (keys(%{$numitems})) {
            if ($status eq $key && !$$numitems{$key}) {
                $r->print(&mt('There are no [_1]s to display in this [_2].',
                              lc($lt{$key}),$gpterm));
                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'}.'" />
');
    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'}}) {
                unless ($curr_tool eq $$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><nobr>'.join('&nbsp;&nbsp;&nbsp;',
                      @{$$userinfo{'currtools'}}).'</nobr></td>';
        }
    }
    $output .= &Apache::loncommon::end_data_table_row();
    return $output;
}

1;


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