IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Poll.php

práce s jednou anketou

php

<?php

class Poll
{

	/** @var array */
	private $data = array();
	
	/** @var bool */
	private $exists;
	
	/** @var Database */
	private $db;
	
	
	const COOKIE_VOTE = "devbook_poll_vote";
	
	
	/**
	 * @param int|NULL
	 * @param bool
	 */
	public function __construct($id = NULL)
	{
		$this->db = Database::getInstance();
		if ($id !== NULL) {
			$query = $this->db->prepare("
				SELECT `question`
				FROM `poll`
				WHERE `id` = ?
				LIMIT 1
			");
			$query->execute(array($id));
			$data = $query->fetch(PDO::FETCH_ASSOC);

			if ($data) {
				$data["id"] = $id;
				$data["answers"] = array();
				
				$query = $this->db->prepare("
					SELECT `id`, `text`, `count`, `color`
					FROM `poll_answer`
					WHERE `poll_id` = ?
				");
				$query->execute(array($id));
				$answers = $query->fetchAll();
				
				foreach ($answers as $answer) {
					$data["answers"][] = array(
						"id" => $answer["id"],
						"answer" => $answer["text"],
						"count" => $answer["count"],
						"color" => $answer["color"]
					);
				}
				
				$this->data = $data;
				$this->exists = TRUE;
			} else {
				$this->exists = FALSE;
			}
		}
	}
	
	
	/**
	 * @param string
	 * @param mixed
	 * @throws PollException
	 */
	public function __set($name, $value)
	{
		throw new PollException("Do třídy 'Poll' nelze ukládat nové hodnoty.");
	} 
	
	
	/**
	 * @param string
	 * @return mixed
	 */
	public function __get($key)
	{
		return $this->data[$key];
	}
	
	
	/**
	 * @param string
	 */
	public function __isset($key)
	{
		return isset($this->data[$key]);
	}
	
	
	/**
	 * @param string
	 * @throws PollException
	 */
	public function __unset($key)
	{
		throw new PollException("Že třídy 'Poll' nelze mazat žádné hodnoty.");
	} 
	
	
	/**
	 * @return array
	 */
	public function getData()
	{
		return $this->data;
	}
	
	
	/**
	 * @param string
	 * @param array
	 * @param array
	 * @throws PollException
	 */
	public function create($question, array $answers, array $colors)
	{
		if ($question === "") {
			throw new PollException("Nebyla zadána otázka.");
		}
		if (count($answers) < 2) {
			throw new PollException("Anketa musí mít minimálně dvě odpovědi.");
		}
		
		$data = array();
		for ($i = 0; $i < count($answers); $i++) {
			if (!empty($answers[$i]) && !empty($colors[$i])) {
				$data[] = array(
					"id" => $answers[$i],
					"color" => $colors[$i]
				);
			}	
		}
		
		if (count($data) < 2) {
			throw new PollException("Anketa musí mít minimálně dvě odpovědi.");
		}
		
		$this->db->beginTransaction();
		$query = $this->db->prepare("
			INSERT INTO `poll` (`id`, `question`)
			VALUES (?, ?)
		");
		$query->execute(array(NULL, $question));
		$id = $this->db->lastInsertId();
		
		foreach ($data as $answer) {
			$query = $this->db->prepare("
				INSERT INTO `poll_answer` (`id`, `poll_id`, `text`, `count`, `color`)
				VALUES (?, ?, ?, ?, ?)
			");
			$query->execute(array(NULL, $id, $answer["id"], 0, $answer["color"]));
		}
		
		$this->db->commit();
	}
	
	
	/**
	 * @return bool
	 */
	public function exists()
	{
		return $this->exists;
	}
	
	
	/**
	 * @param string|NULL
	 * @param bool
	 * @return string
	 */
	public function getForm($action = NULL, $createJS = TRUE)
	{
		if ($action === NULL) {
			$action = $_SERVER["REQUEST_URI"];
		}
		
		$return = <<<EOT
<form action="{$action}" method="post">
	<table>
		<tr><th><label for="add_question">Otázka</label></th></tr>
		<tr><td><input type="text" id="add_question" name="question" size="40" required></td></tr>
		
		<tr><td><a href="javascript:addAnswer()">Přidat odpověď</a></td></tr>
		<tr><td id="answers"></td></tr>
		
		<tr><td><input type="submit" value="Vytvořit"></td></tr>
	</table>
</form>
EOT;

		if ($createJS) {
			$return .= <<<EOT
<script type="text/javascript">

var numAnswers = 0;

function addAnswer()
{
	numAnswers++;
	var row = document.getElementById("answers");
	var inputAnswer = document.createElement("input");
	inputAnswer.type = "text";
	inputAnswer.name = "answers[]";
	inputAnswer.size = 40;
	inputAnswer.required = true;
	
	var inputColor = document.createElement("input");
	inputColor.type = "text";
	inputColor.name = "colors[]";
	inputColor.pattern = "^#[a-zA-Z0-9]{6}$";
	inputColor.required = true;
	inputColor.size = 7;
	inputColor.maxLength = 7;
	
	var answer = document.createElement("span");
	answer.innerHTML += numAnswers + ". ";
	answer.appendChild(inputAnswer);
	answer.innerHTML += " Barva: ";
	answer.appendChild(inputColor);
	answer.innerHTML += "<br />";
	
	row.appendChild(answer);
}

</script>		
EOT;
		}
	
		return $return;
	}
	
	
	/**
	 * @param array
	 * @return array
	 */
	private function getAnswersPercentually($answers)
	{
		$return = array();
		$numAnswered = 0;
		foreach ($answers as $answer) {
			$numAnswered += $answer["count"];
		}
		
		foreach ($answers as $answer) {
			$percentual = 0;
			if ($answer["count"] > 0) {
				$percentual = $answer["count"] / $numAnswered * 100;
			}
			$return[$answer["id"]] = number_format($percentual, 2);
		}
		
		return $return;
	}
	
	
	/**
	 * @param array
	 * @param int
	 * @return float
	 */
	private function getAnswerPercentually($answers, $answerID)
	{
		foreach ($answers as $_answerID => $answer) {
			if ($_answerID == $answerID) {  // intentionally ==
				return $answer;
			}
		}
	}
	
	
	/**
	 * @param int
	 * @return int
	 */
	public function getPollIdByAnswer($id)
	{
		$query = $this->db->prepare("
			SELECT `poll_id` FROM `poll_answer`
			WHERE `id` = ?
			LIMIT 1
		");
		$query->execute(array($id));
		
		return (int) $query->fetchColumn();
	}
	
	
	/**
	 * @param int
	 * @throws PollException
	 */
	public function vote($answerID)
	{
		if ($this->userAlreadyVoted($answerID)) {
			throw new PollException("V této anketě jste již hlasoval.");
		}

		$query = $this->db->prepare("
			UPDATE `poll_answer`
			SET `count` = `count` + 1
			WHERE `id` = ?
		");
		$query->execute(array($answerID));
		
		if ($query->rowCount() === 0) {
			throw new PollException("Nebylo možné odeslat hlas.");
		}
		
		$cookieName = self::COOKIE_VOTE . "_" . $answerID;
		setCookie($cookieName, 1, time() + 60 * 60 * 24 * 30 * 10);
	}
	
	
	/**
	 * @param int
	 * @return bool
	 */
	private function userAlreadyVoted($answerID)
	{
		$cookieName = self::COOKIE_VOTE . "_" . $answerID;
		if (isset($_COOKIE[$cookieName])) {
			return TRUE;
		}
		
		return FALSE;
	}
	
	
	/**
	 * @return string
	 * @throws PollException
	 */
	public function __toString()
	{
		if ($this->exists) {
			$return = '
				<div class="poll" id="poll_' . $this->data["id"] . '">
					<div class="question">
						' . $this->data["question"] . '
					</div>
					<div class="answers">
			';
			$answers = $this->data["answers"];
			$percentualAnswers = $this->getAnswersPercentually($answers, $this->data["answers"]);
			
			$userVoted = FALSE;
			$voteMessage = "";
			foreach ($answers as $answer) {
				if ($this->userAlreadyVoted($answer["id"])) {
					$userVoted = TRUE;
				}
				if (isset($_SESSION["poll_answer_" . $answer["id"]])) {
					$voteMessage = "<br /><br />" . $_SESSION["poll_answer_" . $answer["id"]];
					unset($_SESSION["poll_answer_" . $answer["id"]]);
				}
			}
			
			$return .= '<table class="answers">';
			
			foreach ($answers as $answer) {
				$percent = $this->getAnswerPercentually($percentualAnswers, $answer["id"]);
				
				$answerText = $answer["answer"];
				if (!$userVoted) {
					$answerText = '<a href="?vote&id=' . $answer["id"] . '">' . $answer["answer"] . '</a>';
				}
				
				$return .= '
					<tr><td>' . $answerText . '</td><td></td></tr>
					<tr>
						<td style="width:200px;border:1px solid #000;">
							<div style="background-color:' . $answer["color"] . ';width:' . $percent . '%;height:20px;"></div>
						</td>
						<td class="votes">' . $percent . '% (' . $answer["count"] . ')
						</td>
					</tr>
				';
			}
			
			$return .= "
						</table>
					</div>
					" . $voteMessage . "
				</div>
			";
			
			return $return;
		}

		return "";
	}
}

Neformátovaný

Přidáno: 7.8.2013
Expirace: Neuvedeno

Aktivity