Annotation of loncom/enrollment/Enrollment.pm, revision 1.32

1.7       albertel    1: # Automated Enrollment manager
1.32    ! albertel    2: # $Id: Enrollment.pm,v 1.31 2006/02/08 23:47:26 raeburn Exp $
1.7       albertel    3: #
                      4: # Copyright Michigan State University Board of Trustees
                      5: #
                      6: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      7: #
                      8: # LON-CAPA is free software; you can redistribute it and/or modify
                      9: # it under the terms of the GNU General Public License as published by
                     10: # the Free Software Foundation; either version 2 of the License, or
                     11: # (at your option) any later version.
                     12: #
                     13: # LON-CAPA is distributed in the hope that it will be useful,
                     14: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16: # GNU General Public License for more details.
                     17: #
                     18: # You should have received a copy of the GNU General Public License
                     19: # along with LON-CAPA; if not, write to the Free Software
                     20: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     21: #
                     22: # /home/httpd/html/adm/gpl.txt
                     23: #
                     24: # http://www.lon-capa.org/
                     25: #
1.1       raeburn    26: package LONCAPA::Enrollment;
                     27: 
                     28: use Apache::loncoursedata;
                     29: use Apache::lonnet;
1.32    ! albertel   30: use Apache::loncommon();
1.8       raeburn    31: use Apache::lonmsg;
1.28      raeburn    32: use Apache::lonlocal;
1.1       raeburn    33: use HTML::Entities;
                     34: use LONCAPA::Configuration;
1.8       raeburn    35: use Time::Local;
                     36: use lib '/home/httpd/lib/perl';
