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