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