Diff for /loncom/interface/Attic/londropadd.pm between versions 1.45.2.1 and 1.84

version 1.45.2.1, 2002/08/22 21:22:30 version 1.84, 2003/08/26 04:56:29
Line 31 Line 31
 #  #
 # (TeX Content Handler  # (TeX Content Handler
 #  #
 # YEAR=2000  ###############################################################
 # 05/29/00,05/30,10/11 Gerd Kortemeyer)  ##############################################################
 #  
 # 10/11,10/12,10/16 Gerd Kortemeyer)  
 #  
 # 11/20,11/21,11/22,11/23,11/24,11/25,11/27,11/28,  
 # 12/08,12/12 Gerd Kortemeyer)  
 #  
 # 12/26,12/27,12/28,  
 # YEAR=2001  
 # 01/01/01,01/15,02/10,02/13,02/14,02/22 Gerd Kortemeyer  
 # 8/6 Scott Harrison  
 # Guy Albertelli  
 # 9/25 Gerd Kortemeyer  
 # 12/19 Guy Albertelli  
 # YEAR=2002  
 # 1/4 Gerd Kortemeyer  
   
 package Apache::londropadd;  package Apache::londropadd;
   
 use strict;  use strict;
 use Apache::lonnet();  use Apache::lonnet();
 use Apache::loncommon();  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 $bodytag=&Apache::loncommon::bodytag('Enrollment Manager');
     return(<<ENDHEAD);      return(<<ENDHEAD);
 <html>  <html>
 <head>  <head>
 <title>LON-CAPA Enrollment Manager</title>  <title>LON-CAPA Enrollment Manager</title>
 </head>  </head>
 <body bgcolor="#FFFFFF">  $bodytag
 <img align=right src=/adm/lonIcons/lonlogos.gif>  
 <h1>$ENV{'course.'.$ENV{'request.course.id'}.'.description'}</h1>  
 <h2>Enrollment Manager</h2>  
 <form method="post" enctype="multipart/form-data"    <form method="post" enctype="multipart/form-data"  
       action="/adm/dropadd" name="studentform">        action="/adm/dropadd" name="studentform">
 ENDHEAD  ENDHEAD
 }  }
   
 # =========== Drop student from all sections of a course, except optional $csec  ###############################################################
   ###############################################################
   # Drop student from all sections of a course, except optional $csec
 sub modifystudent {  sub modifystudent {
     my ($udom,$unam,$courseid,$csec,$desiredhost)=@_;      my ($udom,$unam,$courseid,$csec,$desiredhost)=@_;
     # if $csec is undefined, drop the student from all the courses matching      # if $csec is undefined, drop the student from all the courses matching
Line 92  sub modifystudent { Line 79  sub modifystudent {
             # We are in this course              # We are in this course
             my $section=$1;              my $section=$1;
             $section='' if ($course eq $courseid.'_st');              $section='' if ($course eq $courseid.'_st');
             if ( ((!$section) && (!$csec)) || ($section ne $csec) ) {              if ($section eq $csec) {
                   $result .= 'ok:';
               } elsif ( ((!$section) && (!$csec)) || ($section ne $csec) ) {
                 my (undef,$end,$start)=split(/\_/,$roles{$course});                  my (undef,$end,$start)=split(/\_/,$roles{$course});
                 my $now=time;                  my $now=time;
                   # if this is an active role 
                 if (!($start && ($now<$start)) || !($end && ($now>$end))) {                  if (!($start && ($now<$start)) || !($end && ($now>$end))) {
                     my $reply=&Apache::lonnet::modifystudent                      my $reply=&Apache::lonnet::modifystudent
                         ($udom,$unam,'','','','','','','',                          # dom  name  id mode pass     f     m     l     g
                           ($udom,$unam,'',  '',  '',undef,undef,undef,undef,
                          $section,time,undef,undef,$desiredhost);                           $section,time,undef,undef,$desiredhost);
                     $result .= $reply.':';                      $result .= $reply.':';
                 }                  }
Line 105  sub modifystudent { Line 96  sub modifystudent {
         }          }
     }      }
     if ($result eq '') {      if ($result eq '') {
         $result eq 'Unable to find section for this student';          $result = 'Unable to find section for this student';
     } else {      } else {
         $result =~ s/(ok:)+/ok/g;          $result =~ s/(ok:)+/ok/g;
     }      }
     return $result;      return $result;
 }  }
   
 # ============ build a domain and server selection form  ###############################################################
   ###############################################################
   # build a domain and server selection form
 sub domain_form {  sub domain_form {
     my ($defdom) = @_;      my ($defdom) = @_;
     # Set up domain and server selection forms      # Set up domain and server selection forms
Line 141  sub domain_form { Line 134  sub domain_form {
     return $result;      return $result;
 }  }
   
 # ============================================================== Menu Phase One  ###############################################################
 sub menu_phase_one {  ###############################################################
   #  Menu Phase One
   sub print_main_menu {
     my $r=shift;      my $r=shift;
     my $upfile_select=&Apache::loncommon::upfile_select_html();      $r->print(<<END);
     my $create_classlist_help =   <p>
  &Apache::loncommon::help_open_topic("Course_Create_Class_List",  <font size="+1">
            "How do I create a class list from a spreadsheet");      <a href="/adm/dropadd?action=upload">Upload a course list</a>
     my $create_csv_help =  </font>
  &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",  </p><p>
            "How do I create a CSV file from a spreadsheet");  <font size="+1">
     $r->print(<<ENDUPFORM);      <a href="/adm/dropadd?action=enrollstudent">Enroll a single student</a>
 <input type=hidden name=phase value=two>  </font>
 <hr>  </p><p>
 <h3>Upload a courselist</h3>  <font size="+1">
 $upfile_select      <a href="/adm/dropadd?action=modifystudent">Modify student data</a>
 <p><input type=submit name="fileupload" value="Upload Courselist">  </font>
 <br />  </p><p>
 $create_classlist_help <br />  <font size="+1">
 $create_csv_help      <a href="/adm/dropadd?action=classlist">View Class List</a>
   </font>
 <hr />  </p><p>
 <h3>Enroll a single student</h3>  <font size="+1">
 <p><input type=submit name="enroll" value="Enroll Student"></p>      <a href="/adm/dropadd?action=drop">Drop Students</a>
 <hr />  </font>
 <h3>Classlist</h3>  </p>
 <p><input type=submit name="view" value="View Class List">  END
 <input type=submit name="viewcsv" value="Comma Separated Class List"></p>  
 <hr />  
 <h3>Drop students</h3>  
 <p><input type=submit name="drop" value="Selection List"></p>  
 ENDUPFORM  
 }  }
   
 sub phase_two_header {  ###############################################################
   ###############################################################
   sub print_upload_manager_header {
     my ($r,$datatoken,$distotal,$krbdefdom)=@_;      my ($r,$datatoken,$distotal,$krbdefdom)=@_;
     my $javascript;      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') {      if ($ENV{'form.upfile_associate'} eq 'reverse') {
  $javascript=&phase_two_javascript_reverse_associate();   $javascript=&upload_manager_javascript_reverse_associate();
     } else {      } else {
  $javascript=&phase_two_javascript_forward_associate();   $javascript=&upload_manager_javascript_forward_associate();
     }      }
     my $javascript_validations=&javascript_validations($krbdefdom);      my $javascript_validations=&javascript_validations($krbdefdom);
       my $checked=(($ENV{'form.noFirstLine'})?' checked="1"':'');
     $r->print(<<ENDPICK);      $r->print(<<ENDPICK);
 <h3>Uploading Class List</h3>  <h3>Uploading Class List</h3>
 <hr>  <hr>
Line 191  Total number of records found in file: $ Line 194  Total number of records found in file: $
 Enter as many fields as you can. The system will inform you and bring you back  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 />  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="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="associate"  value="" />
 <input type="hidden" name="phase"      value="three" />  
 <input type="hidden" name="datatoken"  value="$datatoken" />  <input type="hidden" name="datatoken"  value="$datatoken" />
 <input type="hidden" name="fileupload" value="$ENV{'form.fileupload'}" />  <input type="hidden" name="fileupload" value="$ENV{'form.fileupload'}" />
   <input type="checkbox" name="noFirstLine" $checked />Ignore First Line
 <input type="hidden" name="upfiletype" value="$ENV{'form.upfiletype'}" />  <input type="hidden" name="upfiletype" value="$ENV{'form.upfiletype'}" />
 <input type="hidden" name="upfile_associate"   <input type="hidden" name="upfile_associate" 
                                        value="$ENV{'form.upfile_associate'}" />                                         value="$ENV{'form.upfile_associate'}" />
Line 206  $javascript_validations Line 211  $javascript_validations
 ENDPICK  ENDPICK
 }  }
   
   ###############################################################
   ###############################################################
 sub javascript_validations {  sub javascript_validations {
     my ($krbdefdom)=@_;      my ($krbdefdom)=@_;
     my %param = ( formname => 'studentform',      my %param = ( formname => 'studentform',
                   kerb_def_dom => $krbdefdom );                    kerb_def_dom => $krbdefdom );
     my $authheader = &Apache::loncommon::authform_header(%param);      my $authheader = &Apache::loncommon::authform_header(%param);
       my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
     return (<<ENDPICK);      return (<<ENDPICK);
 function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec) {  function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail) {
     var foundatype=0;      var foundatype=0;
     var message='';      var message='';
     if (founduname==0) {      if (founduname==0) {
  alert('You need to specify the username field');   alert('You need to specify the username field');
         return;          return;
     }      }
       // alert('current.radiovalue = '+current.radiovalue);
     if (current.radiovalue == null || current.radiovalue == 'nochange') {      if (current.radiovalue == null || current.radiovalue == 'nochange') {
         // They did not check any of the login radiobuttons.          // They did not check any of the login radiobuttons.
         alert('You must choose an authentication type');          alert('You must choose an authentication type');
Line 247  function verify_message (vf,founduname,f Line 256  function verify_message (vf,founduname,f
         }          }
     }      }
   
     if (foundname==0) { message='No name fields specified. '; }      if (foundname==0) { message='name fields'; }
     if (foundid==0) { message+='No ID or student number field specified. '; }      if (foundid==0) { if (message!='') { message+=', '; } message+='student number field'; }
     if (foundsec==0) { message+='No section or group field specified. '; }      if (foundsec==0) {  if (message!='') { message+=', '; } message+='section or group field'; }
     if (vf.startdate.value=='') {      if (foundemail==0) {  if (message!='') { message+=', '; } message+='email address field'; }
  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!='') {      if (message!='') {
        message+='Continue enrollment?';         message='Not specified (optional): '+message+'.  Continue enrollment?';
        if (confirm(message)) {         if (confirm(message)) {
   pclose();            vf.state.value='enrolling';
   vf.submit();    vf.submit();
        }         }
     } else {      } else {
       pclose();        vf.state.value='enrolling';
       vf.submit();        vf.submit();
     }      }
 }  }
   
   $authheader
   ENDPICK
   
     function pclose() {  }
         parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",  
                  "height=350,width=350,scrollbars=no,menubar=no");  
         parmwin.close();  
     }  
   
     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");  
   
   sub javascript_validations_without_auth {
       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;
     }      }
       if (foundname==0) { message='name fields'; }
     function dateset() {      if (foundid==0) { if (message!='') { message+=', '; } message+='student number field'; }
         if (document.studentform.pres_marker.value=='end') {      if (foundsec==0) {  if (message!='') { message+=', '; } message+='section or group field'; }
            document.studentform.enddate.value=      if (foundemail==0) {  if (message!='') { message+=', '; } message+='email address field'; }
        document.studentform.pres_value.value;      if (message!='') {
         }         message='Not specified (optional): '+message+'.  Continue enrollment?';
         if (document.studentform.pres_marker.value=='start') {         if (confirm(message)) {
            document.studentform.startdate.value=            vf.state.value='enrolling';
        document.studentform.pres_value.value;    vf.submit();
         }         }
         pclose();      } else {
         vf.state.value='enrolling';
         vf.submit();
     }      }
   }
   
 $authheader  
 ENDPICK  ENDPICK
   
 }  }
   
 sub phase_two_javascript_forward_associate {  ###############################################################
   ###############################################################
   sub upload_manager_javascript_forward_associate {
     return(<<ENDPICK);      return(<<ENDPICK);
 function verify(vf) {  function verify(vf) {
     var founduname=0;      var founduname=0;
Line 315  function verify(vf) { Line 317  function verify(vf) {
     var foundname=0;      var foundname=0;
     var foundid=0;      var foundid=0;
     var foundsec=0;      var foundsec=0;
       var foundemail=0;
     var tw;      var tw;
     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');
Line 323  function verify(vf) { Line 326  function verify(vf) {
         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; }
     }      }
     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);      verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail);
 }  }
   
   //
   // 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 (tf==1 && nw!=0) {     // If we set this to 'lastname, firstnames', clear out all the ones
       for (i=2;i<=5;i++) {     // set to 'fname','mname','lname','gen' (3,4,5,6) currently.
          eval('vf.f'+i+'.selectedIndex=0;')  
       }  
    }  
    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) &&
