Annotation of loncom/interface/londropadd.pm, revision 1.22
1.1 www 1: # The LearningOnline Network with CAPA
2: # Handler to drop and add students in courses
3: #
1.22 ! albertel 4: # $Id: londropadd.pm,v 1.21 2002/04/03 16:45:25 matthew 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.21 matthew 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.22 ! albertel 256: Total number of records found in file: $distotal <hr />
! 257: Enter as many fields as you can. The system will inform you and bring you back
! 258: to this page if the data selected is insufficient to run your class.<hr />
1.3 www 259: <script>
260: function verify(vf) {
261: var founduname=0;
262: var foundpwd=0;
263: var foundname=0;
264: var foundid=0;
265: var foundsec=0;
266: var foundatype=0;
267: var tw;
268: var message='';
269: for (i=0;i<=vf.nfields.value;i++) {
270: tw=eval('vf.f'+i+'.selectedIndex');
271: if (tw==1) { founduname=1; }
272: if ((tw>=2) && (tw<=6)) { foundname=1; }
273: if (tw==7) { foundid=1; }
274: if (tw==8) { foundsec=1; }
275: if (tw==9) { foundpwd=1; }
276: }
277: if (founduname==0) {
278: alert('You need to specify at least the username field');
279: return;
280: }
281: if (vf.login[0].checked) {
282: foundatype=1;
283: if (vf.krbdom.value=='') {
284: alert('You need to specify the Kerberos domain');
285: return;
286: }
287: }
288: if (vf.login[1].checked) {
289: foundatype=1;
290: if ((vf.intpwd.value=='') && (foundpwd==0)) {
291: alert('You need to specify the initial password');
292: return;
293: }
294: }
1.15 albertel 295: if (vf.login[2].checked) {
296: foundatype=1;
297: //An argument is not required
298: }
1.3 www 299: if (foundatype==0) {
300: alert('You need to set the login type');
301: return;
302: }
303: if (foundname==0) { message='No name fields specified. '; }
304: if (foundid==0) { message+='No ID or student number field specified. '; }
305: if (foundsec==0) { message+='No section or group field specified. '; }
1.4 www 306: if (vf.startdate.value=='') {
307: message+='No starting date set. ';
1.3 www 308: }
1.4 www 309: if (vf.enddate.value=='') {
310: message+='No ending date set. ';
311: }
312: if ((vf.enddate.value!='') && (vf.startdate.value!='')) {
1.10 www 313: if (Math.round(vf.enddate.value)<Math.round(vf.startdate.value)) {
1.4 www 314: alert('Ending date is before starting date');
315: return;
316: }
317: }
318: if (message!='') {
319: message+='Continue enrollment?';
320: if (confirm(message)) {
321: pclose();
322: vf.submit();
323: }
324: } else {
325: pclose();
326: vf.submit();
327: }
1.3 www 328: }
329:
330: function flip(vf,tf) {
331: var nw=eval('vf.f'+tf+'.selectedIndex');
332: var i;
333: for (i=0;i<=vf.nfields.value;i++) {
334: if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {
335: eval('vf.f'+i+'.selectedIndex=0;')
336: }
337: }
338: if (nw==2) {
339: for (i=0;i<=vf.nfields.value;i++) {
340: if ((eval('vf.f'+i+'.selectedIndex')>=3) &&
341: (eval('vf.f'+i+'.selectedIndex')<=6)) {
342: eval('vf.f'+i+'.selectedIndex=0;')
343: }
344: }
345: }
346: if ((nw>=3) && (nw<=6)) {
347: for (i=0;i<=vf.nfields.value;i++) {
348: if (eval('vf.f'+i+'.selectedIndex')==2) {
349: eval('vf.f'+i+'.selectedIndex=0;')
350: }
351: }
352: }
353: if (nw==9) {
354: vf.login[1].checked=true;
355: vf.intpwd.value='';
356: vf.krbdom.value='';
1.15 albertel 357: vf.locarg.value='';
1.3 www 358: }
359:
360: }
361:
362: function clearpwd(vf) {
363: var i;
364: for (i=0;i<=vf.nfields.value;i++) {
365: if (eval('vf.f'+i+'.selectedIndex')==9) {
366: eval('vf.f'+i+'.selectedIndex=0;')
367: }
368: }
369: }
370:
371: function setkrb(vf) {
372: if (vf.krbdom.value!='') {
373: clearpwd(vf);
374: vf.login[0].checked=true;
375: vf.krbdom.value=vf.krbdom.value.toUpperCase();
376: vf.intpwd.value='';
377: }
378: }
379:
380: function setint(vf) {
381: if (vf.intpwd.value!='') {
382: clearpwd(vf);
383: vf.login[1].checked=true;
384: vf.krbdom.value='';
385: }
386: }
387:
388: function clickkrb(vf) {
389: vf.krbdom.value='$krbdefdom';
390: clearpwd(vf);
391: vf.intpwd.value='';
392: }
393:
394: function clickint(vf) {
395: vf.krbdom.value='';
396: }
397:
1.4 www 398: function pclose() {
399: parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
400: "height=350,width=350,scrollbars=no,menubar=no");
401: parmwin.close();
402: }
403:
404: function pjump(type,dis,value,marker,ret,call) {
405: parmwin=window.open("/adm/rat/parameter.html?type="+escape(type)
406: +"&value="+escape(value)+"&marker="+escape(marker)
407: +"&return="+escape(ret)
408: +"&call="+escape(call)+"&name="+escape(dis),"LONCAPAparms",
409: "height=350,width=350,scrollbars=no,menubar=no");
410:
411: }
412:
413: function dateset() {
414: if (document.studentform.pres_marker.value=='end') {
415: document.studentform.enddate.value=
416: document.studentform.pres_value.value;
417: }
418: if (document.studentform.pres_marker.value=='start') {
419: document.studentform.startdate.value=
420: document.studentform.pres_value.value;
421: }
422: pclose();
423: }
1.3 www 424:
425: </script>
1.2 www 426: <table border=2><tr><th>Field</th><th>Samples</th></tr>
427: ENDPICK
1.10 www 428: my %sone; my %stwo; my %sthree;
429: my $i=0;
430:
431: if ($total>=0) {
432: %sone=&record_sep($records[0]);
433: if ($total>=1) {
434: %stwo=&record_sep($records[1]);
435:
1.2 www 436: }
1.10 www 437: if ($total>=2) {
438: %sthree=&record_sep($records[2]);
1.2 www 439: }
1.20 harris41 440: foreach (sort keys %sone) {
1.3 www 441: $r->print('<tr><td><select name=f'.$i.
442: ' onChange="flip(this.form,'.$i.');">');
1.20 harris41 443: foreach ('none: ','username:Username',
1.2 www 444: 'names:Last Name, First Names',
445: 'fname:First Name','mname:Middle Names/Initials',
446: 'lname:Last Name','gen:Generation',
1.3 www 447: 'id:ID/Student Number','sec:Group/Section',
1.20 harris41 448: 'ipwd:Initial Password') {
449: my ($value,$display)=split(/\:/,$_);
450: $r->print('<option value='.$value.'>'.$display.
451: '</option>');
452: }
1.2 www 453: $r->print('</select></td><td>');
1.13 www 454: if (defined($sone{$_})) {
455: $r->print($sone{$_}."</br>\n");
1.2 www 456: }
1.13 www 457: if (defined($stwo{$_})) {
458: $r->print($stwo{$_}."</br>\n");
1.2 www 459: }
1.13 www 460: if (defined($sthree{$_})) {
461: $r->print($sthree{$_}."</br>\n");
1.2 www 462: }
463: $r->print('</td></tr>');
1.10 www 464: $i++;
1.20 harris41 465: }
1.10 www 466: $i--;
1.2 www 467: }
1.10 www 468: my $keyfields=join(',',sort keys %sone);
1.3 www 469: $r->print(<<ENDPICK);
470: </table>
1.10 www 471: <input type=hidden name=nfields value=$i>
472: <input type=hidden name=keyfields value="$keyfields">
1.3 www 473: <h3>Login Type</h3>
1.15 albertel 474: <p>Note: this will not take effect if the user already exists</p>
475: <p>
476: <input type=radio name=login value=krb onClick="clickkrb(this.form);" />
1.3 www 477: Kerberos authenticated with domain
1.15 albertel 478: <input type=text size=10 name=krbdom onChange="setkrb(this.form);" />
479: </p>
480: <p>
481: <input type=radio name=login value=int onClick="clickint(this.form);" />
1.3 www 482: Internally authenticated (with initial password
1.15 albertel 483: <input type=text size=10 name=intpwd onChange="setint(this.form);" />)
484: </p>
485: <p>
486: <input type=radio name=login value=loc onClick="clickloc(this.form);" />
487: Local Authentication with argument
488: <input type=text size=10 name=locarg onChange="setloc(this.form);" />
489: </p>
1.5 www 490: <h3>LON-CAPA Domain for Students</h3>
1.4 www 491: LON-CAPA domain: <input type=text size=10 value=$defdom name=lcdomain><p>
1.5 www 492: <h3>Starting and Ending Dates</h3>
1.4 www 493: <input type="hidden" value='' name="pres_value">
494: <input type="hidden" value='' name="pres_type">
495: <input type="hidden" value='' name="pres_marker">
496: <input type="hidden" value='$today' name=startdate>
497: <input type="hidden" value='$halfyear' name=enddate>
498: <a
499: href="javascript:pjump('date_start','Enrollment Starting Date',document.studentform.startdate.value,'start','studentform.pres','dateset');"
500: >Set Starting Date</a><p>
501:
502: <a
503: href="javascript:pjump('date_end','Enrollment Ending Date',document.studentform.enddate.value,'end','studentform.pres','dateset');"
504: >Set Ending Date</a><p>
1.5 www 505: <h3>Full Update</h3>
506: <input type=checkbox name=fullup value=yes> Full update
1.11 www 507: (also print list of users not enrolled anymore)<p>
1.18 www 508: <h3>ID/Student Number</h3>
509: <input type=checkbox name=forceid value=yes>
510: Disable ID/Student Number Safeguard and Force Change of Conflicting IDs
1.19 www 511: (only do if you know what you are doing)<p>
1.6 www 512: <input type=button onClick="verify(this.form)" value="Update Courselist"><br>
513: Note: for large courses, this operation might be time consuming.
1.3 www 514: ENDPICK
1.10 www 515: }
516:
1.12 www 517: # ======================================================= Enroll single student
518:
519: sub enroll_single_student {
520: my $r=shift;
521: $r->print('<h3>Enrolling Student</h3>');
522: if (($ENV{'form.cuname'})&&($ENV{'form.cuname'}!~/\W/)&&
523: ($ENV{'form.cdomain'})&&($ENV{'form.cdomain'}!~/\W/)) {
524: my $amode='';
525: my $genpwd='';
526: if ($ENV{'form.login'} eq 'krb') {
527: $amode='krb4';
528: $genpwd=$ENV{'form.krbdom'};
529: } elsif ($ENV{'form.login'} eq 'int') {
530: $amode='internal';
531: $genpwd=$ENV{'form.intpwd'};
1.15 albertel 532: } elsif ($ENV{'form.login'} eq 'loc') {
533: $amode='localauth';
534: $genpwd=$ENV{'form.locarg'};
535: if (!$genpwd) { $genpwd=" "; }
536: }
1.12 www 537: if (($amode) && ($genpwd)) {
538: &dropstudent($ENV{'form.cdomain'},$ENV{'form.cuname'},
539: $ENV{'request.course.id'},$ENV{'form.csec'});
540: $r->print(&Apache::lonnet::modifystudent(
541: $ENV{'form.cdomain'},$ENV{'form.cuname'},
542: $ENV{'form.cstid'},$amode,$genpwd,
543: $ENV{'form.cfirst'},$ENV{'form.cmiddle'},
544: $ENV{'form.clast'},$ENV{'form.cgen'},
545: $ENV{'form.csec'},$ENV{'form.enddate'},
1.19 www 546: $ENV{'form.startdate'},$ENV{'form.forceid'}));
1.12 www 547: } else {
548: $r->print('Invalid login mode or password');
549: }
550: } else {
551: $r->print('Invalid username or domain');
552: }
553: }
554:
1.10 www 555: # ======================================================= Menu Phase Two Enroll
556:
557: sub menu_phase_two_enroll {
558: my $r=shift;
1.11 www 559:
560: $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/;
561: my $krbdefdom=$1;
562: $krbdefdom=~tr/a-z/A-Z/;
563:
564: my $today=time;
565: my $halfyear=$today+15552000;
566:
567: my $defdom=$r->dir_config('lonDefDomain');
568:
569: $r->print(<<ENDSENROLL);
1.12 www 570: <script>
571: function verify(vf) {
572: var founduname=0;
573: var foundpwd=0;
574: var foundname=0;
575: var foundid=0;
576: var foundsec=0;
577: var foundatype=0;
578: var tw;
579: var message='';
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: }
598: if (vf.login[0].checked) {
599: foundatype=1;
600: if (vf.krbdom.value=='') {
601: alert('You need to specify the Kerberos domain');
602: return;
603: }
604: }
605: if (vf.login[1].checked) {
606: foundatype=1;
607: if ((vf.intpwd.value=='') && (foundpwd==0)) {
608: alert('You need to specify the initial password');
609: return;
610: }
611: }
1.15 albertel 612: if (vf.login[2].checked) {
613: foundatype=1;
614: //An argument is not required
615: }
1.12 www 616: if (foundatype==0) {
617: alert('You need to set the login type');
618: return;
619: }
620: if (foundname==0) { message='No first and last name specified. '; }
621: if (foundid==0) { message+='No ID or student number field specified. '; }
622: if (foundsec==0) { message+='No section or group field specified. '; }
623: if (vf.startdate.value=='') {
624: message+='No starting date set. ';
625: }
626: if (vf.enddate.value=='') {
627: message+='No ending date set. ';
628: }
629: if ((vf.enddate.value!='') && (vf.startdate.value!='')) {
630: if (Math.round(vf.enddate.value)<Math.round(vf.startdate.value)) {
631: alert('Ending date is before starting date');
632: return;
633: }
634: }
635: if (message!='') {
636: message+='Continue enrollment?';
637: if (confirm(message)) {
638: pclose();
639: vf.submit();
640: }
641: } else {
642: pclose();
643: vf.submit();
644: }
645: }
646:
647: function setkrb(vf) {
648: if (vf.krbdom.value!='') {
649: vf.login[0].checked=true;
650: vf.krbdom.value=vf.krbdom.value.toUpperCase();
651: vf.intpwd.value='';
1.15 albertel 652: vf.locarg.value='';
1.12 www 653: }
654: }
655:
656: function setint(vf) {
657: if (vf.intpwd.value!='') {
658: vf.login[1].checked=true;
659: vf.krbdom.value='';
1.15 albertel 660: vf.locarg.value='';
661: }
662: }
663:
664: function setloc(vf) {
665: if (vf.locarg.value!='') {
666: vf.login[2].checked=true;
667: vf.krbdom.value='';
668: vf.intpwd.value='';
1.12 www 669: }
670: }
671:
672: function clickkrb(vf) {
673: vf.krbdom.value='$krbdefdom';
674: vf.intpwd.value='';
1.15 albertel 675: vf.locarg.value='';
1.12 www 676: }
677:
678: function clickint(vf) {
679: vf.krbdom.value='';
1.15 albertel 680: vf.locarg.value='';
681: }
682:
683: function clickloc(vf) {
684: vf.krbdom.value='';
685: vf.intpwd.value='';
1.12 www 686: }
687:
688: function pclose() {
689: parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
690: "height=350,width=350,scrollbars=no,menubar=no");
691: parmwin.close();
692: }
693:
694: function pjump(type,dis,value,marker,ret,call) {
695: parmwin=window.open("/adm/rat/parameter.html?type="+escape(type)
696: +"&value="+escape(value)+"&marker="+escape(marker)
697: +"&return="+escape(ret)
698: +"&call="+escape(call)+"&name="+escape(dis),"LONCAPAparms",
699: "height=350,width=350,scrollbars=no,menubar=no");
700:
701: }
702:
703: function dateset() {
704: if (document.studentform.pres_marker.value=='end') {
705: document.studentform.enddate.value=
706: document.studentform.pres_value.value;
707: }
708: if (document.studentform.pres_marker.value=='start') {
709: document.studentform.startdate.value=
710: document.studentform.pres_value.value;
711: }
712: pclose();
713: }
714:
715: </script>
1.11 www 716: <h3>Personal Data</h3>
717: First Name: <input type=text name=cfirst size=15><br>
718: Middle Name: <input type=text name=cmiddle size=15><br>
719: Last Name: <input type=text name=clast size=15><br>
720: Generation: <input type=text name=cgen size=5><p>
721:
722: ID/Student Number: <input type=text name=cstid size=10><p>
723:
724: Group/Section: <input type=text name=csec size=5><p>
725:
1.12 www 726: <h3>Login Data</h3>
727: Username: <input type=text name=cuname size=15><p>
728: Domain: <input type=text size=10 value=$defdom name=cdomain><p>
729: Note: login settings below will not take effect if the user already exists<p>
1.11 www 730:
731: <input type=radio name=login value=krb onClick="clickkrb(this.form);">
732: Kerberos authenticated with domain
733: <input type=text size=10 name=krbdom onChange="setkrb(this.form);"><p>
734: <input type=radio name=login value=int onClick="clickint(this.form);">
735: Internally authenticated (with initial password
736: <input type=text size=10 name=intpwd onChange="setint(this.form);">)
1.15 albertel 737: <p>
738: <input type=radio name=login value=loc onClick="clickloc(this.form);" />
739: Local Authentication with argument
740: <input type=text size=10 name=locarg onChange="setloc(this.form);" />
741: </p>
1.11 www 742: <h3>Starting and Ending Dates</h3>
743: <input type="hidden" value='' name="pres_value">
744: <input type="hidden" value='' name="pres_type">
745: <input type="hidden" value='' name="pres_marker">
746: <input type="hidden" value='$today' name=startdate>
747: <input type="hidden" value='$halfyear' name=enddate>
748: <a
749: href="javascript:pjump('date_start','Enrollment Starting Date',document.studentform.startdate.value,'start','studentform.pres','dateset');"
750: >Set Starting Date</a><p>
751:
752: <a
753: href="javascript:pjump('date_end','Enrollment Ending Date',document.studentform.enddate.value,'end','studentform.pres','dateset');"
754: >Set Ending Date</a><p>
1.18 www 755: <h3>ID/Student Number</h3>
756: <input type=checkbox name=forceid value=yes>
757: Disable ID/Student Number Safeguard and Force Change of Conflicting IDs
1.19 www 758: (only do if you know what you are doing)<p>
1.12 www 759: <input type=button onClick="verify(this.form)" value="Enroll as student"><br>
760: <input type=hidden name=phase value=five>
1.11 www 761: ENDSENROLL
1.10 www 762: }
763:
764: # ========================================================= Menu Phase Two Drop
765:
766: sub menu_phase_two_drop {
767: my $r=shift;
1.11 www 768: my $cid=$ENV{'request.course.id'};
769: my $classlst=&Apache::lonnet::reply
770: ('dump:'.$ENV{'course.'.$cid.'.domain'}.':'.
771: $ENV{'course.'.$cid.'.num'}.':classlist',
772: $ENV{'course.'.$cid.'.home'});
773: my %currentlist=();
774: my $now=time;
775: unless ($classlst=~/^error\:/) {
1.20 harris41 776: foreach (split(/\&/,$classlst)) {
1.11 www 777: my ($name,$value)=split(/\=/,$_);
778: my ($end,$start)=split(/\:/,
779: &Apache::lonnet::unescape($value));
780: my $active=1;
781: if (($end) && ($now>$end)) { $active=0; }
782: if ($active) {
783: $currentlist{&Apache::lonnet::unescape($name)}=1;
784: }
1.20 harris41 785: }
1.11 www 786: # ----------------------------------------------------------- Print out choices
787: &show_drop_list($r,%currentlist);
788: } else {
789: $r->print(
790: '<font color=red><h3>Could not access classlist: '.$classlst.
791: '</h3></font>');
792: }
793: }
794:
795: # =================================================== Show student list to drop
796:
797: sub show_drop_list {
798: my ($r,%currentlist)=@_;
799: my $cid=$ENV{'request.course.id'};
800:
801: $r->print('<input type=hidden name=phase value=four>');
802: $r->print('<table border=2>');
1.20 harris41 803: foreach (sort keys %currentlist) {
1.11 www 804: my ($sname,$sdom)=split(/\:/,$_);
805: my %reply=&Apache::lonnet::idrget($sdom,$sname);
806: my $ssec=&Apache::lonnet::usection($sdom,$sname,$cid);
807: my @reply=split(/[\&\=]/,&Apache::lonnet::reply(
808: 'get:'.$sdom.':'.$sname.
809: ':environment:firstname&middlename&lastname&generation',
810: &Apache::lonnet::homeserver($sname,$sdom)));
811: $r->print(
812: '<tr><td><input type=checkbox name="drop:'.$_.'"></td><td>'.
813: $sname.'</td><td>'.$sdom.'</td><td>'.
814: $reply{$sname}.'</td><td>'.
815: &Apache::lonnet::unescape($reply[2]).' '.
816: &Apache::lonnet::unescape($reply[3]).', '.
817: &Apache::lonnet::unescape($reply[0]).' '.
818: &Apache::lonnet::unescape($reply[1]).
819: '</td><td>'.
820: $ssec."</td></tr>\n");
1.20 harris41 821: }
1.11 www 822: $r->print('</table><br>');
823: $r->print('<input type=submit value="Drop Students">');
1.10 www 824: }
825:
826: # ================================================= Drop/Add from uploaded file
827:
828: sub upfile_drop_add {
829: my $r=shift;
830:
831: &load_tmp_file($r);
832: my @studentdata=&upfile_record_sep();
833:
834: my @keyfields=split(/\,/,$ENV{'form.keyfields'});
835: my $cid=$ENV{'request.course.id'};
836:
1.4 www 837: my %fields=();
838: for (my $i=0;$i<=$ENV{'form.nfields'};$i++) {
1.10 www 839: $fields{$ENV{'form.f'.$i}}=$keyfields[$i];
1.4 www 840: }
841: my $startdate=$ENV{'form.startdate'};
842: my $enddate=$ENV{'form.enddate'};
843: if ($startdate=~/\D/) { $startdate=''; }
844: if ($enddate=~/\D/) { $enddate=''; }
1.5 www 845: my $domain=$ENV{'form.lcdomain'};
846: my $amode='';
847: my $genpwd='';
848: if ($ENV{'form.login'} eq 'krb') {
849: $amode='krb4';
850: $genpwd=$ENV{'form.krbdom'};
851: } elsif ($ENV{'form.login'} eq 'int') {
852: $amode='internal';
853: if ((defined($ENV{'form.intpwd'})) && ($ENV{'form.intpwd'})) {
854: $genpwd=$ENV{'form.intpwd'};
855: }
1.15 albertel 856: } elsif ($ENV{'form.login'} eq 'loc') {
857: $amode='localauth';
858: if ((defined($ENV{'form.locarg'})) && ($ENV{'form.locarg'})) {
859: $genpwd=$ENV{'form.locarg'};
860: }
861: }
1.5 www 862: unless (($domain=~/\W/) || ($amode eq '')) {
863: $r->print('<h3>Enrolling Students</h3>');
1.7 www 864: my $count=0;
865: my $flushc=0;
866: my %student=();
1.5 www 867: # ----------------------------------------------------------- Get new classlist
868: # --------------------------------------------------------- Enroll new students
1.20 harris41 869: foreach (@studentdata) {
1.10 www 870: my %entries=&record_sep($_);
871:
872: unless (($entries{$fields{'username'}} eq '') ||
873: (!defined($entries{$fields{'username'}}))) {
1.4 www 874: my $fname=''; my $mname=''; my $lname=''; my $gen='';
875: if (defined($fields{'names'})) {
876: ($lname,$fname,$mname)=
1.10 www 877: ($entries{$fields{'names'}}=~/([^\,]+)\,\s*(\w+)\s*(.*)$/);
1.4 www 878: } else {
879: if (defined($fields{'fname'})) {
1.10 www 880: $fname=$entries{$fields{'fname'}};
1.4 www 881: }
882: if (defined($fields{'mname'})) {
1.10 www 883: $mname=$entries{$fields{'mname'}};
1.4 www 884: }
885: if (defined($fields{'lname'})) {
1.10 www 886: $lname=$entries{$fields{'lname'}};
1.4 www 887: }
888: if (defined($fields{'gen'})) {
1.10 www 889: $gen=$entries{$fields{'gen'}};
1.4 www 890: }
891: }
1.10 www 892: if ($entries{$fields{'username'}}=~/\W/) {
1.4 www 893: $r->print('<p><b>Unacceptable username: '.
1.10 www 894: $entries{$fields{'username'}}.' for user '.
1.4 www 895: $fname.' '.$mname.' '.$lname.' '.$gen.'</b><p>');
1.5 www 896: } else {
897: my $sec='';
1.10 www 898: my $username=$entries{$fields{'username'}};
1.5 www 899: if (defined($fields{'sec'})) {
1.10 www 900: if (defined($entries{$fields{'sec'}})) {
901: $sec=$entries{$fields{'sec'}};
1.5 www 902: }
903: }
904: my $id='';
905: if (defined($fields{'id'})) {
1.10 www 906: if (defined($entries{$fields{'id'}})) {
907: $id=$entries{$fields{'id'}};
1.5 www 908: }
909: $id=~tr/A-Z/a-z/;
910: }
911: my $password='';
912: if ($genpwd) {
913: $password=$genpwd;
914: } else {
915: if (defined($fields{'ipwd'})) {
1.10 www 916: if ($entries{$fields{'ipwd'}}) {
917: $password=$entries{$fields{'ipwd'}};
1.5 www 918: }
919: }
920: }
1.10 www 921: if ($password) {
922: &dropstudent($domain,$username,$cid,$sec);
1.5 www 923: my $reply=&Apache::lonnet::modifystudent(
924: $domain,$username,$id,$amode,$password,
1.19 www 925: $fname,$mname,$lname,$gen,$sec,$enddate,$startdate,
926: $ENV{'form.forceid'});
1.5 www 927: unless ($reply eq 'ok') {
928: $r->print(
929: "<p><b>Error enrolling $username: $reply</b><p>");
1.10 www 930: } else {
1.7 www 931: $count++; $flushc++;
932: $student{$username}=1;
1.6 www 933: $r->print('. ');
1.7 www 934: if ($flushc>15) {
935: $r->rflush;
936: $flushc=0;
937: }
1.6 www 938: }
1.5 www 939: } else {
940: $r->print(
941: "<p><b>No password for $username</b><p>");
942: }
1.4 www 943: }
944: }
1.20 harris41 945: }
1.7 www 946: $r->print('<p>Processed Students: '.$count);
1.5 www 947: # --------------------------------------------------------------- Drop students
948: if ($ENV{'form.fullup'} eq 'yes') {
949: $r->print('<h3>Dropping Students</h3>');
950: # ------------------------------------------------------- Get current classlist
951: my $classlst=&Apache::lonnet::reply
952: ('dump:'.$ENV{'course.'.$cid.'.domain'}.':'.
953: $ENV{'course.'.$cid.'.num'}.':classlist',
954: $ENV{'course.'.$cid.'.home'});
955: my %currentlist=();
956: my $now=time;
957: unless ($classlst=~/^error\:/) {
1.20 harris41 958: foreach (split(/\&/,$classlst)) {
1.7 www 959: my ($name,$value)=split(/\=/,$_);
1.8 www 960: my ($end,$start)=split(/\:/,
1.7 www 961: &Apache::lonnet::unescape($value));
962: my $active=1;
963: if (($end) && ($now>$end)) { $active=0; }
964: if ($active) {
965: $currentlist{&Apache::lonnet::unescape($name)}=1;
966: }
1.20 harris41 967: }
1.10 www 968: # ------------------------------------------------ Now got up-to-date classlist
1.20 harris41 969: foreach (@studentdata) {
1.10 www 970: my %entries=&record_sep($_);
971: unless (($entries{$fields{'username'}} eq '') ||
972: (!defined($entries{$fields{'username'}}))) {
973: delete($currentlist{
974: $entries{$fields{'username'}}.':'.
975: $domain});
976: }
1.20 harris41 977: }
1.10 www 978: # ----------------------------------------------------------- Print out choices
1.11 www 979: &show_drop_list($r,%currentlist);
1.5 www 980: } else {
981: $r->print(
982: '<font color=red><h3>Could not access classlist: '.$classlst.
983: '</h3></font>');
984: }
985: }
986: # ------------------------------------------------------------------------ Done
1.10 www 987:
988: }
989: }
990:
1.11 www 991: # ================================================================== Phase four
992:
993: sub drop_student_list {
994: my $r=shift;
995: my $count=0;
1.20 harris41 996: foreach (keys %ENV) {
1.11 www 997: if ($_=~/^form\.drop\:/) {
998: my ($dummy,$uname,$udom)=split(/\:/,$_);
999: &dropstudent($udom,$uname,$ENV{'request.course.id'});
1000: $r->print('Dropped '.$uname.' at '.$udom.'<br>');
1001: $count++;
1002: }
1.20 harris41 1003: }
1.11 www 1004: $r->print('<p><b>Dropped '.$count.' student(s).</b>');
1005: $r->print('<p>Re-enrollment will re-activate data.');
1006: }
1007:
1.10 www 1008: # ================================================================ Main Handler
1009:
1010: sub handler {
1011: my $r=shift;
1012:
1013: if ($r->header_only) {
1014: $r->content_type('text/html');
1015: $r->send_http_header;
1016: return OK;
1017: }
1018:
1019: # ----------------------------------------------------- Needs to be in a course
1020:
1021: if (($ENV{'request.course.fn'}) &&
1022: (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'}))) {
1023:
1024: # ------------------------------------------------------------------ Start page
1025: $r->content_type('text/html');
1026: $r->send_http_header;
1027: &header($r);
1028:
1029: # --------------------------------------------------- Phase one, initial screen
1030: unless ($ENV{'form.phase'}) {
1031: &menu_phase_one($r);
1032: }
1033: # ------------------------------------------------------------------- Phase two
1034: if ($ENV{'form.phase'} eq 'two') {
1035: if ($ENV{'form.fileupload'}) {
1036: &menu_phase_two_upload($r);
1037: } elsif ($ENV{'form.enroll'}) {
1038: &menu_phase_two_enroll($r);
1039: } elsif ($ENV{'form.drop'}) {
1040: &menu_phase_two_drop($r);
1041: }
1042: }
1043:
1044:
1045:
1046:
1047: # ----------------------------------------------------------------- Phase three
1048: if ($ENV{'form.phase'} eq 'three') {
1049: if ($ENV{'form.datatoken'}) {
1050: &upfile_drop_add($r);
1.2 www 1051: }
1.11 www 1052: }
1053: # ------------------------------------------------------------------ Phase four
1054: if ($ENV{'form.phase'} eq 'four') {
1055: &drop_student_list($r);
1.12 www 1056: }
1057: # ------------------------------------------------------------------ Phase four
1058: if ($ENV{'form.phase'} eq 'five') {
1059: &enroll_single_student($r);
1.2 www 1060: }
1061: # ------------------------------------------------------------------------- End
1.1 www 1062: $r->print('</form></body></html>');
1063: } else {
1064: # ----------------------------- Not in a course, or not allowed to modify parms
1065: $ENV{'user.error.msg'}=
1066: "/adm/dropadd:cst:0:0:Cannot drop or add students";
1067: return HTTP_NOT_ACCEPTABLE;
1068: }
1069: return OK;
1070: }
1071:
1072: 1;
1073: __END__
1074:
1075:
1076:
1077:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>