1.1       raeburn    37: 
                     38: use strict;
                     39: 
                     40: sub update_LC {
1.28      raeburn    41:     my ($dom,$crs,$adds,$drops,$startdate,$enddate,$authtype,$autharg,$classesref,$groupref,$logmsg,$newusermsg,$context,$phototypes) = @_; 
1.19      raeburn    42: # Get institutional code and title of this class
                     43:     my %courseinfo = ();
                     44:     &get_courseinfo($dom,$crs,\%courseinfo);
1.1       raeburn    45: # Get current LON-CAPA student enrollment for this class
                     46:     my $configvars = &LONCAPA::Configuration::read_conf('loncapa.conf');
                     47:     my $cid = $dom."_".$crs;
1.26      raeburn    48:     my $roster = &Apache::loncoursedata::get_classlist($dom,$crs);
1.1       raeburn    49:     my $cend = &Apache::loncoursedata::CL_END;
                     50:     my $cstart = &Apache::loncoursedata::CL_START; 
                     51:     my $stuid=&Apache::loncoursedata::CL_ID;
                     52:     my $sec=&Apache::loncoursedata::CL_SECTION;
                     53:     my $status=&Apache::loncoursedata::CL_STATUS;
                     54:     my $type=&Apache::loncoursedata::CL_TYPE;
1.16      raeburn    55:     my $lockedtype=&Apache::loncoursedata::CL_LOCKEDTYPE;
1.1       raeburn    56:     my @localstudents = ();
1.15      raeburn    57:     my @futurestudents = ();
                     58:     my @activestudents = ();
1.18      raeburn    59:     my @excludedstudents = ();
1.1       raeburn    60:     my $currlist;
                     61:     foreach my $uname (keys %{$roster} ) {
                     62:         if ($uname =~ m/^(.+):$dom$/) {
                     63:             if ($$roster{$uname}[$status] eq "Active") {
1.15      raeburn    64:                 push @activestudents, $1;
                     65:                 @{$$currlist{$1}} = @{$$roster{$uname}};
1.1       raeburn    66:                 push @localstudents, $1;
1.15      raeburn    67:             } elsif ( ($$roster{$uname}[$cstart] > time)  && ($$roster{$uname}[$cend] > time || $$roster{$uname}[$cend] == 0 || $$roster{$uname}[$cend] eq '') ) {
                     68:                 push @futurestudents, $1;
1.1       raeburn    69:                 @{$$currlist{$1}} = @{$$roster{$uname}};
1.15      raeburn    70:                 push @localstudents, $1;
1.18      raeburn    71:             } elsif ($$roster{$uname}[$lockedtype] == 1) {
                     72:                 push @excludedstudents, $1;
1.1       raeburn    73:             }
                     74:         }
                     75:     }
                     76:     my $linefeed = '';
                     77:     my $addresult = '';
                     78:     my $dropresult = '';
1.21      raeburn    79:     my $switchresult = '';
1.28      raeburn    80:     my $photoresult = '';
1.1       raeburn    81:     if ($context eq "updatenow") {
                     82:         $linefeed = "</li>\n<li>"; 
                     83:     } elsif ($context eq "automated") {
                     84:         $linefeed = "\n";
                     85:     }
                     86:     my $enrollcount = 0;
                     87:     my $dropcount = 0;
1.21      raeburn    88:     my $switchcount = 0;
1.1       raeburn    89: 
1.19      raeburn    90: # Get role names
                     91:     my %longroles = ();
                     92:     open(FILE,"<$$configvars{'lonTabDir'}.'/rolesplain.tab");
                     93:     my @rolesplain = <FILE>;
                     94:     close(FILE);
                     95:     foreach (@rolesplain) {
                     96:         if ($_ =~ /^(st|ta|ex|ad|in|cc):([\w\s]+)$/) {
                     97:             $longroles{$1} = $2;
                     98:         }
                     99:     }
                    100: 
1.8       raeburn   101:     srand( time() ^ ($$ + ($$ << 15))  ); # Seed rand in case initial passwords have to be generated for new users.
                    102: 
1.1       raeburn   103: # Get mapping of IDs to usernames for current LON-CAPA student enrollment for this class 
                    104:     my @LCids = ();
                    105:     my %unameFromLCid = ();
                    106:     foreach my $uname (sort keys %{$currlist}) {
                    107:         my $stuID = $$currlist{$uname}[$stuid];
                    108:         if (!grep/^$stuID$/,@LCids) {
                    109:             push @LCids, $stuID;
                    110:             @{$unameFromLCid{$stuID}} = ();
                    111:         }
                    112:         push @{$unameFromLCid{$stuID}},$uname;
                    113:     }
                    114:  
                    115: # Get latest institutional enrollment for this class.
                    116:     my %allenrolled = ();
                    117:     my @reg_students = ();
                    118:     my %place = ();
                    119:     $place{'autharg'} = &CL_autharg();
                    120:     $place{'authtype'} = &CL_authtype();
                    121:     $place{'email'} = &CL_email();
                    122:     $place{'enddate'} = &CL_enddate();
                    123:     $place{'firstname'} = &CL_firstname();
                    124:     $place{'generation'} = &CL_generation();
                    125:     $place{'groupID'} = &CL_groupID();
                    126:     $place{'lastname'} = &CL_lastname();
                    127:     $place{'middlename'} = &CL_middlename();
                    128:     $place{'startdate'} = &CL_startdate();
                    129:     $place{'studentID'} = &CL_studentID();
                    130:     my %ucount = ();
                    131:     my %enrollinfo = ();
                    132:     foreach my $class (@{$classesref}) {
                    133:         my %enrolled = ();
                    134:         &parse_classlist($$configvars{'lonDaemons'},$dom,$crs,$class,\%place,$$groupref{$class},\%enrolled);
                    135:         foreach my $uname (sort keys %enrolled ) {
                    136:             if (!grep/^$uname$/,@reg_students) {
                    137:                 push @reg_students,$uname;
                    138:                 $ucount{$uname} = 0;
                    139:                 @{$allenrolled{$uname}} = ();
                    140:             }
                    141:             @{$allenrolled{$uname}[$ucount{$uname}]} = @{$enrolled{$uname}};
                    142:             $ucount{$uname} ++;
                    143:         }
                    144:     }
                    145: 
                    146: # Check for multiple sections for a single student 
                    147:     my @okusers = ();
                    148:     foreach my $uname (@reg_students)  {
1.18      raeburn   149:         if (grep/^$uname$/,@excludedstudents) {
                    150:             $$logmsg .= "No re-enrollment for $uname - user was previously manually unenrolled and locked.".$linefeed;
                    151:         } elsif (@{$allenrolled{$uname}} > 1) {
1.1       raeburn   152:             my @sections = ();
                    153:             my $saved;
                    154:             for (my $i=0; $i<@{$allenrolled{$uname}}; $i++) {
                    155:                 my @stuinfo = @{$allenrolled{$uname}[$i]};
                    156:                 my $secnum = $stuinfo[ $place{'groupID'} ];
                    157:                 unless ($secnum eq '') {
                    158:                     unless (grep/^$secnum$/,@sections) {
                    159:                         $saved = $i; 
                    160:                         push @sections,$secnum;
                    161:                     }
                    162:                 }
                    163:             }
                    164:             if (@sections == 0) {
                    165:                 @{$enrollinfo{$uname}} = @{$allenrolled{$uname}[0]};
                    166:                 push @okusers, $uname;
                    167:             }
                    168:             elsif (@sections == 1) {
                    169:                 @{$enrollinfo{$uname}} = @{$allenrolled{$uname}[$saved]};
                    170:                 push @okusers, $uname;
                    171:             }
                    172:             elsif (@sections > 1) {
1.27      raeburn   173:                 $$logmsg .=  "$uname appears in classlists for more than one section of this course, i.e. in sections: ";
1.1       raeburn   174:                 foreach (@sections) {
1.5       raeburn   175:                     $$logmsg .= " $_,";
1.1       raeburn   176:                 }
1.5       raeburn   177:                 chop($$logmsg);
1.6       raeburn   178:                 $$logmsg .= ". Because of this ambiguity, no enrollment action was taken for this student.".$linefeed;
1.1       raeburn   179:             }
                    180:         } else {
                    181:             @{$enrollinfo{$uname}} = @{$allenrolled{$uname}[0]};
                    182:             push @okusers, $uname;
                    183:         }
                    184:     }
                    185: # Get mapping of student IDs to usernames for users in institutional data for this class  
                    186:     my @allINids = ();
1.3       raeburn   187:     my %unameFromINid = ();
1.1       raeburn   188:     foreach my $uname (@okusers) {
                    189:         $enrollinfo{$uname}[ $place{'studentID'} ] =~ tr/A-Z/a-z/;
                    190:         my $stuID = $enrollinfo{$uname}[ $place{'studentID'} ];
                    191:         if (grep/^$stuID$/,@allINids)  {
                    192:             push @{$unameFromINid{$stuID}},$uname;
                    193:         } else {
                    194:             push @allINids, $stuID;
                    195:             @{$unameFromINid{$stuID}} = $uname; 
                    196:         }
                    197:     }
1.28      raeburn   198: 
1.5       raeburn   199: # Explicitly allow access to creation/modification of students if called as an automated process.
                    200:     if ($context eq 'automated') {
1.22      albertel  201:         $env{'allowed.cst'}='F';
1.5       raeburn   202:     }
                    203: 
1.1       raeburn   204: # Compare IDs with existing LON-CAPA enrollment for this class
                    205:     foreach my $uname (@okusers) {
1.5       raeburn   206:         unless ($uname eq '') {
                    207:             my %uidhash=&Apache::lonnet::idrget($dom,$uname);
                    208:             my @stuinfo = @{$enrollinfo{$uname}};
1.15      raeburn   209:             my $access = '';
1.5       raeburn   210:             if (grep/^$uname$/,@localstudents) {
1.1       raeburn   211: # Check for studentID changes
1.5       raeburn   212:                 if ( ($uidhash{$uname}) && ($uidhash{$uname} !~ /error\:/) )  {
                    213:                     unless ( ($uidhash{$uname}) eq ($stuinfo[ $place{studentID} ]) ) {
1.6       raeburn   214:                         $$logmsg .= "Change in ID for $uname. StudentID in LON-CAPA system is $uidhash{$uname}; StudentID in institutional data is $stuinfo[ $place{studentID} ]".$linefeed; 
1.5       raeburn   215:                     }
1.1       raeburn   216:                 }
1.16      raeburn   217: # Check for switch from manual to auto
                    218:                 unless (($$currlist{$uname}[$type] eq "auto") || ($$currlist{$uname}[$lockedtype] eq "1") || (!$adds) ) {
                    219: # drop manually added student
                    220:                     my $drop_reply = &Apache::lonnet::modifystudent($dom,$uname,'','','',undef,undef,undef,undef,$$currlist{$uname}[$sec],time,undef,undef,undef,undef,'auto','',$cid);
                    221: # re-enroll as auto student
                    222:                     if ($drop_reply !~ /^ok/) {
                    223:                             $$logmsg .= "An error occured during the attempt to convert $uname from a manual type to an auto type student - $drop_reply.".$linefeed;
                    224:                     } else {
                    225: # re-enroll as auto student
                    226:                         my ($auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,$emailaddr,$pid,$emailenc);
                    227:                         &prepare_add($authtype,$autharg,$enddate,$startdate,\@stuinfo,\%place,\$dom,\$uname,\$auth,\$authparam,\$first,\$middle,\$last,\$gene,\$usec,\$end,\$start,\$emailaddr,\$pid,\$emailenc);
                    228:                         if ($$currlist{$uname}[$sec] ne $usec) {
1.21      raeburn   229:                             $switchresult .= "Section for $uname switched from $$currlist{$uname}[$sec] to ".$usec.$linefeed;
                    230:                             if ($context eq 'automated') {
                    231:                                 $$logmsg .= "Section switch for $uname from $$currlist{$uname}[$sec] to ".$usec.$linefeed; ;
                    232:                             }
                    233:                             $switchcount ++;
1.16      raeburn   234:                         }
                    235:                         &execute_add($context,'switchtype',$uname,$dom,$auth,$authparam,$first,$middle,$last,$gene,$pid,$usec,$end,$start,$emailenc,$cid,\$addresult,\$enrollcount,$linefeed,$logmsg);
                    236:                     }
                    237:                 } 
1.1       raeburn   238: # Check for section changes
1.15      raeburn   239:                 if ($$currlist{$uname}[$sec] eq $stuinfo[ $place{groupID} ]) {
                    240: # Check for access date changes for students with access starting in the future.
                    241:                     if ( (grep/^$uname$/,@futurestudents) && ($$currlist{$uname}[$type] eq "auto") && ($adds == 1) ) {
1.16      raeburn   242:                         my $datechange = &datechange_check($$currlist{$uname}[$cstart],$$currlist{$uname}[$cend],$startdate,$enddate);
1.15      raeburn   243:                         if ($datechange) {
1.16      raeburn   244:                             my $modify_access_result = &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid);
1.15      raeburn   245:                             $access = &showaccess($enddate,$startdate);
                    246:                             if ($modify_access_result =~ /^ok/) {
                    247:                                 $$logmsg .= "Change in access dates for $uname.".$access.$linefeed;
                    248:                             } else {
                    249:                                 $$logmsg .= "Error when attempting to change start and/or end access dates for $uname in section: ".$stuinfo[ $place{groupID} ]." -error $modify_access_result".$linefeed;
                    250:                             }
                    251:                         }
                    252:                     }
                    253:                 } else {
1.5       raeburn   254:                     if ( ($$currlist{$uname}[$type] eq "auto") && ($adds == 1) ) {
1.10      raeburn   255: # Delete from roles.db for current section
                    256:                         my $expiretime = time;
                    257:                         my $uurl='/'.$cid;
                    258:                         $uurl=~s/\_/\//g;
                    259:                         if ($$currlist{$uname}[$sec]) {
                    260:                             $uurl.='/'.$$currlist{$uname}[$sec];
                    261:                         }
                    262:                         my $expire_role_result = &Apache::lonnet::assignrole($dom,$uname,$uurl,'st',$expiretime);
                    263:                         if ($expire_role_result eq 'ok') {
1.15      raeburn   264:                             my $modify_section_result;
                    265:                             if (grep/^$uname$/,@activestudents) {
1.16      raeburn   266:                                 $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);
1.15      raeburn   267:                             } else {
1.16      raeburn   268:                                 $modify_section_result =  &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid);
1.15      raeburn   269:                                 $access =  &showaccess($enddate,$startdate);
                    270:                             }
1.10      raeburn   271:                             if ($modify_section_result =~ /^ok/) {
1.21      raeburn   272:                                 $switchresult .= "Section for $uname switched from old section: ".$$currlist{$uname}[$sec] ." to new section: ".$stuinfo[ $place{groupID} ].".".$access.$linefeed;
                    273:                                 if ($context eq 'automated') {
                    274:                                     $$logmsg .= "Section switch for $uname from $$currlist{$uname}[$sec] to $stuinfo[ $place{groupID} ]".$linefeed;
                    275:                                 }
                    276:                                 $switchcount ++;
1.10      raeburn   277:                             } else {
                    278:                                 $$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;
                    279:                             }
1.5       raeburn   280:                         } else {
1.10      raeburn   281:                             $$logmsg .= "Error when attempting to expire role for $uname in old section" .$$currlist{$uname}[$sec]." -error: $expire_role_result".$linefeed;
1.5       raeburn   282:                         }
1.1       raeburn   283:                     }
                    284:                 }
1.5       raeburn   285:             } else {
1.1       raeburn   286: # Check for changed usernames by checking studentIDs
1.5       raeburn   287:                 if ( ($stuinfo[ $place{studentID} ] ne '') && (grep/^$stuinfo[ $place{studentID} ]$/,@LCids) ) {
1.27      raeburn   288:                     foreach my $match ( @{ $unameFromLCid{ $stuinfo[ $place{studentID} ] } }  ) {
                    289:                         $$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} ].". ";
                    290:                         if (grep/^$match$/,@okusers) {
                    291:                             $$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. ";
                    292:                         } else {
                    293:                             unless ($drops == 1) {
                    294:                                 $$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. ";
1.5       raeburn   295:                             }
1.1       raeburn   296:                         }
1.27      raeburn   297:                         $$logmsg .= "Because of this student ID conflict, the new username - $uname - has not been added to the LON-CAPA classlist.".$linefeed;      
1.1       raeburn   298:                     }
1.5       raeburn   299:                 } elsif ($adds == 1) {
1.16      raeburn   300:                     my ($auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,$emailaddr,$pid,$emailenc);
                    301:                     &prepare_add($authtype,$autharg,$enddate,$startdate,\@stuinfo,\%place,\$dom,\$uname,\$auth,\$authparam,\$first,\$middle,\$last,\$gene,\$usec,\$end,\$start,\$emailaddr,\$pid,\$emailenc);
1.1       raeburn   302: # Check for existing account in this LON-CAPA domain for this username
1.5       raeburn   303:                     my $uhome=&Apache::lonnet::homeserver($uname,$dom);
                    304:                     if ($uhome eq 'no_host') { # User does not exist
1.19      raeburn   305:                         my $args = {'auth' => $auth,
                    306:                                     'authparam' => $authparam,
                    307:                                     'emailenc' => $emailenc,
                    308:                                     'udom' => $dom,
                    309:                                     'uname' => $uname,
                    310:                                     'pid' => $pid,
                    311:                                     'first' => $first,
                    312:                                     'middle' => $middle,
                    313:                                     'last' => $last,
                    314:                                     'gene' => $gene,
                    315:                                     'usec' => $usec,
                    316:                                     'end' => $end,
                    317:                                     'start' => $start,
                    318:                                     'emailaddr' => $emailaddr,
                    319:                                     'cid' => $cid,
                    320:                                     'crs' => $crs,
                    321:                                     'cdom' => $dom,
                    322:                                     'context' => $context,
                    323:                                     'linefeed' => $linefeed,
                    324:                                     'role' => 'st'
                    325:                                    };
1.20      raeburn   326:                         my $outcome = &create_newuser($args,$logmsg,$newusermsg,\$enrollcount,\$addresult,\%longroles,\%courseinfo);
1.5       raeburn   327:                     } else {
1.16      raeburn   328:                         &execute_add($context,'newstudent',$uname,$dom,$auth,$authparam,$first,$middle,$last,$gene,$pid,$usec,$end,$start,$emailenc,$cid,\$addresult,\$enrollcount,$linefeed,$logmsg);
1.3       raeburn   329:                     }
1.31      raeburn   330:                     if ($courseinfo{'showphoto'}) {
1.28      raeburn   331:                         my ($result,$resulttype) = 
                    332:                            &Apache::lonnet::auto_checkphotos($uname,$dom,$pid);
                    333:                         if ($resulttype) {
                    334:                             push(@{$$phototypes{$resulttype}},$uname);
                    335:                         }
                    336:                     }
1.1       raeburn   337:                 }
                    338:             }
                    339:         }
                    340:     }
