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