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 ("MIN_NAME_MATCHING_PERCENTAGE", 85); 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 >= MIN_NAME_MATCHING_PERCENTAGE && $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]} "); 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); ?>