1.31      raeburn   341:     if ($courseinfo{'showphoto'}) {
1.28      raeburn   342:         if (keys(%{$phototypes})>0) {
                    343:             my %lt = &photo_response_types();
                    344:             foreach my $type (sort(keys(%{$phototypes}))) {
                    345:                 my $numphoto = @{$$phototypes{$type}};
                    346:                 if ($numphoto > 0) {
                    347:                     if ($context eq 'updatenow') {
                    348:                         $photoresult .=  '<br /><b>'.
1.29      albertel  349: 			    &mt('For [_1] students, photos ',$numphoto).
                    350: 			    $lt{$type}.'</b><ul><li>';
1.28      raeburn   351:                     } else {
                    352:                         $photoresult .=  "\nFor $numphoto students, photos ".
1.29      albertel  353: 			    $lt{$type}."\n";
1.28      raeburn   354:                     }
                    355:                     foreach my $user (@{$$phototypes{$type}}) { 
                    356:                         $photoresult .= $user.$linefeed;
                    357:                     }
                    358:                     if ($context eq 'updatenow') {
                    359:                         $photoresult = substr($photoresult,0,
1.29      albertel  360: 					      rindex($photoresult,"<li>"));
1.28      raeburn   361:                         $photoresult .= '</ul><br />';
                    362:                     } else {
                    363:                         $photoresult .= "\n";
                    364:                     }
                    365:                 }
                    366:             }
                    367:         }
                    368:     }
                    369: 
