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