Skip to content
Snippets Groups Projects
election.php 5.84 KiB
Newer Older
Denis Walker's avatar
Denis Walker committed
<?php 
$smarty->assign("election_year", ELECTION_YEAR);
$smarty->assign("title", "Executive Election ".ELECTION_YEAR);

function display_ballot() {
	global $DB, $smarty, $output;

	require_once("../lib/members.php");
	$members = new Members;
	$role = $DB->GetAll("SELECT post FROM election_candidates GROUP BY post");

	foreach ($role as $post) {
		$candidate[$post['post']] = $DB->GetAll("SELECT username, manifesto_link FROM election_candidates WHERE post=? ORDER BY username ASC", $post['post']);

		$i=0;
		foreach ($candidate[$post['post']] as $person) {
			$details = $members->memberView($person['username']);
			$candidate[$post['post']][$i]['realname'] = $details[0]['cn'];
			if (empty($person['manifesto_link'])) $candidate[$post['post']][$i]['manifesto_link'] = ELECTION_NO_MANIFESTO;
			$i++;
		}
	}

	$smarty->assign("candidate", $candidate);
	$output = $smarty->fetch('election-vote.tpl');
}


if (!$session->loggedin) {
	# You can't vote if you're not logged in!
	trigger_error("You are not logged in.", E_USER_WARNING);
} else {
	# The election hasn't started yet
	if (strtotime('now') < strtotime(ELECTION_START)) trigger_error("The polling station is not yet open. Voting begins on ".date('l jS F, Y \a\t H:i', strtotime(ELECTION_START)).".");

	# The election is over - display the results
	else if (strtotime('now') > strtotime(ELECTION_END)) {
		require_once("../lib/members.php");
		$members = new Members;
		$role = $DB->GetAll("SELECT post FROM election_candidates GROUP BY post");

		foreach ($role as $post) {
			$candidate[$post['post']] = $DB->GetAll("SELECT username, manifesto_link FROM election_candidates WHERE post=?", $post['post']);
Denis Walker's avatar
Denis Walker committed

			$i=0;
			foreach ($candidate[$post['post']] as $person) {
				$details = $members->memberView($person['username']);
				$candidate[$post['post']][$i]['realname'] = $details[0]['cn'];
				if (empty($person['manifesto_link'])) $candidate[$post['post']][$i]['manifesto_link'] = ELECTION_NO_MANIFESTO;
				$candidate[$post['post']][$i]['votes'] = $DB->GetOne("SELECT count(username) FROM election_votes WHERE ".$post['post']."=?", array($person['username']));
				$i++;
			}
		}

		$smarty->assign("candidate", $candidate);
		$output = $smarty->fetch('election-results.tpl');		
	} else {
	# It's election time
		# Check the user hasn't already voted
		$vote_details = $DB->GetRow("SELECT time, ipaddress FROM election_votes WHERE username=?", $session->username);
		if (count($vote_details)>0) {
			trigger_error("You already voted on ".date('l jS F, Y \a\t H:i', strtotime($vote_details['time']))." from IP address ".$vote_details['ipaddress'].".", E_USER_WARNING);
			$output = "<p>Please email the Returning Officer at <a href=\"mailto:vote@sucs.org\">vote@sucs.org</a> with any queries.</p>\n<p>Once polling has closed on ".date('l jS F, Y \a\t H:i', strtotime(ELECTION_END)).", the election results will be available on this page.</p>";
		} else {
			if ($_POST['submit']=="Cast Votes") {
			# We have a ballot paper to process
				$output = "<h2>Thank you for your vote</h2>\n<p>You will shortly receive an email confirming your vote.</p>\n<p>Once polling has closed on ".date('l jS F, Y \a\t H:i', strtotime(ELECTION_END)).", the election results will be available on this page.</p>";
				
				# Establish which positions are contested
				$role = $DB->GetCol("SELECT post FROM election_candidates GROUP BY post HAVING count(username) > 1");
				
				$fail = FALSE;
				$invalid_candidate = FALSE;
				$abstain_count = 0;
				foreach ($role as $post) {
					if ($_POST[$post] == "abstain") $abstain_count++;					
					# check that we have a valid option selected
					if (!($DB->GetOne("SELECT username FROM election_candidates WHERE post=? AND username=?", array($post, $_POST[$post])) || $_POST[$post]=="abstain")) $fail = TRUE;
				}


				# Check their password first
				if ($session->check_pass($session->username, $_POST['vote_passwd'])) {
					if ($fail) {
					# Either no option or an invalid candidate was supplied
						trigger_error("An invalid option was selected in at least one ballot. Please try again.", E_USER_WARNING);
						display_ballot();
					} else {
					# User has abstained in all votes
						if ($abstain_count == count($role)) {
							trigger_error("You have not selected any candidates in any ballots.", E_USER_WARNING);
							display_ballot();
						} else {
						# The input is valid - record the vote
							$vote = array(
								'username' => $session->username,
								'time' => 'now',
								'ipaddress' => $_SERVER['REMOTE_ADDR']);

							# Email the Returning Officer
							$ro_message = "User: ".$vote['username']."\nIP:   ".$vote['ipaddress']."\n\n";

							# Email the voter with confirmation
							$voter_message = "Thank you for voting in the SUCS election this year. Here are the votes you cast:\n\n";

							foreach ($role as $post) {
								# Don't add votes up as we go
								# $DB->Execute("UPDATE election_candidates SET votes=votes+1 WHERE post=? AND username=?", array($post, $_POST[$post]));
								$vote[$post] = $_POST[$post];
								$ro_message .= ucfirst($post).": ".$_POST[$post]."\n";
								$voter_message .= ucfirst($post).": ".$_POST[$post]."\n";
							}
						
							$voter_message .= "\nResults of the election will be announced on ".date('l jS F, Y \a\t H:i', strtotime(ELECTION_END))." at http://sucs.org/Vote\n";
						
							$DB->AutoExecute("election_votes", $vote, 'INSERT');

							mail("SUCS Returning Officer <vote@sucs.org>", "[SUCS Election] Vote received from ".$vote['username'], $ro_message, "From: SUCS Election ".ELECTION_YEAR." <vote@sucs.org>");
							mail($session->fullname." <".$session->username."@sucs.org>", "[SUCS Election] Thanks For Voting", $voter_message, "From: SUCS Election ".ELECTION_YEAR." <vote@sucs.org>");
						}
					}
				} else {
					display_ballot();
				}				
			} else {
			# Display the ballot paper
				display_ballot();
			}
		}
	}
}

$smarty->assign("body", $output);

?>