1.1       raeburn   370: # Do drops
                    371:     if ( ($drops == 1) && (@reg_students > 0) ) {
                    372:         foreach my $uname (@localstudents) {
                    373:             if ($$currlist{$uname}[$type] eq "auto") {
                    374:                 my @saved = ();
                    375:                 if (!grep/^$uname$/,@reg_students) {
                    376: # Check for changed usernames by checking studentIDs
                    377:                     if (grep/^$$currlist{$uname}[ $stuid ]$/,@allINids) {
                    378:                         foreach my $match (@{$unameFromINid{$$currlist{$uname}[ $stuid ]}} ) {
1.27      raeburn   379:                             $$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;
1.1       raeburn   380:                             push @saved,$uname;
                    381:                         }
                    382:                     } elsif (@saved == 0) {
1.16      raeburn   383:                         my $drop_reply = &Apache::lonnet::modifystudent($dom,$uname,'','','',undef,undef,undef,undef,$$currlist{$uname}[$sec],time,undef,undef,undef,undef,'auto','',$cid);
1.1       raeburn   384:                         if ($drop_reply !~ /^ok/) {
1.5       raeburn   385:                             $$logmsg .= "An error occured during the attempt to expire the $uname from the old section $$currlist{$uname}[$sec] - $drop_reply.".$linefeed;
1.1       raeburn   386:                         } else {
                    387:                             $dropcount ++;
                    388:                             my %userenv = &Apache::lonnet::get('environment',['firstname','lastname','id'],$dom,$uname);
                    389:                             $dropresult .= $userenv{'firstname'}." ".$userenv{'lastname'}." (".$userenv{'id'}.") - ".$uname." dropped from section/group ".$$currlist{$uname}[$sec].$linefeed; 
1.8       raeburn   390:                             if ($context eq 'automated') {
                    391:                                 $$logmsg .= "User $uname student role expired from course.".$linefeed;
                    392:                             }
1.1       raeburn   393:                         }
                    394:                     }
                    395:                 }
                    396:             }
                    397:         }
                    398:     }
