Diff for /loncom/enrollment/Enrollment.pm between versions 1.28 and 1.55

version 1.28, 2006/02/07 05:08:21 version 1.55, 2021/09/08 12:13:13
Line 27  package LONCAPA::Enrollment; Line 27  package LONCAPA::Enrollment;
   
 use Apache::loncoursedata;  use Apache::loncoursedata;
 use Apache::lonnet;  use Apache::lonnet;
   use Apache::loncommon();
 use Apache::lonmsg;  use Apache::lonmsg;
 use Apache::lonlocal;  use Apache::lonlocal;
 use HTML::Entities;  use HTML::Entities;
   use HTML::Parser;
 use LONCAPA::Configuration;  use LONCAPA::Configuration;
   use Math::Random;
 use Time::Local;  use Time::Local;
 use lib '/home/httpd/lib/perl';  use lib '/home/httpd/lib/perl';
   
 use strict;  use strict;
   
 sub update_LC {  sub update_LC {
     my ($dom,$crs,$adds,$drops,$startdate,$enddate,$authtype,$autharg,$classesref,$groupref,$logmsg,$newusermsg,$context,$phototypes) = @_;       my ($dom,$crs,$adds,$drops,$startdate,$enddate,$authtype,$autharg,
           $showcredits,$defaultcredits,$autofailsafe,$classesref,$groupref,
           $logmsg,$newusermsg,$context,$phototypes) = @_;
 # Get institutional code and title of this class  # Get institutional code and title of this class
     my %courseinfo = ();      my %courseinfo = ();
     &get_courseinfo($dom,$crs,\%courseinfo);      &get_courseinfo($dom,$crs,\%courseinfo);
Line 52  sub update_LC { Line 57  sub update_LC {
     my $status=&Apache::loncoursedata::CL_STATUS;      my $status=&Apache::loncoursedata::CL_STATUS;
     my $type=&Apache::loncoursedata::CL_TYPE;      my $type=&Apache::loncoursedata::CL_TYPE;
     my $lockedtype=&Apache::loncoursedata::CL_LOCKEDTYPE;      my $lockedtype=&Apache::loncoursedata::CL_LOCKEDTYPE;
       my $credidx=&Apache::loncoursedata::CL_CREDITS;
       my $instidx = &Apache::loncoursedata::CL_INSTSEC;
     my @localstudents = ();      my @localstudents = ();
     my @futurestudents = ();      my @futurestudents = ();
     my @activestudents = ();      my @activestudents = ();
     my @excludedstudents = ();      my @excludedstudents = ();
     my $currlist;      my $currlist;
       my $now = time;
     foreach my $uname (keys %{$roster} ) {      foreach my $uname (keys %{$roster} ) {
         if ($uname =~ m/^(.+):$dom$/) {          if ($uname =~ m/^(.+):$dom$/) {
             if ($$roster{$uname}[$status] eq "Active") {              if ($$roster{$uname}[$status] eq "Active") {
Line 91  sub update_LC { Line 99  sub update_LC {
     open(FILE,"<$$configvars{'lonTabDir'}.'/rolesplain.tab");      open(FILE,"<$$configvars{'lonTabDir'}.'/rolesplain.tab");
     my @rolesplain = <FILE>;      my @rolesplain = <FILE>;
     close(FILE);      close(FILE);
     foreach (@rolesplain) {      foreach my $item (@rolesplain) {
         if ($_ =~ /^(st|ta|ex|ad|in|cc):([\w\s]+)$/) {          if ($_ =~ /^(st|ta|ex|ad|in|cc|co):([\w\s]+):?([\w\s]*)/) {
             $longroles{$1} = $2;              if ($courseinfo{'type'} eq 'Community') {
                   unless($1 eq 'cc') {
                       $longroles{$1} = $3;
                   }
               } else {
                   unless($1 eq 'co') { 
                       $longroles{$1} = $2;
                   }
               }
         }          }
     }      }
   
Line 114  sub update_LC { Line 130  sub update_LC {
 # Get latest institutional enrollment for this class.  # Get latest institutional enrollment for this class.
     my %allenrolled = ();      my %allenrolled = ();
     my @reg_students = ();      my @reg_students = ();
     my %place = ();      my %place = &place_hash(); 
     $place{'autharg'} = &CL_autharg();  
     $place{'authtype'} = &CL_authtype();  
     $place{'email'} = &CL_email();  
     $place{'enddate'} = &CL_enddate();  
     $place{'firstname'} = &CL_firstname();  
     $place{'generation'} = &CL_generation();  
     $place{'groupID'} = &CL_groupID();  
     $place{'lastname'} = &CL_lastname();  
     $place{'middlename'} = &CL_middlename();  
     $place{'startdate'} = &CL_startdate();  
     $place{'studentID'} = &CL_studentID();  
     my %ucount = ();      my %ucount = ();
     my %enrollinfo = ();      my %enrollinfo = ();
       my %classcount;
     foreach my $class (@{$classesref}) {      foreach my $class (@{$classesref}) {
         my %enrolled = ();          my %enrolled = ();
         &parse_classlist($$configvars{'lonDaemons'},$dom,$crs,$class,\%place,$$groupref{$class},\%enrolled);          &parse_classlist($$configvars{'lonDaemons'},$dom,$crs,$class,\%place,$$groupref{$class},\%enrolled);
           $classcount{$class} = scalar(keys(%enrolled));
         foreach my $uname (sort keys %enrolled ) {          foreach my $uname (sort keys %enrolled ) {
             if (!grep/^$uname$/,@reg_students) {              if (!grep/^$uname$/,@reg_students) {
                 push @reg_students,$uname;                  push @reg_students,$uname;
Line 146  sub update_LC { Line 153  sub update_LC {
     my @okusers = ();      my @okusers = ();
     foreach my $uname (@reg_students)  {      foreach my $uname (@reg_students)  {
         if (grep/^$uname$/,@excludedstudents) {          if (grep/^$uname$/,@excludedstudents) {
             $$logmsg .= "No re-enrollment for $uname - user was previously manually unenrolled and locked.".$linefeed;              $$logmsg .= &mt('No re-enrollment for [_1] - user was previously manually unenrolled and locked.',$uname).$linefeed;
         } elsif (@{$allenrolled{$uname}} > 1) {          } elsif (@{$allenrolled{$uname}} > 1) {
             my @sections = ();              my @sections = ();
             my $saved;              my $saved;
Line 169  sub update_LC { Line 176  sub update_LC {
                 push @okusers, $uname;                  push @okusers, $uname;
             }              }
             elsif (@sections > 1) {              elsif (@sections > 1) {
                 $$logmsg .=  "$uname appears in classlists for more than one section of this course, i.e. in sections: ";                  $$logmsg .=  &mt('[_1] appears in classlists for more than one section of this course, i.e. in sections: ',$uname);
                 foreach (@sections) {                  foreach (@sections) {
                     $$logmsg .= " $_,";                      $$logmsg .= " $_,";
                 }                  }
                 chop($$logmsg);                  chop($$logmsg);
                 $$logmsg .= ". Because of this ambiguity, no enrollment action was taken for this student.".$linefeed;                  $$logmsg .= '. '.&mt('Because of this ambiguity, no enrollment action was taken for this student.').$linefeed;
             }              }
         } else {          } else {
             @{$enrollinfo{$uname}} = @{$allenrolled{$uname}[0]};              @{$enrollinfo{$uname}} = @{$allenrolled{$uname}[0]};
             push @okusers, $uname;              push @okusers, $uname;
         }          }
     }      }
 # Get mapping of student IDs to usernames for users in institutional data for this class    # Get mapping of student/employee IDs to usernames for users in institutional data for this class  
     my @allINids = ();      my @allINids = ();
     my %unameFromINid = ();      my %unameFromINid = ();
     foreach my $uname (@okusers) {      foreach my $uname (@okusers) {
Line 195  sub update_LC { Line 202  sub update_LC {
         }          }
     }      }
   
 # Explicitly allow access to creation/modification of students if called as an automated process.  # Explicitly allow access to creation/modification of students and group membership changes 
   # when called as an automated process.
     if ($context eq 'automated') {      if ($context eq 'automated') {
         $env{'allowed.cst'}='F';          $env{'allowed.cst'}='F';
           $env{'allowed.mdg'}='F';
     }      }
   
 # Compare IDs with existing LON-CAPA enrollment for this class  # Compare IDs with existing LON-CAPA enrollment for this class
Line 205  sub update_LC { Line 214  sub update_LC {
         unless ($uname eq '') {          unless ($uname eq '') {
             my %uidhash=&Apache::lonnet::idrget($dom,$uname);              my %uidhash=&Apache::lonnet::idrget($dom,$uname);
             my @stuinfo = @{$enrollinfo{$uname}};              my @stuinfo = @{$enrollinfo{$uname}};
             my $access = '';              my ($access,$added,$inststatus,$instsec);
               my $credits;
               if ($showcredits) {
                   $credits = $stuinfo[$place{'credits'}];
                   $credits =~ s/[^\d\.]//g;
                   if ($credits eq $defaultcredits) {
                       undef($credits);
                   }
               }
               $inststatus = $stuinfo[$place{inststatus}];
               $instsec = $stuinfo[$place{instsec}];
             if (grep/^$uname$/,@localstudents) {              if (grep/^$uname$/,@localstudents) {
 # Check for studentID changes  # Check for studentID changes
                 if ( ($uidhash{$uname}) && ($uidhash{$uname} !~ /error\:/) )  {                  if ( ($uidhash{$uname}) && ($uidhash{$uname} !~ /error\:/) )  {
                     unless ( ($uidhash{$uname}) eq ($stuinfo[ $place{studentID} ]) ) {                      unless ( ($uidhash{$uname}) eq ($stuinfo[ $place{studentID} ]) ) {
                         $$logmsg .= "Change in ID for $uname. StudentID in LON-CAPA system is $uidhash{$uname}; StudentID in institutional data is $stuinfo[ $place{studentID} ]".$linefeed;                           $$logmsg .= &mt('Change in ID for [_1]. StudentID in LON-CAPA system is [_2]; StudentID in institutional data is [_3].',$uname,$uidhash{$uname},$stuinfo[ $place{studentID} ]).$linefeed; 
                     }                      }
                 }                  }
 # Check for switch from manual to auto  # Check for switch from manual to auto
                 unless (($$currlist{$uname}[$type] eq "auto") || ($$currlist{$uname}[$lockedtype] eq "1") || (!$adds) ) {                  unless (($$currlist{$uname}[$type] eq "auto") || ($$currlist{$uname}[$lockedtype] eq "1") || (!$adds) ) {
 # drop manually added student  # drop manually added student
                     my $drop_reply = &Apache::lonnet::modifystudent($dom,$uname,'','','',undef,undef,undef,undef,$$currlist{$uname}[$sec],time,undef,undef,undef,undef,'auto','',$cid);                      my $drop_reply = &Apache::lonnet::modifystudent($dom,$uname,'','','',undef,undef,undef,undef,$$currlist{$uname}[$sec],time,undef,undef,undef,undef,'auto','',$cid,'',$context);
 # re-enroll as auto student  # re-enroll as auto student
                     if ($drop_reply !~ /^ok/) {                      if ($drop_reply !~ /^ok/) {
                             $$logmsg .= "An error occured during the attempt to convert $uname from a manual type to an auto type student - $drop_reply.".$linefeed;                              $$logmsg .= &mt('An error occurred during the attempt to convert [_1] from a manual type to an auto type student - [_2].',$uname,$drop_reply).$linefeed;
                     } else {                      } else {
 # re-enroll as auto student  # re-enroll as auto student
                         my ($auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,$emailaddr,$pid,$emailenc);                          my ($auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,$emailaddr,$pid,$emailenc);
                         &prepare_add($authtype,$autharg,$enddate,$startdate,\@stuinfo,\%place,\$dom,\$uname,\$auth,\$authparam,\$first,\$middle,\$last,\$gene,\$usec,\$end,\$start,\$emailaddr,\$pid,\$emailenc);                          &prepare_add($authtype,$autharg,$enddate,$startdate,\@stuinfo,\%place,\$dom,\$uname,\$auth,\$authparam,\$first,\$middle,\$last,\$gene,\$usec,\$end,\$start,\$emailaddr,\$pid,\$emailenc);
                         if ($$currlist{$uname}[$sec] ne $usec) {                          if ($$currlist{$uname}[$sec] ne $usec) {
                             $switchresult .= "Section for $uname switched from $$currlist{$uname}[$sec] to ".$usec.$linefeed;                              my $showoldsec = $$currlist{$uname}[$sec];
                               if ($$currlist{$uname}[$sec] eq '') {
                                   $showoldsec = &mt('none');
                               }
                               my $showsec = $usec;
                               if ($usec eq '') {
                                   $showsec = &mt('none');
                               }
                               $switchresult .= &mt('Section for [_1] switched from [_2] to [_3].',$uname,$showoldsec,$showsec).$linefeed;
                             if ($context eq 'automated') {                              if ($context eq 'automated') {
                                 $$logmsg .= "Section switch for $uname from $$currlist{$uname}[$sec] to ".$usec.$linefeed; ;                                  $$logmsg .= &mt('Section switch for [_1] from [_2] to [_3].',$uname,$showoldsec,$usec).$linefeed;
                             }                              }
                             $switchcount ++;                              $switchcount ++;
                         }                          }
                         &execute_add($context,'switchtype',$uname,$dom,$auth,$authparam,$first,$middle,$last,$gene,$pid,$usec,$end,$start,$emailenc,$cid,\$addresult,\$enrollcount,$linefeed,$logmsg);                          &execute_add($context,'switchtype',$uname,$dom,$auth,
                                        $authparam,$first,$middle,$last,$gene,
                                        $pid,$usec,$end,$start,$emailenc,
                                        $credits,$instsec,$cid,\$addresult,\$enrollcount,
                                        $linefeed,$logmsg);
                           $added = 1;
                     }                      }
                 }                   }
 # Check for section changes  # Check for section changes
                 if ($$currlist{$uname}[$sec] eq $stuinfo[ $place{groupID} ]) {                  if ($$currlist{$uname}[$sec] eq $stuinfo[ $place{groupID} ]) {
 # Check for access date changes for students with access starting in the future.  # Check for access date changes for students with access starting in the future.
                     if ( (grep/^$uname$/,@futurestudents) && ($$currlist{$uname}[$type] eq "auto") && ($adds == 1) ) {                      if ( (grep/^$uname$/,@futurestudents) && ($$currlist{$uname}[$type] eq "auto") && ($adds == 1) ) {
                         my $datechange = &datechange_check($$currlist{$uname}[$cstart],$$currlist{$uname}[$cend],$startdate,$enddate);                          my $datechange = &datechange_check($$currlist{$uname}[$cstart],$$currlist{$uname}[$cend],$startdate,$enddate);
                         if ($datechange) {                          if ($datechange) {
                             my $modify_access_result = &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid);                              my $modify_access_result = &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid,'',$context,$credits,$instsec);
                             $access = &showaccess($enddate,$startdate);                              $access = &showaccess($enddate,$startdate);
                             if ($modify_access_result =~ /^ok/) {                              if ($modify_access_result =~ /^ok/) {
                                 $$logmsg .= "Change in access dates for $uname.".$access.$linefeed;                                  $$logmsg .= &mt('Change in access dates for [_1].',$uname).$access.$linefeed;
                                   $added = 1;
                             } else {                              } else {
                                 $$logmsg .= "Error when attempting to change start and/or end access dates for $uname in section: ".$stuinfo[ $place{groupID} ]." -error $modify_access_result".$linefeed;                                  $$logmsg .= &mt('Error when attempting to change start and/or end access dates for [_1] in section: [_2] -error [_3].',$uname,$stuinfo[$place{groupID}],$modify_access_result).$linefeed;
                             }                              }
                         }                          }
                     }                      }
Line 258  sub update_LC { Line 291  sub update_LC {
                         if ($$currlist{$uname}[$sec]) {                          if ($$currlist{$uname}[$sec]) {
                             $uurl.='/'.$$currlist{$uname}[$sec];                              $uurl.='/'.$$currlist{$uname}[$sec];
                         }                          }
                         my $expire_role_result = &Apache::lonnet::assignrole($dom,$uname,$uurl,'st',$expiretime);                          my $expire_role_result = &Apache::lonnet::assignrole($dom,$uname,$uurl,'st',$expiretime,'','','',$context);
                         if ($expire_role_result eq 'ok') {                          if ($expire_role_result eq 'ok') {
                             my $modify_section_result;                              my $modify_section_result;
                             if (grep/^$uname$/,@activestudents) {                              if (grep/^$uname$/,@activestudents) {
                                 $modify_section_result = &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$$currlist{$uname}[$cend],$$currlist{$uname}[$cstart],'auto','',$cid);                                  $modify_section_result = &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$$currlist{$uname}[$cend],$$currlist{$uname}[$cstart],'auto','',$cid,'',$context,$credits,$instsec);
                             } else {                              } else {
                                 $modify_section_result =  &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid);                                  $modify_section_result =  &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid,'',$context,$credits,$instsec);
                                 $access =  &showaccess($enddate,$startdate);                                  $access =  &showaccess($enddate,$startdate);
                             }                              }
                             if ($modify_section_result =~ /^ok/) {                              if ($modify_section_result =~ /^ok/) {
                                 $switchresult .= "Section for $uname switched from old section: ".$$currlist{$uname}[$sec] ." to new section: ".$stuinfo[ $place{groupID} ].".".$access.$linefeed;                                  $switchresult .= &mt('Section for [_1] switched from old section: [_2] to new section: [_3].',$uname,$$currlist{$uname}[$sec],$stuinfo[ $place{groupID} ]).$access.$linefeed;
                                   $added = 1;
                                 if ($context eq 'automated') {                                  if ($context eq 'automated') {
                                     $$logmsg .= "Section switch for $uname from $$currlist{$uname}[$sec] to $stuinfo[ $place{groupID} ]".$linefeed;                                      $$logmsg .= &mt('Section switch for [_1] from [_2] to [_3].',$uname,$$currlist{$uname}[$sec],$stuinfo[ $place{groupID} ]).$linefeed;
                                 }                                  }
                                 $switchcount ++;                                  $switchcount ++;
                             } else {                              } else {
                                 $$logmsg .= "Error when attempting section change for $uname from old section ".$$currlist{$uname}[$sec]." to new section: ".$stuinfo[ $place{groupID} ]." -error: $modify_section_result".$linefeed;                                  $$logmsg .= &mt("Error when attempting section change for [_1], from old section: '[_2]' to new section: '[_3]' -error: [_4]",$uname,$$currlist{$uname}[$sec],$stuinfo[ $place{groupID} ],$modify_section_result).$linefeed;
                             }                              }
                         } else {                          } else {
                             $$logmsg .= "Error when attempting to expire role for $uname in old section" .$$currlist{$uname}[$sec]." -error: $expire_role_result".$linefeed;                              $$logmsg .= &mt("Error when attempting to expire role for [_1] in old section: '[_2]' -error: '[_3]'.",$uname,$$currlist{$uname}[$sec],$expire_role_result).$linefeed;
                         }                          }
                     }                      }
                 }                  }
   # Check for credits changes
                   if (($showcredits) && 
                       ($$currlist{$uname}[$credidx] ne $credits) && (!$added)) {
                       my $modify_credits_result =
                           &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid,'',$context,$credits,$instsec);
                       if ($modify_credits_result =~ /^ok/) {
                           if ($credits ne '') {
                               $$logmsg .= &mt('Credits change for [_1] from [_2] to [_3].',$uname,$$currlist{$uname}[$credidx],$credits).$linefeed;
                           } else {
                               $$logmsg .= &mt('Credits change for [_1] from [_2] to course default [_3].',$uname,$$currlist{$uname}[$credidx],$defaultcredits).$linefeed;
                           }
                       } else {
                           $$logmsg .= &mt('Error when attempting to change credits for [_1] in section: [_2] -error [_3].',$uname,$stuinfo[$place{groupID}],$modify_credits_result).$linefeed;
                       }
                   }
   # Check for institutional section change
                   if (($$currlist{$uname}[$instidx] ne $instsec) && (!$added) && ($$currlist{$uname}[$type] eq "auto")) {
                       my $modify_instsec_result =
                           &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid,'',$context,$credits,$instsec);
                       if ($modify_instsec_result =~ /^ok/) {
                           $$logmsg .= &mt('Institutional section change for [_1] from [_2] to [_3].',$uname,$$currlist{$uname}[$instidx],$instsec).$linefeed;
                       } else {
                           $$logmsg .= &mt('Error when attempting to change institutional section for [_1] in section: [_2] -error [_3].',$uname,$stuinfo[$place{groupID}],$modify_instsec_result).$linefeed;
                       }
                   }
             } else {              } else {
 # Check for changed usernames by checking studentIDs  # Check for changed usernames by checking studentIDs
                 if ( ($stuinfo[ $place{studentID} ] ne '') && (grep/^$stuinfo[ $place{studentID} ]$/,@LCids) ) {                  if ( ($stuinfo[ $place{studentID} ] ne '') && (grep/^$stuinfo[ $place{studentID} ]$/,@LCids) ) {
                     foreach my $match ( @{ $unameFromLCid{ $stuinfo[ $place{studentID} ] } }  ) {                      foreach my $match ( @{ $unameFromLCid{ $stuinfo[ $place{studentID} ] } }  ) {
                         $$logmsg .= "A possible change in username has been detected for a student enrolled in this course. The existing LON-CAPA classlist contains user: $match and student ID: ".$stuinfo[ $place{studentID} ].". ";                          $$logmsg .= &mt('A possible change in username has been detected for a student enrolled in this course.').' '.&mt('The existing LON-CAPA classlist contains user: [_1] and student/employee ID: [_2].',$match,$stuinfo[ $place{studentID} ]);
                         if (grep/^$match$/,@okusers) {                          if (grep/^$match$/,@okusers) {
                             $$logmsg .= "The username $match remains in the institutional classlist, but the same student ID is used for new user: $uname now found in the institutional classlist. You may need to contact your Domain Coordinator to determine how to reolve this issue and whether to move student data files for user: $match to $uname. ";                              $$logmsg .= &mt('The username [_1] remains in the institutional classlist, but the same student/employee ID is used for new user: [_2] now found in the institutional classlist.',$match,$uname).' '.&mt('You may need to contact your Domain Coordinator to determine how to resolve this issue and whether to move student data files for user: [_1] to [_2].',$match,$uname).' ';
                         } else {                          } else {
                             unless ($drops == 1) {                              unless ($drops == 1) {
                                 $$logmsg .= "This username - $match - has been dropped from the institutional classlist, but the student ID of this user is also used by $uname who now appears in the institutional classlist. You may need to contact your Domain Coordinator to request a move of the student data files for user: $match to $uname. ";                                  $$logmsg .= &mt('This username - [_1] - has been dropped from the institutional classlist, but the student/employee ID of this user is also used by [_2] who now appears in the institutional classlist.',$match,$uname).' '.&mt('You may need to contact your Domain Coordinator to request a move of the student data files for user: [_1] to [_2].',$match,$uname).' ';
                             }                              }
                         }                          }
                         $$logmsg .= "Because of this student ID conflict, the new username - $uname - has not been added to the LON-CAPA classlist.".$linefeed;                                $$logmsg .= &mt('Because of this student/employee ID conflict, the new username - [_1] - has not been added to the LON-CAPA classlist',$uname).$linefeed;
                     }                      }
                 } elsif ($adds == 1) {                  } elsif ($adds == 1) {
                     my ($auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,$emailaddr,$pid,$emailenc);                      my ($auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,$emailaddr,$pid,$emailenc,$credithours);
                     &prepare_add($authtype,$autharg,$enddate,$startdate,\@stuinfo,\%place,\$dom,\$uname,\$auth,\$authparam,\$first,\$middle,\$last,\$gene,\$usec,\$end,\$start,\$emailaddr,\$pid,\$emailenc);                      &prepare_add($authtype,$autharg,$enddate,$startdate,\@stuinfo,\%place,\$dom,\$uname,\$auth,\$authparam,\$first,\$middle,\$last,\$gene,\$usec,\$end,\$start,\$emailaddr,\$pid,\$emailenc);
 # Check for existing account in this LON-CAPA domain for this username  # Check for existing account in this LON-CAPA domain for this username
                       next if (($end) && ($end < $now));
                     my $uhome=&Apache::lonnet::homeserver($uname,$dom);                      my $uhome=&Apache::lonnet::homeserver($uname,$dom);
                     if ($uhome eq 'no_host') { # User does not exist                      if ($uhome eq 'no_host') { # User does not exist
                         my $args = {'auth' => $auth,                          my $args = {'auth' => $auth,
Line 320  sub update_LC { Line 380  sub update_LC {
                                     'cdom' => $dom,                                      'cdom' => $dom,
                                     'context' => $context,                                      'context' => $context,
                                     'linefeed' => $linefeed,                                      'linefeed' => $linefeed,
                                     'role' => 'st'                                      'inststatus' => $inststatus,
                                       'instsec'  => $instsec,
                                       'role' => 'st',
                                    };                                     };
                         my $outcome = &create_newuser($args,$logmsg,$newusermsg,\$enrollcount,\$addresult,\%longroles,\%courseinfo);                          if ($credits) {
                               $args->{'credits'} = $credits;
                           }
                           my $outcome = &create_newuser($args,$logmsg,$newusermsg,\$enrollcount,\$addresult,\%longroles,\%courseinfo,$context);
                     } else {                      } else {
                         &execute_add($context,'newstudent',$uname,$dom,$auth,$authparam,$first,$middle,$last,$gene,$pid,$usec,$end,$start,$emailenc,$cid,\$addresult,\$enrollcount,$linefeed,$logmsg);                          &execute_add($context,'newstudent',$uname,$dom,$auth,
                                        $authparam,$first,$middle,$last,$gene,$pid,
                                        $usec,$end,$start,$emailenc,$credits,$instsec,
                                        $cid,\$addresult,\$enrollcount,$linefeed,
                                        $logmsg);
                     }                      }
                     if ($courseinfo{'showphotos'}) {                      if ($courseinfo{'showphoto'}) {
                         my ($result,$resulttype) =                           my ($result,$resulttype) = 
                            &Apache::lonnet::auto_checkphotos($uname,$dom,$pid);                             &Apache::lonnet::auto_checkphotos($uname,$dom,$pid);
                         if ($resulttype) {                          if ($resulttype) {
Line 337  sub update_LC { Line 406  sub update_LC {
             }              }
         }          }
     }      }
     if ($courseinfo{'showphotos'}) {      if ($courseinfo{'showphoto'}) {
         if (keys(%{$phototypes})>0) {          if (keys(%{$phototypes})>0) {
             my %lt = &photo_response_types();              my %lt = &photo_response_types();
             foreach my $type (sort(keys(%{$phototypes}))) {              foreach my $type (sort(keys(%{$phototypes}))) {
Line 345  sub update_LC { Line 414  sub update_LC {
                 if ($numphoto > 0) {                  if ($numphoto > 0) {
                     if ($context eq 'updatenow') {                      if ($context eq 'updatenow') {
                         $photoresult .=  '<br /><b>'.                          $photoresult .=  '<br /><b>'.
                                    &mt('For [_1] students, photos ',$numphoto).      &mt('For [_1] students, photos ',$numphoto).
                                                      $lt{$type}.'</b><ul><li>';      $lt{$type}.'</b><ul><li>';
                     } else {                      } else {
                         $photoresult .=  "\nFor $numphoto students, photos ".                          $photoresult .=  "\n".&mt("For [quant,_1,student], photos ",$numphoto).
                                                                $lt{$type}."\n";      $lt{$type}."\n";
                     }                      }
                     foreach my $user (@{$$phototypes{$type}}) {                       foreach my $user (@{$$phototypes{$type}}) { 
                         $photoresult .= $user.$linefeed;                          $photoresult .= $user.$linefeed;
                     }                      }
                     if ($context eq 'updatenow') {                      if ($context eq 'updatenow') {
                         $photoresult = substr($photoresult,0,                          $photoresult = substr($photoresult,0,
                                                   rindex($photoresult,"<li>"));        rindex($photoresult,"<li>"));
                         $photoresult .= '</ul><br />';                          $photoresult .= '</ul><br />';
                     } else {                      } else {
                         $photoresult .= "\n";                          $photoresult .= "\n";
Line 368  sub update_LC { Line 437  sub update_LC {
   
 # Do drops  # Do drops
     if ( ($drops == 1) && (@reg_students > 0) ) {      if ( ($drops == 1) && (@reg_students > 0) ) {
           my %delaydrops;
         foreach my $uname (@localstudents) {          foreach my $uname (@localstudents) {
             if ($$currlist{$uname}[$type] eq "auto") {              if ($$currlist{$uname}[$type] eq "auto") {
                 my @saved = ();                  my @saved = ();
Line 375  sub update_LC { Line 445  sub update_LC {
 # Check for changed usernames by checking studentIDs  # Check for changed usernames by checking studentIDs
                     if (grep/^$$currlist{$uname}[ $stuid ]$/,@allINids) {                      if (grep/^$$currlist{$uname}[ $stuid ]$/,@allINids) {
                         foreach my $match (@{$unameFromINid{$$currlist{$uname}[ $stuid ]}} ) {                          foreach my $match (@{$unameFromINid{$$currlist{$uname}[ $stuid ]}} ) {
                             $$logmsg .= "A possible change in username has been detected for a student enrolled in this course. The existing LON-CAPA classlist contains user: $uname and student ID: $$currlist{$uname}[ $place{studentID} ].  This username has been dropped from the institutional classlist, but the same student ID is used for user: $match who still appears in the institutional classlist. You may need to move the student data files for user: $uname to $match. Because of this, user $uname has not been dropped from the course.".$linefeed;                              $$logmsg .= &mt('A possible change in username has been detected for a student enrolled in this course.').' '.&mt('The existing LON-CAPA classlist contains user: [_1] and student/employee ID: [_2].',$uname,$$currlist{$uname}[ $stuid ]).' '.&mt('This username has been dropped from the institutional classlist, but the same student/employee ID is used for user: [_1] who still appears in the institutional classlist.',$match).' '.&mt('You may need to move the student data files for user: [_1] to [_2]',$uname,$match).' '.&mt('Because of this, user [_1] has not been dropped from the course.',$uname).$linefeed;
                             push @saved,$uname;                              push @saved,$uname;
                         }                          }
                     } elsif (@saved == 0) {                      } elsif (@saved == 0) {
                         my $drop_reply = &Apache::lonnet::modifystudent($dom,$uname,'','','',undef,undef,undef,undef,$$currlist{$uname}[$sec],time,undef,undef,undef,undef,'auto','',$cid);  # Check enrollment count for institutional section of student to be dropped 
                           if ($$currlist{$uname}[$instidx]) {
                               if (exists($classcount{$$currlist{$uname}[$instidx]})) {
                                   if ($classcount{$$currlist{$uname}[$instidx]} == 0) {
                                       if ($autofailsafe) {
                                           push(@{$delaydrops{$$currlist{$uname}[$instidx]}},$uname);    
                                           next;
                                       }
                                   }
                               }
                           }
                           my $drop_reply = &Apache::lonnet::modifystudent($dom,$uname,'','','',undef,undef,undef,undef,$$currlist{$uname}[$sec],time,undef,undef,undef,undef,'auto','',$cid,'',$context);
                         if ($drop_reply !~ /^ok/) {                          if ($drop_reply !~ /^ok/) {
                             $$logmsg .= "An error occured during the attempt to expire the $uname from the old section $$currlist{$uname}[$sec] - $drop_reply.".$linefeed;                              $$logmsg .= &mt('An error occurred during the attempt to expire the [_1] from the old section [_2] - [_3].',$uname,$$currlist{$uname}[$sec],$drop_reply).$linefeed;
                         } else {                          } else {
                             $dropcount ++;                              $dropcount ++;
                             my %userenv = &Apache::lonnet::get('environment',['firstname','lastname','id'],$dom,$uname);                              my %userenv = &Apache::lonnet::get('environment',['firstname','lastname','id'],$dom,$uname);
                             $dropresult .= $userenv{'firstname'}." ".$userenv{'lastname'}." (".$userenv{'id'}.") - ".$uname." dropped from section/group ".$$currlist{$uname}[$sec].$linefeed;                               $dropresult .= $userenv{'firstname'}." ".$userenv{'lastname'}." (".$userenv{'id'}.") - ".$uname.' '.&mt("dropped from section: '[_1]'.",$$currlist{$uname}[$sec]).$linefeed; 
                             if ($context eq 'automated') {                              if ($context eq 'automated') {
                                 $$logmsg .= "User $uname student role expired from course.".$linefeed;                                  $$logmsg .= &mt('User [_1] student role expired from course.',$uname).$linefeed;
                               }
                           }
                       }
                   }
               }
           }
           if (scalar(keys(%delaydrops)) > 0) {
               foreach my $class (keys(%delaydrops)) {
                   if (ref($delaydrops{$class}) eq 'ARRAY') {
                       if ($autofailsafe < scalar(@{$delaydrops{$class}})) {
                           $$logmsg .= &mt('The following students were not expired from the old section [_1] because the enrollment count retrieved for that institutional section was zero, and the number of students with roles to expire exceeded the failsafe threshold of [_2]:',$class,$autofailsafe);
                           if ($context eq "updatenow") {
                               $$logmsg .= '<br />'.join('<br />',@{$delaydrops{$class}}).$linefeed; 
                           } elsif ($context eq "automated") {
                               $$logmsg .= $linefeed.join($linefeed,@{$delaydrops{$class}}).$linefeed;
                           }
                       } else {
                           foreach my $uname (@{$delaydrops{$class}}) {
                               my $drop_reply = &Apache::lonnet::modifystudent($dom,$uname,'','','',undef,undef,undef,undef,$$currlist{$uname}[$sec],time,undef,undef,undef,undef,'auto','',$cid,'',$context);
                               if ($drop_reply !~ /^ok/) {
                                   $$logmsg .= &mt('An error occurred during the attempt to expire the [_1] from the old section [_2] - [_3].',$uname,$$currlist{$uname}[$sec],$drop_reply).$linefeed;
                               } else {
                                   $dropcount ++;
                                   my %userenv = &Apache::lonnet::get('environment',['firstname','lastname','id'],$dom,$uname);
                                   $dropresult .= $userenv{'firstname'}." ".$userenv{'lastname'}." (".$userenv{'id'}.") - ".$uname.' '.&mt("dropped from section: '[_1]'.",$$currlist{$uname}[$sec]).$linefeed;
                                   if ($context eq 'automated') {
                                      $$logmsg .= &mt('User [_1] student role expired from course.',$uname).$linefeed;
                                   }
                             }                              }
                         }                          }
                     }                      }
Line 396  sub update_LC { Line 505  sub update_LC {
         }          }
     }      }
   
 # Terminated explictly allowed access to student creation/modification  # Terminated explictly allowed access to student creation/modification 
   # and group membership changes
     if ($context eq 'automated') {      if ($context eq 'automated') {
         delete($env{'allowed.cst'});          delete($env{'allowed.cst'});
           delete($env{'allowed.mdg'});
     }      }
     if ($enrollcount > 0) {      if ($enrollcount > 0) {
         if ($context eq "updatenow") {          if ($context eq "updatenow") {
             $addresult = substr($addresult,0,rindex($addresult,"<li>"));              $addresult = substr($addresult,0,rindex($addresult,"<li>"));
             $addresult = "The following $enrollcount student(s) was/were added to this LON-CAPA course:<br/><ul><li>".$addresult."</ul><br/><br/>";              $addresult = &mt("The following [quant,_1,student was,students were] added to this LON-CAPA course:",$enrollcount).'<br/><ul><li>'.$addresult.'</ul><br/><br/>';
             if ($courseinfo{'showphotos'}) {  
   
             }  
         } else {          } else {
             $addresult = "The following $enrollcount student(s) was/were added to this LON-CAPA course:\n\n".$addresult."\n\n";              $addresult = &mt("The following [quant,_1,student was,students were] added to this LON-CAPA course:",$enrollcount)."\n\n".$addresult."\n\n";
         }          }
     }      }
     if ($dropcount > 0) {      if ($dropcount > 0) {
         if ($context eq "updatenow") {          if ($context eq "updatenow") {
             $dropresult = substr($dropresult,0,rindex($dropresult,"<li>"));              $dropresult = substr($dropresult,0,rindex($dropresult,"<li>"));
             $dropresult = "The following $dropcount student(s) was/were expired from this LON-CAPA course:<br/><ul><li>".$dropresult."</ul><br/><br/>";              $dropresult = &mt("The following [quant,_1,student was,students were] expired from this LON-CAPA course:",$dropcount).'<br/><ul><li>'.$dropresult.'</ul><br/><br/>';
         } else {          } else {
             $dropresult = "The following $dropcount student(s) was/were expired from this LON-CAPA course:\n\n".$dropresult."\n\n";              $dropresult = &mt("The following [quant,_1,student was,students were] expired from this LON-CAPA course:",$dropcount)."\n\n".$dropresult."\n\n";
         }          }
     }      }
     if ($switchcount > 0) {      if ($switchcount > 0) {
         if ($context eq "updatenow") {          if ($context eq "updatenow") {
             $switchresult = substr($switchresult,0,rindex($switchresult,"<li>"));              $switchresult = substr($switchresult,0,rindex($switchresult,"<li>"));
             $switchresult = "The following $switchcount student(s) switched sections in this LON-CAPA course:<br/><ul><li>".$switchresult."</ul><br/><br/>";              $switchresult = &mt("The following [quant,_1,student] switched sections in this LON-CAPA course:",$switchcount).'<br/><ul><li>'.$switchresult.'</ul><br/><br/>';
         } else {          } else {
             $switchresult = "The following $switchcount student(s) switched sections in this LON-CAPA course:\n\n".$switchresult."\n\n";              $switchresult = &mt("The following [quant,_1,student] switched sections in this LON-CAPA course:",$switchcount)."\n\n".$switchresult."\n\n";
         }          }
     }      }
     if ( ($adds) && ($enrollcount == 0) ) {      if ( ($adds) && ($enrollcount == 0) ) {
         $addresult = "There were no new students to add to the course.";          $addresult = &mt('There were no new students to add to the course.');
         if ($context eq "updatenow") {          if ($context eq "updatenow") {
             $addresult .="<br/><br/>";              $addresult .="<br/><br/>";
         } else {          } else {
Line 436  sub update_LC { Line 544  sub update_LC {
         }          }
     }      }
     if ( ($drops) && ($dropcount == 0) ) {      if ( ($drops) && ($dropcount == 0) ) {
         $dropresult = "There were no students with roles to expire because all active students previously added to the course from institutional classlist(s) are still officially registered.";          $dropresult = &mt('There were no students with roles to expire because all active students previously added to the course from institutional classlist(s) are still officially registered.');
         if ($context eq "updatenow") {          if ($context eq "updatenow") {
             $dropresult .="<br/>";              $dropresult .="<br/>";
         } else {          } else {
Line 448  sub update_LC { Line 556  sub update_LC {
 }  }
   
 sub create_newuser {  sub create_newuser {
     my ($args,$logmsg,$newusermsg,$enrollcount,$addresult,$longroles,$courseinfo) = @_;      my ($args,$logmsg,$newusermsg,$enrollcount,$addresult,$longroles,
    $courseinfo,$called_context) = @_;
     my $auth = $args->{'auth'};      my $auth = $args->{'auth'};
     my $authparam = $args->{'authparam'};      my $authparam = $args->{'authparam'};
     my $emailenc = $args->{'emailenc'};      my $emailenc = $args->{'emailenc'};
Line 469  sub create_newuser { Line 578  sub create_newuser {
     my $context = $args->{'context'};      my $context = $args->{'context'};
     my $linefeed = $args->{'linefeed'};      my $linefeed = $args->{'linefeed'};
     my $role = $args->{'role'};      my $role = $args->{'role'};
       my $inststatus = $args->{'inststatus'};
       my $credits = $args->{'credits'};
       my $instsec = $args->{'instsec'};
     my $create_passwd = 0;      my $create_passwd = 0;
     my $authchk = '';      my $authchk = '';
     my $outcome;      my $outcome;
Line 476  sub create_newuser { Line 588  sub create_newuser {
 # If no account exists and passwords should be generated  # If no account exists and passwords should be generated
     if ($auth eq "internal") {      if ($auth eq "internal") {
         if ($authparam eq '') {          if ($authparam eq '') {
             $authparam = &create_password();              $authparam = &create_password($udom);
             if ($authparam eq '') {              if ($authparam eq '') {
                 $authchk = '';                  $authchk = '';
             } else {              } else {
Line 485  sub create_newuser { Line 597  sub create_newuser {
             }              }
         }          }
     } elsif ($auth eq "localauth") {      } elsif ($auth eq "localauth") {
         ($authparam,$create_passwd,$authchk) = &Apache::lonnet::auto_create_password($crs,$cdom,$authparam);          ($authparam,$create_passwd,$authchk) = &Apache::lonnet::auto_create_password($crs,$cdom,$authparam,$udom);
     } elsif ($auth =~ m/^krb/) {      } elsif ($auth =~ m/^krb/) {
         if ($authparam eq '') {          if ($authparam eq '') {
             $$logmsg .= "No Kerberos domain was provided for the new user - $uname, so the new user was not enrolled in the course.".$linefeed;              $$logmsg .= &mt('No Kerberos domain was provided for the new user - [_1], so the new user was not enrolled in the course',$uname).$linefeed;
             $authchk = 'invalid';              $authchk = 'invalid';
         }          }
     } else {      } else {
         $authchk = 'invalid';          $authchk = 'invalid';
         $$logmsg .= "An invalid authentication type was provided for the new user - $uname, so the user was not enrolled in the course.".$linefeed;          $$logmsg .= &mt('An invalid authentication type was provided for the new user - [_1], so the user was not enrolled in the course.',$uname).$linefeed;
     }         }
     if ($authchk eq 'ok') {      if ($authchk eq 'ok') {
 # Now create user.  # Now create user.
         my $type = 'auto';          my $type = 'auto';
Line 505  sub create_newuser { Line 617  sub create_newuser {
         if ($context eq 'createowner' || $context eq 'createcourse') {          if ($context eq 'createowner' || $context eq 'createcourse') {
             my $result = &Apache::lonnet::modifyuser($udom,$uname,$pid,$auth,$authparam,$first,$middle,$last,$gene,'1',undef,$emailaddr);              my $result = &Apache::lonnet::modifyuser($udom,$uname,$pid,$auth,$authparam,$first,$middle,$last,$gene,'1',undef,$emailaddr);
             if ($result eq 'ok' && $context eq 'createcourse') {              if ($result eq 'ok' && $context eq 'createcourse') {
                 $outcome = &Apache::loncreateuser::commit_standardrole($udom,$uname,$userurl,$role,$start,$end,$cdom,$crs,$usec);                  $outcome = &Apache::loncommon::commit_standardrole($udom,$uname,$userurl,$role,$start,$end,$cdom,$crs,$usec,$called_context);
                 unless ($outcome =~ /^Error:/) {                  unless ($outcome =~ /^Error:/) {
                     $outcome = 'ok';                      $outcome = 'ok';
                 }                  }
Line 513  sub create_newuser { Line 625  sub create_newuser {
                 $outcome = $result;                  $outcome = $result;
             }              }
         } else {          } else {
             $outcome=&Apache::lonnet::modifystudent($udom,$uname,$pid,$auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,'',undef,$emailaddr,'auto','',$cid);              $outcome=&Apache::lonnet::modifystudent($udom,$uname,$pid,$auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,'',undef,$emailaddr,'auto','',$cid,'',$called_context,$inststatus,$credits,$instsec);
         }          }
         if ($outcome eq 'ok') {          if ($outcome eq 'ok') {
             my $access = &showaccess($end,$start);              my $access = &showaccess($end,$start);
             $$addresult .= "$first $last ($pid) - $uname enrolled in section/group $usec.".$access.$linefeed;              my $showsec = $usec;
               if ($usec eq '') {
                   $showsec = &mt('none');
               }
               $$addresult .= "$first $last ($pid) - $uname ".&mt("enrolled in section: '[_1]'.",$showsec).$access.$linefeed;
             unless ($context eq 'createowner' || $context eq 'createcourse') {              unless ($context eq 'createowner' || $context eq 'createcourse') {
                 $$enrollcount ++;                  $$enrollcount ++;
             }              }
             if ($context eq 'automated') {              if ($called_context eq 'automated') {
                 $$logmsg .= "New $udom user $uname added successfully.";                  $$logmsg .= &mt('New [_1] user [_2] added successfully.',$udom,$uname);
             }              }
             unless ($emailenc eq '' || $context eq 'createowner' || $context eq 'createcourse') {              unless ($emailenc eq '' || $context eq 'createowner' || $context eq 'createcourse') {
                 my %emailHash;                  my %emailHash;
Line 536  sub create_newuser { Line 652  sub create_newuser {
 # If e-mail address is invalid, send password via message to courseowner i  # If e-mail address is invalid, send password via message to courseowner i
 # (if automated call) or to user if roster update.  # (if automated call) or to user if roster update.
                 if ($emailaddr eq '') {                  if ($emailaddr eq '') {
                     $$newusermsg .= " username: $uname, password: ".$authparam.$linefeed."\n";                      $$newusermsg .= &mt(' username: [_1], password: [_2]',$uname,$authparam).$linefeed."\n";
                 } else {                  } else {
                     my $subject = "New LON-CAPA account";                      my $subject = &mt('New LON-CAPA account');
                     my $body;                      my $body;
                       my $portalurl = 'http://'.$ENV{'SERVER_NAME'};
                       my $protocol = 'http';
                       my $lonhost=&Apache::lonnet::domain($udom,'primary');
                       if ($lonhost ne '') {
                           my $ip = &Apache::lonnet::get_host_ip($lonhost);
                           if ($Apache::lonnet::protocol{$lonhost} eq 'https') {
                               $protocol = 'https';
                           }
                           if ($ip ne '') {
                               $portalurl = $protocol.'://'.$ip
                           }
                       }
                     if ($context eq 'createowner') {                      if ($context eq 'createowner') {
                         $body = "A user account has been created for you while creating your new course in the LON-CAPA course management and online homework system.\n\nYou should log-in to the system using the following credentials:\nusername: $uname\npassword: $authparam\n\nThe URL you should use to access the LON-CAPA system at your school is: http://".$ENV{'SERVER_NAME'}."\n\n";                          $body = &mt('A user account has been created for you while creating your new course in the LON-CAPA course management and online homework system.')."\n\n".&mt('You should log-in to the system using the following credentials:')."\n".&mt('username: ').$uname."\n".&mt('password: ').$authparam."\n\n".&mt('The URL you should use to access the LON-CAPA system at your institution is: ').$portalurl."\n\n";
                     } elsif ($context eq 'createcourse') {                      } elsif ($context eq 'createcourse') {
                         $body = "You have been assigned the role of $$longroles{$role} in a new course: $$courseinfo{'description'} - $$courseinfo{'inst_code'} in the LON-CAPA course management and online homework system.  As you did not have an existing user account in the system, one has been created for you.\n\nYou should log-in to the system using the following credentials:\nusername: $uname\npassword: $authparam\n\nThe URL you should use to access the LON-CAPA system at your school is: http://".$ENV{'SERVER_NAME'}."\n\n";                           $body = &mt('You have been assigned the role of [_1] in a new course: [_2] - [_3] in the LON-CAPA course management and online homework system.',$$longroles{$role},$$courseinfo{'description'},$$courseinfo{'inst_code'}).' '.&mt('As you did not have an existing user account in the system, one has been created for you.')."\n\n".&mt("You should log-in to the system using the following credentials:\nusername: [_1]\npassword: [_2]",$uname,$authparam)."\n\n".&mt('The URL you should use to access the LON-CAPA system at your institution is: ').$portalurl."\n\n"; 
                     } else {                      } else {
                         my $access_start = 'immediately';                          my $access_start = 'immediately';
                         if ($start > 0) {                          if ($start > 0) {
                             $access_start = localtime($start)                              $access_start = localtime($start)
                         }                          }
                         $body = "You have been enrolled in the LON-CAPA system at your school, because you are a registered student in a class that is using the LON-CAPA couse management and online homework system.\n\nYou should log-in to the system using the following credentials:\nusername: $uname\npassword: $authparam\n\nThe URL you should use to access the LON-CAPA system at your school is: http://".$ENV{'SERVER_NAME'}."\n\n.When you log-in you will be able to access the LON-CAPA course for $$courseinfo{'description'} - $$courseinfo{'inst_code'} starting $access_start.\n";                          $body =
                               &mt('You have been enrolled in the LON-CAPA system at your institution, because you are a registered student in a class which is using the LON-CAPA course management and online homework system.')."\n\n"
                              .&mt("You should log-in to the system using the following credentials:\nusername: [_1]\npassword: [_2]",$uname,$authparam)."\n\n"
                              .&mt('The URL you should use to access the LON-CAPA system at your institution is: ').$portalurl."\n\n"
                              .&mt('When you log-in you will be able to access the LON-CAPA course for [_1] - [_2] starting [_3].',$$courseinfo{'description'},$$courseinfo{'inst_code'},$access_start)."\n";
                     }                      }
                     &Apache::lonmsg::sendemail($emailaddr,$subject,$body);                      &Apache::lonmsg::sendemail($emailaddr,$subject,$body);
                 }                  }
                 if ($context eq 'automated') {                  if ($called_context eq 'automated') {
                     $$logmsg .= " Initial password -  - sent to ".$emailaddr.$linefeed;                      $$logmsg .= &mt(' Initial password - sent to ').$emailaddr.$linefeed;
                 }                  }
             } else {              } else {
                 if ($context eq 'automated') {                  if ($called_context eq 'automated') {
                     $$logmsg .= $linefeed;                      $$logmsg .= $linefeed;
                 }                  }
             }              }
         } else {          } else {
             $$logmsg .= "An error occurred adding new user $uname - ".$outcome.$linefeed;              $$logmsg .= &mt('An error occurred adding new user [_1] - [_2].',$uname,$outcome).$linefeed;
         }          }
       } else {
           $$logmsg .= &mt('An error occurred adding the new user [_1] because the authcheck failed for authtype [_2] and parameter [_3].',$uname,$auth,$authparam).' '.&mt('The authcheck response was [_1].',$authchk).$linefeed;
     }      }
     return $outcome;      return $outcome;
 }  }
Line 581  sub prepare_add { Line 715  sub prepare_add {
     $$start = $$stuinfo[ $$place{'startdate'} ];      $$start = $$stuinfo[ $$place{'startdate'} ];
     $$emailaddr = $$stuinfo[ $$place{'email'} ];      $$emailaddr = $$stuinfo[ $$place{'email'} ];
     $$pid = $$stuinfo[ $$place{'studentID'} ];      $$pid = $$stuinfo[ $$place{'studentID'} ];
                                                                                     
 # remove non alphanumeric values from section  # remove non alphanumeric values from section
     $$usec =~ s/\W//g;      $$usec =~ s/\W//g;
                                                                                                                                                                       
Line 609  sub prepare_add { Line 743  sub prepare_add {
 }  }
   
 sub execute_add {  sub execute_add {
     my ($context,$caller,$uname,$dom,$auth,$authparam,$first,$middle,$last,$gene,$pid,$usec,$end,$start,$emailenc,$cid,$addresult,$enrollcount,$linefeed,$logmsg) = @_;      my ($context,$caller,$uname,$dom,$auth,$authparam,$first,$middle,$last,
           $gene,$pid,$usec,$end,$start,$emailenc,$credits,$instsec,$cid,$addresult,
           $enrollcount,$linefeed,$logmsg) = @_;
 # Get the user's information and authentication  # Get the user's information and authentication
     my %userenv = &Apache::lonnet::get('environment',['firstname','middlename','lastname','generation','id','critnotification','notification','permanentemail'],$dom,$uname);      my %userenv = &Apache::lonnet::get('environment',['firstname','middlename','lastname','generation','id','critnotification','notification','permanentemail','inststatus'],$dom,$uname);
     my ($tmp) = keys(%userenv);      my ($tmp) = keys(%userenv);
     if ($tmp =~ /^(con_lost|error)/i) {      if ($tmp =~ /^(con_lost|error)/i) {
         %userenv = ();          %userenv = ();
Line 619  sub execute_add { Line 755  sub execute_add {
 # Get the user's e-mail address  # Get the user's e-mail address
     if ($userenv{critnotification} =~ m/%40/) {      if ($userenv{critnotification} =~ m/%40/) {
         unless ($emailenc eq $userenv{critnotification}) {          unless ($emailenc eq $userenv{critnotification}) {
             $$logmsg .= "Current critical notification e-mail              $$logmsg .= &mt('Current critical notification e-mail - [_1] for [_2] is different to e-mail address in institutional classlist - [_3].',
 - ".$userenv{critnotification}." for $uname is different to e-mail address in institutional classlist - ".$emailenc.$linefeed;                             $userenv{critnotification},$uname,$emailenc).
                           $linefeed;
         }          }
     }      }
     if ($userenv{notification} =~ m/%40/) {      if ($userenv{notification} =~ m/%40/) {
         unless ($emailenc eq $userenv{notification}) {          unless ($emailenc eq $userenv{notification}) {
             $$logmsg .= "Current standard notification e-mail              $$logmsg .= &mt('Current standard notification e-mail - [_1] for [_2] is different to e-mail address in institutional classlist - [_3].',
 - ".$userenv{notification}." for $uname is different to e-mail address in institutional classlist - ".$emailenc.$linefeed;                              $userenv{notification},$uname,$emailenc).
                           $linefeed;
         }          }
     }      }
     if ($userenv{permanentemail} =~ m/%40/) {      if ($userenv{permanentemail} =~ m/%40/) {
         unless ($emailenc eq $userenv{permanentemail}) {          unless ($emailenc eq $userenv{permanentemail}) {
             $$logmsg .= "Current permanent e-mail              $$logmsg .= &mt('Current permanent e-mail
 - ".$userenv{permanentemail}." for $uname is different to e-mail address in institutional classlist - ".$emailenc.$linefeed;  - [_1] for [_2] is different to e-mail address in institutional classlist - [_3]',$userenv{permanentemail},$uname,$emailenc).$linefeed;
         }          }
     }      }
     my $krbdefdom = '';      my $krbdefdom = '';
Line 643  sub execute_add { Line 781  sub execute_add {
     } elsif ($currentauth=~ /^(unix|internal|localauth):/) {      } elsif ($currentauth=~ /^(unix|internal|localauth):/) {
         $currentauth = $1;          $currentauth = $1;
     } else {      } else {
         $$logmsg .= "Invalid authentication method $currentauth for $uname.".$linefeed;          $$logmsg .= &mt('Invalid authentication method [_1] for [_2].',$currentauth,$uname).$linefeed;
     }      }
 # Report if authentication methods are different.  # Report if authentication methods are different.
     if ($currentauth ne $auth) {      if ($currentauth ne $auth) {
         $$logmsg .= "Authentication type mismatch for $uname - '$currentauth' in system, '$auth' based on information in classlist or default for this course.".$linefeed;          $$logmsg .= &mt("Authentication type mismatch for [_1] - '[_2]' in system, '[_3]' based on information in classlist or default for this course.",$uname,$currentauth,$auth).$linefeed;
     } elsif ($auth =~ m/^krb/) {      } elsif ($auth =~ m/^krb/) {
         if ($krbdefdom ne $authparam) {          if ($krbdefdom ne $authparam) {
             $$logmsg .= "Kerberos domain mismatch for $uname - '$krbdefdom' in system, '$authparam' based on information in classlist or default for this course.".$linefeed;              $$logmsg .= &mt("Kerberos domain mismatch for [_1] - '[_2]' in system, '[_3]' based on information in classlist or default for this course.",$uname,$krbdefdom,$authparam).$linefeed;
         }          }
     }      }
                                                                                                                                                                       
Line 671  sub execute_add { Line 809  sub execute_add {
         $changeHash{'permanentemail'} = $emailenc;          $changeHash{'permanentemail'} = $emailenc;
         my $putresult = &Apache::lonnet::put('environment',\%changeHash,$dom,$uname);          my $putresult = &Apache::lonnet::put('environment',\%changeHash,$dom,$uname);
         if ($putresult eq 'ok') {          if ($putresult eq 'ok') {
             $$logmsg .= "User information updated for user: $uname prior to enrollment.".$linefeed;              $$logmsg .= &mt('User information updated for user: [_1] prior to enrollment.',$uname).$linefeed;
         } else {          } else {
             $$logmsg .= "There was a problem modifying user data for existing user - $uname -error: $putresult, enrollment will still be attempted.".$linefeed;              $$logmsg .= &mt('There was a problem modifying user data for existing user - [_1] -error: [_2], enrollment will still be attempted.',$uname,$putresult).$linefeed;
         }          }
     }      }
                                                                                                                                                                       
 # Assign the role of student in the course.  # Assign the role of student in the course.
     my $classlist_reply = &Apache::lonnet::modify_student_enrollment($dom,$uname,$pid,$first,$middle,$last,$gene,$usec,$end,$start,'auto','',$cid);      my $classlist_reply = 
           &Apache::lonnet::modify_student_enrollment($dom,$uname,$pid,$first,$middle,
                                                      $last,$gene,$usec,$end,$start,
                                                      'auto','',$cid,'',$context,
                                                      $credits,$instsec);
     if ($classlist_reply eq 'ok') {      if ($classlist_reply eq 'ok') {
         my $access = &showaccess($end,$start);          my $access = &showaccess($end,$start);
           my $showsec = $usec;
           if ($usec eq '') {
               $showsec = &mt('none');
           }
         if ($caller eq 'switchtype') {          if ($caller eq 'switchtype') {
             $$logmsg .= "Existing user $uname detected in institutional classlist - switched from 'manual' to 'auto' enrollment in section/group $usec.".$access.$linefeed;              $$logmsg .= &mt("Existing user [_1] detected in institutional classlist - switched from 'manual' to 'auto' enrollment in section [_2].",$uname,$showsec).$access.$linefeed;
         } elsif ($caller eq 'newstudent') {          } elsif ($caller eq 'newstudent') {
             $$enrollcount ++;              $$enrollcount ++;
             $$addresult .= "$first $last ($pid) - $uname enrolled in section/group $usec.".$access.$linefeed;              $$addresult .= "$first $last ($pid) - $uname ".&mt("enrolled in section '[_1]'.",$showsec).$access.$linefeed;
         }          }
         if ($context eq 'automated') {          if ($context eq 'automated') {
             $$logmsg .= "Existing $dom user $uname enrolled successfully.".$linefeed;              $$logmsg .= &mt('Existing [_1] user [_2] enrolled successfully.',$dom,$uname).$linefeed;
         }          }
     } else {      } else {
            $$logmsg .= "There was a problem updating the classlist db file for user $uname to show the new enrollment -error: $classlist_reply, so no enrollment occurred for this user.".$linefeed;             $$logmsg .= &mt('There was a problem updating the classlist db file for user [_1] to show the new enrollment -error: [_2], so no enrollment occurred for this user.',$uname,$classlist_reply).$linefeed;
     }      }
     return;      return;
 }  }
Line 728  sub showaccess { Line 874  sub showaccess {
     } else {      } else {
         $showend = &Apache::lonlocal::locallocaltime($end);          $showend = &Apache::lonlocal::locallocaltime($end);
     }      }
     my $access_msg = " Access starts: ".$showstart.", ends: ".$showend.".";      my $access_msg = ' '.&mt('Access starts: [_1], ends: [_2].',$showstart,$showend);
     return $access_msg;      return $access_msg;
 }  }
   
Line 737  sub parse_classlist { Line 883  sub parse_classlist {
     my $xmlfile = $tmpdir."/tmp/".$dom."_".$crs."_".$class."_classlist.xml";      my $xmlfile = $tmpdir."/tmp/".$dom."_".$crs."_".$class."_classlist.xml";
     my $uname = '';      my $uname = '';
     my @state;      my @state;
     my @items = ('autharg','authtype','email','firstname','generation','lastname','middlename','studentID');      my @items = ('autharg','authtype','email','firstname','generation','lastname','middlename','studentID','credits','inststatus');
     my $p = HTML::Parser->new      my $p = HTML::Parser->new
     (      (
         xml_mode => 1,          xml_mode => 1,
Line 747  sub parse_classlist { Line 893  sub parse_classlist {
                  push @state, $tagname;                   push @state, $tagname;
                  if ("@state" eq "students student") {                   if ("@state" eq "students student") {
                      $uname = $attr->{username};                       $uname = $attr->{username};
                        $$studentsref{$uname}[ $$placeref{'groupID'} ] = $groupID;
                        $$studentsref{$uname}[ $$placeref{'instsec'} ] = $class;
                  }                   }
             }, "tagname, attr"],              }, "tagname, attr"],
          text_h =>           text_h =>
              [sub {               [sub {
                  my ($text) = @_;                   my ($text) = @_;
                  if ("@state" eq "students student groupID") {                   if ("@state" eq "students student startdate") {
                      $$studentsref{$uname}[ $$placeref{'groupID'} ] = $groupID;  
                  } elsif ("@state" eq "students student startdate") {  
                      my $start = $text;                       my $start = $text;
                      unless ($text eq '') {                       unless ($text eq '') {
                          $start = &process_date($text);                           $start = &process_date($text);
Line 806  sub process_date { Line 952  sub process_date {
 }  }
   
 sub create_password {  sub create_password {
     my $passwd = '';      my ($udom) = @_;
     my @letts = ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");      my %passwdconf = &Apache::lonnet::get_passwdconf($udom);
     for (my $i=0; $i<8; $i++) {      my ($min,$max,@chars);
       $min = $Apache::lonnet::passwdmin;
       if (ref($passwdconf{'chars'}) eq 'ARRAY') {
           if ($passwdconf{'min'} =~ /^\d+$/) {
               if ($passwdconf{'min'} > $min) {
                   $min = $passwdconf{'min'};
               }
           }
           if ($passwdconf{'max'} =~ /^\d+$/) {
               $max = $passwdconf{'max'};
           }
           @chars = @{$passwdconf{'chars'}};
       }
       my @letts = qw(b c d f g h j k l m n p q r s t v w x y z);
       my (@included,%reqd);
       if (@chars) {
           map { $reqd{$_} = 1; } @chars;
       }
       if ($reqd{'uc'}) {
           my $letter = $letts[int( rand(21) )];   
           $letter =~ tr/a-z/A-Z/;
           if ($letter ne '') {
               push(@included,$letter); 
           }
       }
       if ($reqd{'lc'}) {
           my $letter = $letts[int( rand(21) )];
           if ($letter ne '') {
               push(@included,$letter);
           } 
       }
       if ($reqd{'num'}) {
           my $number = int( rand(10) );
           if ($number ne '') {
               push(@included,$number);
           }
       }
       if ($reqd{'spec'}) {
           my @specs = qw(! # * & _ - + $);
           my $special = $specs[int( rand(8) )];
           if ($special ne '') {
               push(@included,$special);
           }
       }
       my $start = 0;
       if (scalar(@included) > 0) {
           $start = scalar(@included);
       }
       my $end = 8;
       if ($min =~ /^\d+$/) {
           if ($min > $end) {
               $end = $min;
           } 
       }
       for (my $i=$start; $i<$end; $i++) {
         my $lettnum = int (rand 2);          my $lettnum = int (rand 2);
         my $item = '';          my $item = '';
         if ($lettnum) {          if ($lettnum) {
             $item = $letts[int( rand(26) )];              $item = $letts[int( rand(21) )];
             my $uppercase = int(rand 2);              my $uppercase = int(rand 2);
             if ($uppercase) {              if ($uppercase) {
                 $item =~ tr/a-z/A-Z/;                  $item =~ tr/a-z/A-Z/;
             }              }
         } else {          } else {
             $item = int( rand(10) );              $item = int( rand(10) );
         }           }
         $passwd .= $item;          if ($item ne '') {
               push(@included,$item);
           }
     }      }
     return ($passwd);      my $passwd = join('',&Math::Random::random_permutation(@included));
       return $passwd;
 }  }
   
 sub get_courseinfo {  sub get_courseinfo {
     my ($dom,$crs,$courseinfo) = @_;      my ($dom,$crs,$courseinfo) = @_;
     my $owner;      my $owner;
     if (defined($dom) && defined($crs)) {      if (defined($dom) && defined($crs)) {
         my %settings = &Apache::lonnet::get('environment',['internal.coursecode','internal.showphotos','description'],$dom,$crs);          my %settings = &Apache::lonnet::get('environment',['internal.coursecode','internal.showphoto','description','internal.defaultcredits'],$dom,$crs);
         if ( defined($settings{'internal.coursecode'}) ) {          if ( defined($settings{'internal.coursecode'}) ) {
             $$courseinfo{'inst_code'} = $settings{'internal.coursecode'};              $$courseinfo{'inst_code'} = $settings{'internal.coursecode'};
         }          }
         if ( defined($settings{'description'}) ) {          if ( defined($settings{'description'}) ) {
             $$courseinfo{'description'} = $settings{'description'};              $$courseinfo{'description'} = $settings{'description'};
         }          }
         if ( defined($settings{'internal.showphotos'}) ) {          if ( defined($settings{'internal.showphoto'}) ) {
             $$courseinfo{'showphotos'} = $settings{'internal.showphotos'};              $$courseinfo{'showphoto'} = $settings{'internal.showphoto'};
           }
           if ( defined($settings{'internal.credithours'}) ) {
               $$courseinfo{'defaultcredits'} = $settings{'internal.defaultcredits'};
         }          }
     }      }
     return;      return;
 }  }
   
 sub CL_autharg { return 0; }  sub place_hash {
 sub CL_authtype { return 1;}      my %place = (
 sub CL_email { return 2;}                    autharg   => 0,
 sub CL_enddate { return 3;}                    authtype  => 1,
 sub CL_firstname { return 4;}                    email     => 2,
 sub CL_generation { return 5;}                    enddate   => 3,
 sub CL_groupID { return 6;}                    firstname => 4,
 sub CL_lastname { return 7;}                    generation => 5,
 sub CL_middlename { return 8;}                    groupID    => 6,
 sub CL_startdate { return 9; }                    lastname   => 7,
 sub CL_studentID { return 10; }                    middlename => 8,
                     startdate  => 9,
                     studentID  => 10,
                     credits    => 11,
                     inststatus => 12,
                     instsec    => 13,
                   );
       return %place;
   }
   
 sub photo_response_types {  sub photo_response_types {
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash(
                       'same' => 'remained unchanged',                        'same' => 'remained unchanged',
                       'update' => 'were updated',                        'update' => 'were updated',
                       'new' => 'were added',                        'new' => 'were added',
                       'missing' => 'were missing',                        'missing' => 'were missing',
                       'error' => 'were not imported because an error occurred',                        'error' => 'were not imported because an error occurred',
                       'nouser' => 'were for users without accounts',                        'nouser' => 'were for users without accounts',
                       'noid' => 'were for users without student IDs',                        'noid' => 'were for users without student/employee IDs',
     );   );
     return %lt;      return %lt;
 }  }
   

Removed from v.1.28  
changed lines
  Added in v.1.55


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