546 lines
18 KiB
PHP
546 lines
18 KiB
PHP
<?php
|
|
|
|
class Voters extends Base {
|
|
|
|
// Variables.
|
|
|
|
private $current_user_serial = 0;
|
|
private $current_user_id = "";
|
|
private $current_user_name = "";
|
|
private $current_user_email = "";
|
|
private $pagination_size = 20;
|
|
private $pagination_page = 1;
|
|
|
|
// =================
|
|
// Class Constructor
|
|
// =================
|
|
|
|
public function __construct() {
|
|
|
|
set_error_handler(array($this, "displayError"));
|
|
|
|
date_default_timezone_set(self::TIMEZONE);
|
|
|
|
$this->current_user_serial = $_SESSION[self::USER_SERIAL] ?? 0;
|
|
$this->current_user_id = $_SESSION[self::USER_ID] ?? "";
|
|
$this->current_user_name = $_SESSION[self::USER_NAME] ?? "";
|
|
$this->current_user_email = $_SESSION[self::USER_EMAIL] ?? "";
|
|
|
|
$this->pagination_page = $_SESSION[self::PAGINATION_PAGE] ?? 1;
|
|
}
|
|
|
|
// =============
|
|
// Manage Voters
|
|
// =============
|
|
|
|
public function manageVoters() {
|
|
|
|
$voters = $this->getVotersPage();
|
|
$popovers = (new Popovers())->getPopovers();
|
|
|
|
$XML = $this->mergeXML($voters, "<XML/>");
|
|
$XML = $this->mergeXML($popovers, $XML);
|
|
|
|
// echo $XML;
|
|
// die();
|
|
|
|
$content = $this->applyXSL($XML, $this->getXSL("manageVoters"));
|
|
|
|
$this->displayContent($content);
|
|
}
|
|
|
|
// =============
|
|
// Voter Summary
|
|
// =============
|
|
|
|
public function voterSummary() {
|
|
|
|
$voter_serial = filter_input(INPUT_POST, "voter_serial", FILTER_SANITIZE_NUMBER_INT) ?: 0;
|
|
|
|
$voter = $this->getVoter($voter_serial);
|
|
|
|
if ($voter->count() == 0) {
|
|
$this->logError("Invalid Voter ({$voter_serial}). " . __METHOD__);
|
|
}
|
|
|
|
$XML = $this->mergeXML($voter, "<XML/>");
|
|
|
|
$content = $this->applyXSL($XML, $this->getXSL("voterSummary"));
|
|
$this->displayContent($content);
|
|
}
|
|
|
|
// =========
|
|
// Add Voter
|
|
// =========
|
|
|
|
public function addVoter() {
|
|
|
|
$step = filter_input(INPUT_POST, "step") ?: "prompt";
|
|
|
|
switch ($step) {
|
|
|
|
case "prompt":
|
|
|
|
$content = $this->applyXSL("", $this->getXSL("addVoter"));
|
|
|
|
$this->displayContent($content);
|
|
|
|
break;
|
|
|
|
case "add":
|
|
|
|
$voter_name = filter_input(INPUT_POST, "voter_name") ?: "";
|
|
$voter_classes = filter_input(INPUT_POST, "voter_classes") ?: "";
|
|
$voter_active = filter_input(INPUT_POST, "voter_active", FILTER_VALIDATE_BOOLEAN) ?: false;
|
|
|
|
$SQL = "insert into voters
|
|
|
|
( voter_name,
|
|
voter_classes,
|
|
voter_active,
|
|
voter_creator,
|
|
voter_created )
|
|
|
|
VALUES ( :voter_name,
|
|
:voter_classes,
|
|
:voter_active,
|
|
:voter_creator,
|
|
:voter_created )";
|
|
|
|
$statement = $this->connect()->prepare($SQL);
|
|
|
|
$statement->bindValue(":voter_name", $voter_name);
|
|
$statement->bindValue(":voter_classes", $voter_classes);
|
|
$statement->bindValue(":voter_active", $voter_active, PDO::PARAM_BOOL);
|
|
$statement->bindValue(":voter_creator", $this->current_user_name);
|
|
$statement->bindValue(":voter_created", $this->getTimestamp());
|
|
|
|
$statement->execute();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
$this->displayHome();
|
|
}
|
|
}
|
|
|
|
// =============
|
|
// Delete Voter
|
|
// =============
|
|
|
|
public function deleteVoter() {
|
|
|
|
$voter_serial = filter_input(INPUT_POST, "voter_serial", FILTER_SANITIZE_NUMBER_INT) ?: 0;
|
|
|
|
$voter = $this->getVoter($voter_serial);
|
|
|
|
if ($voter->count() == 0) {
|
|
$this->logError("Invalid Voter ({$voter_serial}). " . __METHOD__);
|
|
}
|
|
|
|
$SQL = "delete from voters
|
|
where voter_serial = {$voter_serial}";
|
|
|
|
$this->executeSQL($SQL);
|
|
}
|
|
|
|
// ============================
|
|
// Determine if a Voter exists
|
|
// ============================
|
|
|
|
public function voterExists() {
|
|
|
|
$voter_serial = filter_input(INPUT_POST, "voter_serial", FILTER_SANITIZE_NUMBER_INT) ?: 0;
|
|
$voter_name = filter_input(INPUT_POST, "voter_name") ?: "";
|
|
|
|
$SQL = "select voter_serial
|
|
from view_voters
|
|
where voter_serial != :voter_serial
|
|
and lower(voter_name) = :voter_name";
|
|
|
|
$statement = $this->connect()->prepare($SQL);
|
|
|
|
$statement->bindValue(":voter_serial", $voter_serial);
|
|
$statement->bindValue(":voter_name", strtolower($voter_name));
|
|
|
|
$statement->execute();
|
|
|
|
$recordset = $statement->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$exists = (count($recordset) > 0) ? true : false;
|
|
|
|
echo json_encode($exists);
|
|
}
|
|
|
|
// ======================================
|
|
// Determine if a Voter is Active (AJAX)
|
|
// ======================================
|
|
|
|
public function voterActive() {
|
|
|
|
$voter_serial = filter_input(INPUT_POST, "voter_serial", FILTER_SANITIZE_NUMBER_INT) ?: 0;
|
|
|
|
$active = false;
|
|
|
|
$SQL = "select workorder_voter
|
|
from workorders
|
|
where workorder_voter = {$voter_serial}
|
|
limit 1";
|
|
|
|
$workorders = $this->getTable("workorders", $SQL);
|
|
|
|
$active = ($workorders->count() > 0) ? true : false;
|
|
|
|
echo json_encode($active);
|
|
}
|
|
|
|
// =============
|
|
// Edit a Voter
|
|
// =============
|
|
|
|
public function editVoter() {
|
|
|
|
$step = filter_input(INPUT_POST, "step") ?: "prompt";
|
|
|
|
switch ($step) {
|
|
|
|
case "prompt":
|
|
|
|
$voter_serial = filter_input(INPUT_POST, "voter_serial", FILTER_SANITIZE_NUMBER_INT) ?: 0;
|
|
|
|
$voter = $this->getVoter($voter_serial);
|
|
|
|
if ($voter->count() == 0) {
|
|
$this->logError("Invalid Voter ({$voter_serial}). " . __METHOD__);
|
|
}
|
|
|
|
$XML = $this->mergeXML($voter, "<XML/>");
|
|
|
|
$content = $this->applyXSL($XML, $this->getXSL("editVoter"));
|
|
|
|
$this->displayContent($content);
|
|
|
|
break;
|
|
|
|
case "update":
|
|
|
|
$voter_serial = filter_input(INPUT_POST, "voter_serial", FILTER_SANITIZE_NUMBER_INT) ?: 0;
|
|
$voter_name = filter_input(INPUT_POST, "voter_name") ?: "";
|
|
$voter_classes = filter_input(INPUT_POST, "voter_classes") ?: "";
|
|
$voter_active = filter_input(INPUT_POST, "voter_active", FILTER_VALIDATE_BOOLEAN) ?: false;
|
|
$voter_default = filter_input(INPUT_POST, "voter_default", FILTER_VALIDATE_BOOLEAN) ?: false;
|
|
|
|
// Verify the Voter
|
|
|
|
$voter = $this->getVoter($voter_serial);
|
|
|
|
if ($voter->count() == 0) {
|
|
$this->logError("Invalid Voter ({$voter_serial}). " . __METHOD__);
|
|
}
|
|
|
|
$SQL = "update voters
|
|
set voter_name = :voter_name,
|
|
voter_classes = :voter_classes,
|
|
voter_active = :voter_active,
|
|
voter_default = :voter_default,
|
|
voter_changer = :voter_changer,
|
|
voter_changed = :voter_changed
|
|
where voter_serial = :voter_serial";
|
|
|
|
$statement = $this->connect()->prepare($SQL);
|
|
|
|
$statement->bindValue(":voter_serial", $voter_serial);
|
|
$statement->bindValue(":voter_name", $voter_name);
|
|
$statement->bindValue(":voter_classes", $voter_classes);
|
|
$statement->bindValue(":voter_active", $voter_active, PDO::PARAM_BOOL);
|
|
$statement->bindValue(":voter_default", $voter_default, PDO::PARAM_BOOL);
|
|
$statement->bindValue(":voter_changer", $this->current_user_name);
|
|
$statement->bindValue(":voter_changed", $this->getTimestamp());
|
|
|
|
$statement->execute();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
$this->displayHome();
|
|
}
|
|
}
|
|
|
|
// ================================
|
|
// Return an Active Voters Object
|
|
// ================================
|
|
|
|
public function getActiveVoters() {
|
|
|
|
$SQL = "select view_voters.*
|
|
from view_voters
|
|
where voter_active is true";
|
|
|
|
return $this->getTable("voters", $SQL);
|
|
}
|
|
|
|
// -------------------------
|
|
// Return the Default Voter
|
|
// -------------------------
|
|
|
|
public function getDefaultVoter() {
|
|
|
|
$SQL = "select voter_serial
|
|
from view_voters
|
|
where voter_default is true";
|
|
|
|
return $this->getTable("voters", $SQL);
|
|
}
|
|
|
|
// =======================
|
|
// Return an Voter Object
|
|
// =======================
|
|
|
|
public function getVoter($voter_serial = 0) {
|
|
|
|
$SQL = "select view_voters.*
|
|
from view_voters
|
|
where voter_serial = {$voter_serial}";
|
|
|
|
return $this->getTable("voters", $SQL);
|
|
}
|
|
|
|
// ===========================
|
|
// Return a Voters Object
|
|
// ===========================
|
|
|
|
public function getVoters() {
|
|
|
|
$SQL = "select view_voters.*
|
|
from view_voters";
|
|
|
|
return $this->getTable("voters", $SQL);
|
|
}
|
|
|
|
// ============================
|
|
// Return a Voters Page Object
|
|
// ============================
|
|
|
|
public function getVotersPage() {
|
|
|
|
// Find Criteria
|
|
$find_voter = filter_input(INPUT_POST, "find_voter") ?: "";
|
|
$find_voter = trim($this->sanitizeString($find_voter));
|
|
|
|
$connection = $this->connect();
|
|
|
|
// ==========
|
|
// Pagination
|
|
// ==========
|
|
|
|
$pagination = filter_input(INPUT_POST, "pagination") ?: "";
|
|
$count = 0;
|
|
|
|
/*
|
|
* Blank admin load:
|
|
* - keep the count
|
|
*
|
|
* Search:
|
|
* - skip the full count because it is too expensive
|
|
*/
|
|
|
|
if ($find_voter === "") {
|
|
|
|
$SQL = "select count(*) as count
|
|
from voters";
|
|
|
|
$statement = $connection->prepare($SQL);
|
|
$statement->execute();
|
|
|
|
$recordset = $statement->fetch(PDO::FETCH_ASSOC);
|
|
$count = $recordset ? (int) $recordset["count"] : 0;
|
|
|
|
$max_page = max((int) ceil($count / $this->pagination_size), 1);
|
|
} else {
|
|
|
|
// For searches, do not run an expensive count query
|
|
$max_page = max((int) $this->pagination_page, 1);
|
|
}
|
|
|
|
switch ($pagination) {
|
|
|
|
case "first":
|
|
$this->pagination_page = 1;
|
|
break;
|
|
|
|
case "previous":
|
|
$this->pagination_page = max(($this->pagination_page - 1), 1);
|
|
break;
|
|
|
|
case "next":
|
|
$this->pagination_page = ($this->pagination_page + 1);
|
|
break;
|
|
|
|
case "last":
|
|
$this->pagination_page = $max_page;
|
|
break;
|
|
|
|
default:
|
|
$this->pagination_page = max((int) $this->pagination_page, 1);
|
|
break;
|
|
}
|
|
|
|
$offset = (($this->pagination_page - 1) * $this->pagination_size);
|
|
|
|
// ==========
|
|
// Data Query
|
|
// ==========
|
|
|
|
if ($find_voter === "") {
|
|
|
|
/*
|
|
* Blank load:
|
|
* - page voters first
|
|
* - then join the tiny lookup tables to only those page rows
|
|
*/
|
|
|
|
$SQL = "select v.voter_serial,
|
|
v.voter_id,
|
|
v.voter_name_first,
|
|
v.voter_name_last,
|
|
v.voter_residence_address_1,
|
|
v.voter_residence_city,
|
|
v.voter_residence_state,
|
|
v.voter_residence_zipcode,
|
|
v.voter_gender,
|
|
racecodes.racecode_description as voter_race_code_verbose,
|
|
politicalparties.politicalparty_name as voter_party_affiliation_verbose
|
|
from (
|
|
select voter_serial,
|
|
voter_id,
|
|
voter_name_first,
|
|
voter_name_last,
|
|
voter_residence_address_1,
|
|
voter_residence_city,
|
|
voter_residence_state,
|
|
voter_residence_zipcode,
|
|
voter_gender,
|
|
voter_race,
|
|
voter_party_affiliation
|
|
from voters
|
|
order by voter_serial
|
|
limit :limit
|
|
offset :offset
|
|
) v
|
|
left join racecodes
|
|
on racecodes.racecode_code = v.voter_race
|
|
left join politicalparties
|
|
on politicalparties.politicalparty_code = v.voter_party_affiliation
|
|
order by v.voter_serial";
|
|
|
|
$statement = $connection->prepare($SQL);
|
|
$statement->bindValue(":limit", (int) ($this->pagination_size + 1), PDO::PARAM_INT);
|
|
$statement->bindValue(":offset", (int) $offset, PDO::PARAM_INT);
|
|
} else {
|
|
|
|
/*
|
|
* Search:
|
|
* - use UNION so each branch can use its own index
|
|
* - then join back to voters
|
|
* - then join lookup tables
|
|
*/
|
|
|
|
$SQL = "select v.voter_serial,
|
|
v.voter_id,
|
|
v.voter_name_first,
|
|
v.voter_name_last,
|
|
v.voter_residence_address_1,
|
|
v.voter_residence_city,
|
|
v.voter_residence_state,
|
|
v.voter_residence_zipcode,
|
|
v.voter_gender,
|
|
racecodes.racecode_description as voter_race_code_verbose,
|
|
politicalparties.politicalparty_name as voter_party_affiliation_verbose
|
|
from (
|
|
select matches.voter_serial,
|
|
voters.voter_id,
|
|
voters.voter_name_first,
|
|
voters.voter_name_last,
|
|
voters.voter_residence_address_1,
|
|
voters.voter_residence_city,
|
|
voters.voter_residence_state,
|
|
voters.voter_residence_zipcode,
|
|
voters.voter_gender,
|
|
voters.voter_race,
|
|
voters.voter_party_affiliation
|
|
from (
|
|
select voter_serial
|
|
from voters
|
|
where voter_name_first like :find_words_first
|
|
|
|
union
|
|
|
|
select voter_serial
|
|
from voters
|
|
where voter_name_last like :find_words_last
|
|
|
|
union
|
|
|
|
select voter_serial
|
|
from voters
|
|
where voter_id like :find_words_id
|
|
) matches
|
|
join voters
|
|
on voters.voter_serial = matches.voter_serial
|
|
order by voters.voter_name_last, voters.voter_name_first, voters.voter_serial
|
|
limit :limit
|
|
offset :offset
|
|
) v
|
|
left join racecodes
|
|
on racecodes.racecode_code = v.voter_race
|
|
left join politicalparties
|
|
on politicalparties.politicalparty_code = v.voter_party_affiliation
|
|
order by v.voter_name_last, v.voter_name_first, v.voter_serial";
|
|
|
|
$statement = $connection->prepare($SQL);
|
|
$statement->bindValue(":find_words_first", $find_voter . "%", PDO::PARAM_STR);
|
|
$statement->bindValue(":find_words_last", $find_voter . "%", PDO::PARAM_STR);
|
|
$statement->bindValue(":find_words_id", $find_voter . "%", PDO::PARAM_STR);
|
|
$statement->bindValue(":limit", (int) $this->pagination_size, PDO::PARAM_INT);
|
|
$statement->bindValue(":offset", (int) $offset, PDO::PARAM_INT);
|
|
}
|
|
|
|
$statement->execute();
|
|
|
|
$voters = $this->getTableXML("voters", $statement);
|
|
|
|
// ============================
|
|
// Insert Pagination Attributes
|
|
// ============================
|
|
|
|
if ($find_voter === "") {
|
|
|
|
$start = $count > 0 ? ($offset + 1) : 0;
|
|
$end = min($count, ($offset + $this->pagination_size));
|
|
} else {
|
|
|
|
/*
|
|
* Search total count is intentionally skipped.
|
|
* We only know what is on the current page.
|
|
*/
|
|
$rows_on_page = $statement->rowCount();
|
|
$count = 0;
|
|
$start = $rows_on_page > 0 ? ($offset + 1) : 0;
|
|
$end = $offset + $rows_on_page;
|
|
}
|
|
|
|
$voters->addAttribute("count", $count);
|
|
$voters->addAttribute("start", $start);
|
|
$voters->addAttribute("end", $end);
|
|
$voters->addAttribute("page", $this->pagination_page);
|
|
|
|
$_SESSION[self::PAGINATION_PAGE] = $this->pagination_page;
|
|
|
|
return $voters;
|
|
}
|
|
}
|
|
|
|
?>
|