Diff for /loncom/interface/Attic/londropadd.pm between versions 1.10 and 1.73

version 1.10, 2001/02/13 21:24:18 version 1.73, 2003/07/05 10:07:11
Line 1 Line 1
 # The LearningOnline Network with CAPA  # The LearningOnline Network with CAPA
 # Handler to drop and add students in courses   # Handler to drop and add students in courses 
 #  #
 # (Handler to set parameters for assessments  # $Id$
 #  #
 # (Handler to resolve ambiguous file locations  # Copyright Michigan State University Board of Trustees
 #  #
 # (TeX Content Handler  # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
   #
   # LON-CAPA is free software; you can redistribute it and/or modify
   # it under the terms of the GNU General Public License as published by
   # the Free Software Foundation; either version 2 of the License, or
   # (at your option) any later version.
   #
   # LON-CAPA is distributed in the hope that it will be useful,
   # but WITHOUT ANY WARRANTY; without even the implied warranty of
   # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   # GNU General Public License for more details.
   #
   # You should have received a copy of the GNU General Public License
   # along with LON-CAPA; if not, write to the Free Software
   # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #  #
 # 05/29/00,05/30,10/11 Gerd Kortemeyer)  # /home/httpd/html/adm/gpl.txt
 #  #
 # 10/11,10/12,10/16 Gerd Kortemeyer)  # http://www.lon-capa.org/
 #  #
 # 11/20,11/21,11/22,11/23,11/24,11/25,11/27,11/28,  # (Handler to set parameters for assessments
 # 12/08,12/12 Gerd Kortemeyer)  #
   # (Handler to resolve ambiguous file locations
 #  #
 # 12/26,12/27,12/28,  # (TeX Content Handler
 # 01/01/01,01/15,02/10,02/13 Gerd Kortemeyer  #
   ###############################################################
   ###############################################################
   
 package Apache::londropadd;  package Apache::londropadd;
   
 use strict;  use strict;
 use Apache::lonnet;  use Apache::lonnet();
   use Apache::loncommon();
   use Apache::lonhtmlcommon();
 use Apache::Constants qw(:common :http REDIRECT);  use Apache::Constants qw(:common :http REDIRECT);
   use Spreadsheet::WriteExcel;
   
 # ================================================================ Print header  ###############################################################
   ###############################################################
 sub header {  sub header {
     my $r=shift;      my $bodytag=&Apache::loncommon::bodytag('Enrollment Manager');
     $r->print(<<ENDHEAD);      return(<<ENDHEAD);
 <html>  <html>
 <head>  <head>
 <title>LON-CAPA Student Drop/Add</title>  <title>LON-CAPA Enrollment Manager</title>
 </head>  </head>
 <body bgcolor="#FFFFFF">  $bodytag
 <img align=right src=/adm/lonIcons/lonlogos.gif>  <form method="post" enctype="multipart/form-data"  
 <h1>Drop/Add Students</h1>        action="/adm/dropadd" name="studentform">
 <form method="post" enctype="multipart/form-data"  
 action="/adm/dropadd" name="studentform">  
 <h2>Course: $ENV{'course.'.$ENV{'request.course.id'}.'.description'}</h2>  
 ENDHEAD  ENDHEAD
 }  }
   
 # ========================================================= Store uploaded file  ###############################################################
 # needs $ENV{'form.upfile'}  ###############################################################
 # return $datatoken to be put into hidden field  # Drop student from all sections of a course, except optional $csec
   sub modifystudent {
 sub upfile_store {      my ($udom,$unam,$courseid,$csec,$desiredhost)=@_;
     my $r=shift;      # if $csec is undefined, drop the student from all the courses matching
     $ENV{'form.upfile'}=~s/\r/\n/gs;      # this one.  If $csec is defined, drop them from all other sections of 
     $ENV{'form.upfile'}=~s/\f/\n/gs;      # this course and add them to section $csec
     $ENV{'form.upfile'}=~s/\n+/\n/gs;      $courseid=~s/\_/\//g;
     $ENV{'form.upfile'}=~s/\n+$//gs;      $courseid=~s/^(\w)/\/$1/;
             my %roles = &Apache::lonnet::dump('roles',$udom,$unam);
     my $datatoken=$ENV{'user.name'}.'_'.$ENV{'user.domain'}.      my ($tmp) = keys(%roles);
   '_enroll_'.$ENV{'request.course.id'}.'_'.time.'_'.$$;      # Bail out if we were unable to get the students roles
     {      return "$1" if ($tmp =~ /^(con_lost|error|no_such_host)/i);
        my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').      # Go through the roles looking for enrollment in this course
                                    '/tmp/'.$datatoken.'.tmp');      my $result = '';
        print $fh $ENV{'form.upfile'};      foreach my $course (keys(%roles)) {
     }          if ($course=~/^$courseid(?:\/)*(?:\s+)*(\w+)*\_st$/) {
     return $datatoken;              # We are in this course
 }              my $section=$1;
               $section='' if ($course eq $courseid.'_st');
 # ================================================= Load uploaded file from tmp              if ($section eq $csec) {
 # needs $ENV{'form.datatoken'}                  $result .= 'ok:';
 # sets $ENV{'form.upfile'}              } elsif ( ((!$section) && (!$csec)) || ($section ne $csec) ) {
                   my (undef,$end,$start)=split(/\_/,$roles{$course});
 sub load_tmp_file {                  my $now=time;
     my $r=shift;                  # if this is an active role 
     my @studentdata=();                  if (!($start && ($now<$start)) || !($end && ($now>$end))) {
     {                      my $reply=&Apache::lonnet::modifystudent
       my $fh;                          # dom  name  id mode pass     f     m     l     g
       if ($fh=Apache::File->new($r->dir_config('lonDaemons').                          ($udom,$unam,'',  '',  '',undef,undef,undef,undef,
   '/tmp/'.$ENV{'form.datatoken'}.'.tmp')) {                           $section,time,undef,undef,$desiredhost);
      @studentdata=<$fh>;                      $result .= $reply.':';
       }                  }
               }
           }
       }
       if ($result eq '') {
           $result = 'Unable to find section for this student';
       } else {
           $result =~ s/(ok:)+/ok/g;
     }      }
     $ENV{'form.upfile'}=join('',@studentdata);      return $result;
 }  }
   
 # ========================================= Separate uploaded file into records  ###############################################################
 # returns array of records  ###############################################################
   # build a domain and server selection form
 sub upfile_record_sep {  sub domain_form {
     if ($ENV{'form.upfiletype'} eq 'xml') {      my ($defdom) = @_;
     } else {      # Set up domain and server selection forms
        return split(/\n/,$ENV{'form.upfile'});      #
     }      # Get the domains
 }      my @domains = &Apache::loncommon::get_domains();
       # build up the menu information to be passed to 
 # =============================================== Separate a record into fields      # &Apache::loncommon::linked_select_forms
       my %select_menus;
 sub record_sep {      foreach my $dom (@domains) {
     my $record=shift;          # set up the text for this domain
     my %components=();          $select_menus{$dom}->{'text'}= $dom;
     if ($ENV{'form.upfiletype'} eq 'xml') {          # we want a choice of 'default' as the default in the second menu
     } elsif ($ENV{'form.upfiletype'} eq 'space') {          $select_menus{$dom}->{'default'}= 'default';
         my $i=0;          $select_menus{$dom}->{'select2'}->{'default'} = 'default';
         map {          # Now build up the other items in the second menu
             my $field=$_;          my %servers = &Apache::loncommon::get_library_servers($dom);
             $field=~s/^(\"|\')//;          foreach my $server (keys(%servers)) {
             $field=~s/(\"|\')$//;              $select_menus{$dom}->{'select2'}->{$server} 
             $components{$i}=$field;                                              = "$server $servers{$server}";
             $i++;  
         } split(/\s+/,$record);  
     } elsif ($ENV{'form.upfiletype'} eq 'tab') {  
         my $i=0;  
         map {  
             my $field=$_;  
             $field=~s/^(\"|\')//;  
             $field=~s/(\"|\')$//;  
             $components{$i}=$field;  
             $i++;  
         } split(/\t+/,$record);          
     } else {  
         my @allfields=split(/\,/,$record);  
         my $i=0;  
         my $j;  
         for ($j=0;$j<=$#allfields;$j++) {  
             my $field=$allfields[$j];  
             if ($field=~/^\s*(\"|\')/) {  
  my $delimiter=$1;  
                 while (($field!~/$delimiter$/) && ($j<$#allfields)) {  
     $j++;  
     $field.=','.$allfields[$j];  
  }  
                 $field=~s/^\s*$delimiter//;  
                 $field=~s/$delimiter\s*$//;  
             }  
             $components{$i}=$field;  
     $i++;  
         }  
     }  
     return %components;  
 }  
   
 # =========== Drop student from all sections of a course, except optional $csec  
   
 sub dropstudent {  
      my ($udom,$unam,$courseid,$csec)=@_;  
      $courseid=~s/\_/\//g;  
      $courseid=~s/^(\w)/\/$1/;  
      map {  
         my ($key,$value)=split(/\=/,$_);  
         $key=&Apache::lonnet::unescape($key);  
         if ($key=~/^$courseid(?:\/)*(\w+)*\_st$/) {  
           my $section=$1;  
           if ($key eq $courseid.'_st') { $section=''; }  
           if ($section ne $csec) {  
     my ($dummy,$end,$start)=split(/\_/,  
                                     &Apache::lonnet::unescape($value));  
             my $now=time;  
             my $notactive=0;  
             if ($start) {  
  if ($now<$start) { $notactive=1; }  
             }  
             if ($end) {  
                 if ($now>$end) { $notactive=1; }  
             }   
             unless ($notactive) {  
                 my $reply=&Apache::lonnet::modifystudent(  
                                    $udom,$unam,'','','',  
            '','','','',$section,time);  
             }  
   }  
         }          }
     } split(/\&/,&Apache::lonnet::reply('dump:'.$udom.':'.$unam.':roles',      }
                                  &Apache::lonnet::homeserver($unam,$udom)));      my $result  = &Apache::loncommon::linked_select_forms
           ('studentform',' with home server ',$defdom,
            'lcdomain','lcserver',\%select_menus);
       return $result;
 }  }
   
 # ============================================================== Menu Phase One  ###############################################################
   ###############################################################
 sub menu_phase_one {  #  Menu Phase One
   sub print_main_menu {
     my $r=shift;      my $r=shift;
     $r->print(<<ENDUPFORM);      $r->print(<<END);
 <input type=hidden name=phase value=two>  <p>
 <hr>  <font size="+1">
 <h3>Upload a courselist</h3>      <a href="/adm/dropadd?action=upload">Upload a course list</a>
 <input type=file name=upfile size=50>  </font>
 <br>Type: <select name=upfiletype>  </p><p>
 <option value=csv>CSV (comma separated values, spreadsheet)</option>  <font size="+1">
 <option value=space>Space separated</option>      <a href="/adm/dropadd?action=enrollstudent">Enroll a single student</a>
 <option value=tab>Tabulator separated</option>  </font>
 <option value=xml>HTML/XML</option>  </p><p>
 </select>  <font size="+1">
 <p><input type=submit name=fileupload value="Upload Courselist">      <a href="/adm/dropadd?action=modifystudent">Modify student data</a>
 <hr>  </font>
 <h3>Enroll a single student</h3>  </p><p>
 <p><input type=submit name=enroll value="Enroll Student">  <font size="+1">
 <hr>      <a href="/adm/dropadd?action=classlist">View Classlist</a>
 <h3>Drop a student</h3>  </font>
 <p><input type=submit name=drop value="Drop Student">  </p><p>
 ENDUPFORM  <font size="+1">
       <a href="/adm/dropadd?action=drop">Drop Students</a>
   </font>
   </p>
   END
 }  }
   
 # ======================================================= Menu Phase Two Upload  ###############################################################
   ###############################################################
 sub menu_phase_two_upload {  sub print_upload_manager_header {
     my $r=shift;      my ($r,$datatoken,$distotal,$krbdefdom)=@_;
       my $javascript;
       if (! exists($ENV{'form.upfile_associate'})) {
           $ENV{'form.upfile_associate'} = 'forward';
       }
       if ($ENV{'form.associate'} eq 'Reverse Association') {
           if ( $ENV{'form.upfile_associate'} ne 'reverse' ) {
               $ENV{'form.upfile_associate'} = 'reverse';
           } else {
               $ENV{'form.upfile_associate'} = 'forward';
           }
       }
       if ($ENV{'form.upfile_associate'} eq 'reverse') {
    $javascript=&upload_manager_javascript_reverse_associate();
       } else {
    $javascript=&upload_manager_javascript_forward_associate();
       }
       my $javascript_validations=&javascript_validations($krbdefdom);
       $r->print(<<ENDPICK);
   <h3>Uploading Class List</h3>
   <hr>
   <h3>Identify fields</h3>
   Total number of records found in file: $distotal <hr />
   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 run your class.<hr />
   <input type="button" value="Reverse Association" onClick="javascript:this.form.associate.value='Reverse Association';submit(this.form);" />
   <input type="hidden" name="action"     value="upload" />
   <input type="hidden" name="state"      value="got_file" />
   <input type="hidden" name="associate"  value="" />
   <input type="hidden" name="datatoken"  value="$datatoken" />
   <input type="hidden" name="fileupload" value="$ENV{'form.fileupload'}" />
   <input type="hidden" name="upfiletype" value="$ENV{'form.upfiletype'}" />
   <input type="hidden" name="upfile_associate" 
                                          value="$ENV{'form.upfile_associate'}" />
   <hr />
   <script type="text/javascript" language="Javascript">
   $javascript
   $javascript_validations
   </script>
   ENDPICK
   }
   
     my $datatoken=&upfile_store($r);  ###############################################################
   ###############################################################
   sub javascript_validations {
       my ($krbdefdom)=@_;
       my %param = ( formname => 'studentform',
                     kerb_def_dom => $krbdefdom );
       my $authheader = &Apache::loncommon::authform_header(%param);
       my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
       return (<<ENDPICK);
   function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail) {
       var foundatype=0;
       var message='';
       if (founduname==0) {
    alert('You need to specify the username field');
           return;
       }
       // alert('current.radiovalue = '+current.radiovalue);
       if (current.radiovalue == null || current.radiovalue == 'nochange') {
           // They did not check any of the login radiobuttons.
           alert('You must choose an authentication type');
           return;
       }
       foundatype=1;
       if (current.argfield == null || current.argfield == '') {
           var alertmsg = '';
           switch (current.value) {
               case 'krb': 
                   alertmsg = 'You need to specify the Kerberos domain';
                   break;
               case 'loc':
               case 'fsys':
                   alertmsg = 'You need to specify the initial password';
                   break;
               case 'fsys':
                   alertmsg = '';
                   break;
               default: 
                   alertmsg = '';
           }
           if (alertmsg != '') {
               alert(alertmsg);
               return;
           }
       }
   
     my @records=&upfile_record_sep();      if (foundname==0) { message='name fields'; }
     my $total=$#records;      if (foundid==0) { if (message!='') { message+=', '; } message+='student number field'; }
     my $distotal=$total+1;      if (foundsec==0) {  if (message!='') { message+=', '; } message+='section or group field'; }
           if (foundemail==0) {  if (message!='') { message+=', '; } message+='email address field'; }
     $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/;      if (message!='') {
     my $krbdefdom=$1;         message='Not specified (optional): '+message+'.  Continue enrollment?';
     $krbdefdom=~tr/a-z/A-Z/;         if (confirm(message)) {
             vf.state.value='enrolling';
     vf.submit();
          }
       } else {
         vf.state.value='enrolling';
         vf.submit();
       }
   }
   
     my $today=time;  $authheader
     my $halfyear=$today+15552000;  ENDPICK
   
     my $defdom=$r->dir_config('lonDefDomain');  }
   
     $r->print(<<ENDPICK);  ###############################################################
 <input type=hidden name=phase value=three>  ###############################################################
 <input type=hidden name=datatoken value="$datatoken">  sub upload_manager_javascript_forward_associate {
 <input type=hidden name=upfiletype value=$ENV{'form.upfiletype'}>      return(<<ENDPICK);
 <hr>  
 <h3>Identify fields</h3>  
 Total number of records found in file: $distotal  
 <script>  
 function verify(vf) {  function verify(vf) {
     var founduname=0;      var founduname=0;
     var foundpwd=0;      var foundpwd=0;
     var foundname=0;      var foundname=0;
     var foundid=0;      var foundid=0;
     var foundsec=0;      var foundsec=0;
     var foundatype=0;      var foundemail=0;
     var tw;      var tw;
     var message='';  
     for (i=0;i<=vf.nfields.value;i++) {      for (i=0;i<=vf.nfields.value;i++) {
         tw=eval('vf.f'+i+'.selectedIndex');          tw=eval('vf.f'+i+'.selectedIndex');
         if (tw==1) { founduname=1; }          if (tw==1) { founduname=1; }
         if ((tw>=2) && (tw<=6)) { foundname=1; }          if ((tw>=2) && (tw<=6)) { foundname=1; }
         if (tw==7) { foundid=1; }          if (tw==7) { foundid=1; }
         if (tw==8) { foundsec=1; }           if (tw==8) { foundsec=1; }
         if (tw==9) { foundpwd=1; }          if (tw==9) { foundpwd=1; }
           if (tw==10) { foundemail=1; }
     }      }
     if (founduname==0) {      verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail);
  alert('You need to specify at least the username field');  
         return;  
     }  
     if (vf.login[0].checked) {  
  foundatype=1;  
         if (vf.krbdom.value=='') {  
     alert('You need to specify the Kerberos domain');  
             return;  
         }  
     }  
     if (vf.login[1].checked) {  
  foundatype=1;  
         if ((vf.intpwd.value=='') && (foundpwd==0)) {  
     alert('You need to specify the initial password');  
             return;  
         }  
     }  
     if (foundatype==0) {  
  alert('You need to set the login type');  
         return;  
     }  
     if (foundname==0) { message='No name fields specified. '; }  
     if (foundid==0) { message+='No ID or student number field specified. '; }  
     if (foundsec==0) { message+='No section or group field specified. '; }  
     if (vf.startdate.value=='') {  
  message+='No starting date set. ';  
     }  
     if (vf.enddate.value=='') {  
         message+='No ending date set. ';  
     }  
     if ((vf.enddate.value!='') && (vf.startdate.value!='')) {  
        if (Math.round(vf.enddate.value)<Math.round(vf.startdate.value)) {  
           alert('Ending date is before starting date');  
           return;  
        }  
     }  
     if (message!='') {  
        message+='Continue enrollment?';  
        if (confirm(message)) {  
   pclose();  
   vf.submit();  
        }  
     } else {  
       pclose();  
       vf.submit();  
     }     
 }  }
   
   //
   // vf = this.form
   // tf = column number
   //
   // values of nw
   //
   // 0 = none
   // 1 = username
   // 2 = names (lastname, firstnames)
   // 3 = fname (firstname)
   // 4 = mname (middlename)
   // 5 = lname (lastname)
   // 6 = gen   (generation)
   // 7 = id
   // 8 = section
   // 9 = ipwd  (password)
   // 10 = email address
   
 function flip(vf,tf) {  function flip(vf,tf) {
    var nw=eval('vf.f'+tf+'.selectedIndex');     var nw=eval('vf.f'+tf+'.selectedIndex');
    var i;     var i;
      // make sure no other columns are labeled the same as this one
    for (i=0;i<=vf.nfields.value;i++) {     for (i=0;i<=vf.nfields.value;i++) {
       if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {        if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {
           eval('vf.f'+i+'.selectedIndex=0;')                  eval('vf.f'+i+'.selectedIndex=0;')
       }         }
    }     }
      // If we set this to 'lastname, firstnames', clear out all the ones
      // set to 'fname','mname','lname','gen' (3,4,5,6) currently.
    if (nw==2) {     if (nw==2) {
       for (i=0;i<=vf.nfields.value;i++) {        for (i=0;i<=vf.nfields.value;i++) {
          if ((eval('vf.f'+i+'.selectedIndex')>=3) &&           if ((eval('vf.f'+i+'.selectedIndex')>=3) &&
              (eval('vf.f'+i+'.selectedIndex')<=6)) {               (eval('vf.f'+i+'.selectedIndex')<=6)) {
              eval('vf.f'+i+'.selectedIndex=0;')               eval('vf.f'+i+'.selectedIndex=0;')
          }           }
       }              }
    }     }
      // If we set this to one of 'fname','mname','lname','gen' (3,4,5,6),
      // clear out any that are set to 'lastname, firstnames' (2)
    if ((nw>=3) && (nw<=6)) {     if ((nw>=3) && (nw<=6)) {
       for (i=0;i<=vf.nfields.value;i++) {        for (i=0;i<=vf.nfields.value;i++) {
          if (eval('vf.f'+i+'.selectedIndex')==2) {           if (eval('vf.f'+i+'.selectedIndex')==2) {
              eval('vf.f'+i+'.selectedIndex=0;')               eval('vf.f'+i+'.selectedIndex=0;')
          }           }
       }              }
    }     }
      // If we set the password, make the password form below correspond to 
      // the new value.
    if (nw==9) {     if (nw==9) {
        vf.login[1].checked=true;         changed_radio('int',document.studentform);
        vf.intpwd.value='';         set_auth_radio_buttons('int',document.studentform);
        vf.krbdom.value='';         vf.intarg.value='';
          vf.krbarg.value='';
          vf.locarg.value='';
    }     }
   
 }  }
   
 function clearpwd(vf) {  function clearpwd(vf) {
Line 325  function clearpwd(vf) { Line 362  function clearpwd(vf) {
         if (eval('vf.f'+i+'.selectedIndex')==9) {          if (eval('vf.f'+i+'.selectedIndex')==9) {
             eval('vf.f'+i+'.selectedIndex=0;')              eval('vf.f'+i+'.selectedIndex=0;')
         }          }
     }            }
 }  
   
 function setkrb(vf) {  
     if (vf.krbdom.value!='') {  
        clearpwd(vf);  
        vf.login[0].checked=true;  
        vf.krbdom.value=vf.krbdom.value.toUpperCase();  
        vf.intpwd.value='';  
    }  
 }  }
   
 function setint(vf) {  ENDPICK
     if (vf.intpwd.value!='') {  
        clearpwd(vf);  
        vf.login[1].checked=true;  
        vf.krbdom.value='';  
    }  
 }  }
   
 function clickkrb(vf) {  ###############################################################
     vf.krbdom.value='$krbdefdom';  ###############################################################
     clearpwd(vf);  sub upload_manager_javascript_reverse_associate {
     vf.intpwd.value='';      return(<<ENDPICK);
   function verify(vf) {
       var founduname=0;
       var foundpwd=0;
       var foundname=0;
       var foundid=0;
       var foundsec=0;
       var tw;
       for (i=0;i<=vf.nfields.value;i++) {
           tw=eval('vf.f'+i+'.selectedIndex');
           if (i==0 && tw!=0) { founduname=1; }
           if (((i>=1) && (i<=5)) && tw!=0 ) { foundname=1; }
           if (i==6 && tw!=0) { foundid=1; }
           if (i==7 && tw!=0) { foundsec=1; }
           if (i==8 && tw!=0) { foundpwd=1; }
       }
       verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
 }  }
   
 function clickint(vf) {  function flip(vf,tf) {
     vf.krbdom.value='';     var nw=eval('vf.f'+tf+'.selectedIndex');
      var i;
      // picked the all one one name field, reset the other name ones to blank
      if (tf==1 && nw!=0) {
         for (i=2;i<=5;i++) {
            eval('vf.f'+i+'.selectedIndex=0;')
         }
      }
      //picked one of the piecewise name fields, reset the all in
      //one field to blank
      if ((tf>=2) && (tf<=5) && (nw!=0)) {
         eval('vf.f1.selectedIndex=0;')
      }
      // intial password specified, pick internal authentication
      if (tf==8 && nw!=0) {
          changed_radio('int',document.studentform);
          set_auth_radio_buttons('int',document.studentform);
          vf.krbarg.value='';
          vf.intarg.value='';
          vf.locarg.value='';
      }
 }  }
   
     function pclose() {  function clearpwd(vf) {
         parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",      var i;
                  "height=350,width=350,scrollbars=no,menubar=no");      if (eval('vf.f8.selectedIndex')!=0) {
         parmwin.close();          eval('vf.f8.selectedIndex=0;')
     }  
   
     function pjump(type,dis,value,marker,ret,call) {  
         parmwin=window.open("/adm/rat/parameter.html?type="+escape(type)  
                  +"&value="+escape(value)+"&marker="+escape(marker)  
                  +"&return="+escape(ret)  
                  +"&call="+escape(call)+"&name="+escape(dis),"LONCAPAparms",  
                  "height=350,width=350,scrollbars=no,menubar=no");  
   
     }  
   
     function dateset() {  
         if (document.studentform.pres_marker.value=='end') {  
            document.studentform.enddate.value=  
        document.studentform.pres_value.value;  
         }  
         if (document.studentform.pres_marker.value=='start') {  
            document.studentform.startdate.value=  
        document.studentform.pres_value.value;  
         }  
         pclose();  
     }      }
   }
 </script>  
 <table border=2><tr><th>Field</th><th>Samples</th></tr>  
 ENDPICK  ENDPICK
              my %sone; my %stwo; my %sthree;  }
              my $i=0;  
   
              if ($total>=0) {  ###############################################################
                 %sone=&record_sep($records[0]);  ###############################################################
                 if ($total>=1) {  sub print_upload_manager_footer {
                    %stwo=&record_sep($records[1]);      my ($r,$i,$keyfields,$defdom,$today,$halfyear)=@_;
                      
         }      my ($krbdef,$krbdefdom) =
                 if ($total>=2) {          &Apache::loncommon::get_kerberos_defaults($defdom);
                    %sthree=&record_sep($records[2]);      my %param = ( formname => 'document.studentform',
         }                    kerb_def_dom => $krbdefdom,
                 map {                    kerb_def_auth => $krbdef
                    $r->print('<tr><td><select name=f'.$i.                    );
                        ' onChange="flip(this.form,'.$i.');">');      my $krbform = &Apache::loncommon::authform_kerberos(%param);
                    map {      my $intform = &Apache::loncommon::authform_internal(%param);
                       my ($value,$display)=split(/\:/,$_);      my $locform = &Apache::loncommon::authform_local(%param);
                       $r->print('<option value='.$value.'>'.$display.      my $domform = &domain_form($defdom);
                               '</option>');      my $date_table = &date_setting_table();
                    } ('none: ','username:Username',      $r->print(<<ENDPICK);
                       'names:Last Name, First Names',  
                       'fname:First Name','mname:Middle Names/Initials',  
                       'lname:Last Name','gen:Generation',  
                       'id:ID/Student Number','sec:Group/Section',  
                       'ipwd:Initial Password');  
                    $r->print('</select></td><td>');  
                    if (defined($sone{$i})) {   
                       $r->print($sone{$i}."</br>\n");   
                    }  
            if (defined($stwo{$i})) {   
                       $r->print($stwo{$i}."</br>\n");   
                    }  
            if (defined($sthree{$i})) {   
                       $r->print($sthree{$i}."</br>\n");   
                    }  
                    $r->print('</td></tr>');  
                    $i++;  
        } sort keys %sone;  
        $i--;  
      }  
              my $keyfields=join(',',sort keys %sone);  
              $r->print(<<ENDPICK);  
 </table>  </table>
 <input type=hidden name=nfields value=$i>  <input type=hidden name=nfields value=$i>
 <input type=hidden name=keyfields value="$keyfields">  <input type=hidden name=keyfields value="$keyfields">
 <h3>Login Type</h3>  <h3>Login Type</h3>
 <input type=radio name=login value=krb onClick="clickkrb(this.form);">  <p>Note: this will not take effect if the user already exists</p>
 Kerberos authenticated with domain  <p>
 <input type=text size=10 name=krbdom onChange="setkrb(this.form);"><p>  $krbform
 <input type=radio name=login value=int onClick="clickint(this.form);">   </p>
 Internally authenticated (with initial password   <p>
 <input type=text size=10 name=intpwd onChange="setint(this.form);">)  $intform
   </p>
   <p>
   $locform
   </p>
 <h3>LON-CAPA Domain for Students</h3>  <h3>LON-CAPA Domain for Students</h3>
 LON-CAPA domain: <input type=text size=10 value=$defdom name=lcdomain><p>  LON-CAPA domain: $domform <p>
 <h3>Starting and Ending Dates</h3>  <h3>Starting and Ending Dates</h3>
 <input type="hidden" value='' name="pres_value">  <p>
 <input type="hidden" value='' name="pres_type">  $date_table
 <input type="hidden" value='' name="pres_marker">  </p>
 <input type="hidden" value='$today' name=startdate>  
 <input type="hidden" value='$halfyear' name=enddate>  
 <a   
  href="javascript:pjump('date_start','Enrollment Starting Date',document.studentform.startdate.value,'start','studentform.pres','dateset');"  
 >Set Starting Date</a><p>  
   
 <a   
  href="javascript:pjump('date_end','Enrollment Ending Date',document.studentform.enddate.value,'end','studentform.pres','dateset');"  
 >Set Ending Date</a><p>  
 <h3>Full Update</h3>  <h3>Full Update</h3>
 <input type=checkbox name=fullup value=yes> Full update   <input type=checkbox name=fullup value=yes> Full update 
 (also dropping students)<p>  (also print list of users not enrolled anymore)<p>
 <input type=button onClick="verify(this.form)" value="Update Courselist"><br>  <h3>ID/Student Number</h3>
 Note: for large courses, this operation might be time consuming.  <input type=checkbox name=forceid value=yes> 
   Disable ID/Student Number Safeguard and Force Change of Conflicting IDs
   (only do if you know what you are doing)<p>
   <input type="button" onClick="javascript:verify(this.form)" value="Update Courselist" /><br />
   Note: for large courses, this operation may be time consuming.
 ENDPICK  ENDPICK
 }  }
   
 # ======================================================= Menu Phase Two Enroll  # ======================================================= Menu Phase Two Upload
   sub print_upload_manager_form {
       my $r=shift;
   
 sub menu_phase_two_enroll {      my $datatoken;
       if (!$ENV{'form.datatoken'}) {
         $datatoken=&Apache::loncommon::upfile_store($r);
       } else {
         $datatoken=$ENV{'form.datatoken'};
         &Apache::loncommon::load_tmp_file($r);
       }
       my @records=&Apache::loncommon::upfile_record_sep();
       my $total=$#records;
       my $distotal=$total+1;
       my $today=time;
       my $halfyear=$today+15552000;
       my $defdom=$r->dir_config('lonDefDomain');
       my ($krbdef,$krbdefdom) =
           &Apache::loncommon::get_kerberos_defaults($defdom);
       &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom);
       my $i;
       my $keyfields;
       if ($total>=0) {
    my @d=(['username','Username'],
                  ['names','Last Name, First Names'],
          ['fname','First Name'],
                  ['mname','Middle Names/Initials'],
          ['lname','Last Name'],
                  ['gen','Generation'],
          ['id','ID/Student Number'],
                  ['sec','Group/Section'],
          ['ipwd','Initial Password'],
                  ['email','EMail Address']);
    if ($ENV{'form.upfile_associate'} eq 'reverse') {
       &Apache::loncommon::csv_print_samples($r,\@records);
       $i=&Apache::loncommon::csv_print_select_table($r,\@records,\@d);
       foreach (@d) { $keyfields.=$_->[0].','; }
       chop($keyfields);
    } else {
       unshift(@d,['none','']);
       $i=&Apache::loncommon::csv_samples_select_table($r,\@records,\@d);
       my %sone=&Apache::loncommon::record_sep($records[0]);
       $keyfields=join(',',sort(keys(%sone)));
    }
       }
       &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear);
   }
   
   # ======================================================= Enroll single student
   sub enroll_single_student {
     my $r=shift;      my $r=shift;
       #
       # We do the dates first because the action of making them the defaul
       # in the course is entirely seperate from the action of enrolling the
       # student.  Also, a failure in setting the dates as default is not fatal
       # to the process of enrolling / modifying a student.
       my ($startdate,$enddate) = &get_dates_from_form();
       if ($ENV{'form.makedatesdefault'}) {
           $r->print(&make_dates_default($startdate,$enddate));
       }
   
       $r->print('<h3>Enrolling Student</h3>');
       $r->print('<p>Enrolling '.$ENV{'form.cuname'}." \@ ".
                 $ENV{'form.lcdomain'}.'</p>');
       if (($ENV{'form.cuname'})&&($ENV{'form.cuname'}!~/\W/)&&
           ($ENV{'form.lcdomain'})&&($ENV{'form.lcdomain'}!~/\W/)) {
           # Deal with home server selection
           my $domain=$ENV{'form.lcdomain'};
           my $desiredhost = $ENV{'form.lcserver'};
           if (lc($desiredhost) eq 'default') {
               $desiredhost = undef;
           } else {
               my %home_servers =&Apache::loncommon::get_library_servers($domain);
               if (! exists($home_servers{$desiredhost})) {
                   $r->print('<font color="#ff0000">Error:</font>'.
                             'Invalid home server specified');
                   return;
               }
           }
           $r->print(" with server $desiredhost :") if (defined($desiredhost));
           # End of home server selection logic
    my $amode='';
           my $genpwd='';
           if ($ENV{'form.login'} eq 'krb') {
              $amode='krb';
      $amode.=$ENV{'form.krbver'};
              $genpwd=$ENV{'form.krbarg'};
           } elsif ($ENV{'form.login'} eq 'int') {
              $amode='internal';
              $genpwd=$ENV{'form.intarg'};
           }  elsif ($ENV{'form.login'} eq 'loc') {
       $amode='localauth';
       $genpwd=$ENV{'form.locarg'};
       if (!$genpwd) { $genpwd=" "; }
    }
           my $home = &Apache::lonnet::homeserver($ENV{'form.cuname'},
                                                      $ENV{'form.lcdomain'});
           if ((($amode) && ($genpwd)) || ($home ne 'no_host')) {
               # Clean out any old roles the student has in this class.
               &modifystudent($ENV{'form.lcdomain'},$ENV{'form.cuname'},
                              $ENV{'request.course.id'},$ENV{'form.csec'},
                               $desiredhost);
               my $login_result = &Apache::lonnet::modifystudent
                   ($ENV{'form.lcdomain'},$ENV{'form.cuname'},
                    $ENV{'form.cstid'},$amode,$genpwd,
                    $ENV{'form.cfirst'},$ENV{'form.cmiddle'},
                    $ENV{'form.clast'},$ENV{'form.cgen'},
                    $ENV{'form.csec'},$enddate,
                    $startdate,$ENV{'form.forceid'},
                    $desiredhost);
               if ($login_result =~ /^ok/) {
                   $r->print($login_result);
                   $r->print("<p> If active, the new role will be available ".
                             "when the student next logs in to LON-CAPA.</p>");
               } else {
                   $r->print("unable to enroll: ".$login_result);
               }
    } else {
               $r->print('<p><font color="#ff0000">ERROR</font>&nbsp;'.
                         'Invalid login mode or password.  '.
                         'Unable to enroll '.$ENV{'form.cuname'}.'.</p>');
           }          
       } else {
           $r->print('Invalid username or domain');
       }    
 }  }
   
 # ========================================================= Menu Phase Two Drop  sub setup_date_selectors {
       my ($starttime,$endtime) = @_;
       if (! defined($starttime)) {
           $starttime = time;
           if (exists($ENV{'course.'.$ENV{'request.course.id'}.
                               '.default_enrollment_start_date'})) {
               $starttime = $ENV{'course.'.$ENV{'request.course.id'}.
                                     '.default_enrollment_start_date'};
           }
       }
       if (! defined($endtime)) {
           $endtime = time+(6*30*24*60*60); # 6 months from now, approx
           if (exists($ENV{'course.'.$ENV{'request.course.id'}.
                               '.default_enrollment_end_date'})) {
               $endtime = $ENV{'course.'.$ENV{'request.course.id'}.
                                   '.default_enrollment_end_date'};
           }
       }
       my $startdateform = &Apache::lonhtmlcommon::date_setter('studentform',
                                                               'startdate',
                                                               $starttime);
       my $enddateform = &Apache::lonhtmlcommon::date_setter('studentform',
                                                             'enddate',
                                                             $endtime);
       return ($startdateform,$enddateform);
   }
   
   sub get_dates_from_form {
       my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
       my $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate');
       if ($ENV{'form.no_end_date'}) {
           $enddate = 0;
       }
       return ($startdate,$enddate);
   }
   
   sub date_setting_table {
       my ($starttime,$endtime) = @_;
       my ($startform,$endform)=&setup_date_selectors($starttime,$endtime);
       my $dateDefault = '<nobr>'.
           '<input type="checkbox" name="makedatesdefault" />'.
           ' make these dates the default for future enrollment';
       my $perpetual = '<nobr><input type="checkbox" name="no_end_date"';
       if (defined($endtime) && $endtime == 0) {
           $perpetual .= ' checked';
       }
       $perpetual.= ' />'.' no ending date</nobr>';
       my $result = '';
       $result .= "<table>\n";
       $result .= '<tr><td align="right">Starting Date</td>'.
           '<td>'.$startform.'</td>'.
           '<td>'.$dateDefault.'</td>'."</tr>\n";
       $result .= '<tr><td align="right">Ending Date</td>'.
           '<td>'.$endform.'</td>'.
           '<td>'.$perpetual.'</td>'."</tr>\n";
       $result .= "</table>\n";
       return $result;
   }
   
 sub menu_phase_two_drop {  sub make_dates_default {
       my ($startdate,$enddate) = @_;
       my $result = '';
       my $dom = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
       my $crs = $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
       my $put_result = &Apache::lonnet::put('environment',
               {'default_enrollment_start_date'=>$startdate,
                'default_enrollment_end_date'  =>$enddate},$dom,$crs);
       if ($put_result eq 'ok') {
           $result .= "Set default start and end dates for course<br />";
           #
           # Refresh the course environment
           &Apache::lonnet::coursedescription($ENV{'request.course.id'});
       } else {
           $result .= "Unable to set default dates for course:".$put_result.
               '<br />';
       }
       return $result;
   }
   
   # ======================================================= Menu Phase Two Enroll
   sub print_enroll_single_student_form {
     my $r=shift;      my $r=shift;
       $r->print("<h3>Enroll One Student</h3>");
       my $today    = time;
       my $halfyear = $today+15552000;
       my $defdom=$r->dir_config('lonDefDomain');
       # Set up authentication forms
       my ($krbdef,$krbdefdom) =
           &Apache::loncommon::get_kerberos_defaults($defdom);
       my $javascript_validations=&javascript_validations($krbdefdom);
       my %param = ( formname => 'document.studentform',
                     kerb_def_dom => $krbdefdom,
                     kerb_def_auth => $krbdef
                     );
       my $krbform = &Apache::loncommon::authform_kerberos(%param);
       my $intform = &Apache::loncommon::authform_internal(%param);
       my $locform = &Apache::loncommon::authform_local(%param);
       # Set up domain selection form
       my $domform = &domain_form($defdom);
       my $date_table = &date_setting_table();
       # Print it all out
       $r->print(<<END);
   <input type="hidden" name="action" value="enrollstudent">
   <input type="hidden" name="state"  value="done">
   
   <script type="text/javascript" language="Javascript">
   function verify(vf) {
       var founduname=0;
       var foundpwd=0;
       var foundname=0;
       var foundid=0;
       var foundsec=0;
       var tw;
       if ((typeof(vf.cuname.value) !="undefined") && (vf.cuname.value!='') && 
    (typeof(vf.lcdomain.value)!="undefined") && (vf.lcdomain.value!='')) {
           founduname=1;
       }
       if ((typeof(vf.cfirst.value)!="undefined") && (vf.cfirst.value!='') &&
    (typeof(vf.clast.value) !="undefined") && (vf.clast.value!='')) {
           foundname=1;
       }
       if ((typeof(vf.csec.value)!="undefined") && (vf.csec.value!='')) {
           foundsec=1;
       }
       if ((typeof(vf.cstid.value)!="undefined") && (vf.cstid.value!='')) {
    foundid=1;
       }
       if (founduname==0) {
    alert('You need to specify at least the username and domain fields');
           return;
       }
       verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
 }  }
   
 # ================================================= Drop/Add from uploaded file  $javascript_validations
   
 sub upfile_drop_add {  function clearpwd(vf) {
       //nothing else needs clearing
   }
   
   </script>
   <h3>Personal Data</h3>
   <table>
   <tr><td>First Name:</td><td> <input type="text" name="cfirst"  size="15"></td></tr>
   <tr><td>Middle Name:</td><td> <input type="text" name="cmiddle" size="15"></td></tr>
   <tr><td>Last Name: </td><td><input type="text" name="clast"   size="15"></td></tr>
   <tr><td>Generation: </td><td><input type="text" name="cgen"    size="5"> </td></tr>
   </table>
   
   <h3>Login Data</h3>
   <p>Username: <input type="text" name="cuname"  size="15"></p>
   <p>Domain:   $domform</p>
   <p>Note: login settings below  will not take effect if the user already exists
   </p><p>
   $krbform
   </p><p>
   $intform
   </p><p>
   $locform
   </p><p>
   
   <h3>Course Data</h3>
   
   <p>Group/Section: <input type="text" name="csec" size="5" />
   <p>
   $date_table
   </p>
   <h3>ID/Student Number</h3>
   <p>
   ID/Student Number: <input type="text" name="cstid" size="10">
   </p><p>
   <input type="checkbox" name="forceid" value="yes"> 
   Disable ID/Student Number Safeguard and Force Change of Conflicting IDs
   (only do if you know what you are doing)
   </p><p>
   <input type="button" onClick="verify(this.form)" value="Enroll as student">
   </p>
   END
       return;
   }
   
   # ========================================================= Menu Phase Two Drop
   sub print_drop_menu {
     my $r=shift;      my $r=shift;
     $r->print('<input type=hidden name=phase value=four>');      $r->print("<h3>Drop Students</h3>");
       my $cid=$ENV{'request.course.id'};
       my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();
       if (! defined($classlist)) {
           $r->print("There are no students currently enrolled.\n");
           return;
       }
       # Print out the available choices
       &show_drop_list($r,$classlist,$keylist);
       return;
   }
   
     &load_tmp_file($r);  # ============================================== view classlist
     my @studentdata=&upfile_record_sep();  sub print_html_classlist {
       my $r=shift;
       if (! exists($ENV{'form.sortby'})) {
           $ENV{'form.sortby'} = 'username';
       }
       if ($ENV{'form.Status'} !~ /^(Any|Expired|Active)$/) {
           $ENV{'form.Status'} = 'Active';
       }
       my $status_select = &Apache::lonhtmlcommon::StatusOptions
           ($ENV{'form.Status'},'studentform');
       $r->print(<<END);
   <input type="hidden" name="action" value="$ENV{'form.action'}" />
   <input type="hidden" name="state"  value="" />
   <p>
   <font size="+1">Current Classlist</font>
   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
   END
       if ($ENV{'form.action'} ne 'modifystudent') {
           $r->print(<<END);
   <font size="+1">
   <a href="javascript:document.studentform.state.value='csv';document.studentform.submit();">CSV format</a>
   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
   <a href="javascript:document.studentform.state.value='excel';document.studentform.submit();">Excel format</a>
   </font>
   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
   Student Status:
   END
       }
       $r->print($status_select."</p>\n");
       my $cid=$ENV{'request.course.id'};
       my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
       if (! defined($classlist)) {
           $r->print("There are no students currently enrolled.\n");
       } else {
           # Print out the available choices
           if ($ENV{'form.action'} eq 'modifystudent') {
               &show_class_list($r,'view','modify','modifystudent',
                                $ENV{'form.Status'},$classlist,$keylist);
           } else {
               &show_class_list($r,'view','aboutme','classlist',
                                $ENV{'form.Status'},$classlist,$keylist);
           }
       }
   }
   
     my @keyfields=split(/\,/,$ENV{'form.keyfields'});  # ============================================== view classlist
   sub print_formatted_classlist {
       my $r=shift;
       my $mode = shift;
     my $cid=$ENV{'request.course.id'};      my $cid=$ENV{'request.course.id'};
       my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
       if (! defined($classlist)) {
           $r->print("There are no students currently enrolled.\n");
       } else {
           &show_class_list($r,$mode,'nolink','csv',
                            $ENV{'form.Status'},$classlist,$keylist);
       }
   }
   
   # =================================================== Show student list to drop
   sub show_class_list {
       my ($r,$mode,$linkto,$action,$statusmode,$classlist,$keylist)=@_;
       my $cid=$ENV{'request.course.id'};
       #
       # Variables for excel output
       my ($excel_workbook, $excel_sheet, $excel_filename,$row);
       #
       my $sortby = $ENV{'form.sortby'};
       if ($sortby !~ /^(username|domain|section|fullname|id)$/) {
           $sortby = 'username';
       }
       # Print out header 
       if ($mode eq 'view') {
           if ($linkto eq 'aboutme') {
               $r->print('Select a user name to view the users personal page.');
           } elsif ($linkto eq 'modify') {
               $r->print('Select a user name to modify the students information');
           }
           $r->print(<<END);
   
   <input type="hidden" name="sortby" value="$sortby" />
   <input type="hidden" name="sname"  value="" />
   <input type="hidden" name="sdom"   value="" />
   <p>
   <table border=2>
   <tr><th>
          <a href="javascript:document.studentform.sortby.value='username';document.studentform.submit();">username</a>
       </th><th>
          <a href="javascript:document.studentform.sortby.value='domain';document.studentform.submit();">domain</a>
       </th><th>
          <a href="javascript:document.studentform.sortby.value='id';document.studentform.submit();">ID</a>
       </th><th>
          <a href="javascript:document.studentform.sortby.value='fullname';document.studentform.submit();">student name</a>
       </th><th>
          <a href="javascript:document.studentform.sortby.value='section';document.studentform.submit();">section</a>
       </th>
   </tr>
   END
       } elsif ($mode eq 'csv') {
           if($statusmode eq 'Expired') {
               $r->print('"Students with expired roles"');
           }
           if ($statusmode eq 'Any') {
               $r->print('"'.join('","',("username","domain","ID","student name",
                                         "section","status")).'"'."\n");
           } else {
               $r->print('"'.join('","',("username","domain","ID","student name",
                                         "section")).'"'."\n");
           }
       } elsif ($mode eq 'excel') {
           # Create the excel spreadsheet
           $excel_filename = '/prtspool/'.
               $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
                   time.'_'.rand(1000000000).'.xls';
           $excel_workbook = Spreadsheet::WriteExcel->new('/home/httpd'.
                                                          $excel_filename);
           $excel_workbook->set_tempdir('/home/httpd/perl/tmp');
           $excel_sheet = $excel_workbook->addworksheet('classlist');
           #
           my $description = 'Classlist for '.
               $ENV{'course.'.$ENV{'request.course.id'}.'.description'};
           $excel_sheet->write($row++,0,$description);
           #
           $excel_sheet->write($row++,0,["username","domain","ID",
                                         "student name","section","status"]);
       }
       #
       # Sort the students
       my %index;
       my $i;
       foreach (@$keylist) {
           $index{$_} = $i++;
       }
       my $index  = $index{$sortby};
       my $second = $index{'username'};
       my $third  = $index{'domain'};
       my @Sorted_Students = sort {
           lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
               ||
           lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
               ||
           lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
           } (keys(%$classlist));
       foreach my $student (@Sorted_Students) {
           my $username = $classlist->{$student}->[$index{'username'}];
           my $domain   = $classlist->{$student}->[$index{'domain'}];
           my $section  = $classlist->{$student}->[$index{'section'}];
           my $name     = $classlist->{$student}->[$index{'fullname'}];
           my $id       = $classlist->{$student}->[$index{'id'}];
           my $status   = $classlist->{$student}->[$index{'status'}];
           next if (($statusmode ne 'Any') && ($status ne $statusmode));
           if ($mode eq 'view') {
               $r->print("<tr>\n    <td>\n        ");
               if ($linkto eq 'nothing') {
                   $r->print($username);
               } elsif ($linkto eq 'aboutme') {
                   $r->print(&Apache::loncommon::aboutmewrapper($username,
                                                                $username,
                                                                $domain));
               } elsif ($linkto eq 'modify') {
                   $r->print('<a href="'.
                             "javascript:document.studentform.sname.value='".
                             $username.
                             "';document.studentform.sdom.value='".$domain.
                             "';document.studentform.state.value='selected".
                             "';document.studentform.submit();".'">'.
                             $username."</a>\n");
               }
               $r->print(<<"END");
       </td>
       <td>$domain</td>
       <td>$id</td>
       <td>$name</td>
       <td>$section</td>
   </tr>
   END
           } elsif ($mode eq 'csv') {
               # no need to bother with $linkto
               my @line = ();
               foreach ($username,$domain,$id,$name,$section) {
                   push @line,&Apache::loncommon::csv_translate($_);
               }
               if ($statusmode eq 'Any') {
                   push @line,&Apache::loncommon::csv_translate($status);
               }
               my $tmp = $";
               $" = '","';
               $r->print("\"@line\"\n");
               $" = $tmp;
           } elsif ($mode eq 'excel') {
               $excel_sheet->write($row++,0,[$username,$domain,$id,
                                             $name,$section,$status]);
           }
       }
       if ($mode eq 'view') {
           $r->print('</table><br>');
       } elsif ($mode eq 'excel') {
           $excel_workbook->close();
           $r->print('<p><a href="'.$excel_filename.'">'.
                     'Your Excel spreadsheet</a> is ready for download.</p>'."\n");
       }
   }
   
   
   #
   # print out form for modification of a single students data
   #
   sub print_modify_student_form {
       my $r = shift();
       &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                               ['sdom','sname']);    
       my $sname  = $ENV{'form.sname'};
       my $sdom   = $ENV{'form.sdom'};
       my $sortby = $ENV{'form.sortby'};
       # determine the students name information
       my %info=&Apache::lonnet::get('environment',
                                     ['firstname','middlename',
                                      'lastname','generation','id'],
                                     $sdom, $sname);
       my ($tmp) = keys(%info);
       if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
           $r->print('<font color="#ff0000" size="+2">Error</font>'.
                     '<p>'.
                     'Unable to retrieve environment data for '.$sname.
                     'in domain '.$sdom.'</p><p>'.
                     'Please contact your LON-CAPA administrator '.
                     'regarding this situation.</p></body></html>');
           return;
       }
       # determine the students starting and ending times and section
       my ($starttime,$endtime,$section) = &get_enrollment_data($sname,$sdom);
       # Deal with date forms
       my $date_table = &date_setting_table($starttime,$endtime);
       #
       if (! exists($ENV{'form.Status'}) || 
           $ENV{'form.Status'} !~ /^(Any|Expired|Active)$/) {
           $ENV{'form.Status'} = 'crap';
       }
       # Make sure student is enrolled in course    
       $r->print(<<END);
   <p>
   <font size="+1">
   Only domain coordinators can change a users password.
   </font>
   </p>
   <input type="hidden" name="slogin"  value="$sname"  />
   <input type="hidden" name="sdomain" value="$sdom" />
   <input type="hidden" name="action"  value="modifystudent" />
   <input type="hidden" name="state"   value="done" />
   <input type="hidden" name="sortby"  value="$sortby" />
   <input type="hidden" name="Status"  value="$ENV{'form.Status'}" />
   
   <h2>Modify Enrollment for $info{'firstname'} $info{'middlename'} 
   $info{'lastname'} $info{'generation'}, $sname\@$sdom</h2>
   <p>
   <b>Student Name</b>
   <table>
   <tr><th>First</th><th>Middle</th><th>Last</th><th>Generation</th></tr>
   <tr><td>
   <input type="text" name="firstname"  value="$info{'firstname'}"  /></td><td>
   <input type="text" name="middlename" value="$info{'middlename'}" /></td><td>
   <input type="text" name="lastname"   value="$info{'lastname'}"   /></td><td>
   <input type="text" name="generation" value="$info{'generation'}" /></td></tr>
   </table>
   </p><p>
   <b>Student ID</b>: <input type="text" name="id" value="$info{'id'}" size="12"/>
   </p><p>
   <input type="checkbox" name="forceid" > 
   Disable ID/Student Number Safeguard and Force Change of Conflicting IDs
   (only do if you know what you are doing)
   </p><p>
   <b>Section</b>: <input type="text" name="section" value="$section" size="4"/>
   </p>
   <p>$date_table</p>
   <input type="submit" value="Submit Modifications" />
   </body></html>
   END
       return;
   }
   
   #
   # modify a single students section 
   #
   sub modify_single_student {
       my $r = shift;
       #
       # Do the date defaults first
       my ($starttime,$endtime) = &get_dates_from_form();
       if ($ENV{'form.makedatesdefault'}) {
           $r->print(&make_dates_default($starttime,$endtime));
       }
       # Get the 'sortby' and 'Status' variables so the user goes back to their
       # previous screen
       my $sortby = $ENV{'form.sortby'};
       my $status = $ENV{'form.Status'};
       #
       # We always need this information
       my $slogin     = $ENV{'form.slogin'};
       my $sdom       = $ENV{'form.sdomain'};
       #
       # Get the old data
       my %old=&Apache::lonnet::get('environment',
                                    ['firstname','middlename',
                                     'lastname','generation','id'],
                                    $sdom, $slogin);
       $old{'section'} = &Apache::lonnet::getsection($sdom,$slogin,
                                                     $ENV{'request.course.id'});
       my ($tmp) = keys(%old);
       if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
           $r->print("There was an error determining the environment values ".
                     " for $slogin \@ $sdom.");
           return;
       }
       undef $tmp;
       #
       # Get the new data
       my $firstname  = $ENV{'form.firstname'};
       my $middlename = $ENV{'form.middlename'};
       my $lastname   = $ENV{'form.lastname'};
       my $generation = $ENV{'form.generation'};
       my $section    = $ENV{'form.section'};
       my $courseid   = $ENV{'request.course.id'};
       my $sid        = $ENV{'form.id'};
       my $displayable_starttime = localtime($starttime);
       my $displayable_endtime   = localtime($endtime);
       # 
       # check for forceid override
       if ((defined($old{'id'})) && ($old{'id'} ne '') && 
           ($sid ne $old{'id'}) && (! exists($ENV{'form.forceid'}))) {
           $r->print("<font color=\"ff0000\">You changed the students id ".
                     " but did not disable the ID change safeguard.".
                     "  The students id will not be changed.</font>");
           $sid = $old{'id'};
       }
       #
       # talk to the user about what we are going to do
       $r->print(<<END);
       <h2>Modifying data for user $slogin \@ $sdom </h2>
   <h3>Student Information</h3>
   <table rules="rows" border="1" cellpadding="3" >
   <tr>
       <th> Field </th>
       <th> Old Value </th>
       <th> New Value </th>
   </tr>
   <tr>
       <td> <b>First name</b> </td>
       <td> $old{'firstname'} </td>
       <td> $firstname </td>
   </tr><tr>
       <td> <b>Middle name</b> </td>
       <td> $old{'middlename'} </td>
       <td> $middlename </td>
   </tr><tr>
       <td> <b>Last name</b> </td>
       <td> $old{'lastname'} </td>
       <td> $lastname </td>
   </tr><tr>
       <td> <b>Generation</b> </td>
       <td> $old{'generation'} </td>
       <td> $generation </td>
   </tr><tr>
       <td> <b>ID</b> </td>
       <td> $old{'id'} </td>
       <td> $sid </td>
   </tr><tr>
       <td> <b>Section</b> </td>
       <td> $old{'section'} </td>
       <td> $section</td>
   </tr>
   </table>
   <h3>Role Information</h3>
   <table>
   <tr><td align="right"><b>Start Time:</b></td><td> $displayable_starttime </td></tr>
   <tr><td align="right"><b>End Time:</b></td><td> $displayable_endtime   </td></tr>
   </table>
   <p>
   END
       #
       # Send request(s) to modify data (final undef is for 'desiredhost',
       # which is a moot point because the student already has an account.
       my $modify_section_results = &modifystudent($sdom,$slogin,
                                                   $ENV{'request.course.id'},
                                                   $section,undef);
       if ($modify_section_results !~ /^ok/) {
           $r->print("An error occured during the attempt to change the ".
                     "section for this student.<br />");
       }
       my $roleresults = &Apache::lonnet::modifystudent
           ($sdom,$slogin,$sid,undef,undef,$firstname,$middlename,$lastname,
            $generation,$section,$endtime,$starttime,$ENV{'form.forceid'});
       if ($roleresults eq 'refused' ) {
           $r->print("Your request to change the role information for this ".
                     "student was refused.  You do not appear to have ".
                     "sufficient authority to change student information.");
       } elsif ($roleresults !~ /ok/) {
           $r->print("An error occurred during the attempt to change the role".
                     " information for this student.  <br />".
                     "The error reported was ".
                     $roleresults);
           &Apache::lonnet::logthis("londropadd:failed attempt to modify student".
                                    " data for ".$slogin." \@ ".$sdom." by ".
                                    $ENV{'user.name'}." \@ ".$ENV{'user.domain'}.
                                    ":".$roleresults);
       } else { # everything is okay!
           $r->print("Student information updated successfully. <br />".
                     "The student must log out and log in again to see ".
                     "these changes.");
       }
       $r->print(<<END);
   </p><p>
   <input type="hidden" name="action" value="modifystudent" />
   <input type="hidden" name="sortby" value="$sortby" />
   <input type="hidden" name="Status" value="$status" />
   <a href="javascript:document.studentform.submit();">Modify another students data</a>
   </body></html>
   END
       return;
   }
   
   sub get_enrollment_data {
       my ($sname,$sdomain) = @_;
       my $courseid = $ENV{'request.course.id'};
       $courseid =~ s:_:/:g;
       my %roles = &Apache::lonnet::dump('roles',$sdomain,$sname);
       my ($tmp) = keys(%roles);
       # Bail out if we were unable to get the students roles
       return "666" if ($tmp =~ /^(con_lost|error|no_such_host)/i);
       # Go through the roles looking for enrollment in this course
       my ($end,$start) = (undef,undef);
       my $section = '';
       my $count = scalar(keys(%roles));
       while (my ($course,$role) = each(%roles)) {
           if ($course=~ /^\/$courseid\/*\s*(\w+)*_st$/ ) {
               #
               # Get active role
               $section=$1;
               (undef,$end,$start)=split(/\_/,$role);
               my $now=time;
               my $notactive=0;
               if ($start) {
                   if ($now<$start) { $notactive=1; }
               }
               if ($end) {
                   if ($now>$end) { $notactive=1; }
               } 
               unless ($notactive) { return ($start,$end,$section); }
           }
       }
       return ($start,$end,$section);
   }
   
   #################################################
   #################################################
   
              my %fields=();  =pod
              for (my $i=0;$i<=$ENV{'form.nfields'};$i++) {  
                  $fields{$ENV{'form.f'.$i}}=$keyfields[$i];  =item show_drop_list
              }  
              my $startdate=$ENV{'form.startdate'};  Display a list of students to drop
              my $enddate=$ENV{'form.enddate'};  Inputs: 
              if ($startdate=~/\D/) { $startdate=''; }  
              if ($enddate=~/\D/) { $enddate=''; }  =over 4
              my $domain=$ENV{'form.lcdomain'};  
              my $amode='';  =item $r, Apache request
              my $genpwd='';  
              if ($ENV{'form.login'} eq 'krb') {  =item $classlist, hash pointer returned from loncoursedata::get_classlist();
                  $amode='krb4';  
                  $genpwd=$ENV{'form.krbdom'};  =item $keylist, array pointer returned from loncoursedata::get_classlist() 
              } elsif ($ENV{'form.login'} eq 'int') {  which describes the order elements are stored in the %$classlist values.
                  $amode='internal';  
                  if ((defined($ENV{'form.intpwd'})) && ($ENV{'form.intpwd'})) {  =item $nosort, if true, sorting links are omitted.
      $genpwd=$ENV{'form.intpwd'};  
                  }  =back
              }  
              unless (($domain=~/\W/) || ($amode eq '')) {  =cut
               $r->print('<h3>Enrolling Students</h3>');  
               my $count=0;  #################################################
               my $flushc=0;  #################################################
               my %student=();  sub show_drop_list {
 # ----------------------------------------------------------- Get new classlist      my ($r,$classlist,$keylist,$nosort)=@_;
 # --------------------------------------------------------- Enroll new students      my $cid=$ENV{'request.course.id'};
       map {      if (! exists($ENV{'form.sortby'})) {
   my %entries=&record_sep($_);          &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                                   ['sortby']);
                 unless (($entries{$fields{'username'}} eq '') ||      }
                         (!defined($entries{$fields{'username'}}))) {      my $sortby = $ENV{'form.sortby'};
                   my $fname=''; my $mname=''; my $lname=''; my $gen='';      if ($sortby !~ /^(username|domain|section|fullname|id)$/) {
                   if (defined($fields{'names'})) {          $sortby = 'username';
       ($lname,$fname,$mname)=      }
             ($entries{$fields{'names'}}=~/([^\,]+)\,\s*(\w+)\s*(.*)$/);      #
                   } else {      my $action = "drop";
                       if (defined($fields{'fname'})) {      $r->print(<<END);
          $fname=$entries{$fields{'fname'}};  <input type="hidden" name="sortby" value="$sortby" />
       }  <input type="hidden" name="action" value="$action" />
                       if (defined($fields{'mname'})) {  <input type="hidden" name="state"  value="done" />
          $mname=$entries{$fields{'mname'}};  <script>
       }  function checkAll(field) {
                       if (defined($fields{'lname'})) {      for (i = 0; i < field.length; i++)
          $lname=$entries{$fields{'lname'}};          field[i].checked = true ;
       }  }
                       if (defined($fields{'gen'})) {  
          $gen=$entries{$fields{'gen'}};  function uncheckAll(field) {
       }      for (i = 0; i < field.length; i++)
                   }          field[i].checked = false ;
                   if ($entries{$fields{'username'}}=~/\W/) {  }
                      $r->print('<p><b>Unacceptable username: '.  </script>
   <p>
   <input type="hidden" name="phase" value="four">
   END
   
       if ($nosort) {
           $r->print(<<END);
   <table border=2>
   <tr>
       <th>&nbsp;</th>
       <th>username</th>
       <th>domain</th>
       <th>ID</th>
       <th>student name</th>
       <th>section</th>
   </tr>
   END
   
       } else  {
           $r->print(<<END);
   <table border=2>
   <tr><th>&nbsp;</th>
       <th>
          <a href="/adm/dropadd?action=$action&sortby=username">username</a>
       </th><th>
          <a href="/adm/dropadd?action=$action&sortby=domain">domain</a>
       </th><th>
          <a href="/adm/dropadd?action=$action&sortby=id">ID</a>
       </th><th>
          <a href="/adm/dropadd?action=$action&sortby=fullname">student name</a>
       </th><th>
          <a href="/adm/dropadd?action=$action&sortby=section">section</a>
       </th>
   </tr>
   END
       }
       #
       # Sort the students
       my %index;
       my $i;
       foreach (@$keylist) {
           $index{$_} = $i++;
       }
       my $index  = $index{$sortby};
       my $second = $index{'username'};
       my $third  = $index{'domain'};
       my @Sorted_Students = sort {
           lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
               ||
           lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
               ||
           lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
           } (keys(%$classlist));
       foreach my $student (@Sorted_Students) {
           my $error;
           my $username = $classlist->{$student}->[$index{'username'}];
           my $domain   = $classlist->{$student}->[$index{'domain'}];
           my $section  = $classlist->{$student}->[$index{'section'}];
           my $name     = $classlist->{$student}->[$index{'fullname'}];
           my $id       = $classlist->{$student}->[$index{'id'}];
           my $status   = $classlist->{$student}->[$index{'status'}];
           next if ($status ne 'Active');
           #
           $r->print(<<"END");
   <tr>
       <td><input type="checkbox" name="droplist" value="$student"></td>
       <td>$username</td>
       <td>$domain</td>
       <td>$id</td>
       <td>$name</td>
       <td>$section</td>
   </tr>
   END
       }
       $r->print('</table><br>');
       $r->print(<<"END");
   </p><p>
   <input type="button" value="check all" onclick="javascript:checkAll(document.studentform.droplist)"> &nbsp;
   <input type="button" value="uncheck all" onclick="javascript:uncheckAll(document.studentform.droplist)"> 
   <p><input type=submit value="Drop Students"></p>
   END
       return;
   }
   
   #
   # Print out the initial form to get the courselist file
   #
   sub print_first_courselist_upload_form {
       my $r=shift;
       my $upfile_select=&Apache::loncommon::upfile_select_html();
       my $create_classlist_help = 
    &Apache::loncommon::help_open_topic("Course_Create_Class_List",
              "How do I create a class list from a spreadsheet");
       my $create_csv_help =
    &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
              "How do I create a CSV file from a spreadsheet");
       $r->print(<<ENDUPFORM);
   <input type=hidden name=phase value=two>
   <h3>Upload a courselist</h3>
   $upfile_select
   <p>
   <input type=submit name="fileupload" value="Upload Courselist">
   <input type="hidden" name="action" value="upload" />
   <input type="hidden" name="state"  value="got_file" />
   </p>
   $create_classlist_help <br />
   $create_csv_help
   </body></html>
   ENDUPFORM
       return;
   }
   
   # ================================================= Drop/Add from uploaded file
   sub upfile_drop_add {
       my $r=shift;
       &Apache::loncommon::load_tmp_file($r);
       my @studentdata=&Apache::loncommon::upfile_record_sep();
       my @keyfields = split(/\,/,$ENV{'form.keyfields'});
       my $cid = $ENV{'request.course.id'};
       my %fields=();
       for (my $i=0; $i<=$ENV{'form.nfields'}; $i++) {
           if ($ENV{'form.upfile_associate'} eq 'reverse') {
               if ($ENV{'form.f'.$i} ne 'none') {
                   $fields{$keyfields[$i]}=$ENV{'form.f'.$i};
               }
           } else {
               $fields{$ENV{'form.f'.$i}}=$keyfields[$i];
           }
       }
       #
       my ($startdate,$enddate) = &get_dates_from_form();
       if ($ENV{'form.makedatesdefault'}) {
           $r->print(&make_dates_default($startdate,$enddate));
       }
       # Determine domain and desired host (home server)
       my $domain=$ENV{'form.lcdomain'};
       my $desiredhost = $ENV{'form.lcserver'};
       if (lc($desiredhost) eq 'default') {
           $desiredhost = undef;
       } else {
           my %home_servers = &Apache::loncommon::get_library_servers($domain);
           if (! exists($home_servers{$desiredhost})) {
               $r->print('<font color="#ff0000">Error:</font>'.
                         'Invalid home server specified');
               return;
           }
       }
       # Determine authentication mechanism
       my $amode  = '';
       my $genpwd = '';
       if ($ENV{'form.login'} eq 'krb') {
           $amode='krb';
    $amode.=$ENV{'form.krbver'};
           $genpwd=$ENV{'form.krbarg'};
       } elsif ($ENV{'form.login'} eq 'int') {
           $amode='internal';
           if ((defined($ENV{'form.intarg'})) && ($ENV{'form.intarg'})) {
               $genpwd=$ENV{'form.intarg'};
           }
       } elsif ($ENV{'form.login'} eq 'loc') {
           $amode='localauth';
           if ((defined($ENV{'form.locarg'})) && ($ENV{'form.locarg'})) {
               $genpwd=$ENV{'form.locarg'};
           }
       }
       unless (($domain=~/\W/) || ($amode eq '')) {
           #######################################
           ##         Enroll Students           ##
           #######################################
           $r->print('<h3>Enrolling Students</h3>'."\n".'<p>');
           my $count=0;
           my $flushc=0;
           my %student=();
           # Get new classlist
           foreach (@studentdata) {
               my %entries=&Apache::loncommon::record_sep($_);
               # Determine student name
               unless (($entries{$fields{'username'}} eq '') ||
                       (!defined($entries{$fields{'username'}}))) {
                   my ($fname, $mname, $lname,$gen) = ('','','','');
                   if (defined($fields{'names'})) {
                       ($lname,$fname,$mname)=($entries{$fields{'names'}}=~
                                               /([^\,]+)\,\s*(\w+)\s*(.*)$/);
                   } else {
                       if (defined($fields{'fname'})) {
                           $fname=$entries{$fields{'fname'}};
                       }
                       if (defined($fields{'mname'})) {
                           $mname=$entries{$fields{'mname'}};
                       }
                       if (defined($fields{'lname'})) {
                           $lname=$entries{$fields{'lname'}};
                       }
                       if (defined($fields{'gen'})) {
                           $gen=$entries{$fields{'gen'}};
                       }
                   }
                   if ($entries{$fields{'username'}}=~/\W/) {
                       $r->print('<br /><b>Unacceptable username: '.
                               $entries{$fields{'username'}}.' for user '.                                $entries{$fields{'username'}}.' for user '.
                               $fname.' '.$mname.' '.$lname.' '.$gen.'</b><p>');                                $fname.' '.$mname.' '.$lname.' '.$gen.'</b>');
   } else {                  } else {
                       my $sec='';                      # determine section number
                       my $username=$entries{$fields{'username'}};                      my $sec='';
                       if (defined($fields{'sec'})) {                      my $username=$entries{$fields{'username'}};
                          if (defined($entries{$fields{'sec'}})) {                      if (defined($fields{'sec'})) {
      $sec=$entries{$fields{'sec'}};                          if (defined($entries{$fields{'sec'}})) {
                          }                              $sec=$entries{$fields{'sec'}};
                       }                          }
                       my $id='';                      }
                       if (defined($fields{'id'})) {                      # determine student id number
                          if (defined($entries{$fields{'id'}})) {                      my $id='';
      $id=$entries{$fields{'id'}};                      if (defined($fields{'id'})) {
                          }                          if (defined($entries{$fields{'id'}})) {
                          $id=~tr/A-Z/a-z/;                              $id=$entries{$fields{'id'}};
                       }                          }
                       my $password='';                          $id=~tr/A-Z/a-z/;
                       if ($genpwd) {                       }
                          $password=$genpwd;                       # determine email address
       } else {                      my $email='';
                          if (defined($fields{'ipwd'})) {                      if (defined($fields{'email'})) {
      if ($entries{$fields{'ipwd'}}) {                          if (defined($entries{$fields{'email'}})) {
  $password=$entries{$fields{'ipwd'}};                              $email=$entries{$fields{'email'}};
                              }                              unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }
                          }                          }
                       }                      }
                       if ($password) {                      # determine student password
  &dropstudent($domain,$username,$cid,$sec);                      my $password='';
                          my $reply=&Apache::lonnet::modifystudent(                      if ($genpwd) { 
                           $domain,$username,$id,$amode,$password,                          $password=$genpwd; 
    $fname,$mname,$lname,$gen,$sec,$enddate,$startdate);                      } else {
                          unless ($reply eq 'ok') {                          if (defined($fields{'ipwd'})) {
                             $r->print(                              if ($entries{$fields{'ipwd'}}) {
                              "<p><b>Error enrolling $username: $reply</b><p>");                                  $password=$entries{$fields{'ipwd'}};
                               }
                           }
                       }
                       # Clean up whitespace
                       foreach (\$domain,\$username,\$id,\$fname,\$mname,
                                \$lname,\$gen,\$sec) {
                           $$_ =~ s/(\s+$|^\s+)//g;
                       }
                       if ($password) {
                           &modifystudent($domain,$username,$cid,$sec,
                                          $desiredhost);
                           my $reply=&Apache::lonnet::modifystudent
                               ($domain,$username,$id,$amode,$password,
                                $fname,$mname,$lname,$gen,$sec,$enddate,
                                $startdate,$ENV{'form.forceid'},$desiredhost,
                                $email);
                           if ($reply ne 'ok') {
                               $reply =~ s/^error://;
                               $r->print('<br /><b>'.$username.'</b>:'.
                                         '  Unable to enroll: '.$reply);
           } else {            } else {
                             $count++; $flushc++;                              $count++; $flushc++;
                             $student{$username}=1;                              $student{$username}=1;
Line 580  sub upfile_drop_add { Line 1565  sub upfile_drop_add {
                                 $flushc=0;                                  $flushc=0;
                             }                              }
                         }                          }
                      } else {                      } else {
                             $r->print(                          $r->print('<br /><b>'.$username.'</b>:'.
                              "<p><b>No password for $username</b><p>");                             '  Unable to enroll: No password specified.');
                      }                      }
                   }                  }
                  }                               }
               } @studentdata;          } # end of foreach (@studentdata)
               $r->print('<p>Processed Students: '.$count);          $r->print('</p><p>Processed Students: '.$count.'</p>');
 # --------------------------------------------------------------- Drop students          $r->print("<p>If active, the new role will be available when the ".
               if ($ENV{'form.fullup'} eq 'yes') {                    "students next log in to LON-CAPA.</p>");
  $r->print('<h3>Dropping Students</h3>');          #####################################
 # ------------------------------------------------------- Get current classlist          #           Drop students           #
                  my $classlst=&Apache::lonnet::reply          #####################################
                  ('dump:'.$ENV{'course.'.$cid.'.domain'}.':'.          if ($ENV{'form.fullup'} eq 'yes') {
                   $ENV{'course.'.$cid.'.num'}.':classlist',              $r->print('<h3>Dropping Students</h3>');
                   $ENV{'course.'.$cid.'.home'});              #  Get current classlist
                  my %currentlist=();              my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                  my $now=time;              if (! defined($classlist)) {
                  unless ($classlst=~/^error\:/) {                  $r->print("There are no students currently enrolled.\n");
                      map {              } else {
                         my ($name,$value)=split(/\=/,$_);                  # Remove the students we just added from the list of students.
                         my ($end,$start)=split(/\:/,                  foreach (@studentdata) {
                                             &Apache::lonnet::unescape($value));                      my %entries=&Apache::loncommon::record_sep($_);
                         my $active=1;                      unless (($entries{$fields{'username'}} eq '') ||
                         if (($end) && ($now>$end)) { $active=0; }                              (!defined($entries{$fields{'username'}}))) {
                         if ($active) {                          delete($classlist->{$entries{$fields{'username'}}.
            $currentlist{&Apache::lonnet::unescape($name)}=1;                                                  ':'.$domain});
                         }                      }
                      } split(/\&/,$classlst);                  }
 # ------------------------------------------------ Now got up-to-date classlist                  # Print out list of dropped students.
                      map {                  &show_drop_list($r,$classlist,$keylist,'nosort');
                  my %entries=&record_sep($_);              }
                         unless (($entries{$fields{'username'}} eq '') ||          }
                           (!defined($entries{$fields{'username'}}))) {      } # end of unless
    delete($currentlist{  
                             $entries{$fields{'username'}}.':'.  
                             $domain});  
         }  
                      } @studentdata;  
 # ----------------------------------------------------------- Print out choices  
                      $r->print('<table border=2>');  
                      map {  
                          my ($sname,$sdom)=split(/\:/,$_);  
                          my %reply=&Apache::lonnet::idrget($sdom,$sname);  
                          my $ssec=&Apache::lonnet::usection($sdom,$sname,$cid);  
                          my @reply=split(/[\&\=]/,&Apache::lonnet::reply(  
                            'get:'.$sdom.':'.$sname.  
       ':environment:firstname&middlename&lastname&generation',  
                            &Apache::lonnet::homeserver($sname,$sdom)));  
   $r->print(  
                   '<tr><td><input type=checkbox name="drop:'.$_.'"></td><td>'.  
                                    $sname.'</td><td>'.$sdom.'</td><td>'.  
                                    $reply{$sname}.'</td><td>'.  
                                    $reply[2].' '.$reply[3],', '.$reply[0].' '.  
                                    $reply[1].'</td><td>'.  
                                    $ssec."</td></tr>\n");  
                      } sort keys %currentlist;  
                      $r->print('</table><br>');  
                      $r->print('<input type=submit value="Drop Students">');  
   
          } else {  
                      $r->print(  
                   '<font color=red><h3>Could not access classlist: '.$classlst.  
                   '</h3></font>');  
                  }  
      }  
 # ------------------------------------------------------------------------ Done  
   
   }  
 }  }
   
 # ================================================================ Main Handler  # ================================================================== Phase four
   sub drop_student_list {
 sub handler {      my $r=shift;
    my $r=shift;      my $count=0;
       my @droplist;
       if (ref($ENV{'form.droplist'})) {
           @droplist = @{$ENV{'form.droplist'}};
       } else {
           @droplist = ($ENV{'form.droplist'});
       }
       foreach (@droplist) {
           my ($uname,$udom)=split(/\:/,$_);
           # drop student
           my $result = &modifystudent($udom,$uname,$ENV{'request.course.id'});
           if ($result eq 'ok' || $result eq 'ok:') {
               $r->print('Dropped '.$uname.' @ '.$udom.'<br>');
               $count++;
           } else {
               $r->print('Error dropping '.$uname.' @ '.$udom.': '.$result.
                         '<br />');
           }
       }
       $r->print('<p><b>Dropped '.$count.' student(s).</b>');
       $r->print('<p>Re-enrollment will re-activate data.') if ($count);
   }
   
    if ($r->header_only) {  ###################################################################
       $r->content_type('text/html');  ###################################################################
       $r->send_http_header;  
       return OK;  
    }  
   
 # ----------------------------------------------------- Needs to be in a course  =pod
   
    if (($ENV{'request.course.fn'}) &&   =item &handler
        (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'}))) {  
   
 # ------------------------------------------------------------------ Start page  The typical handler you see in all these modules.  Takes $r, the
       $r->content_type('text/html');  http request, as an argument.  
       $r->send_http_header;  
       &header($r);  The response to the request is governed by two form variables
   
 # --------------------------------------------------- Phase one, initial screen   form.action      form.state     response
       unless ($ENV{'form.phase'}) {   ---------------------------------------------------
   &menu_phase_one($r);   undefined        undefined      print main menu
       }   upload           undefined      print courselist upload menu
 # ------------------------------------------------------------------- Phase two   upload           got_file       deal with uploaded file,
       if ($ENV{'form.phase'} eq 'two') {                                   print the upload managing menu
  if ($ENV{'form.fileupload'}) {   upload           enrolling      enroll students based on upload
      &menu_phase_two_upload($r);   drop             undefined      print the classlist ready to drop
          } elsif ($ENV{'form.enroll'}) {   drop             done           drop the selected students
              &menu_phase_two_enroll($r);   enrollstudent    undefined      print single student enroll menu
          } elsif ($ENV{'form.drop'}) {   enrollstudent    enrolling      enroll student
              &menu_phase_two_drop($r);   classlist        undefined      print html classlist
          }   classlist        csv            print csv classlist
       }   modifystudent    undefined      print classlist to select student to modify
    modifystudent    selected       print modify student menu
    modifystudent    done           make modifications to student record
   
   =cut
   
   ###################################################################
   ###################################################################
 # ----------------------------------------------------------------- Phase three  sub handler {
       if ($ENV{'form.phase'} eq 'three') {      my $r=shift;
   if ($ENV{'form.datatoken'}) {      if ($r->header_only) {
       &upfile_drop_add($r);          $r->content_type('text/html');
           }          $r->send_http_header;
       }          return OK;
 # ------------------------------------------------------------------------- End      }
       $r->print('</form></body></html>');      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
    } else {                                              ['action','state']);
 # ----------------------------- Not in a course, or not allowed to modify parms      #  Needs to be in a course
       $ENV{'user.error.msg'}=      if (! (($ENV{'request.course.fn'}) &&
         "/adm/dropadd:cst:0:0:Cannot drop or add students";            (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'})))) {
       return HTTP_NOT_ACCEPTABLE;           # Not in a course, or not allowed to modify parms
    }          $ENV{'user.error.msg'}=
    return OK;              "/adm/dropadd:cst:0:0:Cannot drop or add students";
           return HTTP_NOT_ACCEPTABLE; 
       }
       #
       # Only output the header information if they did not request csv format
       #
       if (exists($ENV{'form.state'}) && ($ENV{'form.state'} eq 'csv')) {
           $r->content_type('text/csv');
       } else {
           # Start page
           $r->content_type('text/html');
           $r->send_http_header;
           $r->print(&header());
       }
       #
       # Main switch on form.action and form.state, as appropriate
       if (! exists($ENV{'form.action'})) {
           &print_main_menu($r);
       } elsif ($ENV{'form.action'} eq 'upload') {
           if (! exists($ENV{'form.state'})) {
               &print_first_courselist_upload_form($r);            
           } elsif ($ENV{'form.state'} eq 'got_file') {
               &print_upload_manager_form($r);
           } elsif ($ENV{'form.state'} eq 'enrolling') {
               if ($ENV{'form.datatoken'}) {
                   &upfile_drop_add($r);
               } else {
                   # Hmmm, this is an error
               }
           } else {
               &print_first_courselist_upload_form($r);            
           }
       } elsif ($ENV{'form.action'} eq 'drop') {
           if (! exists($ENV{'form.state'})) {
               &print_drop_menu($r);
           } elsif ($ENV{'form.state'} eq 'done') {
               &drop_student_list($r);
           } else {
               &print_drop_menu($r);
           }
       } elsif ($ENV{'form.action'} eq 'enrollstudent') {
           if (! exists($ENV{'form.state'})) {
               &print_enroll_single_student_form($r);
           } elsif ($ENV{'form.state'} eq 'enrolling') {
               &enroll_single_student($r);
           } else {
               &print_enroll_single_student_form($r);
           }
       } elsif ($ENV{'form.action'} eq 'classlist') {
           if (! exists($ENV{'form.state'})) {
               &print_html_classlist($r);
           } elsif ($ENV{'form.state'} eq 'csv') {
               &print_formatted_classlist($r,'csv');
           } elsif ($ENV{'form.state'} eq 'excel') {
               &print_formatted_classlist($r,'excel');
           } else {
               &print_html_classlist($r);
           }
       } elsif ($ENV{'form.action'} eq 'modifystudent') {
           if (! exists($ENV{'form.state'})) {
               &print_html_classlist($r);
           } elsif ($ENV{'form.state'} eq 'selected') {
               &print_modify_student_form($r);
           } elsif ($ENV{'form.state'} eq 'done') {
               &modify_single_student($r);
           } else {
               &print_html_classlist($r);
           }        
       } else {
           # We should not end up here, but I guess it is possible
           &Apache::lonnet::logthis("Undetermined state in londropadd.pm.  ".
                                    "form.action = ".$ENV{'form.action'}.
                                    "Someone should fix this.");
           &print_main_menu($r);
       }
       #
       # Finish up
       if (exists($ENV{'form.state'}) && ($ENV{'form.state'} eq 'csv')) {
           $r->print("\n");
       } else {
           $r->print('</form></body></html>');
       }
       return OK;
 }  }
   
   ###################################################################
   ###################################################################
   
 1;  1;
 __END__  __END__
   
   
   
   

Removed from v.1.10  
changed lines
  Added in v.1.73


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