Line 348  function flip(vf,tf) { Line 368  function flip(vf,tf) {
          }           }
       }        }
    }     }
      // 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) {
Line 355  function flip(vf,tf) { Line 377  function flip(vf,tf) {
          }           }
       }        }
    }     }
      // If we set the password, make the password form below correspond to 
      // the new value.
    if (nw==9) {     if (nw==9) {
        changed_radio('int',document.studentform);         changed_radio('int',document.studentform);
        set_auth_radio_buttons('int',document.studentform);         set_auth_radio_buttons('int',document.studentform);
Line 376  function clearpwd(vf) { Line 400  function clearpwd(vf) {
 ENDPICK  ENDPICK
 }  }
   
 sub phase_two_javascript_reverse_associate {  ###############################################################
   ###############################################################
   sub upload_manager_javascript_reverse_associate {
     return(<<ENDPICK);      return(<<ENDPICK);
 function verify(vf) {  function verify(vf) {
     var founduname=0;      var founduname=0;
Line 429  function clearpwd(vf) { Line 455  function clearpwd(vf) {
 ENDPICK  ENDPICK
 }  }
   
 sub phase_two_end {  ###############################################################
   ###############################################################
   sub print_upload_manager_footer {
     my ($r,$i,$keyfields,$defdom,$today,$halfyear)=@_;      my ($r,$i,$keyfields,$defdom,$today,$halfyear)=@_;
     my %param = ( formname => 'document.studentform');  
       my ($krbdef,$krbdefdom) =
           &Apache::loncommon::get_kerberos_defaults($defdom);
       my %param = ( formname => 'document.studentform',
                     kerb_def_dom => $krbdefdom,
                     kerb_def_auth => $krbdef
                     );
     my $krbform = &Apache::loncommon::authform_kerberos(%param);      my $krbform = &Apache::loncommon::authform_kerberos(%param);
     my $intform = &Apache::loncommon::authform_internal(%param);      my $intform = &Apache::loncommon::authform_internal(%param);
     my $locform = &Apache::loncommon::authform_local(%param);      my $locform = &Apache::loncommon::authform_local(%param);
     my $domform = &domain_form($defdom);      my $domform = &domain_form($defdom);
       my $date_table = &date_setting_table();
     $r->print(<<ENDPICK);      $r->print(<<ENDPICK);
 </table>  </table>
 <input type=hidden name=nfields value=$i>  <input type=hidden name=nfields value=$i>
Line 454  $locform Line 489  $locform
 <h3>LON-CAPA Domain for Students</h3>  <h3>LON-CAPA Domain for Students</h3>
 LON-CAPA domain: $domform <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 print list of users not enrolled anymore)<p>  (also print list of users not enrolled anymore)<p>
Line 474  LON-CAPA domain: $domform <p> Line 500  LON-CAPA domain: $domform <p>
 Disable ID/Student Number Safeguard and Force Change of Conflicting IDs  Disable ID/Student Number Safeguard and Force Change of Conflicting IDs
 (only do if you know what you are doing)<p>  (only do if you know what you are doing)<p>
 <input type="button" onClick="javascript:verify(this.form)" value="Update Courselist" /><br />  <input type="button" onClick="javascript:verify(this.form)" value="Update Courselist" /><br />
 Note: for large courses, this operation might be time consuming.  Note: for large courses, this operation may be time consuming.
 ENDPICK  ENDPICK
 }  }
   
 # ======================================================= Menu Phase Two Upload  # ======================================================= Menu Phase Two Upload
 sub menu_phase_two_upload {  sub print_upload_manager_form {
     my $r=shift;      my $r=shift;
       my $firstLine;
     my $datatoken;      my $datatoken;
     if (!$ENV{'form.datatoken'}) {      if (!$ENV{'form.datatoken'}) {
       $datatoken=&Apache::loncommon::upfile_store($r);        $datatoken=&Apache::loncommon::upfile_store($r);
Line 490  sub menu_phase_two_upload { Line 516  sub menu_phase_two_upload {
       &Apache::loncommon::load_tmp_file($r);        &Apache::loncommon::load_tmp_file($r);
     }      }
     my @records=&Apache::loncommon::upfile_record_sep();      my @records=&Apache::loncommon::upfile_record_sep();
       if($ENV{'form.noFirstLine'}){$firstLine=shift(@records);}
     my $total=$#records;      my $total=$#records;
     my $distotal=$total+1;      my $distotal=$total+1;
     $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/;  
     my $krbdefdom=$1;  
     $krbdefdom=~tr/a-z/A-Z/;  
     my $today=time;      my $today=time;
     my $halfyear=$today+15552000;      my $halfyear=$today+15552000;
     my $defdom=$r->dir_config('lonDefDomain');      my $defdom=$ENV{'request.role.domain'};
     &phase_two_header($r,$datatoken,$distotal,$krbdefdom);      my ($krbdef,$krbdefdom) =
           &Apache::loncommon::get_kerberos_defaults($defdom);
       &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom);
     my $i;      my $i;
     my $keyfields;      my $keyfields;
     if ($total>=0) {      if ($total>=0) {
  my @d=(['username','Username'],['names','Last Name, First Names'],   my @d=(['username','Username'],
        ['fname','First Name'],['mname','Middle Names/Initials'],                 ['names','Last Name, First Names'],
        ['lname','Last Name'],['gen','Generation'],         ['fname','First Name'],
        ['id','ID/Student Number'],['sec','Group/Section'],                 ['mname','Middle Names/Initials'],
        ['ipwd','Initial Password']);         ['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') {   if ($ENV{'form.upfile_associate'} eq 'reverse') {
     &Apache::loncommon::csv_print_samples($r,\@records);      &Apache::loncommon::csv_print_samples($r,\@records);
     $i=&Apache::loncommon::csv_print_select_table($r,\@records,\@d);      $i=&Apache::loncommon::csv_print_select_table($r,\@records,\@d);
Line 519  sub menu_phase_two_upload { Line 550  sub menu_phase_two_upload {
     $keyfields=join(',',sort(keys(%sone)));      $keyfields=join(',',sort(keys(%sone)));
  }   }
     }      }
     &phase_two_end($r,$i,$keyfields,$defdom,$today,$halfyear);      &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear);
 }  }
   
 # ======================================================= Enroll single student  # ======================================================= Enroll single student
 sub enroll_single_student {  sub enroll_single_student {
     my $r=shift;      my $r=shift;
       # Remove non alphanumeric values from section
       $ENV{'form.csec'}=~s/\W//g;
       #
       # 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('<h3>Enrolling Student</h3>');
     $r->print('<p>Enrolling '.$ENV{'form.cuname'}." in domain ".      $r->print('<p>Enrolling '.$ENV{'form.cuname'}." \@ ".
               $ENV{'form.lcdomain'}.'</p>');                $ENV{'form.lcdomain'}.'</p>');
     if (($ENV{'form.cuname'})&&($ENV{'form.cuname'}!~/\W/)&&      if (($ENV{'form.cuname'})&&($ENV{'form.cuname'}!~/\W/)&&
         ($ENV{'form.lcdomain'})&&($ENV{'form.lcdomain'}!~/\W/)) {          ($ENV{'form.lcdomain'})&&($ENV{'form.lcdomain'}!~/\W/)) {
Line 562  sub enroll_single_student { Line 605  sub enroll_single_student {
         my $home = &Apache::lonnet::homeserver($ENV{'form.cuname'},          my $home = &Apache::lonnet::homeserver($ENV{'form.cuname'},
                                                    $ENV{'form.lcdomain'});                                                     $ENV{'form.lcdomain'});
         if ((($amode) && ($genpwd)) || ($home ne 'no_host')) {          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'},              &modifystudent($ENV{'form.lcdomain'},$ENV{'form.cuname'},
                            $ENV{'request.course.id'},$ENV{'form.csec'},                             $ENV{'request.course.id'},$ENV{'form.csec'},
                             $desiredhost);                              $desiredhost);
           $r->print(&Apache::lonnet::modifystudent(              my $login_result = &Apache::lonnet::modifystudent
                       $ENV{'form.lcdomain'},$ENV{'form.cuname'},                  ($ENV{'form.lcdomain'},$ENV{'form.cuname'},
                       $ENV{'form.cstid'},$amode,$genpwd,                   $ENV{'form.cstid'},$amode,$genpwd,
                $ENV{'form.cfirst'},$ENV{'form.cmiddle'},                   $ENV{'form.cfirst'},$ENV{'form.cmiddle'},
                       $ENV{'form.clast'},$ENV{'form.cgen'},                   $ENV{'form.clast'},$ENV{'form.cgen'},
                       $ENV{'form.csec'},$ENV{'form.enddate'},                   $ENV{'form.csec'},$enddate,
                       $ENV{'form.startdate'},$ENV{'form.forceid'},                   $startdate,$ENV{'form.forceid'},
                     $desiredhost));                   $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 {   } else {
             $r->print('<p><font color="#ff0000">ERROR</font>&nbsp;'.              $r->print('<p><font color="#ff0000">ERROR</font>&nbsp;');
                       'Invalid login mode or password.  '.              if ($amode =~ /^krb/) {
                       'Unable to enroll '.$ENV{'form.cuname'}.'.</p>');                  $r->print('Missing Kerberos domain information.  ');
         }                        } else {
                   $r->print('Invalid login mode or password.  ');
               }
               $r->print('<b>Unable to enroll '.$ENV{'form.cuname'}.'.</b></p>');
           }
     } else {      } else {
         $r->print('Invalid username or domain');          $r->print('Invalid username or domain');
     }          }    
 }  }
   
 # ======================================================= Menu Phase Two Enroll  sub setup_date_selectors {
 sub menu_phase_two_enroll {      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 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;
   }
   
   ##
   ## Single student enrollment routines (some of them)
   ##
   sub get_student_username_domain_form {
       my $r = shift;
       my $domform = &Apache::loncommon::select_dom_form
           ($ENV{'request.role.domain'},'cudomain',0);
       $r->print(<<END);
   <input type="hidden" name="action" value="enrollstudent" />
   <input type="hidden" name="state"  value="gotusername" />
   <h3>Enroll One Student</h3>
   <table>
   <tr><th>Username:</th>
       <td><input type="text" name="cuname"  size="15" /></td></tr>
   <tr><th>Domain:</th>
       <td>$domform</td></tr>
   <tr><th>&nbsp;</th>
       <td>
       <input type="submit" name="Begin Enrollment" value="Begin Enrollment" />
       </td></tr>
   </table>
   END
       return;
   }
   
   sub print_enroll_single_student_form {
     my $r=shift;      my $r=shift;
     $r->print("<h3>Enroll One Student</h3>");      $r->print("<h3>Enroll One Student</h3>");
     my ($krbdefdom) = $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/;      #
     $krbdefdom=~tr/a-z/A-Z/;      my $username = $ENV{'form.cuname'};
     my $today    = time;      my $domain   = $ENV{'form.cudomain'};
     my $halfyear = $today+15552000;      my $home = &Apache::lonnet::homeserver($username,$domain);
     my $defdom=$r->dir_config('lonDefDomain');      # $new_user flags whether we are creating a new user or using an old one
     my $javascript_validations=&javascript_validations($krbdefdom);      my $new_user = 1;
     # Set up authentication forms      if ($home ne 'no_host') {
     my %param = ( formname => 'document.studentform');          $new_user = 0;
     my $krbform = &Apache::loncommon::authform_kerberos(%param);      }
     my $intform = &Apache::loncommon::authform_internal(%param);      &Apache::lonnet::logthis('home = '.$home);
     my $locform = &Apache::loncommon::authform_local(%param);      #
     # Set up domain selection form      my $user_data_html = '';
     my $domform = &domain_form($defdom);      my $javascript_validations = '';
     # Print it all out      if ($new_user) {
     $r->print(<<ENDSENROLL);          my $defdom=$ENV{'request.role.domain'};
           # Set up authentication forms
           my ($krbdef,$krbdefdom) =
               &Apache::loncommon::get_kerberos_defaults($domain);
           $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 $homeserver_form = '';
           my %servers = &Apache::loncommon::get_library_servers($domain);
           $homeserver_form = '<select name="lcserver" size="1">'."\n".
               '<option value="default" selected>default</option>'."\n";
           while (my ($servername,$serverdescription) = each (%servers)) {
               $homeserver_form .= '<option value="'.$servername.'">'.
                   $serverdescription."</option>\n";
           }
           $homeserver_form .= "</select>\n";
           #
           #
           $user_data_html = <<END;
   <h3>User Data for $username\@$domain</h3>
   <table>
   <tr><th>First Name:</th>
       <td><input type="text" name="cfirst"  size="15"></td></tr>
   <tr><th>Middle Name:</th>
       <td><input type="text" name="cmiddle" size="15"></td></tr>
   <tr><th>Last Name:</th>
       <td><input type="text" name="clast"   size="15"></td></tr>
   <tr><th>Generation:</th>
       <td><input type="text" name="cgen"    size="5"> </td></tr>
   <tr><th>Home Server:</th>
       <td>$homeserver_form</td></tr>
   </table>
   <h3>Password</h3>
   Please select an authentication mechanism
   <table>
   <p>
   $krbform
   <br />
   $intform
   <br />
   $locform
   </p>
   END
       } else {
           # User already exists.  Do not worry about authentication
           my %uenv = &Apache::lonnet::dump('environment',$domain,$username);
           $javascript_validations = &javascript_validations_without_auth();
           $user_data_html = <<END;
   <h3>User Data for $username\@$domain</h3>
   <input type="hidden" name="lcserver" value="default" />
   <table>
   <tr><th>First Name:</th>
       <td>
       <input type="text" name="cfirst" value="$uenv{'firstname'}" size="15" />
       </td></tr>
   <tr><th>Middle Name:</th>
       <td>
       <input type="text" name="cmiddle" value="$uenv{'middlename'}" size="15" />
       </td></tr>
   <tr><th>Last Name:</th>
       <td>
       <input type="text" name="clast"value="$uenv{'lastname'}" size="15" />
       </td></tr>
   <tr><th>Generation:</th>
       <td>
       <input type="text" name="cgen" value="$uenv{'generation'}" size="5" />
       </td></tr>
   </table>
   END
       }
       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" />
   <input type="hidden" name="cuname" value="$username" />
   <input type="hidden" name="lcdomain" value="$domain" />
 <script type="text/javascript" language="Javascript">  <script type="text/javascript" language="Javascript">
 function verify(vf) {  function verify(vf) {
     var founduname=0;      var founduname=0;
Line 638  function clearpwd(vf) { Line 879  function clearpwd(vf) {
 }  }
   
 </script>  </script>
 <h3>Personal Data</h3>  
 First Name:  <input type="text" name="cfirst"  size="15"><br>  $user_data_html
 Middle Name: <input type="text" name="cmiddle" size="15"><br>  
 Last Name:   <input type="text" name="clast"   size="15"><br>  <h3>Course Data</h3>
 Generation:  <input type="text" name="cgen"    size="5">   
   <p>Group/Section: <input type="text" name="csec" size="5" />
 <p>ID/Student Number: <input type="text" name="cstid" size="10"></p>  <p>
   $date_table
 <p>Group/Section: <input type=text name=csec size=5></p>  </p>
   
 <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>Starting and Ending Dates</h3>  
 <input type="hidden" value='' name="pres_value">  
 <input type="hidden" value='' name="pres_type">  
 <input type="hidden" value='' name="pres_marker">  
 <input type="hidden" value='$today' name=startdate>  
 <input type="hidden" value='$halfyear' name=enddate>  
 </p><p>  
 <a   
  href="javascript:pjump('date_start','Enrollment Starting Date',document.studentform.startdate.value,'start','studentform.pres','dateset');"  
 >Set Starting Date</a>  
 </p><p>  
 <a   
  href="javascript:pjump('date_end','Enrollment Ending Date',document.studentform.enddate.value,'end','studentform.pres','dateset');"  
 >Set Ending Date</a>  
 </p><p>  
 <h3>ID/Student Number</h3>  <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">   <input type="checkbox" name="forceid" value="yes"> 
 Disable ID/Student Number Safeguard and Force Change of Conflicting IDs  Disable ID/Student Number Safeguard and Force Change of Conflicting IDs
 (only do if you know what you are doing)<p>  (only do if you know what you are doing)
 <input type="button" onClick="verify(this.form)" value="Enroll as student"><br>  </p><p>
 <input type="hidden" name="phase" value="five">  <input type="button" onClick="verify(this.form)" value="Enroll as student">
 </p>  </p>
 ENDSENROLL  END
 }      return;
   
 # =================================================== get the current classlist  
 sub get_current_classlist {  
     my ($domain,$identifier) = @_;  
     # domain is the domain the class is being run in  
     # identifier is the internal, unique identifier for the class.  
     my %currentlist=();  
     my $now=time;  
     my %results=&Apache::lonnet::dump('classlist',$domain,$identifier);  
     my ($tmp) = keys(%results);  
     if ($tmp !~ /^(con_lost|error|no_such_host)/i) {  
         foreach my $student (keys(%results)) {  
             # Extract the start and end dates  
             my ($end,$start)=split(/\:/,$results{$student});  
             # If the class isn't over, put it in the list  
             unless (($end) && ($now>$end)) {   
                 $currentlist{$student}=1;  
             }  
         }  
         return (undef,%currentlist);  
     } else {  
         $tmp =~ s/^error://;  
         return ($tmp,undef);  
     }  
 }  }
   
 # ========================================================= Menu Phase Two Drop  # ========================================================= Menu Phase Two Drop
 sub menu_phase_two_drop {  sub print_drop_menu {
     my $r=shift;      my $r=shift;
     $r->print("<h3>Drop Students</h3>");      $r->print("<h3>Drop Students</h3>");
     my $cid=$ENV{'request.course.id'};      my $cid=$ENV{'request.course.id'};
     my ($error,%currentlist)=&get_current_classlist      my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();
         ($ENV{'course.'.$cid.'.domain'},$ENV{'course.'.$cid.'.num'});      if (! defined($classlist)) {
     if (defined($error)) {  
         if ($error =~ /^No such file or directory/) {  
             $r->print("There are no students currently enrolled.\n");  
         } else {  
             $r->print("<pre>ERROR:$error</pre>");  
         }  
     } elsif (!defined(%currentlist)) {   
         $r->print("There are no students currently enrolled.\n");          $r->print("There are no students currently enrolled.\n");
     } else {          return;
         # Print out the available choices  
         &show_drop_list($r,%currentlist);  
     }      }
       # Print out the available choices
       &show_drop_list($r,$classlist,$keylist);
       return;
 }  }
   
 # ============================================== view classlist  # ============================================== view classlist
 sub menu_phase_two_view {  sub print_html_classlist {
     my $r=shift;      my $r=shift;
     $r->print("<h3>Current Classlist</h3>");      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 Class List</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 $cid=$ENV{'request.course.id'};
     my ($error,%currentlist)=&get_current_classlist      my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
         ($ENV{'course.'.$cid.'.domain'},$ENV{'course.'.$cid.'.num'});      if (! defined($classlist)) {
     if (defined($error)) {  
         if ($error =~ /^No such file or directory/) {  
             $r->print("There are no students currently enrolled.\n");  
         } else {  
             $r->print("<pre>ERROR:$error</pre>");  
         }  
     } elsif (!defined(%currentlist)) {   
         $r->print("There are no students currently enrolled.\n");          $r->print("There are no students currently enrolled.\n");
     } else {      } else {
         # Print out the available choices          # Print out the available choices
         &show_class_list($r,'view',%currentlist);          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);
           }
     }      }
 }  }
   
 # ============================================== view classlist  # ============================================== view classlist
 sub menu_phase_two_viewcsv {  sub print_formatted_classlist {
     my $r=shift;      my $r=shift;
       my $mode = shift;
     my $cid=$ENV{'request.course.id'};      my $cid=$ENV{'request.course.id'};
     my ($error,%currentlist)=&get_current_classlist      my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
         ($ENV{'course.'.$cid.'.domain'},$ENV{'course.'.$cid.'.num'});      if (! defined($classlist)) {
     if (defined($error)) {  
         if ($error =~ /^No such file or directory/) {  
             $r->print("There are no students currently enrolled.\n");  
         } else {  
             $r->print("<pre>ERROR:$error</pre>");  
         }  
     } elsif (!defined(%currentlist)) {   
         $r->print("There are no students currently enrolled.\n");          $r->print("There are no students currently enrolled.\n");
     } else {      } else {
         &show_class_list($r,'csv',%currentlist);          &show_class_list($r,$mode,'nolink','csv',
                            $ENV{'form.Status'},$classlist,$keylist);
     }      }
 }  }
   
 # =================================================== Show student list to drop  # =================================================== Show student list to drop
 sub show_class_list {  sub show_class_list {
     my ($r,$mode,%currentlist)=@_;      my ($r,$mode,$linkto,$action,$statusmode,$classlist,$keylist)=@_;
     my $cid=$ENV{'request.course.id'};      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       # Print out header 
     if ($mode eq 'view') {      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);          $r->print(<<END);
   
   <input type="hidden" name="sortby" value="$sortby" />
   <input type="hidden" name="sname"  value="" />
   <input type="hidden" name="sdom"   value="" />
 <p>  <p>
 <table border=2>  <table border=2>
 <tr><th>username</th><th>domain</th><th>ID</th>  <tr><th>
     <th>student name</th><th>generation</th><th>section</th></tr>         <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  END
     } elsif ($mode eq 'csv') {      } elsif ($mode eq 'csv') {
         $r->print(<<END);          if($statusmode eq 'Expired') {
 username,domain,ID,last name,first name,middle name,generation,section              $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 = 'Class List 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  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]);
           }
     }      }
     foreach (sort keys %currentlist) {      if ($mode eq 'view') {
         my ($sname,$sdom)=split(/\:/,$_);          $r->print('</table><br>');
         my %reply=&Apache::lonnet::idrget($sdom,$sname);      } elsif ($mode eq 'excel') {
         my $ssec=&Apache::lonnet::usection($sdom,$sname,$cid);          $excel_workbook->close();
         my %info=&Apache::lonnet::get('environment',          $r->print('<p><a href="'.$excel_filename.'">'.
                                       ['firstname','middlename',                    'Your Excel spreadsheet</a> is ready for download.</p>'."\n");
                                        'lastname','generation'],      }
                                       $sdom, $sname);  }
         my ($tmp) = keys(%info);  
         if ($tmp =~ /^(con_lost|error|no_such_host)/i) {  
             $r->print( ($mode eq 'view' ?   #
                        '<tr><td colspan="6"><font color="red">' :'').  # print out form for modification of a single students data
                        'Internal error: unable to get environment '.  #
                        'for '.$sname.' in domain '.$sdom.  sub print_modify_student_form {
                        ( $mode eq 'view' ?'</font></td></tr>' :''));      my $r = shift();
         } else {      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
             if ($mode eq 'view') {                                              ['sdom','sname']);    
                 $r->print(<<"END");      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;
       #
       # Remove non alphanumeric values from the section
       $ENV{'form.section'} =~ s/\W//g;
       #
       # 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>  <tr>
     <td>$sname</td>      <td> <b>First name</b> </td>
     <td>$sdom</td>      <td> $old{'firstname'} </td>
     <td>$reply{$sname}</td>      <td> $firstname </td>
     <td>$info{'lastname'}, $info{'firstname'} $info{'middlename'}</td>  </tr><tr>
     <td>$info{'generation'}</td>      <td> <b>Middle name</b> </td>
     <td>$ssec</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>  </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  END
             } elsif ($mode eq 'csv') {      #
                 my @line = ();      # Send request(s) to modify data (final undef is for 'desiredhost',
                 foreach ($sname,$sdom,$reply{$sname},      # which is a moot point because the student already has an account.
                          $info{'lastname'},$info{'firstname'},      my $modify_section_results = &modifystudent($sdom,$slogin,
                          $info{'middlename'},$info{'generation'},$ssec) {                                                  $ENV{'request.course.id'},
                     push @line,&Apache::loncommon::csv_translate($_);                                                  $section,undef);
                 }      if ($modify_section_results !~ /^ok/) {
                 my $tmp = $";          $r->print("An error occured during the attempt to change the ".
                 $" = '","';                    "section for this student.<br />");
                 $r->print("\"@line\"\n");      }
                 $" = $tmp;      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); }
         }          }
     }      }
     $r->print('</table><br>') if ($mode eq 'view');      return ($start,$end,$section);
 }  }
   
 # =================================================== Show student list to drop  #################################################
   #################################################
   
   =pod
   
   =item show_drop_list
   
   Display a list of students to drop
   Inputs: 
   
   =over 4
   
   =item $r, Apache request
   
   =item $classlist, hash pointer returned from loncoursedata::get_classlist();
   
   =item $keylist, array pointer returned from loncoursedata::get_classlist() 
   which describes the order elements are stored in the %$classlist values.
   
   =item $nosort, if true, sorting links are omitted.
   
   =back
   
   =cut
   
   #################################################
   #################################################
 sub show_drop_list {  sub show_drop_list {
     my ($r,%currentlist)=@_;      my ($r,$classlist,$keylist,$nosort)=@_;
     my $cid=$ENV{'request.course.id'};      my $cid=$ENV{'request.course.id'};
     $r->print(<<'END');      if (! exists($ENV{'form.sortby'})) {
           &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                                   ['sortby']);
       }
       my $sortby = $ENV{'form.sortby'};
       if ($sortby !~ /^(username|domain|section|fullname|id)$/) {
           $sortby = 'username';
       }
       #
       my $action = "drop";
       $r->print(<<END);
   <input type="hidden" name="sortby" value="$sortby" />
   <input type="hidden" name="action" value="$action" />
   <input type="hidden" name="state"  value="done" />
 <script>  <script>
 function checkAll(field)  function checkAll(field) {
 {  
     for (i = 0; i < field.length; i++)      for (i = 0; i < field.length; i++)
         field[i].checked = true ;          field[i].checked = true ;
 }  }
   
 function uncheckAll(field)  function uncheckAll(field) {
 {  
     for (i = 0; i < field.length; i++)      for (i = 0; i < field.length; i++)
         field[i].checked = false ;          field[i].checked = false ;
 }  }
 </script>  </script>
 <p>  <p>
 <input type="hidden" name="phase" value="four">  <input type="hidden" name="phase" value="four">
   END
   
       if ($nosort) {
           $r->print(<<END);
 <table border=2>  <table border=2>
 <tr><th>&nbsp;</th><th>username</th><th>domain</th>  <tr>
 <th>ID</th><th>student name</th><th>generation</th>      <th>&nbsp;</th>
 <th>section</th></tr>      <th>username</th>
       <th>domain</th>
       <th>ID</th>
       <th>student name</th>
       <th>section</th>
   </tr>
 END  END
     foreach (sort keys %currentlist) {  
         my ($sname,$sdom)=split(/\:/,$_);      } else  {
         my %reply=&Apache::lonnet::idrget($sdom,$sname);          $r->print(<<END);
         my $ssec=&Apache::lonnet::usection($sdom,$sname,$cid);  <table border=2>
         my %info=&Apache::lonnet::get('environment',  <tr><th>&nbsp;</th>
                                       ['firstname','middlename',      <th>
                                        'lastname','generation'],         <a href="/adm/dropadd?action=$action&sortby=username">username</a>
                                       $sdom, $sname);      </th><th>
         my ($tmp) = keys(%info);         <a href="/adm/dropadd?action=$action&sortby=domain">domain</a>
         if ($tmp =~ /^(con_lost|error|no_such_host)/i) {      </th><th>
             $r->print('<tr><td colspan="7"><font color="red">'.         <a href="/adm/dropadd?action=$action&sortby=id">ID</a>
                       'Internal error: unable to get environment '.      </th><th>
                       'for '.$sname.' in domain '.$sdom.'</font></td></tr>');         <a href="/adm/dropadd?action=$action&sortby=fullname">student name</a>
         } else {      </th><th>
             $r->print(<<"END");         <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>  <tr>
     <td><input type="checkbox" name="droplist" value="$_"></td>      <td><input type="checkbox" name="droplist" value="$student"></td>
     <td>$sname</td>      <td>$username</td>
     <td>$sdom</td>      <td>$domain</td>
     <td>$reply{$sname}</td>      <td>$id</td>
     <td>$info{'lastname'}, $info{'firstname'} $info{'middlename'}</td>      <td>$name</td>
     <td>$info{'generation'}</td>      <td>$section</td>
     <td>$ssec</td>  
 </tr>  </tr>
 END  END
         }  
     }      }
     $r->print('</table><br>');      $r->print('</table><br>');
     $r->print(<<"END");      $r->print(<<"END");
Line 890  END Line 1508  END
 <input type="button" value="uncheck all" onclick="javascript:uncheckAll(document.studentform.droplist)">   <input type="button" value="uncheck all" onclick="javascript:uncheckAll(document.studentform.droplist)"> 
 <p><input type=submit value="Drop Students"></p>  <p><input type=submit value="Drop Students"></p>
 END  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" />
   <input type="checkbox" name="noFirstLine" /> Ignore First Line<br />
   </p>
   $create_classlist_help <br />
   $create_csv_help
   </body></html>
   ENDUPFORM
       return;
 }  }
   
 # ================================================= Drop/Add from uploaded file  # ================================================= Drop/Add from uploaded file
Line 897  sub upfile_drop_add { Line 1545  sub upfile_drop_add {
     my $r=shift;      my $r=shift;
     &Apache::loncommon::load_tmp_file($r);      &Apache::loncommon::load_tmp_file($r);
     my @studentdata=&Apache::loncommon::upfile_record_sep();      my @studentdata=&Apache::loncommon::upfile_record_sep();
       if($ENV{'form.noFirstLine'}){shift(@studentdata);}
     my @keyfields = split(/\,/,$ENV{'form.keyfields'});      my @keyfields = split(/\,/,$ENV{'form.keyfields'});
     my $cid = $ENV{'request.course.id'};      my $cid = $ENV{'request.course.id'};
     my %fields=();      my %fields=();
Line 910  sub upfile_drop_add { Line 1559  sub upfile_drop_add {
         }          }
     }      }
     #      #
     my $startdate = $ENV{'form.startdate'};      my ($startdate,$enddate) = &get_dates_from_form();
     my $enddate   = $ENV{'form.enddate'};      if ($ENV{'form.makedatesdefault'}) {
     if ($startdate=~/\D/) { $startdate=''; }          $r->print(&make_dates_default($startdate,$enddate));
     if ($enddate=~/\D/)   { $enddate=''; }      }
     # Determine domain and desired host (home server)      # Determine domain and desired host (home server)
     my $domain=$ENV{'form.lcdomain'};      my $domain=$ENV{'form.lcdomain'};
     my $desiredhost = $ENV{'form.lcserver'};      my $desiredhost = $ENV{'form.lcserver'};
Line 945  sub upfile_drop_add { Line 1594  sub upfile_drop_add {
             $genpwd=$ENV{'form.locarg'};              $genpwd=$ENV{'form.locarg'};
         }          }
     }      }
       if ($amode =~ /^krb/) {
           if (! defined($genpwd) || $genpwd eq '') {
               $r->print('<font color="red" size="+1">'.
                         'Unable to enroll students:'.'</font>  '.
                         'No Kerberos domain was specified.</p>');
               $amode = ''; # This causes the loop below to be skipped
           }
       }
     unless (($domain=~/\W/) || ($amode eq '')) {      unless (($domain=~/\W/) || ($amode eq '')) {
         #######################################          #######################################
         ##         Enroll Students           ##          ##         Enroll Students           ##
         #######################################          #######################################
         $r->print('<h3>Enrolling Students</h3>');          $r->print('<h3>Enrolling Students</h3>'."\n".'<p>');
         my $count=0;          my $count=0;
         my $flushc=0;          my $flushc=0;
         my %student=();          my %student=();
Line 978  sub upfile_drop_add { Line 1635  sub upfile_drop_add {
                     }                      }
                 }                  }
                 if ($entries{$fields{'username'}}=~/\W/) {                  if ($entries{$fields{'username'}}=~/\W/) {
                     $r->print('<p><b>Unacceptable username: '.                      $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 {
                     # determine section number                      # determine section number
                     my $sec='';                      my $sec='';
Line 990  sub upfile_drop_add { Line 1647  sub upfile_drop_add {
                             $sec=$entries{$fields{'sec'}};                              $sec=$entries{$fields{'sec'}};
                         }                          }
                     }                      }
                       # remove non alphanumeric values from section
                       $sec =~ s/\W//g;
                     # determine student id number                      # determine student id number
                     my $id='';                      my $id='';
                     if (defined($fields{'id'})) {                      if (defined($fields{'id'})) {
Line 998  sub upfile_drop_add { Line 1657  sub upfile_drop_add {
                         }                          }
                         $id=~tr/A-Z/a-z/;                          $id=~tr/A-Z/a-z/;
                     }                      }
                       # determine email address
                       my $email='';
                       if (defined($fields{'email'})) {
                           if (defined($entries{$fields{'email'}})) {
                               $email=$entries{$fields{'email'}};
                               unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }
                           }
                       }
                     # determine student password                      # determine student password
                     my $password='';                      my $password='';
                     if ($genpwd) {                       if ($genpwd) { 
Line 1009  sub upfile_drop_add { Line 1676  sub upfile_drop_add {
                             }                              }
                         }                          }
                     }                      }
                     if ($password) {                      # Clean up whitespace
                       foreach (\$domain,\$username,\$id,\$fname,\$mname,
                                \$lname,\$gen,\$sec) {
                           $$_ =~ s/(\s+$|^\s+)//g;
                       }
                       if ($password || $ENV{'form.login'} eq 'loc') {
                         &modifystudent($domain,$username,$cid,$sec,                          &modifystudent($domain,$username,$cid,$sec,
                                        $desiredhost);                                         $desiredhost);
                         my $reply=&Apache::lonnet::modifystudent                          my $reply=&Apache::lonnet::modifystudent
                             ($domain,$username,$id,$amode,$password,                              ($domain,$username,$id,$amode,$password,
                              $fname,$mname,$lname,$gen,$sec,$enddate,                               $fname,$mname,$lname,$gen,$sec,$enddate,
                              $startdate,$ENV{'form.forceid'},$desiredhost);                               $startdate,$ENV{'form.forceid'},$desiredhost,
                                $email);
                         if ($reply ne 'ok') {                          if ($reply ne 'ok') {
                             $r->print('<p><b>'.                              $reply =~ s/^error://;
                                       'Error enrolling '.$username.': '.                              $r->print('<br /><b>'.$username.'</b>:'.
                                       $reply.'</b></p>');                                        '  Unable to enroll: '.$reply);
           } else {            } else {
                             $count++; $flushc++;                              $count++; $flushc++;
                             $student{$username}=1;                              $student{$username}=1;
Line 1030  sub upfile_drop_add { Line 1703  sub upfile_drop_add {
                             }                              }
                         }                          }
                     } else {                      } else {
                         $r->print("<p><b>No password for $username</b><p>");                          $r->print('<br /><b>'.$username.'</b>:'.
                              '  Unable to enroll: No password specified.');
                     }                      }
                 }                  }
             }              }
         } # end of foreach (@studentdata)          } # end of foreach (@studentdata)
         $r->print('<p>Processed Students: '.$count);          $r->print('</p><p>Processed Students: '.$count.'</p>');
           $r->print("<p>If active, the new role will be available when the ".
                     "students next log in to LON-CAPA.</p>");
         #####################################          #####################################
         #           Drop students           #          #           Drop students           #
         #####################################          #####################################
         if ($ENV{'form.fullup'} eq 'yes') {          if ($ENV{'form.fullup'} eq 'yes') {
             $r->print('<h3>Dropping Students</h3>');              $r->print('<h3>Dropping Students</h3>');
             #  Get current classlist              #  Get current classlist
             my ($error,%currentlist)=&get_current_classlist              my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                 ($ENV{'course.'.$cid.'.domain'},              if (! defined($classlist)) {
                  $ENV{'course.'.$cid.'.num'});                  $r->print("There are no students currently enrolled.\n");
             if (defined($error)) {              } else {
                 $r->print('<pre>ERROR:$error</pre>');                  # Remove the students we just added from the list of students.
             }  
             if (defined(%currentlist)) {  
                 # Drop the students  
                 foreach (@studentdata) {                  foreach (@studentdata) {
                     my %entries=&Apache::loncommon::record_sep($_);                      my %entries=&Apache::loncommon::record_sep($_);
                     unless (($entries{$fields{'username'}} eq '') ||                      unless (($entries{$fields{'username'}} eq '') ||
                             (!defined($entries{$fields{'username'}}))) {                              (!defined($entries{$fields{'username'}}))) {
                         delete($currentlist{$entries{$fields{'username'}}.                          delete($classlist->{$entries{$fields{'username'}}.
                                                 ':'.$domain});                                                  ':'.$domain});
                     }                      }
                 }                  }
                 # Print out list of dropped students                  # Print out list of dropped students.
                 &show_drop_list($r,%currentlist);                  &show_drop_list($r,$classlist,$keylist,'nosort');
             } else {  
                 $r->print("There are no students currently enrolled.\n");  
             }              }
         }          }
     } # end of unless      } # end of unless
