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

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Handler to drop and add students in courses 
                      3: #
1.95    ! albertel    4: # $Id: londropadd.pm,v 1.94 2003/12/12 18:04:38 sakharuk 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: #
1.50      matthew    29: ###############################################################
1.82      www        30: ##############################################################
1.1       www        31: 
                     32: package Apache::londropadd;
                     33: 
                     34: use strict;
1.24      albertel   35: use Apache::lonnet();
                     36: use Apache::loncommon();
1.50      matthew    37: use Apache::lonhtmlcommon();
1.1       www        38: use Apache::Constants qw(:common :http REDIRECT);
1.60      matthew    39: use Spreadsheet::WriteExcel;
1.86      www        40: use Apache::lonlocal;
1.1       www        41: 
1.50      matthew    42: ###############################################################
                     43: ###############################################################
1.10      www        44: sub header {
1.46      www        45:     my $bodytag=&Apache::loncommon::bodytag('Enrollment Manager');
1.88      matthew    46:     my $title = &mt('LON-CAPA Enrollment Manager');
1.27      matthew    47:     return(<<ENDHEAD);
1.1       www        48: <html>
                     49: <head>
1.88      matthew    50: <title>$title</title>
1.1       www        51: </head>
1.46      www        52: $bodytag
1.40      matthew    53: <form method="post" enctype="multipart/form-data"  
                     54:       action="/adm/dropadd" name="studentform">
1.1       www        55: ENDHEAD
1.10      www        56: }
                     57: 
1.50      matthew    58: ###############################################################
                     59: ###############################################################
                     60: # Drop student from all sections of a course, except optional $csec
1.26      matthew    61: sub modifystudent {
1.33      matthew    62:     my ($udom,$unam,$courseid,$csec,$desiredhost)=@_;
1.26      matthew    63:     # if $csec is undefined, drop the student from all the courses matching
                     64:     # this one.  If $csec is defined, drop them from all other sections of 
                     65:     # this course and add them to section $csec
1.25      matthew    66:     $courseid=~s/\_/\//g;
                     67:     $courseid=~s/^(\w)/\/$1/;
1.26      matthew    68:     my %roles = &Apache::lonnet::dump('roles',$udom,$unam);
                     69:     my ($tmp) = keys(%roles);
                     70:     # Bail out if we were unable to get the students roles
1.35      matthew    71:     return "$1" if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.26      matthew    72:     # Go through the roles looking for enrollment in this course
1.35      matthew    73:     my $result = '';
1.26      matthew    74:     foreach my $course (keys(%roles)) {
1.35      matthew    75:         if ($course=~/^$courseid(?:\/)*(?:\s+)*(\w+)*\_st$/) {
1.26      matthew    76:             # We are in this course
1.25      matthew    77:             my $section=$1;
1.26      matthew    78:             $section='' if ($course eq $courseid.'_st');
1.87      matthew    79:             if (defined($csec) && $section eq $csec) {
1.71      matthew    80:                 $result .= 'ok:';
                     81:             } elsif ( ((!$section) && (!$csec)) || ($section ne $csec) ) {
1.27      matthew    82:                 my (undef,$end,$start)=split(/\_/,$roles{$course});
1.25      matthew    83:                 my $now=time;
1.50      matthew    84:                 # if this is an active role 
1.27      matthew    85:                 if (!($start && ($now<$start)) || !($end && ($now>$end))) {
1.25      matthew    86:                     my $reply=&Apache::lonnet::modifystudent
1.70      matthew    87:                         # dom  name  id mode pass     f     m     l     g
                     88:                         ($udom,$unam,'',  '',  '',undef,undef,undef,undef,
1.33      matthew    89:                          $section,time,undef,undef,$desiredhost);
1.35      matthew    90:                     $result .= $reply.':';
1.25      matthew    91:                 }
1.10      www        92:             }
                     93:         }
1.20      harris41   94:     }
1.35      matthew    95:     if ($result eq '') {
1.62      matthew    96:         $result = 'Unable to find section for this student';
1.37      matthew    97:     } else {
                     98:         $result =~ s/(ok:)+/ok/g;
1.35      matthew    99:     }
                    100:     return $result;
1.10      www       101: }
                    102: 
1.50      matthew   103: ###############################################################
                    104: ###############################################################
                    105: # build a domain and server selection form
1.31      matthew   106: sub domain_form {
                    107:     my ($defdom) = @_;
                    108:     # Set up domain and server selection forms
                    109:     #
                    110:     # Get the domains
                    111:     my @domains = &Apache::loncommon::get_domains();
                    112:     # build up the menu information to be passed to 
                    113:     # &Apache::loncommon::linked_select_forms
                    114:     my %select_menus;
                    115:     foreach my $dom (@domains) {
                    116:         # set up the text for this domain
                    117:         $select_menus{$dom}->{'text'}= $dom;
                    118:         # we want a choice of 'default' as the default in the second menu
                    119:         $select_menus{$dom}->{'default'}= 'default';
                    120:         $select_menus{$dom}->{'select2'}->{'default'} = 'default';
                    121:         # Now build up the other items in the second menu
1.45      matthew   122:         my %servers = &Apache::loncommon::get_library_servers($dom);
1.31      matthew   123:         foreach my $server (keys(%servers)) {
                    124:             $select_menus{$dom}->{'select2'}->{$server} 
                    125:                                             = "$server $servers{$server}";
                    126:         }
                    127:     }
                    128:     my $result  = &Apache::loncommon::linked_select_forms
                    129:         ('studentform',' with home server ',$defdom,
                    130:          'lcdomain','lcserver',\%select_menus);
                    131:     return $result;
                    132: }
                    133: 
1.50      matthew   134: ###############################################################
                    135: ###############################################################
                    136: #  Menu Phase One
                    137: sub print_main_menu {
1.10      www       138:     my $r=shift;
1.88      matthew   139:     my %Text = &Apache::lonlocal::texthash
                    140:         ('upload'    => 'Upload a class list',
                    141:          'enrollone' => 'Enroll a single student',
                    142:          'modify'    => 'Modify student data',
                    143:          'view'      => 'View Class List',
1.91      raeburn   144:          'drop'      => 'Drop Students',
                    145:          'populate'  => 'Automated Enrollment Manager');
1.88      matthew   146: 
1.48      matthew   147:     $r->print(<<END);
                    148: <p>
1.50      matthew   149: <font size="+1">
1.88      matthew   150:     <a href="/adm/dropadd?action=upload">$Text{'upload'}</a>
1.50      matthew   151: </font>
                    152: </p><p>
                    153: <font size="+1">
1.88      matthew   154:     <a href="/adm/dropadd?action=enrollstudent">$Text{'enrollone'}</a>
1.50      matthew   155: </font>
1.48      matthew   156: </p><p>
1.50      matthew   157: <font size="+1">
1.88      matthew   158:     <a href="/adm/dropadd?action=modifystudent">$Text{'modify'}</a>
1.50      matthew   159: </font>
1.48      matthew   160: </p><p>
1.50      matthew   161: <font size="+1">
1.88      matthew   162:     <a href="/adm/dropadd?action=classlist">$Text{'view'}</a>
1.50      matthew   163: </font>
1.48      matthew   164: </p><p>
1.50      matthew   165: <font size="+1">
1.88      matthew   166:     <a href="/adm/dropadd?action=drop">$Text{'drop'}</a>
1.50      matthew   167: </font>
1.91      raeburn   168: </p><p>
                    169: <font size="+1">
                    170:     <a href="/adm/populate">$Text{'populate'}</a>
                    171: </font>
1.48      matthew   172: END
1.10      www       173: }
                    174: 
1.50      matthew   175: ###############################################################
                    176: ###############################################################
1.89      matthew   177: sub hidden_input {
                    178:     my ($name,$value) = @_;
                    179:     return '<input type="hidden" name="'.$name.'" value="'.$value.'" />'."\n";
                    180: }
                    181: 
1.50      matthew   182: sub print_upload_manager_header {
1.23      albertel  183:     my ($r,$datatoken,$distotal,$krbdefdom)=@_;
1.24      albertel  184:     my $javascript;
1.50      matthew   185:     if (! exists($ENV{'form.upfile_associate'})) {
                    186:         $ENV{'form.upfile_associate'} = 'forward';
                    187:     }
                    188:     if ($ENV{'form.associate'} eq 'Reverse Association') {
                    189:         if ( $ENV{'form.upfile_associate'} ne 'reverse' ) {
                    190:             $ENV{'form.upfile_associate'} = 'reverse';
                    191:         } else {
                    192:             $ENV{'form.upfile_associate'} = 'forward';
                    193:         }
                    194:     }
1.24      albertel  195:     if ($ENV{'form.upfile_associate'} eq 'reverse') {
1.50      matthew   196: 	$javascript=&upload_manager_javascript_reverse_associate();
1.24      albertel  197:     } else {
1.50      matthew   198: 	$javascript=&upload_manager_javascript_forward_associate();
1.24      albertel  199:     }
1.89      matthew   200:     my $javascript_validations=&javascript_validations('auth',$krbdefdom);
1.82      www       201:     my $checked=(($ENV{'form.noFirstLine'})?' checked="1"':'');
1.88      matthew   202:     $r->print('<h3>'.&mt('Uploading Class List')."</h3>\n".
                    203:               "<hr>\n".
                    204:               '<h3>'.&mt('Identify fields')."</h3>\n");
                    205:     $r->print("<p>\n".
                    206:               &mt('Total number of records found in file: [_1].',$distotal).
                    207:               "\n".
                    208:               "</p><hr>\n");
1.94      sakharuk  209:     $r->print(&mt('Enter as many fields as you can. The system will inform you and bring you back to this page if the data selected is insufficient to enroll students in your class.')."<hr>\n");
1.89      matthew   210:     $r->print(&hidden_input('action','upload').
                    211:               &hidden_input('state','got_file').
                    212:               &hidden_input('associate','').
                    213:               &hidden_input('datatoken',$datatoken).
                    214:               &hidden_input('fileupload',$ENV{'form.fileupload'}).
                    215:               &hidden_input('upfiletype',$ENV{'form.upfiletype'}).
                    216:               &hidden_input('upfile_associate',$ENV{'form.upfile_associate'}));
                    217:     $r->print('<input type="button" value="Reverse Association" '.
                    218:               'name="'.&mt('Reverse Association').'" '.
                    219:               'onClick="javascript:this.form.associate.value=\'Reverse Association\';submit(this.form);" />');
                    220:     $r->print('<input type="checkbox" name="noFirstLine" $checked />'.
                    221:               &mt('Ignore First Line'));
                    222:     $r->print("<hr />\n".
                    223:               '<script type="text/javascript" language="Javascript">'."\n".
                    224:               $javascript."\n".$javascript_validations.'</script>');
1.24      albertel  225: }
                    226: 
1.50      matthew   227: ###############################################################
                    228: ###############################################################
1.24      albertel  229: sub javascript_validations {
1.89      matthew   230:     my ($mode,$krbdefdom)=@_;
                    231:     my $authheader;
                    232:     if ($mode eq 'auth') {
                    233:         my %param = ( formname => 'studentform',
                    234:                       kerb_def_dom => $krbdefdom );
                    235:         $authheader = &Apache::loncommon::authform_header(%param);
1.91      raeburn   236:     } elsif ($mode eq 'createcourse') {
                    237:         my %param = ( formname => 'ccrs',
                    238:                   kerb_def_dom => $krbdefdom );
                    239:         $authheader = &Apache::loncommon::authform_header(%param);
1.89      matthew   240:     }
1.91      raeburn   241:     
1.89      matthew   242:     my %alert = &Apache::lonlocal::texthash
                    243:         (username => 'You need to specify the username field.',
                    244:          authen   => 'You must choose an authentication type.',
                    245:          krb      => 'You need to specify the Kerberos domain.',
                    246:          ipass    => 'You need to specify the initial password.',
                    247:          name     => 'The optional name field was not specified.',
                    248:          snum     => 'The optional student number field was not specified.',
                    249:          section  => 'The optional section or group field was not specified.', 
                    250:          email    => 'The optional email address field was not specified.',
                    251:          continue => 'Continue enrollment?',
                    252:          );
                    253:     
                    254: #    my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
                    255:     my $function_name =(<<END);
1.73      www       256: function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail) {
1.89      matthew   257: END
                    258:     my $auth_checks = (<<END);
1.3       www       259:     var foundatype=0;
1.91      raeburn   260: END
                    261:     unless ($mode eq 'createcourse') {
                    262:         $auth_checks .= (<<END);
1.3       www       263:     if (founduname==0) {
1.89      matthew   264: 	alert('$alert{'username'}');
1.3       www       265:         return;
                    266:     }
1.91      raeburn   267: END
                    268:     }
                    269:     $auth_checks .= (<<END);
1.61      matthew   270:     // alert('current.radiovalue = '+current.radiovalue);
1.29      matthew   271:     if (current.radiovalue == null || current.radiovalue == 'nochange') {
1.28      matthew   272:         // They did not check any of the login radiobuttons.
1.89      matthew   273:         alert('$alert{'authen'}');
1.28      matthew   274:         return;
                    275:     }
                    276:     foundatype=1;
1.29      matthew   277:     if (current.argfield == null || current.argfield == '') {
1.28      matthew   278:         var alertmsg = '';
1.29      matthew   279:         switch (current.value) {
1.28      matthew   280:             case 'krb': 
1.89      matthew   281:                 alertmsg = '$alert{'krb'}';
1.28      matthew   282:                 break;
                    283:             case 'loc':
                    284:             case 'fsys':
1.89      matthew   285:                 alertmsg = '$alert{'ipass'}';
1.28      matthew   286:                 break;
                    287:             case 'fsys':
                    288:                 alertmsg = '';
                    289:                 break;
                    290:             default: 
                    291:                 alertmsg = '';
1.3       www       292:         }
1.28      matthew   293:         if (alertmsg != '') {
                    294:             alert(alertmsg);
1.3       www       295:             return;
                    296:         }
                    297:     }
1.89      matthew   298: END
1.91      raeburn   299:     my $optional_checks = '';
                    300:     if ($mode eq 'createcourse') {
                    301:         $optional_checks = (<<END);
                    302:     vf.submit();
                    303: }
                    304: END
                    305:     } else {
                    306:         $optional_checks = (<<END);
1.89      matthew   307:     var message='';
                    308:     if (foundname==0) { 
                    309:         message='$alert{'name'}';
1.24      albertel  310:     }
1.89      matthew   311:     if (foundid==0) { 
                    312:         if (message!='') { 
                    313:             message+='\\n'; 
                    314:         }
                    315:         message+='$alert{'snum'}';
                    316:     }
                    317:     if (foundsec==0) {
                    318:         if (message!='') {
                    319:             message+='\\n';
                    320:         } 
                    321:         message+='$alert{'section'}';
                    322:     }
                    323:     if (foundemail==0) {
                    324:         if (message!='') {
                    325:             message+='\\n';
                    326:         }
                    327:         message+='$alert{'email'}';
1.74      matthew   328:     }
                    329:     if (message!='') {
1.89      matthew   330:         message+= '\\n$alert{'continue'}';
                    331:         if (confirm(message)) {
                    332:             vf.state.value='enrolling';
                    333:             vf.submit();
                    334:         }
1.74      matthew   335:     } else {
1.89      matthew   336:         vf.state.value='enrolling';
                    337:         vf.submit();
1.74      matthew   338:     }
                    339: }
