--- loncom/interface/Attic/londropadd.pm 2002/04/04 17:32:45 1.22
+++ loncom/interface/Attic/londropadd.pm 2004/03/01 16:34:54 1.106
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Handler to drop and add students in courses
#
-# $Id: londropadd.pm,v 1.22 2002/04/04 17:32:45 albertel Exp $
+# $Id: londropadd.pm,v 1.106 2004/03/01 16:34:54 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -25,338 +25,476 @@
#
# http://www.lon-capa.org/
#
-# (Handler to set parameters for assessments
#
-# (Handler to resolve ambiguous file locations
-#
-# (TeX Content Handler
-#
-# YEAR=2000
-# 05/29/00,05/30,10/11 Gerd Kortemeyer)
-#
-# 10/11,10/12,10/16 Gerd Kortemeyer)
-#
-# 11/20,11/21,11/22,11/23,11/24,11/25,11/27,11/28,
-# 12/08,12/12 Gerd Kortemeyer)
-#
-# 12/26,12/27,12/28,
-# YEAR=2001
-# 01/01/01,01/15,02/10,02/13,02/14,02/22 Gerd Kortemeyer
-# 8/6 Scott Harrison
-# Guy Albertelli
-# 9/25 Gerd Kortemeyer
-# 12/19 Guy Albertelli
-# YEAR=2002
-# 1/4 Gerd Kortemeyer
+###############################################################
+##############################################################
package Apache::londropadd;
use strict;
-use Apache::lonnet;
+use Apache::lonnet();
+use Apache::loncommon();
+use Apache::lonhtmlcommon();
use Apache::Constants qw(:common :http REDIRECT);
+use Spreadsheet::WriteExcel;
+use Apache::lonlocal;
-# ================================================================ Print header
-
+###############################################################
+###############################################################
sub header {
- my $r=shift;
- $r->print(<
-
Drop/Add Students
-
+ + $Text{'enrollone'} + $help{'Course_Add_Student'} +
+ + $Text{'modify'} + $help{'Course_Modify_Student_Data'} +
+ + $Text{'view'} + $help{'Course_View_Class_List'} +
+ + $Text{'drop'} + $help{'Course_Drop_Student'} +
+ + $Text{'populate'} + +END +} + +############################################################### +############################################################### +sub hidden_input { + my ($name,$value) = @_; + return ''."\n"; +} + +sub print_upload_manager_header { + my ($r,$datatoken,$distotal,$krbdefdom)=@_; + my $javascript; + # + if (! exists($ENV{'form.upfile_associate'})) { + $ENV{'form.upfile_associate'} = 'forward'; + } + if ($ENV{'form.associate'} eq 'Reverse Association') { + if ( $ENV{'form.upfile_associate'} ne 'reverse' ) { + $ENV{'form.upfile_associate'} = 'reverse'; + } else { + $ENV{'form.upfile_associate'} = 'forward'; + } + } + if ($ENV{'form.upfile_associate'} eq 'reverse') { + $javascript=&upload_manager_javascript_reverse_associate(); } else { - return split(/\n/,$ENV{'form.upfile'}); + $javascript=&upload_manager_javascript_forward_associate(); + } + # + # Deal with restored settings + my $password_choice = ''; + if (exists($ENV{'form.ipwd_choice'}) && + $ENV{'form.ipwd_choice'} ne '') { + # If a column was specified for password, assume it is for an + # internal password. This is a bug waiting to be filed (could be + # local or krb auth instead of internal) but I do not have the + # time to mess around with this now. + $password_choice = 'int'; + } + # + my $javascript_validations=&javascript_validations('auth',$krbdefdom, + $password_choice); + my $checked=(($ENV{'form.noFirstLine'})?' checked="1"':''); + $r->print('
\n". + &mt('Total number of records found in file: [_1].',$distotal). + "\n". + "
-
-
-ENDUPFORM
+END
+ }
+ my $result = $function_name;
+ if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
+ $result .= $auth_checks;
+ }
+ $result .= $optional_checks;
+ if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
+ $result .= $authheader;
+ }
+ return $result;
}
-# ======================================================= Menu Phase Two Upload
-
-sub menu_phase_two_upload {
- my $r=shift;
-
- my $datatoken=&upfile_store($r);
-
- my @records=&upfile_record_sep();
- my $total=$#records;
- my $distotal=$total+1;
-
- $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/;
- my $krbdefdom=$1;
- $krbdefdom=~tr/a-z/A-Z/;
-
- my $today=time;
- my $halfyear=$today+15552000;
-
- my $defdom=$r->dir_config('lonDefDomain');
-
- $r->print(< Note: this will not take effect if the user already exists
-
-Kerberos authenticated with domain
-
-
-
-Internally authenticated (with initial password
-)
-
-
-Local Authentication with argument
-
-
-
-
-
- '.&mt('Enrolling').' '.$ENV{'form.cuname'}." \@ ".
+ $ENV{'form.lcdomain'}.' ".&mt('If active, the new role will be available when the student next logs in to LON-CAPA.')." '.&mt('ERROR').' ');
+ if ($amode =~ /^krb/) {
+ $r->print(&mt('Missing Kerberos domain information.').' ');
+ } else {
+ $r->print(&mt('Invalid login mode or password.').' ');
+ }
+ $r->print(''.&mt('Unable to enroll').' '.$ENV{'form.cuname'}.'.
+$krbform
+ $lt{'gs'}:
+
+$date_table
+
+$lt{'idsn'}:
+
+
+$lt{'disn'}
+
+
+ \n");
+ if ($ENV{'form.action'} ne 'modifystudent') {
+ my %lt=&Apache::lonlocal::texthash('csv' => "CSV",
+ 'excel' => "Excel",
+ 'html' => 'HTML');
+ $r->print('');
+ my $output_selector = '';
+ $r->print(&mt('Output Format: [_1]',$output_selector).(' 'x3));
}
- if (vf.login[1].checked) {
- foundatype=1;
- if ((vf.intpwd.value=='') && (foundpwd==0)) {
- alert('You need to specify the initial password');
- return;
+ $r->print(&mt('Student Status: [_1]',$status_select)."\n");
+ $r->print(''.
+ "\n
+ '.
+ &mt('Your Excel spreadsheet').' '.&mt('is ready for download').'. '.
+ &mt('Unable to retrieve environment data for').' '.$sname.
+ &mt('in domain').' '.$sdom.' '.
+ &mt('Please contact your LON-CAPA administrator regarding this situation.').'
-Identify fields
-Total number of records found in file: $distotal
-Enter as many fields as you can. The system will inform you and bring you back
-to this page if the data selected is insufficient to run your class.
-
-
-ENDPICK
- my %sone; my %stwo; my %sthree;
- my $i=0;
-
- if ($total>=0) {
- %sone=&record_sep($records[0]);
- if ($total>=1) {
- %stwo=&record_sep($records[1]);
-
- }
- if ($total>=2) {
- %sthree=&record_sep($records[2]);
- }
- foreach (sort keys %sone) {
- $r->print('Field Samples ');
- $i++;
- }
- $i--;
- }
- my $keyfields=join(',',sort keys %sone);
- $r->print(<');
- if (defined($sone{$_})) {
- $r->print($sone{$_}."\n");
- }
- if (defined($stwo{$_})) {
- $r->print($stwo{$_}."\n");
- }
- if (defined($sthree{$_})) {
- $r->print($sthree{$_}."\n");
- }
- $r->print(' Login Type
-LON-CAPA Domain for Students
-LON-CAPA domain: Starting and Ending Dates
-
-
-
-
-
-Set Starting DateFull Update
- Full update
-(also print list of users not enrolled anymore)ID/Student Number
-
-Disable ID/Student Number Safeguard and Force Change of Conflicting IDs
-(only do if you know what you are doing)
-Note: for large courses, this operation might be time consuming.
-ENDPICK
+ my $total=$#records;
+ my $distotal=$total+1;
+ my $today=time;
+ my $halfyear=$today+15552000;
+ #
+ # Restore memorized settings
+ &Apache::loncommon::restore_course_settings
+ ('enrollment_upload',{ 'username_choice' => 'scalar', # column settings
+ 'names_choice' => 'scalar',
+ 'fname_choice' => 'scalar',
+ 'mname_choice' => 'scalar',
+ 'lname_choice' => 'scalar',
+ 'gen_choice' => 'scalar',
+ 'id_choice' => 'scalar',
+ 'sec_choice' => 'scalar',
+ 'ipwd_choice' => 'scalar',
+ 'email_choice' => 'scalar',
+ });
+ #
+ # Determine kerberos parameters as appropriate
+ my $defdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
+ my ($krbdef,$krbdefdom) =
+ &Apache::loncommon::get_kerberos_defaults($defdom);
+ #
+ &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom);
+ my $i;
+ my $keyfields;
+ if ($total>=0) {
+ my @field=
+ (['username',&mt('Username'), $ENV{'form.username_choice'}],
+ ['names',&mt('Last Name, First Names'),$ENV{'form.names_choice'}],
+ ['fname',&mt('First Name'), $ENV{'form.fname_choice'}],
+ ['mname',&mt('Middle Names/Initials'),$ENV{'form.mname_choice'}],
+ ['lname',&mt('Last Name'), $ENV{'form.lname_choice'}],
+ ['gen', &mt('Generation'), $ENV{'form.gen_choice'}],
+ ['id', &mt('ID/Student Number'),$ENV{'form.id_choice'}],
+ ['sec', &mt('Group/Section'), $ENV{'form.sec_choice'}],
+ ['ipwd', &mt('Initial Password'),$ENV{'form.ipwd_choice'}],
+ ['email',&mt('EMail Address'), $ENV{'form.email_choice'}]);
+ if ($ENV{'form.upfile_associate'} eq 'reverse') {
+ &Apache::loncommon::csv_print_samples($r,\@records);
+ $i=&Apache::loncommon::csv_print_select_table($r,\@records,
+ \@field);
+ foreach (@field) {
+ $keyfields.=$_->[0].',';
+ }
+ chop($keyfields);
+ } else {
+ unshift(@field,['none','']);
+ $i=&Apache::loncommon::csv_samples_select_table($r,\@records,
+ \@field);
+ my %sone=&Apache::loncommon::record_sep($records[0]);
+ $keyfields=join(',',sort(keys(%sone)));
+ }
+ }
+ &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear);
}
-# ======================================================= Enroll single student
-
+###############################################################
+###############################################################
sub enroll_single_student {
my $r=shift;
- $r->print('Enrolling Student
');
+ # Remove non alphanumeric values from section
+ $ENV{'form.csec'}=~s/\W//g;
+ #
+ # We do the dates first because the action of making them the defaul
+ # in the course is entirely seperate from the action of enrolling the
+ # student. Also, a failure in setting the dates as default is not fatal
+ # to the process of enrolling / modifying a student.
+ my ($startdate,$enddate) = &get_dates_from_form();
+ if ($ENV{'form.makedatesdefault'}) {
+ $r->print(&make_dates_default($startdate,$enddate));
+ }
+
+ $r->print(''.&mt('Enrolling Student').'
');
+ $r->print('\n";
+ $result .= '
\n";
+ return $result;
+}
+
+sub make_dates_default {
+ my ($startdate,$enddate) = @_;
+ my $result = '';
+ my $dom = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
+ my $crs = $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
+ my $put_result = &Apache::lonnet::put('environment',
+ {'default_enrollment_start_date'=>$startdate,
+ 'default_enrollment_end_date' =>$enddate},$dom,$crs);
+ if ($put_result eq 'ok') {
+ $result .= "Set default start and end dates for course \n";
+ $result .= ''.&mt('Starting Date').' '.
+ ''.$startform.' '.
+ ''.$dateDefault.' '." \n";
+ $result .= "'.&mt('Ending Date').' '.
+ ''.$endform.' '.
+ ''.$perpetual.' '."
";
+ #
+ # Refresh the course environment
+ &Apache::lonnet::coursedescription($ENV{'request.course.id'});
+ } else {
+ $result .= &mt('Unable to set default dates for course').":".$put_result.
+ '
';
+ }
+ return $result;
+}
- my $defdom=$r->dir_config('lonDefDomain');
+##
+## Single student enrollment routines (some of them)
+##
+sub get_student_username_domain_form {
+ my $r = shift;
+ my $domform = &Apache::loncommon::select_dom_form
+ ($ENV{'course.'.$ENV{'request.course.id'}.'.domain'},'cudomain',0);
+ my %lt=&Apache::lonlocal::texthash(
+ 'eos' => "Enroll One Student",
+ 'usr' => "Username",
+ 'dom' => "Domain",
+ 'been' => "Begin Enrollment",
+ );
+ $r->print(<$lt{'eos'}
+
+
+END
+ return;
+}
- $r->print(<
+$lt{'usr'}:
+
+$lt{'dom'}:
+ $domform
+
+
+
+ ".&mt('Enroll One Student')."
");
+ #
+ my $username = $ENV{'form.cuname'};
+ my $domain = $ENV{'form.cudomain'};
+ my $home = &Apache::lonnet::homeserver($username,$domain);
+ # $new_user flags whether we are creating a new user or using an old one
+ my $new_user = 1;
+ if ($home ne 'no_host') {
+ $new_user = 0;
+ }
+ #
+ my $user_data_html = '';
+ my $javascript_validations = '';
+ if ($new_user) {
+ my $defdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
+ # Set up authentication forms
+ my ($krbdef,$krbdefdom) =
+ &Apache::loncommon::get_kerberos_defaults($domain);
+ $javascript_validations=&javascript_validations('auth',$krbdefdom);
+ my %param = ( formname => 'document.studentform',
+ kerb_def_dom => $krbdefdom,
+ kerb_def_auth => $krbdef
+ );
+ my $krbform = &Apache::loncommon::authform_kerberos(%param);
+ my $intform = &Apache::loncommon::authform_internal(%param);
+ my $locform = &Apache::loncommon::authform_local(%param);
+ #
+ # Set up domain selection form
+ my $homeserver_form = '';
+ my %servers = &Apache::loncommon::get_library_servers($domain);
+ $homeserver_form = '\n";
+ #
+ #
+ my %lt=&Apache::lonlocal::texthash(
+ 'udf' => "User Data for",
+ 'fn' => "First Name",
+ 'mn' => "Middle Name",
+ 'ln' => "Last Name",
+ 'gen' => "Generation",
+ 'hs' => "Home Server",
+ 'pswd' => "Password",
+ 'psam' => "Please select an authentication mechanism",
+ );
+ $user_data_html = <
+
+
+$lt{'fn'}:
+
+$lt{'mn'}:
+
+$lt{'ln'}:
+
+$lt{'gen'}:
+
+$lt{'hs'}:
+ $homeserver_form $lt{'pswd'}
+$lt{'psam'}
+
+
+$intform
+
+$locform
+
+
+END
+ }
+ my $date_table = &date_setting_table();
+ # Print it all out
+ my %lt=&Apache::lonlocal::texthash(
+ 'cd' => "Course Data",
+ 'gs' => "Group/Section",
+ 'idsn' => "ID/Student Number",
+ 'disn' => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
+ 'eas' => "Enroll as student",
+ );
+ $r->print(<
+$lt{'fn'}:
+
+
+
+$lt{'mn'}:
+
+
+
+$lt{'ln'}:
+
+
+
+$lt{'gen'}:
+
+
+ $lt{'cd'}
+
+$lt{'idsn'}
+".&mt('Drop Students')."
");
+ my $cid=$ENV{'request.course.id'};
+ my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();
+ if (! defined($classlist)) {
+ $r->print(&mt('There are no students currently enrolled.')."\n");
+ return;
+ }
+ # Print out the available choices
+ &show_drop_list($r,$classlist,$keylist);
+ return;
+}
+
+# ============================================== view classlist
+sub print_html_classlist {
+ my ($r,$mode) = @_;
+ if (! exists($ENV{'form.sortby'})) {
+ $ENV{'form.sortby'} = 'username';
+ }
+ if ($ENV{'form.Status'} !~ /^(Any|Expired|Active)$/) {
+ $ENV{'form.Status'} = 'Active';
+ }
+ my $status_select = &Apache::lonhtmlcommon::StatusOptions
+ ($ENV{'form.Status'});
+ my $cid=$ENV{'request.course.id'};
+ my $cdom=$ENV{'course.'.$cid.'.domain'};
+ my $cnum=$ENV{'course.'.$cid.'.num'};
+ #
+ # List course personnel
+ my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum);
+ $r->print('');
+ foreach (sort keys %coursepersonnel) {
+ $r->print('
');
+ #
+ # Interface output
+ my $CCL=&mt('Current Class List');
+ $r->print('');
+ $r->print(" ');
+ }
+ $r->print(''.$_.' ');
+ foreach (split(/\,/,$coursepersonnel{$_})) {
+ my ($puname,$pudom)=split(/\:/,$_);
+ $r->print(' '.&Apache::loncommon::aboutmewrapper(
+ &Apache::loncommon::plainname($puname,
+ $pudom),$puname,$pudom));
+ }
+ $r->print(' '.&mt('Current Class List').'
');
+ my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
+ if (! defined($classlist)) {
+ $r->print(&mt('There are no students currently enrolled.')."\n");
+ } else {
+ # Print out the available choices
+ if ($ENV{'form.action'} eq 'modifystudent') {
+ &show_class_list($r,'view','modify','modifystudent',
+ $ENV{'form.Status'},$classlist,$keylist);
+ } elsif (! defined($mode) || $mode eq '') {
+ &show_class_list($r,'view','aboutme','classlist',
+ $ENV{'form.Status'},$classlist,$keylist);
+ } elsif ($mode eq 'csv' || $mode eq 'excel') {
+ &show_class_list($r,$mode,'nolink','csv',
+ $ENV{'form.Status'},$classlist,$keylist);
}
}
- if (vf.login[2].checked) {
- foundatype=1;
- //An argument is not required
+}
+
+# =================================================== Show student list to drop
+sub show_class_list {
+ my ($r,$mode,$linkto,$action,$statusmode,$classlist,$keylist)=@_;
+ my $cid=$ENV{'request.course.id'};
+ #
+ # Variables for excel output
+ my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format);
+ #
+ # Variables for csv output
+ my ($CSVfile,$CSVfilename);
+ #
+ my $sortby = $ENV{'form.sortby'};
+ if ($sortby !~ /^(username|domain|section|fullname|id)$/) {
+ $sortby = 'username';
+ }
+ # Print out header
+ $r->print(<
+
+END
+ } elsif ($mode eq 'csv') {
+ #
+ # Open a file
+ $CSVfilename = '/prtspool/'.
+ $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
+ time.'_'.rand(1000000000).'.csv';
+ unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) {
+ $r->log_error("Couldn't open $CSVfilename for output $!");
+ $r->print("Problems occured in writing the csv file. ".
+ "This error has been logged. ".
+ "Please alert your LON-CAPA administrator.");
+ $CSVfile = undef;
+ }
+ #
+ # Write headers and data to file
+ if($statusmode eq 'Expired') {
+ print $CSVfile '"'.&mt('Students with expired roles').'"'."\n";
+ }
+ if ($statusmode eq 'Any') {
+ print $CSVfile '"'.join('","',map {
+ &Apache::loncommon::csv_translate(&mt($_))
+ } ("username","domain","ID","student name",
+ "section","status")).'"'."\n";
+ } else {
+ print $CSVfile '"'.join('","',map {
+ &Apache::loncommon::csv_translate(&mt($_))
+ } ("username","domain","ID","student name",
+ "section")).'"'."\n";
+ }
+ } elsif ($mode eq 'excel') {
+ # Create the excel spreadsheet
+ $excel_filename = '/prtspool/'.
+ $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
+ time.'_'.rand(1000000000).'.xls';
+ $excel_workbook = Spreadsheet::WriteExcel->new('/home/httpd'.
+ $excel_filename);
+ $excel_workbook->set_tempdir('/home/httpd/perl/tmp');
+ #
+ $format = &Apache::loncommon::define_excel_formats($excel_workbook);
+ $excel_sheet = $excel_workbook->addworksheet('classlist');
+ #
+ my $description = 'Class List for '.
+ $ENV{'course.'.$ENV{'request.course.id'}.'.description'};
+ $excel_sheet->write($row++,0,$description,$format->{'h1'});
+ #
+ $excel_sheet->write($row++,0,["username","domain","ID",
+ "student name","section","status"],$format->{'bold'});
+ }
+ #
+ # Sort the students
+ my %index;
+ my $i;
+ foreach (@$keylist) {
+ $index{$_} = $i++;
+ }
+ my $index = $index{$sortby};
+ my $second = $index{'username'};
+ my $third = $index{'domain'};
+ my @Sorted_Students = sort {
+ lc($classlist->{$a}->[$index]) cmp lc($classlist->{$b}->[$index])
+ ||
+ lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
+ ||
+ lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
+ } (keys(%$classlist));
+ foreach my $student (@Sorted_Students) {
+ my $username = $classlist->{$student}->[$index{'username'}];
+ my $domain = $classlist->{$student}->[$index{'domain'}];
+ my $section = $classlist->{$student}->[$index{'section'}];
+ my $name = $classlist->{$student}->[$index{'fullname'}];
+ my $id = $classlist->{$student}->[$index{'id'}];
+ my $status = $classlist->{$student}->[$index{'status'}];
+ next if (($statusmode ne 'Any') && ($status ne $statusmode));
+ if ($mode eq 'view') {
+ $r->print("
+ $lt{'usrn'}
+
+ $lt{'dom'}
+
+ ID
+
+ $lt{'sn'}
+
+ $lt{'sec'}
+
+\n
+END
+ } elsif ($mode eq 'csv') {
+ next if (! defined($CSVfile));
+ # no need to bother with $linkto
+ my @line = ();
+ foreach ($username,$domain,$id,$name,$section) {
+ push @line,&Apache::loncommon::csv_translate($_);
+ }
+ if ($statusmode eq 'Any') {
+ push @line,&Apache::loncommon::csv_translate($status);
+ }
+ print $CSVfile '"'.join('","',@line).'"'."\n";
+ } elsif ($mode eq 'excel') {
+ $excel_sheet->write($row++,0,[$username,$domain,$id,
+ $name,$section,$status]);
+ }
}
- if (foundatype==0) {
- alert('You need to set the login type');
+ if ($mode eq 'view') {
+ $r->print('\n ");
+ if ($linkto eq 'nothing') {
+ $r->print($username);
+ } elsif ($linkto eq 'aboutme') {
+ $r->print(&Apache::loncommon::aboutmewrapper($username,
+ $username,
+ $domain));
+ } elsif ($linkto eq 'modify') {
+ $r->print(''.
+ $username."\n");
+ }
+ $r->print(<<"END");
+
+ $domain
+ $id
+ $name
+ $section
+
');
+ } elsif ($mode eq 'excel') {
+ $excel_workbook->close();
+ $r->print('