1.5       raeburn   399: 
                    400: # Terminated explictly allowed access to student creation/modification
                    401:     if ($context eq 'automated') {
1.22      albertel  402:         delete($env{'allowed.cst'});
1.5       raeburn   403:     }
1.1       raeburn   404:     if ($enrollcount > 0) {
                    405:         if ($context eq "updatenow") {
1.6       raeburn   406:             $addresult = substr($addresult,0,rindex($addresult,"<li>"));
1.21      raeburn   407:             $addresult = "The following $enrollcount student(s) was/were added to this LON-CAPA course:<br/><ul><li>".$addresult."</ul><br/><br/>";
1.1       raeburn   408:         } else {
1.21      raeburn   409:             $addresult = "The following $enrollcount student(s) was/were added to this LON-CAPA course:\n\n".$addresult."\n\n";
                    410:         }
1.1       raeburn   411:     }
                    412:     if ($dropcount > 0) {
                    413:         if ($context eq "updatenow") {
1.6       raeburn   414:             $dropresult = substr($dropresult,0,rindex($dropresult,"<li>"));
1.21      raeburn   415:             $dropresult = "The following $dropcount student(s) was/were expired from this LON-CAPA course:<br/><ul><li>".$dropresult."</ul><br/><br/>";
1.1       raeburn   416:         } else {
                    417:             $dropresult = "The following $dropcount student(s) was/were expired from this LON-CAPA course:\n\n".$dropresult."\n\n";
                    418:         }
                    419:     }
1.21      raeburn   420:     if ($switchcount > 0) {
                    421:         if ($context eq "updatenow") {
                    422:             $switchresult = substr($switchresult,0,rindex($switchresult,"<li>"));
                    423:             $switchresult = "The following $switchcount student(s) switched sections in this LON-CAPA course:<br/><ul><li>".$switchresult."</ul><br/><br/>";
                    424:         } else {
                    425:             $switchresult = "The following $switchcount student(s) switched sections in this LON-CAPA course:\n\n".$switchresult."\n\n";
                    426:         }
                    427:     }
1.1       raeburn   428:     if ( ($adds) && ($enrollcount == 0) ) {
                    429:         $addresult = "There were no new students to add to the course.";
                    430:         if ($context eq "updatenow") {
                    431:             $addresult .="<br/><br/>";
                    432:         } else {
                    433:             $addresult .="\n";
                    434:         }
                    435:     }
                    436:     if ( ($drops) && ($dropcount == 0) ) {
                    437:         $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.";
                    438:         if ($context eq "updatenow") {
                    439:             $dropresult .="<br/>";
                    440:         } else {
                    441:             $dropresult .="\n";
                    442:         }
                    443:     }
1.21      raeburn   444:     my $changecount = $enrollcount + $dropcount + $switchcount;
1.28      raeburn   445:     return ($changecount,$addresult.$photoresult.$dropresult.$switchresult);
1.6       raeburn   446: }
1.1       raeburn   447: 
1.19      raeburn   448: sub create_newuser {
                    449:     my ($args,$logmsg,$newusermsg,$enrollcount,$addresult,$longroles,$courseinfo) = @_;
                    450:     my $auth = $args->{'auth'};
                    451:     my $authparam = $args->{'authparam'};
                    452:     my $emailenc = $args->{'emailenc'};
                    453:     my $udom = $args->{'udom'};
                    454:     my $uname = $args->{'uname'};
                    455:     my $pid = $args->{'pid'};
                    456:     my $first = $args->{'first'};
                    457:     my $middle = $args->{'middle'};
                    458:     my $last = $args->{'last'} ;
                    459:     my $gene = $args->{'gene'};
                    460:     my $usec = $args->{'usec'};
                    461:     my $end = $args->{'end'};
                    462:     my $start = $args->{'start'};
                    463:     my $emailaddr = $args->{'emailaddr'};
                    464:     my $cid = $args->{'cid'};
                    465:     my $crs = $args->{'crs'};
                    466:     my $cdom = $args->{'cdom'};
                    467:     my $context = $args->{'context'};
                    468:     my $linefeed = $args->{'linefeed'};
                    469:     my $role = $args->{'role'};
                    470:     my $create_passwd = 0;
                    471:     my $authchk = '';
                    472:     my $outcome;
                    473:     unless ($authparam eq '') { $authchk = 'ok'; };
                    474: # If no account exists and passwords should be generated
                    475:     if ($auth eq "internal") {
                    476:         if ($authparam eq '') {
                    477:             $authparam = &create_password();
                    478:             if ($authparam eq '') {
                    479:                 $authchk = '';
                    480:             } else {
                    481:                 $create_passwd = 1;
                    482:                 $authchk = 'ok';
                    483:             }
                    484:         }
                    485:     } elsif ($auth eq "localauth") {
                    486:         ($authparam,$create_passwd,$authchk) = &Apache::lonnet::auto_create_password($crs,$cdom,$authparam);
                    487:     } elsif ($auth =~ m/^krb/) {
                    488:         if ($authparam eq '') {
                    489:             $$logmsg .= "No Kerberos domain was provided for the new user - $uname, so the new user was not enrolled in the course.".$linefeed;
                    490:             $authchk = 'invalid';
                    491:         }
                    492:     } else {
                    493:         $authchk = 'invalid';
                    494:         $$logmsg .= "An invalid authentication type was provided for the new user - $uname, so the user was not enrolled in the course.".$linefeed;
                    495:     }   
                    496:     if ($authchk eq 'ok') {
                    497: # Now create user.
                    498:         my $type = 'auto';
                    499:         my $userurl = '/'.$cdom.'/'.$crs;
                    500:         if ($usec ne '') {
                    501:             $userurl .= '/'.$usec;
                    502:         }
                    503:         if ($context eq 'createowner' || $context eq 'createcourse') {
                    504:             my $result = &Apache::lonnet::modifyuser($udom,$uname,$pid,$auth,$authparam,$first,$middle,$last,$gene,'1',undef,$emailaddr);
                    505:             if ($result eq 'ok' && $context eq 'createcourse') {
1.32    ! albertel  506:                 $outcome = &Apache::loncommon::commit_standardrole($udom,$uname,$userurl,$role,$start,$end,$cdom,$crs,$usec);
1.19      raeburn   507:                 unless ($outcome =~ /^Error:/) {
                    508:                     $outcome = 'ok';
                    509:                 }
                    510:             } else {
                    511:                 $outcome = $result;
                    512:             }
                    513:         } else {
                    514:             $outcome=&Apache::lonnet::modifystudent($udom,$uname,$pid,$auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,'',undef,$emailaddr,'auto','',$cid);
                    515:         }
                    516:         if ($outcome eq 'ok') {
                    517:             my $access = &showaccess($end,$start);
                    518:             $$addresult .= "$first $last ($pid) - $uname enrolled in section/group $usec.".$access.$linefeed;
                    519:             unless ($context eq 'createowner' || $context eq 'createcourse') {
                    520:                 $$enrollcount ++;
                    521:             }
                    522:             if ($context eq 'automated') {
                    523:                 $$logmsg .= "New $udom user $uname added successfully.";
                    524:             }
                    525:             unless ($emailenc eq '' || $context eq 'createowner' || $context eq 'createcourse') {
                    526:                 my %emailHash;
                    527:                 $emailHash{'critnotification'}  = $emailenc;
                    528:                 $emailHash{'notification'} = $emailenc;
1.23      raeburn   529:                 $emailHash{'permanentemail'} = $emailenc;
1.19      raeburn   530:                 my $putresult = &Apache::lonnet::put('environment',\%emailHash,$udom,$uname);
                    531:             }
                    532:             if ($create_passwd) {
                    533: # Send e-mail with initial password to new user at $emailaddr.
                    534: # If e-mail address is invalid, send password via message to courseowner i
                    535: # (if automated call) or to user if roster update.
                    536:                 if ($emailaddr eq '') {
                    537:                     $$newusermsg .= " username: $uname, password: ".$authparam.$linefeed."\n";
                    538:                 } else {
                    539:                     my $subject = "New LON-CAPA account";
                    540:                     my $body;
                    541:                     if ($context eq 'createowner') {
                    542:                         $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";
                    543:                     } elsif ($context eq 'createcourse') {
                    544:                         $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"; 
                    545:                     } else {
                    546:                         my $access_start = 'immediately';
                    547:                         if ($start > 0) {
                    548:                             $access_start = localtime($start)
                    549:                         }
                    550:                         $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";
                    551:                     }
                    552:                     &Apache::lonmsg::sendemail($emailaddr,$subject,$body);
                    553:                 }
                    554:                 if ($context eq 'automated') {
                    555:                     $$logmsg .= " Initial password -  - sent to ".$emailaddr.$linefeed;
                    556:                 }
                    557:             } else {
                    558:                 if ($context eq 'automated') {
                    559:                     $$logmsg .= $linefeed;
                    560:                 }
                    561:             }
                    562:         } else {
                    563:             $$logmsg .= "An error occurred adding new user $uname - ".$outcome.$linefeed;
                    564:         }
                    565:     }
                    566:     return $outcome;
                    567: }
                    568: 