1.89      matthew   340: END
1.91      raeburn   341:     }
1.89      matthew   342:     my $result = $function_name;
1.91      raeburn   343:     if ( ($mode eq 'auth') || ($mode eq 'createcourse') ) {
1.89      matthew   344:         $result .= $auth_checks;
                    345:     }
                    346:     $result .= $optional_checks;
1.91      raeburn   347:     if ( ($mode eq 'auth') || ($mode eq 'createcourse') ) {
1.89      matthew   348:         $result .= $authheader;
                    349:     }
                    350:     return $result;
1.74      matthew   351: }
                    352: 
1.50      matthew   353: ###############################################################
                    354: ###############################################################
                    355: sub upload_manager_javascript_forward_associate {
1.24      albertel  356:     return(<<ENDPICK);
                    357: function verify(vf) {
                    358:     var founduname=0;
                    359:     var foundpwd=0;
                    360:     var foundname=0;
                    361:     var foundid=0;
                    362:     var foundsec=0;
1.73      www       363:     var foundemail=0;
1.24      albertel  364:     var tw;
                    365:     for (i=0;i<=vf.nfields.value;i++) {
                    366:         tw=eval('vf.f'+i+'.selectedIndex');
                    367:         if (tw==1) { founduname=1; }
                    368:         if ((tw>=2) && (tw<=6)) { foundname=1; }
                    369:         if (tw==7) { foundid=1; }
                    370:         if (tw==8) { foundsec=1; }
                    371:         if (tw==9) { foundpwd=1; }
1.73      www       372:         if (tw==10) { foundemail=1; }
1.24      albertel  373:     }
1.73      www       374:     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail);
1.24      albertel  375: }
                    376: 
1.49      matthew   377: //
                    378: // vf = this.form
                    379: // tf = column number
                    380: //
                    381: // values of nw
                    382: //
                    383: // 0 = none
                    384: // 1 = username
                    385: // 2 = names (lastname, firstnames)
                    386: // 3 = fname (firstname)
                    387: // 4 = mname (middlename)
                    388: // 5 = lname (lastname)
                    389: // 6 = gen   (generation)
                    390: // 7 = id
                    391: // 8 = section
                    392: // 9 = ipwd  (password)
1.73      www       393: // 10 = email address
                    394: 
1.24      albertel  395: function flip(vf,tf) {
                    396:    var nw=eval('vf.f'+tf+'.selectedIndex');
                    397:    var i;
1.49      matthew   398:    // make sure no other columns are labeled the same as this one
1.24      albertel  399:    for (i=0;i<=vf.nfields.value;i++) {
                    400:       if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {
                    401:           eval('vf.f'+i+'.selectedIndex=0;')
                    402:       }
                    403:    }
1.49      matthew   404:    // If we set this to 'lastname, firstnames', clear out all the ones
                    405:    // set to 'fname','mname','lname','gen' (3,4,5,6) currently.
1.24      albertel  406:    if (nw==2) {
                    407:       for (i=0;i<=vf.nfields.value;i++) {
                    408:          if ((eval('vf.f'+i+'.selectedIndex')>=3) &&
                    409:              (eval('vf.f'+i+'.selectedIndex')<=6)) {
                    410:              eval('vf.f'+i+'.selectedIndex=0;')
                    411:          }
                    412:       }
                    413:    }
1.49      matthew   414:    // If we set this to one of 'fname','mname','lname','gen' (3,4,5,6),
                    415:    // clear out any that are set to 'lastname, firstnames' (2)
1.24      albertel  416:    if ((nw>=3) && (nw<=6)) {
                    417:       for (i=0;i<=vf.nfields.value;i++) {
                    418:          if (eval('vf.f'+i+'.selectedIndex')==2) {
                    419:              eval('vf.f'+i+'.selectedIndex=0;')
                    420:          }
                    421:       }
                    422:    }
1.49      matthew   423:    // If we set the password, make the password form below correspond to 
                    424:    // the new value.
1.24      albertel  425:    if (nw==9) {
1.28      matthew   426:        changed_radio('int',document.studentform);
                    427:        set_auth_radio_buttons('int',document.studentform);
                    428:        vf.intarg.value='';
                    429:        vf.krbarg.value='';
1.24      albertel  430:        vf.locarg.value='';
                    431:    }
                    432: }
                    433: 
                    434: function clearpwd(vf) {
                    435:     var i;
                    436:     for (i=0;i<=vf.nfields.value;i++) {
                    437:         if (eval('vf.f'+i+'.selectedIndex')==9) {
                    438:             eval('vf.f'+i+'.selectedIndex=0;')
                    439:         }
                    440:     }
                    441: }
                    442: 
                    443: ENDPICK
                    444: }
                    445: 
1.50      matthew   446: ###############################################################
                    447: ###############################################################
                    448: sub upload_manager_javascript_reverse_associate {
1.24      albertel  449:     return(<<ENDPICK);
                    450: function verify(vf) {
                    451:     var founduname=0;
                    452:     var foundpwd=0;
                    453:     var foundname=0;
                    454:     var foundid=0;
                    455:     var foundsec=0;
                    456:     var tw;
                    457:     for (i=0;i<=vf.nfields.value;i++) {
                    458:         tw=eval('vf.f'+i+'.selectedIndex');
                    459:         if (i==0 && tw!=0) { founduname=1; }
                    460:         if (((i>=1) && (i<=5)) && tw!=0 ) { foundname=1; }
                    461:         if (i==6 && tw!=0) { foundid=1; }
                    462:         if (i==7 && tw!=0) { foundsec=1; }
                    463:         if (i==8 && tw!=0) { foundpwd=1; }
                    464:     }
                    465:     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
                    466: }
                    467: 
                    468: function flip(vf,tf) {
                    469:    var nw=eval('vf.f'+tf+'.selectedIndex');
                    470:    var i;
                    471:    // picked the all one one name field, reset the other name ones to blank
                    472:    if (tf==1 && nw!=0) {
                    473:       for (i=2;i<=5;i++) {
                    474:          eval('vf.f'+i+'.selectedIndex=0;')
                    475:       }
                    476:    }
                    477:    //picked one of the piecewise name fields, reset the all in
                    478:    //one field to blank
                    479:    if ((tf>=2) && (tf<=5) && (nw!=0)) {
                    480:       eval('vf.f1.selectedIndex=0;')
                    481:    }
                    482:    // intial password specified, pick internal authentication
                    483:    if (tf==8 && nw!=0) {
1.28      matthew   484:        changed_radio('int',document.studentform);
                    485:        set_auth_radio_buttons('int',document.studentform);
                    486:        vf.krbarg.value='';
                    487:        vf.intarg.value='';
1.24      albertel  488:        vf.locarg.value='';
                    489:    }
                    490: }
                    491: 
                    492: function clearpwd(vf) {
                    493:     var i;
                    494:     if (eval('vf.f8.selectedIndex')!=0) {
                    495:         eval('vf.f8.selectedIndex=0;')
                    496:     }
                    497: }
1.2       www       498: ENDPICK
1.23      albertel  499: }
1.10      www       500: 
1.50      matthew   501: ###############################################################
                    502: ###############################################################
                    503: sub print_upload_manager_footer {
1.23      albertel  504:     my ($r,$i,$keyfields,$defdom,$today,$halfyear)=@_;
1.64      albertel  505: 
                    506:     my ($krbdef,$krbdefdom) =
                    507:         &Apache::loncommon::get_kerberos_defaults($defdom);
                    508:     my %param = ( formname => 'document.studentform',
                    509:                   kerb_def_dom => $krbdefdom,
                    510:                   kerb_def_auth => $krbdef
                    511:                   );
1.28      matthew   512:     my $krbform = &Apache::loncommon::authform_kerberos(%param);
                    513:     my $intform = &Apache::loncommon::authform_internal(%param);
                    514:     my $locform = &Apache::loncommon::authform_local(%param);
1.31      matthew   515:     my $domform = &domain_form($defdom);
1.68      matthew   516:     my $date_table = &date_setting_table();
1.90      matthew   517:     my $Str = "</table>\n";
                    518:     $Str .= &hidden_input('nfields',$i);
                    519:     $Str .= &hidden_input('keyfields',$keyfields);
                    520:     $Str .= '<h3>'.&mt('Login Type')."</h3>\n";
                    521:     $Str .= "<p>\n".
                    522:         &mt('Note: this will not take effect if the user already exists').
                    523:         "</p><p>\n";
                    524:     $Str .= $krbform."\n</p><p>\n".
                    525:         $intform."\n</p><p>\n".
                    526:         $locform."\n</p>\n";
                    527:     $Str .= '<h3>'.&mt('LON-CAPA Domain for Students')."</h3>\n";
                    528:     $Str .= "<p>\n".&mt('LON-CAPA domain: [_1]',$domform)."\n</p>\n";
                    529:     $Str .= "<h3>".&mt('Starting and Ending Dates')."</h3>\n";
                    530:     $Str .= "<p>\n".$date_table."</p>\n";
                    531:     $Str .= "<h3>".&mt('Full Update')."</h3>\n";
                    532:     $Str .= '<input type="checkbox" name="fullup" value="yes">'.
                    533:         ' '.&mt('Full update (also print list of users not enrolled anymore)').
                    534:         "</p>\n";
                    535:     $Str .= "<h3>".&mt('Student Number')."</h3>\n";
                    536:     $Str .= "<p>\n".'<input type="checkbox" name="forceid" value="yes">';
                    537:     $Str .= &mt('Disable ID/Student Number Safeguard and Force Change '.
                    538:                 'of Conflicting IDs (only do if you know what you are doing)').
                    539:                 "\n</p><p>\n";
                    540:     $Str .= '<input type="button" onClick="javascript:verify(this.form)" '.
1.95    ! albertel  541:         'value="Update Class List" />'."<br />\n";
1.90      matthew   542:     $Str .= &mt('Note: for large courses, this operation may be time '.
                    543:                 'consuming');
                    544:     $r->print($Str);
                    545:     return;
1.23      albertel  546: }
1.24      albertel  547: 
1.90      matthew   548: ###############################################################
                    549: ###############################################################
1.50      matthew   550: sub print_upload_manager_form {
1.23      albertel  551:     my $r=shift;
1.82      www       552:     my $firstLine;
1.24      albertel  553:     my $datatoken;
                    554:     if (!$ENV{'form.datatoken'}) {
1.90      matthew   555:         $datatoken=&Apache::loncommon::upfile_store($r);
1.24      albertel  556:     } else {
1.90      matthew   557:         $datatoken=$ENV{'form.datatoken'};
                    558:         &Apache::loncommon::load_tmp_file($r);
1.24      albertel  559:     }
                    560:     my @records=&Apache::loncommon::upfile_record_sep();
1.90      matthew   561:     if($ENV{'form.noFirstLine'}){
                    562:         $firstLine=shift(@records);
                    563:     }
1.23      albertel  564:     my $total=$#records;
                    565:     my $distotal=$total+1;
                    566:     my $today=time;
                    567:     my $halfyear=$today+15552000;
1.85      matthew   568:     my $defdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
1.64      albertel  569:     my ($krbdef,$krbdefdom) =
                    570:         &Apache::loncommon::get_kerberos_defaults($defdom);
1.50      matthew   571:     &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom);
1.24      albertel  572:     my $i;
                    573:     my $keyfields;
