first commit
commit
f6be542440
@ -0,0 +1,211 @@
|
||||
<?php
|
||||
/*
|
||||
* This script takes two files, an IServ user export CSV and a DiViS student <> parents CSV
|
||||
* and maps the parents to the IServ students, creating a third CSV file that can be imported
|
||||
* into the IServ Elternverwaltung module.
|
||||
*
|
||||
* The IServ user export CSV is expected to have the following columns:
|
||||
* Account;Vorname;Nachname;Status;"Erstellt am";"Erstellt von";"Interne ID";Benutzertyp;Import-ID;Klasse/Information;E-Mail-Adresse;Gruppen
|
||||
*
|
||||
* The student <> parents mapped CSV from DiViS should have the following columns:
|
||||
* "Schüler Vorname","Schüler Nachname","Eltern 1 Vorname","Eltern 1 Nachname","Eltern 2 Vorname","Eltern 2 Nachname"
|
||||
*
|
||||
* The CSV exported by this script will have the following columns:
|
||||
* Nachname;Vorname;Kind-ID;Klasse
|
||||
*
|
||||
* Status messages, information and errors are always written to STDERR, while the generated CSV
|
||||
* will be exported to STDOUT, meaning you can redirect the STDOUT output of this script to a file
|
||||
* to export the CSV and still be able to read any informational messages:
|
||||
* $ php ./IServ_Elternimport_Divis.php iserv-user-export.csv divis-parents-export.csv > Parents_Import.csv
|
||||
*/
|
||||
|
||||
define ("WRITE_TO_CONSOLE", true);
|
||||
define ("IS_CLI", (php_sapi_name() == "cli"));
|
||||
|
||||
/**
|
||||
* Writes text to the STDERR stream when running from the command line.
|
||||
*
|
||||
* @param string $text The text to write to console
|
||||
* @return void
|
||||
*/
|
||||
function console_write ($text) {
|
||||
global $argv;
|
||||
|
||||
if (IS_CLI && WRITE_TO_CONSOLE) {
|
||||
fwrite (STDERR, $text . PHP_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns the first and last name of a student into a single string
|
||||
* used to identify the student in the students array.
|
||||
*
|
||||
* @param string $firstname First name of the student
|
||||
* @param string $lastname Last name of the student
|
||||
* @return string Combined and lower-cased names of the student
|
||||
*/
|
||||
function hash_student ($firstname, $lastname) {
|
||||
return strtolower($firstname) . "_" . strtolower($lastname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries the parent(s) of a student by their first and last name
|
||||
* in the DiViS student <> parents mapped CSV.
|
||||
*
|
||||
* @param string $firstname First name of the student
|
||||
* @param string $lastname Last name of the student
|
||||
* @return string|null Array of parents first and last names,
|
||||
* or null if no matching data was found.
|
||||
*/
|
||||
function find_parent_by_student ($firstname, $lastname) {
|
||||
global $divis_parents;
|
||||
|
||||
$student_hash = hash_student ($firstname, $lastname);
|
||||
$best_match = [ "match_perc" => 0 ];
|
||||
$perc = 0;
|
||||
|
||||
console_write ("INFO: Searching parent(s) for '{$firstname} {$lastname}' ({$student_hash})");
|
||||
|
||||
foreach ($divis_parents as $hash => $parent) {
|
||||
similar_text ($student_hash, $hash, $perc);
|
||||
|
||||
// If match is bigger or equal to 85% and this match is higher
|
||||
// ranked than the last, make this the current best match
|
||||
if ($perc >= 85 && $best_match["match_perc"] < $perc) {
|
||||
console_write ("INFO: New best match '{$hash}' at {$perc}%");
|
||||
$best_match = [
|
||||
"match_perc" => $perc,
|
||||
"student_hash" => $student_hash,
|
||||
"parent_data" => $parent
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ($best_match["match_perc"] == 0) {
|
||||
console_write ("WARN: Could not find parent for '{$firstname} {$lastname}'!");
|
||||
return null;
|
||||
}
|
||||
|
||||
$parent1_firstname = $best_match['parent_data']['parent1_firstname'];
|
||||
$parent1_lastname = $best_match['parent_data']['parent1_lastname'];
|
||||
$parent2_firstname = $best_match['parent_data']['parent2_firstname'];
|
||||
$parent2_lastname = $best_match['parent_data']['parent2_lastname'];
|
||||
console_write ("INFO: Found parent(s):");
|
||||
console_write ("INFO: First Parent: {$parent1_firstname} {$parent1_lastname}");
|
||||
console_write ("INFO: Second Parent: {$parent2_firstname} {$parent2_lastname}");
|
||||
|
||||
return [
|
||||
"parent1" => [
|
||||
"firstname" => $parent1_firstname,
|
||||
"lastname" => $parent1_lastname
|
||||
],
|
||||
"parent2" => [
|
||||
"firstname" => $parent2_firstname,
|
||||
"lastname" => $parent2_lastname
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
// Test if the two required input files have been specified
|
||||
if (isset ($argc) && $argc == 3) {
|
||||
$iserv_infile = $argv[1];
|
||||
$divis_infile = $argv[2];
|
||||
|
||||
if (! is_file ($iserv_infile)) {
|
||||
console_write ("CRIT: The IServ CSV file specified is not a file or does not exist.");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (! is_file ($divis_infile)) {
|
||||
console_write ("CRIT: The DiViS CSV file specified is not a file or does not exist.");
|
||||
exit (1);
|
||||
}
|
||||
} else {
|
||||
console_write ("Usage: ");
|
||||
console_write (" {$argv[0]} <iserv-user-export.csv> <divis-parents-export.csv>");
|
||||
console_write ("");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
// Read DiViS student <> parents mapped CSV to an array
|
||||
$parents_csv_fd = fopen ($divis_infile, "r");
|
||||
$divis_parents = [];
|
||||
while ($parent = fgetcsv ($parents_csv_fd)) {
|
||||
$student_firstname = $parent[0];
|
||||
$student_lastname = $parent[1];
|
||||
$student_hash = hash_student ($student_firstname, $student_lastname);
|
||||
|
||||
$divis_parents[$student_hash] = [
|
||||
"student_firstname" => $student_firstname,
|
||||
"student_lastname" => $student_lastname,
|
||||
"parent1_firstname" => $parent[2],
|
||||
"parent1_lastname" => $parent[3],
|
||||
"parent2_firstname" => $parent[4],
|
||||
"parent2_lastname" => $parent[5]
|
||||
];
|
||||
}
|
||||
fclose ($parents_csv_fd);
|
||||
|
||||
|
||||
// Iterate through all students in the IServ student export CSV
|
||||
$students_csv_fd = fopen ($iserv_infile, "r");
|
||||
$parents_to_export = [];
|
||||
$students_without_parents = [];
|
||||
fgets ($students_csv_fd); // Skip header in the CSV file
|
||||
while ($student = fgetcsv ($students_csv_fd, null, ";")) {
|
||||
// Skip non-student users
|
||||
if ($student[7] !== "Schüler") continue;
|
||||
|
||||
$student_firstname = $student[1];
|
||||
$student_lastname = $student[2];
|
||||
$student_userid = $student[8];
|
||||
$student_class = strtolower ($student[9]);
|
||||
$student_class = "klasse." . str_replace (" ", ".", $student_class);
|
||||
|
||||
$parents = find_parent_by_student ($student_firstname, $student_lastname);
|
||||
|
||||
if ($parents == null) {
|
||||
$students_without_parents[] = $student;
|
||||
} else {
|
||||
if ($parents["parent1"]["firstname"] && $parents["parent1"]["lastname"]) {
|
||||
$parents_to_export[] = [
|
||||
$parents["parent1"]["firstname"],
|
||||
$parents["parent1"]["lastname"],
|
||||
$student_userid,
|
||||
$student_class
|
||||
];
|
||||
} else {
|
||||
console_write ("WARN: Parent 1 dataset non-existant for student '{$student_firstname} {$student_lastname}'");
|
||||
}
|
||||
|
||||
if ($parents["parent2"]["firstname"] && $parents["parent2"]["lastname"]) {
|
||||
$parents_to_export[] = [
|
||||
$parents["parent2"]["firstname"],
|
||||
$parents["parent2"]["lastname"],
|
||||
$student_userid,
|
||||
$student_class
|
||||
];
|
||||
} else {
|
||||
console_write ("WARN: Parent 2 dataset non-existant for student '{$student_firstname} {$student_lastname}'");
|
||||
}
|
||||
}
|
||||
|
||||
console_write ("");
|
||||
}
|
||||
fclose ($students_csv_fd);
|
||||
|
||||
// Iterate through each exportable parent and convert them to a CSV line
|
||||
if (IS_CLI) {
|
||||
$out_fd = STDOUT;
|
||||
} else {
|
||||
$out_fd = fopen ("php://output", "w");
|
||||
header('Content-Type: text/csv');
|
||||
header('Content-Disposition: attachment; filename="Elternimport.csv";');
|
||||
}
|
||||
|
||||
foreach ($parents_to_export as $parent) {
|
||||
fputcsv($out_fd, $parent, ";");
|
||||
}
|
||||
|
||||
fclose ($out_fd);
|
||||
?>
|
||||
@ -0,0 +1,20 @@
|
||||
## DiViS Parents Export to IServ Elternverwaltung module import ##
|
||||
|
||||
This script takes two files, an IServ user export CSV and a DiViS student <> parents CSV
|
||||
and maps the parents to the IServ students, creating a third CSV file that can be imported
|
||||
into the IServ Elternverwaltung module.
|
||||
|
||||
The IServ user export CSV is expected to have the following columns:
|
||||
`Account;Vorname;Nachname;Status;"Erstellt am";"Erstellt von";"Interne ID";Benutzertyp;Import-ID;Klasse/Information;E-Mail-Adresse;Gruppen`
|
||||
|
||||
The student <> parents mapped CSV from DiViS should have the following columns:
|
||||
`"Schüler Vorname","Schüler Nachname","Eltern 1 Vorname","Eltern 1 Nachname","Eltern 2 Vorname","Eltern 2 Nachname"`
|
||||
|
||||
The CSV exported by this script will have the following columns:
|
||||
`Nachname;Vorname;Kind-ID;Klasse`
|
||||
|
||||
Status messages, information and errors are always written to `STDERR`, while the generated CSV
|
||||
will be exported to `STDOUT`, meaning you can redirect the `STDOUT` output of this script to a file
|
||||
to export the CSV and still be able to read any informational messages:
|
||||
|
||||
`$ php ./IServ_Elternimport_Divis.php iserv-user-export.csv divis-parents-export.csv > Parents_Import.csv`
|
||||
Loading…
Reference in New Issue