;
close(FILE);
###################################
# Before updating the database we back it up
###################################
if (( -e "$path_to_CL_DB" ) and (!$second_pass)){
$message .= "Backing up current classlist database to: ${path_to_CL_DB}_bak1
\n";
&backup($path_to_CL_DB);
}
my %loginName_StudentID_Hash = %{getLoginName_StudentID_Hash()};
my %studentID_LoginName_Hash =%{getStudentID_LoginName_Hash()};
# my $WW_DB_exists = 0;
# $WW_DB_exists = 1 if ( -e "${databaseDirectory}$Global::database" );
# my %loginName_StudentID_Hash_from_WW_DB =();
# my %studentID_LoginName_Hash_from_WW_DB =();
# if ($WW_DB_exists) {
# %loginName_StudentID_Hash_from_WW_DB =%{getLoginName_StudentID_Hash_from_WW_DB()};
# %studentID_LoginName_Hash_from_WW_DB = reverse %loginName_StudentID_Hash_from_WW_DB;
# }
my $errors ='';
my $drop_profs = ''; ## profs who will not be dropped
my $remove_profs = ''; ## profs who will not be removed
my $remove_students_with_sets = ''; ## students for whom sets exits who will not
## not be removed on first pass
my %new_good_classlist_students =(); ## students in new classlist without conflicts
my %new_bad_classlist_students =(); ## students in new classlist with conflicts
foreach (@classList) { ## read through classlist and create
## class list database
unless ($_ =~ /\S/) {next;} ## skip blank lines
chomp;
my @classListRecord=&getRecord($_);
my ($studentID, $lastName, $firstName, $status, $comment, $section, $recitation, $email_address, $login_name)
= @classListRecord;
## First we get a list of any conflicts with current students
if ((defined $loginName_StudentID_Hash{$login_name})
and ($loginName_StudentID_Hash{$login_name} ne $studentID)) {
$errors .= "$firstName $lastName, $login_name, $studentID
\n ";
$new_bad_classlist_students{$login_name} =1;
next;
}
if ((defined $studentID_LoginName_Hash{$studentID})
and ($studentID_LoginName_Hash{$studentID} ne $login_name)) {
$errors .= "$firstName $lastName, $login_name, $studentID
\n ";
$new_bad_classlist_students{$login_name} =1;
next;
}
## OK, the student record has no conflicts
$new_good_classlist_students{$login_name} =1;
## Handle students already in classlist DB
if (defined $loginName_StudentID_Hash{$login_name}) {
&attachCLRecord($login_name);
&CL_putStudentLastName ($lastName, $login_name) if $update_lastName;
&CL_putStudentFirstName ($firstName, $login_name) if $update_firstName;
&CL_putComment ($comment, $login_name) if $update_comment;
&CL_putClassSection ($section,$login_name) if $update_section;
&CL_putClassRecitation ($recitation,$login_name) if $update_recitation;
&CL_putStudentEmailAddress ($email_address, $login_name) if $update_email_address;
## test for dropping a professor
my $studentPermissions = &get_permissions($login_name, $permissionsFile);
my $orgStudentStatus = &CL_getStudentStatus($login_name);
if ($update_status and
defined $studentPermissions and
$studentPermissions == $Global::instructor_permissions and
&dropStatus($status) != &dropStatus($orgStudentStatus) and
&dropStatus($status)
)
{$drop_profs .= "$firstName $lastName, $login_name, $studentID
\n ";}
elsif ($update_status)
{&CL_putStudentStatus ($status, $login_name);}
$Global::over_ride_CLBD_lock = 1;
&saveCLRecord($login_name);
$Global::over_ride_CLBD_lock = 0;
}
else { ## Handle new students
&CL_putStudentID ($studentID, $login_name);
&CL_putStudentLastName ($lastName, $login_name);
&CL_putStudentFirstName ($firstName, $login_name);
&CL_putStudentStatus ($status, $login_name);
&CL_putComment ($comment, $login_name);
&CL_putClassSection ($section,$login_name);
&CL_putClassRecitation ($recitation,$login_name);
&CL_putStudentEmailAddress ($email_address, $login_name);
$Global::over_ride_CLBD_lock = 1;
&saveCLRecord($login_name);
$Global::over_ride_CLBD_lock = 0;
}
}
## Now we take care of students who are in the current classlist database but are not in
## the classlist file.
my %drop_list =();
my $login_name;
%loginName_StudentID_Hash = %{getLoginName_StudentID_Hash()};
foreach $login_name (keys %loginName_StudentID_Hash) {
$drop_list{$login_name} = 1 unless (
(defined ($new_good_classlist_students{$login_name})) or (defined ($new_bad_classlist_students{$login_name}))
);
}
if ($update_drop eq 'drop') {
my $status = 'D';
$status = $Global::statusDrop[0] if defined $Global::statusDrop[0];
foreach $login_name (keys %drop_list) {
&attachCLRecord($login_name);
## test for dropping a professor. If not a prof, drop them.
my $studentPermissions = &get_permissions($login_name, $permissionsFile);
my $orgStudentStatus = &CL_getStudentStatus($login_name);
if (defined $studentPermissions and
$studentPermissions == $Global::instructor_permissions and
!&dropStatus($orgStudentStatus)
) {
my $lastName = &CL_getStudentLastName($login_name);
my $firstName = &CL_getStudentFirstName($login_name);
my $studentID = &CL_getStudentID($login_name);
$drop_profs .= "$firstName $lastName, $login_name, $studentID
\n ";
}
else {&CL_putStudentStatus($status, $login_name);}
$Global::over_ride_CLBD_lock = 1;
&saveCLRecord($login_name);
$Global::over_ride_CLBD_lock = 0;
}
}
elsif ($update_drop eq 'remove') {
$remove_profs = '';
$remove_students_with_sets = '';
foreach $login_name (keys %drop_list) {
&attachCLRecord($login_name);
## test for removing a professor.
my $studentPermissions = &get_permissions($login_name, $permissionsFile);
my $orgStudentStatus = &CL_getStudentStatus($login_name);
if (defined $studentPermissions and
$studentPermissions == $Global::instructor_permissions and
!&dropStatus($orgStudentStatus)
) {
my $lastName = &CL_getStudentLastName($login_name);
my $firstName = &CL_getStudentFirstName($login_name);
my $studentID = &CL_getStudentID($login_name);
$remove_profs .= "$firstName $lastName, $login_name, $studentID
\n ";
}
## test for removing a students with existing problem sets.
elsif (check_Record($login_name)) {
my $lastName = &CL_getStudentLastName($login_name);
my $firstName = &CL_getStudentFirstName($login_name);
my $studentID = &CL_getStudentID($login_name);
$remove_students_with_sets .= "$firstName $lastName, $login_name, $studentID
\n ";
if ($second_pass) {
removeRecord($login_name);
$Global::over_ride_CLBD_lock = 1;
deleteClassListRecord($login_name);
$Global::over_ride_CLBD_lock = 0;
}
}
else {
$Global::over_ride_CLBD_lock = 1;
deleteClassListRecord($login_name);
$Global::over_ride_CLBD_lock = 0;
}
}
}
else { ## if this case $update_drop eq 'leave' and we do nothing
}
unlock_CL_database();
if (($remove_profs) and (!$second_pass)){
$message .= "
The following professors HAVE NOT BEEN REMOVED.
If you really want to remove a professor, do this from the Edit Class Roster page where there are more
options and safe guards.
";
$message .= "\n $remove_profs
";
}
if (($drop_profs) and (!$second_pass)) {
$message .= "
The following professors HAVE NOT BEEN DROPPED.
If you really want to drop a professor, do this from the Edit Class Roster page where there are more
options and safe guards.
";
$message .= "\n $drop_profs
";
}
if ($remove_students_with_sets) {
if (!$second_pass) {
$message .= "
The following students HAVE NOT BEEN REMOVED.
There are existing sets for these students. If you choose to remove all records for these students,
all this data will be destroyed. This action can not be undone. Generally it is preferable to change
their \"Enrollment Status\" to \"D\" (for Drop) rather than to totally remove all records. To change
their \"Enrollment Status\" to \"D\", use your brower's back button and select \"Change student's
status to 'drop' in the classlist database\". If you want details on which sets exist for which
students, go to the Edit Class Roster page, select the student and then click \"Remove THIS RECORD\".
You will see a list of existing sets and then be given the oportunity to remove them if you wish.
If you really want to remove all records for these students,
click on 'Remove all records'.
";
}
else {
$message .= "
The following students HAVE BEEN REMOVED.
All records for these students have been deleted.
";
}
$message .= "\n $remove_students_with_sets
";
$message .= &remove_students_form() unless $second_pass;
}
if ($errors) {
$message .= "
The following students HAVE NOT BEEN ENTERED IN THE
CLASSLIST DATABASE
because of a conflict with entries in the WeBWorK problem set database or the classlist database.
These students have a studentID or a loginName that conflicts with a current student.
Enter this information again from the Add Student(s) Page to get a more detailed error message
and instructions on how to correct the problem.
";
$message .= "\n $errors
";
}
$message;
}
sub initial_passwords {
my %studentsinclass=();
my @classListRecord=();
my $msg ='';
# Check that the files exist:
# The permissions file must exist and have both read and write privilages.
# The password file must exist and have both read and write privilages.
unless ( -r $passwordFile and -w $passwordFile) {
wwerror ($0, "Permissions set incorrectly on $passwordFile or its directory.
Cannot access file to both read and write.");
}
unless ( -r $permissionsFile and -w $permissionsFile) {
wwerror ($0, "Permissions set incorrectly on $permissionsFile or its directory.
Cannot access file to both read and write.");
}
my $login_name;
my @classList = @{getAllLoginNames()};
$msg .= "\n
Modifying the password file: $passwordFile
\n ";
foreach $login_name (@classList) { ## read through classlist database and create
## passwords for all active students
## except if passwords already exist for student
attachCLRecord($login_name);
my $status = CL_getStudentStatus($login_name);
my $studentID = CL_getStudentID($login_name);
$studentsinclass{$login_name}++ unless(&dropStatus($status));
if(&dropStatus($status)) {
$msg .= ' '."$login_name not added because status is $status
\n ";
}
elsif (&get_password($login_name, $passwordFile)) {
$msg .= ' '."$login_name not added because password already exists
\n ";
}
else {
&new_password($login_name, $studentID, $passwordFile);
&put_permissions(0,$login_name,$permissionsFile);
$msg .= "added: $login_name, $studentID
\n ";
}
}
my @pwStudents = &get_keys_from_db($passwordFile);
my ($ans,$student);
$msg .= "\n
The following login's (if any) in the password and permissions databases are either\n ";
$msg .= "(1) not listed in the new class list database file \n";
$msg .= "or (2) have DROP status in the new class list database file.\n";
$msg .= "They will all be removed from the password and permissions databases.
\n ";
foreach $student (@pwStudents) {
next if defined($studentsinclass{$student});
&delete_password($student,$passwordFile);
&delete_permissions($student,$permissionsFile);
$msg .= "$student
\n ";
}
$msg = ''; ## returning too much info so don't return this
$msg;
}
sub uploadSuccess {
my ($msg) = @_;
print"content-type: text/html\n\n
The classlist database has been updated.
\n";
print $msg;
print &htmlBOTTOM("profImportClasslistDatabase.pl", \%inputs);
}
sub backup {
## takes as a parameter the full path name
## makes upto two backups of the file with _bak1, or _bak2
## appended to filename where _bak1 is the most recent backup
use File::Copy;
my $fileName =$_[0];
if (-e "${fileName}_bak1") {
rename("${fileName}_bak1","${fileName}_bak2") or
&wwerror("$0","can't rename ${fileName}_bak1");
}
if (-e "${fileName}") {
copy("${fileName}","${fileName}_bak1") or
&wwerror("$0","can't copy ${fileName}");
}
}
sub check_Record {
my $studentLogin = shift @_;
my $setsExist = 0;
# check to see if there is data for this student in the WW DB
if ( -e "${databaseDirectory}$Global::database" ){
$setsExist = &setsExistForStudentLogin($studentLogin);
}
return $setsExist;
}
sub removeRecordWarningPage {
my ($inputref, $studentLogin, $setsExist, $SetNumberKeysref) = @_;
my @SetNumberKeys = @$SetNumberKeysref;
my %inputs = %$inputref;
attachCLRecord($studentLogin);
my $studentLastName = CL_getStudentLastName($studentLogin);
my $studentFirstName = CL_getStudentFirstName($studentLogin);
my $studentID = CL_getStudentID($studentLogin);
my $studentPermissions = &get_permissions($studentLogin, $permissionsFile);
my $word = 'informational';
if ($setsExist or (defined $studentPermissions and $studentPermissions == $Global::instructor_permissions))
{$word = "WARNING";}
# print HTML text
print &htmlTOP("Data for the classlist record for $studentLogin");
print qq!WeBWorK $word message concerning user $studentLogin
($studentFirstName $studentLastName $studentID)
\n!;
print qq!You have requested to remove the the classlist records and all associated data for the above user.
NO CHANGES HAVE BEEN MADE YET.
!;
if ($User eq $studentLogin) {
print qq!YOU ARE TRYING TO REMOVE YOURSELF FROM THE COURSE. \n
If you do this, you will immediately be locked out of the course. You will no longer be able to\n
login and/or administer the course. Removing yourself is something you almost never want to do.\n
Use your browser's "Back" button to cancel this action.
\n!;
}
elsif (defined $studentPermissions and $studentPermissions == $Global::instructor_permissions){
print qq!YOU ARE TRYING TO REMOVE A PROFESSOR FROM THE COURSE. \n
If you do this, $studentFirstName $studentLastName will imediately be locked out of the course.
He or she will no longer be able to login and/or administer the course.
Use your browser's "Back" button to cancel this action.
\n!;
}
if ($setsExist) {
print qq! Data exists in the WeBWorK databases for following sets for user $studentLogin
\n!;
foreach my $set (@SetNumberKeys) {
print "
Set $set\n";
}
print "
If you choose to remove all records for $studentLogin, all this data will be destroyed. This action can not be undone.
\n";
}
print qq!
Generally if the user $studentLogin is a real user, it is preferable to change his or her "Enrollment Status"\n
to "D" (for Drop) rather than to totally remove all records. That way records are not destroyed\n
and also the student can be reactivated simply by changing his or her "Enrollment Status" back to "C" (for Current).\n!;
print qq!
If you have scored any of the above sets, scores for user $studentLogin will be contained in the
${Course}_totals.csv file (and the other scoring files). These scores will not be removed.\n!;
print qq!
If you want to change the "Enrollment Status" for $studentLogin to "D" (for Drop), use your browser's "Back" button.
\n!;
print qq!
!;
print &htmlBOTTOM('profEditClasslistDB.pl', \%inputs);
} #end of removeRecordWarningPage
sub removeRecord {
my $studentLogin = shift @_;
my $setsExist = 0;
my @SetNumberKeys = ();
my %setNumberHash = ();
# check to see if there is data for this student in the WW DB
if ( -e "${databaseDirectory}$Global::database" ){
$setsExist = &setsExistForStudentLogin($studentLogin);
if ($setsExist) {
%setNumberHash=&getAllSetNumbersForStudentLoginHash($studentLogin);
@SetNumberKeys = keys(%setNumberHash);
}
}
## Now remove all that data in the WeBWorK database, the .sco files,
## dvipng images, and any LaTeX2HTML images
my ($setName, $psvn);
if ($setsExist) {
foreach $setName (@SetNumberKeys) {
$psvn = $setNumberHash{$setName};
&attachProbSetRecord($psvn);
&deleteProbSetRecord($psvn);
# remove .sco file if it exists
system ("rm ${databaseDirectory}S${setName}-${psvn}.sco") if (-e "${databaseDirectory}S${setName}-${psvn}.sco");
# remove any l2h files
my $l2hDir = getCoursel2hDirectory();
my $tempDir = convertPath("${l2hDir}set${setName}/*-$psvn");
system ("rm -rf $tempDir");
# remove any dvipng images -- reuse the variable names
$l2hDir = getCourseTempDirectory();
$tempDir = convertPath("${l2hDir}png/${setName}/$psvn");
system ("rm -rf $tempDir");
}
}
## Next remove password and permission data
delete_password($studentLogin,$passwordFile);
delete_permissions($studentLogin,$permissionsFile);
}
sub remove_students_form {
my $form = '';
$form .= $cgi->startform(-action=>"${cgiURL}profImportClasslistDatabase.pl")."\n";
$form .= $cgi->hidden(-name=>'classList', -value=>"$inputs{'classList'}")."\n";
$form .= $cgi->hidden(-name=>'course', -value=>"$inputs{'course'}")."\n";
$form .= $cgi->hidden(-name=>'user', -value=>"$inputs{'user'}")."\n";
$form .= $cgi->hidden(-name=>'key', -value=>"$inputs{'key'}")."\n";
$form .= $cgi->hidden(-name=>'update_drop', -value=>'remove')."\n";
$form .= $cgi->submit(-name=>'action', -value=>'Remove all records')."\n";
$form .= $cgi->endform()."\n";
return $form;
}