1.23      albertel  574:     if ($total>=0) {
1.90      matthew   575:         my @field=(['username',&mt('Username')],
                    576:                    ['names',&mt('Last Name, First Names')],
                    577:                    ['fname',&mt('First Name')],
                    578:                    ['mname',&mt('Middle Names/Initials')],
                    579:                    ['lname',&mt('Last Name')],
                    580:                    ['gen',&mt('Generation')],
                    581:                    ['id',&mt('ID/Student Number')],
                    582:                    ['sec',&mt('Group/Section')],
                    583:                    ['ipwd',&mt('Initial Password')],
                    584:                    ['email',&mt('EMail Address')]);
1.24      albertel  585: 	if ($ENV{'form.upfile_associate'} eq 'reverse') {	
                    586: 	    &Apache::loncommon::csv_print_samples($r,\@records);
1.90      matthew   587: 	    $i=&Apache::loncommon::csv_print_select_table($r,\@records,
                    588:                                                           \@field);
                    589: 	    foreach (@field) { 
                    590:                 $keyfields.=$_->[0].','; 
                    591:             }
1.24      albertel  592: 	    chop($keyfields);
                    593: 	} else {
1.90      matthew   594: 	    unshift(@field,['none','']);
                    595: 	    $i=&Apache::loncommon::csv_samples_select_table($r,\@records,
                    596:                                                             \@field);
1.24      albertel  597: 	    my %sone=&Apache::loncommon::record_sep($records[0]);
                    598: 	    $keyfields=join(',',sort(keys(%sone)));
1.23      albertel  599: 	}
                    600:     }
1.50      matthew   601:     &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear);
1.10      www       602: }
                    603: 
1.90      matthew   604: ###############################################################
                    605: ###############################################################
1.12      www       606: sub enroll_single_student {
                    607:     my $r=shift;
1.80      matthew   608:     # Remove non alphanumeric values from section
                    609:     $ENV{'form.csec'}=~s/\W//g;
1.68      matthew   610:     #
                    611:     # We do the dates first because the action of making them the defaul
                    612:     # in the course is entirely seperate from the action of enrolling the
                    613:     # student.  Also, a failure in setting the dates as default is not fatal
                    614:     # to the process of enrolling / modifying a student.
                    615:     my ($startdate,$enddate) = &get_dates_from_form();
                    616:     if ($ENV{'form.makedatesdefault'}) {
                    617:         $r->print(&make_dates_default($startdate,$enddate));
                    618:     }
                    619: 
1.94      sakharuk  620:     $r->print('<h3>'.&mt('Enrolling Student').'</h3>');
                    621:     $r->print('<p>'.&mt('Enrolling').' '.$ENV{'form.cuname'}." \@ ".
1.34      matthew   622:               $ENV{'form.lcdomain'}.'</p>');
1.12      www       623:     if (($ENV{'form.cuname'})&&($ENV{'form.cuname'}!~/\W/)&&
1.31      matthew   624:         ($ENV{'form.lcdomain'})&&($ENV{'form.lcdomain'}!~/\W/)) {
                    625:         # Deal with home server selection
                    626:         my $domain=$ENV{'form.lcdomain'};
                    627:         my $desiredhost = $ENV{'form.lcserver'};
                    628:         if (lc($desiredhost) eq 'default') {
                    629:             $desiredhost = undef;
                    630:         } else {
1.45      matthew   631:             my %home_servers =&Apache::loncommon::get_library_servers($domain);
1.31      matthew   632:             if (! exists($home_servers{$desiredhost})) {
1.94      sakharuk  633:                 $r->print('<font color="#ff0000">'.&mt('Error').':</font>'.
                    634:                           &mt('Invalid home server specified'));
1.31      matthew   635:                 return;
                    636:             }
                    637:         }
1.94      sakharuk  638:         $r->print(" ".&mt('with server')." $desiredhost :") if (defined($desiredhost));
1.31      matthew   639:         # End of home server selection logic
1.12      www       640: 	my $amode='';
                    641:         my $genpwd='';
                    642:         if ($ENV{'form.login'} eq 'krb') {
1.47      albertel  643:            $amode='krb';
                    644: 	   $amode.=$ENV{'form.krbver'};
1.28      matthew   645:            $genpwd=$ENV{'form.krbarg'};
1.12      www       646:         } elsif ($ENV{'form.login'} eq 'int') {
1.26      matthew   647:            $amode='internal';
1.28      matthew   648:            $genpwd=$ENV{'form.intarg'};
1.15      albertel  649:         }  elsif ($ENV{'form.login'} eq 'loc') {
                    650: 	    $amode='localauth';
                    651: 	    $genpwd=$ENV{'form.locarg'};
                    652: 	    if (!$genpwd) { $genpwd=" "; }
                    653: 	}
1.34      matthew   654:         my $home = &Apache::lonnet::homeserver($ENV{'form.cuname'},
                    655:                                                    $ENV{'form.lcdomain'});
                    656:         if ((($amode) && ($genpwd)) || ($home ne 'no_host')) {
1.55      matthew   657:             # Clean out any old roles the student has in this class.
1.33      matthew   658:             &modifystudent($ENV{'form.lcdomain'},$ENV{'form.cuname'},
                    659:                            $ENV{'request.course.id'},$ENV{'form.csec'},
                    660:                             $desiredhost);
1.55      matthew   661:             my $login_result = &Apache::lonnet::modifystudent
                    662:                 ($ENV{'form.lcdomain'},$ENV{'form.cuname'},
                    663:                  $ENV{'form.cstid'},$amode,$genpwd,
                    664:                  $ENV{'form.cfirst'},$ENV{'form.cmiddle'},
                    665:                  $ENV{'form.clast'},$ENV{'form.cgen'},
1.67      matthew   666:                  $ENV{'form.csec'},$enddate,
                    667:                  $startdate,$ENV{'form.forceid'},
1.55      matthew   668:                  $desiredhost);
                    669:             if ($login_result =~ /^ok/) {
                    670:                 $r->print($login_result);
1.94      sakharuk  671:                 $r->print("<p> ".&mt('If active, the new role will be available when the student next logs in to LON-CAPA.')."</p>");
1.55      matthew   672:             } else {
1.94      sakharuk  673:                 $r->print(&mt('unable to enroll').": ".$login_result);
1.55      matthew   674:             }
1.12      www       675: 	} else {
1.94      sakharuk  676:             $r->print('<p><font color="#ff0000">'.&mt('ERROR').'</font>&nbsp;');
1.79      matthew   677:             if ($amode =~ /^krb/) {
1.94      sakharuk  678:                 $r->print(&mt('Missing Kerberos domain information.').'  ');
1.79      matthew   679:             } else {
1.94      sakharuk  680:                 $r->print(&mt('Invalid login mode or password.').'  ');
1.79      matthew   681:             }
1.94      sakharuk  682:             $r->print('<b>'.&mt('Unable to enroll').' '.$ENV{'form.cuname'}.'.</b></p>');
1.79      matthew   683:         }
1.12      www       684:     } else {
1.94      sakharuk  685:         $r->print(&mt('Invalid username or domain'));
1.26      matthew   686:     }    
1.12      www       687: }
                    688: 
1.68      matthew   689: sub setup_date_selectors {
1.91      raeburn   690:     my ($starttime,$endtime,$mode) = @_;
1.68      matthew   691:     if (! defined($starttime)) {
                    692:         $starttime = time;
1.91      raeburn   693:         unless ($mode eq 'createcourse') {
                    694:             if (exists($ENV{'course.'.$ENV{'request.course.id'}.
1.68      matthew   695:                             '.default_enrollment_start_date'})) {
1.91      raeburn   696:                 $starttime = $ENV{'course.'.$ENV{'request.course.id'}.
1.68      matthew   697:                                   '.default_enrollment_start_date'};
1.91      raeburn   698:             }
1.68      matthew   699:         }
                    700:     }
                    701:     if (! defined($endtime)) {
                    702:         $endtime = time+(6*30*24*60*60); # 6 months from now, approx
1.91      raeburn   703:         unless ($mode eq 'createcourse') {
                    704:             if (exists($ENV{'course.'.$ENV{'request.course.id'}.
1.68      matthew   705:                             '.default_enrollment_end_date'})) {
1.91      raeburn   706:                 $endtime = $ENV{'course.'.$ENV{'request.course.id'}.
1.68      matthew   707:                                 '.default_enrollment_end_date'};
1.91      raeburn   708:             }
1.68      matthew   709:         }
                    710:     }
                    711:     my $startdateform = &Apache::lonhtmlcommon::date_setter('studentform',
                    712:                                                             'startdate',
                    713:                                                             $starttime);
                    714:     my $enddateform = &Apache::lonhtmlcommon::date_setter('studentform',
                    715:                                                           'enddate',
                    716:                                                           $endtime);
1.91      raeburn   717:     if ($mode eq 'createcourse') {
                    718:         $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
                    719:                                                             'startdate',
                    720:                                                             $starttime);
                    721:         $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
                    722:                                                           'enddate',
                    723:                                                           $endtime);
                    724:     }
1.68      matthew   725:     return ($startdateform,$enddateform);
                    726: }
                    727: 
                    728: sub get_dates_from_form {
                    729:     my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
                    730:     my $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate');
                    731:     if ($ENV{'form.no_end_date'}) {
                    732:         $enddate = 0;
                    733:     }
                    734:     return ($startdate,$enddate);
                    735: }
                    736: 
                    737: sub date_setting_table {
1.91      raeburn   738:     my ($starttime,$endtime,$mode) = @_;
                    739:     my ($startform,$endform)=&setup_date_selectors($starttime,$endtime,$mode);
1.68      matthew   740:     my $dateDefault = '<nobr>'.
1.94      sakharuk  741:         '<input type="checkbox" name="makedatesdefault" /> '.
                    742:         &mt('make these dates the default for future enrollment');
1.91      raeburn   743:     if ($mode eq 'createcourse') {
                    744:         $dateDefault = '&nbsp;';
                    745:     }
1.68      matthew   746:     my $perpetual = '<nobr><input type="checkbox" name="no_end_date"';
                    747:     if (defined($endtime) && $endtime == 0) {
                    748:         $perpetual .= ' checked';
                    749:     }
1.94      sakharuk  750:     $perpetual.= ' /> '.&mt('no ending date').'</nobr>';
1.68      matthew   751:     my $result = '';
                    752:     $result .= "<table>\n";
1.94      sakharuk  753:     $result .= '<tr><td align="right">'.&mt('Starting Date').'</td>'.
1.68      matthew   754:         '<td>'.$startform.'</td>'.
                    755:         '<td>'.$dateDefault.'</td>'."</tr>\n";
1.94      sakharuk  756:     $result .= '<tr><td align="right">'.&mt('Ending Date').'</td>'.
1.68      matthew   757:         '<td>'.$endform.'</td>'.
                    758:         '<td>'.$perpetual.'</td>'."</tr>\n";
                    759:     $result .= "</table>\n";
                    760:     return $result;
                    761: }
                    762: 
                    763: sub make_dates_default {
                    764:     my ($startdate,$enddate) = @_;
                    765:     my $result = '';
                    766:     my $dom = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
                    767:     my $crs = $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
                    768:     my $put_result = &Apache::lonnet::put('environment',
                    769:             {'default_enrollment_start_date'=>$startdate,
                    770:              'default_enrollment_end_date'  =>$enddate},$dom,$crs);
                    771:     if ($put_result eq 'ok') {
                    772:         $result .= "Set default start and end dates for course<br />";
1.69      matthew   773:         #
                    774:         # Refresh the course environment
                    775:         &Apache::lonnet::coursedescription($ENV{'request.course.id'});
1.68      matthew   776:     } else {
1.94      sakharuk  777:         $result .= &mt('Unable to set default dates for course').":".$put_result.
1.68      matthew   778:             '<br />';
                    779:     }
                    780:     return $result;
                    781: }
                    782: 
1.74      matthew   783: ##
                    784: ## Single student enrollment routines (some of them)
                    785: ##
                    786: sub get_student_username_domain_form {
                    787:     my $r = shift;
                    788:     my $domform = &Apache::loncommon::select_dom_form
1.85      matthew   789:         ($ENV{'course.'.$ENV{'request.course.id'}.'.domain'},'cudomain',0);
1.94      sakharuk  790:     my %lt=&Apache::lonlocal::texthash(
                    791: 		    'eos'  => "Enroll One Student",
                    792: 		    'usr'  => "Username",
                    793:                     'dom'  => "Domain",
                    794:                     'been' => "Begin Enrollment",
                    795: 				       );
1.74      matthew   796:     $r->print(<<END);
                    797: <input type="hidden" name="action" value="enrollstudent" />
                    798: <input type="hidden" name="state"  value="gotusername" />
1.94      sakharuk  799: <h3>$lt{'eos'}</h3>
1.74      matthew   800: <table>
1.94      sakharuk  801: <tr><th>$lt{'usr'}:</th>
1.74      matthew   802:     <td><input type="text" name="cuname"  size="15" /></td></tr>
1.94      sakharuk  803: <tr><th>$lt{'dom'}:</th>
1.74      matthew   804:     <td>$domform</td></tr>
                    805: <tr><th>&nbsp;</th>
                    806:     <td>
1.94      sakharuk  807:     <input type="submit" name="Begin Enrollment" value="$lt{'been'}" />
1.74      matthew   808:     </td></tr>
                    809: </table>
                    810: END
                    811:     return;
                    812: }
                    813: 