1.16      raeburn   569: sub prepare_add {
                    570:     my ($authtype,$autharg,$enddate,$startdate,$stuinfo,$place,$dom,$uname,$auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,$emailaddr,$pid,$emailenc) = @_;
                    571:     $$auth = $$stuinfo[ $$place{'authtype'} ];
                    572:     $$authparam = $$stuinfo[ $$place{'autharg'} ];
                    573:     $$first = $$stuinfo[ $$place{'firstname'} ];
                    574:     $$middle = $$stuinfo[ $$place{'middlename'} ];
                    575:     $$last = $$stuinfo[ $$place{'lastname'} ];
                    576:     $$gene = $$stuinfo[ $$place{'generation'} ];
                    577:     $$usec = $$stuinfo[ $$place{'groupID'} ];
                    578:     $$end = $$stuinfo[ $$place{'enddate'} ];
                    579:     $$start = $$stuinfo[ $$place{'startdate'} ];
                    580:     $$emailaddr = $$stuinfo[ $$place{'email'} ];
                    581:     $$pid = $$stuinfo[ $$place{'studentID'} ];
                    582:                                                                                   
                    583: # remove non alphanumeric values from section
                    584:     $$usec =~ s/\W//g;
                    585:                                                                                   
                    586:     unless ($$emailaddr =~/^[^\@]+\@[^\@]+$/) { $$emailaddr =''; }
                    587:     $$emailenc = &HTML::Entities::encode($$emailaddr,'<>&"');
                    588:                                                                                   
                    589: # Use course defaults where entry is absent
                    590:     if ( ($$auth eq '') || (!defined($$auth)) ) {
                    591:         $$auth =  $authtype;
                    592:     }
                    593:     if ( ($$authparam eq '')  || (!defined($$authparam)) )  {
                    594:         $$authparam = $autharg;
                    595:     }
                    596:     if ( ($$end eq '') || (!defined($$end)) )  {
                    597:         $$end = $enddate;
                    598:     }
                    599:     if ( ($$start eq '')  || (!defined($$start)) )  {
                    600:         $$start = $startdate;
                    601:     }
                    602: # Clean up whitespace
                    603:     foreach ($dom,$uname,$pid,$first,$middle,$last,$gene,$usec) {
                    604:         $$_ =~ s/(\s+$|^\s+)//g;
                    605:     }
                    606:     return;
                    607: }
                    608: 
                    609: sub execute_add {
                    610:     my ($context,$caller,$uname,$dom,$auth,$authparam,$first,$middle,$last,$gene,$pid,$usec,$end,$start,$emailenc,$cid,$addresult,$enrollcount,$linefeed,$logmsg) = @_;
                    611: # Get the user's information and authentication
1.23      raeburn   612:     my %userenv = &Apache::lonnet::get('environment',['firstname','middlename','lastname','generation','id','critnotification','notification','permanentemail'],$dom,$uname);
1.16      raeburn   613:     my ($tmp) = keys(%userenv);
                    614:     if ($tmp =~ /^(con_lost|error)/i) {
                    615:         %userenv = ();
                    616:     }
                    617: # Get the user's e-mail address
                    618:     if ($userenv{critnotification} =~ m/%40/) {
                    619:         unless ($emailenc eq $userenv{critnotification}) {
                    620:             $$logmsg .= "Current critical notification e-mail
                    621: - ".$userenv{critnotification}." for $uname is different to e-mail address in institutional classlist - ".$emailenc.$linefeed;
                    622:         }
                    623:     }
                    624:     if ($userenv{notification} =~ m/%40/) {
1.23      raeburn   625:         unless ($emailenc eq $userenv{notification}) {
1.16      raeburn   626:             $$logmsg .= "Current standard notification e-mail
                    627: - ".$userenv{notification}." for $uname is different to e-mail address in institutional classlist - ".$emailenc.$linefeed;
                    628:         }
                    629:     }
1.23      raeburn   630:     if ($userenv{permanentemail} =~ m/%40/) {
                    631:         unless ($emailenc eq $userenv{permanentemail}) {
                    632:             $$logmsg .= "Current permanent e-mail
                    633: - ".$userenv{permanentemail}." for $uname is different to e-mail address in institutional classlist - ".$emailenc.$linefeed;
                    634:         }
                    635:     }
1.16      raeburn   636:     my $krbdefdom = '';
                    637:     my $currentauth=&Apache::lonnet::queryauthenticate($uname,$dom);
                    638:     if ($currentauth=~/^(krb[45]):(.*)/) {
                    639:         $currentauth = $1;
                    640:         $krbdefdom = $2;
                    641:     } elsif ($currentauth=~ /^(unix|internal|localauth):/) {
                    642:         $currentauth = $1;
                    643:     } else {
                    644:         $$logmsg .= "Invalid authentication method $currentauth for $uname.".$linefeed;
                    645:     }
                    646: # Report if authentication methods are different.
                    647:     if ($currentauth ne $auth) {
                    648:         $$logmsg .= "Authentication type mismatch for $uname - '$currentauth' in system, '$auth' based on information in classlist or default for this course.".$linefeed;
                    649:     } elsif ($auth =~ m/^krb/) {
                    650:         if ($krbdefdom ne $authparam) {
                    651:             $$logmsg .= "Kerberos domain mismatch for $uname - '$krbdefdom' in system, '$authparam' based on information in classlist or default for this course.".$linefeed;
                    652:         }
                    653:     }
                    654:                                                                                   
                    655: # Check user data
                    656:     if ($first  ne $userenv{'firstname'}  ||
                    657:         $middle ne $userenv{'middlename'} ||
                    658:         $last   ne $userenv{'lastname'}   ||
                    659:         $gene   ne $userenv{'generation'} ||
1.23      raeburn   660:         $pid    ne $userenv{'id'} ||
                    661:         $emailenc ne $userenv{'permanentemail'} ) {
1.16      raeburn   662: # Make the change(s)
                    663:         my %changeHash;
                    664:         $changeHash{'firstname'}  = $first;
                    665:         $changeHash{'middlename'} = $middle;
                    666:         $changeHash{'lastname'}   = $last;
                    667:         $changeHash{'generation'} = $gene;
                    668:         $changeHash{'id'} = $pid;
1.23      raeburn   669:         $changeHash{'permanentemail'} = $emailenc;
1.16      raeburn   670:         my $putresult = &Apache::lonnet::put('environment',\%changeHash,$dom,$uname);
                    671:         if ($putresult eq 'ok') {
                    672:             $$logmsg .= "User information updated for user: $uname prior to enrollment.".$linefeed;
                    673:         } else {
                    674:             $$logmsg .= "There was a problem modifying user data for existing user - $uname -error: $putresult, enrollment will still be attempted.".$linefeed;
                    675:         }
                    676:     }
                    677:                                                                                   
                    678: # Assign the role of student in the course.
                    679:     my $classlist_reply = &Apache::lonnet::modify_student_enrollment($dom,$uname,$pid,$first,$middle,$last,$gene,$usec,$end,$start,'auto','',$cid);
                    680:     if ($classlist_reply eq 'ok') {
                    681:         my $access = &showaccess($end,$start);
                    682:         if ($caller eq 'switchtype') {
                    683:             $$logmsg .= "Existing user $uname detected in institutional classlist - switched from 'manual' to 'auto' enrollment in section/group $usec.".$access.$linefeed;
                    684:         } elsif ($caller eq 'newstudent') {
                    685:             $$enrollcount ++;
                    686:             $$addresult .= "$first $last ($pid) - $uname enrolled in section/group $usec.".$access.$linefeed;
                    687:         }
                    688:         if ($context eq 'automated') {
                    689:             $$logmsg .= "Existing $dom user $uname enrolled successfully.".$linefeed;
                    690:         }
                    691:     } else {
                    692:            $$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;
                    693:     }
                    694:     return;
                    695: }
                    696: 
                    697: sub datechange_check {
                    698:     my ($oldstart,$oldend,$startdate,$enddate) = @_;
                    699:     my $datechange = 0;
                    700:     unless ($oldstart eq $startdate) {
                    701:         $datechange = 1;
                    702:     }
                    703:     if (!$datechange) {
                    704:         if (!$oldend) {
                    705:             if ($enddate) {
                    706:                 $datechange = 1;
                    707:             }
                    708:         } elsif ($oldend ne $enddate) {
                    709:             $datechange = 1;
                    710:         }
                    711:     }
                    712:     return $datechange;
                    713: }
                    714: 
