<?php
require_once("/home/data/httpd/eclipse-php8-classes/system/dbconnection_polls_rw.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/app.class.php");

/*******************************************************************************
 * Copyright (c) 2006 Eclipse Foundation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Denis Roy (Eclipse Foundation)- initial API and implementation
 *******************************************************************************/

#*****************************************************************************
#
# poll.php
#
# Author: 		Denis Roy
# Date:			2006-02-02
#
# Description: Class to use polls
#
#****************************************************************************

# prevent caching the host web page
if (ob_get_length() == 0) {
	header("Pragma: no-cache");
}


class Poll {
	var $poll_id		= 0;  #PK
	var $url			= "";
	var $poll_index		= 0;
	var $poll_title		= "";
	var $poll_action	= "";
	var $total_votes 	= 0;
	var $show_graph		= true;
	var $require_login	= false;
	var $bugzilla_id	= 0;
	var $error			= "";

	var $COOKIE_NAME = "ECLIPSE_INSTA_POLLS";

	# Initiate session
	var $Session = 		null;

	var $poll_options	= array(); # Array of PollOption objects


	/**
	 * Default constructor
	 * @param int $poll_index  to identify the poll index on a page (for multiple polls)
	 * @param string $poll_title
	 * @param string $id optional static id to identify the poll, instead of the URL, so it can be used anywhere
	 *
	 */
	function __construct($_poll_index, $_poll_title, $_id = null) {

		if($_id == null) {
			$this->url			= $_SERVER['SCRIPT_NAME'];
		}
		else {
			$this->url			= $_id;
		}
		$this->poll_index	= $_poll_index;
		$this->poll_title	= $_poll_title;
		$this->selectInsertPollID();  ## We need this before going on!


		if(isset($_POST['poll_action' . $_poll_index])) {
			$this->poll_action 	= $_POST['poll_action' . $_poll_index];
		}

		$App = new App();
		$this->Session = $App->useSession("optional");

		# Clean incoming
		$this->url = str_replace("..", "", $this->url);
		$this->url = str_replace(";", "", $this->url);

		if(!is_numeric($this->poll_index)) {
			$this->poll_index = 1;
		}

		# Determine the action to take.
		if($this->poll_action == "vote" && $this->isVoteable()) {

			if($this->require_login && $this->Session->getBugzillaID() <= 0) {
				# should not happen unless someone forces a post.
				$this->error = "You must be logged in to vote.";
			}

			if(isset($_POST['polloption']) && is_numeric($_POST['polloption'])) {
				# Save poll options!
				$this->updatePollCount();
			}
			else {
				$this->error = "You must choose an option to vote.";
				$this->poll_action = "";
			}
		}
	}


	/**
	 * fetch poll counts from the database
	 *
	 */
	function selectPollCounts() {
		# Get poll counts for poll id

		if($this->isValidPollID()) {

			$App = new App();

			$this->total_votes = 0;

		    $sql = "SELECT
						option_id,
						answer_count
		        	FROM
						poll_options
					WHERE poll_id = " . $this->poll_id;

		    $dbc = new DBConnectionPollsRW();
		    $dbh = $dbc->connect();

		    $result = mysqli_query($dbh, $sql);

			# find the right poll option, and increment the count
		    while($myrow = mysqli_fetch_array($result)) {
				for($i = 0; $i < count($this->poll_options); $i++) {
					$PollOption = $this->poll_options[$i];

					if($PollOption->option_id == $myrow['option_id']) {
						$PollOption->answer_count 	= $myrow['answer_count'];
						$this->total_votes 			+= $myrow['answer_count'];
						$this->poll_options[$i] 	= $PollOption;
						break;
					}
				}
		    }

		    $dbc->disconnect();
		    $dbh 	= null;
		    $dbc 	= null;
		    $result = null;
		    $myrow	= null;
		}
	}