1.50      matthew   814: sub print_enroll_single_student_form {
1.10      www       815:     my $r=shift;
1.94      sakharuk  816:     $r->print("<h3>".&mt('Enroll One Student')."</h3>");
1.74      matthew   817:     #
                    818:     my $username = $ENV{'form.cuname'};
                    819:     my $domain   = $ENV{'form.cudomain'};
                    820:     my $home = &Apache::lonnet::homeserver($username,$domain);
                    821:     # $new_user flags whether we are creating a new user or using an old one
                    822:     my $new_user = 1;
                    823:     if ($home ne 'no_host') {
                    824:         $new_user = 0;
                    825:     }
                    826:     #
                    827:     my $user_data_html = '';
                    828:     my $javascript_validations = '';
                    829:     if ($new_user) {
1.85      matthew   830:         my $defdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
1.74      matthew   831:         # Set up authentication forms
                    832:         my ($krbdef,$krbdefdom) =
1.75      matthew   833:             &Apache::loncommon::get_kerberos_defaults($domain);
1.89      matthew   834:         $javascript_validations=&javascript_validations('auth',$krbdefdom);
1.74      matthew   835:         my %param = ( formname => 'document.studentform',
                    836:                       kerb_def_dom => $krbdefdom,
                    837:                       kerb_def_auth => $krbdef
                    838:                       );
                    839:         my $krbform = &Apache::loncommon::authform_kerberos(%param);
                    840:         my $intform = &Apache::loncommon::authform_internal(%param);
                    841:         my $locform = &Apache::loncommon::authform_local(%param);
                    842:         #
                    843:         # Set up domain selection form
                    844:         my $homeserver_form = '';
                    845:         my %servers = &Apache::loncommon::get_library_servers($domain);
                    846:         $homeserver_form = '<select name="lcserver" size="1">'."\n".
                    847:             '<option value="default" selected>default</option>'."\n";
                    848:         while (my ($servername,$serverdescription) = each (%servers)) {
                    849:             $homeserver_form .= '<option value="'.$servername.'">'.
                    850:                 $serverdescription."</option>\n";
                    851:         }
                    852:         $homeserver_form .= "</select>\n";
                    853:         #
                    854:         #
1.94      sakharuk  855: 	my %lt=&Apache::lonlocal::texthash(
                    856: 		       'udf'  => "User Data for",
                    857:                        'fn'   => "First Name",
                    858:                        'mn'   => "Middle Name",
                    859:                        'ln'   => "Last Name",
                    860:                        'gen'  => "Generation",
                    861:                        'hs'   => "Home Server",
                    862:                        'pswd' => "Password",
                    863: 		       'psam' => "Please select an authentication mechanism",
                    864: 					   );
1.74      matthew   865:         $user_data_html = <<END;
1.94      sakharuk  866: <h3>$lt{'udf'} $username\@$domain</h3>
1.74      matthew   867: <table>
1.94      sakharuk  868: <tr><th>$lt{'fn'}:</th>
1.74      matthew   869:     <td><input type="text" name="cfirst"  size="15"></td></tr>
1.94      sakharuk  870: <tr><th>$lt{'mn'}:</th>
1.74      matthew   871:     <td><input type="text" name="cmiddle" size="15"></td></tr>
1.94      sakharuk  872: <tr><th>$lt{'ln'}:</th>
1.74      matthew   873:     <td><input type="text" name="clast"   size="15"></td></tr>
1.94      sakharuk  874: <tr><th>$lt{'gen'}:</th>
1.74      matthew   875:     <td><input type="text" name="cgen"    size="5"> </td></tr>
1.94      sakharuk  876: <tr><th>$lt{'hs'}:</th>
1.74      matthew   877:     <td>$homeserver_form</td></tr>
                    878: </table>
1.94      sakharuk  879: <h3>$lt{'pswd'}</h3>
                    880: $lt{'psam'}
1.74      matthew   881: <table>
                    882: <p>
                    883: $krbform
1.75      matthew   884: <br />
1.74      matthew   885: $intform
1.75      matthew   886: <br />
1.74      matthew   887: $locform
                    888: </p>
                    889: END
                    890:     } else {
                    891:         # User already exists.  Do not worry about authentication
                    892:         my %uenv = &Apache::lonnet::dump('environment',$domain,$username);
1.89      matthew   893:         $javascript_validations = &javascript_validations('noauth');
1.94      sakharuk  894: 	my %lt=&Apache::lonlocal::texthash(
                    895: 		       'udf'  => "User Data for",
                    896:                        'fn'   => "First Name",
                    897:                        'mn'   => "Middle Name",
                    898:                        'ln'   => "Last Name",
                    899:                        'gen'  => "Generation",
                    900: 					   );
1.74      matthew   901:         $user_data_html = <<END;
1.94      sakharuk  902: <h3>$lt{'udf'} $username\@$domain</h3>
1.74      matthew   903: <input type="hidden" name="lcserver" value="default" />
                    904: <table>
1.94      sakharuk  905: <tr><th>$lt{'fn'}:</th>
1.74      matthew   906:     <td>
                    907:     <input type="text" name="cfirst" value="$uenv{'firstname'}" size="15" />
                    908:     </td></tr>
1.94      sakharuk  909: <tr><th>$lt{'mn'}:</th>
1.74      matthew   910:     <td>
                    911:     <input type="text" name="cmiddle" value="$uenv{'middlename'}" size="15" />
                    912:     </td></tr>
1.94      sakharuk  913: <tr><th>$lt{'ln'}:</th>
1.74      matthew   914:     <td>
                    915:     <input type="text" name="clast"value="$uenv{'lastname'}" size="15" />
                    916:     </td></tr>
1.94      sakharuk  917: <tr><th>$lt{'gen'}:</th>
1.74      matthew   918:     <td>
                    919:     <input type="text" name="cgen" value="$uenv{'generation'}" size="5" />
                    920:     </td></tr>
                    921: </table>
                    922: END
                    923:     }
1.68      matthew   924:     my $date_table = &date_setting_table();
1.74      matthew   925:         # Print it all out
1.94      sakharuk  926:     my %lt=&Apache::lonlocal::texthash(
                    927: 		   'cd'   => "Course Data",
                    928:                    'gs'   => "Group/Section",
                    929:                    'idsn' => "ID/Student Number",
                    930:                    'disn' => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                    931:                    'eas'  => "Enroll as student",
                    932: 				       );
1.50      matthew   933:     $r->print(<<END);
1.74      matthew   934: <input type="hidden" name="action" value="enrollstudent" />
                    935: <input type="hidden" name="state"  value="done" />
                    936: <input type="hidden" name="cuname" value="$username" />
                    937: <input type="hidden" name="lcdomain" value="$domain" />
1.28      matthew   938: <script type="text/javascript" language="Javascript">
1.12      www       939: function verify(vf) {
                    940:     var founduname=0;
                    941:     var foundpwd=0;
                    942:     var foundname=0;
                    943:     var foundid=0;
                    944:     var foundsec=0;
                    945:     var tw;
1.26      matthew   946:     if ((typeof(vf.cuname.value) !="undefined") && (vf.cuname.value!='') && 
1.31      matthew   947: 	(typeof(vf.lcdomain.value)!="undefined") && (vf.lcdomain.value!='')) {
1.12      www       948:         founduname=1;
                    949:     }
1.14      harris41  950:     if ((typeof(vf.cfirst.value)!="undefined") && (vf.cfirst.value!='') &&
1.26      matthew   951: 	(typeof(vf.clast.value) !="undefined") && (vf.clast.value!='')) {
1.12      www       952:         foundname=1;
                    953:     }
1.14      harris41  954:     if ((typeof(vf.csec.value)!="undefined") && (vf.csec.value!='')) {
1.12      www       955:         foundsec=1;
                    956:     }
1.14      harris41  957:     if ((typeof(vf.cstid.value)!="undefined") && (vf.cstid.value!='')) {
1.12      www       958: 	foundid=1;
                    959:     }
                    960:     if (founduname==0) {
                    961: 	alert('You need to specify at least the username and domain fields');
                    962:         return;
                    963:     }
1.24      albertel  964:     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
1.12      www       965: }
                    966: 
1.24      albertel  967: $javascript_validations
1.12      www       968: 
1.24      albertel  969: function clearpwd(vf) {
                    970:     //nothing else needs clearing
1.15      albertel  971: }
                    972: 
1.12      www       973: </script>
1.11      www       974: 
1.74      matthew   975: $user_data_html
1.50      matthew   976: 
1.94      sakharuk  977: <h3>$lt{'cd'}</h3>
1.50      matthew   978: 
1.94      sakharuk  979: <p>$lt{'gs'}: <input type="text" name="csec" size="5" />
1.50      matthew   980: <p>
1.68      matthew   981: $date_table
1.50      matthew   982: </p>
1.94      sakharuk  983: <h3>$lt{'idsn'}</h3>
1.50      matthew   984: <p>
1.94      sakharuk  985: $lt{'idsn'}: <input type="text" name="cstid" size="10">
1.26      matthew   986: </p><p>
                    987: <input type="checkbox" name="forceid" value="yes"> 
1.94      sakharuk  988: $lt{'disn'}
1.50      matthew   989: </p><p>
1.94      sakharuk  990: <input type="button" onClick="verify(this.form)" value="$lt{'eas'}">
1.26      matthew   991: </p>
1.50      matthew   992: END
                    993:     return;
1.10      www       994: }
                    995: 
                    996: # ========================================================= Menu Phase Two Drop
1.51      matthew   997: sub print_drop_menu {
1.10      www       998:     my $r=shift;
1.92      sakharuk  999:     $r->print("<h3>".&mt('Drop Students')."</h3>");
1.11      www      1000:     my $cid=$ENV{'request.course.id'};
1.56      matthew  1001:     my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();
                   1002:     if (! defined($classlist)) {
1.94      sakharuk 1003:         $r->print(&mt('There are no students currently enrolled.')."\n");
1.51      matthew  1004:         return;
1.25      matthew  1005:     }
1.51      matthew  1006:     # Print out the available choices
1.56      matthew  1007:     &show_drop_list($r,$classlist,$keylist);
1.51      matthew  1008:     return;
1.11      www      1009: }
                   1010: 
1.40      matthew  1011: # ============================================== view classlist
1.50      matthew  1012: sub print_html_classlist {
1.40      matthew  1013:     my $r=shift;
1.57      matthew  1014:     if (! exists($ENV{'form.sortby'})) {
                   1015:         $ENV{'form.sortby'} = 'username';
                   1016:     }
1.59      matthew  1017:     if ($ENV{'form.Status'} !~ /^(Any|Expired|Active)$/) {
1.57      matthew  1018:         $ENV{'form.Status'} = 'Active';
                   1019:     }
                   1020:     my $status_select = &Apache::lonhtmlcommon::StatusOptions
                   1021:         ($ENV{'form.Status'},'studentform');
1.94      sakharuk 1022:     my $CCL=&mt('Current Class List');
1.48      matthew  1023:     $r->print(<<END);
1.58      matthew  1024: <input type="hidden" name="action" value="$ENV{'form.action'}" />
1.57      matthew  1025: <input type="hidden" name="state"  value="" />
1.50      matthew  1026: <p>
1.94      sakharuk 1027: <font size="+1">$CCL</font>
1.57      matthew  1028: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
1.59      matthew  1029: END
                   1030:     if ($ENV{'form.action'} ne 'modifystudent') {
1.94      sakharuk 1031: 	my %lt=&Apache::lonlocal::texthash(
                   1032: 		   'ef'   => "Excel format",
                   1033:                    'ss'   => "Student Status",
                   1034: 					   );
1.59      matthew  1035:         $r->print(<<END);
1.57      matthew  1036: <font size="+1">
                   1037: <a href="javascript:document.studentform.state.value='csv';document.studentform.submit();">CSV format</a>
1.61      matthew  1038: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
1.94      sakharuk 1039: <a href="javascript:document.studentform.state.value='excel';document.studentform.submit();">$lt{'ef'}</a>
1.57      matthew  1040: </font>
                   1041: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
1.94      sakharuk 1042: $lt{'ss'}:
1.48      matthew  1043: END
1.59      matthew  1044:     }
                   1045:     $r->print($status_select."</p>\n");
1.40      matthew  1046:     my $cid=$ENV{'request.course.id'};
1.56      matthew  1047:     my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                   1048:     if (! defined($classlist)) {
1.94      sakharuk 1049:         $r->print(&mt('There are no students currently enrolled.')."\n");
1.40      matthew  1050:     } else {
                   1051:         # Print out the available choices
1.50      matthew  1052:         if ($ENV{'form.action'} eq 'modifystudent') {
1.53      matthew  1053:             &show_class_list($r,'view','modify','modifystudent',
1.57      matthew  1054:                              $ENV{'form.Status'},$classlist,$keylist);
1.50      matthew  1055:         } else {
1.53      matthew  1056:             &show_class_list($r,'view','aboutme','classlist',
1.57      matthew  1057:                              $ENV{'form.Status'},$classlist,$keylist);
1.50      matthew  1058:         }
1.41      matthew  1059:     }
                   1060: }
                   1061: 
                   1062: # ============================================== view classlist
