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

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

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