Line 1079  sub drop_student_list { Line 1750  sub drop_student_list {
     }      }
     foreach (@droplist) {      foreach (@droplist) {
         my ($uname,$udom)=split(/\:/,$_);          my ($uname,$udom)=split(/\:/,$_);
           # drop student
         my $result = &modifystudent($udom,$uname,$ENV{'request.course.id'});          my $result = &modifystudent($udom,$uname,$ENV{'request.course.id'});
         if ($result eq 'ok' || $result eq 'ok:') {          if ($result eq 'ok' || $result eq 'ok:') {
             $r->print('Dropped '.$uname.' at '.$udom.'<br>');              $r->print('Dropped '.$uname.' @ '.$udom.'<br>');
               $count++;
         } else {          } else {
             $r->print('Error dropping '.$uname.' at '.$udom.': '.$result.              $r->print('Error dropping '.$uname.' @ '.$udom.': '.$result.
                       '<br />');                        '<br />');
         }          }
         $count++;  
     }      }
     $r->print('<p><b>Dropped '.$count.' student(s).</b>');      $r->print('<p><b>Dropped '.$count.' student(s).</b>');
     $r->print('<p>Re-enrollment will re-activate data.');      $r->print('<p>Re-enrollment will re-activate data.') if ($count);
 }  }
   
 # ================================================================ Main Handler  ###################################################################
   ###################################################################
   
   =pod
   
   =item &handler
   
   The typical handler you see in all these modules.  Takes $r, the
   http request, as an argument.  
   
   The response to the request is governed by two form variables
   
    form.action      form.state     response
    ---------------------------------------------------
    undefined        undefined      print main menu
    upload           undefined      print courselist upload menu
    upload           got_file       deal with uploaded file,
                                    print the upload managing menu
    upload           enrolling      enroll students based on upload
    drop             undefined      print the classlist ready to drop
    drop             done           drop the selected students
    enrollstudent    undefined      print student username domain form
    enrollstudent    gotusername    print single student enroll menu
    enrollstudent    enrolling      enroll student
    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
   
   ###################################################################
   ###################################################################
 sub handler {  sub handler {
     my $r=shift;      my $r=shift;
     if ($r->header_only) {      if ($r->header_only) {
Line 1100  sub handler { Line 1805  sub handler {
         $r->send_http_header;          $r->send_http_header;
         return OK;          return OK;
     }      }
       &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                               ['action','state']);
     #  Needs to be in a course      #  Needs to be in a course
     if (($ENV{'request.course.fn'}) &&       if (! (($ENV{'request.course.fn'}) &&
         (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'}))) {            (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'})))) {
           # Not in a course, or not allowed to modify parms
           $ENV{'user.error.msg'}=
               "/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          # Start page
         $r->content_type('text/html') if (! exists($ENV{'form.viewcsv'}));          $r->content_type('text/html');
         $r->send_http_header;          $r->send_http_header;
         $r->print(&header()) if (! exists($ENV{'form.viewcsv'}));          $r->print(&header());
         # Phase one, initial screen      }
         unless ($ENV{'form.phase'}) {      #
             &menu_phase_one($r);      # Main switch on form.action and form.state, as appropriate
         }      if (! exists($ENV{'form.action'})) {
         # Phase two          &print_main_menu($r);
         if ($ENV{'form.associate'} eq 'Reverse Association') {      } elsif ($ENV{'form.action'} eq 'upload') {
             $ENV{'form.phase'} = 'two';          if (! exists($ENV{'form.state'})) {
             if ( $ENV{'form.upfile_associate'} ne 'reverse' ) {              &print_first_courselist_upload_form($r);            
                 $ENV{'form.upfile_associate'} = 'reverse';          } elsif ($ENV{'form.state'} eq 'got_file') {
             } else {              &print_upload_manager_form($r);
                 $ENV{'form.upfile_associate'} = 'forward';          } elsif ($ENV{'form.state'} eq 'enrolling') {
             }  
         }  
         if ($ENV{'form.phase'} eq 'two') {  
             if ($ENV{'form.fileupload'}) {  
                 &menu_phase_two_upload($r);  
             } elsif ($ENV{'form.enroll'}) {  
                 &menu_phase_two_enroll($r);  
             } elsif ($ENV{'form.drop'}) {  
                 &menu_phase_two_drop($r);  
             } elsif ($ENV{'form.view'}) {  
                 &menu_phase_two_view($r);  
             } elsif ($ENV{'form.viewcsv'}) {  
                 &menu_phase_two_viewcsv($r);  
             }  
         }  
         # Phase three  
         if ($ENV{'form.phase'} eq 'three') {  
             if ($ENV{'form.datatoken'}) {              if ($ENV{'form.datatoken'}) {
                 &upfile_drop_add($r);                  &upfile_drop_add($r);
               } else {
                   # Hmmm, this is an error
             }              }
           } else {
               &print_first_courselist_upload_form($r);            
         }          }
         # Phase four      } elsif ($ENV{'form.action'} eq 'drop') {
         if ($ENV{'form.phase'} eq 'four') {          if (! exists($ENV{'form.state'})) {
               &print_drop_menu($r);
           } elsif ($ENV{'form.state'} eq 'done') {
             &drop_student_list($r);              &drop_student_list($r);
           } else {
               &print_drop_menu($r);
         }          }
         # Phase five      } elsif ($ENV{'form.action'} eq 'enrollstudent') {
         if ($ENV{'form.phase'} eq 'five') {          if (! exists($ENV{'form.state'})) {
               &get_student_username_domain_form($r);
           } elsif ($ENV{'form.state'} eq 'gotusername') {
               &print_enroll_single_student_form($r);
           } elsif ($ENV{'form.state'} eq 'enrolling') {
             &enroll_single_student($r);              &enroll_single_student($r);
           } else {
               &get_student_username_domain_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);
         }          }
          # End      } elsif ($ENV{'form.action'} eq 'modifystudent') {
         $r->print('</form></body></html>') if (! exists($ENV{'form.viewcsv'}));          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 {      } else {
         # Not in a course, or not allowed to modify parms          # We should not end up here, but I guess it is possible
         $ENV{'user.error.msg'}=          &Apache::lonnet::logthis("Undetermined state in londropadd.pm.  ".
             "/adm/dropadd:cst:0:0:Cannot drop or add students";                                   "form.action = ".$ENV{'form.action'}.
         return HTTP_NOT_ACCEPTABLE;                                    "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;      return OK;
 }  }
   
   ###################################################################
   ###################################################################
   
 1;  1;
 __END__  __END__
   
   

Removed from v.1.45.2.1  
changed lines
  Added in v.1.84


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