1.60      matthew  1063: sub print_formatted_classlist {
1.41      matthew  1064:     my $r=shift;
1.60      matthew  1065:     my $mode = shift;
1.41      matthew  1066:     my $cid=$ENV{'request.course.id'};
1.56      matthew  1067:     my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                   1068:     if (! defined($classlist)) {
1.94      sakharuk 1069:         $r->print(&mt('There are no students currently enrolled.')."\n");
1.41      matthew  1070:     } else {
1.60      matthew  1071:         &show_class_list($r,$mode,'nolink','csv',
1.57      matthew  1072:                          $ENV{'form.Status'},$classlist,$keylist);
1.40      matthew  1073:     }
                   1074: }
                   1075: 
                   1076: # =================================================== Show student list to drop
                   1077: sub show_class_list {
1.56      matthew  1078:     my ($r,$mode,$linkto,$action,$statusmode,$classlist,$keylist)=@_;
1.40      matthew  1079:     my $cid=$ENV{'request.course.id'};
1.60      matthew  1080:     #
                   1081:     # Variables for excel output
                   1082:     my ($excel_workbook, $excel_sheet, $excel_filename,$row);
                   1083:     #
1.53      matthew  1084:     my $sortby = $ENV{'form.sortby'};
                   1085:     if ($sortby !~ /^(username|domain|section|fullname|id)$/) {
                   1086:         $sortby = 'username';
                   1087:     }
1.42      matthew  1088:     # Print out header 
1.41      matthew  1089:     if ($mode eq 'view') {
1.50      matthew  1090:         if ($linkto eq 'aboutme') {
1.94      sakharuk 1091:             $r->print(&mt('Select a user name to view the users personal page.'));
1.50      matthew  1092:         } elsif ($linkto eq 'modify') {
1.94      sakharuk 1093:             $r->print(&mt('Select a user name to modify the students information'));
1.50      matthew  1094:         }
1.94      sakharuk 1095: 	my %lt=&Apache::lonlocal::texthash(
                   1096: 	               'usrn'   => "username",
                   1097:                        'dom'    => "domain",
                   1098:                        'sn'     => "student name",
                   1099:                        'sec'    => "section",
                   1100: 					   );
1.41      matthew  1101:         $r->print(<<END);
1.59      matthew  1102: 
1.53      matthew  1103: <input type="hidden" name="sortby" value="$sortby" />
1.59      matthew  1104: <input type="hidden" name="sname"  value="" />
                   1105: <input type="hidden" name="sdom"   value="" />
1.40      matthew  1106: <p>
                   1107: <table border=2>
1.53      matthew  1108: <tr><th>
1.94      sakharuk 1109:        <a href="javascript:document.studentform.sortby.value='username';document.studentform.submit();">$lt{'usrn'}</a>
1.53      matthew  1110:     </th><th>
1.94      sakharuk 1111:        <a href="javascript:document.studentform.sortby.value='domain';document.studentform.submit();">$lt{'dom'}</a>
1.53      matthew  1112:     </th><th>
1.57      matthew  1113:        <a href="javascript:document.studentform.sortby.value='id';document.studentform.submit();">ID</a>
1.53      matthew  1114:     </th><th>
1.94      sakharuk 1115:        <a href="javascript:document.studentform.sortby.value='fullname';document.studentform.submit();">$lt{'sn'}</a>
1.53      matthew  1116:     </th><th>
1.94      sakharuk 1117:        <a href="javascript:document.studentform.sortby.value='section';document.studentform.submit();">$lt{'sec'}</a>
1.53      matthew  1118:     </th>
                   1119: </tr>
1.40      matthew  1120: END
1.41      matthew  1121:     } elsif ($mode eq 'csv') {
1.58      matthew  1122:         if($statusmode eq 'Expired') {
1.94      sakharuk 1123:             $r->print(&mt('Students with expired roles'));
1.58      matthew  1124:         }
                   1125:         if ($statusmode eq 'Any') {
1.94      sakharuk 1126:             $r->print('"'.join('","',(&mt("username"),&mt("domain"),"ID",
                   1127:                       &mt("student name"),&mt("section"),&mt("status"))).
                   1128:                       '"'."\n");
1.58      matthew  1129:         } else {
1.94      sakharuk 1130:             $r->print('"'.join('","',(&mt("username"),&mt("domain"),"ID",
                   1131:                       &mt("student name"),&mt("section"))).'"'."\n");
1.58      matthew  1132:         }
1.60      matthew  1133:     } elsif ($mode eq 'excel') {
                   1134:         # Create the excel spreadsheet
                   1135:         $excel_filename = '/prtspool/'.
                   1136:             $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
                   1137:                 time.'_'.rand(1000000000).'.xls';
                   1138:         $excel_workbook = Spreadsheet::WriteExcel->new('/home/httpd'.
                   1139:                                                        $excel_filename);
                   1140:         $excel_workbook->set_tempdir('/home/httpd/perl/tmp');
                   1141:         $excel_sheet = $excel_workbook->addworksheet('classlist');
                   1142:         #
1.76      albertel 1143:         my $description = 'Class List for '.
1.60      matthew  1144:             $ENV{'course.'.$ENV{'request.course.id'}.'.description'};
                   1145:         $excel_sheet->write($row++,0,$description);
                   1146:         #
                   1147:         $excel_sheet->write($row++,0,["username","domain","ID",
                   1148:                                       "student name","section","status"]);
1.41      matthew  1149:     }
1.56      matthew  1150:     #
                   1151:     # Sort the students
                   1152:     my %index;
                   1153:     my $i;
                   1154:     foreach (@$keylist) {
                   1155:         $index{$_} = $i++;
                   1156:     }
                   1157:     my $index  = $index{$sortby};
                   1158:     my $second = $index{'username'};
                   1159:     my $third  = $index{'domain'};
1.53      matthew  1160:     my @Sorted_Students = sort {
1.56      matthew  1161:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   1162:             ||
                   1163:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   1164:             ||
                   1165:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   1166:         } (keys(%$classlist));
1.53      matthew  1167:     foreach my $student (@Sorted_Students) {
1.56      matthew  1168:         my $username = $classlist->{$student}->[$index{'username'}];
                   1169:         my $domain   = $classlist->{$student}->[$index{'domain'}];
                   1170:         my $section  = $classlist->{$student}->[$index{'section'}];
                   1171:         my $name     = $classlist->{$student}->[$index{'fullname'}];
                   1172:         my $id       = $classlist->{$student}->[$index{'id'}];
                   1173:         my $status   = $classlist->{$student}->[$index{'status'}];
1.57      matthew  1174:         next if (($statusmode ne 'Any') && ($status ne $statusmode));
1.51      matthew  1175:         if ($mode eq 'view') {
                   1176:             $r->print("<tr>\n    <td>\n        ");
                   1177:             if ($linkto eq 'nothing') {
                   1178:                 $r->print($username);
                   1179:             } elsif ($linkto eq 'aboutme') {
                   1180:                 $r->print(&Apache::loncommon::aboutmewrapper($username,
                   1181:                                                              $username,
                   1182:                                                              $domain));
                   1183:             } elsif ($linkto eq 'modify') {
1.59      matthew  1184:                 $r->print('<a href="'.
                   1185:                           "javascript:document.studentform.sname.value='".
                   1186:                           $username.
                   1187:                           "';document.studentform.sdom.value='".$domain.
                   1188:                           "';document.studentform.state.value='selected".
                   1189:                           "';document.studentform.submit();".'">'.
1.53      matthew  1190:                           $username."</a>\n");
1.50      matthew  1191:             }
1.51      matthew  1192:             $r->print(<<"END");
1.50      matthew  1193:     </td>
1.51      matthew  1194:     <td>$domain</td>
                   1195:     <td>$id</td>
                   1196:     <td>$name</td>
                   1197:     <td>$section</td>
1.40      matthew  1198: </tr>
                   1199: END
1.51      matthew  1200:         } elsif ($mode eq 'csv') {
                   1201:             # no need to bother with $linkto
                   1202:             my @line = ();
                   1203:             foreach ($username,$domain,$id,$name,$section) {
                   1204:                 push @line,&Apache::loncommon::csv_translate($_);
1.58      matthew  1205:             }
                   1206:             if ($statusmode eq 'Any') {
                   1207:                 push @line,&Apache::loncommon::csv_translate($status);
1.41      matthew  1208:             }
1.51      matthew  1209:             my $tmp = $";
                   1210:             $" = '","';
                   1211:             $r->print("\"@line\"\n");
                   1212:             $" = $tmp;
1.60      matthew  1213:         } elsif ($mode eq 'excel') {
                   1214:             $excel_sheet->write($row++,0,[$username,$domain,$id,
                   1215:                                           $name,$section,$status]);
1.40      matthew  1216:         }
                   1217:     }
1.60      matthew  1218:     if ($mode eq 'view') {
                   1219:         $r->print('</table><br>');
                   1220:     } elsif ($mode eq 'excel') {
                   1221:         $excel_workbook->close();
                   1222:         $r->print('<p><a href="'.$excel_filename.'">'.
1.94      sakharuk 1223:                   &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n");
1.60      matthew  1224:     }
1.40      matthew  1225: }
                   1226: 
1.50      matthew  1227: 
                   1228: #
                   1229: # print out form for modification of a single students data
                   1230: #
                   1231: sub print_modify_student_form {
                   1232:     my $r = shift();
                   1233:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.59      matthew  1234:                                             ['sdom','sname']);    
1.53      matthew  1235:     my $sname  = $ENV{'form.sname'};
                   1236:     my $sdom   = $ENV{'form.sdom'};
                   1237:     my $sortby = $ENV{'form.sortby'};
1.50      matthew  1238:     # determine the students name information
                   1239:     my %info=&Apache::lonnet::get('environment',
                   1240:                                   ['firstname','middlename',
1.52      matthew  1241:                                    'lastname','generation','id'],
1.50      matthew  1242:                                   $sdom, $sname);
                   1243:     my ($tmp) = keys(%info);
                   1244:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94      sakharuk 1245:         $r->print('<font color="#ff0000" size="+2">'.&mt('Error').'</font>'.
1.50      matthew  1246:                   '<p>'.
1.94      sakharuk 1247:                   &mt('Unable to retrieve environment data for').' '.$sname.
                   1248:                   &mt('in domain').' '.$sdom.'</p><p>'.
                   1249:                   &mt('Please contact your LON-CAPA administrator regarding this situation.').'</p></body></html>');
1.50      matthew  1250:         return;
                   1251:     }
                   1252:     # determine the students starting and ending times and section
                   1253:     my ($starttime,$endtime,$section) = &get_enrollment_data($sname,$sdom);
1.87      matthew  1254:     if ($starttime =~ /^error/) {
1.94      sakharuk 1255:         $r->print('<h2>'&mt('Error').'</h2>');
1.87      matthew  1256:         $r->print('<p>'.$starttime.'</p>');
                   1257:         return;
                   1258:     }
1.50      matthew  1259:     # Deal with date forms
1.68      matthew  1260:     my $date_table = &date_setting_table($starttime,$endtime);
1.59      matthew  1261:     #
                   1262:     if (! exists($ENV{'form.Status'}) || 
                   1263:         $ENV{'form.Status'} !~ /^(Any|Expired|Active)$/) {
                   1264:         $ENV{'form.Status'} = 'crap';
                   1265:     }
1.94      sakharuk 1266:     # Make sure student is enrolled in course
                   1267:     my %lt=&Apache::lonlocal::texthash(
                   1268: 	           'mef'   => "Modify Enrollment for",
                   1269:                    'odcc'  => "Only domain coordinators can change a users password.",
                   1270:                    'sn'    => "Student Name",
                   1271:                    'fn'    => "First",
                   1272:                    'mn'    => "Middle",
                   1273:                    'ln'    => "Last",
                   1274:                    'gen'   => "Generation",
                   1275:                    'sid'   => "Student ID",
                   1276:                    'disn'  => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                   1277:                    'sec'   => "Section",
                   1278:                    'sm'    => "Submit Modifications",
                   1279: 				       );
1.50      matthew  1280:     $r->print(<<END);
1.52      matthew  1281: <p>
                   1282: <font size="+1">
1.94      sakharuk 1283: $lt{'odcc'}
1.52      matthew  1284: </font>
                   1285: </p>
1.50      matthew  1286: <input type="hidden" name="slogin"  value="$sname"  />
                   1287: <input type="hidden" name="sdomain" value="$sdom" />
                   1288: <input type="hidden" name="action"  value="modifystudent" />
1.53      matthew  1289: <input type="hidden" name="state"   value="done" />
                   1290: <input type="hidden" name="sortby"  value="$sortby" />
1.59      matthew  1291: <input type="hidden" name="Status"  value="$ENV{'form.Status'}" />
                   1292: 
1.94      sakharuk 1293: <h2>$lt{'mef'} $info{'firstname'} $info{'middlename'} 
1.50      matthew  1294: $info{'lastname'} $info{'generation'}, $sname\@$sdom</h2>
                   1295: <p>
