Annotation of loncom/interface/londropadd.pm, revision 1.16
1.1 www 1: # The LearningOnline Network with CAPA
2: # Handler to drop and add students in courses
3: #
4: # (Handler to set parameters for assessments
5: #
6: # (Handler to resolve ambiguous file locations
7: #
8: # (TeX Content Handler
9: #
1.14 harris41 10: # YEAR=2000
1.1 www 11: # 05/29/00,05/30,10/11 Gerd Kortemeyer)
12: #
13: # 10/11,10/12,10/16 Gerd Kortemeyer)
14: #
15: # 11/20,11/21,11/22,11/23,11/24,11/25,11/27,11/28,
16: # 12/08,12/12 Gerd Kortemeyer)
17: #
1.7 www 18: # 12/26,12/27,12/28,
1.14 harris41 19: # YEAR=2001
1.13 www 20: # 01/01/01,01/15,02/10,02/13,02/14,02/22 Gerd Kortemeyer
1.14 harris41 21: # 8/6 Scott Harrison
1.16 ! www 22: # Guy Albertelli
! 23: # 9/25 Gerd Kortemeyer
1.1 www 24:
25: package Apache::londropadd;
26:
27: use strict;
28: use Apache::lonnet;
29: use Apache::Constants qw(:common :http REDIRECT);
30:
1.10 www 31: # ================================================================ Print header
1.1 www 32:
1.10 www 33: sub header {
34: my $r=shift;
35: $r->print(<<ENDHEAD);
1.1 www 36: <html>
37: <head>
38: <title>LON-CAPA Student Drop/Add</title>
39: </head>
40: <body bgcolor="#FFFFFF">
41: <img align=right src=/adm/lonIcons/lonlogos.gif>
42: <h1>Drop/Add Students</h1>
43: <form method="post" enctype="multipart/form-data"
44: action="/adm/dropadd" name="studentform">
45: <h2>Course: $ENV{'course.'.$ENV{'request.course.id'}.'.description'}</h2>
46: ENDHEAD
1.10 www 47: }
48:
49: # ========================================================= Store uploaded file
50: # needs $ENV{'form.upfile'}
51: # return $datatoken to be put into hidden field
52:
53: sub upfile_store {
54: my $r=shift;
55: $ENV{'form.upfile'}=~s/\r/\n/gs;
56: $ENV{'form.upfile'}=~s/\f/\n/gs;
57: $ENV{'form.upfile'}=~s/\n+/\n/gs;
58: $ENV{'form.upfile'}=~s/\n+$//gs;
59:
60: my $datatoken=$ENV{'user.name'}.'_'.$ENV{'user.domain'}.
61: '_enroll_'.$ENV{'request.course.id'}.'_'.time.'_'.$$;
62: {
63: my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').
64: '/tmp/'.$datatoken.'.tmp');
65: print $fh $ENV{'form.upfile'};
66: }
67: return $datatoken;
68: }
69:
70: # ================================================= Load uploaded file from tmp
71: # needs $ENV{'form.datatoken'}
72: # sets $ENV{'form.upfile'}
73:
74: sub load_tmp_file {
75: my $r=shift;
76: my @studentdata=();
77: {
78: my $fh;
79: if ($fh=Apache::File->new($r->dir_config('lonDaemons').
80: '/tmp/'.$ENV{'form.datatoken'}.'.tmp')) {
81: @studentdata=<$fh>;
82: }
83: }
84: $ENV{'form.upfile'}=join('',@studentdata);
85: }
86:
87: # ========================================= Separate uploaded file into records
88: # returns array of records
89:
90: sub upfile_record_sep {
91: if ($ENV{'form.upfiletype'} eq 'xml') {
92: } else {
93: return split(/\n/,$ENV{'form.upfile'});
94: }
95: }
96:
97: # =============================================== Separate a record into fields
98:
99: sub record_sep {
100: my $record=shift;
101: my %components=();
102: if ($ENV{'form.upfiletype'} eq 'xml') {
103: } elsif ($ENV{'form.upfiletype'} eq 'space') {
104: my $i=0;
105: map {
106: my $field=$_;
107: $field=~s/^(\"|\')//;
108: $field=~s/(\"|\')$//;
109: $components{$i}=$field;
110: $i++;
111: } split(/\s+/,$record);
112: } elsif ($ENV{'form.upfiletype'} eq 'tab') {
113: my $i=0;
114: map {
115: my $field=$_;
116: $field=~s/^(\"|\')//;
117: $field=~s/(\"|\')$//;
118: $components{$i}=$field;
119: $i++;
120: } split(/\t+/,$record);
121: } else {
122: my @allfields=split(/\,/,$record);
123: my $i=0;
124: my $j;
125: for ($j=0;$j<=$#allfields;$j++) {
126: my $field=$allfields[$j];
127: if ($field=~/^\s*(\"|\')/) {
128: my $delimiter=$1;
129: while (($field!~/$delimiter$/) && ($j<$#allfields)) {
130: $j++;
131: $field.=','.$allfields[$j];
132: }
133: $field=~s/^\s*$delimiter//;
134: $field=~s/$delimiter\s*$//;
135: }
136: $components{$i}=$field;
137: $i++;
138: }
139: }
140: return %components;
141: }
142:
143: # =========== Drop student from all sections of a course, except optional $csec
144:
145: sub dropstudent {
146: my ($udom,$unam,$courseid,$csec)=@_;
147: $courseid=~s/\_/\//g;
148: $courseid=~s/^(\w)/\/$1/;
149: map {
150: my ($key,$value)=split(/\=/,$_);
151: $key=&Apache::lonnet::unescape($key);
152: if ($key=~/^$courseid(?:\/)*(\w+)*\_st$/) {
153: my $section=$1;
154: if ($key eq $courseid.'_st') { $section=''; }
1.16 ! www 155: if (((!$section) && (!$csec)) || ($section ne $csec)) {
1.10 www 156: my ($dummy,$end,$start)=split(/\_/,
157: &Apache::lonnet::unescape($value));
158: my $now=time;
159: my $notactive=0;
160: if ($start) {
161: if ($now<$start) { $notactive=1; }
162: }
163: if ($end) {
164: if ($now>$end) { $notactive=1; }
165: }
166: unless ($notactive) {
167: my $reply=&Apache::lonnet::modifystudent(
168: $udom,$unam,'','','',
169: '','','','',$section,time);
170: }
171: }
172: }
173: } split(/\&/,&Apache::lonnet::reply('dump:'.$udom.':'.$unam.':roles',
174: &Apache::lonnet::homeserver($unam,$udom)));
175: }
176:
177: # ============================================================== Menu Phase One
178:
179: sub menu_phase_one {
180: my $r=shift;
181: $r->print(<<ENDUPFORM);
1.2 www 182: <input type=hidden name=phase value=two>
183: <hr>
184: <h3>Upload a courselist</h3>
185: <input type=file name=upfile size=50>
186: <br>Type: <select name=upfiletype>
187: <option value=csv>CSV (comma separated values, spreadsheet)</option>
188: <option value=space>Space separated</option>
189: <option value=tab>Tabulator separated</option>
190: <option value=xml>HTML/XML</option>
191: </select>
192: <p><input type=submit name=fileupload value="Upload Courselist">
193: <hr>
194: <h3>Enroll a single student</h3>
195: <p><input type=submit name=enroll value="Enroll Student">
196: <hr>
1.11 www 197: <h3>Drop students</h3>
198: <p><input type=submit name=drop value="Selection List">
1.2 www 199: ENDUPFORM
1.10 www 200: }
201:
202: # ======================================================= Menu Phase Two Upload
203:
204: sub menu_phase_two_upload {
205: my $r=shift;
206:
207: my $datatoken=&upfile_store($r);
208:
209: my @records=&upfile_record_sep();
210: my $total=$#records;
211: my $distotal=$total+1;
212:
213: $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/;
214: my $krbdefdom=$1;
215: $krbdefdom=~tr/a-z/A-Z/;
216:
217: my $today=time;
218: my $halfyear=$today+15552000;
219:
220: my $defdom=$r->dir_config('lonDefDomain');
221:
222: $r->print(<<ENDPICK);
1.2 www 223: <input type=hidden name=phase value=three>
224: <input type=hidden name=datatoken value="$datatoken">
225: <input type=hidden name=upfiletype value=$ENV{'form.upfiletype'}>
226: <hr>
227: <h3>Identify fields</h3>
1.10 www 228: Total number of records found in file: $distotal
1.3 www 229: <script>
230: function verify(vf) {
231: var founduname=0;
232: var foundpwd=0;
233: var foundname=0;
234: var foundid=0;
235: var foundsec=0;
236: var foundatype=0;
237: var tw;
238: var message='';
239: for (i=0;i<=vf.nfields.value;i++) {
240: tw=eval('vf.f'+i+'.selectedIndex');
241: if (tw==1) { founduname=1; }
242: if ((tw>=2) && (tw<=6)) { foundname=1; }
243: if (tw==7) { foundid=1; }
244: if (tw==8) { foundsec=1; }
245: if (tw==9) { foundpwd=1; }
246: }
247: if (founduname==0) {
248: alert('You need to specify at least the username field');
249: return;
250: }
251: if (vf.login[0].checked) {
252: foundatype=1;
253: if (vf.krbdom.value=='') {
254: alert('You need to specify the Kerberos domain');
255: return;
256: }
257: }
258: if (vf.login[1].checked) {
259: foundatype=1;
260: if ((vf.intpwd.value=='') && (foundpwd==0)) {
261: alert('You need to specify the initial password');
262: return;
263: }
264: }
1.15 albertel 265: if (vf.login[2].checked) {
266: foundatype=1;
267: //An argument is not required
268: }
1.3 www 269: if (foundatype==0) {
270: alert('You need to set the login type');
271: return;
272: }
273: if (foundname==0) { message='No name fields specified. '; }
274: if (foundid==0) { message+='No ID or student number field specified. '; }
275: if (foundsec==0) { message+='No section or group field specified. '; }
1.4 www 276: if (vf.startdate.value=='') {
277: message+='No starting date set. ';
1.3 www 278: }
1.4 www 279: if (vf.enddate.value=='') {
280: message+='No ending date set. ';
281: }
282: if ((vf.enddate.value!='') && (vf.startdate.value!='')) {
1.10 www 283: if (Math.round(vf.enddate.value)<Math.round(vf.startdate.value)) {
1.4 www 284: alert('Ending date is before starting date');
285: return;
286: }
287: }
288: if (message!='') {
289: message+='Continue enrollment?';
290: if (confirm(message)) {
291: pclose();
292: vf.submit();
293: }
294: } else {
295: pclose();
296: vf.submit();
297: }
1.3 www 298: }
299:
300: function flip(vf,tf) {
301: var nw=eval('vf.f'+tf+'.selectedIndex');
302: var i;
303: for (i=0;i<=vf.nfields.value;i++) {
304: if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {
305: eval('vf.f'+i+'.selectedIndex=0;')
306: }
307: }
308: if (nw==2) {
309: for (i=0;i<=vf.nfields.value;i++) {
310: if ((eval('vf.f'+i+'.selectedIndex')>=3) &&
311: (eval('vf.f'+i+'.selectedIndex')<=6)) {
312: eval('vf.f'+i+'.selectedIndex=0;')
313: }
314: }
315: }
316: if ((nw>=3) && (nw<=6)) {
317: for (i=0;i<=vf.nfields.value;i++) {
318: if (eval('vf.f'+i+'.selectedIndex')==2) {
319: eval('vf.f'+i+'.selectedIndex=0;')
320: }
321: }
322: }
323: if (nw==9) {
324: vf.login[1].checked=true;
325: vf.intpwd.value='';
326: vf.krbdom.value='';
1.15 albertel 327: vf.locarg.value='';
1.3 www 328: }
329:
330: }
331:
332: function clearpwd(vf) {
333: var i;
334: for (i=0;i<=vf.nfields.value;i++) {
335: if (eval('vf.f'+i+'.selectedIndex')==9) {
336: eval('vf.f'+i+'.selectedIndex=0;')
337: }
338: }
339: }
340:
341: function setkrb(vf) {
342: if (vf.krbdom.value!='') {
343: clearpwd(vf);
344: vf.login[0].checked=true;
345: vf.krbdom.value=vf.krbdom.value.toUpperCase();
346: vf.intpwd.value='';
347: }
348: }
349:
350: function setint(vf) {
351: if (vf.intpwd.value!='') {
352: clearpwd(vf);
353: vf.login[1].checked=true;
354: vf.krbdom.value='';
355: }
356: }
357:
358: function clickkrb(vf) {
359: vf.krbdom.value='$krbdefdom';
360: clearpwd(vf);
361: vf.intpwd.value='';
362: }
363:
364: function clickint(vf) {
365: vf.krbdom.value='';
366: }
367:
1.4 www 368: function pclose() {
369: parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
370: "height=350,width=350,scrollbars=no,menubar=no");
371: parmwin.close();
372: }
373:
374: function pjump(type,dis,value,marker,ret,call) {
375: parmwin=window.open("/adm/rat/parameter.html?type="+escape(type)
376: +"&value="+escape(value)+"&marker="+escape(marker)
377: +"&return="+escape(ret)
378: +"&call="+escape(call)+"&name="+escape(dis),"LONCAPAparms",
379: "height=350,width=350,scrollbars=no,menubar=no");
380:
381: }
382:
383: function dateset() {
384: if (document.studentform.pres_marker.value=='end') {
385: document.studentform.enddate.value=
386: document.studentform.pres_value.value;
387: }
388: if (document.studentform.pres_marker.value=='start') {
389: document.studentform.startdate.value=
390: document.studentform.pres_value.value;
391: }
392: pclose();
393: }
1.3 www 394:
395: </script>
1.2 www 396: <table border=2><tr><th>Field</th><th>Samples</th></tr>
397: ENDPICK
1.10 www 398: my %sone; my %stwo; my %sthree;
399: my $i=0;
400:
401: if ($total>=0) {
402: %sone=&record_sep($records[0]);
403: if ($total>=1) {
404: %stwo=&record_sep($records[1]);
405:
1.2 www 406: }
1.10 www 407: if ($total>=2) {
408: %sthree=&record_sep($records[2]);
1.2 www 409: }
1.10 www 410: map {
1.3 www 411: $r->print('<tr><td><select name=f'.$i.
412: ' onChange="flip(this.form,'.$i.');">');
1.2 www 413: map {
414: my ($value,$display)=split(/\:/,$_);
415: $r->print('<option value='.$value.'>'.$display.
416: '</option>');
417: } ('none: ','username:Username',
418: 'names:Last Name, First Names',
419: 'fname:First Name','mname:Middle Names/Initials',
420: 'lname:Last Name','gen:Generation',
1.3 www 421: 'id:ID/Student Number','sec:Group/Section',
422: 'ipwd:Initial Password');
1.2 www 423: $r->print('</select></td><td>');
1.13 www 424: if (defined($sone{$_})) {
425: $r->print($sone{$_}."</br>\n");
1.2 www 426: }
1.13 www 427: if (defined($stwo{$_})) {
428: $r->print($stwo{$_}."</br>\n");
1.2 www 429: }
1.13 www 430: if (defined($sthree{$_})) {
431: $r->print($sthree{$_}."</br>\n");
1.2 www 432: }
433: $r->print('</td></tr>');
1.10 www 434: $i++;
435: } sort keys %sone;
436: $i--;
1.2 www 437: }
1.10 www 438: my $keyfields=join(',',sort keys %sone);
1.3 www 439: $r->print(<<ENDPICK);
440: </table>
1.10 www 441: <input type=hidden name=nfields value=$i>
442: <input type=hidden name=keyfields value="$keyfields">
1.3 www 443: <h3>Login Type</h3>
1.15 albertel 444: <p>Note: this will not take effect if the user already exists</p>
445: <p>
446: <input type=radio name=login value=krb onClick="clickkrb(this.form);" />
1.3 www 447: Kerberos authenticated with domain
1.15 albertel 448: <input type=text size=10 name=krbdom onChange="setkrb(this.form);" />
449: </p>
450: <p>
451: <input type=radio name=login value=int onClick="clickint(this.form);" />
1.3 www 452: Internally authenticated (with initial password
1.15 albertel 453: <input type=text size=10 name=intpwd onChange="setint(this.form);" />)
454: </p>
455: <p>
456: <input type=radio name=login value=loc onClick="clickloc(this.form);" />
457: Local Authentication with argument
458: <input type=text size=10 name=locarg onChange="setloc(this.form);" />
459: </p>
1.5 www 460: <h3>LON-CAPA Domain for Students</h3>
1.4 www 461: LON-CAPA domain: <input type=text size=10 value=$defdom name=lcdomain><p>
1.5 www 462: <h3>Starting and Ending Dates</h3>
1.4 www 463: <input type="hidden" value='' name="pres_value">
464: <input type="hidden" value='' name="pres_type">
465: <input type="hidden" value='' name="pres_marker">
466: <input type="hidden" value='$today' name=startdate>
467: <input type="hidden" value='$halfyear' name=enddate>
468: <a
469: href="javascript:pjump('date_start','Enrollment Starting Date',document.studentform.startdate.value,'start','studentform.pres','dateset');"
470: >Set Starting Date</a><p>
471:
472: <a
473: href="javascript:pjump('date_end','Enrollment Ending Date',document.studentform.enddate.value,'end','studentform.pres','dateset');"
474: >Set Ending Date</a><p>
1.5 www 475: <h3>Full Update</h3>
476: <input type=checkbox name=fullup value=yes> Full update
1.11 www 477: (also print list of users not enrolled anymore)<p>
1.6 www 478: <input type=button onClick="verify(this.form)" value="Update Courselist"><br>
479: Note: for large courses, this operation might be time consuming.
1.3 www 480: ENDPICK
1.10 www 481: }
482:
1.12 www 483: # ======================================================= Enroll single student
484:
485: sub enroll_single_student {
486: my $r=shift;
487: $r->print('<h3>Enrolling Student</h3>');
488: if (($ENV{'form.cuname'})&&($ENV{'form.cuname'}!~/\W/)&&
489: ($ENV{'form.cdomain'})&&($ENV{'form.cdomain'}!~/\W/)) {
490: my $amode='';
491: my $genpwd='';
492: if ($ENV{'form.login'} eq 'krb') {
493: $amode='krb4';
494: $genpwd=$ENV{'form.krbdom'};
495: } elsif ($ENV{'form.login'} eq 'int') {
496: $amode='internal';
497: $genpwd=$ENV{'form.intpwd'};
1.15 albertel 498: } elsif ($ENV{'form.login'} eq 'loc') {
499: $amode='localauth';
500: $genpwd=$ENV{'form.locarg'};
501: if (!$genpwd) { $genpwd=" "; }
502: }
1.12 www 503: if (($amode) && ($genpwd)) {
504: &dropstudent($ENV{'form.cdomain'},$ENV{'form.cuname'},
505: $ENV{'request.course.id'},$ENV{'form.csec'});
506: $r->print(&Apache::lonnet::modifystudent(
507: $ENV{'form.cdomain'},$ENV{'form.cuname'},
508: $ENV{'form.cstid'},$amode,$genpwd,
509: $ENV{'form.cfirst'},$ENV{'form.cmiddle'},
510: $ENV{'form.clast'},$ENV{'form.cgen'},
511: $ENV{'form.csec'},$ENV{'form.enddate'},
512: $ENV{'form.startdate'}));
513: } else {
514: $r->print('Invalid login mode or password');
515: }
516: } else {
517: $r->print('Invalid username or domain');
518: }
519: }
520:
1.10 www 521: # ======================================================= Menu Phase Two Enroll
522:
523: sub menu_phase_two_enroll {
524: my $r=shift;
1.11 www 525:
526: $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/;
527: my $krbdefdom=$1;
528: $krbdefdom=~tr/a-z/A-Z/;
529:
530: my $today=time;
531: my $halfyear=$today+15552000;
532:
533: my $defdom=$r->dir_config('lonDefDomain');
534:
535: $r->print(<<ENDSENROLL);
1.12 www 536: <script>
537: function verify(vf) {
538: var founduname=0;
539: var foundpwd=0;
540: var foundname=0;
541: var foundid=0;
542: var foundsec=0;
543: var foundatype=0;
544: var tw;
545: var message='';
1.14 harris41 546: if ((typeof(vf.cuname.value)!="undefined") && (vf.cuname.value!='') &&
547: (typeof(vf.cdomain.value)!="undefined") && (vf.cdomain.value!='')) {
1.12 www 548: founduname=1;
549: }
1.14 harris41 550: if ((typeof(vf.cfirst.value)!="undefined") && (vf.cfirst.value!='') &&
551: (typeof(vf.clast.value)!="undefined") && (vf.clast.value!='')) {
1.12 www 552: foundname=1;
553: }
1.14 harris41 554: if ((typeof(vf.csec.value)!="undefined") && (vf.csec.value!='')) {
1.12 www 555: foundsec=1;
556: }
1.14 harris41 557: if ((typeof(vf.cstid.value)!="undefined") && (vf.cstid.value!='')) {
1.12 www 558: foundid=1;
559: }
560: if (founduname==0) {
561: alert('You need to specify at least the username and domain fields');
562: return;
563: }
564: if (vf.login[0].checked) {
565: foundatype=1;
566: if (vf.krbdom.value=='') {
567: alert('You need to specify the Kerberos domain');
568: return;
569: }
570: }
571: if (vf.login[1].checked) {
572: foundatype=1;
573: if ((vf.intpwd.value=='') && (foundpwd==0)) {
574: alert('You need to specify the initial password');
575: return;
576: }
577: }
1.15 albertel 578: if (vf.login[2].checked) {
579: foundatype=1;
580: //An argument is not required
581: }
1.12 www 582: if (foundatype==0) {
583: alert('You need to set the login type');
584: return;
585: }
586: if (foundname==0) { message='No first and last name specified. '; }
587: if (foundid==0) { message+='No ID or student number field specified. '; }
588: if (foundsec==0) { message+='No section or group field specified. '; }
589: if (vf.startdate.value=='') {
590: message+='No starting date set. ';
591: }
592: if (vf.enddate.value=='') {
593: message+='No ending date set. ';
594: }
595: if ((vf.enddate.value!='') && (vf.startdate.value!='')) {
596: if (Math.round(vf.enddate.value)<Math.round(vf.startdate.value)) {
597: alert('Ending date is before starting date');
598: return;
599: }
600: }
601: if (message!='') {
602: message+='Continue enrollment?';
603: if (confirm(message)) {
604: pclose();
605: vf.submit();
606: }
607: } else {
608: pclose();
609: vf.submit();
610: }
611: }
612:
613: function setkrb(vf) {
614: if (vf.krbdom.value!='') {
615: vf.login[0].checked=true;
616: vf.krbdom.value=vf.krbdom.value.toUpperCase();
617: vf.intpwd.value='';
1.15 albertel 618: vf.locarg.value='';
1.12 www 619: }
620: }
621:
622: function setint(vf) {
623: if (vf.intpwd.value!='') {
624: vf.login[1].checked=true;
625: vf.krbdom.value='';
1.15 albertel 626: vf.locarg.value='';
627: }
628: }
629:
630: function setloc(vf) {
631: if (vf.locarg.value!='') {
632: vf.login[2].checked=true;
633: vf.krbdom.value='';
634: vf.intpwd.value='';
1.12 www 635: }
636: }
637:
638: function clickkrb(vf) {
639: vf.krbdom.value='$krbdefdom';
640: vf.intpwd.value='';
1.15 albertel 641: vf.locarg.value='';
1.12 www 642: }
643:
644: function clickint(vf) {
645: vf.krbdom.value='';
1.15 albertel 646: vf.locarg.value='';
647: }
648:
649: function clickloc(vf) {
650: vf.krbdom.value='';
651: vf.intpwd.value='';
1.12 www 652: }
653:
654: function pclose() {
655: parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
656: "height=350,width=350,scrollbars=no,menubar=no");
657: parmwin.close();
658: }
659:
660: function pjump(type,dis,value,marker,ret,call) {
661: parmwin=window.open("/adm/rat/parameter.html?type="+escape(type)
662: +"&value="+escape(value)+"&marker="+escape(marker)
663: +"&return="+escape(ret)
664: +"&call="+escape(call)+"&name="+escape(dis),"LONCAPAparms",
665: "height=350,width=350,scrollbars=no,menubar=no");
666:
667: }
668:
669: function dateset() {
670: if (document.studentform.pres_marker.value=='end') {
671: document.studentform.enddate.value=
672: document.studentform.pres_value.value;
673: }
674: if (document.studentform.pres_marker.value=='start') {
675: document.studentform.startdate.value=
676: document.studentform.pres_value.value;
677: }
678: pclose();
679: }
680:
681: </script>
1.11 www 682: <h3>Personal Data</h3>
683: First Name: <input type=text name=cfirst size=15><br>
684: Middle Name: <input type=text name=cmiddle size=15><br>
685: Last Name: <input type=text name=clast size=15><br>
686: Generation: <input type=text name=cgen size=5><p>
687:
688: ID/Student Number: <input type=text name=cstid size=10><p>
689:
690: Group/Section: <input type=text name=csec size=5><p>
691:
1.12 www 692: <h3>Login Data</h3>
693: Username: <input type=text name=cuname size=15><p>
694: Domain: <input type=text size=10 value=$defdom name=cdomain><p>
695: Note: login settings below will not take effect if the user already exists<p>
1.11 www 696:
697: <input type=radio name=login value=krb onClick="clickkrb(this.form);">
698: Kerberos authenticated with domain
699: <input type=text size=10 name=krbdom onChange="setkrb(this.form);"><p>
700: <input type=radio name=login value=int onClick="clickint(this.form);">
701: Internally authenticated (with initial password
702: <input type=text size=10 name=intpwd onChange="setint(this.form);">)
1.15 albertel 703: <p>
704: <input type=radio name=login value=loc onClick="clickloc(this.form);" />
705: Local Authentication with argument
706: <input type=text size=10 name=locarg onChange="setloc(this.form);" />
707: </p>
1.11 www 708: <h3>Starting and Ending Dates</h3>
709: <input type="hidden" value='' name="pres_value">
710: <input type="hidden" value='' name="pres_type">
711: <input type="hidden" value='' name="pres_marker">
712: <input type="hidden" value='$today' name=startdate>
713: <input type="hidden" value='$halfyear' name=enddate>
714: <a
715: href="javascript:pjump('date_start','Enrollment Starting Date',document.studentform.startdate.value,'start','studentform.pres','dateset');"
716: >Set Starting Date</a><p>
717:
718: <a
719: href="javascript:pjump('date_end','Enrollment Ending Date',document.studentform.enddate.value,'end','studentform.pres','dateset');"
720: >Set Ending Date</a><p>
1.12 www 721: <input type=button onClick="verify(this.form)" value="Enroll as student"><br>
722: <input type=hidden name=phase value=five>
1.11 www 723: ENDSENROLL
1.10 www 724: }
725:
726: # ========================================================= Menu Phase Two Drop
727:
728: sub menu_phase_two_drop {
729: my $r=shift;
1.11 www 730: my $cid=$ENV{'request.course.id'};
731: my $classlst=&Apache::lonnet::reply
732: ('dump:'.$ENV{'course.'.$cid.'.domain'}.':'.
733: $ENV{'course.'.$cid.'.num'}.':classlist',
734: $ENV{'course.'.$cid.'.home'});
735: my %currentlist=();
736: my $now=time;
737: unless ($classlst=~/^error\:/) {
738: map {
739: my ($name,$value)=split(/\=/,$_);
740: my ($end,$start)=split(/\:/,
741: &Apache::lonnet::unescape($value));
742: my $active=1;
743: if (($end) && ($now>$end)) { $active=0; }
744: if ($active) {
745: $currentlist{&Apache::lonnet::unescape($name)}=1;
746: }
747: } split(/\&/,$classlst);
748: # ----------------------------------------------------------- Print out choices
749: &show_drop_list($r,%currentlist);
750: } else {
751: $r->print(
752: '<font color=red><h3>Could not access classlist: '.$classlst.
753: '</h3></font>');
754: }
755: }
756:
757: # =================================================== Show student list to drop
758:
759: sub show_drop_list {
760: my ($r,%currentlist)=@_;
761: my $cid=$ENV{'request.course.id'};
762:
763: $r->print('<input type=hidden name=phase value=four>');
764: $r->print('<table border=2>');
765: map {
766: my ($sname,$sdom)=split(/\:/,$_);
767: my %reply=&Apache::lonnet::idrget($sdom,$sname);
768: my $ssec=&Apache::lonnet::usection($sdom,$sname,$cid);
769: my @reply=split(/[\&\=]/,&Apache::lonnet::reply(
770: 'get:'.$sdom.':'.$sname.
771: ':environment:firstname&middlename&lastname&generation',
772: &Apache::lonnet::homeserver($sname,$sdom)));
773: $r->print(
774: '<tr><td><input type=checkbox name="drop:'.$_.'"></td><td>'.
775: $sname.'</td><td>'.$sdom.'</td><td>'.
776: $reply{$sname}.'</td><td>'.
777: &Apache::lonnet::unescape($reply[2]).' '.
778: &Apache::lonnet::unescape($reply[3]).', '.
779: &Apache::lonnet::unescape($reply[0]).' '.
780: &Apache::lonnet::unescape($reply[1]).
781: '</td><td>'.
782: $ssec."</td></tr>\n");
783: } sort keys %currentlist;
784: $r->print('</table><br>');
785: $r->print('<input type=submit value="Drop Students">');
1.10 www 786: }
787:
788: # ================================================= Drop/Add from uploaded file
789:
790: sub upfile_drop_add {
791: my $r=shift;
792:
793: &load_tmp_file($r);
794: my @studentdata=&upfile_record_sep();
795:
796: my @keyfields=split(/\,/,$ENV{'form.keyfields'});
797: my $cid=$ENV{'request.course.id'};
798:
1.4 www 799: my %fields=();
800: for (my $i=0;$i<=$ENV{'form.nfields'};$i++) {
1.10 www 801: $fields{$ENV{'form.f'.$i}}=$keyfields[$i];
1.4 www 802: }
803: my $startdate=$ENV{'form.startdate'};
804: my $enddate=$ENV{'form.enddate'};
805: if ($startdate=~/\D/) { $startdate=''; }
806: if ($enddate=~/\D/) { $enddate=''; }
1.5 www 807: my $domain=$ENV{'form.lcdomain'};
808: my $amode='';
809: my $genpwd='';
810: if ($ENV{'form.login'} eq 'krb') {
811: $amode='krb4';
812: $genpwd=$ENV{'form.krbdom'};
813: } elsif ($ENV{'form.login'} eq 'int') {
814: $amode='internal';
815: if ((defined($ENV{'form.intpwd'})) && ($ENV{'form.intpwd'})) {
816: $genpwd=$ENV{'form.intpwd'};
817: }
1.15 albertel 818: } elsif ($ENV{'form.login'} eq 'loc') {
819: $amode='localauth';
820: if ((defined($ENV{'form.locarg'})) && ($ENV{'form.locarg'})) {
821: $genpwd=$ENV{'form.locarg'};
822: }
823: }
1.5 www 824: unless (($domain=~/\W/) || ($amode eq '')) {
825: $r->print('<h3>Enrolling Students</h3>');
1.7 www 826: my $count=0;
827: my $flushc=0;
828: my %student=();
1.5 www 829: # ----------------------------------------------------------- Get new classlist
830: # --------------------------------------------------------- Enroll new students
1.2 www 831: map {
1.10 www 832: my %entries=&record_sep($_);
833:
834: unless (($entries{$fields{'username'}} eq '') ||
835: (!defined($entries{$fields{'username'}}))) {
1.4 www 836: my $fname=''; my $mname=''; my $lname=''; my $gen='';
837: if (defined($fields{'names'})) {
838: ($lname,$fname,$mname)=
1.10 www 839: ($entries{$fields{'names'}}=~/([^\,]+)\,\s*(\w+)\s*(.*)$/);
1.4 www 840: } else {
841: if (defined($fields{'fname'})) {
1.10 www 842: $fname=$entries{$fields{'fname'}};
1.4 www 843: }
844: if (defined($fields{'mname'})) {
1.10 www 845: $mname=$entries{$fields{'mname'}};
1.4 www 846: }
847: if (defined($fields{'lname'})) {
1.10 www 848: $lname=$entries{$fields{'lname'}};
1.4 www 849: }
850: if (defined($fields{'gen'})) {
1.10 www 851: $gen=$entries{$fields{'gen'}};
1.4 www 852: }
853: }
1.10 www 854: if ($entries{$fields{'username'}}=~/\W/) {
1.4 www 855: $r->print('<p><b>Unacceptable username: '.
1.10 www 856: $entries{$fields{'username'}}.' for user '.
1.4 www 857: $fname.' '.$mname.' '.$lname.' '.$gen.'</b><p>');
1.5 www 858: } else {
859: my $sec='';
1.10 www 860: my $username=$entries{$fields{'username'}};
1.5 www 861: if (defined($fields{'sec'})) {
1.10 www 862: if (defined($entries{$fields{'sec'}})) {
863: $sec=$entries{$fields{'sec'}};
1.5 www 864: }
865: }
866: my $id='';
867: if (defined($fields{'id'})) {
1.10 www 868: if (defined($entries{$fields{'id'}})) {
869: $id=$entries{$fields{'id'}};
1.5 www 870: }
871: $id=~tr/A-Z/a-z/;
872: }
873: my $password='';
874: if ($genpwd) {
875: $password=$genpwd;
876: } else {
877: if (defined($fields{'ipwd'})) {
1.10 www 878: if ($entries{$fields{'ipwd'}}) {
879: $password=$entries{$fields{'ipwd'}};
1.5 www 880: }
881: }
882: }
1.10 www 883: if ($password) {
884: &dropstudent($domain,$username,$cid,$sec);
1.5 www 885: my $reply=&Apache::lonnet::modifystudent(
886: $domain,$username,$id,$amode,$password,
887: $fname,$mname,$lname,$gen,$sec,$enddate,$startdate);
888: unless ($reply eq 'ok') {
889: $r->print(
890: "<p><b>Error enrolling $username: $reply</b><p>");
1.10 www 891: } else {
1.7 www 892: $count++; $flushc++;
893: $student{$username}=1;
1.6 www 894: $r->print('. ');
1.7 www 895: if ($flushc>15) {
896: $r->rflush;
897: $flushc=0;
898: }
1.6 www 899: }
1.5 www 900: } else {
901: $r->print(
902: "<p><b>No password for $username</b><p>");
903: }
1.4 www 904: }
905: }
906: } @studentdata;
1.7 www 907: $r->print('<p>Processed Students: '.$count);
1.5 www 908: # --------------------------------------------------------------- Drop students
909: if ($ENV{'form.fullup'} eq 'yes') {
910: $r->print('<h3>Dropping Students</h3>');
911: # ------------------------------------------------------- Get current classlist
912: my $classlst=&Apache::lonnet::reply
913: ('dump:'.$ENV{'course.'.$cid.'.domain'}.':'.
914: $ENV{'course.'.$cid.'.num'}.':classlist',
915: $ENV{'course.'.$cid.'.home'});
916: my %currentlist=();
917: my $now=time;
918: unless ($classlst=~/^error\:/) {
1.7 www 919: map {
920: my ($name,$value)=split(/\=/,$_);
1.8 www 921: my ($end,$start)=split(/\:/,
1.7 www 922: &Apache::lonnet::unescape($value));
923: my $active=1;
924: if (($end) && ($now>$end)) { $active=0; }
925: if ($active) {
926: $currentlist{&Apache::lonnet::unescape($name)}=1;
927: }
928: } split(/\&/,$classlst);
1.10 www 929: # ------------------------------------------------ Now got up-to-date classlist
930: map {
931: my %entries=&record_sep($_);
932: unless (($entries{$fields{'username'}} eq '') ||
933: (!defined($entries{$fields{'username'}}))) {
934: delete($currentlist{
935: $entries{$fields{'username'}}.':'.
936: $domain});
937: }
938: } @studentdata;
939: # ----------------------------------------------------------- Print out choices
1.11 www 940: &show_drop_list($r,%currentlist);
1.5 www 941: } else {
942: $r->print(
943: '<font color=red><h3>Could not access classlist: '.$classlst.
944: '</h3></font>');
945: }
946: }
947: # ------------------------------------------------------------------------ Done
1.10 www 948:
949: }
950: }
951:
1.11 www 952: # ================================================================== Phase four
953:
954: sub drop_student_list {
955: my $r=shift;
956: my $count=0;
957: map {
958: if ($_=~/^form\.drop\:/) {
959: my ($dummy,$uname,$udom)=split(/\:/,$_);
960: &dropstudent($udom,$uname,$ENV{'request.course.id'});
961: $r->print('Dropped '.$uname.' at '.$udom.'<br>');
962: $count++;
963: }
964: } keys %ENV;
965: $r->print('<p><b>Dropped '.$count.' student(s).</b>');
966: $r->print('<p>Re-enrollment will re-activate data.');
967: }
968:
1.10 www 969: # ================================================================ Main Handler
970:
971: sub handler {
972: my $r=shift;
973:
974: if ($r->header_only) {
975: $r->content_type('text/html');
976: $r->send_http_header;
977: return OK;
978: }
979:
980: # ----------------------------------------------------- Needs to be in a course
981:
982: if (($ENV{'request.course.fn'}) &&
983: (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'}))) {
984:
985: # ------------------------------------------------------------------ Start page
986: $r->content_type('text/html');
987: $r->send_http_header;
988: &header($r);
989:
990: # --------------------------------------------------- Phase one, initial screen
991: unless ($ENV{'form.phase'}) {
992: &menu_phase_one($r);
993: }
994: # ------------------------------------------------------------------- Phase two
995: if ($ENV{'form.phase'} eq 'two') {
996: if ($ENV{'form.fileupload'}) {
997: &menu_phase_two_upload($r);
998: } elsif ($ENV{'form.enroll'}) {
999: &menu_phase_two_enroll($r);
1000: } elsif ($ENV{'form.drop'}) {
1001: &menu_phase_two_drop($r);
1002: }
1003: }
1004:
1005:
1006:
1007:
1008: # ----------------------------------------------------------------- Phase three
1009: if ($ENV{'form.phase'} eq 'three') {
1010: if ($ENV{'form.datatoken'}) {
1011: &upfile_drop_add($r);
1.2 www 1012: }
1.11 www 1013: }
1014: # ------------------------------------------------------------------ Phase four
1015: if ($ENV{'form.phase'} eq 'four') {
1016: &drop_student_list($r);
1.12 www 1017: }
1018: # ------------------------------------------------------------------ Phase four
1019: if ($ENV{'form.phase'} eq 'five') {
1020: &enroll_single_student($r);
1.2 www 1021: }
1022: # ------------------------------------------------------------------------- End
1.1 www 1023: $r->print('</form></body></html>');
1024: } else {
1025: # ----------------------------- Not in a course, or not allowed to modify parms
1026: $ENV{'user.error.msg'}=
1027: "/adm/dropadd:cst:0:0:Cannot drop or add students";
1028: return HTTP_NOT_ACCEPTABLE;
1029: }
1030: return OK;
1031: }
1032:
1033: 1;
1034: __END__
1035:
1036:
1037:
1038:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>