Files
votervue/classes/imports/Import_VoterRecords.php
T
2026-07-03 15:46:56 -04:00

277 lines
9.5 KiB
PHP

<?php
// ====================
// Import Voter Records
// ====================
class Import_VoterRecords {
// Variables
private $log = "";
private $settings = "";
private $connection = "";
// ==================
// Class Constructor.
// ==================
public function __construct() {
// Open the Log
$this->log = fopen("../scripts/import_voter_records.log", "w+");
if ($this->log === false) {
error_log("VoterVue : Unable to open log file");
exit();
}
$this->log(str_repeat("*", 50));
// Get Settings
$this->settings = new SimpleXMLElement((file_exists("../xml/settings.xml") ? file_get_contents("../xml/settings.xml") : "<settings/>"));
if ($this->settings->count() === 0) {
error_log("VoterVue : Unable to initialize settings");
exit();
}
// Open Database Connections
$this->connection = $this->connect();
}
// ================================================
// Return a New DEC-DR Database Database Connection
// ================================================
public function connect() {
try {
$host = (string) $this->settings->DatabaseServer;
$database = (string) $this->settings->DatabaseName;
$user = (string) $this->settings->DatabaseUser;
$password = (string) $this->settings->DatabasePassword;
$connection = new PDO("mysql:host={$host};dbname={$database};charset=utf8", $user, $password);
$connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException | Exception $e) {
trigger_error($e->getMessage());
}
return $connection;
}
// =============================
// Log a message to the Log File
// =============================
private function log($message = "") {
fwrite($this->log, date("Y-m-d H:i A") . " : " . "{$message} \n");
}
// ===================
// Process Parcel Data
// ===================
public function process() {
$this->log("Starting Voter Record Import Process");
$this->importVoterRecords();
$this->log("Voter Record Import Process Complete");
}
// ====================
// Import Voter Records
// ====================
private function importVoterRecords() {
$this->log("Processing Voter Records");
$voter_record_file_path = '/data/ositssrc/projects/votervue_raw_data/20251210_Voter_Detail_20251210';
$voter_history_files = glob("{$voter_record_file_path}/*.txt");
sort($voter_history_files);
$SQL = "INSERT INTO voters
( voter_county_code,
voter_id,
voter_name_last,
voter_name_suffix,
voter_name_first,
voter_name_middle,
voter_public_records_exempt,
voter_residence_address_1,
voter_residence_address_2,
voter_residence_city,
voter_residence_state,
voter_residence_zipcode,
voter_mailing_address_1,
voter_mailing_address_2,
voter_mailing_address_3,
voter_mailing_city,
voter_mailing_state,
voter_mailing_zipcode,
voter_mailing_country,
voter_gender,
voter_race,
voter_birth_date,
voter_registration_date,
voter_party_affiliation,
voter_precinct,
voter_precinct_group,
voter_precinct_split,
voter_precinct_suffix,
voter_voter_status,
voter_congressional_district,
voter_house_district,
voter_senate_district,
voter_county_commission_district,
voter_school_board_district,
voter_daytime_area_code,
voter_daytime_phone_number,
voter_daytime_phone_extension,
voter_email_address )
VALUES
( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ? )";
$statement = $this->connection->prepare($SQL);
$counter = 0;
foreach ($voter_history_files as $file) {
$this->log("Importing file: {$file}");
$voterhistory = fopen($file, 'r');
if ($voterhistory === false) {
$this->log("Unable to open {$file}");
echo "❌ Unable to open {$file}\n";
continue;
}
$lineNum = 0;
while (($line = fgets($voterhistory)) !== false) {
$lineNum++;
$line = rtrim($line, "\r\n");
if ($line === '') {
continue;
}
$cols = explode("\t", $line);
if (count($cols) < 38) {
$this->log("Skipped malformed line {$lineNum} in {$file} (cols=" . count($cols) . ")");
continue;
}
[$county_code, $voter_id, $name_last, $name_suffix, $name_first, $name_middle, $public_exempt, $res_addr1, $res_addr2, $res_city, $res_state, $res_zip,
$mail_addr1, $mail_addr2, $mail_addr3, $mail_city, $mail_state, $mail_zip, $mail_country, $gender, $race, $birth_date, $reg_date, $party, $precinct,
$precinct_group, $precinct_split, $precinct_suffix, $status, $cd, $hd, $sd, $ccd, $sbd, $area, $phone, $ext, $email] = $cols;
try {
$statement->execute([
$this->normalize($county_code),
$this->normalize($voter_id),
$this->normalize($name_last),
$this->normalize($name_suffix),
$this->normalize($name_first),
$this->normalize($name_middle),
$this->normalize($public_exempt),
$this->normalize($res_addr1),
$this->normalize($res_addr2),
$this->normalize($res_city),
$this->normalize($res_state),
$this->normalize($res_zip),
$this->normalize($mail_addr1),
$this->normalize($mail_addr2),
$this->normalize($mail_addr3),
$this->normalize($mail_city),
$this->normalize($mail_state),
$this->normalize($mail_zip),
$this->normalize($mail_country),
$this->normalize($gender),
$this->normalize($race),
$this->parseDate($birth_date),
$this->parseDate($reg_date),
$this->normalize($party),
$this->normalize($precinct),
$this->normalize($precinct_group),
$this->normalize($precinct_split),
$this->normalize($precinct_suffix),
$this->normalize($status),
$this->normalize($cd),
$this->normalize($hd),
$this->normalize($sd),
$this->normalize($ccd),
$this->normalize($sbd),
$this->normalize($area),
$this->normalize($phone),
$this->normalize($ext),
$this->normalize($email)
]);
$counter++;
if (($counter % 10) === 0) {
$this->log("Processed {$counter} records...");
}
} catch (Throwable $e) {
$this->log("Insert failed {$file}:{$lineNum} - " . $e->getMessage());
echo "❌ Insert failed {$file}:{$lineNum}{$e->getMessage()}\n";
}
}
fclose($voterhistory);
}
$this->log("Completed voter import. Total records processed: {$counter}");
}
// =================================
// Return a $this->normalized String
// =================================
private function normalize(?string $value): ?string {
$value = trim((string) $value);
return ($value === '' || $value === '*') ? null : $value;
}
// ====================
// Return a Parsed Date
// ====================
private function parseDate(?string $value): ?string {
$value = $this->normalize($value);
if ($value === null) {
return null;
}
$dt = DateTime::createFromFormat('m/d/Y', $value);
return $dt ? $dt->format('Y-m-d') : null;
}
}
?>