1.15      raeburn   715: sub showaccess {
                    716:     my ($end,$start) = @_;
                    717:     my $showstart;
                    718:     my $showend;
                    719:     if ( (!$start) || ($start <= time) ) {
                    720:         $showstart = 'immediately';
                    721:     } else {
                    722:         $showstart = &Apache::lonlocal::locallocaltime($start);
                    723:     }
                    724:     if (!$end) {
                    725:         $showend = 'no end date';
                    726:     } else {
                    727:         $showend = &Apache::lonlocal::locallocaltime($end);
                    728:     }
                    729:     my $access_msg = " Access starts: ".$showstart.", ends: ".$showend.".";
                    730:     return $access_msg;
                    731: }
                    732: 
1.1       raeburn   733: sub parse_classlist {
1.6       raeburn   734:     my ($tmpdir,$dom,$crs,$class,$placeref,$groupID,$studentsref) = @_;
1.5       raeburn   735:     my $xmlfile = $tmpdir."/tmp/".$dom."_".$crs."_".$class."_classlist.xml";
1.6       raeburn   736:     my $uname = '';
                    737:     my @state;
1.8       raeburn   738:     my @items = ('autharg','authtype','email','firstname','generation','lastname','middlename','studentID');
1.6       raeburn   739:     my $p = HTML::Parser->new
                    740:     (
                    741:         xml_mode => 1,
                    742:         start_h =>
                    743:             [sub {
                    744:                  my ($tagname, $attr) = @_;
                    745:                  push @state, $tagname;
                    746:                  if ("@state" eq "students student") {
                    747:                      $uname = $attr->{username};
                    748:                  }
                    749:             }, "tagname, attr"],
                    750:          text_h =>
                    751:              [sub {
                    752:                  my ($text) = @_;
                    753:                  if ("@state" eq "students student groupID") {
                    754:                      $$studentsref{$uname}[ $$placeref{'groupID'} ] = $groupID;
1.8       raeburn   755:                  } elsif ("@state" eq "students student startdate") {
                    756:                      my $start = $text;
                    757:                      unless ($text eq '') {
                    758:                          $start = &process_date($text);
                    759:                      }
                    760:                      $$studentsref{$uname}[ $$placeref{'startdate'} ] = $start; 
                    761:                  } elsif ("@state" eq "students student enddate") {
                    762:                      my $end = $text;
                    763:                      unless ($text eq '') {
                    764:                          $end = &process_date($text);
                    765:                      }
                    766:                      $$studentsref{$uname}[ $$placeref{'enddate'} ] = $end;
1.6       raeburn   767:                  } else {
                    768:                      foreach my $item (@items) {
                    769:                          if ("@state" eq "students student $item") {
                    770:                              $$studentsref{$uname}[ $$placeref{$item} ] = $text;
                    771:                          }
                    772:                      }
                    773:                  }
                    774:                }, "dtext"],
                    775:          end_h =>
                    776:                [sub {
                    777:                    my ($tagname) = @_;
                    778:                    pop @state;
                    779:                 }, "tagname"],
                    780:     );
                    781:                                                                                                              
                    782:     $p->parse_file($xmlfile);
                    783:     $p->eof;
1.8       raeburn   784:     if (-e "$xmlfile") {
                    785:         unlink $xmlfile;
                    786:     }
1.3       raeburn   787:     return;
1.1       raeburn   788: }
                    789: 
