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