1.94      sakharuk 1296: <b>$lt{'sn'}</b>
1.50      matthew  1297: <table>
1.94      sakharuk 1298: <tr><th>$lt{'fn'}</th><th>$lt{'mn'}</th><th>$lt{'ln'}</th><th>$lt{'gen'}</th></tr>
1.50      matthew  1299: <tr><td>
                   1300: <input type="text" name="firstname"  value="$info{'firstname'}"  /></td><td>
                   1301: <input type="text" name="middlename" value="$info{'middlename'}" /></td><td>
                   1302: <input type="text" name="lastname"   value="$info{'lastname'}"   /></td><td>
                   1303: <input type="text" name="generation" value="$info{'generation'}" /></td></tr>
                   1304: </table>
                   1305: </p><p>
1.94      sakharuk 1306: <b>$lt{'sid'}</b>: <input type="text" name="id" value="$info{'id'}" size="12"/>
1.52      matthew  1307: </p><p>
1.53      matthew  1308: <input type="checkbox" name="forceid" > 
1.94      sakharuk 1309: $lt{'disn'}
1.53      matthew  1310: </p><p>
1.94      sakharuk 1311: <b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="4"/>
1.50      matthew  1312: </p>
1.68      matthew  1313: <p>$date_table</p>
1.94      sakharuk 1314: <input type="submit" value="$lt{'sm'}" />
1.50      matthew  1315: </body></html>
                   1316: END
                   1317:     return;
                   1318: }
                   1319: 
                   1320: #
                   1321: # modify a single students section 
                   1322: #
                   1323: sub modify_single_student {
                   1324:     my $r = shift;
1.68      matthew  1325:     #
1.80      matthew  1326:     # Remove non alphanumeric values from the section
                   1327:     $ENV{'form.section'} =~ s/\W//g;
1.77      matthew  1328:     #
1.68      matthew  1329:     # Do the date defaults first
                   1330:     my ($starttime,$endtime) = &get_dates_from_form();
                   1331:     if ($ENV{'form.makedatesdefault'}) {
                   1332:         $r->print(&make_dates_default($starttime,$endtime));
                   1333:     }
1.59      matthew  1334:     # Get the 'sortby' and 'Status' variables so the user goes back to their
                   1335:     # previous screen
1.53      matthew  1336:     my $sortby = $ENV{'form.sortby'};
1.59      matthew  1337:     my $status = $ENV{'form.Status'};
1.53      matthew  1338:     #
                   1339:     # We always need this information
                   1340:     my $slogin     = $ENV{'form.slogin'};
                   1341:     my $sdom       = $ENV{'form.sdomain'};
                   1342:     #
                   1343:     # Get the old data
                   1344:     my %old=&Apache::lonnet::get('environment',
                   1345:                                  ['firstname','middlename',
                   1346:                                   'lastname','generation','id'],
                   1347:                                  $sdom, $slogin);
1.59      matthew  1348:     $old{'section'} = &Apache::lonnet::getsection($sdom,$slogin,
                   1349:                                                   $ENV{'request.course.id'});
1.53      matthew  1350:     my ($tmp) = keys(%old);
                   1351:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94      sakharuk 1352:         $r->print(&mt('There was an error determining the environment values for')." $slogin \@ $sdom.");
1.53      matthew  1353:         return;
                   1354:     }
                   1355:     undef $tmp;
                   1356:     #
                   1357:     # Get the new data
1.50      matthew  1358:     my $firstname  = $ENV{'form.firstname'};
                   1359:     my $middlename = $ENV{'form.middlename'};
                   1360:     my $lastname   = $ENV{'form.lastname'};
                   1361:     my $generation = $ENV{'form.generation'};
                   1362:     my $section    = $ENV{'form.section'};
                   1363:     my $courseid   = $ENV{'request.course.id'};
1.52      matthew  1364:     my $sid        = $ENV{'form.id'};
1.50      matthew  1365:     my $displayable_starttime = localtime($starttime);
                   1366:     my $displayable_endtime   = localtime($endtime);
1.53      matthew  1367:     # 
                   1368:     # check for forceid override
1.63      matthew  1369:     if ((defined($old{'id'})) && ($old{'id'} ne '') && 
                   1370:         ($sid ne $old{'id'}) && (! exists($ENV{'form.forceid'}))) {
1.94      sakharuk 1371:         $r->print("<font color=\"ff0000\">".&mt('You changed the students id but did not disable the ID change safeguard. The students id will not be changed.')."</font>");
1.53      matthew  1372:         $sid = $old{'id'};
                   1373:     }
                   1374:     #
1.50      matthew  1375:     # talk to the user about what we are going to do
1.94      sakharuk 1376:     my %lt=&Apache::lonlocal::texthash(
                   1377: 	           'mdu'   => "Modifying data for user",
                   1378:                    'si'    => "Student Information",
                   1379:                    'fd'    => "Field",
                   1380:                    'ov'    => "Old Value",
                   1381:                    'nv'    => "New Value",
                   1382:                    'fn'    => "First name",
                   1383:                    'mn'    => "Middle name",
                   1384:                    'ln'    => "Last name",
                   1385:                    'gen'   => "Generation",
                   1386:                    'sec'   => "Section",
                   1387:                    'ri'    => "Role Information",
                   1388:                    'st'    => "Start Time",
                   1389:                    'et'    => "End Time",
                   1390: 				       );
1.50      matthew  1391:     $r->print(<<END);
1.94      sakharuk 1392:     <h2>$lt{'mdu'} $slogin \@ $sdom </h2>
                   1393: <h3>$lt{'si'}</h3>
1.53      matthew  1394: <table rules="rows" border="1" cellpadding="3" >
                   1395: <tr>
1.94      sakharuk 1396:     <th> $lt{'fd'} </th>
                   1397:     <th> $lt{'ov'} </th>
                   1398:     <th> $lt{'nv'} </th>
1.53      matthew  1399: </tr>
                   1400: <tr>
1.94      sakharuk 1401:     <td> <b>$lt{'fn'}</b> </td>
1.53      matthew  1402:     <td> $old{'firstname'} </td>
                   1403:     <td> $firstname </td>
                   1404: </tr><tr>
1.94      sakharuk 1405:     <td> <b>$lt{'mn'}</b> </td>
1.53      matthew  1406:     <td> $old{'middlename'} </td>
                   1407:     <td> $middlename </td>
                   1408: </tr><tr>
1.94      sakharuk 1409:     <td> <b>$lt{'ln'}</b> </td>
1.53      matthew  1410:     <td> $old{'lastname'} </td>
                   1411:     <td> $lastname </td>
                   1412: </tr><tr>
1.94      sakharuk 1413:     <td> <b>$lt{'gen'}</b> </td>
1.53      matthew  1414:     <td> $old{'generation'} </td>
                   1415:     <td> $generation </td>
                   1416: </tr><tr>
                   1417:     <td> <b>ID</b> </td>
                   1418:     <td> $old{'id'} </td>
                   1419:     <td> $sid </td>
1.59      matthew  1420: </tr><tr>
1.94      sakharuk 1421:     <td> <b>$lt{'sec'}</b> </td>
1.59      matthew  1422:     <td> $old{'section'} </td>
                   1423:     <td> $section</td>
1.53      matthew  1424: </tr>
1.50      matthew  1425: </table>
1.94      sakharuk 1426: <h3>$lt{'ri'}</h3>
1.50      matthew  1427: <table>
1.94      sakharuk 1428: <tr><td align="right"><b>$lt{'st'}:</b></td><td> $displayable_starttime </td></tr>
                   1429: <tr><td align="right"><b>$lt{'et'}:</b></td><td> $displayable_endtime   </td></tr>
1.50      matthew  1430: </table>
1.52      matthew  1431: <p>
1.50      matthew  1432: END
1.53      matthew  1433:     #
1.63      matthew  1434:     # Send request(s) to modify data (final undef is for 'desiredhost',
                   1435:     # which is a moot point because the student already has an account.
                   1436:     my $modify_section_results = &modifystudent($sdom,$slogin,
                   1437:                                                 $ENV{'request.course.id'},
                   1438:                                                 $section,undef);
                   1439:     if ($modify_section_results !~ /^ok/) {
1.94      sakharuk 1440:         $r->print(&mt('An error occured during the attempt to change the section for this student.')."<br />");
1.63      matthew  1441:     }
1.52      matthew  1442:     my $roleresults = &Apache::lonnet::modifystudent
1.53      matthew  1443:         ($sdom,$slogin,$sid,undef,undef,$firstname,$middlename,$lastname,
                   1444:          $generation,$section,$endtime,$starttime,$ENV{'form.forceid'});
                   1445:     if ($roleresults eq 'refused' ) {
1.94      sakharuk 1446:         $r->print(&mt('Your request to change the role information for this student was refused. You do not appear to have sufficient authority to change student information.'));
1.50      matthew  1447:     } elsif ($roleresults !~ /ok/) {
1.94      sakharuk 1448:         $r->print(&mt('An error occurred during the attempt to change the role information for this student.')."  <br />".
                   1449:                   &mt('The error reported was')." ".
1.50      matthew  1450:                   $roleresults);
1.53      matthew  1451:         &Apache::lonnet::logthis("londropadd:failed attempt to modify student".
                   1452:                                  " data for ".$slogin." \@ ".$sdom." by ".
                   1453:                                  $ENV{'user.name'}." \@ ".$ENV{'user.domain'}.
                   1454:                                  ":".$roleresults);
1.50      matthew  1455:     } else { # everything is okay!
1.94      sakharuk 1456:         $r->print(&mt('Student information updated successfully.')." <br />".
                   1457:                   &mt('The student must log out and log in again to see these changes.'));
1.50      matthew  1458:     }
1.94      sakharuk 1459:     my $Masd=&mt('Modify another students data');
1.50      matthew  1460:     $r->print(<<END);
1.52      matthew  1461: </p><p>
1.59      matthew  1462: <input type="hidden" name="action" value="modifystudent" />
                   1463: <input type="hidden" name="sortby" value="$sortby" />
                   1464: <input type="hidden" name="Status" value="$status" />