1.8       raeburn   790: sub process_date {
                    791:     my $timestr = shift;
                    792:     my $timestamp = '';
                    793:     if ($timestr =~ m/^\d{4}:\d{2}:\d{2}/) {
                    794:         my @entries = split/:/,$timestr;
                    795:         for (my $j=0; $j<@entries; $j++) {
                    796:             if ( length($entries[$j]) > 1 ) {
                    797:                 $entries[$j] =~ s/^0//;
                    798:             }
                    799:         }
                    800:         $entries[1] = $entries[1] - 1;
                    801:         $timestamp =  timelocal($entries[5],$entries[4],$entries[3],$entries[2],$entries[1],$entries[0]);
                    802:     }
                    803:     return $timestamp;
                    804: }
                    805: 
1.1       raeburn   806: sub create_password {
1.8       raeburn   807:     my $passwd = '';
1.11      raeburn   808:     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");
1.8       raeburn   809:     for (my $i=0; $i<8; $i++) {
                    810:         my $lettnum = int (rand 2);
                    811:         my $item = '';
                    812:         if ($lettnum) {
                    813:             $item = $letts[int( rand(26) )];
                    814:             my $uppercase = int(rand 2);
                    815:             if ($uppercase) {
                    816:                 $item =~ tr/a-z/A-Z/;
                    817:             }
                    818:         } else {
                    819:             $item = int( rand(10) );
                    820:         } 
                    821:         $passwd .= $item;
                    822:     }
                    823:     return ($passwd);
1.9       raeburn   824: }
                    825: 
1.19      raeburn   826: sub get_courseinfo {
                    827:     my ($dom,$crs,$courseinfo) = @_;
                    828:     my $owner;
                    829:     if (defined($dom) && defined($crs)) {
1.31      raeburn   830:         my %settings = &Apache::lonnet::get('environment',['internal.coursecode','internal.showphoto','description'],$dom,$crs);
1.19      raeburn   831:         if ( defined($settings{'internal.coursecode'}) ) {
                    832:             $$courseinfo{'inst_code'} = $settings{'internal.coursecode'};
                    833:         }
                    834:         if ( defined($settings{'description'}) ) {
                    835:             $$courseinfo{'description'} = $settings{'description'};
                    836:         }
1.31      raeburn   837:         if ( defined($settings{'internal.showphoto'}) ) {
                    838:             $$courseinfo{'showphoto'} = $settings{'internal.showphoto'};
1.28      raeburn   839:         }
1.19      raeburn   840:     }
                    841:     return;
                    842: }
                    843: 
1.1       raeburn   844: sub CL_autharg { return 0; }
                    845: sub CL_authtype { return 1;}
                    846: sub CL_email { return 2;}
                    847: sub CL_enddate { return 3;}
                    848: sub CL_firstname { return 4;}
                    849: sub CL_generation { return 5;}
                    850: sub CL_groupID { return 6;}
                    851: sub CL_lastname { return 7;}
                    852: sub CL_middlename { return 8;}
                    853: sub CL_startdate { return 9; }
                    854: sub CL_studentID { return 10; }
                    855: 
1.28      raeburn   856: sub photo_response_types {
1.29      albertel  857:     my %lt = &Apache::lonlocal::texthash(
1.28      raeburn   858:                       'same' => 'remained unchanged',
                    859:                       'update' => 'were updated',
                    860:                       'new' => 'were added',
                    861:                       'missing' => 'were missing',
                    862:                       'error' => 'were not imported because an error occurred',
                    863:                       'nouser' => 'were for users without accounts',
                    864:                       'noid' => 'were for users without student IDs',
1.29      albertel  865: 					 );
1.28      raeburn   866:     return %lt;
                    867: }
                    868: 
                    869: 
1.1       raeburn   870: 1;

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