Annotation of loncom/interface/grouproster.pm, revision 1.10
1.1 raeburn 1: # The LearningOnline Network with CAPA
2: #
1.10 ! raeburn 3: # $Id: grouproster.pm,v 1.9 2010/03/22 20:11:22 droeschl 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.9 droeschl 145: $args = { 'no_nav_bar' => 1, };
1.4 raeburn 146: }
1.1 raeburn 147: my $jscript = qq|
148: function changeSort(caller) {
149: document.grouproster.sortby.value = caller;
150: document.grouproster.submit();
151: }\n|;
1.4 raeburn 152: my $itemtitle = &mt('Group membership status - [_1]',$description);
1.1 raeburn 153: my $output =
1.4 raeburn 154: &Apache::loncommon::start_page('Group Membership',
1.1 raeburn 155: '<script type="text/javascript">'.
1.4 raeburn 156: $jscript.'</script>',$args);
157: if ($env{'form.ref'} eq 'popup') {
158: $output .= '<h3>'.&mt('Group membership status - [_1]',$description).
159: '</h3>';
160: } else {
1.10 ! raeburn 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: }
1.4 raeburn 174: &Apache::lonhtmlcommon::add_breadcrumb
1.10 ! raeburn 175: ({href=>'/adm/grouproster?group='.$group.'&'.$refarg,
1.6 schafran 176: text=>"Membership Roster",
1.4 raeburn 177: title=>"Display group membership"},);
1.5 bisitz 178: $output .= &Apache::lonhtmlcommon::breadcrumbs(&mt($gpterm.' membership status - [_1]',$description));
1.4 raeburn 179: }
1.1 raeburn 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:
1.3 raeburn 189: my ($memberinfo,$numitems,$hastools,$addtools) =
1.1 raeburn 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) {
1.5 bisitz 225: $r->print(&mt('There are no membership data to display for this '.$gpterm.'.'));
1.1 raeburn 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'}.'"/>'.
1.3 raeburn 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: }
1.4 raeburn 245: $r->print('</form><br />');
1.1 raeburn 246:
247: }
1.4 raeburn 248: $r->print('<br />');
1.1 raeburn 249: if (ref($numitems) eq 'HASH') {
250: foreach my $key (keys(%{$numitems})) {
251: if ($status eq $key && !$$numitems{$key}) {
1.5 bisitz 252: $r->print(&mt('There are no '.$gpterm.'s to display in this [_1].',
253: lc($lt{$key})));
1.1 raeburn 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'}.'" />
1.4 raeburn 262: <input type="hidden" name="status" value="'.$status.'" />
1.1 raeburn 263: ');
1.3 raeburn 264: if (exists($env{'form.ref'})) {
265: $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
266: '" />');
267: }
1.1 raeburn 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'}}) {
1.4 raeburn 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}.', ';
1.1 raeburn 356: }
357: }
358: $privlist =~ s/, $//;
359: $output .= '<td>'.$privlist.'</td>';
360: } elsif ($view_details) {
1.7 bisitz 361: $output .= '<td><span class="LC_nobreak">'.join(' ',
362: @{$$userinfo{'currtools'}}).'</span></td>';
1.1 raeburn 363: }
364: }
365: $output .= &Apache::loncommon::end_data_table_row();
366: return $output;
367: }
368:
369: 1;
370:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>