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

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

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