Annotation of loncom/interface/grouproster.pm, revision 1.9
1.1 raeburn 1: # The LearningOnline Network with CAPA
2: #
1.9 ! droeschl 3: # $Id: grouproster.pm,v 1.8 2009/02/13 17:20:29 bisitz 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.2 raeburn 36: use LONCAPA;
1.1 raeburn 37: use Apache::Constants qw(:common :http);
38: use lib '/home/httpd/lib/perl/';
39:
40: sub handler {
41: my ($r) = @_;
42: &Apache::loncommon::content_type($r,'text/html');
43: $r->send_http_header;
44:
45: if ($r->header_only) {
46: return OK;
47: }
48:
49: # Needs to be in a course
50: if (! ($env{'request.course.fn'})) {
51: # Not in a course
52: $env{'user.error.msg'}=
53: "/adm/coursegroups:mdg:0:0:Cannot edit or view course groups";
54: return HTTP_NOT_ACCEPTABLE;
55: }
56:
1.4 raeburn 57: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
58: ['group','ref','status']);
1.1 raeburn 59:
60: my $gpterm = &Apache::loncommon::group_term();
61: my $ucgpterm = $gpterm;
62: $ucgpterm =~ s/^(\w)/uc($1)/e;
63: my $crstype = &Apache::loncommon::course_type();
64: my $group;
1.4 raeburn 65: my %curr_groups;
1.1 raeburn 66:
1.4 raeburn 67: # Validating group input.
68: my $badinput;
1.1 raeburn 69: if ((!defined($env{'form.group'})) || ($env{'form.group'} eq '')) {
1.5 bisitz 70: $r->print(&mt('No group name provided.').'<br />');
1.4 raeburn 71: $badinput = 1;
1.1 raeburn 72: } else {
73: $group = $env{'form.group'};
74: $group =~ s/\W//g;
75: }
1.4 raeburn 76: if (!$badinput && $group eq '') {
1.5 bisitz 77: $r->print(&mt('Invalid group name provided.').'<br />');
1.4 raeburn 78: $badinput = 1;
1.1 raeburn 79: }
80:
81: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
82: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
83:
84: if ($cdom eq '' || $cnum eq '') {
1.5 bisitz 85: $r->print(&mt('Invalid [_1]',$crstype).'<br />');
1.4 raeburn 86: $badinput = 1;
1.1 raeburn 87: }
88:
1.4 raeburn 89: if (!$badinput) {
90: %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
91: if (!defined($curr_groups{$group})) {
92: $r->print(&mt('"[_1]" is not the name of a valid group in this [_2].',
93: $group,lc($crstype)));
94: $badinput = 1;
95: }
96: }
97: if ($badinput) {
1.2 raeburn 98: return OK;
1.4 raeburn 99: }
1.1 raeburn 100:
101: &Apache::lonhtmlcommon::clear_breadcrumbs();
102:
103: my $can_view = &Apache::lonnet::allowed('vgm',$env{'request.course.id'}.
104: '/'.$group);
105: my $view_details = &Apache::lonnet::allowed('vmd',$env{'request.course.id'}.'/'.$group);
106:
1.3 raeburn 107: my $viewgrps = &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
1.1 raeburn 108: my $editgrps = &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
109:
110: if ((!$can_view) && (!$view_details) && (!$viewgrps) && (!$editgrps)) {
1.5 bisitz 111: $r->print(&mt('You do not have privileges to view the membership roster in this '.$gpterm.'.'));
1.1 raeburn 112: return OK;
113: }
1.2 raeburn 114: my %content = &Apache::longroup::get_group_settings($curr_groups{$group});
1.1 raeburn 115: my $description = &unescape($content{'description'});
116: $r->print(&roster_header($cdom,$cnum,$group,$description,$gpterm,$ucgpterm));
117:
118: my $available;
119: foreach my $tool (sort(keys(%{$content{'functions'}}))) {
120: if ($content{functions}{$tool} eq 'on') {
121: push(@{$available},$tool);
122: }
123: }
124:
125: &roster_table($r,$cdom,$cnum,$group,$can_view,$view_details,$viewgrps,
126: $editgrps,$available,$gpterm,$ucgpterm);
127:
128: $r->print(&Apache::loncommon::end_page());
129: return OK;
130: }
131:
132: sub roster_header {
133: my ($cdom,$cnum,$group,$description,$gpterm,$ucgpterm) = @_;
1.3 raeburn 134: my $refarg;
1.4 raeburn 135: if (exists($env{'form.ref'}) && $env{'form.ref'} ne 'popup') {
1.3 raeburn 136: $refarg = 'ref='.$env{'form.ref'};
137: &Apache::lonhtmlcommon::add_breadcrumb
138: ({href=>"/adm/coursegroups",
139: text=>"Groups",
140: title=>"View course groups"});
141: }
1.4 raeburn 142: my $args;
143: if ($env{'form.ref'} eq 'popup') {
1.9 ! droeschl 144: $args = { 'no_nav_bar' => 1, };
1.4 raeburn 145: }
1.1 raeburn 146: my $jscript = qq|
147: function changeSort(caller) {
148: document.grouproster.sortby.value = caller;
149: document.grouproster.submit();
150: }\n|;
1.4 raeburn 151: my $itemtitle = &mt('Group membership status - [_1]',$description);
1.1 raeburn 152: my $output =
1.4 raeburn 153: &Apache::loncommon::start_page('Group Membership',
1.1 raeburn 154: '<script type="text/javascript">'.
1.4 raeburn 155: $jscript.'</script>',$args);
156: if ($env{'form.ref'} eq 'popup') {
157: $output .= '<h3>'.&mt('Group membership status - [_1]',$description).
158: '</h3>';
159: } else {
160: &Apache::lonhtmlcommon::add_breadcrumb
161: ({href=>"/adm/$cdom/$cnum/$group/smppg?$refarg",
162: text=>"$ucgpterm: $description",
163: title=>"Go to group's home page"},
164: {href=>'/adm/grouproster?group='.$group.'&'.$refarg,
1.6 schafran 165: text=>"Membership Roster",
1.4 raeburn 166: title=>"Display group membership"},);
1.5 bisitz 167: $output .= &Apache::lonhtmlcommon::breadcrumbs(&mt($gpterm.' membership status - [_1]',$description));
1.4 raeburn 168: }
1.1 raeburn 169: return $output;
170: }
171:
172: sub roster_table {
173: my ($r,$cdom,$cnum,$group,$can_view,$view_details,$viewgrps,$editgrps,
174: $available,$gpterm,$ucgpterm) = @_;
175:
176: my $fixedprivs = &Apache::longroup::get_fixed_privs();
177:
1.3 raeburn 178: my ($memberinfo,$numitems,$hastools,$addtools) =
1.1 raeburn 179: &Apache::longroup::group_memberlist($cdom,$cnum,$group,$fixedprivs,
180: $available);
181: my (%tooltype,$toolprivs);
182:
183: if ($hastools) {
184: $toolprivs = &Apache::longroup::get_tool_privs($gpterm);
185: foreach my $tool (sort(keys(%{$toolprivs}))) {
186: foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
187: $tooltype{$priv} = $tool;
188: }
189: }
190: }
191:
192: my %lt = &Apache::lonlocal::texthash(
193: 'name' => 'Name',
194: 'usnm' => 'Username',
195: 'doma' => 'Domain',
196: 'stid' => 'ID',
197: 'stda' => 'Start Date',
198: 'enda' => 'End Date',
199: 'func' => 'Functionality',
200: 'priv' => 'Privileges',
201: 'all' => 'Any Membership status',
202: 'active' => 'Active Member',
203: 'previous' => 'Former Member',
204: 'future' => 'Future Member',
205: 'updi' => 'Update Display',
206: );
207: my $status = $env{'form.status'};
208: if (!defined($status)) {
209: $status = 'active';
210: }
211: if (($viewgrps) || ($editgrps) ||
212: (&Apache::lonnet::allowed('vmd',$env{'request.course.id'}.'/'.$group))) {
213: if (keys(%{$memberinfo}) == 0) {
1.5 bisitz 214: $r->print(&mt('There are no membership data to display for this '.$gpterm.'.'));
1.1 raeburn 215: return;
216: }
217: $r->print('<br /><form name="rosterstatus" method="post" action="/adm/grouproster">'.&mt('Membership status: ').'<select name="status">');
218: foreach my $type ('active','previous','future','all') {
219: $r->print('<option value="'.$type.'" ');
220: if ($status eq $type) {
221: $r->print('selected="selected"');
222: }
223: $r->print('>'.$lt{$type}.'</option>');
224: }
225: $r->print('</select>'."\n".
226: '<input type="submit" name="statusbutton" value="'.
227: $lt{'updi'}.'"><input type="hidden" name="sortby" value="'.
228: $env{'form.sortby'}.'"/>'.
1.3 raeburn 229: '<input type="hidden" name="group" value="'.$group.'"/>');
230: if (exists($env{'form.ref'})) {
231: $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
232: '" />');
233: }
1.4 raeburn 234: $r->print('</form><br />');
1.1 raeburn 235:
236: }
1.4 raeburn 237: $r->print('<br />');
1.1 raeburn 238: if (ref($numitems) eq 'HASH') {
239: foreach my $key (keys(%{$numitems})) {
240: if ($status eq $key && !$$numitems{$key}) {
1.5 bisitz 241: $r->print(&mt('There are no '.$gpterm.'s to display in this [_1].',
242: lc($lt{$key})));
1.1 raeburn 243: return;
244: }
245: }
246: }
247: $r->print('
248: <form name="grouproster" action="/adm/grouproster" method="post">
249: <input type="hidden" name="group" value="'.$group.'" />
250: <input type="hidden" name="sortby" value="'.$env{'form.sortby'}.'" />
1.4 raeburn 251: <input type="hidden" name="status" value="'.$status.'" />
1.1 raeburn 252: ');
1.3 raeburn 253: if (exists($env{'form.ref'})) {
254: $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
255: '" />');
256: }
1.1 raeburn 257: my %Sortby = ();
258: my $usercount = 0;
259: foreach my $user (sort(keys(%{$memberinfo}))) {
260: if ($env{'form.sortby'} eq 'fullname') {
261: push(@{$Sortby{$$memberinfo{$user}{fullname}}},$user);
262: } elsif ($env{'form.sortby'} eq 'username') {
263: push(@{$Sortby{$$memberinfo{$user}{uname}}},$user);
264: } elsif ($env{'form.sortby'} eq 'domain') {
265: push(@{$Sortby{$$memberinfo{$user}{udom}}},$user);
266: } elsif ($env{'form.sortby'} eq 'id') {
267: push(@{$Sortby{$$memberinfo{$user}{id}}},$user);
268: } else {
269: push(@{$Sortby{$$memberinfo{$user}{fullname}}},$user);
270: }
271: }
272: $r->print(&Apache::loncommon::start_data_table());
273: $r->print(&members_table_header_row(\%lt,$viewgrps,$editgrps,$view_details,
274: $hastools));
275: foreach my $key (sort(keys(%Sortby))) {
276: foreach my $user (@{$Sortby{$key}}) {
277: if (($status eq 'all') ||
278: ($status eq $$memberinfo{$user}{status})) {
279: $r->print(&members_table_row($viewgrps,$editgrps,$view_details,
280: $hastools,\%tooltype,$toolprivs,$$memberinfo{$user}));
281: }
282: }
283: }
284: $r->print(&Apache::loncommon::end_data_table());
285: $r->print('</form>');
286: return;
287: }
288:
289: sub members_table_header_row {
290: my ($lt,$viewgrps,$editgrps,$view_details,$hastools) = @_;
291: my $output = &Apache::loncommon::start_data_table_header_row();
292: $output .= "<th><a href=\"javascript:changeSort('fullname')\">".
293: "$$lt{'name'}</a></th>";
294: if ($viewgrps || $editgrps || $view_details ) {
295: $output .= "<th><a href=\"javascript:changeSort('username')\">$$lt{'usnm'}</a></th>";
296: $output .= "<th><a href=\"javascript:changeSort('domain')\">$$lt{'doma'}</a></th>";
297: }
298: if ($viewgrps || $editgrps) {
299: $output .= "<th><a href=\"javascript:changeSort('id')\">$$lt{'stid'}</a></th>";
300: }
301: if ($viewgrps || $editgrps || $view_details ) {
302: $output .= "<th><a href=\"javascript:changeSort('start')\">$$lt{'stda'}</a></th>";
303: $output .= "<th><a href=\"javascript:changeSort('end')\">$$lt{'enda'}</a></th>";
304: if ($hastools) {
305: if ($viewgrps || $editgrps) {
306: $output .= '<th><b>'.$$lt{'priv'}.'</b></th>';
307: } elsif ($view_details) {
308: $output .= '<th><b>'.$$lt{'func'}.'</b></th>';
309: }
310: }
311: }
312: $output .= &Apache::loncommon::end_data_table_header_row();
313: return $output;
314: }
315:
316: sub members_table_row {
317: my ($viewgrps,$editgrps,$view_details,$hastools,$tooltype,$toolprivs,
318: $userinfo) = @_;
319: my $output = &Apache::loncommon::start_data_table_row();
320: $output .= '<td>'.&Apache::loncommon::aboutmewrapper($$userinfo{'fullname'},
321: $$userinfo{'uname'},$$userinfo{'udom'} ).
322: '</td>';
323: if ($viewgrps || $editgrps || $view_details ) {
324: $output .= '<td>'.$$userinfo{'uname'}.'</td>';
325: $output .= '<td>'.$$userinfo{'udom'}.'</td>';
326: }
327: if ($viewgrps || $editgrps) {
328: $output .= '<td>'.$$userinfo{'id'}.'</td>';
329: }
330: if ($viewgrps || $editgrps || $view_details) {
331: $output .= '<td>'.$$userinfo{'start'}.'</td>';
332: $output .= '<td>'.$$userinfo{'end'}.'</td>';
333: }
334: if ($hastools) {
335: if ($viewgrps || $editgrps) {
336: my $curr_tool;
337: my $privlist;
338: foreach my $priv (@{$$userinfo{'privs'}}) {
1.4 raeburn 339: if (defined($$tooltype{$priv})) {
340: if ($curr_tool ne $$tooltype{$priv}) {
341: $curr_tool = $$tooltype{$priv};
342: $privlist .= '<b>'.$curr_tool.'</b>: ';
343: }
344: $privlist .= $$toolprivs{$curr_tool}{$priv}.', ';
1.1 raeburn 345: }
346: }
347: $privlist =~ s/, $//;
348: $output .= '<td>'.$privlist.'</td>';
349: } elsif ($view_details) {
1.7 bisitz 350: $output .= '<td><span class="LC_nobreak">'.join(' ',
351: @{$$userinfo{'currtools'}}).'</span></td>';
1.1 raeburn 352: }
353: }
354: $output .= &Apache::loncommon::end_data_table_row();
355: return $output;
356: }
357:
358: 1;
359:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>