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

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

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