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