	/**
	 * get poll id from db, or create if not found
	 */
	function selectInsertPollID() {

		if($this->isValidPollID()) {
			# Get poll ID from the database, or create one if it doesn't exist.
			$App = new App();

		    $sql = "SELECT
						POL.poll_id, POL.require_login
		        	FROM
						polls AS POL
					WHERE POL.url = " . $App->returnQuotedString($this->url) . "
						AND POL.poll_index = " . $this->poll_index;

		    $dbc = new DBConnectionPollsRW();
		    $dbh = $dbc->connect();

		    $result = mysqli_query($dbh, $sql);

		    if($myrow = mysqli_fetch_array($result)) {
		            $this->poll_id  		= $myrow["poll_id"];
		            $this->require_login	= $myrow['require_login'];
		    }
		    else {
		    	$sql = "INSERT INTO polls (
							poll_id,
							url,
							poll_index,
							first_seen)
						VALUES (
							NULL,
						" . $App->returnQuotedString($this->url) . ",
						" . $this->poll_index . ",
							CURDATE())";

				mysqli_query($dbh, $sql);
				$this->poll_id = mysqli_insert_id($dbh);

				# Perform house cleaning when creating new polls
				# Pass database handle to recycle the connection
				$this->flushOldPolls($dbh);
		    }

	    	$dbc->disconnect();
	    	$dbh 	= null;
	    	$dbc 	= null;
	    	$result = null;
	    	$myrow	= null;
		}
	}


	/**
	 * update poll count in db as a result of voting
	 */
	function updatePollCount() {

		if($this->isValidPollID()) {
			$App = new App();

			# if poll requires login, ensure client is logged in
			$Session = $this->Session;
			# echo "Session: " . $Session->getBugzillaID() . " Login req: " . $this->require_login; exit;
			if( ($this->require_login && $Session->getBugzillaID() > 0) || !$this->require_login) {

			    # we have the poll id, add a count
			    $poll_option = $_POST['polloption'];
				if(!is_numeric($poll_option)) {
					$poll_option = 1;
				}

				$dbc = new DBConnectionPollsRW();
			    $dbh = $dbc->connect();

				# Attempt to insert this user's vote in poll_login_votes.
				# If it fails, the user has already voted and we must not continue
				$error = false;
				if($this->require_login && $Session->getBugzillaID() > 0) {
					$sql = "INSERT INTO poll_login_votes (poll_id, bugzilla_id) VALUES (" . $this->poll_id . ", " . $Session->getBugzillaID() . ")";
					mysqli_query($dbh, $sql);

					if(mysqli_affected_rows($dbh) <= 0) {
						$error = true;
					}
				}

				if(!$error) {

			    	$sql = "UPDATE poll_options SET
								answer_count = answer_count + 1
							WHERE
								poll_id = " . $this->poll_id . "
								AND option_id = " . $poll_option;


					mysqli_query($dbh, $sql);

					if(mysqli_affected_rows($dbh) == 0) {
						# Update failed.  Issue insert statement
						$sql = "INSERT INTO poll_options (
									poll_id,
									option_id,
									answer_count) VALUES (
								" . $this->poll_id . ",
								" . $poll_option . ",
								1)";

						mysqli_query($dbh, $sql);
					}

					# put cookie on the browser to indicate user has voted
					$this->setCookie();
				}

			    $dbc->disconnect();
			    $dbh 	= null;
			    $dbc 	= null;
			    $result = null;
			    $myrow	= null;
			}
		}
	}


	/**
	 * set cookie on the browser to avoid ballot stuffers
	 */
	function setCookie() {
		/*
		 * Cookie is called ECLIPSE_INSTA_POLLS
		 * We put a csv list of poll id's the user has voted on
		 * all in one cookie.  Makes for fewer cookies on the browser
		 *
		 */

		$insta_polls = array();
		if(isset($_COOKIE[$this->COOKIE_NAME])) {
			$insta_polls = explode(",", $_COOKIE[$this->COOKIE_NAME]);
		}

		if(!is_numeric(array_search($this->poll_id, $insta_polls))) {
			$insta_polls[count($insta_polls)] = $this->poll_id;
		}

		setcookie($this->COOKIE_NAME, implode(",", $insta_polls), time()+604800, "/");
	}

	/**
	 * determine if user can vote
	 * @return bool
	 */
	function isVoteable() {

		/*
		 * isVoteable - used to determine if we display a form or just get the actual results
		 */

		$rValue = false;

		$insta_polls = array();
		if(isset($_COOKIE[$this->COOKIE_NAME])) {
			$insta_polls = explode(",", $_COOKIE[$this->COOKIE_NAME]);
		}

		if(!is_numeric(array_search($this->poll_id, $insta_polls))) {
			$rValue = true;
		}
		return $rValue;
	}


	/**
	 * Add a poll option to the object's array
	 * @param string $option_id a 12-character alphanumeric key to represent the option
	 * @param string $option_text
	 */
	function addOption($_option_id, $_option_text) {
		$PollOption = new PollOption();
		$PollOption->poll_id = $this->poll_id;
		$PollOption->option_id = $_option_id;
		$PollOption->option_text = str_replace("\"", "'", $_option_text);

		$this->poll_options[count($this->poll_options)] = $PollOption;

	}

	/**
	 * disable graph display
	 */
	function noGraph() {
		$this->show_graph = false;
	}

	/**
	 * disable anonymous polls
	 */
	function requireLogin() {

		# the constructor should have read this state from the DB
		# if we're setting requireLogin() and it's false in this object,
		# then this is the first time we've set requireLogin

		if(!$this->require_login) {

			$this->require_login = true;

			$App = new App();

		    $dbc = new DBConnectionPollsRW();
		    $dbh = $dbc->connect();
			$sql = "UPDATE polls SET require_login = 1 WHERE poll_id = " . $this->poll_id;

			mysqli_query($dbh, $sql);


	    	$dbc->disconnect();
	    	$dbh 	= null;
	    	$dbc 	= null;
		}
	}

	/**
	 * generate HTML required for the poll
	 * @return string
	 */
	function getHTML() {

		$rValue = "";

		if($this->poll_action == "" && $this->isVoteable()) {

			# display poll options

			$rValue = "<p><b>" . $this->poll_title . "</b><form method=\"post\">";
			$rValue .= "<input type=\"hidden\" name=\"poll_index\" value=\"" . $this->poll_index . "\" />";
			$rValue .= "<input type=\"hidden\" name=\"poll_action" . $this->poll_index . "\" value=\"vote\" />";
			for($i = 0; $i < count($this->poll_options); $i++) {
				$PollOption = $this->poll_options[$i];

				$rValue .= "<input type=\"radio\" name=\"polloption\" value=\"" . $PollOption->option_id . "\" />" . $PollOption->option_text . "<br />";
			}

			if($this->error != "") {
				$rValue .= "<font color='red'>Error: " . $this->error . "</font><br />";
			}

			$Session = $this->Session;

			if($Session->getBugzillaID() <= 0 && $this->require_login) {
				$rValue .= "You must be logged in to vote. Please login <a href='" . $Session->getLoginPageURL() . "'>here</a>.";
			}
			else {
				$rValue .= "<input type=\"submit\" value=\"Vote\" /></form></p>";
			}
		}

		if($this->poll_action == "vote" || !($this->isVoteable())) {

			# display poll options

			$this->selectPollCounts();

			$rValue = "<p><b>Results: " . $this->poll_title . "</b></p>";

			for($i = 0; $i < count($this->poll_options); $i++) {
				$PollOption = $this->poll_options[$i];

				$thisPercent = 0;

				if($this->total_votes > 0) {
					$thisPercent = round($PollOption->answer_count / $this->total_votes * 100);
				}
				$rValue .= $PollOption->option_text . ": " . $thisPercent . " %<br />";

				if($thisPercent > 0 && $this->show_graph) {
					$rValue .= "<table height=\"9\" cellpadding=\"0\" cellspacing=\"0\"><td class=\"poll_start\" width=\"3\"></td><td width=\"$thisPercent\" class=\"poll_bar\"></td><td width=\"3\" class=\"poll_end\" style=\"font-size: 2pt;\">&nbsp;</td></tr></table><br />";
				}
				else {
					$rValue .= "<br />";
				}

			}


			$rValue .= "<p><b>Total votes: </b>" . $this->total_votes . "</p>";
		}

		return $rValue;
	}


	/**
	 * determine if poll_id is valid
	 * @return bool
	 */
	function isValidPollID() {
		if(is_numeric($this->poll_id)) {
			return true;
		}
		else {
			return false;
		}
	}

	/**
	 * flush old polls and results.  Polls can still be used, this is simply for house cleaning.
	 * This code should be run automatically when a new poll is created.
	 * @param dbh $_dbh a writable database connection
	 *
	 */
	function flushOldPolls($_dbh) {

		# a Foreign Key constraint will enforce deletion of poll_options
		$sql = "DELETE FROM
					polls
				WHERE
					first_seen <=  DATE_SUB(CURDATE(), INTERVAL 3 MONTH)";

		mysqli_query($_dbh, $sql);

	    $_dbh 	= null;
	}
}

class PollOption {
	var $poll_id		= 0;  #PK
	var $option_id		= 0; #PK
	var $option_text	= "";
	var $answer_count	= 0;
}

?>