1.94      sakharuk 1465: <a href="javascript:document.studentform.submit();">$Masd</a>
1.50      matthew  1466: </body></html>
                   1467: END
                   1468:     return;
                   1469: }
                   1470: 
                   1471: sub get_enrollment_data {
                   1472:     my ($sname,$sdomain) = @_;
                   1473:     my $courseid = $ENV{'request.course.id'};
                   1474:     $courseid =~ s:_:/:g;
                   1475:     my %roles = &Apache::lonnet::dump('roles',$sdomain,$sname);
                   1476:     my ($tmp) = keys(%roles);
                   1477:     # Bail out if we were unable to get the students roles
1.87      matthew  1478:     return ('error'.$tmp) if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.50      matthew  1479:     # Go through the roles looking for enrollment in this course
                   1480:     my ($end,$start) = (undef,undef);
                   1481:     my $section = '';
                   1482:     my $count = scalar(keys(%roles));
                   1483:     while (my ($course,$role) = each(%roles)) {
                   1484:         if ($course=~ /^\/$courseid\/*\s*(\w+)*_st$/ ) {
                   1485:             #
                   1486:             # Get active role
                   1487:             $section=$1;
                   1488:             (undef,$end,$start)=split(/\_/,$role);
                   1489:             my $now=time;
                   1490:             my $notactive=0;
                   1491:             if ($start) {
                   1492:                 if ($now<$start) { $notactive=1; }
                   1493:             }
                   1494:             if ($end) {
                   1495:                 if ($now>$end) { $notactive=1; }
                   1496:             } 
                   1497:             unless ($notactive) { return ($start,$end,$section); }
                   1498:         }
                   1499:     }
                   1500:     return ($start,$end,$section);
                   1501: }
                   1502: 
1.56      matthew  1503: #################################################
                   1504: #################################################
                   1505: 
                   1506: =pod
                   1507: 
                   1508: =item show_drop_list
                   1509: 
                   1510: Display a list of students to drop
                   1511: Inputs: 
                   1512: 
                   1513: =over 4
                   1514: 
                   1515: =item $r, Apache request
                   1516: 
                   1517: =item $classlist, hash pointer returned from loncoursedata::get_classlist();
                   1518: 
                   1519: =item $keylist, array pointer returned from loncoursedata::get_classlist() 
                   1520: which describes the order elements are stored in the %$classlist values.
                   1521: 
                   1522: =item $nosort, if true, sorting links are omitted.
                   1523: 
                   1524: =back
                   1525: 
                   1526: =cut
                   1527: 
                   1528: #################################################
                   1529: #################################################
1.11      www      1530: sub show_drop_list {
1.56      matthew  1531:     my ($r,$classlist,$keylist,$nosort)=@_;
1.11      www      1532:     my $cid=$ENV{'request.course.id'};
1.59      matthew  1533:     if (! exists($ENV{'form.sortby'})) {
                   1534:         &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   1535:                                                 ['sortby']);
                   1536:     }
1.54      matthew  1537:     my $sortby = $ENV{'form.sortby'};
                   1538:     if ($sortby !~ /^(username|domain|section|fullname|id)$/) {
                   1539:         $sortby = 'username';
                   1540:     }
1.56      matthew  1541:     #
1.54      matthew  1542:     my $action = "drop";
                   1543:     $r->print(<<END);
                   1544: <input type="hidden" name="sortby" value="$sortby" />
                   1545: <input type="hidden" name="action" value="$action" />
1.50      matthew  1546: <input type="hidden" name="state"  value="done" />
1.32      matthew  1547: <script>
1.51      matthew  1548: function checkAll(field) {
1.32      matthew  1549:     for (i = 0; i < field.length; i++)
                   1550:         field[i].checked = true ;
                   1551: }
                   1552: 
1.51      matthew  1553: function uncheckAll(field) {
1.32      matthew  1554:     for (i = 0; i < field.length; i++)
                   1555:         field[i].checked = false ;
                   1556: }
                   1557: </script>
                   1558: <p>
1.26      matthew  1559: <input type="hidden" name="phase" value="four">
1.56      matthew  1560: END
                   1561: 
                   1562:     if ($nosort) {
1.94      sakharuk 1563: 	my %lt=&Apache::lonlocal::texthash(
                   1564: 	               'usrn'   => "username",
                   1565:                        'dom'    => "domain",
                   1566:                        'sn'     => "student name",
                   1567:                        'sec'    => "section",
                   1568: 					   );
1.56      matthew  1569:         $r->print(<<END);
                   1570: <table border=2>
                   1571: <tr>
                   1572:     <th>&nbsp;</th>
1.94      sakharuk 1573:     <th>$lt{'usrn'}</th>
                   1574:     <th>$lt{'dom'}</th>
1.56      matthew  1575:     <th>ID</th>
1.94      sakharuk 1576:     <th>$lt{'sn'}</th>
                   1577:     <th>$lt{'sec'}</th>
1.56      matthew  1578: </tr>
                   1579: END
                   1580: 
                   1581:     } else  {
1.94      sakharuk 1582: 	my %lt=&Apache::lonlocal::texthash(
                   1583: 	               'usrn'   => "username",
                   1584:                        'dom'    => "domain",
                   1585:                        'sn'     => "student name",
                   1586:                        'sec'    => "section",
                   1587: 					   );
1.56      matthew  1588:         $r->print(<<END);
1.26      matthew  1589: <table border=2>
1.54      matthew  1590: <tr><th>&nbsp;</th>
                   1591:     <th>
1.94      sakharuk 1592:        <a href="/adm/dropadd?action=$action&sortby=username">$lt{'usrn'}</a>
1.54      matthew  1593:     </th><th>
1.94      sakharuk 1594:        <a href="/adm/dropadd?action=$action&sortby=domain">$lt{'dom'}</a>
1.54      matthew  1595:     </th><th>
                   1596:        <a href="/adm/dropadd?action=$action&sortby=id">ID</a>
                   1597:     </th><th>
1.94      sakharuk 1598:        <a href="/adm/dropadd?action=$action&sortby=fullname">$lt{'sn'}</a>
1.54      matthew  1599:     </th><th>
1.94      sakharuk 1600:        <a href="/adm/dropadd?action=$action&sortby=section">$lt{'sec'}</a>
1.54      matthew  1601:     </th>
                   1602: </tr>
1.26      matthew  1603: END
1.56      matthew  1604:     }
                   1605:     #
                   1606:     # Sort the students
                   1607:     my %index;
                   1608:     my $i;
                   1609:     foreach (@$keylist) {
                   1610:         $index{$_} = $i++;
                   1611:     }
                   1612:     my $index  = $index{$sortby};
                   1613:     my $second = $index{'username'};
                   1614:     my $third  = $index{'domain'};
1.54      matthew  1615:     my @Sorted_Students = sort {
1.56      matthew  1616:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   1617:             ||
                   1618:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   1619:             ||
                   1620:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   1621:         } (keys(%$classlist));
1.54      matthew  1622:     foreach my $student (@Sorted_Students) {
1.52      matthew  1623:         my $error;
1.56      matthew  1624:         my $username = $classlist->{$student}->[$index{'username'}];
                   1625:         my $domain   = $classlist->{$student}->[$index{'domain'}];
                   1626:         my $section  = $classlist->{$student}->[$index{'section'}];
                   1627:         my $name     = $classlist->{$student}->[$index{'fullname'}];
                   1628:         my $id       = $classlist->{$student}->[$index{'id'}];
                   1629:         my $status   = $classlist->{$student}->[$index{'status'}];
1.51      matthew  1630:         next if ($status ne 'Active');
                   1631:         #
                   1632:         $r->print(<<"END");
1.26      matthew  1633: <tr>
1.51      matthew  1634:     <td><input type="checkbox" name="droplist" value="$student"></td>
                   1635:     <td>$username</td>
                   1636:     <td>$domain</td>
                   1637:     <td>$id</td>
                   1638:     <td>$name</td>
                   1639:     <td>$section</td>
1.26      matthew  1640: </tr>
                   1641: END
1.25      matthew  1642:     }
                   1643:     $r->print('</table><br>');
1.94      sakharuk 1644:     my %lt=&Apache::lonlocal::texthash(
                   1645: 	               'dp'   => "Drop Students",
                   1646:                        'ca'   => "check all",
                   1647:                        'ua'   => "uncheck all",
                   1648: 				       );
1.32      matthew  1649:     $r->print(<<"END");
                   1650: </p><p>
1.94      sakharuk 1651: <input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.droplist)"> &nbsp;
                   1652: <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.droplist)"> 
                   1653: <p><input type=submit value="$lt{'dp'}"></p>
1.32      matthew  1654: END
1.51      matthew  1655:     return;
1.10      www      1656: }
                   1657: 
1.48      matthew  1658: #
                   1659: # Print out the initial form to get the courselist file
                   1660: #
                   1661: sub print_first_courselist_upload_form {
                   1662:     my $r=shift;
1.88      matthew  1663:     my $str;
                   1664:     $str  = '<input type="hidden" name="phase" value="two">';
                   1665:     $str .= '<input type="hidden" name="action" value="upload" />';
                   1666:     $str .= '<input type="hidden"   name="state"  value="got_file" />';
                   1667:     $str .= "<h3>".&mt('Upload a class list')."</h3>\n";
                   1668:     $str .= &Apache::loncommon::upfile_select_html();
                   1669:     $str .= "<p>\n";
                   1670:     $str .= '<input type="submit" name="fileupload" value="'.
                   1671:         &mt('Upload class list').'">'."\n";
                   1672:     $str .= '<input type="checkbox" name="noFirstLine" /> '.
                   1673:         &mt('Ignore First Line')."</p>\n";
                   1674:     $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
1.92      sakharuk 1675:                          &mt("How do I create a class list from a spreadsheet")).
1.88      matthew  1676:                              "<br />\n";
                   1677:     $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
1.92      sakharuk 1678:                            &mt("How do I create a CSV file from a spreadsheet")).
1.88      matthew  1679:                                "<br />\n";
                   1680:     $str .= "</body>\n</html>\n";
                   1681:     $r->print($str);
1.48      matthew  1682:     return;
                   1683: }
                   1684: 
1.10      www      1685: # ================================================= Drop/Add from uploaded file
                   1686: sub upfile_drop_add {
                   1687:     my $r=shift;
1.24      albertel 1688:     &Apache::loncommon::load_tmp_file($r);
                   1689:     my @studentdata=&Apache::loncommon::upfile_record_sep();
1.82      www      1690:     if($ENV{'form.noFirstLine'}){shift(@studentdata);}
1.26      matthew  1691:     my @keyfields = split(/\,/,$ENV{'form.keyfields'});
                   1692:     my $cid = $ENV{'request.course.id'};
1.25      matthew  1693:     my %fields=();
1.26      matthew  1694:     for (my $i=0; $i<=$ENV{'form.nfields'}; $i++) {
1.25      matthew  1695:         if ($ENV{'form.upfile_associate'} eq 'reverse') {
                   1696:             if ($ENV{'form.f'.$i} ne 'none') {
                   1697:                 $fields{$keyfields[$i]}=$ENV{'form.f'.$i};
                   1698:             }
                   1699:         } else {
                   1700:             $fields{$ENV{'form.f'.$i}}=$keyfields[$i];
                   1701:         }
                   1702:     }
1.26      matthew  1703:     #
1.68      matthew  1704:     my ($startdate,$enddate) = &get_dates_from_form();
                   1705:     if ($ENV{'form.makedatesdefault'}) {
                   1706:         $r->print(&make_dates_default($startdate,$enddate));
                   1707:     }
1.31      matthew  1708:     # Determine domain and desired host (home server)
1.25      matthew  1709:     my $domain=$ENV{'form.lcdomain'};
1.31      matthew  1710:     my $desiredhost = $ENV{'form.lcserver'};
                   1711:     if (lc($desiredhost) eq 'default') {
                   1712:         $desiredhost = undef;
                   1713:     } else {
1.45      matthew  1714:         my %home_servers = &Apache::loncommon::get_library_servers($domain);
1.31      matthew  1715:         if (! exists($home_servers{$desiredhost})) {
1.88      matthew  1716:             $r->print('<font color="#ff0000">'.&mt('Error').'</font>'.
                   1717:                       &mt('Invalid home server specified'));
                   1718:             $r->print("</body>\n</html>\n");
1.31      matthew  1719:             return;
                   1720:         }
                   1721:     }
1.26      matthew  1722:     # Determine authentication mechanism
                   1723:     my $amode  = '';
                   1724:     my $genpwd = '';
1.25      matthew  1725:     if ($ENV{'form.login'} eq 'krb') {
1.47      albertel 1726:         $amode='krb';
                   1727: 	$amode.=$ENV{'form.krbver'};
1.28      matthew  1728:         $genpwd=$ENV{'form.krbarg'};
1.25      matthew  1729:     } elsif ($ENV{'form.login'} eq 'int') {
                   1730:         $amode='internal';
1.28      matthew  1731:         if ((defined($ENV{'form.intarg'})) && ($ENV{'form.intarg'})) {
                   1732:             $genpwd=$ENV{'form.intarg'};
1.25      matthew  1733:         }
                   1734:     } elsif ($ENV{'form.login'} eq 'loc') {
                   1735:         $amode='localauth';
                   1736:         if ((defined($ENV{'form.locarg'})) && ($ENV{'form.locarg'})) {
                   1737:             $genpwd=$ENV{'form.locarg'};
1.79      matthew  1738:         }
                   1739:     }
                   1740:     if ($amode =~ /^krb/) {
                   1741:         if (! defined($genpwd) || $genpwd eq '') {
                   1742:             $r->print('<font color="red" size="+1">'.
1.88      matthew  1743:                       &mt('Unable to enroll students').'</font>  '.
                   1744:                       &mt('No Kerberos domain was specified.').'</p>');
1.79      matthew  1745:             $amode = ''; # This causes the loop below to be skipped
1.25      matthew  1746:         }
                   1747:     }
                   1748:     unless (($domain=~/\W/) || ($amode eq '')) {
1.26      matthew  1749:         #######################################
                   1750:         ##         Enroll Students           ##
                   1751:         #######################################
1.88      matthew  1752:         $r->print('<h3>'.&mt('Enrolling Students')."</h3>\n<p>\n");
1.25      matthew  1753:         my $count=0;
                   1754:         my $flushc=0;
                   1755:         my %student=();
1.26      matthew  1756:         # Get new classlist
1.25      matthew  1757:         foreach (@studentdata) {
                   1758:             my %entries=&Apache::loncommon::record_sep($_);
1.26      matthew  1759:             # Determine student name
1.25      matthew  1760:             unless (($entries{$fields{'username'}} eq '') ||
                   1761:                     (!defined($entries{$fields{'username'}}))) {
1.26      matthew  1762:                 my ($fname, $mname, $lname,$gen) = ('','','','');
1.25      matthew  1763:                 if (defined($fields{'names'})) {
1.26      matthew  1764:                     ($lname,$fname,$mname)=($entries{$fields{'names'}}=~
                   1765:                                             /([^\,]+)\,\s*(\w+)\s*(.*)$/);
1.25      matthew  1766:                 } else {
                   1767:                     if (defined($fields{'fname'})) {
                   1768:                         $fname=$entries{$fields{'fname'}};
                   1769:                     }
                   1770:                     if (defined($fields{'mname'})) {
                   1771:                         $mname=$entries{$fields{'mname'}};
                   1772:                     }
                   1773:                     if (defined($fields{'lname'})) {
                   1774:                         $lname=$entries{$fields{'lname'}};
                   1775:                     }
                   1776:                     if (defined($fields{'gen'})) {
                   1777:                         $gen=$entries{$fields{'gen'}};
                   1778:                     }
                   1779:                 }
                   1780:                 if ($entries{$fields{'username'}}=~/\W/) {
1.88      matthew  1781:                     $r->print('<br />'.
                   1782:       &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]',
                   1783:           $entries{$fields{'username'}},$fname,$mname,$lname,$gen).
                   1784:                               '</b>');
1.25      matthew  1785:                 } else {
1.26      matthew  1786:                     # determine section number
1.25      matthew  1787:                     my $sec='';
                   1788:                     my $username=$entries{$fields{'username'}};
                   1789:                     if (defined($fields{'sec'})) {
                   1790:                         if (defined($entries{$fields{'sec'}})) {
                   1791:                             $sec=$entries{$fields{'sec'}};
                   1792:                         }
                   1793:                     }
1.80      matthew  1794:                     # remove non alphanumeric values from section
                   1795:                     $sec =~ s/\W//g;
1.26      matthew  1796:                     # determine student id number
1.25      matthew  1797:                     my $id='';
                   1798:                     if (defined($fields{'id'})) {
                   1799:                         if (defined($entries{$fields{'id'}})) {
                   1800:                             $id=$entries{$fields{'id'}};
                   1801:                         }
                   1802:                         $id=~tr/A-Z/a-z/;
                   1803:                     }
1.73      www      1804:                     # determine email address
                   1805:                     my $email='';
                   1806:                     if (defined($fields{'email'})) {
                   1807:                         if (defined($entries{$fields{'email'}})) {
                   1808:                             $email=$entries{$fields{'email'}};
                   1809:                             unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }
                   1810:                         }
                   1811:                     }
1.26      matthew  1812:                     # determine student password
1.25      matthew  1813:                     my $password='';
                   1814:                     if ($genpwd) { 
                   1815:                         $password=$genpwd; 
                   1816:                     } else {
                   1817:                         if (defined($fields{'ipwd'})) {
                   1818:                             if ($entries{$fields{'ipwd'}}) {
                   1819:                                 $password=$entries{$fields{'ipwd'}};
                   1820:                             }
                   1821:                         }
                   1822:                     }
1.56      matthew  1823:                     # Clean up whitespace
                   1824:                     foreach (\$domain,\$username,\$id,\$fname,\$mname,
                   1825:                              \$lname,\$gen,\$sec) {
                   1826:                         $$_ =~ s/(\s+$|^\s+)//g;
                   1827:                     }
1.84      albertel 1828:                     if ($password || $ENV{'form.login'} eq 'loc') {
1.33      matthew  1829:                         &modifystudent($domain,$username,$cid,$sec,
                   1830:                                        $desiredhost);
1.25      matthew  1831:                         my $reply=&Apache::lonnet::modifystudent
                   1832:                             ($domain,$username,$id,$amode,$password,
                   1833:                              $fname,$mname,$lname,$gen,$sec,$enddate,
1.73      www      1834:                              $startdate,$ENV{'form.forceid'},$desiredhost,
                   1835:                              $email);
1.26      matthew  1836:                         if ($reply ne 'ok') {
1.72      matthew  1837:                             $reply =~ s/^error://;
1.88      matthew  1838:                             $r->print('<br />'.
                   1839:                 &mt('<b>[_1]</b>:  Unable to enroll: [_2]',$username,$reply));
1.10      www      1840:          		} else {
1.7       www      1841:                             $count++; $flushc++;
                   1842:                             $student{$username}=1;
1.6       www      1843:                             $r->print('. ');
1.7       www      1844:                             if ($flushc>15) {
                   1845: 				$r->rflush;
                   1846:                                 $flushc=0;
                   1847:                             }
1.6       www      1848:                         }
1.25      matthew  1849:                     } else {
1.88      matthew  1850:                         $r->print('<br />'.
                   1851:       &mt('<b>[_1]</b>: Unable to enroll.  No password specified.',$username)
                   1852:                                   );
1.25      matthew  1853:                     }
                   1854:                 }
1.26      matthew  1855:             }
                   1856:         } # end of foreach (@studentdata)
1.88      matthew  1857:         $r->print("</p>\n<p>\n".&mt('Processed [_1] student(s).',$count).
                   1858:                   "</p>\n");
                   1859:         $r->print("<p>\n".
                   1860:                   &mt('If active, the new role will be available when the '.
                   1861:                   'students next log in to LON-CAPA.')."</p>\n");
1.26      matthew  1862:         #####################################
                   1863:         #           Drop students           #
                   1864:         #####################################
1.25      matthew  1865:         if ($ENV{'form.fullup'} eq 'yes') {
1.88      matthew  1866:             $r->print('<h3>'.&mt('Dropping Students')."</h3>\n");
1.26      matthew  1867:             #  Get current classlist
1.56      matthew  1868:             my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                   1869:             if (! defined($classlist)) {
1.88      matthew  1870:                 $r->print(&mt('There are no students currently enrolled.').
                   1871:                           "\n");
1.56      matthew  1872:             } else {
                   1873:                 # Remove the students we just added from the list of students.
1.25      matthew  1874:                 foreach (@studentdata) {
                   1875:                     my %entries=&Apache::loncommon::record_sep($_);
                   1876:                     unless (($entries{$fields{'username'}} eq '') ||
                   1877:                             (!defined($entries{$fields{'username'}}))) {
1.56      matthew  1878:                         delete($classlist->{$entries{$fields{'username'}}.
1.26      matthew  1879:                                                 ':'.$domain});
1.25      matthew  1880:                     }
                   1881:                 }
1.56      matthew  1882:                 # Print out list of dropped students.
                   1883:                 &show_drop_list($r,$classlist,$keylist,'nosort');
1.25      matthew  1884:             }
                   1885:         }
1.26      matthew  1886:     } # end of unless
1.10      www      1887: }
                   1888: 
1.11      www      1889: # ================================================================== Phase four
                   1890: sub drop_student_list {
                   1891:     my $r=shift;
                   1892:     my $count=0;
1.35      matthew  1893:     my @droplist;
                   1894:     if (ref($ENV{'form.droplist'})) {
                   1895:         @droplist = @{$ENV{'form.droplist'}};
                   1896:     } else {
                   1897:         @droplist = ($ENV{'form.droplist'});
                   1898:     }
                   1899:     foreach (@droplist) {
1.26      matthew  1900:         my ($uname,$udom)=split(/\:/,$_);
1.56      matthew  1901:         # drop student
1.35      matthew  1902:         my $result = &modifystudent($udom,$uname,$ENV{'request.course.id'});
1.37      matthew  1903:         if ($result eq 'ok' || $result eq 'ok:') {
1.88      matthew  1904:             $r->print(&mt('Dropped [_1]',$uname.'@'.$udom).'<br>');
1.59      matthew  1905:             $count++;
1.35      matthew  1906:         } else {
1.88      matthew  1907:             $r->print(
                   1908:           &mt('Error dropping [_1]:[_2]',$uname.'@'.$udom,$result).
1.35      matthew  1909:                       '<br />');
                   1910:         }
1.20      harris41 1911:     }
1.88      matthew  1912:     $r->print('<p><b>'.&mt('Dropped [_1] student(s).',$count).'</b></p>');
                   1913:     $r->print('<p>'.&mt('Re-enrollment will re-activate data.')) if ($count);
1.11      www      1914: }
                   1915: 
1.50      matthew  1916: ###################################################################
                   1917: ###################################################################
                   1918: 
                   1919: =pod
                   1920: 
                   1921: =item &handler
                   1922: 
                   1923: The typical handler you see in all these modules.  Takes $r, the
                   1924: http request, as an argument.  
                   1925: 
                   1926: The response to the request is governed by two form variables
                   1927: 
                   1928:  form.action      form.state     response
                   1929:  ---------------------------------------------------
                   1930:  undefined        undefined      print main menu
                   1931:  upload           undefined      print courselist upload menu
                   1932:  upload           got_file       deal with uploaded file,
                   1933:                                  print the upload managing menu
                   1934:  upload           enrolling      enroll students based on upload
                   1935:  drop             undefined      print the classlist ready to drop
                   1936:  drop             done           drop the selected students
1.74      matthew  1937:  enrollstudent    undefined      print student username domain form
                   1938:  enrollstudent    gotusername    print single student enroll menu
1.50      matthew  1939:  enrollstudent    enrolling      enroll student
                   1940:  classlist        undefined      print html classlist
                   1941:  classlist        csv            print csv classlist
                   1942:  modifystudent    undefined      print classlist to select student to modify
                   1943:  modifystudent    selected       print modify student menu
                   1944:  modifystudent    done           make modifications to student record
                   1945: 
                   1946: =cut
                   1947: 
                   1948: ###################################################################
                   1949: ###################################################################
1.10      www      1950: sub handler {
1.26      matthew  1951:     my $r=shift;
                   1952:     if ($r->header_only) {
1.86      www      1953:         &Apache::loncommon::content_type($r,'text/html');
1.26      matthew  1954:         $r->send_http_header;
                   1955:         return OK;
                   1956:     }
1.48      matthew  1957:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.50      matthew  1958:                                             ['action','state']);
1.26      matthew  1959:     #  Needs to be in a course
1.50      matthew  1960:     if (! (($ENV{'request.course.fn'}) &&
                   1961:           (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'})))) {
                   1962:         # Not in a course, or not allowed to modify parms
                   1963:         $ENV{'user.error.msg'}=
                   1964:             "/adm/dropadd:cst:0:0:Cannot drop or add students";
                   1965:         return HTTP_NOT_ACCEPTABLE; 
                   1966:     }
                   1967:     #
                   1968:     # Only output the header information if they did not request csv format
                   1969:     #
                   1970:     if (exists($ENV{'form.state'}) && ($ENV{'form.state'} eq 'csv')) {
                   1971:         $r->content_type('text/csv');
                   1972:     } else {
1.26      matthew  1973:         # Start page
1.86      www      1974:         &Apache::loncommon::content_type($r,'text/html');
1.26      matthew  1975:         $r->send_http_header;
1.50      matthew  1976:         $r->print(&header());
                   1977:     }
                   1978:     #
                   1979:     # Main switch on form.action and form.state, as appropriate
                   1980:     if (! exists($ENV{'form.action'})) {
                   1981:         &print_main_menu($r);
                   1982:     } elsif ($ENV{'form.action'} eq 'upload') {
                   1983:         if (! exists($ENV{'form.state'})) {
                   1984:             &print_first_courselist_upload_form($r);            
                   1985:         } elsif ($ENV{'form.state'} eq 'got_file') {
                   1986:             &print_upload_manager_form($r);
                   1987:         } elsif ($ENV{'form.state'} eq 'enrolling') {
1.26      matthew  1988:             if ($ENV{'form.datatoken'}) {
                   1989:                 &upfile_drop_add($r);
1.50      matthew  1990:             } else {
                   1991:                 # Hmmm, this is an error
1.26      matthew  1992:             }
1.50      matthew  1993:         } else {
                   1994:             &print_first_courselist_upload_form($r);            
1.26      matthew  1995:         }
1.50      matthew  1996:     } elsif ($ENV{'form.action'} eq 'drop') {
                   1997:         if (! exists($ENV{'form.state'})) {
1.51      matthew  1998:             &print_drop_menu($r);
1.50      matthew  1999:         } elsif ($ENV{'form.state'} eq 'done') {
1.26      matthew  2000:             &drop_student_list($r);
1.50      matthew  2001:         } else {
1.55      matthew  2002:             &print_drop_menu($r);
1.26      matthew  2003:         }
1.50      matthew  2004:     } elsif ($ENV{'form.action'} eq 'enrollstudent') {
                   2005:         if (! exists($ENV{'form.state'})) {
1.74      matthew  2006:             &get_student_username_domain_form($r);
                   2007:         } elsif ($ENV{'form.state'} eq 'gotusername') {
1.50      matthew  2008:             &print_enroll_single_student_form($r);
                   2009:         } elsif ($ENV{'form.state'} eq 'enrolling') {
1.26      matthew  2010:             &enroll_single_student($r);
1.50      matthew  2011:         } else {
1.74      matthew  2012:             &get_student_username_domain_form($r);
1.26      matthew  2013:         }
1.50      matthew  2014:     } elsif ($ENV{'form.action'} eq 'classlist') {
                   2015:         if (! exists($ENV{'form.state'})) {
                   2016:             &print_html_classlist($r);
                   2017:         } elsif ($ENV{'form.state'} eq 'csv') {
1.60      matthew  2018:             &print_formatted_classlist($r,'csv');
                   2019:         } elsif ($ENV{'form.state'} eq 'excel') {
                   2020:             &print_formatted_classlist($r,'excel');
1.50      matthew  2021:         } else {
                   2022:             &print_html_classlist($r);
                   2023:         }
                   2024:     } elsif ($ENV{'form.action'} eq 'modifystudent') {
                   2025:         if (! exists($ENV{'form.state'})) {
                   2026:             &print_html_classlist($r);
                   2027:         } elsif ($ENV{'form.state'} eq 'selected') {
                   2028:             &print_modify_student_form($r);
                   2029:         } elsif ($ENV{'form.state'} eq 'done') {
                   2030:             &modify_single_student($r);
                   2031:         } else {
                   2032:             &print_html_classlist($r);
                   2033:         }        
                   2034:     } else {
                   2035:         # We should not end up here, but I guess it is possible
                   2036:         &Apache::lonnet::logthis("Undetermined state in londropadd.pm.  ".
                   2037:                                  "form.action = ".$ENV{'form.action'}.
                   2038:                                  "Someone should fix this.");
                   2039:         &print_main_menu($r);
                   2040:     }
                   2041:     #
                   2042:     # Finish up
                   2043:     if (exists($ENV{'form.state'}) && ($ENV{'form.state'} eq 'csv')) {
                   2044:         $r->print("\n");
1.26      matthew  2045:     } else {
1.50      matthew  2046:         $r->print('</form></body></html>');
1.26      matthew  2047:     }
                   2048:     return OK;
1.1       www      2049: }
                   2050: 
1.50      matthew  2051: ###################################################################
                   2052: ###################################################################
                   2053: 
1.1       www      2054: 1;
                   2055: __END__
1.50      matthew  2056: 
1.1       www      2057: 

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