File:
[LON-CAPA] /
loncom /
interface /
grouproster.pm
Revision
1.4:
download - view:
text,
annotated -
select for diffs
Thu Aug 17 23:36:05 2006 UTC (18 years ago) by
raeburn
Branches:
MAIN
CVS tags:
version_2_6_X,
version_2_6_3,
version_2_6_2,
version_2_6_1,
version_2_6_0,
version_2_5_X,
version_2_5_99_1,
version_2_5_99_0,
version_2_5_2,
version_2_5_1,
version_2_5_0,
version_2_4_X,
version_2_4_99_0,
version_2_4_2,
version_2_4_1,
version_2_4_0,
version_2_3_X,
version_2_3_99_0,
version_2_3_2,
version_2_3_1,
version_2_3_0,
version_2_2_X,
version_2_2_99_1,
version_2_2_99_0,
version_2_2_2,
version_2_2_1,
version_2_2_0,
HEAD
loncommon::start_page() does its own &mt(). Current status type should be retained when changing sorting used in roster display. Roster can be displayed in a pop-up window. Links provided to open pop-up window in table listing course groups, where membership > 0. Membership roster now available (via popup) to users with mdg or vcg privilege in cases where membership roster is not enbled in the group.
1: # The LearningOnline Network with CAPA
2: #
3: # Copyright Michigan State University Board of Trustees
4: #
5: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
6: #
7: # LON-CAPA is free software; you can redistribute it and/or modify
8: # it under the terms of the GNU General Public License as published by
9: # the Free Software Foundation; either version 2 of the License, or
10: # (at your option) any later version.
11: #
12: # LON-CAPA is distributed in the hope that it will be useful,
13: # but WITHOUT ANY WARRANTY; without even the implied warranty of
14: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: # GNU General Public License for more details.
16: #
17: # You should have received a copy of the GNU General Public License
18: # along with LON-CAPA; if not, write to the Free Software
19: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20: #
21: # /home/httpd/html/adm/gpl.txt
22: #
23: # http://www.lon-capa.org/
24: #
25:
26: package Apache::grouproster;
27:
28: use strict;
29: use Apache::lonnet;
30: use Apache::loncommon;
31: use Apache::lonhtmlcommon;
32: use Apache::lonlocal;
33: use Apache::longroup;
34: use LONCAPA;
35: use Apache::Constants qw(:common :http);
36: use lib '/home/httpd/lib/perl/';
37:
38: sub handler {
39: my ($r) = @_;
40: &Apache::loncommon::content_type($r,'text/html');
41: $r->send_http_header;
42:
43: if ($r->header_only) {
44: return OK;
45: }
46:
47: # Needs to be in a course
48: if (! ($env{'request.course.fn'})) {
49: # Not in a course
50: $env{'user.error.msg'}=
51: "/adm/coursegroups:mdg:0:0:Cannot edit or view course groups";
52: return HTTP_NOT_ACCEPTABLE;
53: }
54:
55: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
56: ['group','ref','status']);
57:
58: my $gpterm = &Apache::loncommon::group_term();
59: my $ucgpterm = $gpterm;
60: $ucgpterm =~ s/^(\w)/uc($1)/e;
61: my $crstype = &Apache::loncommon::course_type();
62: my $group;
63: my %curr_groups;
64:
65: # Validating group input.
66: my $badinput;
67: if ((!defined($env{'form.group'})) || ($env{'form.group'} eq '')) {
68: $r->print(&mt('No group name provided.<br />'));
69: $badinput = 1;
70: } else {
71: $group = $env{'form.group'};
72: $group =~ s/\W//g;
73: }
74: if (!$badinput && $group eq '') {
75: $r->print(&mt('Invalid group name provided.<br />'));
76: $badinput = 1;
77: }
78:
79: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
80: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
81:
82: if ($cdom eq '' || $cnum eq '') {
83: $r->print(&mt('Invalid [_1]<br />',$crstype));
84: $badinput = 1;
85: }
86:
87: if (!$badinput) {
88: %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
89: if (!defined($curr_groups{$group})) {
90: $r->print(&mt('"[_1]" is not the name of a valid group in this [_2].',
91: $group,lc($crstype)));
92: $badinput = 1;
93: }
94: }
95: if ($badinput) {
96: return OK;
97: }
98:
99: &Apache::lonhtmlcommon::clear_breadcrumbs();
100:
101: my $can_view = &Apache::lonnet::allowed('vgm',$env{'request.course.id'}.
102: '/'.$group);
103: my $view_details = &Apache::lonnet::allowed('vmd',$env{'request.course.id'}.'/'.$group);
104:
105: my $viewgrps = &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
106: my $editgrps = &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
107:
108: if ((!$can_view) && (!$view_details) && (!$viewgrps) && (!$editgrps)) {
109: $r->print(&mt('You do not have privileges to view the membership roster in this [_1]',$gpterm));
110: return OK;
111: }
112: my %content = &Apache::longroup::get_group_settings($curr_groups{$group});
113: my $description = &unescape($content{'description'});
114: $r->print(&roster_header($cdom,$cnum,$group,$description,$gpterm,$ucgpterm));
115:
116: my $available;
117: foreach my $tool (sort(keys(%{$content{'functions'}}))) {
118: if ($content{functions}{$tool} eq 'on') {
119: push(@{$available},$tool);
120: }
121: }
122:
123: &roster_table($r,$cdom,$cnum,$group,$can_view,$view_details,$viewgrps,
124: $editgrps,$available,$gpterm,$ucgpterm);
125:
126: $r->print(&Apache::loncommon::end_page());
127: return OK;
128: }
129:
130: sub roster_header {
131: my ($cdom,$cnum,$group,$description,$gpterm,$ucgpterm) = @_;
132: my $refarg;
133: if (exists($env{'form.ref'}) && $env{'form.ref'} ne 'popup') {
134: $refarg = 'ref='.$env{'form.ref'};
135: &Apache::lonhtmlcommon::add_breadcrumb
136: ({href=>"/adm/coursegroups",
137: text=>"Groups",
138: title=>"View course groups"});
139: }
140: my $args;
141: if ($env{'form.ref'} eq 'popup') {
142: $args = {
143: 'no_nav_bar' => 1,
144: 'no_inline_link' => 1,
145: };
146: }
147: my $jscript = qq|
148: function changeSort(caller) {
149: document.grouproster.sortby.value = caller;
150: document.grouproster.submit();
151: }\n|;
152: my $itemtitle = &mt('Group membership status - [_1]',$description);
153: my $output =
154: &Apache::loncommon::start_page('Group Membership',
155: '<script type="text/javascript">'.
156: $jscript.'</script>',$args);
157: if ($env{'form.ref'} eq 'popup') {
158: $output .= '<h3>'.&mt('Group membership status - [_1]',$description).
159: '</h3>';
160: } else {
161: &Apache::lonhtmlcommon::add_breadcrumb
162: ({href=>"/adm/$cdom/$cnum/$group/smppg?$refarg",
163: text=>"$ucgpterm: $description",
164: title=>"Go to group's home page"},
165: {href=>'/adm/grouproster?group='.$group.'&'.$refarg,
166: text=>"Membership roster",
167: title=>"Display group membership"},);
168: $output .= &Apache::lonhtmlcommon::breadcrumbs(&mt('[_1] membership status - [_2]',$gpterm,$description));
169: }
170: return $output;
171: }
172:
173: sub roster_table {
174: my ($r,$cdom,$cnum,$group,$can_view,$view_details,$viewgrps,$editgrps,
175: $available,$gpterm,$ucgpterm) = @_;
176:
177: my $fixedprivs = &Apache::longroup::get_fixed_privs();
178:
179: my ($memberinfo,$numitems,$hastools,$addtools) =
180: &Apache::longroup::group_memberlist($cdom,$cnum,$group,$fixedprivs,
181: $available);
182: my (%tooltype,$toolprivs);
183:
184: if ($hastools) {
185: $toolprivs = &Apache::longroup::get_tool_privs($gpterm);
186: foreach my $tool (sort(keys(%{$toolprivs}))) {
187: foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
188: $tooltype{$priv} = $tool;
189: }
190: }
191: }
192:
193: my %lt = &Apache::lonlocal::texthash(
194: 'name' => 'Name',
195: 'usnm' => 'Username',
196: 'doma' => 'Domain',
197: 'stid' => 'ID',
198: 'stda' => 'Start Date',
199: 'enda' => 'End Date',
200: 'func' => 'Functionality',
201: 'priv' => 'Privileges',
202: 'all' => 'Any Membership status',
203: 'active' => 'Active Member',
204: 'previous' => 'Former Member',
205: 'future' => 'Future Member',
206: 'updi' => 'Update Display',
207: );
208: my $status = $env{'form.status'};
209: if (!defined($status)) {
210: $status = 'active';
211: }
212: if (($viewgrps) || ($editgrps) ||
213: (&Apache::lonnet::allowed('vmd',$env{'request.course.id'}.'/'.$group))) {
214: if (keys(%{$memberinfo}) == 0) {
215: $r->print(&mt('There are no membership data to display for this [_1]',
216: $gpterm));
217: return;
218: }
219: $r->print('<br /><form name="rosterstatus" method="post" action="/adm/grouproster">'.&mt('Membership status: ').'<select name="status">');
220: foreach my $type ('active','previous','future','all') {
221: $r->print('<option value="'.$type.'" ');
222: if ($status eq $type) {
223: $r->print('selected="selected"');
224: }
225: $r->print('>'.$lt{$type}.'</option>');
226: }
227: $r->print('</select>'."\n".
228: '<input type="submit" name="statusbutton" value="'.
229: $lt{'updi'}.'"><input type="hidden" name="sortby" value="'.
230: $env{'form.sortby'}.'"/>'.
231: '<input type="hidden" name="group" value="'.$group.'"/>');
232: if (exists($env{'form.ref'})) {
233: $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
234: '" />');
235: }
236: $r->print('</form><br />');
237:
238: }
239: $r->print('<br />');
240: if (ref($numitems) eq 'HASH') {
241: foreach my $key (keys(%{$numitems})) {
242: if ($status eq $key && !$$numitems{$key}) {
243: $r->print(&mt('There are no [_1]s to display in this [_2].',
244: lc($lt{$key}),$gpterm));
245: return;
246: }
247: }
248: }
249: $r->print('
250: <form name="grouproster" action="/adm/grouproster" method="post">
251: <input type="hidden" name="group" value="'.$group.'" />
252: <input type="hidden" name="sortby" value="'.$env{'form.sortby'}.'" />
253: <input type="hidden" name="status" value="'.$status.'" />
254: ');
255: if (exists($env{'form.ref'})) {
256: $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.
257: '" />');
258: }
259: my %Sortby = ();
260: my $usercount = 0;
261: foreach my $user (sort(keys(%{$memberinfo}))) {
262: if ($env{'form.sortby'} eq 'fullname') {
263: push(@{$Sortby{$$memberinfo{$user}{fullname}}},$user);
264: } elsif ($env{'form.sortby'} eq 'username') {
265: push(@{$Sortby{$$memberinfo{$user}{uname}}},$user);
266: } elsif ($env{'form.sortby'} eq 'domain') {
267: push(@{$Sortby{$$memberinfo{$user}{udom}}},$user);
268: } elsif ($env{'form.sortby'} eq 'id') {
269: push(@{$Sortby{$$memberinfo{$user}{id}}},$user);
270: } else {
271: push(@{$Sortby{$$memberinfo{$user}{fullname}}},$user);
272: }
273: }
274: $r->print(&Apache::loncommon::start_data_table());
275: $r->print(&members_table_header_row(\%lt,$viewgrps,$editgrps,$view_details,
276: $hastools));
277: foreach my $key (sort(keys(%Sortby))) {
278: foreach my $user (@{$Sortby{$key}}) {
279: if (($status eq 'all') ||
280: ($status eq $$memberinfo{$user}{status})) {
281: $r->print(&members_table_row($viewgrps,$editgrps,$view_details,
282: $hastools,\%tooltype,$toolprivs,$$memberinfo{$user}));
283: }
284: }
285: }
286: $r->print(&Apache::loncommon::end_data_table());
287: $r->print('</form>');
288: return;
289: }
290:
291: sub members_table_header_row {
292: my ($lt,$viewgrps,$editgrps,$view_details,$hastools) = @_;
293: my $output = &Apache::loncommon::start_data_table_header_row();
294: $output .= "<th><a href=\"javascript:changeSort('fullname')\">".
295: "$$lt{'name'}</a></th>";
296: if ($viewgrps || $editgrps || $view_details ) {
297: $output .= "<th><a href=\"javascript:changeSort('username')\">$$lt{'usnm'}</a></th>";
298: $output .= "<th><a href=\"javascript:changeSort('domain')\">$$lt{'doma'}</a></th>";
299: }
300: if ($viewgrps || $editgrps) {
301: $output .= "<th><a href=\"javascript:changeSort('id')\">$$lt{'stid'}</a></th>";
302: }
303: if ($viewgrps || $editgrps || $view_details ) {
304: $output .= "<th><a href=\"javascript:changeSort('start')\">$$lt{'stda'}</a></th>";
305: $output .= "<th><a href=\"javascript:changeSort('end')\">$$lt{'enda'}</a></th>";
306: if ($hastools) {
307: if ($viewgrps || $editgrps) {
308: $output .= '<th><b>'.$$lt{'priv'}.'</b></th>';
309: } elsif ($view_details) {
310: $output .= '<th><b>'.$$lt{'func'}.'</b></th>';
311: }
312: }
313: }
314: $output .= &Apache::loncommon::end_data_table_header_row();
315: return $output;
316: }
317:
318: sub members_table_row {
319: my ($viewgrps,$editgrps,$view_details,$hastools,$tooltype,$toolprivs,
320: $userinfo) = @_;
321: my $output = &Apache::loncommon::start_data_table_row();
322: $output .= '<td>'.&Apache::loncommon::aboutmewrapper($$userinfo{'fullname'},
323: $$userinfo{'uname'},$$userinfo{'udom'} ).
324: '</td>';
325: if ($viewgrps || $editgrps || $view_details ) {
326: $output .= '<td>'.$$userinfo{'uname'}.'</td>';
327: $output .= '<td>'.$$userinfo{'udom'}.'</td>';
328: }
329: if ($viewgrps || $editgrps) {
330: $output .= '<td>'.$$userinfo{'id'}.'</td>';
331: }
332: if ($viewgrps || $editgrps || $view_details) {
333: $output .= '<td>'.$$userinfo{'start'}.'</td>';
334: $output .= '<td>'.$$userinfo{'end'}.'</td>';
335: }
336: if ($hastools) {
337: if ($viewgrps || $editgrps) {
338: my $curr_tool;
339: my $privlist;
340: foreach my $priv (@{$$userinfo{'privs'}}) {
341: if (defined($$tooltype{$priv})) {
342: if ($curr_tool ne $$tooltype{$priv}) {
343: $curr_tool = $$tooltype{$priv};
344: $privlist .= '<b>'.$curr_tool.'</b>: ';
345: }
346: $privlist .= $$toolprivs{$curr_tool}{$priv}.', ';
347: }
348: }
349: $privlist =~ s/, $//;
350: $output .= '<td>'.$privlist.'</td>';
351: } elsif ($view_details) {
352: $output .= '<td><nobr>'.join(' ',
353: @{$$userinfo{'currtools'}}).'</nobr></td>';
354: }
355: }
356: $output .= &Apache::loncommon::end_data_table_row();
357: return $output;
358: }
359:
360: 1;
361:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>