File:
[LON-CAPA] /
loncom /
interface /
lonuserutils.pm
Revision
1.20:
download - view:
text,
annotated -
select for diffs
Fri Dec 21 17:27:57 2007 UTC (16 years, 7 months ago) by
raeburn
Branches:
MAIN
CVS tags:
HEAD
loncreateuser.pm
- &lonuserutils::can_modify_userinfo() used to determine if personal info field can be modified.
- Replace $home with $uhome as name of homeserver variable for newly created user.
lonuserutils.pm
can_modify_userinfo() returns a hash with information about which personal data fields are modifiable, as determined by context (author, course or domain) and roles of user being modified. DC sets the domain configuration for user modification.
1: # The LearningOnline Network with CAPA
2: # Utility functions for managing LON-CAPA user accounts
3: #
4: # $Id: lonuserutils.pm,v 1.20 2007/12/21 17:27:57 raeburn Exp $
5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA#
23: # /home/httpd/html/adm/gpl.txt
24: #
25: # http://www.lon-capa.org/
26: #
27: #
28: ###############################################################
29: ###############################################################
30:
31: package Apache::lonuserutils;
32:
33: use strict;
34: use Apache::lonnet;
35: use Apache::loncommon();
36: use Apache::lonhtmlcommon;
37: use Apache::lonlocal;
38: use Apache::longroup;
39: use LONCAPA qw(:DEFAULT :match);
40:
41: ###############################################################
42: ###############################################################
43: # Drop student from all sections of a course, except optional $csec
44: sub modifystudent {
45: my ($udom,$unam,$courseid,$csec,$desiredhost)=@_;
46: # if $csec is undefined, drop the student from all the courses matching
47: # this one. If $csec is defined, drop them from all other sections of
48: # this course and add them to section $csec
49: my ($cnum,$cdom) = &get_course_identity($courseid);
50: my %roles = &Apache::lonnet::dump('roles',$udom,$unam);
51: my ($tmp) = keys(%roles);
52: # Bail out if we were unable to get the students roles
53: return "$1" if ($tmp =~ /^(con_lost|error|no_such_host)/i);
54: # Go through the roles looking for enrollment in this course
55: my $result = '';
56: foreach my $course (keys(%roles)) {
57: if ($course=~m{^/\Q$cdom\E/\Q$cnum\E(?:\/)*(?:\s+)*(\w+)*\_st$}) {
58: # We are in this course
59: my $section=$1;
60: $section='' if ($course eq "/$cdom/$cnum".'_st');
61: if (defined($csec) && $section eq $csec) {
62: $result .= 'ok:';
63: } elsif ( ((!$section) && (!$csec)) || ($section ne $csec) ) {
64: my (undef,$end,$start)=split(/\_/,$roles{$course});
65: my $now=time;
66: # if this is an active role
67: if (!($start && ($now<$start)) || !($end && ($now>$end))) {
68: my $reply=&Apache::lonnet::modifystudent
69: # dom name id mode pass f m l g
70: ($udom,$unam,'', '', '',undef,undef,undef,undef,
71: $section,time,undef,undef,$desiredhost);
72: $result .= $reply.':';
73: }
74: }
75: }
76: }
77: if ($result eq '') {
78: $result = 'Unable to find section for this student';
79: } else {
80: $result =~ s/(ok:)+/ok/g;
81: }
82: return $result;
83: }
84:
85: sub modifyuserrole {
86: my ($context,$setting,$changeauth,$cid,$udom,$uname,$uid,$umode,$upass,
87: $first,$middle,$last,$gene,$sec,$forceid,$desiredhome,$email,$role,
88: $end,$start,$checkid) = @_;
89: my ($scope,$userresult,$authresult,$roleresult,$idresult);
90: if ($setting eq 'course' || $context eq 'course') {
91: $scope = '/'.$cid;
92: $scope =~ s/\_/\//g;
93: if ($role ne 'cc' && $sec ne '') {
94: $scope .='/'.$sec;
95: }
96: } elsif ($context eq 'domain') {
97: $scope = '/'.$env{'request.role.domain'}.'/';
98: } elsif ($context eq 'author') {
99: $scope = '/'.$env{'user.domain'}.'/'.$env{'user.name'};
100: }
101: if ($context eq 'domain') {
102: my $uhome = &Apache::lonnet::homeserver($uname,$udom);
103: if ($uhome ne 'no_host') {
104: if (($changeauth eq 'Yes') && (&Apache::lonnet::allowed('mau',$udom))) {
105: if ((($umode =~ /^krb4|krb5|internal$/) && $upass ne '') ||
106: ($umode eq 'localauth')) {
107: $authresult = &Apache::lonnet::modifyuserauth($udom,$uname,$umode,$upass);
108: }
109: }
110: if (($forceid) && (&Apache::lonnet::allowed('mau',$udom)) &&
111: ($env{'form.recurseid'}) && ($checkid)) {
112: my %userupdate = (
113: lastname => $last,
114: middlename => $middle,
115: firstname => $first,
116: generation => $gene,
117: id => $uid,
118: );
119: $idresult = &propagate_id_change($uname,$udom,\%userupdate);
120: }
121: }
122: }
123: $userresult =
124: &Apache::lonnet::modifyuser($udom,$uname,$uid,$umode,$upass,$first,
125: $middle,$last,$gene,$forceid,$desiredhome,
126: $email,$role,$start,$end);
127: if ($userresult eq 'ok') {
128: if ($role ne '') {
129: $roleresult = &Apache::lonnet::assignrole($udom,$uname,$scope,
130: $role,$end,$start);
131: }
132: }
133: return ($userresult,$authresult,$roleresult,$idresult);
134: }
135:
136: sub propagate_id_change {
137: my ($uname,$udom,$user) = @_;
138: my (@types,@roles);
139: @types = ('active','future');
140: @roles = ('st');
141: my $idresult;
142: my %roleshash = &Apache::lonnet::get_my_roles($uname,
143: $udom,'userroles',\@types,\@roles);
144: my %args = (
145: one_time => 1,
146: );
147: foreach my $item (keys(%roleshash)) {
148: my ($cnum,$cdom,$role) = split(/:/,$item);
149: my ($start,$end) = split(/:/,$roleshash{$item});
150: if (&Apache::lonnet::is_course($cdom,$cnum)) {
151: my $result = &update_classlist($cdom,$cnum,$udom,$uname,$user);
152: my %coursehash =
153: &Apache::lonnet::coursedescription($cdom.'_'.$cnum,\%args);
154: my $cdesc = $coursehash{'description'};
155: if ($cdesc eq '') {
156: $cdesc = $cdom.'_'.$cnum;
157: }
158: if ($result eq 'ok') {
159: $idresult .= &mt('Classlist update for "[_1]" in "[_2]".',$uname.':'.$udom,$cdesc).'<br />'."\n";
160: } else {
161: $idresult .= &mt('Error: "[_1]" during classlist update for "[_2]" in "[_3]".',$result,$uname.':'.$udom,$cdesc).'<br />'."\n";
162: }
163: }
164: }
165: return $idresult;
166: }
167:
168: sub update_classlist {
169: my ($cdom,$cnum,$udom,$uname,$user) = @_;
170: my ($uid,$classlistentry);
171: my $fullname =
172: &Apache::lonnet::format_name($user->{'firstname'},$user->{'middlename'},
173: $user->{'lastname'},$user->{'generation'},
174: 'lastname');
175: my %classhash = &Apache::lonnet::get('classlist',[$uname.':'.$udom],
176: $cdom,$cnum);
177: my @classinfo = split(/:/,$classhash{$uname.':'.$udom});
178: my $ididx=&Apache::loncoursedata::CL_ID() - 2;
179: my $nameidx=&Apache::loncoursedata::CL_FULLNAME() - 2;
180: for (my $i=0; $i<@classinfo; $i++) {
181: if ($i == $ididx) {
182: if (defined($user->{'id'})) {
183: $classlistentry .= $user->{'id'}.':';
184: } else {
185: $classlistentry .= $classinfo[$i].':';
186: }
187: } elsif ($i == $nameidx) {
188: $classlistentry .= $fullname.':';
189: } else {
190: $classlistentry .= $classinfo[$i].':';
191: }
192: }
193: $classlistentry =~ s/:$//;
194: my $reply=&Apache::lonnet::cput('classlist',
195: {"$uname:$udom" => $classlistentry},
196: $cdom,$cnum);
197: if (($reply eq 'ok') || ($reply eq 'delayed')) {
198: return 'ok';
199: } else {
200: return 'error: '.$reply;
201: }
202: }
203:
204:
205: ###############################################################
206: ###############################################################
207: # build a role type and role selection form
208: sub domain_roles_select {
209: # Set up the role type and role selection boxes when in
210: # domain context
211: #
212: # Role types
213: my @roletypes = ('domain','author','course');
214: my %lt = &role_type_names();
215: #
216: # build up the menu information to be passed to
217: # &Apache::loncommon::linked_select_forms
218: my %select_menus;
219: if ($env{'form.roletype'} eq '') {
220: $env{'form.roletype'} = 'domain';
221: }
222: foreach my $roletype (@roletypes) {
223: # set up the text for this domain
224: $select_menus{$roletype}->{'text'}= $lt{$roletype};
225: # we want a choice of 'default' as the default in the second menu
226: if ($env{'form.roletype'} ne '') {
227: $select_menus{$roletype}->{'default'} = $env{'form.showrole'};
228: } else {
229: $select_menus{$roletype}->{'default'} = 'Any';
230: }
231: # Now build up the other items in the second menu
232: my @roles;
233: if ($roletype eq 'domain') {
234: @roles = &domain_roles();
235: } elsif ($roletype eq 'author') {
236: @roles = &construction_space_roles();
237: } else {
238: my $custom = 1;
239: @roles = &course_roles('domain',undef,$custom);
240: }
241: my $order = ['Any',@roles];
242: $select_menus{$roletype}->{'order'} = $order;
243: foreach my $role (@roles) {
244: if ($role eq 'cr') {
245: $select_menus{$roletype}->{'select2'}->{$role} =
246: &mt('Custom role');
247: } else {
248: $select_menus{$roletype}->{'select2'}->{$role} =
249: &Apache::lonnet::plaintext($role);
250: }
251: }
252: $select_menus{$roletype}->{'select2'}->{'Any'} = &mt('Any');
253: }
254: my $result = &Apache::loncommon::linked_select_forms
255: ('studentform',(' 'x3).&mt('Role: '),$env{'form.roletype'},
256: 'roletype','showrole',\%select_menus,['domain','author','course']);
257: return $result;
258: }
259:
260: ###############################################################
261: ###############################################################
262: sub hidden_input {
263: my ($name,$value) = @_;
264: return '<input type="hidden" name="'.$name.'" value="'.$value.'" />'."\n";
265: }
266:
267: sub print_upload_manager_header {
268: my ($r,$datatoken,$distotal,$krbdefdom,$context)=@_;
269: my $javascript;
270: #
271: if (! exists($env{'form.upfile_associate'})) {
272: $env{'form.upfile_associate'} = 'forward';
273: }
274: if ($env{'form.associate'} eq 'Reverse Association') {
275: if ( $env{'form.upfile_associate'} ne 'reverse' ) {
276: $env{'form.upfile_associate'} = 'reverse';
277: } else {
278: $env{'form.upfile_associate'} = 'forward';
279: }
280: }
281: if ($env{'form.upfile_associate'} eq 'reverse') {
282: $javascript=&upload_manager_javascript_reverse_associate();
283: } else {
284: $javascript=&upload_manager_javascript_forward_associate();
285: }
286: #
287: # Deal with restored settings
288: my $password_choice = '';
289: if (exists($env{'form.ipwd_choice'}) &&
290: $env{'form.ipwd_choice'} ne '') {
291: # If a column was specified for password, assume it is for an
292: # internal password. This is a bug waiting to be filed (could be
293: # local or krb auth instead of internal) but I do not have the
294: # time to mess around with this now.
295: $password_choice = 'int';
296: }
297: #
298: my $javascript_validations =
299: &javascript_validations('auth',$krbdefdom,$password_choice,undef,
300: $env{'request.role.domain'});
301: my $checked=(($env{'form.noFirstLine'})?' checked="checked" ':'');
302: $r->print(&mt('Total number of records found in file: <b>[_1]</b>.',$distotal).
303: "<br />\n");
304: $r->print('<div class="LC_left_float"><h3>'.
305: &mt('Identify fields in uploaded list')."</h3>\n");
306: $r->print(&mt('Enter as many fields as you can.<br /> The system will inform you and bring you back to this page, <br /> if the data selected are insufficient to add users.')."<br />\n");
307: $r->print(&hidden_input('action','upload').
308: &hidden_input('state','got_file').
309: &hidden_input('associate','').
310: &hidden_input('datatoken',$datatoken).
311: &hidden_input('fileupload',$env{'form.fileupload'}).
312: &hidden_input('upfiletype',$env{'form.upfiletype'}).
313: &hidden_input('upfile_associate',$env{'form.upfile_associate'}));
314: $r->print('<br /><input type="button" value="Reverse Association" '.
315: 'name="'.&mt('Reverse Association').'" '.
316: 'onClick="javascript:this.form.associate.value=\'Reverse Association\';submit(this.form);" />');
317: $r->print('<label><input type="checkbox" name="noFirstLine"'.$checked.'/>'.
318: &mt('Ignore First Line').'</label>');
319: $r->print("<br /><br />\n".
320: '<script type="text/javascript" language="Javascript">'."\n".
321: $javascript."\n".$javascript_validations.'</script>');
322: }
323:
324: ###############################################################
325: ###############################################################
326: sub javascript_validations {
327: my ($mode,$krbdefdom,$curr_authtype,$curr_authfield,$domain)=@_;
328: my $authheader;
329: if ($mode eq 'auth') {
330: my %param = ( formname => 'studentform',
331: kerb_def_dom => $krbdefdom,
332: curr_authtype => $curr_authtype);
333: $authheader = &Apache::loncommon::authform_header(%param);
334: } elsif ($mode eq 'createcourse') {
335: my %param = ( formname => 'ccrs',
336: kerb_def_dom => $krbdefdom,
337: curr_authtype => $curr_authtype );
338: $authheader = &Apache::loncommon::authform_header(%param);
339: } elsif ($mode eq 'modifycourse') {
340: my %param = ( formname => 'cmod',
341: kerb_def_dom => $krbdefdom,
342: mode => 'modifycourse',
343: curr_authtype => $curr_authtype,
344: curr_autharg => $curr_authfield );
345: $authheader = &Apache::loncommon::authform_header(%param);
346: }
347:
348: my %alert = &Apache::lonlocal::texthash
349: (username => 'You need to specify the username field.',
350: authen => 'You must choose an authentication type.',
351: krb => 'You need to specify the Kerberos domain.',
352: ipass => 'You need to specify the initial password.',
353: name => 'The optional name field was not specified.',
354: snum => 'The optional ID number field was not specified.',
355: section => 'The optional section field was not specified.',
356: email => 'The optional email address field was not specified.',
357: role => 'The optional role field was not specified.',
358: continue => 'Continue adding users?',
359: );
360:
361: # my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
362: my $function_name =(<<END);
363: function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail) {
364: END
365: my ($authnum,%can_assign) = &Apache::loncommon::get_assignable_auth($domain);
366: my $auth_checks;
367: if ($mode eq 'createcourse') {
368: $auth_checks .= (<<END);
369: if (vf.autoadds[0].checked == true) {
370: if (current.radiovalue == null || current.radiovalue == 'nochange') {
371: alert('$alert{'authen'}');
372: return;
373: }
374: }
375: END
376: } else {
377: $auth_checks .= (<<END);
378: var foundatype=0;
379: if (founduname==0) {
380: alert('$alert{'username'}');
381: return;
382: }
383:
384: END
385: if ($authnum > 1) {
386: $auth_checks .= (<<END);
387: if (current.radiovalue == null || current.radiovalue == '' || current.radiovalue == 'nochange') {
388: // They did not check any of the login radiobuttons.
389: alert('$alert{'authen'}');
390: return;
391: }
392: END
393: }
394: }
395: if ($mode eq 'createcourse') {
396: $auth_checks .= "
397: if ( (vf.autoadds[0].checked == true) &&
398: (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '') ) {
399: ";
400: } elsif ($mode eq 'modifycourse') {
401: $auth_checks .= "
402: if (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '') {
403: ";
404: }
405: if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
406: $auth_checks .= (<<END);
407: var alertmsg = '';
408: switch (current.radiovalue) {
409: case 'krb':
410: alertmsg = '$alert{'krb'}';
411: break;
412: default:
413: alertmsg = '';
414: }
415: if (alertmsg != '') {
416: alert(alertmsg);
417: return;
418: }
419: }
420: END
421: } else {
422: $auth_checks .= (<<END);
423: foundatype=1;
424: if (current.argfield == null || current.argfield == '') {
425: var alertmsg = '';
426: switch (current.value) {
427: case 'krb':
428: alertmsg = '$alert{'krb'}';
429: break;
430: case 'loc':
431: case 'fsys':
432: alertmsg = '$alert{'ipass'}';
433: break;
434: case 'fsys':
435: alertmsg = '';
436: break;
437: default:
438: alertmsg = '';
439: }
440: if (alertmsg != '') {
441: alert(alertmsg);
442: return;
443: }
444: }
445: END
446: }
447: my $section_checks;
448: my $optional_checks = '';
449: if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
450: $optional_checks = (<<END);
451: vf.submit();
452: }
453: END
454: } else {
455: $section_checks = §ion_check_js();
456: $optional_checks = (<<END);
457: var message='';
458: if (foundname==0) {
459: message='$alert{'name'}';
460: }
461: if (foundid==0) {
462: if (message!='') {
463: message+='\\n';
464: }
465: message+='$alert{'snum'}';
466: }
467: if (foundsec==0) {
468: if (message!='') {
469: message+='\\n';
470: }
471: }
472: if (foundemail==0) {
473: if (message!='') {
474: message+='\\n';
475: }
476: message+='$alert{'email'}';
477: }
478: if (message!='') {
479: message+= '\\n$alert{'continue'}';
480: if (confirm(message)) {
481: vf.state.value='enrolling';
482: vf.submit();
483: }
484: } else {
485: vf.state.value='enrolling';
486: vf.submit();
487: }
488: }
489: END
490: }
491: my $result = $function_name;
492: if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
493: $result .= $auth_checks;
494: }
495: $result .= $optional_checks."\n".$section_checks;
496: if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
497: $result .= $authheader;
498: }
499: return $result;
500: }
501: ###############################################################
502: ###############################################################
503: sub upload_manager_javascript_forward_associate {
504: return(<<ENDPICK);
505: function verify(vf,sec_caller) {
506: var founduname=0;
507: var foundpwd=0;
508: var foundname=0;
509: var foundid=0;
510: var foundsec=0;
511: var foundemail=0;
512: var foundrole=0;
513: var tw;
514: for (i=0;i<=vf.nfields.value;i++) {
515: tw=eval('vf.f'+i+'.selectedIndex');
516: if (tw==1) { founduname=1; }
517: if ((tw>=2) && (tw<=6)) { foundname=1; }
518: if (tw==7) { foundid=1; }
519: if (tw==8) { foundsec=1; }
520: if (tw==9) { foundpwd=1; }
521: if (tw==10) { foundemail=1; }
522: if (tw==11) { foundrole=1; }
523: }
524: verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole);
525: }
526:
527: //
528: // vf = this.form
529: // tf = column number
530: //
531: // values of nw
532: //
533: // 0 = none
534: // 1 = username
535: // 2 = names (lastname, firstnames)
536: // 3 = fname (firstname)
537: // 4 = mname (middlename)
538: // 5 = lname (lastname)
539: // 6 = gen (generation)
540: // 7 = id
541: // 8 = section
542: // 9 = ipwd (password)
543: // 10 = email address
544: // 11 = role
545:
546: function flip(vf,tf) {
547: var nw=eval('vf.f'+tf+'.selectedIndex');
548: var i;
549: // make sure no other columns are labeled the same as this one
550: for (i=0;i<=vf.nfields.value;i++) {
551: if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {
552: eval('vf.f'+i+'.selectedIndex=0;')
553: }
554: }
555: // If we set this to 'lastname, firstnames', clear out all the ones
556: // set to 'fname','mname','lname','gen' (3,4,5,6) currently.
557: if (nw==2) {
558: for (i=0;i<=vf.nfields.value;i++) {
559: if ((eval('vf.f'+i+'.selectedIndex')>=3) &&
560: (eval('vf.f'+i+'.selectedIndex')<=6)) {
561: eval('vf.f'+i+'.selectedIndex=0;')
562: }
563: }
564: }
565: // If we set this to one of 'fname','mname','lname','gen' (3,4,5,6),
566: // clear out any that are set to 'lastname, firstnames' (2)
567: if ((nw>=3) && (nw<=6)) {
568: for (i=0;i<=vf.nfields.value;i++) {
569: if (eval('vf.f'+i+'.selectedIndex')==2) {
570: eval('vf.f'+i+'.selectedIndex=0;')
571: }
572: }
573: }
574: // If we set the password, make the password form below correspond to
575: // the new value.
576: if (nw==9) {
577: changed_radio('int',document.studentform);
578: set_auth_radio_buttons('int',document.studentform);
579: vf.intarg.value='';
580: vf.krbarg.value='';
581: vf.locarg.value='';
582: }
583: }
584:
585: function clearpwd(vf) {
586: var i;
587: for (i=0;i<=vf.nfields.value;i++) {
588: if (eval('vf.f'+i+'.selectedIndex')==9) {
589: eval('vf.f'+i+'.selectedIndex=0;')
590: }
591: }
592: }
593:
594: ENDPICK
595: }
596:
597: ###############################################################
598: ###############################################################
599: sub upload_manager_javascript_reverse_associate {
600: return(<<ENDPICK);
601: function verify(vf,sec_caller) {
602: var founduname=0;
603: var foundpwd=0;
604: var foundname=0;
605: var foundid=0;
606: var foundsec=0;
607: var foundrole=0;
608: var tw;
609: for (i=0;i<=vf.nfields.value;i++) {
610: tw=eval('vf.f'+i+'.selectedIndex');
611: if (i==0 && tw!=0) { founduname=1; }
612: if (((i>=1) && (i<=5)) && tw!=0 ) { foundname=1; }
613: if (i==6 && tw!=0) { foundid=1; }
614: if (i==7 && tw!=0) { foundsec=1; }
615: if (i==8 && tw!=0) { foundpwd=1; }
616: if (i==9 && tw!=0) { foundrole=1; }
617: }
618: verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundrole);
619: }
620:
621: function flip(vf,tf) {
622: var nw=eval('vf.f'+tf+'.selectedIndex');
623: var i;
624: // picked the all one name field, reset the other name ones to blank
625: if (tf==1 && nw!=0) {
626: for (i=2;i<=5;i++) {
627: eval('vf.f'+i+'.selectedIndex=0;')
628: }
629: }
630: //picked one of the piecewise name fields, reset the all in
631: //one field to blank
632: if ((tf>=2) && (tf<=5) && (nw!=0)) {
633: eval('vf.f1.selectedIndex=0;')
634: }
635: // intial password specified, pick internal authentication
636: if (tf==8 && nw!=0) {
637: changed_radio('int',document.studentform);
638: set_auth_radio_buttons('int',document.studentform);
639: vf.krbarg.value='';
640: vf.intarg.value='';
641: vf.locarg.value='';
642: }
643: }
644:
645: function clearpwd(vf) {
646: var i;
647: if (eval('vf.f8.selectedIndex')!=0) {
648: eval('vf.f8.selectedIndex=0;')
649: }
650: }
651: ENDPICK
652: }
653:
654: ###############################################################
655: ###############################################################
656: sub print_upload_manager_footer {
657: my ($r,$i,$keyfields,$defdom,$today,$halfyear,$context)=@_;
658: my $formname;
659: if ($context eq 'course') {
660: $formname = 'document.studentform';
661: } elsif ($context eq 'author') {
662: $formname = 'document.studentform';
663: } elsif ($context eq 'domain') {
664: $formname = 'document.studentform';
665: }
666: my ($krbdef,$krbdefdom) =
667: &Apache::loncommon::get_kerberos_defaults($defdom);
668: my %param = ( formname => $formname,
669: kerb_def_dom => $krbdefdom,
670: kerb_def_auth => $krbdef
671: );
672: if (exists($env{'form.ipwd_choice'}) &&
673: defined($env{'form.ipwd_choice'}) &&
674: $env{'form.ipwd_choice'} ne '') {
675: $param{'curr_authtype'} = 'int';
676: }
677: my $krbform = &Apache::loncommon::authform_kerberos(%param);
678: my $intform = &Apache::loncommon::authform_internal(%param);
679: my $locform = &Apache::loncommon::authform_local(%param);
680: my $date_table = &date_setting_table(undef,undef,$context);
681:
682: my $Str = "\n".'<div class="LC_left_float">';
683: $Str .= &hidden_input('nfields',$i);
684: $Str .= &hidden_input('keyfields',$keyfields);
685: $Str .= "<h3>".&mt('Login Type')."</h3>\n";
686: if ($context eq 'domain') {
687: $Str .= '<p>'.&mt('Change authentication for existing users to these settings?').' <span class="LC_nobreak"><label><input type="radio" name="changeauth" value="No" checked="checked" />'.&mt('No').'</label> <label><input type="radio" name="changeauth" value="Yes" />'.&mt('Yes').'</label></span></p>';
688: } else {
689: $Str .= "<p>\n".
690: &mt('Note: this will not take effect if the user already exists').
691: &Apache::loncommon::help_open_topic('Auth_Options').
692: "</p>\n";
693: }
694: $Str .= &set_login($defdom,$krbform,$intform,$locform);
695: my ($home_server_pick,$numlib) =
696: &Apache::loncommon::home_server_form_item($defdom,'lcserver',
697: 'default','hide');
698: if ($numlib > 1) {
699: $Str .= '<h3>'.&mt('LON-CAPA Home Server for New Users')."</h3>\n".
700: &mt('LON-CAPA domain: [_1] with home server: [_2]',$defdom,
701: $home_server_pick).'<br />';
702: } else {
703: $Str .= $home_server_pick;
704: }
705: $Str .= '<h3>'.&mt('Starting and Ending Dates').
706: "</h3>\n";
707: $Str .= "<p>\n".$date_table."</p>\n";
708: if ($context eq 'domain') {
709: $Str .= '<h3>'.&mt('Settings for assigning roles:').'</h3>'."\n".
710: &mt('Pick the action to take on roles for these users:').'<br /><span class="LC_nobreak"><label><input type="radio" name="roleaction" value="norole" checked="checked" /> '.&mt('No role changes').'</label> <label><input type="radio" name="roleaction" value="domain" /> '.&mt('Add a domain role').'</label> <label><input type="radio" name="roleaction" value="course" /> '.&mt('Add a course role').'</label></span>';
711: }
712: if ($context eq 'author') {
713: $Str .= '<h3>'.&mt('Default role')."</h3>\n".
714: &mt('Choose the role to assign to users without one specified in the uploaded file');
715: } elsif ($context eq 'course') {
716: $Str .= '<h3>'.&mt('Default role and section')."</h3>\n".
717: &mt('Choose the role and/or section to assign to users without one specified in the uploaded file');
718: } else {
719: $Str .= '<br /><br /><b>'.&mt('Default role and/or section')."</b><br />\n".
720: &mt('Role and/or section for users without one in the uploaded file.');
721: }
722: $Str .= '<br /><br />';
723: my ($options,$cb_script,$coursepick) = &default_role_selector($context,'defaultrole',1);
724: if ($context eq 'domain') {
725: $Str .= '<span class="LC_role_level">'.&mt('Domain Level').'</span><br />'.$options.'<br /><br /><span class="LC_role_level">'.&mt('Course Level').'</span><br />'.$cb_script.$coursepick;
726: } elsif ($context eq 'author') {
727: $Str .= $options;
728: } else {
729: $Str .= '<table><tr><td><span class="LC_nobreak"<b>'.&mt('role').': </b>'.
730: $options.'</span></td><td> </td><td><span class="LC_nobreak">'.
731: '<b>'.&mt('section').': </b><input type="text" name="section" value="" size="12" /></span></td></tr></table>';
732: }
733: if ($context eq 'course') {
734: $Str .= "<h3>".&mt('Full Update')."</h3>\n".
735: '<label><input type="checkbox" name="fullup" value="yes">'.
736: ' '.&mt('Full update (also print list of users not enrolled anymore)').
737: "</label></p>\n";
738: }
739: if ($context eq 'course' || $context eq 'domain') {
740: $Str .= &forceid_change($context);
741: }
742: $Str .= '</div><div class="LC_clear_float_footer"><br /><input type="button"'.
743: 'onClick="javascript:verify(this.form,this.form.csec)" '.
744: 'value="Update Users" />'."<br />\n";
745: if ($context eq 'course') {
746: $Str .= &mt('Note: for large courses, this operation may be time '.
747: 'consuming');
748: }
749: $Str .= '</div>';
750: $r->print($Str);
751: return;
752: }
753:
754: sub forceid_change {
755: my ($context) = @_;
756: my $output =
757: "<h3>".&mt('ID/Student Number')."</h3>\n".
758: "<p>\n".'<label><input type="checkbox" name="forceid" value="yes">'.
759: &mt('Disable ID/Student Number Safeguard and Force Change '.
760: 'of Conflicting IDs').'</label><br />'."\n".
761: &mt('(only do if you know what you are doing.)')."</br><br />\n";
762: if ($context eq 'domain') {
763: $output .= '<label><input type="checkbox" name="recurseid"'.
764: ' value="yes">'.
765: &mt('Update ID/Student Number in courses in which user is Active/Future student,<br />(if forcing change).').
766: '</label></p>'."\n";
767: }
768: return $output;
769: }
770:
771: ###############################################################
772: ###############################################################
773: sub print_upload_manager_form {
774: my ($r,$context) = @_;
775: my $firstLine;
776: my $datatoken;
777: if (!$env{'form.datatoken'}) {
778: $datatoken=&Apache::loncommon::upfile_store($r);
779: } else {
780: $datatoken=$env{'form.datatoken'};
781: &Apache::loncommon::load_tmp_file($r);
782: }
783: my @records=&Apache::loncommon::upfile_record_sep();
784: if($env{'form.noFirstLine'}){
785: $firstLine=shift(@records);
786: }
787: my $total=$#records;
788: my $distotal=$total+1;
789: my $today=time;
790: my $halfyear=$today+15552000;
791: #
792: # Restore memorized settings
793: my $col_setting_names = { 'username_choice' => 'scalar', # column settings
794: 'names_choice' => 'scalar',
795: 'fname_choice' => 'scalar',
796: 'mname_choice' => 'scalar',
797: 'lname_choice' => 'scalar',
798: 'gen_choice' => 'scalar',
799: 'id_choice' => 'scalar',
800: 'sec_choice' => 'scalar',
801: 'ipwd_choice' => 'scalar',
802: 'email_choice' => 'scalar',
803: 'role_choice' => 'scalar',
804: };
805: my $defdom = $env{'request.role.domain'};
806: if ($context eq 'course') {
807: &Apache::loncommon::restore_course_settings('enrollment_upload',
808: $col_setting_names);
809: } else {
810: &Apache::loncommon::restore_settings($context,'user_upload',
811: $col_setting_names);
812: }
813: #
814: # Determine kerberos parameters as appropriate
815: my ($krbdef,$krbdefdom) =
816: &Apache::loncommon::get_kerberos_defaults($defdom);
817: #
818: &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom,$context);
819: my $i;
820: my $keyfields;
821: if ($total>=0) {
822: my @field=
823: (['username',&mt('Username'), $env{'form.username_choice'}],
824: ['names',&mt('Last Name, First Names'),$env{'form.names_choice'}],
825: ['fname',&mt('First Name'), $env{'form.fname_choice'}],
826: ['mname',&mt('Middle Names/Initials'),$env{'form.mname_choice'}],
827: ['lname',&mt('Last Name'), $env{'form.lname_choice'}],
828: ['gen', &mt('Generation'), $env{'form.gen_choice'}],
829: ['id', &mt('ID/Student Number'),$env{'form.id_choice'}],
830: ['sec', &mt('Section'), $env{'form.sec_choice'}],
831: ['ipwd', &mt('Initial Password'),$env{'form.ipwd_choice'}],
832: ['email',&mt('E-mail Address'), $env{'form.email_choice'}],
833: ['role',&mt('Role'), $env{'form.role_choice'}]);
834: if ($env{'form.upfile_associate'} eq 'reverse') {
835: &Apache::loncommon::csv_print_samples($r,\@records);
836: $i=&Apache::loncommon::csv_print_select_table($r,\@records,
837: \@field);
838: foreach (@field) {
839: $keyfields.=$_->[0].',';
840: }
841: chop($keyfields);
842: } else {
843: unshift(@field,['none','']);
844: $i=&Apache::loncommon::csv_samples_select_table($r,\@records,
845: \@field);
846: my %sone=&Apache::loncommon::record_sep($records[0]);
847: $keyfields=join(',',sort(keys(%sone)));
848: }
849: }
850: $r->print('</div>');
851: &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear,
852: $context);
853: }
854:
855: sub setup_date_selectors {
856: my ($starttime,$endtime,$mode,$nolink) = @_;
857: if (! defined($starttime)) {
858: $starttime = time;
859: unless ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
860: if (exists($env{'course.'.$env{'request.course.id'}.
861: '.default_enrollment_start_date'})) {
862: $starttime = $env{'course.'.$env{'request.course.id'}.
863: '.default_enrollment_start_date'};
864: }
865: }
866: }
867: if (! defined($endtime)) {
868: $endtime = time+(6*30*24*60*60); # 6 months from now, approx
869: unless ($mode eq 'createcourse') {
870: if (exists($env{'course.'.$env{'request.course.id'}.
871: '.default_enrollment_end_date'})) {
872: $endtime = $env{'course.'.$env{'request.course.id'}.
873: '.default_enrollment_end_date'};
874: }
875: }
876: }
877:
878: my $startdateform =
879: &Apache::lonhtmlcommon::date_setter('studentform','startdate',$starttime,
880: undef,undef,undef,undef,undef,undef,undef,$nolink);
881:
882: my $enddateform =
883: &Apache::lonhtmlcommon::date_setter('studentform','enddate',$endtime,
884: undef,undef,undef,undef,undef,undef,undef,$nolink);
885:
886: if ($mode eq 'create_enrolldates') {
887: $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
888: 'startenroll',
889: $starttime);
890: $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
891: 'endenroll',
892: $endtime);
893: }
894: if ($mode eq 'create_defaultdates') {
895: $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
896: 'startaccess',
897: $starttime);
898: $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
899: 'endaccess',
900: $endtime);
901: }
902: return ($startdateform,$enddateform);
903: }
904:
905:
906: sub get_dates_from_form {
907: my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
908: my $enddate = &Apache::lonhtmlcommon::get_date_from_form('enddate');
909: if ($env{'form.no_end_date'}) {
910: $enddate = 0;
911: }
912: return ($startdate,$enddate);
913: }
914:
915: sub date_setting_table {
916: my ($starttime,$endtime,$mode,$bulkaction) = @_;
917: my $nolink;
918: if ($bulkaction) {
919: $nolink = 1;
920: }
921: my ($startform,$endform) =
922: &setup_date_selectors($starttime,$endtime,$mode,$nolink);
923: my $dateDefault;
924: if ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
925: $dateDefault = ' ';
926: } elsif ($mode ne 'author' && $mode ne 'domain') {
927: if (($bulkaction eq 'reenable') ||
928: ($bulkaction eq 'activate') ||
929: ($bulkaction eq 'chgdates')) {
930: $dateDefault = '<span class="LC_nobreak">'.
931: '<label><input type="checkbox" name="makedatesdefault" /> '.
932: &mt('make these dates the default for future enrollment').
933: '</label></span>';
934: }
935: }
936: my $perpetual = '<span class="LC_nobreak"><label><input type="checkbox" name="no_end_date"';
937: if (defined($endtime) && $endtime == 0) {
938: $perpetual .= ' checked';
939: }
940: $perpetual.= ' /> '.&mt('no ending date').'</label></span>';
941: if ($mode eq 'create_enrolldates') {
942: $perpetual = ' ';
943: }
944: my $result = &Apache::lonhtmlcommon::start_pick_box()."\n";
945: $result .= &Apache::lonhtmlcommon::row_title(&mt('Starting Date'),
946: 'LC_oddrow_value')."\n".
947: $startform."\n".
948: &Apache::lonhtmlcommon::row_closure(1).
949: &Apache::lonhtmlcommon::row_title(&mt('Ending Date'),
950: 'LC_oddrow_value')."\n".
951: $endform.' '.$perpetual.
952: &Apache::lonhtmlcommon::row_closure(1).
953: &Apache::lonhtmlcommon::end_pick_box().'<br />';
954: if ($dateDefault) {
955: $result .= $dateDefault.'<br />'."\n";
956: }
957: return $result;
958: }
959:
960: sub make_dates_default {
961: my ($startdate,$enddate,$context) = @_;
962: my $result = '';
963: if ($context eq 'course') {
964: my ($cnum,$cdom) = &get_course_identity();
965: my $put_result = &Apache::lonnet::put('environment',
966: {'default_enrollment_start_date'=>$startdate,
967: 'default_enrollment_end_date' =>$enddate},$cdom,$cnum);
968: if ($put_result eq 'ok') {
969: $result .= &mt('Set default start and end dates for course').
970: '<br />'."\n";
971: #
972: # Refresh the course environment
973: &Apache::lonnet::coursedescription($env{'request.course.id'},
974: {'freshen_cache' => 1});
975: } else {
976: $result .= &mt('Unable to set default dates for course').":".$put_result.
977: '<br />';
978: }
979: }
980: return $result;
981: }
982:
983: sub default_role_selector {
984: my ($context,$checkpriv) = @_;
985: my %customroles;
986: my ($options,$coursepick,$cb_jscript);
987: if ($context ne 'author') {
988: %customroles = &my_custom_roles();
989: }
990:
991: my %lt=&Apache::lonlocal::texthash(
992: 'rol' => "Role",
993: 'grs' => "Section",
994: 'exs' => "Existing sections",
995: 'new' => "New section",
996: );
997: $options = '<select name="defaultrole">'."\n".
998: ' <option value="">'.&mt('Please select').'</option>'."\n";
999: if ($context eq 'course') {
1000: $options .= &default_course_roles($context,$checkpriv,%customroles);
1001: } elsif ($context eq 'author') {
1002: my @roles = &construction_space_roles($checkpriv);
1003: foreach my $role (@roles) {
1004: my $plrole=&Apache::lonnet::plaintext($role);
1005: $options .= ' <option value="'.$role.'">'.$plrole.'</option>'."\n";
1006: }
1007: } elsif ($context eq 'domain') {
1008: my @roles = &domain_roles($checkpriv);
1009: foreach my $role (@roles) {
1010: my $plrole=&Apache::lonnet::plaintext($role);
1011: $options .= ' <option value="'.$role.'">'.$plrole.'</option>';
1012: }
1013: my $courseform = &Apache::loncommon::selectcourse_link
1014: ('studentform','defaultcourse','defaultdomain','defaultdesc',"$env{'request.role.domain'}",undef,'Course');
1015: $cb_jscript =
1016: &Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'},'defaultsec','studentform');
1017: $coursepick = &Apache::loncommon::start_data_table().
1018: &Apache::loncommon::start_data_table_header_row().
1019: '<th>'.$courseform.'</th><th>'.$lt{'rol'}.'</th>'.
1020: '<th>'.$lt{'grs'}.'</th>'.
1021: &Apache::loncommon::end_data_table_header_row().
1022: &Apache::loncommon::start_data_table_row()."\n".
1023: '<td><input type="text" name="defaultdesc" value="" onFocus="this.blur();opencrsbrowser('."'studentform','defcourse','defdomain','coursedesc',''".')" /></td>'."\n".
1024: '<td><select name="courserole">'."\n".
1025: &default_course_roles($context,$checkpriv,%customroles)."\n".
1026: '</select></td><td>'.
1027: '<table class="LC_createuser">'.
1028: '<tr class="LC_section_row"><td valign"top">'.
1029: $lt{'exs'}.'<br /><select name="defaultsec">'.
1030: ' <option value=""><--'.&mt('Pick course first').
1031: '</select></td>'.
1032: '<td> </td>'.
1033: '<td valign="top">'.$lt{'new'}.'<br />'.
1034: '<input type="text" name="newsec" value="" size="5" />'.
1035: '<input type="hidden" name="groups" value="" /></td>'.
1036: '</tr></table></td>'.
1037: &Apache::loncommon::end_data_table_row().
1038: &Apache::loncommon::end_data_table()."\n".
1039: '<input type="hidden" name="defaultcourse" value="" />'.
1040: '<input type="hidden" name="defaultdomain" value="" />';
1041: }
1042: $options .= '</select>';
1043: return ($options,$cb_jscript,$coursepick);
1044: }
1045:
1046: sub default_course_roles {
1047: my ($context,$checkpriv,%customroles) = @_;
1048: my $output;
1049: my $custom = 1;
1050: my @roles = &course_roles($context,$checkpriv,$custom);
1051: foreach my $role (@roles) {
1052: my $plrole=&Apache::lonnet::plaintext($role);
1053: $output .= ' <option value="'.$role.'">'.$plrole.'</option>';
1054: }
1055: if (keys(%customroles) > 0) {
1056: my %customroles = &my_custom_roles();
1057: foreach my $cust (sort(keys(%customroles))) {
1058: my $custrole='cr_cr_'.$env{'user.domain'}.
1059: '_'.$env{'user.name'}.'_'.$cust;
1060: $output .= ' <option value="'.$custrole.'">'.$cust.'</option>';
1061: }
1062: }
1063: return $output;
1064: }
1065:
1066: sub construction_space_roles {
1067: my ($checkpriv) = @_;
1068: my @allroles = &roles_by_context('author');
1069: my @roles;
1070: if ($checkpriv) {
1071: foreach my $role (@allroles) {
1072: if (&Apache::lonnet::allowed('c'.$role,$env{'user.domain'}.'/'.$env{'user.name'})) {
1073: push(@roles,$role);
1074: }
1075: }
1076: return @roles;
1077: } else {
1078: return @allroles;
1079: }
1080: }
1081:
1082: sub domain_roles {
1083: my ($checkpriv) = @_;
1084: my @allroles = &roles_by_context('domain');
1085: my @roles;
1086: if ($checkpriv) {
1087: foreach my $role (@allroles) {
1088: if (&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) {
1089: push(@roles,$role);
1090: }
1091: }
1092: return @roles;
1093: } else {
1094: return @allroles;
1095: }
1096: }
1097:
1098: sub course_roles {
1099: my ($context,$checkpriv,$custom) = @_;
1100: my @allroles = &roles_by_context('course',$custom);
1101: my @roles;
1102: if ($context eq 'domain') {
1103: @roles = @allroles;
1104: } elsif ($context eq 'course') {
1105: if ($env{'request.course.id'}) {
1106: if ($checkpriv) {
1107: foreach my $role (@allroles) {
1108: if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {
1109: push(@roles,$role);
1110: } else {
1111: if ($role ne 'cc' && $env{'request.course.section'} ne '') {
1112: if (!&Apache::lonnet::allowed('c'.$role,
1113: $env{'request.course.id'}.'/'.
1114: $env{'request.course.section'})) {
1115: push(@roles,$role);
1116: }
1117: }
1118: }
1119: }
1120: } else {
1121: @roles = @allroles;
1122: }
1123: }
1124: }
1125: return @roles;
1126: }
1127:
1128: sub curr_role_permissions {
1129: my ($context,$setting,$checkpriv) = @_;
1130: my $custom = 1;
1131: my @roles;
1132: if ($context eq 'author') {
1133: @roles = &construction_space_roles($checkpriv);
1134: } elsif ($context eq 'domain') {
1135: if ($setting eq 'course') {
1136: @roles = &course_roles($context,$checkpriv,$custom);
1137: } else {
1138: @roles = &domain_roles($checkpriv);
1139: }
1140: } elsif ($context eq 'course') {
1141: @roles = &course_roles($context,$checkpriv,$custom);
1142: }
1143: return @roles;
1144: }
1145:
1146: # ======================================================= Existing Custom Roles
1147:
1148: sub my_custom_roles {
1149: my %returnhash=();
1150: my %rolehash=&Apache::lonnet::dump('roles');
1151: foreach my $key (keys %rolehash) {
1152: if ($key=~/^rolesdef\_(\w+)$/) {
1153: $returnhash{$1}=$1;
1154: }
1155: }
1156: return %returnhash;
1157: }
1158:
1159: sub print_userlist {
1160: my ($r,$mode,$permission,$context,$formname,$totcodes,$codetitles,
1161: $idlist,$idlist_titles) = @_;
1162: my $format = $env{'form.output'};
1163: if (! exists($env{'form.sortby'})) {
1164: $env{'form.sortby'} = 'username';
1165: }
1166: if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
1167: $env{'form.Status'} = 'Active';
1168: }
1169: my $status_select = &Apache::lonhtmlcommon::StatusOptions
1170: ($env{'form.Status'});
1171:
1172: if ($env{'form.showrole'} eq '') {
1173: if ($context eq 'course') {
1174: $env{'form.showrole'} = 'st';
1175: } else {
1176: $env{'form.showrole'} = 'Any';
1177: }
1178: }
1179: if (! defined($env{'form.output'}) ||
1180: $env{'form.output'} !~ /^(csv|excel|html)$/ ) {
1181: $env{'form.output'} = 'html';
1182: }
1183:
1184: my @statuses;
1185: if ($env{'form.Status'} eq 'Any') {
1186: @statuses = ('previous','active','future');
1187: } elsif ($env{'form.Status'} eq 'Expired') {
1188: @statuses = ('previous');
1189: } elsif ($env{'form.Status'} eq 'Active') {
1190: @statuses = ('active');
1191: } elsif ($env{'form.Status'} eq 'Future') {
1192: @statuses = ('future');
1193: }
1194:
1195: # if ($context eq 'course') {
1196: # $r->print(&display_adv_courseroles());
1197: # }
1198: #
1199: # Interface output
1200: $r->print('<form name="studentform" method="post" action="/adm/createuser">'."\n".
1201: '<input type="hidden" name="action" value="'.
1202: $env{'form.action'}.'" />');
1203: $r->print("<p>\n");
1204: if ($env{'form.action'} ne 'modifystudent') {
1205: my %lt=&Apache::lonlocal::texthash('csv' => "CSV",
1206: 'excel' => "Excel",
1207: 'html' => 'HTML');
1208: my $output_selector = '<select size="1" name="output" >';
1209: foreach my $outputformat ('html','csv','excel') {
1210: my $option = '<option value="'.$outputformat.'" ';
1211: if ($outputformat eq $env{'form.output'}) {
1212: $option .= 'selected ';
1213: }
1214: $option .='>'.$lt{$outputformat}.'</option>';
1215: $output_selector .= "\n".$option;
1216: }
1217: $output_selector .= '</select>';
1218: $r->print('<label>'.&mt('Output Format: [_1]',$output_selector).'</label>'.(' 'x3));
1219: }
1220: $r->print('<label>'.&mt('User Status: [_1]',$status_select).'</label>'.(' 'x3)."\n");
1221: my $roleselected = '';
1222: if ($env{'form.showrole'} eq 'Any') {
1223: $roleselected = ' selected="selected" ';
1224: }
1225: my $role_select;
1226: if ($context eq 'domain') {
1227: $role_select = &domain_roles_select();
1228: $r->print('<label>'.&mt('Role Type: [_1]',$role_select).'</label>');
1229: } else {
1230: $role_select = '<select name="showrole">'."\n".
1231: '<option value="Any" '.$roleselected.'>'.
1232: &mt('Any role').'</option>';
1233: my @poss_roles = &curr_role_permissions($context);
1234: foreach my $role (@poss_roles) {
1235: $roleselected = '';
1236: if ($role eq $env{'form.showrole'}) {
1237: $roleselected = ' selected="selected" ';
1238: }
1239: my $plrole=&Apache::lonnet::plaintext($role);
1240: $role_select .= '<option value="'.$role.'"'.$roleselected.'>'.$plrole.'</option>';
1241: }
1242: $roleselected = '';
1243: if ($env{'form.showrole'} eq 'cr') {
1244: $roleselected = ' selected="selected" ';
1245: }
1246: $role_select .= '<option value="cr"'.$roleselected.'>'.&mt('Custom role').'</option>'.
1247: '</select>';
1248: $r->print('<label>'.&mt('Role: [_1]',$role_select).'</label>');
1249: }
1250: if (!(($context eq 'domain') && ($env{'form.roletype'} eq 'course'))) {
1251: $r->print(&list_submit_button(&mt('Update Display'))."\n</p>\n");
1252: }
1253: my ($indexhash,$keylist) = &make_keylist_array();
1254: my (%userlist,%userinfo);
1255: if ($context eq 'domain' && $env{'form.roletype'} eq 'course') {
1256: my $courseform =
1257: &Apache::lonhtmlcommon::course_selection($formname,$totcodes,
1258: $codetitles,$idlist,$idlist_titles);
1259: $r->print('<p>'.&Apache::lonhtmlcommon::start_pick_box()."\n".
1260: &Apache::lonhtmlcommon::start_pick_box()."\n".
1261: &Apache::lonhtmlcommon::row_title(&mt('Select Course(s)'),
1262: 'LC_oddrow_value')."\n".
1263: $courseform."\n".
1264: &Apache::lonhtmlcommon::row_closure(1).
1265: &Apache::lonhtmlcommon::end_pick_box().'</p>'.
1266: '<p>'.&list_submit_button(&mt('Update Display')).
1267: "\n</p>\n");
1268: if ($env{'form.coursepick'}) {
1269: $r->print('<hr />'.&mt('Searching').' ...<br /> <br />');
1270: }
1271: } else {
1272: $r->print('<hr />'.&mt('Searching').' ...<br /> <br />');
1273: }
1274: $r->rflush();
1275: if ($context eq 'course') {
1276: my $classlist = &Apache::loncoursedata::get_classlist();
1277: my $secidx = &Apache::loncoursedata::CL_SECTION();
1278: foreach my $student (keys(%{$classlist})) {
1279: if (exists($permission->{'view_section'})) {
1280: if ($classlist->{$student}[$secidx] ne $permission->{'view_section'}) {
1281: next;
1282: } else {
1283: $userlist{$student} = $classlist->{$student};
1284: }
1285: } else {
1286: $userlist{$student} = $classlist->{$student};
1287: }
1288: }
1289: my $cid =$env{'request.course.id'};
1290: my ($cnum,$cdom) = &get_course_identity($cid);
1291: my $showroles;
1292: if ($env{'form.showrole'} ne 'Any') {
1293: $showroles = [$env{'form.showrole'}];
1294: } else {
1295: $showroles = undef;
1296: }
1297: my %advrolehash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef,
1298: \@statuses,$showroles);
1299: &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo,
1300: \%advrolehash,$permission);
1301: } else {
1302: my (%cstr_roles,%dom_roles);
1303: if ($context eq 'author') {
1304: # List co-authors and assistant co-authors
1305: my @possroles = &roles_by_context($context);
1306: %cstr_roles = &Apache::lonnet::get_my_roles(undef,undef,undef,
1307: \@statuses,\@possroles);
1308: &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo,
1309: \%cstr_roles,$permission);
1310: } elsif ($context eq 'domain') {
1311: if ($env{'form.roletype'} eq 'domain') {
1312: %dom_roles = &Apache::lonnet::get_domain_roles($env{'request.role.domain'});
1313: foreach my $key (keys(%dom_roles)) {
1314: if (ref($dom_roles{$key}) eq 'HASH') {
1315: &gather_userinfo($context,$format,\%userlist,$indexhash,
1316: \%userinfo,$dom_roles{$key},$permission);
1317: }
1318: }
1319: } elsif ($env{'form.roletype'} eq 'author') {
1320: my %dom_roles = &Apache::lonnet::get_domain_roles($env{'request.role.domain'},['au']);
1321: my %coauthors;
1322: foreach my $key (keys(%dom_roles)) {
1323: if (ref($dom_roles{$key}) eq 'HASH') {
1324: if ($env{'form.showrole'} eq 'au') {
1325: &gather_userinfo($context,$format,\%userlist,$indexhash,
1326: \%userinfo,$dom_roles{$key},$permission);
1327: } else {
1328: my @possroles;
1329: if ($env{'form.showrole'} eq 'Any') {
1330: my @possroles = &roles_by_context($context);
1331: } else {
1332: @possroles = ($env{'form.showrole'});
1333: }
1334: foreach my $author (sort(keys(%{$dom_roles{$key}}))) {
1335: my ($role,$authorname,$authordom) = split(/:/,$author);
1336: my $extent = '/'.$authordom.'/'.$authorname;
1337: %{$coauthors{$extent}} =
1338: &Apache::lonnet::get_my_roles($authorname,
1339: $authordom,undef,\@statuses,\@possroles);
1340: }
1341: &gather_userinfo($context,$format,\%userlist,
1342: $indexhash,\%userinfo,\%coauthors,$permission);
1343: }
1344: }
1345: }
1346: } elsif ($env{'form.roletype'} eq 'course') {
1347: if ($env{'form.coursepick'}) {
1348: my %courses = &process_coursepick();
1349: my %allusers;
1350: foreach my $cid (keys(%courses)) {
1351: my %coursehash =
1352: &Apache::lonnet::coursedescription($cid,{'one_time' => 1});
1353: my ($cnum,$cdom,$cdesc) = &get_course_identity($cid);
1354: next if ($cnum eq '' || $cdom eq '');
1355: my $custom = 1;
1356: my (@roles,@sections,%access,%users,%userdata,
1357: %statushash);
1358: if ($env{'form.showrole'} eq 'Any') {
1359: @roles = &course_roles($context,undef,$custom);
1360: unshift(@roles,'cr');
1361: } else {
1362: @roles = ($env{'form.showrole'});
1363: }
1364: foreach my $role (@roles) {
1365: %{$users{$role}} = ();
1366: }
1367: foreach my $type (@statuses) {
1368: $access{$type} = $type;
1369: }
1370: &Apache::loncommon::get_course_users($cdom,$cnum,\%access,\@roles,\@sections,\%users,\%userdata,\%statushash);
1371: foreach my $user (keys(%userdata)) {
1372: next if (ref($userinfo{$user}) eq 'HASH');
1373: foreach my $item ('fullname','id') {
1374: $userinfo{$user}{$item} = $userdata{$user}[$indexhash->{$item}];
1375: }
1376: }
1377: foreach my $role (keys(%users)) {
1378: foreach my $user (keys(%{$users{$role}})) {
1379: my $uniqid = $user.':'.$role;
1380: $allusers{$uniqid}{$cid} = { desc => $cdesc,
1381: secs => $statushash{$user}{$role},
1382: };
1383: }
1384: }
1385: }
1386: &gather_userinfo($context,$format,\%userlist,$indexhash,
1387: \%userinfo,\%allusers,$permission);
1388: } else {
1389: $r->print('<input type="hidden" name="phase" value="'.
1390: $env{'form.phase'}.'" /></form>');
1391: return;
1392: }
1393: }
1394: }
1395: }
1396: if (keys(%userlist) == 0) {
1397: if ($context eq 'author') {
1398: $r->print(&mt('There are no co-authors to display.')."\n");
1399: } elsif ($context eq 'domain') {
1400: if ($env{'form.roletype'} eq 'domain') {
1401: $r->print(&mt('There are no users with domain roles to display.')."\n");
1402: } elsif ($env{'form.roletype'} eq 'author') {
1403: $r->print(&mt('There are no authors or co-authors to display.')."\n");
1404: } elsif ($env{'form.roletype'} eq 'course') {
1405: $r->print(&mt('There are no course users to display')."\n");
1406: }
1407: } elsif ($context eq 'course') {
1408: $r->print(&mt('There are no course users to display.')."\n");
1409: }
1410: } else {
1411: # Print out the available choices
1412: my $usercount;
1413: if ($env{'form.action'} eq 'modifystudent') {
1414: ($usercount) = &show_users_list($r,$context,'view',$permission,
1415: $env{'form.Status'},\%userlist,$keylist);
1416: } else {
1417: ($usercount) = &show_users_list($r,$context,$env{'form.output'},
1418: $permission,$env{'form.Status'},\%userlist,$keylist);
1419: }
1420: if (!$usercount) {
1421: $r->print('<br />'.&mt('There are no users matching the search criteria.'));
1422: }
1423: }
1424: $r->print('<input type="hidden" name="phase" value="'.
1425: $env{'form.phase'}.'" /></form>');
1426: }
1427:
1428: sub list_submit_button {
1429: my ($text) = @_;
1430: return '<input type="button" name="updatedisplay" value="'.$text.'" onclick="javascript:display_update()" />';
1431: }
1432:
1433: sub gather_userinfo {
1434: my ($context,$format,$userlist,$indexhash,$userinfo,$rolehash,$permission) = @_;
1435: foreach my $item (keys(%{$rolehash})) {
1436: @{$userlist->{$item}} = ();
1437: my %userdata;
1438: if ($context eq 'author' || $context eq 'course') {
1439: ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) =
1440: split(/:/,$item);
1441: ($userdata{'start'},$userdata{'end'})=split(/:/,$rolehash->{$item});
1442: &build_user_record(\%userdata,$userinfo,$indexhash,$item,$userlist);
1443: } elsif ($context eq 'domain') {
1444: if ($env{'form.roletype'} eq 'domain') {
1445: ($userdata{'role'},$userdata{'username'},$userdata{'domain'}) =
1446: split(/:/,$item);
1447: ($userdata{'end'},$userdata{'start'})=split(/:/,$rolehash->{$item});
1448: &build_user_record(\%userdata,$userinfo,$indexhash,$item,$userlist);
1449: } elsif ($env{'form.roletype'} eq 'author') {
1450: if (ref($rolehash->{$item}) eq 'HASH') {
1451: $userdata{'extent'} = $item;
1452: foreach my $key (keys(%{$rolehash->{$item}})) {
1453: ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) = split(/:/,$key);
1454: ($userdata{'start'},$userdata{'end'}) =
1455: split(/:/,$rolehash->{$item}{$key});
1456: my $uniqid = $key.':'.$item;
1457: &build_user_record(\%userdata,$userinfo,$indexhash,$uniqid,$userlist);
1458: }
1459: }
1460: } elsif ($env{'form.roletype'} eq 'course') {
1461: ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) =
1462: split(/:/,$item);
1463: if (ref($rolehash->{$item}) eq 'HASH') {
1464: my $numcids = keys(%{$rolehash->{$item}});
1465: foreach my $cid (sort(keys(%{$rolehash->{$item}}))) {
1466: if (ref($rolehash->{$item}{$cid}) eq 'HASH') {
1467: my $spanstart = '';
1468: my $spanend = '; ';
1469: my $space = ', ';
1470: if ($format eq 'html' || $format eq 'view') {
1471: $spanstart = '<span class="LC_nobreak">';
1472: if ($permission->{'cusr'}) {
1473: if ($numcids > 1) {
1474: $spanstart .= '<input type="radio" name="'.$item.'" value="'.$cid.'" />';
1475: } else {
1476: $spanstart .= '<input type="hidden" name="'.$item.'" value="'.$cid.'" />';
1477: }
1478: }
1479: $spanend = '</span><br />';
1480: $space = ', ';
1481: }
1482: $userdata{'extent'} .= $spanstart.
1483: $rolehash->{$item}{$cid}{'desc'}.$space;
1484: if (ref($rolehash->{$item}{$cid}{'secs'}) eq 'HASH') {
1485: foreach my $sec (sort(keys(%{$rolehash->{$item}{$cid}{'secs'}}))) {
1486: $userdata{'extent'} .= $sec.$space.$rolehash->{$item}{$cid}{'secs'}{$sec}.$spanend;
1487: }
1488: }
1489: }
1490: }
1491: }
1492: &build_user_record(\%userdata,$userinfo,$indexhash,$item,$userlist);
1493: }
1494: }
1495: }
1496: return;
1497: }
1498:
1499: sub build_user_record {
1500: my ($userdata,$userinfo,$indexhash,$record_key,$userlist) = @_;
1501: next if ($userdata->{'start'} eq '-1' && $userdata->{'end'} eq '-1');
1502: &process_date_info($userdata);
1503: my $username = $userdata->{'username'};
1504: my $domain = $userdata->{'domain'};
1505: if (ref($userinfo->{$username.':'.$domain}) eq 'HASH') {
1506: $userdata->{'fullname'} =
1507: $userinfo->{$username.':'.$domain}{'fullname'};
1508: $userdata->{'id'} = $userinfo->{$username.':'.$domain}{'id'};
1509: } else {
1510: &aggregate_user_info($domain,$username,$userinfo);
1511: $userdata->{'fullname'} = $userinfo->{$username.':'.$domain}{'fullname'};
1512: $userdata->{'id'} = $userinfo->{$username.':'.$domain}{'id'};
1513: }
1514: foreach my $key (keys(%{$indexhash})) {
1515: if (defined($userdata->{$key})) {
1516: $userlist->{$record_key}[$indexhash->{$key}] = $userdata->{$key};
1517: }
1518: }
1519: return;
1520: }
1521:
1522: sub courses_selector {
1523: my ($cdom,$formname) = @_;
1524: my %coursecodes = ();
1525: my %codes = ();
1526: my @codetitles = ();
1527: my %cat_titles = ();
1528: my %cat_order = ();
1529: my %idlist = ();
1530: my %idnums = ();
1531: my %idlist_titles = ();
1532: my $caller = 'global';
1533: my $format_reply;
1534: my $jscript = '';
1535:
1536: my $totcodes = 0;
1537: $totcodes =
1538: &Apache::courseclassifier::retrieve_instcodes(\%coursecodes,
1539: $cdom,$totcodes);
1540: if ($totcodes > 0) {
1541: $format_reply =
1542: &Apache::lonnet::auto_instcode_format($caller,$cdom,\%coursecodes,
1543: \%codes,\@codetitles,\%cat_titles,\%cat_order);
1544: if ($format_reply eq 'ok') {
1545: my $numtypes = @codetitles;
1546: &Apache::courseclassifier::build_code_selections(\%codes,\@codetitles,\%cat_titles,\%cat_order,\%idlist,\%idnums,\%idlist_titles);
1547: my ($scripttext,$longtitles) = &Apache::courseclassifier::javascript_definitions(\@codetitles,\%idlist,\%idlist_titles,\%idnums,\%cat_titles);
1548: my $longtitles_str = join('","',@{$longtitles});
1549: my $allidlist = $idlist{$codetitles[0]};
1550: $jscript .= &Apache::courseclassifier::courseset_js_start($formname,$longtitles_str,$allidlist);
1551: $jscript .= $scripttext;
1552: $jscript .= &Apache::courseclassifier::javascript_code_selections($formname,@codetitles);
1553: }
1554: }
1555: my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($cdom);
1556:
1557: my %elements = (
1558: Year => 'selectbox',
1559: coursepick => 'radio',
1560: coursetotal => 'text',
1561: courselist => 'text',
1562: );
1563: $jscript .= &Apache::lonhtmlcommon::set_form_elements(\%elements);
1564: if ($env{'form.coursepick'} eq 'category') {
1565: $jscript .= qq|
1566: function setCourseCat(formname) {
1567: if (formname.Year.options[formname.Year.selectedIndex].value == -1) {
1568: return;
1569: }
1570: courseSet('Year');
1571: for (var j=0; j<formname.Semester.length; j++) {
1572: if (formname.Semester.options[j].value == "$env{'form.Semester'}") {
1573: formname.Semester.options[j].selected = true;
1574: }
1575: }
1576: if (formname.Semester.options[formname.Semester.selectedIndex].value == -1) {
1577: return;
1578: }
1579: courseSet('Semester');
1580: for (var j=0; j<formname.Department.length; j++) {
1581: if (formname.Department.options[j].value == "$env{'form.Department'}") { formname.Department.options[j].selected = true;
1582: }
1583: }
1584: if (formname.Department.options[formname.Department.selectedIndex].value == -1) {
1585: return;
1586: }
1587: courseSet('Department');
1588: for (var j=0; j<formname.Number.length; j++) {
1589: if (formname.Number.options[j].value == "$env{'form.Number'}") {
1590: formname.Number.options[j].selected = true;
1591: }
1592: }
1593: }
1594: |;
1595: }
1596: return ($cb_jscript,$jscript,$totcodes,\@codetitles,\%idlist,
1597: \%idlist_titles);
1598: }
1599:
1600: sub course_selector_loadcode {
1601: my ($formname) = @_;
1602: my $loadcode;
1603: if ($env{'form.coursepick'} ne '') {
1604: $loadcode = 'javascript:setFormElements(document.'.$formname.')';
1605: if ($env{'form.coursepick'} eq 'category') {
1606: $loadcode .= ';javascript:setCourseCat(document.'.$formname.')';
1607: }
1608: }
1609: return $loadcode;
1610: }
1611:
1612: sub process_coursepick {
1613: my $coursefilter = $env{'form.coursepick'};
1614: my $cdom = $env{'request.role.domain'};
1615: my %courses;
1616: if ($coursefilter eq 'all') {
1617: %courses = &Apache::lonnet::courseiddump($cdom,'.','.','.','.','.',
1618: undef,undef,'Course');
1619: } elsif ($coursefilter eq 'category') {
1620: my $instcode = &instcode_from_coursefilter();
1621: %courses = &Apache::lonnet::courseiddump($cdom,'.','.',$instcode,'.','.',
1622: undef,undef,'Course');
1623: } elsif ($coursefilter eq 'specific') {
1624: if ($env{'form.coursetotal'} > 1) {
1625: my @course_ids = split(/&&/,$env{'form.courselist'});
1626: foreach my $cid (@course_ids) {
1627: $courses{$cid} = '';
1628: }
1629: } else {
1630: $courses{$env{'form.courselist'}} = '';
1631: }
1632: }
1633: return %courses;
1634: }
1635:
1636: sub instcode_from_coursefilter {
1637: my $instcode = '';
1638: my @cats = ('Semester','Year','Department','Number');
1639: foreach my $category (@cats) {
1640: if (defined($env{'form.'.$category})) {
1641: unless ($env{'form.'.$category} eq '-1') {
1642: $instcode .= $env{'form.'.$category};
1643: }
1644: }
1645: }
1646: if ($instcode eq '') {
1647: $instcode = '.';
1648: }
1649: return $instcode;
1650: }
1651:
1652: sub display_adv_courseroles {
1653: my $output;
1654: #
1655: # List course personnel
1656: my %coursepersonnel =
1657: &Apache::lonnet::get_course_adv_roles($env{'request.course.id'});
1658: #
1659: $output = '<br />'.&Apache::loncommon::start_data_table();
1660: foreach my $role (sort(keys(%coursepersonnel))) {
1661: next if ($role =~ /^\s*$/);
1662: $output .= &Apache::loncommon::start_data_table_row().
1663: '<td>'.$role.'</td><td>';
1664: foreach my $user (split(',',$coursepersonnel{$role})) {
1665: my ($puname,$pudom)=split(':',$user);
1666: $output .= ' '.&Apache::loncommon::aboutmewrapper(
1667: &Apache::loncommon::plainname($puname,$pudom),
1668: $puname,$pudom);
1669: }
1670: $output .= '</td>'.&Apache::loncommon::end_data_table_row();
1671: }
1672: $output .= &Apache::loncommon::end_data_table();
1673: }
1674:
1675: sub make_keylist_array {
1676: my ($index,$keylist);
1677: $index->{'domain'} = &Apache::loncoursedata::CL_SDOM();
1678: $index->{'username'} = &Apache::loncoursedata::CL_SNAME();
1679: $index->{'end'} = &Apache::loncoursedata::CL_END();
1680: $index->{'start'} = &Apache::loncoursedata::CL_START();
1681: $index->{'id'} = &Apache::loncoursedata::CL_ID();
1682: $index->{'section'} = &Apache::loncoursedata::CL_SECTION();
1683: $index->{'fullname'} = &Apache::loncoursedata::CL_FULLNAME();
1684: $index->{'status'} = &Apache::loncoursedata::CL_STATUS();
1685: $index->{'type'} = &Apache::loncoursedata::CL_TYPE();
1686: $index->{'lockedtype'} = &Apache::loncoursedata::CL_LOCKEDTYPE();
1687: $index->{'groups'} = &Apache::loncoursedata::CL_GROUP();
1688: $index->{'email'} = &Apache::loncoursedata::CL_PERMANENTEMAIL();
1689: $index->{'role'} = &Apache::loncoursedata::CL_ROLE();
1690: $index->{'extent'} = &Apache::loncoursedata::CL_EXTENT();
1691: foreach my $key (keys(%{$index})) {
1692: $keylist->[$index->{$key}] = $key;
1693: }
1694: return ($index,$keylist);
1695: }
1696:
1697: sub aggregate_user_info {
1698: my ($udom,$uname,$userinfo) = @_;
1699: my %info=&Apache::lonnet::get('environment',
1700: ['firstname','middlename',
1701: 'lastname','generation','id'],
1702: $udom,$uname);
1703: my ($tmp) = keys(%info);
1704: my ($fullname,$id);
1705: if ($tmp =~/^(con_lost|error|no_such_host)/i) {
1706: $fullname = 'not available';
1707: $id = 'not available';
1708: &Apache::lonnet::logthis('unable to retrieve environment '.
1709: 'for '.$uname.':'.$udom);
1710: } else {
1711: $fullname = &Apache::lonnet::format_name(@info{qw/firstname middlename lastname generation/},'lastname');
1712: $id = $info{'id'};
1713: }
1714: $userinfo->{$uname.':'.$udom} = {
1715: fullname => $fullname,
1716: id => $id,
1717: };
1718: return;
1719: }
1720:
1721: sub process_date_info {
1722: my ($userdata) = @_;
1723: my $now = time;
1724: $userdata->{'status'} = 'Active';
1725: if ($userdata->{'start'} > 0) {
1726: if ($now < $userdata->{'start'}) {
1727: $userdata->{'status'} = 'Future';
1728: }
1729: }
1730: if ($userdata->{'end'} > 0) {
1731: if ($now > $userdata->{'end'}) {
1732: $userdata->{'status'} = 'Expired';
1733: }
1734: }
1735: return;
1736: }
1737:
1738: sub show_users_list {
1739: my ($r,$context,$mode,$permission,$statusmode,$userlist,$keylist)=@_;
1740: #
1741: # Variables for excel output
1742: my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format);
1743: #
1744: # Variables for csv output
1745: my ($CSVfile,$CSVfilename);
1746: #
1747: my $sortby = $env{'form.sortby'};
1748: my @sortable = ('username','domain','id','fullname','start','end','email','role');
1749: if ($context eq 'course') {
1750: push(@sortable,('section','groups','type'));
1751: } else {
1752: push(@sortable,'extent');
1753: }
1754: if (!grep(/^\Q$sortby\E$/,@sortable)) {
1755: $sortby = 'username';
1756: }
1757: my $setting = $env{'form.roleaction'};
1758: my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers);
1759: if ($context eq 'course') {
1760: $cid=$env{'request.course.id'};
1761: ($cnum,$cdom) = &get_course_identity($cid);
1762: ($classgroups) = &Apache::loncoursedata::get_group_memberships(
1763: $userlist,$keylist,$cdom,$cnum);
1764: if ($mode eq 'autoenroll') {
1765: $env{'form.showrole'} = 'st';
1766: } else {
1767: if (! exists($env{'form.displayphotos'})) {
1768: $env{'form.displayphotos'} = 'off';
1769: }
1770: $displayphotos = $env{'form.displayphotos'};
1771: if (! exists($env{'form.displayclickers'})) {
1772: $env{'form.displayclickers'} = 'off';
1773: }
1774: $displayclickers = $env{'form.displayclickers'};
1775: if ($env{'course.'.$cid.'.internal.showphoto'}) {
1776: $r->print('
1777: <script type="text/javascript">
1778: function photowindow(photolink) {
1779: var title = "Photo_Viewer";
1780: var options = "scrollbars=1,resizable=1,menubar=0";
1781: options += ",width=240,height=240";
1782: stdeditbrowser = open(photolink,title,options,"1");
1783: stdeditbrowser.focus();
1784: }
1785: </script>
1786: ');
1787: }
1788: $r->print(<<END);
1789: <input type="hidden" name="displayphotos" value="$displayphotos" />
1790: <input type="hidden" name="displayclickers" value="$displayclickers" />
1791: END
1792: }
1793: }
1794: if ($mode ne 'autoenroll') {
1795: my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript();
1796: my $alert = &mt("You must select at least one user by checking a user's 'Select' checkbox");
1797: my $singconfirm = &mt(' for a single user');
1798: my $multconfirm = &mt(' for multiple users');
1799: my $date_sec_selector = &date_section_javascript($context,$setting,$statusmode);
1800: $r->print(<<END);
1801:
1802: <script type="text/javascript" language="Javascript">
1803: $check_uncheck_js
1804:
1805: function verify_action (field) {
1806: var numchecked = 0;
1807: var singconf = '$singconfirm';
1808: var multconf = '$multconfirm';
1809: if (field.length > 0) {
1810: for (i = 0; i < field.length; i++) {
1811: if (field[i].checked == true) {
1812: numchecked ++;
1813: }
1814: }
1815: } else {
1816: if (field.checked == true) {
1817: numchecked ++;
1818: }
1819: }
1820: if (numchecked == 0) {
1821: alert("$alert");
1822: }
1823: else {
1824: var message = document.studentform.bulkaction[document.studentform.bulkaction.selectedIndex].text;
1825: if (numchecked == 1) {
1826: message += singconf;
1827: }
1828: else {
1829: message += multconf;
1830: }
1831: if (confirm(message)) {
1832: document.studentform.phase.value = 'bulkchange';
1833: document.studentform.submit();
1834: }
1835: }
1836: }
1837:
1838: function username_display_launch(username,domain) {
1839: var target;
1840: for (var i=0; i<document.studentform.usernamelink.length; i++) {
1841: if (document.studentform.usernamelink[i].checked) {
1842: target = document.studentform.usernamelink[i].value;
1843: }
1844: }
1845: if (target == 'modify') {
1846: document.studentform.srchterm.value=username;
1847: document.studentform.srchdomain.value=domain;
1848: document.studentform.phase.value='get_user_info';
1849: document.studentform.action.value = 'singleuser';
1850: document.studentform.submit();
1851: }
1852: else {
1853: document.location.href = '/adm/'+domain+'/'+username+'/aboutme';
1854: }
1855: }
1856: </script>
1857: $date_sec_selector
1858: <input type="hidden" name="state" value="$env{'form.state'}" />
1859: END
1860: }
1861: $r->print(<<END);
1862: <input type="hidden" name="sortby" value="$sortby" />
1863: END
1864:
1865: my %lt=&Apache::lonlocal::texthash(
1866: 'username' => "username",
1867: 'domain' => "domain",
1868: 'id' => 'ID',
1869: 'fullname' => "name",
1870: 'section' => "section",
1871: 'groups' => "active groups",
1872: 'start' => "start date",
1873: 'end' => "end date",
1874: 'status' => "status",
1875: 'role' => "role",
1876: 'type' => "enroll type/action",
1877: 'email' => "email address",
1878: 'clicker' => "clicker id",
1879: 'photo' => "photo",
1880: 'extent' => "extent",
1881: 'pr' => "Proceed",
1882: 'ca' => "check all",
1883: 'ua' => "uncheck all",
1884: 'ac' => "Action to take for selected users",
1885: 'link' => "Behavior of username links",
1886: 'aboutme' => "Display a user's personal page",
1887: 'modify' => "Modify a user's information",
1888: );
1889: if ($context eq 'domain' && $env{'form.roletype'} eq 'course') {
1890: $lt{'extent'} = &mt('Course(s): description, section(s), status');
1891: } elsif ($context eq 'author') {
1892: $lt{'extent'} = &mt('Author');
1893: }
1894: my @cols = ('username','domain','id','fullname');
1895: if ($context eq 'course') {
1896: push(@cols,'section');
1897: }
1898: if (!($context eq 'domain' && $env{'form.roletype'} eq 'course')) {
1899: push(@cols,('start','end'));
1900: }
1901: if ($env{'form.showrole'} eq 'Any' || $env{'form.showrole'} eq 'cr') {
1902: push(@cols,'role');
1903: }
1904: if ($context eq 'domain' && ($env{'form.roletype'} eq 'author' ||
1905: $env{'form.roletype'} eq 'course')) {
1906: push (@cols,'extent');
1907: }
1908: if (($statusmode eq 'Any') &&
1909: (!($context eq 'domain' && $env{'form.roletype'} eq 'course'))) {
1910: push(@cols,'status');
1911: }
1912: if ($context eq 'course') {
1913: push(@cols,'groups');
1914: }
1915: push(@cols,'email');
1916:
1917: my $rolefilter = $env{'form.showrole'};
1918: if ($env{'form.showrole'} eq 'cr') {
1919: $rolefilter = &mt('custom');
1920: } elsif ($env{'form.showrole'} ne 'Any') {
1921: $rolefilter = &Apache::lonnet::plaintext($env{'form.showrole'});
1922: }
1923: my $results_description;
1924: if ($mode ne 'autoenroll') {
1925: $results_description = &results_header_row($rolefilter,$statusmode,
1926: $context,$permission);
1927: $r->print('<b>'.$results_description.'</b><br />');
1928: }
1929: my ($output,$actionselect);
1930: if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll') {
1931: if ($mode ne 'autoenroll') {
1932: if ($permission->{'cusr'}) {
1933: $actionselect = &select_actions($context,$setting,$statusmode);
1934: }
1935: $r->print(<<END);
1936: <input type="hidden" name="srchby" value="uname" />
1937: <input type="hidden" name="srchin" value="dom" />
1938: <input type="hidden" name="srchtype" value="exact" />
1939: <input type="hidden" name="srchterm" value="" />
1940: <input type="hidden" name="srchdomain" value="" />
1941: END
1942: $output = '<p>';
1943: my @linkdests = ('aboutme');
1944: if ($permission->{'cusr'}) {
1945: push (@linkdests,'modify');
1946: $output .= '<span class="LC_nobreak">'.$lt{'link'}.': ';
1947: my $usernamelink = $env{'form.usernamelink'};
1948: if ($usernamelink eq '') {
1949: $usernamelink = 'aboutme';
1950: }
1951: foreach my $item (@linkdests) {
1952: my $checkedstr = '';
1953: if ($item eq $usernamelink) {
1954: $checkedstr = ' checked="checked" ';
1955: }
1956: $output .= '<label><input type="radio" name="usernamelink" value="'.$item.'"'.$checkedstr.'> '.$lt{$item}.'</label> ';
1957: }
1958: $output .= '</span><br />';
1959: } else {
1960: $output .= &mt("Click on a username to view the user's personal page.").'<br />';
1961: }
1962: if ($actionselect) {
1963: $output .= <<"END";
1964: $lt{'ac'}: $actionselect <input type="button" value="$lt{'pr'}" onclick="javascript:verify_action(document.studentform.actionlist)" /></p>
1965: <p><input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.actionlist)" />
1966: <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.actionlist)" />
1967: END
1968: }
1969: }
1970: $output .= "\n<p>\n".
1971: &Apache::loncommon::start_data_table().
1972: &Apache::loncommon::start_data_table_header_row();
1973: if ($mode eq 'autoenroll') {
1974: $output .= "
1975: <th><a href=\"javascript:document.studentform.sortby.value='type';document.studentform.submit();\">$lt{'type'}</a></th>
1976: ";
1977: } else {
1978: $output .= "\n".'<th>'.&mt('Count').'</th>'."\n";
1979: if ($actionselect) {
1980: $output .= '<th>'.&mt('Select').'</th>'."\n";
1981: }
1982: }
1983: foreach my $item (@cols) {
1984: $output .= "<th><a href=\"javascript:document.studentform.sortby.value='$item';document.studentform.submit();\">$lt{$item}</a></th>\n";
1985: }
1986: my %role_types = &role_type_names();
1987: if ($context eq 'course' && $mode ne 'autoenroll') {
1988: if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') {
1989: # Clicker display on or off?
1990: my %clicker_options = &Apache::lonlocal::texthash(
1991: 'on' => 'Show',
1992: 'off' => 'Hide',
1993: );
1994: my $clickerchg = 'on';
1995: if ($displayclickers eq 'on') {
1996: $clickerchg = 'off';
1997: }
1998: $output .= ' <th>'."\n".' '.
1999: '<a href="javascript:document.studentform.displayclickers.value='.
2000: "'".$clickerchg."'".';document.studentform.submit();">'.
2001: $clicker_options{$clickerchg}.'</a> '.$lt{'clicker'}."\n".
2002: ' </th>'."\n";
2003:
2004: # Photo display on or off?
2005: if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
2006: my %photo_options = &Apache::lonlocal::texthash(
2007: 'on' => 'Show',
2008: 'off' => 'Hide',
2009: );
2010: my $photochg = 'on';
2011: if ($displayphotos eq 'on') {
2012: $photochg = 'off';
2013: }
2014: $output .= ' <th>'."\n".' '.
2015: '<a href="javascript:document.studentform.displayphotos.value='.
2016: "'".$photochg."'".';document.studentform.submit();">'.
2017: $photo_options{$photochg}.'</a> '.$lt{'photo'}."\n".
2018: ' </th>'."\n";
2019: }
2020: }
2021: }
2022: $output .= &Apache::loncommon::end_data_table_header_row();
2023: # Done with the HTML header line
2024: } elsif ($mode eq 'csv') {
2025: #
2026: # Open a file
2027: $CSVfilename = '/prtspool/'.
2028: $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
2029: time.'_'.rand(1000000000).'.csv';
2030: unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) {
2031: $r->log_error("Couldn't open $CSVfilename for output $!");
2032: $r->print("Problems occured in writing the csv file. ".
2033: "This error has been logged. ".
2034: "Please alert your LON-CAPA administrator.");
2035: $CSVfile = undef;
2036: }
2037: #
2038: # Write headers and data to file
2039: print $CSVfile '"'.$results_description.'"'."\n";
2040: print $CSVfile '"'.join('","',map {
2041: &Apache::loncommon::csv_translate($lt{$_})
2042: } (@cols)).'"'."\n";
2043: } elsif ($mode eq 'excel') {
2044: # Create the excel spreadsheet
2045: ($excel_workbook,$excel_filename,$format) =
2046: &Apache::loncommon::create_workbook($r);
2047: return if (! defined($excel_workbook));
2048: $excel_sheet = $excel_workbook->addworksheet('userlist');
2049: $excel_sheet->write($row++,0,$results_description,$format->{'h2'});
2050: #
2051: my @colnames = map {$lt{$_}} (@cols);
2052: $excel_sheet->write($row++,0,\@colnames,$format->{'bold'});
2053: }
2054:
2055: # Done with header lines in all formats
2056:
2057: my %index;
2058: my $i;
2059: foreach my $idx (@$keylist) {
2060: $index{$idx} = $i++;
2061: }
2062: my $usercount = 0;
2063: # Get groups, role, permanent e-mail so we can sort on them if
2064: # necessary.
2065: foreach my $user (keys(%{$userlist})) {
2066: if ($context eq 'domain' && $user eq $env{'request.role.domain'}.'-domainconfig:'.$env{'request.role.domain'}) {
2067: delete($userlist->{$user});
2068: next;
2069: }
2070: my ($uname,$udom,$role,$groups,$email);
2071: if (($statusmode ne 'Any') &&
2072: ($userlist->{$user}->[$index{'status'}] ne $statusmode)) {
2073: delete($userlist->{$user});
2074: next;
2075: }
2076: if ($context eq 'domain') {
2077: if ($env{'form.roletype'} eq 'domain') {
2078: ($role,$uname,$udom) = split(/:/,$user);
2079: if (($uname eq $env{'request.role.domain'}.'-domainconfig') &&
2080: ($udom eq $env{'request.role.domain'})) {
2081: delete($userlist->{$user});
2082: next;
2083: }
2084: } elsif ($env{'form.roletype'} eq 'author') {
2085: ($uname,$udom,$role) = split(/:/,$user,-1);
2086: } elsif ($env{'form.roletype'} eq 'course') {
2087: ($uname,$udom,$role) = split(/:/,$user);
2088: }
2089: } else {
2090: ($uname,$udom,$role) = split(/:/,$user,-1);
2091: if (($context eq 'course') && $role eq '') {
2092: $role = 'st';
2093: }
2094: }
2095: $userlist->{$user}->[$index{'role'}] = $role;
2096: if (($env{'form.showrole'} ne 'Any') && (!($env{'form.showrole'} eq 'cr' && $role =~ /^cr\//)) && ($role ne $env{'form.showrole'})) {
2097: delete($userlist->{$user});
2098: next;
2099: }
2100: if (ref($classgroups) eq 'HASH') {
2101: $groups = $classgroups->{$user};
2102: }
2103: if (ref($groups->{active}) eq 'HASH') {
2104: $userlist->{$user}->[$index{'groups'}] = join(', ',keys(%{$groups->{'active'}}));
2105: }
2106: my %emails = &Apache::loncommon::getemails($uname,$udom);
2107: if ($emails{'permanentemail'} =~ /\S/) {
2108: $userlist->{$user}->[$index{'email'}] = $emails{'permanentemail'};
2109: }
2110: $usercount ++;
2111: }
2112: my $autocount = 0;
2113: my $manualcount = 0;
2114: my $lockcount = 0;
2115: my $unlockcount = 0;
2116: if ($usercount) {
2117: $r->print($output);
2118: } else {
2119: if ($mode eq 'autoenroll') {
2120: return ($usercount,$autocount,$manualcount,$lockcount,$unlockcount);
2121: } else {
2122: return;
2123: }
2124: }
2125: #
2126: # Sort the users
2127: my $index = $index{$sortby};
2128: my $second = $index{'username'};
2129: my $third = $index{'domain'};
2130: my @sorted_users = sort {
2131: lc($userlist->{$a}->[$index]) cmp lc($userlist->{$b}->[$index])
2132: ||
2133: lc($userlist->{$a}->[$second]) cmp lc($userlist->{$b}->[$second]) ||
2134: lc($userlist->{$a}->[$third]) cmp lc($userlist->{$b}->[$third])
2135: } (keys(%$userlist));
2136: my $rowcount = 0;
2137: foreach my $user (@sorted_users) {
2138: my %in;
2139: my $sdata = $userlist->{$user};
2140: $rowcount ++;
2141: foreach my $item (@{$keylist}) {
2142: $in{$item} = $sdata->[$index{$item}];
2143: }
2144: my $role = $in{'role'};
2145: $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}]);
2146: if (! defined($in{'start'}) || $in{'start'} == 0) {
2147: $in{'start'} = &mt('none');
2148: } else {
2149: $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'});
2150: }
2151: if (! defined($in{'end'}) || $in{'end'} == 0) {
2152: $in{'end'} = &mt('none');
2153: } else {
2154: $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});
2155: }
2156: if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
2157: $r->print(&Apache::loncommon::start_data_table_row());
2158: my $checkval;
2159: if ($mode eq 'autoenroll') {
2160: my $cellentry;
2161: if ($in{'type'} eq 'auto') {
2162: $cellentry = '<b>'.&mt('auto').'</b> <label><input type="checkbox" name="chgauto" value="'.$in{'username'}.':'.$in{'domain'}.'" /> Change</label>';
2163: $autocount ++;
2164: } else {
2165: $cellentry = '<table border="0" cellspacing="0"><tr><td rowspan="2"><b>'.&mt('manual').'</b></td><td><nobr><label><input type="checkbox" name="chgmanual" value="'.$in{'username'}.':'.$in{'domain'}.'" /> Change</label></nobr></td></tr><tr><td><nobr>';
2166: $manualcount ++;
2167: if ($in{'lockedtype'}) {
2168: $cellentry .= '<label><input type="checkbox" name="unlockchg" value="'.$in{'username'}.':'.$in{'domain'}.'" /> '.&mt('Unlock').'</label>';
2169: $unlockcount ++;
2170: } else {
2171: $cellentry .= '<label><input type="checkbox" name="lockchg" value="'.$in{'username'}.':'.$in{'domain'}.'" /> '.&mt('Lock').'</label>';
2172: $lockcount ++;
2173: }
2174: $cellentry .= '</nobr></td></tr></table>';
2175: }
2176: $r->print("<td>$cellentry</td>\n");
2177: } else {
2178: $r->print("<td>$rowcount</td>\n");
2179: $checkval;
2180: if ($actionselect) {
2181: $checkval = $user;
2182: if ($context eq 'course') {
2183: if ($role eq 'st') {
2184: $checkval .= ':st';
2185: }
2186: $checkval .= ':'.$in{'section'};
2187: if ($role eq 'st') {
2188: $checkval .= ':'.$in{'type'}.':'.$in{'lockedtype'};
2189: }
2190: }
2191: $r->print('<td><input type="checkbox" name="actionlist" value="'.
2192: $checkval.'"></td>');
2193: }
2194: }
2195: foreach my $item (@cols) {
2196: if ($item eq 'username') {
2197: $r->print('<td>'.&print_username_link($mode,$permission,
2198: \%in).'</td>');
2199: } elsif (($item eq 'start' || $item eq 'end') && ($actionselect)) {
2200: $r->print('<td>'.$in{$item}.'<input type="hidden" name="'.$checkval.'_'.$item.'" value="'.$sdata->[$index{$item}].'" /></td>'."\n");
2201: } else {
2202: $r->print('<td>'.$in{$item}.'</td>'."\n");
2203: }
2204: }
2205: if (($context eq 'course') && ($mode ne 'autoenroll')) {
2206: if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') {
2207: if ($displayclickers eq 'on') {
2208: my $clickers =
2209: (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1];
2210: if ($clickers!~/\w/) { $clickers='-'; }
2211: $r->print('<td>'.$clickers.'</td>');
2212: } else {
2213: $r->print(' <td> </td> ');
2214: }
2215: if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
2216: if ($displayphotos eq 'on' && $sdata->[$index{'role'}] eq 'st') {
2217: my $imgurl =
2218: &Apache::lonnet::retrievestudentphoto($in{'domain'},$in{'username'},
2219: 'gif','thumbnail');
2220: $r->print(' <td align="right"><a href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($in{'domain'},$in{'username'},'jpg')."'".')"><img src="'.$imgurl.'" border="1"></a></td>');
2221: } else {
2222: $r->print(' <td> </td> ');
2223: }
2224: }
2225: }
2226: }
2227: $r->print(&Apache::loncommon::end_data_table_row());
2228: } elsif ($mode eq 'csv') {
2229: next if (! defined($CSVfile));
2230: # no need to bother with $linkto
2231: if (! defined($in{'start'}) || $in{'start'} == 0) {
2232: $in{'start'} = &mt('none');
2233: } else {
2234: $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'});
2235: }
2236: if (! defined($in{'end'}) || $in{'end'} == 0) {
2237: $in{'end'} = &mt('none');
2238: } else {
2239: $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'});
2240: }
2241: my @line = ();
2242: foreach my $item (@cols) {
2243: push @line,&Apache::loncommon::csv_translate($in{$item});
2244: }
2245: print $CSVfile '"'.join('","',@line).'"'."\n";
2246: } elsif ($mode eq 'excel') {
2247: my $col = 0;
2248: foreach my $item (@cols) {
2249: if ($item eq 'start' || $item eq 'end') {
2250: if (defined($item) && $item != 0) {
2251: $excel_sheet->write($row,$col++,
2252: &Apache::lonstathelpers::calc_serial($in{item}),
2253: $format->{'date'});
2254: } else {
2255: $excel_sheet->write($row,$col++,'none');
2256: }
2257: } else {
2258: $excel_sheet->write($row,$col++,$in{$item});
2259: }
2260: }
2261: $row++;
2262: }
2263: }
2264: if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
2265: $r->print(&Apache::loncommon::end_data_table().'<br />');
2266: } elsif ($mode eq 'excel') {
2267: $excel_workbook->close();
2268: $r->print('<p><a href="'.$excel_filename.'">'.
2269: &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n");
2270: } elsif ($mode eq 'csv') {
2271: close($CSVfile);
2272: $r->print('<a href="'.$CSVfilename.'">'.
2273: &mt('Your CSV file').'</a> is ready for download.'.
2274: "\n");
2275: $r->rflush();
2276: }
2277: if ($mode eq 'autoenroll') {
2278: return ($usercount,$autocount,$manualcount,$lockcount,$unlockcount);
2279: } else {
2280: return ($usercount);
2281: }
2282: }
2283:
2284: sub print_username_link {
2285: my ($mode,$permission,$in) = @_;
2286: my $output;
2287: if ($mode eq 'autoenroll') {
2288: $output = $in->{'username'};
2289: } elsif (!$permission->{'cusr'}) {
2290: $output = &Apache::loncommon::aboutmewrapper($in->{'username'},
2291: $in->{'username'},
2292: $in->{'domain'});
2293: } else {
2294: $output = '<a href="javascript:username_display_launch('.
2295: "'$in->{'username'}','$in->{'domain'}'".')" />'.
2296: $in->{'username'}.'</a>';
2297: }
2298: return $output;
2299: }
2300:
2301: sub role_type_names {
2302: my %lt = &Apache::lonlocal::texthash (
2303: 'domain' => 'Domain Roles',
2304: 'author' => 'Co-Author Roles',
2305: 'course' => 'Course Roles',
2306: );
2307: return %lt;
2308: }
2309:
2310: sub select_actions {
2311: my ($context,$setting,$statusmode) = @_;
2312: my %lt = &Apache::lonlocal::texthash(
2313: revoke => "Revoke user roles",
2314: delete => "Delete user roles",
2315: reenable => "Re-enable expired user roles",
2316: activate => "Make future user roles active now",
2317: chgdates => "Change starting/ending dates",
2318: chgsec => "Change section associated with user roles",
2319: );
2320: my ($output,$options,%choices);
2321: if ($statusmode eq 'Any') {
2322: $options .= '
2323: <option value="chgdates">'.$lt{'chgdates'}.'</option>';
2324: $choices{'dates'} = 1;
2325: } else {
2326: if ($statusmode eq 'Future') {
2327: $options .= '
2328: <option value="activate">'.$lt{'activate'}.'</option>';
2329: $choices{'dates'} = 1;
2330: } elsif ($statusmode eq 'Expired') {
2331: $options .= '
2332: <option value="reenable">'.$lt{'reenable'}.'</option>';
2333: $choices{'dates'} = 1;
2334: }
2335: if ($statusmode eq 'Active' || $statusmode eq 'Future') {
2336: $options .= '
2337: <option value="chgdates">'.$lt{'chgdates'}.'</option>
2338: <option value="revoke">'.$lt{'revoke'}.'</option>';
2339: $choices{'dates'} = 1;
2340: }
2341: }
2342: if ($context eq 'domain') {
2343: $options .= '
2344: <option value="delete">'.$lt{'delete'}.'</option>';
2345: }
2346: if (($context eq 'course') || ($context eq 'domain' && $setting eq 'course')) {
2347: if ($statusmode ne 'Expired') {
2348: $options .= '
2349: <option value="chgsec">'.$lt{'chgsec'}.'</option>';
2350: $choices{'sections'} = 1;
2351: }
2352: }
2353: if ($options) {
2354: $output = '<select name="bulkaction" onchange="javascript:opendatebrowser(this.form,'."'studentform'".')" />'."\n".
2355: '<option value="" selected="selected">'.
2356: &mt('Please select').'</option>'."\n".$options."\n".'</select>';
2357: if ($choices{'dates'}) {
2358: $output .=
2359: '<input type="hidden" name="startdate_month" value="" />'."\n".
2360: '<input type="hidden" name="startdate_day" value="" />'."\n".
2361: '<input type="hidden" name="startdate_year" value="" />'."\n".
2362: '<input type="hidden" name="startdate_hour" value="" />'."\n".
2363: '<input type="hidden" name="startdate_minute" value="" />'."\n".
2364: '<input type="hidden" name="startdate_second" value="" />'."\n".
2365: '<input type="hidden" name="enddate_month" value="" />'."\n".
2366: '<input type="hidden" name="enddate_day" value="" />'."\n".
2367: '<input type="hidden" name="enddate_year" value="" />'."\n".
2368: '<input type="hidden" name="enddate_hour" value="" />'."\n".
2369: '<input type="hidden" name="enddate_minute" value="" />'."\n".
2370: '<input type="hidden" name="enddate_second" value="" />'."\n";
2371: if ($context eq 'course') {
2372: $output .= '<input type="hidden" name="makedatesdefault" value="" />'."\n";
2373: }
2374: }
2375: if ($choices{'sections'}) {
2376: $output .= '<input type="hidden" name="retainsec" value= "" />'."\n".
2377: '<input type="hidden" name="newsecs" value= "" />'."\n";
2378: }
2379: }
2380: return $output;
2381: }
2382:
2383: sub date_section_javascript {
2384: my ($context,$setting) = @_;
2385: my $title;
2386: if (($context eq 'course') || ($context eq 'domain' && $setting eq 'course')) {
2387: $title = &mt('Date and Section selector');
2388: } else {
2389: $title = &mt('Date selector');
2390: }
2391: my $output = '
2392: <script type="text/javascript">
2393: var stdeditbrowser;'."\n";
2394: $output .= <<"ENDONE";
2395: function opendatebrowser(callingform,formname) {
2396: var bulkaction = callingform.bulkaction.options[callingform.bulkaction.selectedIndex].value;
2397: if (bulkaction == 'revoke' || bulkaction == 'delete' || bulkaction == '') {
2398: return;
2399: }
2400: var url = '/adm/createuser?';
2401: var type = '';
2402: var showrole = callingform.showrole.options[callingform.showrole.selectedIndex].value;
2403: ENDONE
2404: if ($context eq 'domain') {
2405: $output .= '
2406: type = callingform.roletype.options[callingform.roletype.selectedIndex].value;
2407: ';
2408: }
2409: my $width= '700';
2410: my $height = '400';
2411: $output .= <<"ENDTWO";
2412: url += 'action=dateselect&callingform=' + formname +
2413: '&roletype='+type+'&showrole='+showrole +'&bulkaction='+bulkaction;
2414: var title = '$title';
2415: var options = 'scrollbars=1,resizable=1,menubar=0';
2416: options += ',width=$width,height=$height';
2417: stdeditbrowser = open(url,title,options,'1');
2418: stdeditbrowser.focus();
2419: }
2420: </script>
2421: ENDTWO
2422: return $output;
2423: }
2424:
2425: sub date_section_selector {
2426: my ($context) = @_;
2427: my $callingform = $env{'form.callingform'};
2428: my $formname = 'dateselect';
2429: my $groupslist = &get_groupslist();
2430: my $sec_js = &setsections_javascript($formname,$groupslist);
2431: my $output = <<"END";
2432: <script type="text/javascript">
2433:
2434: $sec_js
2435:
2436: function saveselections(formname) {
2437:
2438: END
2439: if ($env{'form.bulkaction'} eq 'chgsec') {
2440: $output .= <<"END";
2441: opener.document.$callingform.retainsec.value = formname.retainsec.value;
2442: setSections(formname);
2443: if (seccheck == 'ok') {
2444: opener.document.$callingform.newsecs.value = formname.sections.value;
2445: window.close();
2446: }
2447: return;
2448: END
2449: } else {
2450: if ($context eq 'course') {
2451: if (($env{'form.bulkaction'} eq 'reenable') ||
2452: ($env{'form.bulkaction'} eq 'activate') ||
2453: ($env{'form.bulkaction'} eq 'chgdates')) {
2454: $output .= <<"END";
2455:
2456: if (formname.makedatesdefault.checked == true) {
2457: opener.document.$callingform.makedatesdefault.value = 1;
2458: }
2459: else {
2460: opener.document.$callingform.makedatesdefault.value = 0;
2461: }
2462:
2463: END
2464: }
2465: }
2466: $output .= <<"END";
2467: opener.document.$callingform.startdate_month.value = formname.startdate_month.options[formname.startdate_month.selectedIndex].value;
2468: opener.document.$callingform.startdate_day.value = formname.startdate_day.value;
2469: opener.document.$callingform.startdate_year.value = formname.startdate_year.value;
2470: opener.document.$callingform.startdate_hour.value = formname.startdate_hour.options[formname.startdate_hour.selectedIndex].value;
2471: opener.document.$callingform.startdate_minute.value = formname.startdate_minute.value;
2472: opener.document.$callingform.startdate_second.value = formname.startdate_second.value;
2473: opener.document.$callingform.enddate_month.value = formname.enddate_month.options[formname.enddate_month.selectedIndex].value;
2474: opener.document.$callingform.enddate_day.value = formname.enddate_day.value;
2475: opener.document.$callingform.enddate_year.value = formname.enddate_year.value;
2476: opener.document.$callingform.enddate_hour.value = formname.enddate_hour.options[formname.enddate_hour.selectedIndex].value;
2477: opener.document.$callingform.enddate_minute.value = formname.enddate_minute.value;
2478: opener.document.$callingform.enddate_second.value = formname.enddate_second.value;
2479: window.close();
2480: END
2481: }
2482: $output .= '
2483: }
2484: </script>
2485: ';
2486: my %lt = &Apache::lonlocal::texthash (
2487: chac => 'Access dates to apply for selected users',
2488: chse => 'Changes in section affiliation to apply to selected users',
2489: fors => 'For student roles changing the section, will result in a section switch as students may only be in one section of a course at a time.',
2490: forn => 'For a role in a course that is not a student role, a user may have roles in more than one section of a course at a time.',
2491: reta => "Retain each user's current section affiliations?",
2492: dnap => '(Does not apply to student roles).',
2493: );
2494: my ($date_items,$headertext);
2495: if ($env{'form.bulkaction'} eq 'chgsec') {
2496: $headertext = $lt{'chse'};
2497: } else {
2498: $headertext = $lt{'chac'};
2499: my $starttime;
2500: if (($env{'form.bulkaction'} eq 'activate') ||
2501: ($env{'form.bulkaction'} eq 'reenable')) {
2502: $starttime = time;
2503: }
2504: $date_items = &date_setting_table($starttime,undef,$context,
2505: $env{'form.bulkaction'});
2506: }
2507: $output .= '<h3>'.$headertext.'</h3>'.
2508: '<form name="'.$formname.'" method="post">'."\n".
2509: $date_items;
2510: if ($context eq 'course' && $env{'form.bulkaction'} eq 'chgsec') {
2511: my ($cnum,$cdom) = &get_course_identity();
2512: my %sections_count =
2513: &Apache::loncommon::get_sections($cdom,$cnum);
2514: my $info;
2515: if ($env{'form.showrole'} eq 'st') {
2516: $output .= '<p>'.$lt{'fors'}.'</p>';
2517: } elsif ($env{'form.shorole'} eq 'Any') {
2518: $output .= '<p>'.$lt{'fors'}.'</p>'.
2519: '<p>'.$lt{'forn'}.' ';
2520: $info = $lt{'reta'};
2521: } else {
2522: $output .= '<p>'.$lt{'forn'}.' ';
2523: $info = $lt{'reta'};
2524: }
2525: if ($info) {
2526: $info .= '<span class="LC_nobreak">'.
2527: '<label><input type="radio" name="retainsec" value="1" '.
2528: 'checked="checked" />'.&mt('Yes').'</label> '.
2529: '<label><input type="radio" name="retainsec" value="0" />'.
2530: &mt('No').'</label></span>';
2531: if ($env{'form.showrole'} eq 'Any') {
2532: $info .= '<br />'.$lt{'dnap'};
2533: }
2534: $info .= '</p>';
2535: } else {
2536: $info = '<input type="hidden" name="retainsec" value="0" />';
2537: }
2538: my $sections_select .= &course_sections(\%sections_count,$env{'form.showrole'});
2539: my $secbox = '<p>'.&Apache::lonhtmlcommon::start_pick_box()."\n".
2540: &Apache::lonhtmlcommon::row_title(&mt('New section to assign'),'LC_oddrow_value')."\n".
2541: '<table class="LC_createuser"><tr class="LC_section_row">'."\n".
2542: '<td align="center">'.&mt('Existing sections')."\n".
2543: '<br />'.$sections_select.'</td><td align="center">'.
2544: &mt('New section').'<br />'."\n".
2545: '<input type="text" name="newsec" size="15" />'."\n".
2546: '<input type="hidden" name="sections" value="" />'."\n".
2547: '</td></tr></table>'."\n".
2548: &Apache::lonhtmlcommon::row_closure(1)."\n".
2549: &Apache::lonhtmlcommon::end_pick_box().'</p>';
2550: $output .= $info.$secbox;
2551: }
2552: $output .= '<p>'.
2553: &mt('Use "Save" to update the main window with your selections.').'<br /><br />'.
2554: '<input type="button" name="dateselection" value="'.&mt('Save').'" onclick="javascript:saveselections(this.form)" /></p>'."\n".
2555: '</form>';
2556: return $output;
2557: }
2558:
2559: sub section_picker {
2560: my ($cdom,$cnum,$role,$rowtitle,$permission,$context,$mode) = @_;
2561: my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);
2562: my $sections_select .= &course_sections(\%sections_count,$role);
2563: my $secbox = '<p>'.&Apache::lonhtmlcommon::start_pick_box()."\n";
2564: if ($mode eq 'upload') {
2565: my ($options,$cb_script,$coursepick) =
2566: &default_role_selector($context,1);
2567: $secbox .= &Apache::lonhtmlcommon::row_title('role','LC_oddrow_value').
2568: $options. &Apache::lonhtmlcommon::row_closure(1)."\n";
2569: }
2570: $secbox .= &Apache::lonhtmlcommon::row_title($rowtitle,'LC_oddrow_value')."\n";
2571: if ($env{'request.course.sec'} eq '') {
2572: $secbox .= '<table class="LC_createuser"><tr class="LC_section_row">'."\n".
2573: '<td align="center">'.&mt('Existing sections')."\n".
2574: '<br />'.$sections_select.'</td><td align="center">'.
2575: &mt('New section').'<br />'."\n".
2576: '<input type="text" name="newsec" size="15" />'."\n".
2577: '<input type="hidden" name="sections" value="" />'."\n".
2578: '</td></tr></table>'."\n";
2579: } else {
2580: $secbox .= '<input type="hidden" name="sections" value="'.
2581: $env{'request.course.sec'}.'" />'.
2582: $env{'request.course.sec'};
2583: }
2584: $secbox .= &Apache::lonhtmlcommon::row_closure(1)."\n".
2585: &Apache::lonhtmlcommon::end_pick_box().'</p>';
2586: return $secbox;
2587: }
2588:
2589: sub results_header_row {
2590: my ($rolefilter,$statusmode,$context,$permission) = @_;
2591: my ($description,$showfilter);
2592: if ($rolefilter ne 'Any') {
2593: $showfilter = $rolefilter;
2594: }
2595: if ($context eq 'course') {
2596: $description = &mt('Course - ').$env{'course.'.$env{'request.course.id'}.'.description'}.': ';
2597: if ($statusmode eq 'Expired') {
2598: $description .= &mt('Users in course with expired [_1] roles',$showfilter);
2599: } elsif ($statusmode eq 'Future') {
2600: $description .= &mt('Users in course with future [_1] roles',$showfilter);
2601: } elsif ($statusmode eq 'Active') {
2602: $description .= &mt('Users in course with active [_1] roles',$showfilter);
2603: } else {
2604: if ($rolefilter eq 'Any') {
2605: $description .= &mt('All users in course');
2606: } else {
2607: $description .= &mt('All users in course with [_1] roles',$rolefilter);
2608: }
2609: }
2610: if (exists($permission->{'view_section'})) {
2611: if ($env{'form.showrole'} eq 'st') {
2612: $description .= ' '.&mt('(section [_1] only)',$permission->{'view_section'});
2613: } elsif ($env{'form.showrole'} eq 'any') {
2614: $description .= ' '.&mt('(section [_1] only)',$permission->{'view_section'});
2615: }
2616: }
2617: } elsif ($context eq 'author') {
2618: $description =
2619: &mt('Author space for <span class="LC_cusr_emph">[_1]</span>',
2620: &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'})).': ';
2621: if ($statusmode eq 'Expired') {
2622: $description .= &mt('Co-authors with expired [_1] roles',$showfilter);
2623: } elsif ($statusmode eq 'Future') {
2624: $description .= &mt('Co-authors with future [_1] roles',$showfilter);
2625: } elsif ($statusmode eq 'Active') {
2626: $description .= &mt('Co-authors with active [_1] roles',$showfilter);
2627: } else {
2628: if ($rolefilter eq 'Any') {
2629: $description .= &mt('All co-authors');
2630: } else {
2631: $description .= &mt('All co-authors with [_1] roles',$rolefilter);
2632: }
2633: }
2634: } elsif ($context eq 'domain') {
2635: my $domdesc = &Apache::lonnet::domain($env{'request.role.domain'},'description');
2636: $description = &mt('Domain - ').$domdesc.': ';
2637: if ($env{'form.roletype'} eq 'domain') {
2638: if ($statusmode eq 'Expired') {
2639: $description .= &mt('Users in domain with expired [_1] roles',$showfilter);
2640: } elsif ($statusmode eq 'Future') {
2641: $description .= &mt('Users in domain with future [_1] roles',$showfilter);
2642: } elsif ($statusmode eq 'Active') {
2643: $description .= &mt('Users in domain with active [_1] roles',$showfilter);
2644: } else {
2645: if ($rolefilter eq 'Any') {
2646: $description .= &mt('All users in domain');
2647: } else {
2648: $description .= &mt('All users in domain with [_1] roles',$rolefilter);
2649: }
2650: }
2651: } elsif ($env{'form.roletype'} eq 'author') {
2652: if ($statusmode eq 'Expired') {
2653: $description .= &mt('Co-authors in domain with expired [_1] roles',$showfilter);
2654: } elsif ($statusmode eq 'Future') {
2655: $description .= &mt('Co-authors in domain with future [_1] roles',$showfilter);
2656: } elsif ($statusmode eq 'Active') {
2657: $description .= &mt('Co-authors in domain with active [_1] roles',$showfilter);
2658: } else {
2659: if ($rolefilter eq 'Any') {
2660: $description .= &mt('All users with co-author roles in domain',$showfilter);
2661: } else {
2662: $description .= &mt('All co-authors in domain with [_1] roles',$rolefilter);
2663: }
2664: }
2665: } elsif ($env{'form.roletype'} eq 'course') {
2666: my $coursefilter = $env{'form.coursepick'};
2667: if ($coursefilter eq 'category') {
2668: my $instcode = &instcode_from_coursefilter();
2669: if ($instcode eq '.') {
2670: $description .= &mt('All courses in domain').' - ';
2671: } else {
2672: $description .= &mt('Courses in domain with institutional code: [_1]',$instcode).' - ';
2673: }
2674: } elsif ($coursefilter eq 'selected') {
2675: $description .= &mt('Selected courses in domain').' - ';
2676: } elsif ($coursefilter eq 'all') {
2677: $description .= &mt('All courses in domain').' - ';
2678: }
2679: if ($statusmode eq 'Expired') {
2680: $description .= &mt('users with expired [_1] roles',$showfilter);
2681: } elsif ($statusmode eq 'Future') {
2682: $description .= &mt('users with future [_1] roles',$showfilter);
2683: } elsif ($statusmode eq 'Active') {
2684: $description .= &mt('users with active [_1] roles',$showfilter);
2685: } else {
2686: if ($rolefilter eq 'Any') {
2687: $description .= &mt('all users');
2688: } else {
2689: $description .= &mt('users with [_1] roles',$rolefilter);
2690: }
2691: }
2692: }
2693: }
2694: return $description;
2695: }
2696:
2697: #################################################
2698: #################################################
2699: sub show_drop_list {
2700: my ($r,$classlist,$keylist,$nosort,$permission)=@_;
2701: my $cid=$env{'request.course.id'};
2702: my ($cnum,$cdom) = &get_course_identity($cid);
2703: if (! exists($env{'form.sortby'})) {
2704: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
2705: ['sortby']);
2706: }
2707: my $sortby = $env{'form.sortby'};
2708: if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) {
2709: $sortby = 'username';
2710: }
2711: my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
2712: $classlist,$keylist,$cdom,$cnum);
2713: #
2714: my $action = "drop";
2715: my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript();
2716: $r->print(<<END);
2717: <input type="hidden" name="sortby" value="$sortby" />
2718: <input type="hidden" name="action" value="$action" />
2719: <input type="hidden" name="state" value="done" />
2720: <script type="text/javascript" language="Javascript">
2721: $check_uncheck_js
2722: </script>
2723: <p>
2724: <input type="hidden" name="phase" value="four">
2725: END
2726:
2727: my %lt=&Apache::lonlocal::texthash('usrn' => "username",
2728: 'dom' => "domain",
2729: 'sn' => "student name",
2730: 'sec' => "section",
2731: 'start' => "start date",
2732: 'end' => "end date",
2733: 'groups' => "active groups",
2734: );
2735: if ($nosort) {
2736: $r->print(&Apache::loncommon::start_data_table().
2737: &Apache::loncommon::start_data_table_header_row());
2738: $r->print(<<END);
2739: <th> </th>
2740: <th>$lt{'usrn'}</th>
2741: <th>$lt{'dom'}</th>
2742: <th>ID</th>
2743: <th>$lt{'sn'}</th>
2744: <th>$lt{'sec'}</th>
2745: <th>$lt{'start'}</th>
2746: <th>$lt{'end'}</th>
2747: <th>$lt{'groups'}</th>
2748: END
2749: $r->print(&Apache::loncommon::end_data_table_header_row());
2750: } else {
2751: $r->print(&Apache::loncommon::start_data_table().
2752: &Apache::loncommon::start_data_table_header_row());
2753: $r->print(<<END);
2754: <th> </th>
2755: <th>
2756: <a href="/adm/createuser?action=$action&sortby=username">$lt{'usrn'}</a>
2757: </th><th>
2758: <a href="/adm/createuser?action=$action&sortby=domain">$lt{'dom'}</a>
2759: </th><th>
2760: <a href="/adm/createuser?action=$action&sortby=id">ID</a>
2761: </th><th>
2762: <a href="/adm/createuser?action=$action&sortby=fullname">$lt{'sn'}</a>
2763: </th><th>
2764: <a href="/adm/createuser?action=$action&sortby=section">$lt{'sec'}</a>
2765: </th><th>
2766: <a href="/adm/createuser?action=$action&sortby=start">$lt{'start'}</a>
2767: </th><th>
2768: <a href="/adm/createuser?action=$action&sortby=end">$lt{'end'}</a>
2769: </th><th>
2770: <a href="/adm/createuser?action=$action&sortby=groups">$lt{'groups'}</a>
2771: </th>
2772: END
2773: $r->print(&Apache::loncommon::end_data_table_header_row());
2774: }
2775: #
2776: # Sort the students
2777: my %index;
2778: my $i;
2779: foreach (@$keylist) {
2780: $index{$_} = $i++;
2781: }
2782: $index{'groups'} = scalar(@$keylist);
2783: my $index = $index{$sortby};
2784: my $second = $index{'username'};
2785: my $third = $index{'domain'};
2786: my @Sorted_Students = sort {
2787: lc($classlist->{$a}->[$index]) cmp lc($classlist->{$b}->[$index])
2788: ||
2789: lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
2790: ||
2791: lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
2792: } (keys(%$classlist));
2793: foreach my $student (@Sorted_Students) {
2794: my $error;
2795: my $sdata = $classlist->{$student};
2796: my $username = $sdata->[$index{'username'}];
2797: my $domain = $sdata->[$index{'domain'}];
2798: my $section = $sdata->[$index{'section'}];
2799: my $name = $sdata->[$index{'fullname'}];
2800: my $id = $sdata->[$index{'id'}];
2801: my $start = $sdata->[$index{'start'}];
2802: my $end = $sdata->[$index{'end'}];
2803: my $groups = $classgroups->{$student};
2804: my $active_groups;
2805: if (ref($groups->{active}) eq 'HASH') {
2806: $active_groups = join(', ',keys(%{$groups->{'active'}}));
2807: }
2808: if (! defined($start) || $start == 0) {
2809: $start = &mt('none');
2810: } else {
2811: $start = &Apache::lonlocal::locallocaltime($start);
2812: }
2813: if (! defined($end) || $end == 0) {
2814: $end = &mt('none');
2815: } else {
2816: $end = &Apache::lonlocal::locallocaltime($end);
2817: }
2818: my $status = $sdata->[$index{'status'}];
2819: next if ($status ne 'Active');
2820: if ($env{'request.course.sec'} ne '') {
2821: if ($section ne $env{'request.course.sec'}) {
2822: next;
2823: }
2824: }
2825: my $studentkey = $student.':'.$section;
2826: my $startitem = '<input type="hidden" name="'.$studentkey.'_start" value="'.$sdata->[$index{'start'}].'" />';
2827: #
2828: $r->print(&Apache::loncommon::start_data_table_row());
2829: $r->print(<<"END");
2830: <td><input type="checkbox" name="droplist" value="$student"></td>
2831: <td>$username</td>
2832: <td>$domain</td>
2833: <td>$id</td>
2834: <td>$name</td>
2835: <td>$section</td>
2836: <td>$start</td>
2837: <td>$end</td>
2838: <td>$active_groups</td>
2839: END
2840: $r->print(&Apache::loncommon::end_data_table_row());
2841: }
2842: $r->print(&Apache::loncommon::end_data_table().'<br />');
2843: %lt=&Apache::lonlocal::texthash(
2844: 'dp' => "Expire Users' Roles",
2845: 'ca' => "check all",
2846: 'ua' => "uncheck all",
2847: );
2848: $r->print(<<"END");
2849: </p><p>
2850: <input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.droplist)">
2851: <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.droplist)">
2852: <p><input type=submit value="$lt{'dp'}"></p>
2853: END
2854: return;
2855: }
2856:
2857: #
2858: # Print out the initial form to get the file containing a list of users
2859: #
2860: sub print_first_users_upload_form {
2861: my ($r,$context) = @_;
2862: my $str;
2863: $str = '<input type="hidden" name="phase" value="two">';
2864: $str .= '<input type="hidden" name="action" value="upload" />';
2865: $str .= '<input type="hidden" name="state" value="got_file" />';
2866: $str .= "<h3>".&mt('Upload a file containing information about users')."</h3>\n";
2867: $str .= &Apache::loncommon::upfile_select_html();
2868: $str .= "<p>\n";
2869: $str .= '<input type="submit" name="fileupload" value="'.
2870: &mt('Upload file of users').'">'."\n";
2871: $str .= '<label><input type="checkbox" name="noFirstLine" /> '.
2872: &mt('Ignore First Line')."</label></p>\n";
2873: $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
2874: &mt("How do I create a users list from a spreadsheet")).
2875: "<br />\n";
2876: $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
2877: &mt("How do I create a CSV file from a spreadsheet")).
2878: "<br />\n";
2879: $str .= &Apache::loncommon::end_page();
2880: $r->print($str);
2881: return;
2882: }
2883:
2884: # ================================================= Drop/Add from uploaded file
2885: sub upfile_drop_add {
2886: my ($r,$context) = @_;
2887: &Apache::loncommon::load_tmp_file($r);
2888: my @userdata=&Apache::loncommon::upfile_record_sep();
2889: if($env{'form.noFirstLine'}){shift(@userdata);}
2890: my @keyfields = split(/\,/,$env{'form.keyfields'});
2891: my %fields=();
2892: for (my $i=0; $i<=$env{'form.nfields'}; $i++) {
2893: if ($env{'form.upfile_associate'} eq 'reverse') {
2894: if ($env{'form.f'.$i} ne 'none') {
2895: $fields{$keyfields[$i]}=$env{'form.f'.$i};
2896: }
2897: } else {
2898: $fields{$env{'form.f'.$i}}=$keyfields[$i];
2899: }
2900: }
2901: #
2902: # Store the field choices away
2903: foreach my $field (qw/username names
2904: fname mname lname gen id sec ipwd email role/) {
2905: $env{'form.'.$field.'_choice'}=$fields{$field};
2906: }
2907: &Apache::loncommon::store_course_settings('enrollment_upload',
2908: { 'username_choice' => 'scalar',
2909: 'names_choice' => 'scalar',
2910: 'fname_choice' => 'scalar',
2911: 'mname_choice' => 'scalar',
2912: 'lname_choice' => 'scalar',
2913: 'gen_choice' => 'scalar',
2914: 'id_choice' => 'scalar',
2915: 'sec_choice' => 'scalar',
2916: 'ipwd_choice' => 'scalar',
2917: 'email_choice' => 'scalar',
2918: 'role_choice' => 'scalar' });
2919: #
2920: my ($startdate,$enddate) = &get_dates_from_form();
2921: if ($env{'form.makedatesdefault'}) {
2922: $r->print(&make_dates_default($startdate,$enddate));
2923: }
2924: # Determine domain and desired host (home server)
2925: my $domain=$env{'request.role.domain'};
2926: my $desiredhost = $env{'form.lcserver'};
2927: if (lc($desiredhost) eq 'default') {
2928: $desiredhost = undef;
2929: } else {
2930: my %home_servers = &Apache::lonnet::get_servers($domain,'library');
2931: if (! exists($home_servers{$desiredhost})) {
2932: $r->print('<span class="LC_error">'.&mt('Error').
2933: &mt('Invalid home server specified').'</span>');
2934: $r->print(&Apache::loncommon::end_page());
2935: return;
2936: }
2937: }
2938: # Determine authentication mechanism
2939: my $changeauth;
2940: if ($context eq 'domain') {
2941: $changeauth = $env{'form.changeauth'};
2942: }
2943: my $amode = '';
2944: my $genpwd = '';
2945: if ($env{'form.login'} eq 'krb') {
2946: $amode='krb';
2947: $amode.=$env{'form.krbver'};
2948: $genpwd=$env{'form.krbarg'};
2949: } elsif ($env{'form.login'} eq 'int') {
2950: $amode='internal';
2951: if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) {
2952: $genpwd=$env{'form.intarg'};
2953: }
2954: } elsif ($env{'form.login'} eq 'loc') {
2955: $amode='localauth';
2956: if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) {
2957: $genpwd=$env{'form.locarg'};
2958: }
2959: }
2960: if ($amode =~ /^krb/) {
2961: if (! defined($genpwd) || $genpwd eq '') {
2962: $r->print('<span class="Error">'.
2963: &mt('Unable to enroll users').' '.
2964: &mt('No Kerberos domain was specified.').'</span></p>');
2965: $amode = ''; # This causes the loop below to be skipped
2966: }
2967: }
2968: my ($cid,$defaultsec,$defaultrole,$setting);
2969: if ($context eq 'domain') {
2970: $setting = $env{'form.roleaction'};
2971: if ($setting eq 'domain') {
2972: $defaultrole = $env{'form.defaultrole'};
2973: } elsif ($setting eq 'course') {
2974: $defaultrole = $env{'form.courserole'};
2975: }
2976: } elsif ($context eq 'author') {
2977: $defaultrole = $env{'form.defaultrole'};
2978: }
2979: if ($context eq 'domain' && $setting eq 'course') {
2980: if ($env{'form.newsec'} ne '') {
2981: $defaultsec = $env{'form.newsec'};
2982: } elsif ($env{'form.defaultsec'} ne '') {
2983: $defaultsec = $env{'form.defaultsec'}
2984: }
2985: }
2986: if ($env{'request.course.id'} ne '') {
2987: $cid = $env{'request.course.id'};
2988: } elsif ($env{'form.defaultdomain'} ne '' && $env{'form.defaultcourse'} ne '') {
2989: $cid = $env{'form.defaultdomain'}.'_'.
2990: $env{'form.defaultcourse'};
2991: }
2992: if ( $domain eq &LONCAPA::clean_domain($domain)
2993: && ($amode ne '')) {
2994: #######################################
2995: ## Add/Modify Users ##
2996: #######################################
2997: if ($context eq 'course') {
2998: $r->print('<h3>'.&mt('Enrolling Users')."</h3>\n<p>\n");
2999: } elsif ($context eq 'author') {
3000: $r->print('<h3>'.&mt('Updating Co-authors')."</h3>\n<p>\n");
3001: } else {
3002: $r->print('<h3>'.&mt('Adding/Modifying Users')."</h3>\n<p>\n");
3003: }
3004: my %counts = (
3005: user => 0,
3006: auth => 0,
3007: role => 0,
3008: );
3009: my $flushc=0;
3010: my %student=();
3011: my %curr_groups;
3012: my %userchg;
3013: if ($context eq 'course') {
3014: # Get information about course groups
3015: %curr_groups = &Apache::longroup::coursegroups();
3016: }
3017: my (%curr_rules,%got_rules,%alerts);
3018: # Get new users list
3019: foreach (@userdata) {
3020: my %entries=&Apache::loncommon::record_sep($_);
3021: # Determine user name
3022: unless (($entries{$fields{'username'}} eq '') ||
3023: (!defined($entries{$fields{'username'}}))) {
3024: my ($fname, $mname, $lname,$gen) = ('','','','');
3025: if (defined($fields{'names'})) {
3026: ($lname,$fname,$mname)=($entries{$fields{'names'}}=~
3027: /([^\,]+)\,\s*(\w+)\s*(.*)$/);
3028: } else {
3029: if (defined($fields{'fname'})) {
3030: $fname=$entries{$fields{'fname'}};
3031: }
3032: if (defined($fields{'mname'})) {
3033: $mname=$entries{$fields{'mname'}};
3034: }
3035: if (defined($fields{'lname'})) {
3036: $lname=$entries{$fields{'lname'}};
3037: }
3038: if (defined($fields{'gen'})) {
3039: $gen=$entries{$fields{'gen'}};
3040: }
3041: }
3042: if ($entries{$fields{'username'}}
3043: ne &LONCAPA::clean_username($entries{$fields{'username'}})) {
3044: $r->print('<br />'.
3045: &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]',
3046: $entries{$fields{'username'}},$fname,$mname,$lname,$gen).
3047: '</b>');
3048: } else {
3049: my $username = $entries{$fields{'username'}};
3050: my $sec;
3051: if ($context eq 'course' || $setting eq 'course') {
3052: # determine section number
3053: if (defined($fields{'sec'})) {
3054: if (defined($entries{$fields{'sec'}})) {
3055: $sec=$entries{$fields{'sec'}};
3056: }
3057: } else {
3058: $sec = $defaultsec;
3059: }
3060: # remove non alphanumeric values from section
3061: $sec =~ s/\W//g;
3062: if ($sec eq "none" || $sec eq 'all') {
3063: $r->print('<br />'.
3064: &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a reserved word.',
3065: $username,$sec,$fname,$mname,$lname,$gen));
3066: next;
3067: } elsif (($sec ne '') && (exists($curr_groups{$sec}))) {
3068: $r->print('<br />'.
3069: &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a course group. Section names and group names must be distinct.',
3070: $username,$sec,$fname,$mname,$lname,$gen));
3071: next;
3072: }
3073: }
3074: # determine id number
3075: my $id='';
3076: if (defined($fields{'id'})) {
3077: if (defined($entries{$fields{'id'}})) {
3078: $id=$entries{$fields{'id'}};
3079: }
3080: $id=~tr/A-Z/a-z/;
3081: }
3082: # determine email address
3083: my $email='';
3084: if (defined($fields{'email'})) {
3085: if (defined($entries{$fields{'email'}})) {
3086: $email=$entries{$fields{'email'}};
3087: unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; } }
3088: }
3089: # determine user password
3090: my $password = $genpwd;
3091: if (defined($fields{'ipwd'})) {
3092: if ($entries{$fields{'ipwd'}}) {
3093: $password=$entries{$fields{'ipwd'}};
3094: }
3095: }
3096: # determine user role
3097: my $role = '';
3098: if (defined($fields{'role'})) {
3099: if ($entries{$fields{'role'}}) {
3100: my @poss_roles =
3101: &curr_role_permissions($context,$setting);
3102: if (grep(/^\Q$entries{$fields{'role'}}\E/,@poss_roles)) {
3103: $role=$entries{$fields{'role'}};
3104: } else {
3105: my $rolestr = join(', ',@poss_roles);
3106: $r->print('<br />'.
3107: &mt('<b>[_1]</b>: You do not have permission to add the requested role [_2] for the user.',$entries{$fields{'username'}},$entries{$fields{'role'}}).'<br />'.&mt('Allowable role(s) is/are: [_1].',$rolestr)."\n");
3108: next;
3109: }
3110: }
3111: }
3112: if ($role eq '') {
3113: $role = $defaultrole;
3114: }
3115: # Clean up whitespace
3116: foreach (\$domain,\$username,\$id,\$fname,\$mname,
3117: \$lname,\$gen,\$sec,\$role) {
3118: $$_ =~ s/(\s+$|^\s+)//g;
3119: }
3120: # check against rules
3121: my $checkid = 0;
3122: my $newuser = 0;
3123: my (%rulematch,%inst_results,%idinst_results);
3124: my $uhome=&Apache::lonnet::homeserver($username,$domain);
3125: if ($uhome eq 'no_host') {
3126: $checkid = 1;
3127: $newuser = 1;
3128: my $checkhash;
3129: my $checks = { 'username' => 1 };
3130: $checkhash->{$username.':'.$domain} = { 'newuser' => 1, };
3131: &Apache::loncommon::user_rule_check($checkhash,$checks,
3132: \%alerts,\%rulematch,\%inst_results,\%curr_rules,
3133: \%got_rules);
3134: if (ref($alerts{'username'}) eq 'HASH') {
3135: if (ref($alerts{'username'}{$domain}) eq 'HASH') {
3136: next if ($alerts{'username'}{$domain}{$username});
3137: }
3138: }
3139: } else {
3140: # FIXME check if user info can be updated.
3141: }
3142: if ($id ne '') {
3143: if (!$newuser) {
3144: my %idhash = &Apache::lonnet::idrget($domain,($username));
3145: if ($idhash{$username} ne $id) {
3146: $checkid = 1;
3147: }
3148: }
3149: if ($checkid) {
3150: my $checkhash;
3151: my $checks = { 'id' => 1 };
3152: $checkhash->{$username.':'.$domain} = { 'newuser' => $newuser,
3153: 'id' => $id };
3154: &Apache::loncommon::user_rule_check($checkhash,$checks,
3155: \%alerts,\%rulematch,\%idinst_results,\%curr_rules,
3156: \%got_rules);
3157: if (ref($alerts{'id'}) eq 'HASH') {
3158: if (ref($alerts{'id'}{$domain}) eq 'HASH') {
3159: next if ($alerts{'id'}{$domain}{$id});
3160: }
3161: }
3162: }
3163: }
3164: if ($password || $env{'form.login'} eq 'loc') {
3165: my ($userresult,$authresult,$roleresult);
3166: if ($role eq 'st') {
3167: &modifystudent($domain,$username,$cid,$sec,
3168: $desiredhost);
3169: $roleresult =
3170: &Apache::lonnet::modifystudent
3171: ($domain,$username,$id,$amode,$password,
3172: $fname,$mname,$lname,$gen,$sec,$enddate,
3173: $startdate,$env{'form.forceid'},
3174: $desiredhost,$email);
3175: } else {
3176: ($userresult,$authresult,$roleresult) =
3177: &modifyuserrole($context,$setting,
3178: $changeauth,$cid,$domain,$username,
3179: $id,$amode,$password,$fname,
3180: $mname,$lname,$gen,$sec,
3181: $env{'form.forceid'},$desiredhost,
3182: $email,$role,$enddate,$startdate,$checkid);
3183: }
3184: $flushc =
3185: &user_change_result($r,$userresult,$authresult,
3186: $roleresult,\%counts,$flushc,
3187: $username,%userchg);
3188: } else {
3189: if ($context eq 'course') {
3190: $r->print('<br />'.
3191: &mt('<b>[_1]</b>: Unable to enroll. No password specified.',$username)
3192: );
3193: } elsif ($context eq 'author') {
3194: $r->print('<br />'.
3195: &mt('<b>[_1]</b>: Unable to add co-author. No password specified.',$username)
3196: );
3197: } else {
3198: $r->print('<br />'.
3199: &mt('<b>[_1]</b>: Unable to add user. No password specified.',$username)
3200: );
3201: }
3202: }
3203: }
3204: }
3205: } # end of foreach (@userdata)
3206: # Flush the course logs so reverse user roles immediately updated
3207: &Apache::lonnet::flushcourselogs();
3208: $r->print("</p>\n<p>\n".&mt('Processed [_1] user(s).',$counts{'user'}).
3209: "</p>\n");
3210: if ($counts{'role'} > 0) {
3211: $r->print("<p>\n".
3212: &mt('Roles added for [_1] users. If user is active, the new role will be available when the user next logs in to LON-CAPA.',$counts{'role'})."</p>\n");
3213: }
3214: if ($counts{'auth'} > 0) {
3215: $r->print("<p>\n".
3216: &mt('Authentication changed for [_1] existing users.',
3217: $counts{'auth'})."</p>\n");
3218: }
3219: $r->print(&print_namespacing_alerts($domain,\%alerts,\%curr_rules));
3220: $r->print('<form name="uploadresult" action="/adm/createuser">');
3221: $r->print(&Apache::lonhtmlcommon::echo_form_input(['phase','prevphase','currstate']));
3222: $r->print('</form>');
3223: #####################################
3224: # Drop students #
3225: #####################################
3226: if ($env{'form.fullup'} eq 'yes') {
3227: $r->print('<h3>'.&mt('Dropping Students')."</h3>\n");
3228: # Get current classlist
3229: my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
3230: if (! defined($classlist)) {
3231: $r->print(&mt('There are no students currently enrolled.').
3232: "\n");
3233: } else {
3234: # Remove the students we just added from the list of students.
3235: foreach (@userdata) {
3236: my %entries=&Apache::loncommon::record_sep($_);
3237: unless (($entries{$fields{'username'}} eq '') ||
3238: (!defined($entries{$fields{'username'}}))) {
3239: delete($classlist->{$entries{$fields{'username'}}.
3240: ':'.$domain});
3241: }
3242: }
3243: # Print out list of dropped students.
3244: &show_drop_list($r,$classlist,$keylist,'nosort');
3245: }
3246: }
3247: } # end of unless
3248: }
3249:
3250: sub print_namespacing_alerts {
3251: my ($domain,$alerts,$curr_rules) = @_;
3252: my $output;
3253: if (ref($alerts) eq 'HASH') {
3254: if (keys(%{$alerts}) > 0) {
3255: if (ref($alerts->{'username'}) eq 'HASH') {
3256: foreach my $dom (sort(keys(%{$alerts->{'username'}}))) {
3257: my $count;
3258: if (ref($alerts->{'username'}{$dom}) eq 'HASH') {
3259: $count = keys(%{$alerts->{'username'}{$dom}});
3260: }
3261: my $domdesc = &Apache::lonnet::domain($domain,'description');
3262: if (ref($curr_rules->{$dom}) eq 'HASH') {
3263: $output .= &Apache::loncommon::instrule_disallow_msg(
3264: 'username',$domdesc,$count,'upload');
3265: }
3266: $output .= &Apache::loncommon::user_rule_formats($dom,
3267: $domdesc,$curr_rules->{$dom}{'username'},
3268: 'username');
3269: }
3270: }
3271: if (ref($alerts->{'id'}) eq 'HASH') {
3272: foreach my $dom (sort(keys(%{$alerts->{'id'}}))) {
3273: my $count;
3274: if (ref($alerts->{'id'}{$dom}) eq 'HASH') {
3275: $count = keys(%{$alerts->{'id'}{$dom}});
3276: }
3277: my $domdesc = &Apache::lonnet::domain($domain,'description');
3278: if (ref($curr_rules->{$dom}) eq 'HASH') {
3279: $output .= &Apache::loncommon::instrule_disallow_msg(
3280: 'id',$domdesc,$count,'upload');
3281: }
3282: $output .= &Apache::loncommon::user_rule_formats($dom,
3283: $domdesc,$curr_rules->{$dom}{'id'},'id');
3284: }
3285: }
3286: }
3287: }
3288: }
3289:
3290: sub user_change_result {
3291: my ($r,$userresult,$authresult,$roleresult,$counts,$flushc,$username,
3292: $userchg) = @_;
3293: my $okresult = 0;
3294: if ($userresult ne 'ok') {
3295: if ($userresult =~ /^error:(.+)$/) {
3296: my $error = $1;
3297: $r->print('<br />'.
3298: &mt('<b>[_1]</b>: Unable to add/modify: [_2]',$username,$error));
3299: }
3300: } else {
3301: $counts->{'user'} ++;
3302: $okresult = 1;
3303: }
3304: if ($authresult ne 'ok') {
3305: if ($authresult =~ /^error:(.+)$/) {
3306: my $error = $1;
3307: $r->print('<br />'.
3308: &mt('<b>[_1]</b>: Unable to modify authentication: [_2]',$username,$error));
3309: }
3310: } else {
3311: $counts->{'auth'} ++;
3312: $okresult = 1;
3313: }
3314: if ($roleresult ne 'ok') {
3315: if ($roleresult =~ /^error:(.+)$/) {
3316: my $error = $1;
3317: $r->print('<br />'.
3318: &mt('<b>[_1]</b>: Unable to add role: [_2]',$username,$error));
3319: }
3320: } else {
3321: $counts->{'role'} ++;
3322: $okresult = 1;
3323: }
3324: if ($okresult) {
3325: $flushc++;
3326: $userchg->{$username}=1;
3327: $r->print('. ');
3328: if ($flushc>15) {
3329: $r->rflush;
3330: $flushc=0;
3331: }
3332: }
3333: return $flushc;
3334: }
3335:
3336: # ========================================================= Menu Phase Two Drop
3337: sub print_drop_menu {
3338: my ($r,$context,$permission) = @_;
3339: $r->print('<h3>'.&mt("Drop Students").'</h3>'."\n".
3340: '<form name="studentform" method="post">'."\n");
3341: my $cid=$env{'request.course.id'};
3342: my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();
3343: if (! defined($classlist)) {
3344: $r->print(&mt('There are no students currently enrolled.')."\n");
3345: return;
3346: }
3347: # Print out the available choices
3348: &show_drop_list($r,$classlist,$keylist,$permission);
3349: $r->print('</form>'. &Apache::loncommon::end_page());
3350: return;
3351: }
3352:
3353: # ================================================================== Phase four
3354:
3355: sub update_user_list {
3356: my ($r,$context,$setting,$choice) = @_;
3357: my $now = time;
3358: my $count=0;
3359: my @changelist;
3360: if ($choice ne '') {
3361: @changelist = &Apache::loncommon::get_env_multiple('form.actionlist');
3362: } else {
3363: @changelist = &Apache::loncommon::get_env_multiple('form.droplist');
3364: }
3365: my %result_text = ( ok => { 'revoke' => 'Revoked',
3366: 'delete' => 'Deleted',
3367: 'reenable' => 'Re-enabled',
3368: 'activate' => 'Activated',
3369: 'chgdates' => 'Changed Access Dates for',
3370: 'chgsec' => 'Changed section for',
3371: 'drop' => 'Dropped',
3372: },
3373: error => {'revoke' => 'revoking',
3374: 'delete' => 'deleting',
3375: 'reenable' => 're-enabling',
3376: 'activate' => 'activating',
3377: 'chgdates' => 'changing access dates for',
3378: 'chgsec' => 'changing section for',
3379: 'drop' => 'dropping',
3380: },
3381: );
3382: my ($startdate,$enddate);
3383: if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') {
3384: ($startdate,$enddate) = &get_dates_from_form();
3385: }
3386: foreach my $item (@changelist) {
3387: my ($role,$uname,$udom,$cid,$sec,$scope,$result,$type,$locktype,@sections,
3388: $scopestem);
3389: if ($choice eq 'drop') {
3390: ($uname,$udom,$sec) = split(/:/,$item,-1);
3391: $role = 'st';
3392: $cid = $env{'request.course.id'};
3393: $scopestem = '/'.$cid;
3394: $scopestem =~s/\_/\//g;
3395: if ($sec eq '') {
3396: $scope = $scopestem;
3397: } else {
3398: $scope = $scopestem.'/'.$sec;
3399: }
3400: } elsif ($context eq 'course') {
3401: ($uname,$udom,$role,$sec,$type,$locktype) = split(/\:/,$item,-1);
3402: $cid = $env{'request.course.id'};
3403: $scopestem = '/'.$cid;
3404: $scopestem =~s/\_/\//g;
3405: if ($sec eq '') {
3406: $scope = $scopestem;
3407: } else {
3408: $scope = $scopestem.'/'.$sec;
3409: }
3410: } elsif ($context eq 'author') {
3411: ($uname,$udom,$role) = split(/\:/,$item,-1);
3412: $scope = '/'.$env{'user.domain'}.'/'.$env{'user.name'};
3413: } elsif ($context eq 'domain') {
3414: if ($setting eq 'domain') {
3415: ($role,$uname,$udom) = split(/\:/,$item,-1);
3416: $scope = '/'.$env{'request.role.domain'}.'/';
3417: } elsif ($setting eq 'author') {
3418: ($uname,$udom,$role,$scope) = split(/\:/,$item);
3419: } elsif ($setting eq 'course') {
3420: ($uname,$udom,$role,$cid,$sec,$type,$locktype) =
3421: split(/\:/,$item);
3422: $scope = '/'.$cid;
3423: $scope =~s/\_/\//g;
3424: if ($sec ne '') {
3425: $scope .= '/'.$sec;
3426: }
3427: }
3428: }
3429: my $plrole = &Apache::lonnet::plaintext($role);
3430: my ($uid,$first,$middle,$last,$gene,$sec);
3431: my $start = $env{'form.'.$item.'_start'};
3432: my $end = $env{'form.'.$item.'_end'};
3433: if ($choice eq 'drop') {
3434: # drop students
3435: $end = $now;
3436: $type = 'manual';
3437: $result =
3438: &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid);
3439: } elsif ($choice eq 'revoke') {
3440: # revoke or delete user role
3441: $end = $now;
3442: if ($role eq 'st') {
3443: $result =
3444: &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid);
3445: } else {
3446: $result =
3447: &Apache::lonnet::revokerole($udom,$uname,$scope,$role);
3448: }
3449: } elsif ($choice eq 'delete') {
3450: $start = -1;
3451: $end = -1;
3452: if ($role eq 'st') {
3453: # FIXME - how does role deletion affect classlist?
3454: &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid);
3455: } else {
3456: $result =
3457: &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$now,
3458: 0,1);
3459: }
3460: } else {
3461: #reenable, activate, change access dates or change section
3462: if ($choice ne 'chgsec') {
3463: $start = $startdate;
3464: $end = $enddate;
3465: }
3466: if ($choice eq 'reenable') {
3467: if ($role eq 'st') {
3468: $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid);
3469: } else {
3470: $result =
3471: &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
3472: $now);
3473: }
3474: } elsif ($choice eq 'activate') {
3475: if ($role eq 'st') {
3476: $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid);
3477: } else {
3478: $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
3479: $now);
3480: }
3481: } elsif ($choice eq 'chgdates') {
3482: if ($role eq 'st') {
3483: $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid);
3484: } else {
3485: $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end,
3486: $start);
3487: }
3488: } elsif ($choice eq 'chgsec') {
3489: my (@newsecs,$revresult,$nochg,@retained);
3490: if ($role ne 'cc') {
3491: @newsecs = split(/,/,$env{'form.newsecs'});
3492: }
3493: # remove existing section if not to be retained.
3494: if (!$env{'form.retainsec'}) {
3495: if ($sec eq '') {
3496: if (@newsecs == 0) {
3497: $result = &mt('No change in section assignment (none)');
3498: $nochg = 1;
3499: }
3500: } else {
3501: if (!grep(/^\Q$sec\E$/,@newsecs)) {
3502: $revresult =
3503: &Apache::lonnet::revokerole($udom,$uname,$scope,$role);
3504: } else {
3505: push(@retained,$sec);
3506: }
3507: }
3508: } else {
3509: push(@retained,$sec);
3510: }
3511: # add new sections
3512: if (@newsecs == 0) {
3513: if (!$nochg) {
3514: if ($sec ne '') {
3515: if ($role eq 'st') {
3516: $result =
3517: &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid);
3518: } else {
3519: my $newscope = $scopestem;
3520: $result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start);
3521: }
3522: }
3523: }
3524: } else {
3525: foreach my $newsec (@newsecs) {
3526: if (!grep(/^\Q$newsec\E$/,@retained)) {
3527: if ($role eq 'st') {
3528: $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$newsec,$end,$start,$type,$locktype,$cid);
3529: } else {
3530: my $newscope = $scopestem;
3531: if ($newsec ne '') {
3532: $newscope .= '/'.$newsec;
3533: }
3534: $result = &Apache::lonnet::assignrole($udom,$uname,
3535: $newscope,$role,$end,$start);
3536: }
3537: }
3538: }
3539: }
3540: }
3541: }
3542: my $extent = $scope;
3543: if ($choice eq 'drop' || $context eq 'course') {
3544: my ($cnum,$cdom,$cdesc) = &get_course_identity($cid);
3545: if ($cdesc) {
3546: $extent = $cdesc;
3547: }
3548: }
3549: if ($result eq 'ok' || $result eq 'ok:') {
3550: $r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for [_3]",
3551: $plrole,$extent,$uname.':'.$udom).'<br />');
3552: $count++;
3553: } else {
3554: $r->print(
3555: &mt("Error $result_text{'error'}{$choice} [_1] in [_2] for [_3]:[_4]",
3556: $plrole,$extent,$uname.':'.$udom,$result).'<br />');
3557: }
3558: }
3559: $r->print('<p><b>'.&mt("$result_text{'ok'}{$choice} role(s) for [quant,_1,user,users,users].",$count).'</b></p>');
3560: if ($count > 0) {
3561: if ($choice eq 'revoke' || $choice eq 'drop') {
3562: $r->print('<p>'.&mt('Re-enabling will re-activate data for the role.</p>'));
3563: }
3564: # Flush the course logs so reverse user roles immediately updated
3565: &Apache::lonnet::flushcourselogs();
3566: }
3567: if ($env{'form.makedatesdefault'}) {
3568: if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') {
3569: $r->print(&make_dates_default($startdate,$enddate));
3570: }
3571: }
3572: }
3573:
3574: sub classlist_drop {
3575: my ($scope,$uname,$udom,$now,$action) = @_;
3576: my ($cdom,$cnum) = ($scope=~m{^/($match_domain)/($match_courseid)});
3577: my $cid=$cdom.'_'.$cnum;
3578: my $user = $uname.':'.$udom;
3579: if ($action eq 'drop') {
3580: if (!&active_student_roles($cnum,$cdom,$uname,$udom)) {
3581: my $result =
3582: &Apache::lonnet::cput('classlist',
3583: { $user => $now },
3584: $env{'course.'.$cid.'.domain'},
3585: $env{'course.'.$cid.'.num'});
3586: return &mt('Drop from classlist: [_1]',
3587: '<b>'.$result.'</b>').'<br />';
3588: }
3589: }
3590: }
3591:
3592: sub active_student_roles {
3593: my ($cnum,$cdom,$uname,$udom) = @_;
3594: my %roles =
3595: &Apache::lonnet::get_my_roles($uname,$udom,'userroles',
3596: ['future','active'],['st']);
3597: return exists($roles{"$cnum:$cdom:st"});
3598: }
3599:
3600: sub section_check_js {
3601: my $groupslist= &get_groupslist();
3602: return <<"END";
3603: function validate(caller) {
3604: var groups = new Array($groupslist);
3605: var secname = caller.value;
3606: if ((secname == 'all') || (secname == 'none')) {
3607: alert("'"+secname+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name.");
3608: return 'error';
3609: }
3610: if (secname != '') {
3611: for (var k=0; k<groups.length; k++) {
3612: if (secname == groups[k]) {
3613: alert("'"+secname+"' may not be used as the name for a section, as it is the name of a course group.\\nSection names and group names must be distinct. Please choose a different section name.");
3614: return 'error';
3615: }
3616: }
3617: }
3618: return 'ok';
3619: }
3620: END
3621: }
3622:
3623: sub set_login {
3624: my ($dom,$authformkrb,$authformint,$authformloc) = @_;
3625: my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom);
3626: my $response;
3627: my ($authnum,%can_assign) =
3628: &Apache::loncommon::get_assignable_auth($dom);
3629: if ($authnum) {
3630: $response = &Apache::loncommon::start_data_table();
3631: if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) {
3632: $response .= &Apache::loncommon::start_data_table_row().
3633: '<td>'.$authformkrb.'</td>'.
3634: &Apache::loncommon::end_data_table_row()."\n";
3635: }
3636: if ($can_assign{'int'}) {
3637: $response .= &Apache::loncommon::start_data_table_row().
3638: '<td>'.$authformint.'</td>'.
3639: &Apache::loncommon::end_data_table_row()."\n"
3640: }
3641: if ($can_assign{'loc'}) {
3642: $response .= &Apache::loncommon::start_data_table_row().
3643: '<td>'.$authformloc.'</td>'.
3644: &Apache::loncommon::end_data_table_row()."\n";
3645: }
3646: $response .= &Apache::loncommon::end_data_table();
3647: }
3648: return $response;
3649: }
3650:
3651: sub course_sections {
3652: my ($sections_count,$role) = @_;
3653: my $output = '';
3654: my @sections = (sort {$a <=> $b} keys %{$sections_count});
3655: if (scalar(@sections) == 1) {
3656: $output = '<select name="currsec_'.$role.'" >'."\n".
3657: ' <option value="">Select</option>'."\n".
3658: ' <option value="">No section</option>'."\n".
3659: ' <option value="'.$sections[0].'" >'.$sections[0].'</option>'."\n";
3660: } else {
3661: $output = '<select name="currsec_'.$role.'" ';
3662: my $multiple = 4;
3663: if (scalar(@sections) < 4) { $multiple = scalar(@sections); }
3664: $output .= 'multiple="multiple" size="'.$multiple.'">'."\n";
3665: foreach my $sec (@sections) {
3666: $output .= '<option value="'.$sec.'">'.$sec."</option>\n";
3667: }
3668: }
3669: $output .= '</select>';
3670: return $output;
3671: }
3672:
3673: sub get_groupslist {
3674: my $groupslist;
3675: my %curr_groups = &Apache::longroup::coursegroups();
3676: if (%curr_groups) {
3677: $groupslist = join('","',sort(keys(%curr_groups)));
3678: $groupslist = '"'.$groupslist.'"';
3679: }
3680: return $groupslist;
3681: }
3682:
3683: sub setsections_javascript {
3684: my ($form,$groupslist) = @_;
3685: my ($checkincluded,$finish,$roleplace,$setsection_js);
3686: if ($form eq 'cu') {
3687: $checkincluded = 'formname.elements[i-1].checked == true';
3688: $finish = 'formname.submit()';
3689: $roleplace = 3;
3690: } else {
3691: $checkincluded = 'formname.name == "'.$form.'"';
3692: $finish = "seccheck = 'ok';";
3693: $roleplace = 1;
3694: $setsection_js = "var seccheck = 'alert';";
3695: }
3696: my %alerts = &Apache::lonlocal::texthash(
3697: secd => 'Section designations do not apply to Course Coordinator roles.',
3698: accr => 'A course coordinator role will be added with access to all sections.',
3699: inea => 'In each course, each user may only have one student role at a time.',
3700: youh => 'You had selected ',
3701: secs => 'sections.',
3702: plmo => 'Please modify your selections so they include no more than one section.',
3703: mayn => 'may not be used as the name for a section, as it is a reserved word.',
3704: plch => 'Please choose a different section name.',
3705: mnot => 'may not be used as a section name, as it is the name of a course group.',
3706: secn => 'Section names and group names must be distinct. Please choose a different section name.',
3707: );
3708: $setsection_js .= <<"ENDSECCODE";
3709:
3710: function setSections(formname) {
3711: var re1 = /^currsec_/;
3712: var groups = new Array($groupslist);
3713: for (var i=0;i<formname.elements.length;i++) {
3714: var str = formname.elements[i].name;
3715: var checkcurr = str.match(re1);
3716: if (checkcurr != null) {
3717: if ($checkincluded) {
3718: var match = str.split('_');
3719: var role = match[$roleplace];
3720: if (role == 'cc') {
3721: alert("$alerts{'secd'}\\n$alerts{'accr'}");
3722: }
3723: else {
3724: var sections = '';
3725: var numsec = 0;
3726: var sections;
3727: for (var j=0; j<formname.elements[i].length; j++) {
3728: if (formname.elements[i].options[j].selected == true ) {
3729: if (formname.elements[i].options[j].value != "") {
3730: if (numsec == 0) {
3731: if (formname.elements[i].options[j].value != "") {
3732: sections = formname.elements[i].options[j].value;
3733: numsec ++;
3734: }
3735: }
3736: else {
3737: sections = sections + "," + formname.elements[i].options[j].value
3738: numsec ++;
3739: }
3740: }
3741: }
3742: }
3743: if (numsec > 0) {
3744: if (formname.elements[i+1].value != "" && formname.elements[i+1].value != null) {
3745: sections = sections + "," + formname.elements[i+1].value;
3746: }
3747: }
3748: else {
3749: sections = formname.elements[i+1].value;
3750: }
3751: var newsecs = formname.elements[i+1].value;
3752: var numsplit;
3753: if (newsecs != null && newsecs != "") {
3754: numsplit = newsecs.split(/,/g);
3755: numsec = numsec + numsplit.length;
3756: }
3757:
3758: if ((role == 'st') && (numsec > 1)) {
3759: alert("$alerts{'inea'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}")
3760: return;
3761: }
3762: else {
3763: if (numsplit != null) {
3764: for (var j=0; j<numsplit.length; j++) {
3765: if ((numsplit[j] == 'all') ||
3766: (numsplit[j] == 'none')) {
3767: alert("'"+numsplit[j]+"' $alerts{'mayn'}\\n$alerts{'plch'}");
3768: return;
3769: }
3770: for (var k=0; k<groups.length; k++) {
3771: if (numsplit[j] == groups[k]) {
3772: alert("'"+numsplit[j]+"' $alerts{'mnot'}\\n$alerts{'secn'}");
3773: return;
3774: }
3775: }
3776: }
3777: }
3778: formname.elements[i+2].value = sections;
3779: }
3780: }
3781: }
3782: }
3783: }
3784: $finish
3785: }
3786: ENDSECCODE
3787: return $setsection_js;
3788: }
3789:
3790: sub can_create_user {
3791: my ($dom,$context,$usertype) = @_;
3792: my %domconf = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom);
3793: my $cancreate = 1;
3794: if (ref($domconf{'usercreation'}) eq 'HASH') {
3795: if (ref($domconf{'usercreation'}{'cancreate'}) eq 'HASH') {
3796: if ($context eq 'course' || $context eq 'author') {
3797: my $creation = $domconf{'usercreation'}{'cancreate'}{$context};
3798: if ($creation eq 'none') {
3799: $cancreate = 0;
3800: } elsif ($creation ne 'any') {
3801: if (defined($usertype)) {
3802: if ($creation ne $usertype) {
3803: $cancreate = 0;
3804: }
3805: }
3806: }
3807: }
3808: }
3809: }
3810: return $cancreate;
3811: }
3812:
3813: sub can_modify_userinfo {
3814: my ($context,$dom,$fields,$userroles) = @_;
3815: my %domconfig =
3816: &Apache::lonnet::get_dom('configuration',['usermodification'],
3817: $dom);
3818: my %canmodify;
3819: if (ref($fields) eq 'ARRAY') {
3820: foreach my $field (@{$fields}) {
3821: $canmodify{$field} = 0;
3822: if (&Apache::lonnet::allowed('mau',$dom)) {
3823: $canmodify{$field} = 1;
3824: } else {
3825: if (ref($domconfig{'usermodification'}) eq 'HASH') {
3826: if (ref($domconfig{'usermodification'}{$context}) eq 'HASH') {
3827: if (ref($userroles) eq 'ARRAY') {
3828: foreach my $role (@{$userroles}) {
3829: my $testrole;
3830: if ($role =~ /^cr\//) {
3831: $testrole = 'cr';
3832: } else {
3833: $testrole = $role;
3834: }
3835: if (ref($domconfig{'usermodification'}{$context}{$testrole}) eq 'HASH') {
3836: if ($domconfig{'usermodification'}{$context}{$testrole}{$field}) {
3837: $canmodify{$field} = 1;
3838: last;
3839: }
3840: }
3841: }
3842: } else {
3843: foreach my $key (keys(%{$domconfig{'usermodification'}{$context}})) {
3844: if (ref($domconfig{'usermodification'}{$context}{$key}) eq 'HASH') {
3845: if ($domconfig{'usermodification'}{$context}{$key}{$field}) {
3846: $canmodify{$field} = 1;
3847: last;
3848: }
3849: }
3850: }
3851: }
3852: }
3853: } elsif ($context eq 'course') {
3854: if (ref($userroles) eq 'ARRAY') {
3855: if (grep(/^st$/,@{$userroles})) {
3856: $canmodify{$field} = 1;
3857: }
3858: } else {
3859: $canmodify{$field} = 1;
3860: }
3861: }
3862: }
3863: }
3864: }
3865: return %canmodify;
3866: }
3867:
3868: sub check_usertype {
3869: my ($dom,$uname,$rules) = @_;
3870: my $usertype;
3871: if (ref($rules) eq 'HASH') {
3872: my @user_rules = keys(%{$rules});
3873: if (@user_rules > 0) {
3874: my %rule_check = &Apache::lonnet::inst_rulecheck($dom,$uname,undef,'username',\@user_rules);
3875: if (keys(%rule_check) > 0) {
3876: $usertype = 'unofficial';
3877: foreach my $item (keys(%rule_check)) {
3878: if ($rule_check{$item}) {
3879: $usertype = 'official';
3880: last;
3881: }
3882: }
3883: }
3884: }
3885: }
3886: return $usertype;
3887: }
3888:
3889: sub roles_by_context {
3890: my ($context,$custom) = @_;
3891: my @allroles;
3892: if ($context eq 'course') {
3893: @allroles = ('st','ad','ta','ep','in','cc');
3894: if ($custom) {
3895: push(@allroles,'cr');
3896: }
3897: } elsif ($context eq 'author') {
3898: @allroles = ('ca','aa');
3899: } elsif ($context eq 'domain') {
3900: @allroles = ('li','dg','sc','au','dc');
3901: }
3902: return @allroles;
3903: }
3904:
3905: sub get_permission {
3906: my ($context,$roles) = @_;
3907: my %permission;
3908: if ($context eq 'course') {
3909: my $custom = 1;
3910: my @allroles = &roles_by_context($context,$custom);
3911: foreach my $role (@allroles) {
3912: if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) {
3913: $permission{'cusr'} = 1;
3914: last;
3915: }
3916: }
3917: if (&Apache::lonnet::allowed('ccr',$env{'request.course.id'})) {
3918: $permission{'custom'} = 1;
3919: }
3920: if (&Apache::lonnet::allowed('vcl',$env{'request.course.id'})) {
3921: $permission{'view'} = 1;
3922: }
3923: if (!$permission{'view'}) {
3924: my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'};
3925: $permission{'view'} = &Apache::lonnet::allowed('vcl',$scope);
3926: if ($permission{'view'}) {
3927: $permission{'view_section'} = $env{'request.course.sec'};
3928: }
3929: }
3930: if (!$permission{'cusr'}) {
3931: if ($env{'request.course.sec'} ne '') {
3932: my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'};
3933: $permission{'cusr'} = (&Apache::lonnet::allowed('cst',$scope));
3934: if ($permission{'cusr'}) {
3935: $permission{'cusr_section'} = $env{'request.course.sec'};
3936: }
3937: }
3938: }
3939: if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
3940: $permission{'grp_manage'} = 1;
3941: }
3942: } elsif ($context eq 'author') {
3943: $permission{'cusr'} = &authorpriv($env{'user.name'},$env{'request.role.domain'});
3944: $permission{'view'} = $permission{'cusr'};
3945: } else {
3946: my @allroles = &roles_by_context($context);
3947: foreach my $role (@allroles) {
3948: if (&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) { $permission{'cusr'} = 1;
3949: last;
3950: }
3951: }
3952: if (!$permission{'cusr'}) {
3953: if (&Apache::lonnet::allowed('mau',$env{'request.role.domain'})) {
3954: $permission{'cusr'} = 1;
3955: }
3956: }
3957: if (&Apache::lonnet::allowed('ccr',$env{'request.role.domain'})) {
3958: $permission{'custom'} = 1;
3959: }
3960: $permission{'view'} = $permission{'cusr'};
3961: }
3962: my $allowed = 0;
3963: foreach my $perm (values(%permission)) {
3964: if ($perm) { $allowed=1; last; }
3965: }
3966: return (\%permission,$allowed);
3967: }
3968:
3969: # ==================================================== Figure out author access
3970:
3971: sub authorpriv {
3972: my ($auname,$audom)=@_;
3973: unless ((&Apache::lonnet::allowed('cca',$audom.'/'.$auname))
3974: || (&Apache::lonnet::allowed('caa',$audom.'/'.$auname))) { return ''; } return 1;
3975: }
3976:
3977: sub get_course_identity {
3978: my ($cid) = @_;
3979: my ($cnum,$cdom,$cdesc);
3980: if ($cid eq '') {
3981: $cid = $env{'request.course.id'}
3982: }
3983: if ($cid ne '') {
3984: $cnum = $env{'course.'.$cid.'.num'};
3985: $cdom = $env{'course.'.$cid.'.domain'};
3986: $cdesc = $env{'course.'.$cid.'.description'};
3987: if ($cnum eq '' || $cdom eq '') {
3988: my %coursehash =
3989: &Apache::lonnet::coursedescription($cid,{'one_time' => 1});
3990: $cdom = $coursehash{'domain'};
3991: $cnum = $coursehash{'num'};
3992: $cdesc = $coursehash{'description'};
3993: }
3994: }
3995: return ($cnum,$cdom,$cdesc);
3996: }
3997:
3998: sub dc_setcourse_js {
3999: my ($formname,$mode) = @_;
4000: my $dc_setcourse_code;
4001: my $cctext = &Apache::lonnet::plaintext('cc');
4002: my %alerts = §ioncheck_alerts();
4003: my $role = 'role';
4004: if ($mode eq 'upload') {
4005: $role = 'courserole';
4006: }
4007: $dc_setcourse_code = (<<"SCRIPTTOP");
4008: function setCourse() {
4009: var course = document.$formname.dccourse.value;
4010: if (course != "") {
4011: if (document.$formname.dcdomain.value != document.$formname.origdom.value) {
4012: alert("$alerts{'curd'}");
4013: return;
4014: }
4015: var userrole = document.$formname.$role.options[document.$formname.$role.selectedIndex].value
4016: var section="";
4017: var numsections = 0;
4018: var newsecs = new Array();
4019: for (var i=0; i<document.$formname.currsec.length; i++) {
4020: if (document.$formname.currsec.options[i].selected == true ) {
4021: if (document.$formname.currsec.options[i].value != "" && document.$formname.currsec.options[i].value != null) {
4022: if (numsections == 0) {
4023: section = document.$formname.currsec.options[i].value
4024: numsections = 1;
4025: }
4026: else {
4027: section = section + "," + document.$formname.currsec.options[i].value
4028: numsections ++;
4029: }
4030: }
4031: }
4032: }
4033: if (document.$formname.newsec.value != "" && document.$formname.newsec.value != null) {
4034: if (numsections == 0) {
4035: section = document.$formname.newsec.value
4036: }
4037: else {
4038: section = section + "," + document.$formname.newsec.value
4039: }
4040: newsecs = document.$formname.newsec.value.split(/,/g);
4041: numsections = numsections + newsecs.length;
4042: }
4043: if ((userrole == 'st') && (numsections > 1)) {
4044: alert("$alerts{'inea'}. $alerts{'youh'} "+numsections+" $alerts{'sect'}.\\n$alerts{'plsm'}.")
4045: return;
4046: }
4047: for (var j=0; j<newsecs.length; j++) {
4048: if ((newsecs[j] == 'all') || (newsecs[j] == 'none')) {
4049: alert("'"+newsecs[j]+"' $alerts{'mayn'}.\\n$alerts{'plsc'}.");
4050: return;
4051: }
4052: if (document.$formname.groups.value != '') {
4053: var groups = document.$formname.groups.value.split(/,/g);
4054: for (var k=0; k<groups.length; k++) {
4055: if (newsecs[j] == groups[k]) {
4056: alert("'"+newsecs[j]+"' $alerts{'mayt'}.\\n$alerts{'secn'}. $alerts{'plsc'}.");
4057: return;
4058: }
4059: }
4060: }
4061: }
4062: if ((userrole == 'cc') && (numsections > 0)) {
4063: alert("$alerts{'secd'} $cctext $alerts{'role'}.\\n$alerts{'accr'}.");
4064: section = "";
4065: }
4066: SCRIPTTOP
4067: if ($mode ne 'upload') {
4068: $dc_setcourse_code .= (<<"ENDSCRIPT");
4069: var coursename = "_$env{'request.role.domain'}"+"_"+course+"_"+userrole
4070: var numcourse = getIndex(document.$formname.dccourse);
4071: if (numcourse == "-1") {
4072: alert("$alerts{'thwa'}");
4073: return;
4074: }
4075: else {
4076: document.$formname.elements[numcourse].name = "act"+coursename;
4077: var numnewsec = getIndex(document.$formname.newsec);
4078: if (numnewsec != "-1") {
4079: document.$formname.elements[numnewsec].name = "sec"+coursename;
4080: document.$formname.elements[numnewsec].value = section;
4081: }
4082: var numstart = getIndex(document.$formname.start);
4083: if (numstart != "-1") {
4084: document.$formname.elements[numstart].name = "start"+coursename;
4085: }
4086: var numend = getIndex(document.$formname.end);
4087: if (numend != "-1") {
4088: document.$formname.elements[numend].name = "end"+coursename
4089: }
4090: }
4091: }
4092: document.$formname.submit();
4093: }
4094:
4095: ENDSCRIPT
4096: } else {
4097: $dc_setcourse_code .= "
4098: document.$formname.sections.value = section;
4099: }
4100: return 'ok';
4101: }
4102: ";
4103: }
4104: $dc_setcourse_code .= (<<"ENDSCRIPT");
4105:
4106: function getIndex(caller) {
4107: for (var i=0;i<document.$formname.elements.length;i++) {
4108: if (document.$formname.elements[i] == caller) {
4109: return i;
4110: }
4111: }
4112: return -1;
4113: }
4114: ENDSCRIPT
4115: }
4116:
4117: sub sectioncheck_alerts {
4118: my %alerts = &Apache::lonlocal::texthash(
4119: curd => 'You must select a course in the current domain',
4120: inea => 'In each course, each user may only have one student role at a time',
4121: youh => 'You had selected',
4122: sect => 'sections',
4123: plsm => 'Please modify your selections so they include no more than one section',
4124: mayn => 'may not be used as the name for a section, as it is a reserved word',
4125: plsc => 'Please choose a different section name',
4126: mayt => 'may not be used as the name for a section, as it is the name of a course group',
4127: secn => 'Section names and group names must be distinct',
4128: secd => 'Section designations do not apply to ',
4129: role => 'roles',
4130: accr => 'role will be added with access to all sections',
4131: thwa => 'There was a problem with your course selection'
4132: );
4133: return %alerts;
4134: }
4135:
4136:
4137: 1;
4138:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>