Annotation of loncom/interface/londropadd.pm, revision 1.25

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>