Annotation of loncom/interface/loncoursegroups.pm, revision 1.4
1.1 raeburn 1: #
2: # Copyright Michigan State University Board of Trustees
3: #
4: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
5: #
6: # LON-CAPA is free software; you can redistribute it and/or modify
7: # it under the terms of the GNU General Public License as published by
8: # the Free Software Foundation; either version 2 of the License, or
9: # (at your option) any later version.
10: #
11: # LON-CAPA is distributed in the hope that it will be useful,
12: # but WITHOUT ANY WARRANTY; without even the implied warranty of
13: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: # GNU General Public License for more details.
15: #
16: # You should have received a copy of the GNU General Public License
17: # along with LON-CAPA; if not, write to the Free Software
18: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19: #
20: # /home/httpd/html/adm/gpl.txt
21: #
22: # http://www.lon-capa.org/
23: #
24:
25: package Apache::loncoursegroups;
26:
27: use strict;
28: use Apache::lonnet;
29: use Apache::loncommon;
30: use Apache::lonhtmlcommon;
31: use Apache::lonlocal;
1.3 raeburn 32: use Apache::lonnavmaps;
1.1 raeburn 33: use Apache::Constants qw(:common :http);
34:
35: sub handler {
36: my ($r) = @_;
1.3 raeburn 37:
1.1 raeburn 38: &Apache::loncommon::content_type($r,'text/html');
39: $r->send_http_header;
40:
41: if ($r->header_only) {
42: return OK;
43: }
44:
45: # Needs to be in a course
46: if (! ($env{'request.course.fn'})) {
47: # Not in a course
48: $env{'user.error.msg'}=
1.3 raeburn 49: "/adm/coursegroups:mdg:0:0:Cannot edit or view course groups";
1.1 raeburn 50: return HTTP_NOT_ACCEPTABLE;
51: }
52:
1.3 raeburn 53: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
54: ['action','refpage']);
55:
56: my $function = &Apache::loncommon::get_users_function();
57: my $tabcol = &Apache::loncommon::designparm($function.'.tabbg');
58: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
59: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
60:
1.1 raeburn 61: my $view_permission =
1.3 raeburn 62: &Apache::lonnet::allowed('vcg',$env{'request.course.id'});
1.1 raeburn 63: my $manage_permission =
1.3 raeburn 64: &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
65:
66: &Apache::lonhtmlcommon::clear_breadcrumbs();
67:
68: my %functions = (
69: email => 'E-mail',
70: discussion => 'Discussion boards',
71: chat => 'Chat',
72: files => 'File repository',
73: roster => 'Membership roster',
74: homepage => 'Group home page',
75: );
76:
77: my %idx = ();
78: $idx{id} = &Apache::loncoursedata::CL_ID();
79: $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME();
80: $idx{udom} = &Apache::loncoursedata::CL_SDOM();
81: $idx{uname} = &Apache::loncoursedata::CL_SNAME();
82:
83: my $action = $env{'form.action'};
84: if ($action eq 'create' || $action eq 'modify' || $action eq 'view') {
85: if ($view_permission || $manage_permission) {
86: &group_administration($r,$action,$cdom,$cnum,$function,$tabcol,
87: \%functions,\%idx,$view_permission,$manage_permission);
88: } else {
89: $r->print('You do not have group administration '.
90: 'privileges in this course');
91: }
92: } else {
93: &print_main_menu($r,$cdom,$cnum,$function,$tabcol,\%functions,\%idx,
94: $view_permission,$manage_permission);
95: }
96: return OK;
97: }
98:
99: sub print_main_menu {
100: my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission,
101: $manage_permission)
102: = @_;
103: $r->print(&header('Course Groups',&mt('LON-CAPA Course Groups'),
104: undef,undef,undef,$function));
105: &Apache::lonhtmlcommon::add_breadcrumb
106: ({href=>"/adm/coursegroups",
107: text=>"Course Groups",});
108: $r->print(&Apache::lonhtmlcommon::breadcrumbs
109: (undef,'Course Groups'));
110: &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
111: $view_permission,$manage_permission);
112: $r->print(&footer());
113: return;
114: }
115:
116: sub display_groups {
117: my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission,
118: $manage_permission) = @_;
119: my %curr_groups = ();
120: my %grp_info = ();
121: my $rowColor1 = "#dddddd";
122: my $rowColor2 = "#eeeeee";
123:
124: $r->print('<br /><br />');
125: if ($view_permission) {
1.4 ! raeburn 126: my %curr_groups;
! 127: if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {
1.3 raeburn 128: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.4 ! raeburn 129: $r->print(<<"END");
1.3 raeburn 130: <table border="0" cellpadding="4" cellspacing="1">
131: <tr bgcolor="$tabcol" align="center">
132: <td><b>Action</b></td>
133: <td><b><a href="javascript:changeSort('groupname')">Group Name</a></b></td>
134: <td><b><a href="javascript:changeSort('description')">Description</a></b></td>
135: <td><b><a href="javascript:changeSort('creator')">Creator</a></b>
136: </td>
137: <td><b><a href="javascript:changeSort('creation')">Created</a></b>
138: </td>
139: <td><b><a href="javascript:changeSort('modified')">Last Modified</a></b>
140: </td>
141: <td><b>Functionality</b>
142: </td>
143: <td><b><a href="javascript:changeSort('quota')">Quota (Mb)</a></b></td>
144: <td><b><a href="javascript:changeSort('totalmembers)">Members</a></b></td>
145: <td><b><a href="javascript:changeSort('totalfiles')">Files</a></b></td>
146: <td><b><a href="javascript:changeSort('boards')">Discussion boards</a></b></td>
147: <td><b><a href="javascript:changeSort('diskuse')">Disk use</a></b></td>
148: </tr>
149: END
1.4 ! raeburn 150: my %Sortby = ();
! 151: foreach my $group (sort(keys(%curr_groups))) {
! 152: %{$grp_info{$group}} =
! 153: &Apache::loncommon::get_group_settings(
1.3 raeburn 154: $curr_groups{$group});
1.4 ! raeburn 155: my $members_result = &group_members($cdom,$cnum,$group,\%grp_info);
! 156: my $files_result = &group_files($group,\%grp_info);
! 157: if ($env{'form.sortby'} eq 'groupname') {
! 158: push(@{$Sortby{$group}},$group);
! 159: } elsif ($env{'form.sortby'} eq 'description') {
! 160: push(@{$Sortby{$grp_info{$group}{'description'}}},
1.3 raeburn 161: $group);
1.4 ! raeburn 162: } elsif ($env{'form.sortby'} eq 'creator') {
! 163: push(@{$Sortby{$grp_info{$group}{'creator'}}},$group);
! 164: } elsif ($env{'form.sortby'} eq 'creation') {
! 165: push(@{$Sortby{$grp_info{$group}{'creation'}}},$group);
! 166: } elsif ($env{'form.sortby'} eq 'modified') {
! 167: push(@{$Sortby{$grp_info{$group}{'modified'}}},$group);
! 168: } elsif ($env{'form.sortby'} eq 'quota') {
! 169: push(@{$Sortby{$grp_info{$group}{'quota'}}},$group);
! 170: } elsif ($env{'form.sortby'} eq 'totalmembers') {
! 171: push(@{$Sortby{$grp_info{$group}{'totalmembers'}}},
1.3 raeburn 172: $group);
1.4 ! raeburn 173: } elsif ($env{'form.sortby'} eq 'totalfiles') {
! 174: push(@{$Sortby{$grp_info{$group}{'totalfiles'}}},
1.3 raeburn 175: $group);
1.4 ! raeburn 176: } elsif ($env{'form.sortby'} eq 'boards') {
! 177: push(@{$Sortby{$grp_info{$group}{'boards'}}},$group);
! 178: } elsif ($env{'form.sortby'} eq 'diskuse') {
! 179: push(@{$Sortby{$grp_info{$group}{'diskuse'}}},$group);
! 180: } else {
! 181: push(@{$Sortby{$group}},$group);
! 182: }
! 183: }
! 184: my $rowNum = 0;
! 185: my $rowColor;
! 186: foreach my $key (sort(keys(%Sortby))) {
! 187: foreach my $group (@{$Sortby{$key}}) {
! 188: if ($rowNum %2 == 1) {
! 189: $rowColor = $rowColor1;
1.3 raeburn 190: } else {
1.4 ! raeburn 191: $rowColor = $rowColor2;
1.3 raeburn 192: }
1.4 ! raeburn 193: my $description =
1.3 raeburn 194: &Apache::lonnet::unescape($grp_info{$group}{'description'});
1.4 ! raeburn 195: my $creator = $grp_info{$group}{'creator'};
! 196: my $creation = $grp_info{$group}{'creation'};
! 197: my $modified = $grp_info{$group}{'modified'};
! 198: my $quota = $grp_info{$group}{'quota'};
! 199: my $totalmembers = $grp_info{$group}{'totalmembers'};
! 200: my $totalfiles = $grp_info{$group}{'totalfiles'};
! 201: my $boards = $grp_info{$group}{'boards'};
! 202: my $diskuse = $grp_info{$group}{'diskuse'};
! 203: my $functionality;
! 204: foreach my $tool (sort keys(%{$functions})) {
! 205: if (defined($grp_info{$group}{functions}{$tool})) {
! 206: $functionality .= ' '.$tool;
1.3 raeburn 207: }
208: }
1.4 ! raeburn 209: if (!$functionality) {
! 210: $functionality = 'None available';
! 211: }
! 212: $r->print('<tr bgcolor="'.$rowColor.'"><td align="right">
! 213: <a href="/adm/'.$cdom.'/'.$cnum.'/'.$group.'/grppg?register=1"/>View</a> <a href="/adm/coursegroups?action=modify&group='.$group.'">Modify</a></td><td><small>'.$group.'</small></td><td><small>'.$description.'</small></td><td><small>'.$creator.'</small></td><td><small>'. &Apache::lonnavmaps::timeToHumanString($creation).'</small></td><td><small>'. &Apache::lonnavmaps::timeToHumanString($modified).'</small></td><td><small>'.$functionality.'</small></td><td><small>'.$quota.'</small></td><td><small>'.$totalmembers.'</small></td><td><small>'.$totalfiles.'</small></td><td><small>'.$boards.'</small></td><td><small>'.$diskuse.'</small></td></tr>');
! 214: $rowNum ++;
1.3 raeburn 215: }
1.4 ! raeburn 216: }
! 217: $r->print('</table>');
! 218: $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.3 raeburn 219: } else {
220: $r->print('No groups exist');
221: }
222: } else {
1.4 ! raeburn 223: my @coursegroups = split(/:/,$env{'request.course.groups'});
! 224: if (@coursegroups > 0) {
! 225: my %curr_groups;
! 226: if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {
! 227: foreach my $group (@coursegroups) {
! 228: my %group_info = &Apache::loncommon::get_group_settings(
! 229: $curr_groups{$group});
! 230: my $description = &Apache::lonnet::unescape(
! 231: $group_info{description});
! 232: my ($uname,$udom) = split(/:/,$group_info{creator});
! 233: $r->print('<font size="+1"><a href="/adm/'.$udom.'/'.$uname.'/'.$group.'/grppg?register=1">'.$group,'</a><font><br /><small>'.$description.'</small><br /><br />');
! 234: }
! 235: }
! 236: } else {
! 237: $r->print('You are not currently a member of any active groups in this course');
! 238: }
1.3 raeburn 239: }
240: return;
241: }
242:
243: sub group_administration {
244: my ($r,$action,$cdom,$cnum,$function,$tabcol,$functions,$idx,
245: $view_permission,$manage_permission) = @_;
246: my %sectioncount = ();
247: my @tools = ();
248: my @types = ();
249: my @roles = ();
250: my @sections = ();
251: my %users = ();
252: my %userdata = ();
253: my @members = ();
254: my %usertools = ();
255:
256: my $state = $env{'form.state'};
257: my ($groupname,$description,$startdate,$enddate);
258:
259: if ($action eq 'create') {
260: if ($state eq '') {
261: $state = 'pick_name';
262: } else {
263: ($startdate,$enddate) = &get_dates_from_form();
264: if (defined($env{'form.groupname'})) {
265: $groupname = $env{'form.groupname'};
266: }
267: if (defined($env{'form.description'})) {
268: $description = $env{'form.description'};
269: }
270: if (defined($env{'form.tool'})) {
271: @tools=&Apache::loncommon::get_env_multiple('form.tool');
272: }
273: if (defined($env{'form.member'})) {
274: @members = &Apache::loncommon::get_env_multiple('form.member');
275: foreach my $user (@members) {
276: %{$usertools{$user}} = ();
277: }
278: }
279: }
280: }
281:
282: my %toolprivs = ();
283: %{$toolprivs{'email'}} = (
284: sgm => 'Send group mail',
285: sgb => 'Broadcast mail',
286: );
287: %{$toolprivs{'discussion'}} = (
288: cgb => 'Create boards',
289: pgd => 'Post',
290: pag => 'Anon. posts',
291: rgi => 'Get identities',
292: vgb => 'View boards',
293: );
294: %{$toolprivs{'chat'}} = (
295: pgc => 'Chat',
296: );
297: %{$toolprivs{'files'}} = (
298: rgf => 'Retrieve',
299: ugf => 'Upload',
300: dgf => 'Delete',
301: );
302: %{$toolprivs{'roster'}} = (
303: vgm => 'View',
304: );
305: %{$toolprivs{'homepage'}} = (
306: vgh => 'View page',
307: mgh => 'Modify page',
308: );
309: my %fixedprivs = ();
310: %{$fixedprivs{'email'}} = ('sgm' => 1);
311: %{$fixedprivs{'discussion'}} = ('vgb' => 1);
312: %{$fixedprivs{'chat'}} = ('pgc' => 1);
313: %{$fixedprivs{'files'}} = ('rgf' => 1);
314: %{$fixedprivs{'roster'}} = ('vgm' => 1);
315: %{$fixedprivs{'homepage'}} = ('vgh' => 1);
316:
317: my %elements = ();
318: %{$elements{'create'}} = ();
319: %{$elements{'modify'}} = ();
320: %{$elements{'create'}{'pick_name'}} = (
321: startdate_month => 'selectbox',
322: startdate_hour => 'selectbox',
323: enddate_month => 'selectbox',
324: enddate_hour => 'selectbox',
325: types => 'selectbox',
326: roles => 'selectbox',
327: startdate_day => 'text',
328: startdate_year => 'text',
329: startdate_minute => 'text',
330: startdate_second => 'text',
331: enddate_day => 'text',
332: enddate_year => 'text',
333: enddate_minute => 'text',
334: enddate_second => 'text',
335: groupname => 'text',
336: description => 'text',
337: tool => 'checkbox',
338: granularity => 'radio',
339: no_end_date => 'checkbox',
340: );
341: %{$elements{'create'}{'pick_members'}} = (
342: member => 'checkbox',
343: );
344: if (($action eq 'create') && ($state eq 'pick_name')) {
345: my $numsections = &Apache::loncommon::get_sections($cdom,$cnum,
346: \%sectioncount);
347: if ($numsections > 0) {
348: $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox';
349: }
350: }
351:
352: if (($action eq 'create') && (($state eq 'pick_members') ||
353: ($state eq 'pick_privs'))) {
354: if (defined($env{'form.types'})) {
355: @types=&Apache::loncommon::get_env_multiple('form.types');
356: }
357: if (defined($env{'form.roles'})) {
358: @roles=&Apache::loncommon::get_env_multiple('form.roles');
359: }
360: if (defined($env{'form.sectionpick'})) {
361: @sections=&Apache::loncommon::get_env_multiple('form.sectionpick');
362: if (grep/^_all$/,@sections) {
363: @sections = sort {$a cmp $b} keys(%sectioncount);
364: }
365: }
366: &build_members_list($cdom,$cnum,\@types,\@roles,
367: \@sections,\%users,\%userdata);
368: if ((keys(%users) > 0) && (@tools > 0)) {
369: foreach my $tool (@tools) {
370: if ($env{'form.granularity'} eq 'Yes') {
371: $elements{'create'}{'pick_members'}{'user_'.$tool} = 'checkbox';
372: }
373: }
374: $elements{'create'}{'pick_members'}{'specificity'} = 'radio';
375: }
376: }
377:
378: if (($action eq 'create') && (($state eq 'pick_privs') || (($state eq 'result') &&
379: ($env{'form.specificity'} eq 'No')))) {
380: foreach my $tool (@tools) {
381: my @values = &Apache::loncommon::get_env_multiple('form.user_'.$tool);
382: foreach my $user (@values) {
383: unless(exists($usertools{$user}{$tool})) {
384: $usertools{$user}{$tool} = 1;
385: }
386: }
387: }
388: if (($state eq 'pick_privs') && ($env{'form.specificity'} eq 'Yes')) {
389: foreach my $member (@members) {
390: foreach my $tool (keys(%{$usertools{$member}})) {
391: foreach my $priv (keys(%{$toolprivs{$tool}})) {
392: unless (exists($fixedprivs{$tool}{$priv})) {
393: $elements{'create'}{'pick_privs'}{'userpriv_'.$priv} =
394: 'checkbox';
395: }
396: }
397: }
398: }
399: }
400: }
401:
402: my $jscript;
403: if ($env{'form.action'} eq 'create') {
404: $jscript = &Apache::loncommon::check_uncheck_jscript();
405: }
406: $jscript .= qq|
407: function nextPage(formname,nextstate) {
408: formname.state.value= nextstate;
409: formname.submit();
410: }
411: function backPage(formname,prevstate) {
412: formname.state.value = prevstate;
413: formname.submit();
414: }
415:
416: |;
417:
418: $jscript .= &Apache::lonhtmlcommon::set_form_elements(
419: \%{$elements{$action}{$state}});
420:
421:
422: my $loaditems = &onload_action($action,$state);
423: $r->print(&header('Course Groups Manager',&mt('LON-CAPA Groups Manager'),
424: $jscript,$action,$state,$function,$loaditems));
1.1 raeburn 425:
1.3 raeburn 426: if ($env{'form.refpage'} eq 'enrl') {
427: &Apache::lonhtmlcommon::add_breadcrumb
428: ({href=>"/adm/dropadd",
429: text=>"Enrollment Manager",
430: faq=>9,bug=>'Instructor Interface',});
431: } else {
1.1 raeburn 432: &Apache::lonhtmlcommon::add_breadcrumb
1.3 raeburn 433: ({href=>"/adm/coursegroups",
434: text=>"Course Groups",
435: faq=>9,bug=>'Instructor Interface',});
436: }
437:
438: my %states = ();
439: @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result');
440: @{$states{'modify'}} = ();
441:
442: my %trail = ();
443: %{$trail{'create'}} = (
444: pick_name => 'Group Settings',
445: pick_members => 'Select Members',
446: pick_privs => 'Choose Privileges',
447: result => 'Creation Complete',
448: );
449: %{$trail{'modify'}} = ();
450:
451: if ((($action eq 'create') || ($action eq 'modify')) &&
452: ($manage_permission)) {
453: for (my $i=0; $i<@{$states{$action}}; $i++) {
454: if ($state eq $states{$action}[$i]) {
455: &Apache::lonhtmlcommon::add_breadcrumb(
456: {text=>"$trail{$action}{$state}"});
457: $r->print(&Apache::lonhtmlcommon::breadcrumbs
458: (undef,'Course Groups Manager'));
459: &display_control($r,$cdom,$cnum,$tabcol,$action,$state,
460: \%sectioncount,$groupname,$description,$functions,
461: \@tools,\%toolprivs,\%fixedprivs,$startdate,$enddate,
462: \%users,\%userdata,$idx,\@members,\%usertools);
463: last;
464: } else {
465: if ($state eq 'result' && $i > 0) {
466: &Apache::lonhtmlcommon::add_breadcrumb(
467: {href=>"javascript:backPage(document.$state,'$states{$action}[0]')",
468: text=>"$trail{$action}{$states{$action}[$i]}"});
469: } else {
470: &Apache::lonhtmlcommon::add_breadcrumb(
471: {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')",
472: text=>"$trail{$action}{$states{$action}[$i]}"});
473: }
474: }
475: }
476: } elsif (($action eq 'view') && ($view_permission)) {
477: &Apache::lonhtmlcommon::add_breadcrumb(
478: {text=>"View groups"});
1.1 raeburn 479: $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.3 raeburn 480: (undef,'Course Groups Manager'));
481: &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
482: $view_permission,$manage_permission);
483:
484: }
485: $r->print(&footer());
486: return;
487: }
488:
489: sub display_control {
490: my ($r,$cdom,$cnum,$tabcol,$action,$state,$sectioncount,$groupname,
491: $description,$functions,$tools,$toolprivs,$fixedprivs,$startdate,
492: $enddate,$users,$userdata,$idx,$members,$usertools) = @_;
493: if ($action eq 'create') {
494: if ($state eq 'pick_name') {
495: &first_creation_form($r,$cdom,$cnum,$tabcol,$state,$functions,
496: $sectioncount);
497: } elsif ($state eq 'pick_members') {
498: &second_creation_form($r,$cdom,$cnum,$tabcol,$state,$groupname,
499: $description,$startdate,$enddate,$tools,
500: $functions,$users,$userdata,$idx);
501: } elsif ($state eq 'pick_privs') {
502: &third_creation_form($r,$cdom,$cnum,$tabcol,$state,$startdate,
503: $enddate,$tools,$functions,$toolprivs,$fixedprivs,
504: $userdata,$members,$usertools,$idx);
505: } elsif ($state eq 'result') {
506: &completed_creation($r,$cdom,$cnum,$tabcol,$state,$groupname,
507: $description,$userdata,$startdate,$enddate,$tools,
508: $functions,$toolprivs,$members,$usertools,$idx);
1.1 raeburn 509: }
510: }
511: }
512:
513: sub header {
1.3 raeburn 514: my ($bodytitle,$title,$jscript,$action,$state,$function,$loaditems) = @_;
1.1 raeburn 515: my $html=&Apache::lonxml::xmlbegin();
1.3 raeburn 516: my $bodytag=&Apache::loncommon::bodytag($bodytitle,$function,$loaditems);
517: my $output = <<"END";
1.1 raeburn 518: $html
519: <head>
520: <title>$title</title>
1.3 raeburn 521: <script type="text/javascript">
522: $jscript
523: </script>
1.1 raeburn 524: </head>
525: $bodytag
1.3 raeburn 526: <form method="post" name="$state">
527:
528: END
529: if ($action eq 'create' || $action eq 'modify') {
530: $output .= <<"END";
531: <input type="hidden" name="action" value="$action" />
532: <input type="hidden" name="state" value="" />
533: <input type="hidden" name="origin" value="$state" />
534: END
535: }
536: return $output;
1.1 raeburn 537: }
538:
1.3 raeburn 539: sub onload_action {
540: my ($action,$state) = @_;
541: my $loaditems;
542: if ((defined($env{'form.origin'})) && ($action eq 'create') &&
543: ($state eq 'pick_name' || $state eq 'pick_members' ||
544: $state eq 'pick_privs')) {
545: unless ($env{'form.origin'} eq '') {
546: $loaditems =
547: 'onload="javascript:setFormElements(document.'.$state.')"';
1.1 raeburn 548: }
549: }
1.3 raeburn 550: return $loaditems;
1.1 raeburn 551: }
552:
553: sub footer {
554: return(<<ENDFOOT);
555: </form>
556: </body>
557: </html>
558: ENDFOOT
559: }
560:
1.3 raeburn 561: sub build_members_list {
562: my ($cdom,$cnum,$types,$roles,$sections,$users,$userdata) = @_;
563: my %access = ();
564: foreach my $role (@{$roles}) {
565: %{$$users{$role}} = ();
566: }
567: foreach my $type (@{$types}) {
568: $access{$type} = $type;
569: }
570: &Apache::loncommon::get_course_users($cdom,$cnum,\%access,$roles,
571: $sections,$users,$userdata);
572: return;
573: }
574:
575: sub group_files {
576: return;
577: }
578:
579: sub group_members {
1.4 ! raeburn 580: my ($cdom,$cnum,$group,$group_info) = @_;
! 581: my %memberhash = &Apache::lonnet::get_group_membership($cdom,$cnum,$group);
! 582: my $now = time;
! 583: my ($tmp)=keys(%memberhash);
! 584: if ($tmp=~/^error:/) {
! 585: $$group_info{'totalmembers'} = 'Unknown - an error occurred';
! 586: return $tmp;
! 587: }
! 588: my $now = time;
! 589: my $totalmembers = 0;
! 590: my $active = 0;
! 591: my $previous = 0;
! 592: my $future = 0;
! 593: foreach my $member (keys %memberhash) {
! 594: $totalmembers ++;
! 595: my ($end,$start) = split(/:/,$memberhash{$member});
! 596: if (($end!=0) && ($end<$now)) {
! 597: $previous ++;
! 598: } elsif (($start!=0) && ($start>$now)) {
! 599: $future ++;
! 600: } else {
! 601: $active ++;
! 602: }
! 603: }
! 604: if ($totalmembers == 0) {
! 605: $$group_info{$group}{'totalmembers'} = 'None';
! 606: } else {
! 607: $$group_info{$group}{'totalmembers'} = $active.' - active<br />'.$previous.' -previous<br />'.$future.' -future';
! 608: }
! 609: return 'ok';
1.3 raeburn 610: }
611:
612:
1.1 raeburn 613: sub first_creation_form {
1.3 raeburn 614: my ($r,$cdom,$cnum,$tabcol,$formname,$functions,$sectioncount) = @_;
1.1 raeburn 615: my %lt = &Apache::lonlocal::texthash(
616: 'gmem' => 'Group membership options',
1.3 raeburn 617: 'picr' => 'Pick the criteria to use to build a list of course users '.
618: 'from which you will select members of the new group',
1.1 raeburn 619: 'gdat' => 'Group open and close dates',
620: 'sten' => 'Set a start date/time and end date/time for the group',
1.3 raeburn 621: 'acty' => 'Access types',
1.1 raeburn 622: 'coro' => 'Course roles',
623: 'cose' => 'Course sections',
624: 'gfun' => 'Group functionality',
625: );
626:
627: my %status_types = (
628: active => &mt('Currently has access'),
629: previous => &mt('Previously had access'),
630: future => &mt('Will have future access'),
631: );
632:
633: my @roles = ('st','cc','in','ta','ep','cr');
634:
1.3 raeburn 635: my $starttime = time;
636: my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
637: my ($start_table,$end_table) = &date_setting_table
638: ($starttime,$endtime,$formname);
639:
1.1 raeburn 640: my @sections = ();
641: my $section_sel = '';
1.3 raeburn 642: my $numvisible = 4;
1.1 raeburn 643:
1.3 raeburn 644: @sections = sort {$a cmp $b} keys(%{$sectioncount});
645: if (@sections > 0) {
646: unshift(@sections,'_all'); # Put 'all' at the front of the list
647: if (@sections < 4) {
648: $numvisible = @sections;
649: }
650: foreach (@sections) {
651: if ($_ eq '_all') {
652: $section_sel .= ' <option value="'.$_.'" />all sections'."\n";
653: } else {
654: $section_sel .= ' <option value="'.$_.'" />'.$_."\n";
655: }
656: }
1.1 raeburn 657: }
658:
659: $r->print(<<"END");
1.3 raeburn 660: <br />
661: <table width="100%" cellpadding="0" cellspacing="0" border="0">
662: <tr bgcolor="$tabcol">
663: <td> </td>
664: <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step1.gif"
665: valign="bottom"> </nobr>
666: </td>
667: <td align="left"><nobr>
668: <font face="arial,helvetica,sans-serif"><b>Group name, description
669: and available functionality</b></font></nobr>
670: </td>
671: <td width="100%"> </td>
672: </tr>
673: <tr>
674: <td colspan="4"> </td>
675: </tr>
676: <tr>
677: <td> </td>
678: <td colspan="3">
679: <table border="0" cellpadding="2" cellspacing="2">
680: <tr>
681: <td><b>Group Name:</b></td>
682: <td colspan="5"><input type="text" name="groupname" size="25" />
683: </td>
684: <tr>
685: <tr>
686: <td><b>Description:</b></td>
687: <td colspan="5"><input type="text" name="description" size="40" />
688: </td>
689: <tr>
690: <tr>
691: <td><b>Functionality:</b></td>
692: END
693: my $numitems = keys(%{$functions});
694: my $halfnum = int($numitems/2);
695: my $remnum = $numitems%2;
696: if ($remnum) {
697: $halfnum ++;
698: }
699: my @allfunctions = sort (keys (%{$functions}));
700: for (my $i=0; $i<$halfnum; $i++) {
701: $r->print('<td><input type="checkbox" name="tool" value="'.
702: $allfunctions[$i].'" /> '.
703: $$functions{$allfunctions[$i]}.'</td>
704: <td> </td><td> </td>');
705: }
706: $r->print('<td><input type="button" value="check all" '.
707: 'onclick="javascript:checkAll(document.'.$formname.'.tool)" />'.
708: '</td></tr><tr><td> </td>');
709: for (my $j=$halfnum; $j<@allfunctions; $j++) {
710: $r->print('<td><input type="checkbox" name="tool" value="'.
711: $allfunctions[$j].'" /> '.
712: $$functions{$allfunctions[$j]}.'</td>
713: <td> </td><td> </td>');
714: }
715: if ($remnum) {
716: $r->print('<td> </td>');
717: }
718: $r->print(<<"END");
719: <td>
720: <input type="button" value="uncheck all"
721: onclick="javascript:uncheckAll(document.$formname.tool)" />
722: </td>
723: </tr>
724: <tr>
725: <td><b>Granularity:</b></td>
726: <td colspan="9">Do you want to assign different functionality to different group members? <input type="radio" name="granularity" value="Yes" />Yes <input type="radio" name="granularity" value="No" checked="checked" />No</td>
727: </tr>
728: </table>
729: </td>
730: </tr>
731: <tr>
732: <td colspan="4"> </td>
733: </tr>
734: <tr bgcolor="$tabcol">
735: <td> </td>
736: <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step2.gif"
737: valign="bottom"> </nobr>
738: </td>
739: <td align="left"><nobr>
740: <font face="arial,helvetica,sans-serif"><b>Start and end dates for group
741: access</b></font></nobr>
742: </td>
743: <td width="100%"> </td>
744: </tr>
745: <tr>
746: <td colspan="4"> </td>
747: </tr>
748: <tr>
749: <td> </td>
750: <td colspan="3">$start_table</td>
751: <tr>
752: <tr>
753: <td colspan="4"> </td>
754: </tr>
755: <tr>
756: <td> </td>
757: <td colspan="3">$end_table</td>
758: <tr>
759: <tr>
760: <td colspan="4"> </td>
761: </tr>
762: <tr bgcolor="$tabcol">
763: <td> </td>
764: <td valign="bottom"><nobr><img src="/res/adm/pages/bl_step3.gif"
765: valign="bottom"> </nobr>
766: </td>
767: <td align="left"><nobr>
768: <font face="arial,helvetica,sans-serif"><b>Pick parameters to generate
769: membership list</b></nobr>
770: </font>
771: </td>
772: <td width="100%"> </td>
773: </tr>
774: <tr>
775: <td colspan="4"> </td>
776: </tr>
777: <tr>
778: <td> </td>
779: <td colspan="3">
780: <b>$lt{'gmem'}</b><br/> $lt{'picr'}
781: <br /><br />
782: <table border="0">
783: <tr>
784: <td><b>$lt{'acty'}</b></td>
785: <td> </td>
786: <td><b>$lt{'coro'}</b></td>
787: END
788: if (@sections >0) {
789: $r->print('
790: <td> </td>
791: <td><b>'.$lt{'cose'}.'</b></td>
792: <td> </td>');
793: }
794: $r->print('</tr><tr>');
795: $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types));
796: $r->print('<td> </td>');
797: $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles));
798: if (@sections > 0) {
799: $r->print('
800: <td> </td>
801: <td colspan="3" align="center" valign="top">
802: <select name="sectionpick" multiple="true" size="'.$numvisible.'">
803: '.$section_sel.'
804: </select>
805: </td>');
806: }
807: $r->print('
808: </tr>
809: </table>
810: </td>
811: </tr>
812: <tr>
813: <td colspan="4"> </td>
814: </tr>
815: <tr>
816: <td> </td>
817: <td colspan="3" align="left">
818: <input type="button" value="Go to next step"
819: onclick="javascript:nextPage(document.'.$formname.','."'pick_members'".')>
820: </td>
821: </tr>
822: </table>
823: ');
824: return;
825: }
826:
827: sub second_creation_form {
828: my ($r,$cdom,$cnum,$tabcol,$formname,$groupname,$description,$startdate,
829: $enddate,$tools,$functions,$users,$userdata,$idx) = @_;
830: my @regexps = ('user_','userpriv_');
831: $r->print(&Apache::lonhtmlcommon::echo_form_input(
832: ['origin','action','state','member','specificity'],\@regexps));
833: my %sectioncount = ();
834: my $numsec = &Apache::loncommon::get_sections($cdom,$cnum,\%sectioncount);
1.4 ! raeburn 835: my %curr_groups;
! 836: my $numgroups = &Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum);
! 837: my $earlyout;
1.3 raeburn 838: my $exitmsg = '<b>Invalid group name</b><br /><br />The group name entered "'.
839: $groupname.'" ';
840: my $dupmsg = 'Group names and section names used in a course must be unique.';
841: if ($groupname =~ /\W/) {
842: $earlyout = $exitmsg.'is not a valid name.<br />Group names may only contain letters, numbers or underscores';
843: }
844: if ($numsec) {
845: if (exists($sectioncount{$groupname})) {
1.4 ! raeburn 846: $earlyout = $exitmsg.'can not be used as it is the name of a '.
! 847: 'section in this course.<br />'.$dupmsg;
1.3 raeburn 848: }
849: }
850: if ($numgroups) {
851: if (exists($curr_groups{$groupname})) {
852: $earlyout = $exitmsg.'can not be used as it is the name of an
853: existing group in this course.<br />'.$dupmsg;
854: }
855: }
856: if ($earlyout) {
857: $r->print('<table border="0" cellpadding="2" cellspacing="2">
1.1 raeburn 858: <tr>
859: <td> </td>
1.3 raeburn 860: <td>'.$earlyout.'</td>
861: </tr>
862: <tr>
863: <td colspan="2"> </td>
864: </tr>
865: <tr>
1.1 raeburn 866: <td> </td>
1.3 raeburn 867: <td align="left">
868: <input type="button" name="previous" value = "Go to previous page"
869: onclick="javascript:backPage(document.'.$formname.','."'pick_name'".')"/>
870: </td>
871: </tr>
872: </table>
873: ');
874: return;
875: }
876: my $rowColor1 = "#dddddd";
877: my $rowColor2 = "#eeeeee";
878: my $showstart = &Apache::lonlocal::locallocaltime($startdate);
879: my $showend = &Apache::lonlocal::locallocaltime($enddate);
880: $r->print('<table border="0" cellpadding="0" cellspacing="20">
881: <tr>
882: <td><font face="arial,helvetica,sans-serif"><b>New group selections</b></font>
883: <br />When you create the new group, the following settings will apply:
884: </td>
885: </tr>
886: <tr>
887: <td>');
888: $r->print(&Apache::lonhtmlcommon::start_pick_box());
889: $r->print('
890: <table cellspacing="1" cellpadding="4">
891: <tr bgcolor="'.$tabcol.'" align="center">
892: <td><b>Group Name</b></td>
893: <td><b>Description</b></td>
894: <td><b>Group Functionality</b></td>
895: <td><b>Default access dates</b></td>
896: </tr>
897: <tr bgcolor="'.$rowColor2.'">
898: <td valign="top"><small>'.$groupname.'</small></td>
899: <td valign="top"><small>'.$description.'</small></td>
900: <td>
901: ');
902: my @available = ();
903: my @unavailable = ();
904: foreach my $item (sort(keys(%{$functions}))) {
905: if (grep/^$item$/,@{$tools}) {
906: push(@available,$item);
907: } else {
908: push(@unavailable,$item);
909: }
910: }
911: if (@available > 0) {
912: $r->print('<small><b>Available:</b></small>
913: <table cellpadding="" cellspacing="1"><tr>');
914: my $rowcell = int(@available/2) + @available%2;
915: for (my $i=0; $i<@available; $i++) {
916: if (@available > 3) {
917: if ($i==$rowcell) {
918: $r->print('</tr><tr>');
919: }
920: }
921: $r->print('<td><small>'.$$functions{$available[$i]}.
922: '</small></td><td> </td>');
923: }
924: if ((@available > 3) && (@available%2)) {
925: $r->print('<td> </td><td> </td>');
926: }
927: $r->print('</tr></table><br />');
928: }
929: if (@unavailable > 0) {
930: $r->print('<small><b>Unavailable:</b></small>
931: <table cellpadding="0" cellspacing="1" border="0"><tr>');
932: my $rowcell = int(@unavailable/2) + @unavailable%2;
933: for (my $j=0; $j<@unavailable; $j++) {
934: if (@unavailable > 3) {
935: if ($j==$rowcell) {
936: $r->print('</tr><tr>');
937: }
938: }
939: $r->print('<td><small>'.$$functions{$unavailable[$j]}.
940: '</small></td><td> </td>');
941: }
942: if ((@unavailable > 3) && (@unavailable%2)) {
943: $r->print('<td> </td><td> </td>');
944: }
945: $r->print('</tr></table>');
946: }
947: $r->print(<<"END");
948: </td>
949: <td valign="top"><small><b>Start date:</b> $showstart<br />
950: <b>End date:</b> $showend</small>
951: </td>
952: </tr>
953: </table>
954: END
955: $r->print(&Apache::lonhtmlcommon::end_pick_box());
956: my %members = ();
957: foreach my $role (keys(%{$users})) {
958: foreach my $user (keys(%{$$users{$role}})) {
959: unless (defined($members{$user})) {
960: @{$members{$user}} = @{$$userdata{$user}};
961: }
962: }
963: }
964: $r->print('</td></tr></table><br />');
965: if (keys(%members) > 0) {
966: if ($env{'form.granularity'} eq 'Yes') {
967: $r->print('
968: <script type="text/javascript">
969: function checkAllTools(formname) {
970: ');
971: foreach my $tool (@available) {
972: $r->print(' checkAll(formname.user_'.$tool.');'."\n");
973: }
974: $r->print('
975: }
976: function uncheckAllTools(formname) {
977: ');
978: foreach my $tool (@available) {
979: $r->print(' uncheckAll(formname.user_'.$tool.');'."\n");
980: }
981: $r->print('
982: }
983: </script>
984: ');
985: }
986: $r->print(<<"END");
987: <table width="100%" cellpadding="0" cellspacing="0" border="0">
988: <tr bgcolor="$tabcol">
1.1 raeburn 989: <td> </td>
1.3 raeburn 990: <td valign="top" align="left">
991: <nobr><img src="/res/adm/pages/bl_step4.gif" valign="middle"> </nobr>
992: </td>
993: <td alin="left">
994: <nobr>
995: <font face="arial,helvetica,sans-serif">
996: <b>Select group members</b>
997: </font></nobr>
998: </td>
999: <td width="100%"> </td>
1.1 raeburn 1000: </tr>
1001: <tr>
1.3 raeburn 1002: <td colspan="4"> </td>
1003: </tr>
1.1 raeburn 1004: <tr>
1.3 raeburn 1005: <td> </td>
1006: <td colspan="2">
1007: <table>
1008: <tr>
1009: <td>
1010: <nobr>
1011: <fieldset><legend><b>Add members</b></legend>
1012: <input type="button" value="check all"
1013: onclick="javascript:checkAll(document.$formname.member)" />
1014:
1015: <input type="button" value="uncheck all"
1016: onclick="javascript:uncheckAll(document.$formname.member)" />
1017: </fieldset></nobr></td>
1.1 raeburn 1018: END
1.3 raeburn 1019: if (@available > 0 && $env{'form.granularity'} eq 'Yes') {
1020: $r->print('<td><nobr><fieldset><legend><b>
1021: Set functionality</b></legend>
1022: <input type="button" value="check all"
1023: onclick="javascript:checkAllTools(document.'.$formname.')" />
1024:
1025: <input type="button" value="uncheck all"
1026: onclick="javascript:uncheckAllTools(document.'.$formname.')" />
1027: </fieldset></nobr></td>');
1028: }
1029: $r->print('</tr></table>
1030: </td>
1031: <td width="100%"> </td>
1032: </tr>
1033: <tr>
1034: <td colspan="4"> </td>
1035: </tr>
1036: <tr>
1037: <td> </td>
1038: <td colspan="3">
1039: ');
1040: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1041: $r->print(<<"END");
1042: <table border="0" cellpadding="4" cellspacing="1">
1043: <tr bgcolor="$tabcol" align="center">
1044: <td><b>Add?</b></td>
1045: <td><b><a href="javascript:changeSort('fullname')">Name</a></b></td>
1046: <td><b><a href="javascript:changeSort('username')">Username</a></b>
1047: </td>
1048: <td><b><a href="javascript:changeSort('domain')">Domain</a></b></td>
1049: <td><b><a href="javascript:changeSort('id')">ID</a></b></td>
1050: END
1051: if (@available > 0) {
1052: $r->print('<td><b>Functionality</b></td>');
1053: }
1054: $r->print('</tr>');
1055: my %Sortby = ();
1056: foreach my $user (sort(keys(%members))) {
1057: if ($env{'form.sortby'} eq 'fullname') {
1058: push(@{$Sortby{$members{$user}[$$idx{fullname}]}},$user);
1059: } elsif ($env{'form.sortby'} eq 'username') {
1060: push(@{$Sortby{$members{$user}[$$idx{uname}]}},$user);
1061: } elsif ($env{'form.sortby'} eq 'domain') {
1062: push(@{$Sortby{$members{$user}[$$idx{udom}]}},$user);
1063: } elsif ($env{'form.sortby'} eq 'id') {
1064: push(@{$Sortby{$members{$user}[$$idx{id}]}},$user);
1065: } else {
1066: push(@{$Sortby{$members{$user}[$$idx{fullname}]}},$user);
1067: }
1068: }
1069: my $rowNum = 0;
1070: my $rowColor;
1071: foreach my $key (sort(keys(%Sortby))) {
1072: foreach my $user (@{$Sortby{$key}}) {
1073: if ($rowNum %2 == 1) {
1074: $rowColor = $rowColor1;
1075: } else {
1076: $rowColor = $rowColor2;
1077: }
1078: my $id = $members{$user}[$$idx{id}];
1079: my $fullname = $members{$user}[$$idx{fullname}];
1080: my $udom = $members{$user}[$$idx{udom}];
1081: my $uname = $members{$user}[$$idx{uname}];
1082: $r->print('<tr bgcolor="'.$rowColor.'"><td align="right">
1083: <input type="checkbox" name="member" value="'.$user.'" /></td><td><small>'.
1084: $fullname.'</small></td><td><small>'.$uname.'</small></td><td><small>'.
1085: $udom.'</small></td><td><small>'.$id.'</small></td>');
1086: if (@available > 0) {
1087: $r->print('<td align="center"><small>');
1088: foreach my $tool (@available) {
1089: if ($env{'form.granularity'} eq 'Yes') {
1090: $r->print('<input type="checkbox" name="user_'.
1091: $tool.'" value="'.$user.'" />'.$tool.' ');
1092: } else {
1093: $r->print('<input type="hidden" name="user_'.
1094: $tool.'" value="'.$user.'" />'.$tool.' ');
1095: }
1096: }
1097: $r->print('</small></td>');
1098: }
1099: $r->print('</tr>'."\n");
1100: $rowNum ++;
1101: }
1102: }
1103: $r->print(&Apache::lonhtmlcommon::end_pick_box());
1104: $r->print('
1105: </td>
1106: </tr>
1107: <tr>
1108: <td colspan="4"> </td>
1109: </tr>');
1110: if (@available > 0) {
1111: $r->print('
1112: <tr bgcolor="'.$tabcol.'">
1113: <td> </td>
1114: <td valign="middle" align="left">
1115: <nobr><img src="/res/adm/pages/bl_step5.gif" valign="middle"> </nobr>
1116: </td>
1117: <td align="left"><nobr>
1118: <font face="arial,helvetica,sans-serif">
1119: <b>User privileges</b>
1120: </font></nobr>
1121: </td>
1122: <td width="100%"> </td>
1123: </tr>
1124: <tr>
1125: <td> </td>
1126: <td colspan="3">
1127: <br />
1128: For each type of functionality you have chosen to include, there is a
1129: set of standard privileges which apply to all of those for whom the functionality is enabled.<br />There are also additional privileges which can be set for some, or all, members. Please choose one of the following:<br />
1130: <br /><input type="radio" name="specificity" value="No" checked="checked" /> All group members will receive the same privileges.<br/><input type="radio" name="specificity" value="Yes" /> Some group members will receive different privileges from others.
1131: </td>
1132: </tr>
1133: <tr>
1134: <td colspan="4"> </td>
1135: </tr>
1136: ');
1137: }
1138: $r->print('
1139: <tr>
1140: <td> </td>
1141: <td colspan="3">
1142: <input type="button" name="previous" value = "Go to previous page"
1143: onclick="javascript:backPage(document.'.$formname.','."'pick_name'".')"/>
1144:
1145: <input type="button" name="next" value="Go to next page"
1146: onclick="javascript:nextPage(document.'.$formname.','."'pick_privs'".')" />
1147: </td>
1148: </tr>
1149: ');
1150: } else {
1151: $r->print('No members to add');
1152: }
1153: $r->print('
1154: </table>
1155: </td>
1156: </tr>
1157: </table>');
1158: return;
1159: }
1160:
1161: sub third_creation_form {
1162: my ($r,$cdom,$cnum,$tabcol,$formname,$startdate,$enddate,$tools,$functions,
1163: $toolprivs,$fixedprivs,$userdata,$members,$usertools,$idx) = @_;
1164: my @regexps = ('userpriv_','allpriv_');
1165: $r->print(&Apache::lonhtmlcommon::echo_form_input(
1166: ['origin','action','state'],\@regexps));
1167: my %possibles = ();
1168: my %showboxes = ();
1169: my $totalboxes = 0;
1170: my $rowColor1 = "#dddddd";
1171: my $rowColor2 = "#eeeeee";
1172: my $numtools = 1 + @{$tools};
1173: foreach my $tool (@{$tools}) {
1174: @{$showboxes{$tool}} = ();
1175: foreach my $user (@{$members}) {
1176: if (exists($$usertools{$user}{$tool})) {
1177: foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
1178: unless (exists($$fixedprivs{$tool}{$priv})) {
1179: push(@{$possibles{$user}},$priv);
1180: unless(grep(/^$priv$/,@{$showboxes{$tool}})) {
1181: push(@{$showboxes{$tool}},$priv);
1182: $totalboxes ++;
1183: }
1184: }
1185: }
1186: }
1187: }
1188: }
1189: if ($totalboxes > 0) {
1190: $r->print('
1191: <script type="text/javascript">
1192: function checkAllTools(formname) {
1193: ');
1194: foreach my $tool (sort(keys(%showboxes))) {
1195: foreach my $priv (@{$showboxes{$tool}}) {
1196: $r->print(' checkAll(formname.userpriv_'.$priv.');'."\n");
1197: }
1198: }
1199: $r->print('
1200: }
1201: function uncheckAllTools(formname) {
1202: ');
1203: foreach my $tool (sort(keys(%showboxes))) {
1204: foreach my $priv (@{$showboxes{$tool}}) {
1205: $r->print(' uncheckAll(formname.userpriv_'.$priv.');'."\n");
1206: }
1207: }
1208: $r->print('
1209: }
1210: </script>
1211: ');
1212: }
1213: $r->print(<<"END");
1214: <br />
1215: <table width="100%" cellpadding="0" cellspacing="0" border="0">
1216: <tr bgcolor="$tabcol">
1.1 raeburn 1217: <td> </td>
1.3 raeburn 1218: <td valign="middle" align="left">
1219: <nobr><img src="/res/adm/pages/bl_step6.gif" valign="middle"> </nobr>
1.1 raeburn 1220: </td>
1.3 raeburn 1221: <th align="left"><nobr>
1222: Group member privileges
1223: </nobr>
1224: </th>
1225: <td width="100%"> </td>
1226: </tr>
1227: <tr>
1228: <td colspan="4"> </td>
1.1 raeburn 1229: </tr>
1.3 raeburn 1230: <tr>
1231: <td> </td>
1232: <td colspan="3">
1233: END
1234: if ($env{'form.specificity'} eq 'Yes') {
1235: $r->print('
1236: <table border="0" cellspacing="2" cellpadding="2" border="0">
1237: <tr>
1238: <td valign="top">
1239: ');
1240: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1241: $r->print(<<"END");
1242: <tr bgcolor="$tabcol">
1243: <th><b>Fullname</th>
1244: <th><b>Username</th>
1245: <th>Domain</th>
1246: <th colspan="$numtools">Additional Privileges</th>
1247: </tr>
1.1 raeburn 1248: END
1.3 raeburn 1249: }
1250: if ($env{'form.specificity'} eq 'Yes') {
1251: &member_privs_entries($r,$tabcol,$rowColor1,$rowColor2,$members,$tools,
1252: $usertools,$toolprivs,$fixedprivs,$userdata,$idx);
1253: }
1254: if ($env{'form.specificity'} eq 'Yes') {
1255: $r->print('</td>');
1256: $r->print(&Apache::lonhtmlcommon::end_pick_box());
1257: $r->print('<td> </td>
1258: <td> </td><td valign="top">');
1259: my @toolboxes = sort(keys(%showboxes));
1260: foreach my $tool (@{$tools}) {
1261: if (@{$showboxes{$tool}} > 0) {
1262: $r->print('<table class="thinborder"><tr bgcolor="'.$tabcol.
1263: '"><th>'.$tool.'</th></tr>');
1264: foreach my $priv (@{$showboxes{$tool}}) {
1265: $r->print(qq|
1266: <tr><td>
1267: <fieldset><legend><b>$$toolprivs{$tool}{$priv}</b></legend>
1268: <input type="button" value="check all"
1269: onclick="javascript:checkAll(document.$formname.userpriv_$priv)" />
1270:
1271: <input type="button" value="uncheck all"
1272: onclick="javascript:uncheckAll(document.$formname.userpriv_$priv)" />
1273: </nobr></fieldset></td></tr>|);
1274: }
1275: $r->print('</table><br /><br />');
1276: }
1277: }
1278: $r->print('</td></tr></table>');
1279: } else {
1280: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1281: $r->print('<tr><td bgcolor="'.$tabcol.'" valign="top"><table cellspacing="0" cellpadding="1"><tr><td valign="top"><b>Function</b></td></tr><tr><td valign="top"><b>Fixed privileges</b>'.
1282: '</td></tr><tr><td valign="top"><b>Optional privileges</b></td></tr></table></td>');
1283: foreach my $tool (@{$tools}) {
1284: $r->print('<td align="center" valign="top"><table cellspacing="0" cellpadding="1"><tr bgcolor="#cccccc">'.
1285: '<td colspan="2" align="center"><b>'.$tool.'</b></td></tr>');
1286: my $privcount = 0;
1287: my $fixed = '';
1288: my $dynamic = '';
1289: foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
1290: if (exists($$fixedprivs{$tool}{$priv})) {
1291: $fixed .= '<input type="hidden" name="allpriv_'.$priv.'" value="all" />'.$$toolprivs{$tool}{$priv}.' ';
1292: } else {
1293: $privcount ++;
1294: if ($privcount == 3) {
1295: $dynamic .= '</tr><tr bgcolor="'.$rowColor1.'">';
1296: }
1297: $dynamic .= '<td><input type="checkbox" name="allpriv_'.$priv.'" value="all" />'.$$toolprivs{$tool}{$priv}.'</td>';
1298: }
1299: }
1300: if ($dynamic eq '') {
1301: $dynamic = '<td>None</td>';
1302: }
1303: if ($privcount < 3) {
1304: $dynamic .= '</tr><tr bgcolor="'.$rowColor1.'"><td colspan="2"> </td>';
1305: } elsif ($privcount%2) {
1306: $dynamic = '<td> </td>';
1307: }
1308: $r->print('<tr bgcolor="'.$rowColor2.'"><td colspan="2" align="center"><nobr>'.$fixed.'</nobr></td></tr><tr bgcolor="'.$rowColor1.'">'.$dynamic.'</tr></table></td>');
1309: }
1310: $r->print('</tr>');
1311: $r->print(&Apache::lonhtmlcommon::end_pick_box());
1312: }
1313: $r->print('</td></tr>
1314: <tr>
1315: <td colspan="4"> </td>
1316: </tr>
1317: <tr>
1318: <td> </td>
1319: <td colspan="3">
1320: <input type="button" name="previous" value = "Go to previous page"
1321: onclick="javascript:backPage(document.'.$formname.','."'pick_members'".')"/>
1322:
1323: <input type="button" name="next" value="Create group"
1324: onclick="javascript:nextPage(document.'.$formname.','."'result'".')" />
1325: </td>
1326: </tr>
1327: ');
1328: $r->print('
1329: </table>');
1330:
1.1 raeburn 1331: return;
1332: }
1333:
1.3 raeburn 1334: sub completed_creation {
1335: my ($r,$cdom,$cnum,$tabcol,$formname,$groupname,$description,$userdata,
1336: $startdate,$enddate,$tools,$functions,$toolprivs,$members,$usertools,$idx) = @_;
1337:
1338: $r->print(&Apache::lonhtmlcommon::echo_form_input(
1339: ['origin','action','state']));
1340: my @added= ();
1341: my @failed = ();
1342: my $now = time;
1343: my %group_privs = ();
1344: my %tooltype = ();
1345: foreach my $tool (@{$tools}) {
1346: foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
1347: $tooltype{$priv} = $tool;
1348: if ($env{'form.specificity'} eq 'Yes') {
1349: my @users =
1350: &Apache::loncommon::get_env_multiple('form.userpriv_'.$priv);
1351: foreach my $user (@users) {
1352: $group_privs{$user} .= $priv.':';
1353: }
1354: } else {
1355: if (defined($env{'form.allpriv_'.$priv})) {
1356: foreach my $user (@{$members}) {
1357: if ($$usertools{$user}{$tool}) {
1358: $group_privs{$user} .= $priv.':';
1359: }
1360: }
1361: }
1362: }
1363: }
1364: }
1365: foreach my $user (keys(%group_privs)) {
1366: $group_privs{$user} =~ s/:$//;
1367: }
1368: my $esc_description = &Apache::lonnet::escape($description);
1369: my @attributes = ('description','functions','startdate','enddate','creation','modified','creator');
1370:
1371: my %groupinfo = (
1372: description => $esc_description,
1373: startdate => $startdate,
1374: enddate => $enddate,
1375: creation => $now,
1376: modified => $now,
1377: creator => $env{'user.name'}.':'.$env{'user.domain'},
1378: );
1379: foreach my $func (keys(%{$functions})) {
1380: my $status;
1381: if (grep(/^$func$/,@{$tools})) {
1382: $status = 'on';
1383: } else {
1384: $status = 'off';
1385: }
1386: $groupinfo{'functions'} .= qq|<name id="$func">$status</name>|;
1387: }
1388:
1389: my %curr_groups = ();
1390: my %groupsettings = ();
1391: my %usersettings = ();
1.4 ! raeburn 1392: if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum,$groupname)) {
1.3 raeburn 1393: if (exists($curr_groups{$groupname})) {
1.4 ! raeburn 1394: $r->print('Non-unique name - please choose another');
1.3 raeburn 1395: return;
1396: }
1397: }
1398: my $groupentry;
1399: foreach my $item (@attributes) {
1400: $groupsettings{$groupname} .= qq|<$item>$groupinfo{$item}</$item>|;
1401: }
1402: my $result = &Apache::lonnet::modify_coursegroup($cdom,$cnum,
1403: \%groupsettings);
1404: if ($result eq 'ok') {
1405: my $put_result = &create_homepage($cdom,$cnum,$groupname,\%groupinfo,$tools);
1406: foreach my $user (sort(@{$members})) {
1407: $usersettings{$groupname.':'.$user} = $enddate.':'.$startdate.':'.$group_privs{$user};
1408: if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
1409: $user,$enddate,$startdate,$group_privs{$user}) eq 'ok') {
1410: push(@added,$user);
1411: } else {
1412: push(@failed,$user);
1413: }
1414: }
1415: my $roster_result = &Apache::lonnet::modify_coursegroup_membership(
1416: $cdom,$cnum,\%usersettings);
1417: $r->print('
1418: Group '.$groupname.' was created.<br />');
1419: if (@added > 0) {
1420: $r->print('Users were added with following privileges:<br />');
1421: foreach my $user (@added) {
1422: my @privs = split(/:/,$group_privs{$user});
1423: my $privlist= '';
1424: my $curr_tool = '';
1425: foreach my $priv (@privs) {
1426: unless ($curr_tool eq $tooltype{$priv}) {
1427: $curr_tool = $tooltype{$priv};
1428: $privlist .= '<b>'.$curr_tool.'</b>: ';
1429: }
1430: $privlist .= $$toolprivs{$curr_tool}{$priv}.', ';
1431: }
1432: $privlist =~ s/, $//;
1433: $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.': '.$privlist.'<br />');
1434: }
1435: }
1436: if (@failed > 0) {
1437: $r->print('Addition of the following users was unsuccessful:<br />');
1438: foreach my $user (@failed) {
1439: $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');
1440: }
1441: }
1442: if ($roster_result eq 'ok') {
1443: $r->print('<br />Group membership list updated.');
1444: } else {
1445: $r->print('<br />An error occurred while updating the group membership list -'.$roster_result.'<br />');
1446: }
1447: } else {
1448: &Apache::lonnet::logthis('Failed to create group '.$groupname.
1449: 'in course: '.$cnum.' in domain: '.$cdom);
1450:
1451: $r->print('An error occurred when creating the new group. '.
1452: 'Please try again.');
1453: }
1454: return;
1455: }
1456:
1457: sub member_privs_entries {
1458: my ($r,$tabcol,$rowColor1,$rowColor2,$members,$tools,$usertools,$toolprivs,
1459: $fixedprivs,$userdata,$idx) = @_;
1460: my $rowColor;
1461: my $rowNum = 0;
1462: foreach my $member (@{$members}) {
1463: my ($uname,$udom) = split(/:/,$member);
1464: if ($rowNum %2 == 1) {
1465: $rowColor = $rowColor1;
1466: } else {
1467: $rowColor = $rowColor2;
1468: }
1469: $r->print('<tr bgcolor="'.$rowColor.'">
1470: <td>'.$$userdata{$member}[$$idx{fullname}].'</td>
1471: <td>'.$uname.'</td>
1472: <td>'.$udom.'</td>
1473: <td valign="top"><table><tr><td><b>Function</b></td></tr><tr><td><b>Fixed</b></td></tr><tr><td><b>Optional</b></td></tr></table></td>');
1474: foreach my $tool (@{$tools}) {
1475: if (exists($$usertools{$member}{$tool})) {
1476: $r->print('<td valign="top"><table><tr bgcolor="'.$tabcol.'"><td colspan="2" align="center"><b>'.$tool.'</b></td></tr>');
1477: my $privcount = 0;
1478: my $fixed = '';
1479: my $dynamic = '';
1480: foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
1481: if (exists($$fixedprivs{$tool}{$priv})) {
1482: $fixed .= '<input type="hidden" name="userpriv_'.$priv.'" value="'.$member.'" />'.$$toolprivs{$tool}{$priv}.' ';
1483: } else {
1484: $privcount ++;
1485: if ($privcount == 3) {
1486: $dynamic .= '</tr><tr>';
1487: }
1488: $dynamic .= '<td><input type="checkbox" name="userpriv_'.$priv.'" value="'.$member.'" />'.$$toolprivs{$tool}{$priv}.'</td>';
1489: }
1490: }
1491: $r->print('<tr><td colspan="2"><nobr>'.$fixed.'</nobr></td></tr><tr>'.$dynamic.'</tr></table></td>');
1492: } else {
1493: $r->print('<td> </td>');
1494: }
1495: }
1496: $rowNum ++;
1497: }
1498: }
1499:
1500:
1501: sub get_dates_from_form {
1502: my $startdate;
1503: my $enddate;
1504: $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
1505: $enddate = &Apache::lonhtmlcommon::get_date_from_form('enddate');
1506: if ( exists ($env{'form.no_end_date'}) ) {
1507: $enddate = 0;
1508: }
1509: return ($startdate,$enddate);
1510: }
1511: sub date_setting_table {
1512: my ($starttime,$endtime,$formname) = @_;
1513: my $startform = &Apache::lonhtmlcommon::date_setter($formname,
1514: 'startdate',$starttime);
1515: my $endform = &Apache::lonhtmlcommon::date_setter($formname,
1516: 'enddate',$endtime);
1517: my $perpetual = '<nobr><input type="checkbox" name="no_end_date" />
1518: no ending date</nobr>';
1519: my $start_table = '';
1520: $start_table .= "<table>\n";
1521: $start_table .= '<tr><td align="right">Default starting date for
1522: member access</td>'.
1523: '<td>'.$startform.'</td>'.
1524: '<td> </td>'."</tr>\n";
1525: $start_table .= "</table>";
1526: my $end_table = '';
1527: $end_table .= "<table>\n";
1528: $end_table .= '<tr><td align="right">Default ending date for
1529: member access</td>'.
1530: '<td>'.$endform.'</td>'.
1531: '<td>'.$perpetual.'</td>'."</tr>\n";
1532: $end_table .= "</table>\n";
1533: return ($start_table, $end_table);
1.1 raeburn 1534: }
1535:
1.3 raeburn 1536: sub create_homepage {
1537: my ($cdom,$cnum,$name,$groupinfo,$tools) = @_;
1538: my $functionality = join(',',@{$tools});
1539: my $content = &Apache::lonnet::unescape($$groupinfo{description});
1540: $content=~s/\s+$//s;
1541: $content=~s/^\s+//s;
1542: $content=~s/\<br\s*\/*\>$//s;
1543: $content=&Apache::lonfeedback::clear_out_html($content,1);
1544:
1545: my %pageinfo = (
1546: 'aaa_title' => 'Group: '.$name,
1547: 'abb_links' => $functionality,
1548: 'bbb_content' => $content,
1549: 'ccc_webreferences' => '',
1550: 'uploaded.lastmodified' => time,
1551: );
1552: my $putresult = &Apache::lonnet::put('grppage_'.$name,\%pageinfo,$cdom,$cnum);
1553: return $putresult;
1.1 raeburn 1554: }
1555:
1.3 raeburn 1556:
1.1 raeburn 1557: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>