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

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

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