implement multiple questions for Questtype ?multiple choice?

This commit is contained in:
coderkun 2014-04-03 01:16:43 +02:00
commit 25c2eab459
4 changed files with 247 additions and 65 deletions

View file

@ -34,14 +34,23 @@
*/
public function saveAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers)
{
// Get questions
$questions = $this->Multiplechoice->getQuestionsOfQuest($quest['id']);
// Save temporary user answer of last question
$answers = (!is_array($answers)) ? array() : $answers;
$pos = $this->Multiplechoice->getQuestionsCountOfQuest($quest['id']);
$question = $this->Multiplechoice->getQuestionOfQuest($quest['id'], $pos);
$this->saveUserAnswers($quest['id'], $question['id'], $answers);
// Save answers
$questions = $this->Multiplechoice->getQuestionsOfQuest($quest['id']);
foreach($questions as &$question)
{
$answer = (array_key_exists(intval($question['pos'])-1, $answers)) ? true : false;
$this->Multiplechoice->setCharacterSubmission($question['id'], $character['id'], $answer);
$userAnswers = $this->getUserAnswers($quest['id'], $question['id']);
$answers = $this->Multiplechoice->getAnswersOfQuestion($question['id']);
foreach($answers as &$answer)
{
$userAnswer = (array_key_exists($answer['pos']-1, $userAnswers)) ? true : false;
$this->Multiplechoice->setCharacterSubmission($answer['id'], $character['id'], $userAnswer);
}
}
}
@ -57,27 +66,43 @@
*/
public function matchAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers)
{
// Get right answers
$tickQuestions = $this->Multiplechoice->getTickQuestionsOfQuest($quest['id']);
// Save temporary user answer of last question
$answers = (!is_array($answers)) ? array() : $answers;
$pos = $this->Multiplechoice->getQuestionsCountOfQuest($quest['id']);
$question = $this->Multiplechoice->getQuestionOfQuest($quest['id'], $pos);
$this->saveUserAnswers($quest['id'], $question['id'], $answers);
// Match tick questions with user answers
$allSolved = true;
foreach($tickQuestions as &$tickQuestion)
// Get questions
$questions = $this->Multiplechoice->getQuestionsOfQuest($quest['id']);
// Iterate questions
foreach($questions as &$question)
{
$pos = intval($tickQuestion['pos'])-1;
if(!array_key_exists($pos, $answers) || $answers[$pos] != 'true')
// Get answers
$userAnswers = $this->getUserAnswers($quest['id'], $question['id']);
$answers = $this->Multiplechoice->getAnswersOfQuestion($question['id']);
var_dump($userAnswers);
var_dump($answers);
// Match answers with user answers
foreach($answers as &$answer)
{
$allSolved = false;
break;
}
else {
unset($answers[$pos]);
if($answer['tick']) {
if(!array_key_exists($answer['pos']-1, $userAnswers)) {
return false;
}
}
else {
if(array_key_exists($answer['pos']-1, $userAnswers)) {
return false;
}
}
}
}
// Return status
return ($allSolved && count($answers) == 0);
// All questions correct answerd
return true;
}
@ -94,24 +119,54 @@
*/
public function quest($seminary, $questgroup, $quest, $character)
{
// Get questions
$questions = $this->Multiplechoice->getQuestionsOfQuest($quest['id']);
// Get count of questions
$count = $this->Multiplechoice->getQuestionsCountOfQuest($quest['id']);
// Get user answers
if($this->request->getGetParam('show-answer') == 'true')
{
foreach($questions as &$question) {
$question['answer'] = $this->Multiplechoice->getCharacterSubmission($question['id'], $character['id']);
// Get position
$pos = 1;
if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('submit-answer')))
{
if(!is_null($this->request->getPostParam('question')))
{
// Get current position
$pos = intval($this->request->getPostParam('question'));
if($pos < 0 || $pos > $count) {
throw new \nre\exceptions\ParamsNotValidException($pos);
}
// Save temporary answer of user
$question = $this->Multiplechoice->getQuestionOfQuest($quest['id'], $pos);
$answers = ($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('answers'))) ? $this->request->getPostParam('answers') : array();
$this->saveUserAnswers($quest['id'], $question['id'], $answers);
// Go to next position
$pos++;
}
else {
throw new \nre\exceptions\ParamsNotValidException('pos');
}
}
// Has Character already solved Quest?
$solved = $this->Quests->hasCharacterSolvedQuest($quest['id'], $character['id']);
// Get current question
$question = $this->Multiplechoice->getQuestionOfQuest($quest['id'], $pos);
// Get answers
$question['answers'] = $this->Multiplechoice->getAnswersOfQuestion($question['id']);
// Get previous user answers
if($this->request->getGetParam('show-answer') == 'true')
{
foreach($question['answers'] as &$answer) {
$answer['useranswer'] = $this->Multiplechoice->getCharacterSubmission($answer['id'], $character['id']);
}
}
// Pass data to view
$this->set('questions', $questions);
$this->set('solved', $solved);
$this->set('question', $question);
$this->set('pos', $pos);
$this->set('count', $count);
}
@ -129,8 +184,16 @@
{
// Get questions
$questions = $this->Multiplechoice->getQuestionsOfQuest($quest['id']);
foreach($questions as &$question) {
$question['answer'] = $this->Multiplechoice->getCharacterSubmission($question['id'], $character['id']);
// Get answers
foreach($questions as &$question)
{
$question['answers'] = $this->Multiplechoice->getAnswersOfQuestion($question['id']);
// Get user answers
foreach($question['answers'] as &$answer) {
$answer['useranswer'] = $this->Multiplechoice->getCharacterSubmission($answer['id'], $character['id']);
}
}
@ -138,6 +201,60 @@
$this->set('questions', $questions);
}
/**
* Save the answers of a user for a question temporary in the
* session.
*
* @param int $questId ID of Quest
* @param int $questionId ID of multiple choice question
* @param array $userAnswers Answers of user for the question
*/
private function saveUserAnswers($questId, $questionId, $userAnswers)
{
// Ensure session structure
if(!array_key_exists('answers', $_SESSION)) {
$_SESSION['answers'] = array();
}
if(!array_key_exists($questId, $_SESSION['answers'])) {
$_SESSION['answers'][$questId] = array();
}
$_SESSION['answers'][$questId][$questionId] = array();
// Save answres
foreach($userAnswers as $pos => &$answer) {
$_SESSION['answers'][$questId][$questionId][$pos] = $answer;
}
}
/**
* Get the temporary saved answers of a user for a question.
*
* @param int $questId ID of Quest
* @param int $questionId ID of multiple choice question
* @return array Answers of user for the question
*/
private function getUserAnswers($questId, $questionId)
{
// Ensure session structure
if(!array_key_exists('answers', $_SESSION)) {
$_SESSION['answers'] = array();
}
if(!array_key_exists($questId, $_SESSION['answers'])) {
$_SESSION['answers'][$questId] = array();
}
if(!array_key_exists($questionId, $_SESSION['answers'][$questId])) {
$_SESSION['answers'][$questId][$questionId] = array();
}
// Return answers
return $_SESSION['answers'][$questId][$questionId];
}
}
?>

View file

@ -23,6 +23,30 @@
/**
* Get the count of multiple choice questions for a Quest.
*
* @param int $questId ID of Quest to get count for
* @return int Conut of questions
*/
public function getQuestionsCountOfQuest($questId)
{
$data = $this->db->query(
'SELECT count(id) AS c '.
'FROM questtypes_multiplechoice '.
'WHERE quest_id = ?',
'i',
$questId
);
if(!empty($data)) {
return $data[0]['c'];
}
return 0;
}
/**
* Get all multiple choice questions of a Quest.
*
@ -32,7 +56,7 @@
public function getQuestionsOfQuest($questId)
{
return $this->db->query(
'SELECT id, pos, question, tick '.
'SELECT id, pos, question '.
'FROM questtypes_multiplechoice '.
'WHERE quest_id = ?',
'i',
@ -42,20 +66,44 @@
/**
* Get all multiple choice questions of a Quest that should be
* ticked.
* Get one multiple choice question of a Quest.
*
* @param int $questId ID of Quest
* @return array Multiple choice questions that should be ticked
* @param int $pos Position of question
* @return array Question data
*/
public function getTickQuestionsOfQuest($questId)
public function getQuestionOfQuest($questId, $pos)
{
$data = $this->db->query(
'SELECT id, pos, question '.
'FROM questtypes_multiplechoice '.
'WHERE quest_id = ? AND pos = ?',
'ii',
$questId, $pos
);
if(!empty($data)) {
return $data[0];
}
return null;
}
/**
* Get all answers of a multiple choice question.
*
* @param int $questionId ID of multiple choice question
* @return array Answers of question
*/
public function getAnswersOfQuestion($questionId)
{
return $this->db->query(
'SELECT id, question, tick, pos '.
'FROM questtypes_multiplechoice '.
'WHERE quest_id = ? AND tick = True',
'SELECT id, pos, answer, tick '.
'FROM questtypes_multiplechoice_answers '.
'WHERE questtypes_multiplechoice_id = ?',
'i',
$questId
$questionId
);
}
@ -63,21 +111,21 @@
/**
* Save Characters submitted answer for one option.
*
* @param int $multipleChoiceId ID of multiple choice option
* @param int $characterId ID of Character
* @param boolean $answer Submitted answer for this option
* @param int $answerId ID of multiple choice answer
* @param int $characterId ID of Character
* @param boolean $answer Submitted answer for this option
*/
public function setCharacterSubmission($multipleChoiceId, $characterId, $answer)
public function setCharacterSubmission($answerId, $characterId, $answer)
{
$this->db->query(
'INSERT INTO questtypes_multiplechoice_characters '.
'(questtypes_multiplechoice_id, character_id, ticked) '.
'(questtypes_multiplechoice_answer_id, character_id, ticked) '.
'VALUES '.
'(?, ?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'ticked = ?',
'iiii',
$multipleChoiceId, $characterId, $answer, $answer
$answerId, $characterId, $answer, $answer
);
}
@ -85,18 +133,18 @@
/**
* Get answer of one option submitted by Character.
*
* @param int $multipleChoiceId ID of multiple choice option
* @param int $characterId ID of Character
* @return boolean Submitted answer of Character or false
* @param int $answerId ID of multiple choice answer
* @param int $characterId ID of Character
* @return boolean Submitted answer of Character or false
*/
public function getCharacterSubmission($multipleChoiscId, $characterId)
public function getCharacterSubmission($answerId, $characterId)
{
$data = $this->db->query(
'SELECT ticked '.
'FROM questtypes_multiplechoice_characters '.
'WHERE questtypes_multiplechoice_id = ? AND character_id = ? ',
'WHERE questtypes_multiplechoice_answer_id = ? AND character_id = ? ',
'ii',
$multipleChoiscId, $characterId
$answerId, $characterId
);
if(!empty($data)) {
return $data[0]['ticked'];

View file

@ -1,11 +1,21 @@
<form method="post">
<ol>
<?php foreach($questions as $i => &$question) : ?>
<li>
<input type="checkbox" id="answers[<?=$i?>]" name="answers[<?=$i?>]" value="true" <?=(array_key_exists('answer', $question) && $question['answer']) ? 'checked="checked"' : '' ?> />
<label for="answers[<?=$i?>]"><?=\hhu\z\Utils::t($question['question'])?></label>
</li>
<?php endforeach ?>
</ol>
<fieldset>
<legend><?=sprintf(_('Question %d of %d'), $pos, $count)?></legend>
<p><?=\hhu\z\Utils::t($question['question'])?></p>
<ol>
<?php foreach($question['answers'] as $i => &$answer) : ?>
<li>
<input type="checkbox" id="answers[<?=$i?>]" name="answers[<?=$i?>]" value="true" <?=(array_key_exists('useranswer', $answer) && $answer['useranswer']) ? 'checked="checked"' : '' ?> />
<label for="answers[<?=$i?>]"><?=\hhu\z\Utils::t($answer['answer'])?></label>
</li>
<?php endforeach ?>
</ol>
</fieldset>
<input type="hidden" name="question" value="<?=$pos?>" />
<?php if($pos < $count) : ?>
<input type="submit" name="submit-answer" value="<?=_('solve Question')?>" />
<?php else : ?>
<input type="submit" name="submit" value="<?=_('solve')?>" />
<?php endif ?>
</form>

View file

@ -1,9 +1,16 @@
<ul>
<?php foreach($questions as &$question) : ?>
<ol>
<?php foreach($questions as $pos => &$question) : ?>
<li>
<?php if($question['answer']) : ?>☑<?php else : ?>☐<?php endif ?>
<?php if($question['answer'] == $question['tick']) : ?>✓<?php else : ?>×<?php endif ?>
<?=$question['question']?>
<h1><?=\hhu\z\Utils::t($question['question'])?></h1>
<ol>
<?php foreach($question['answers'] as &$answer) : ?>
<li>
<?php if($answer['useranswer']) : ?>☑<?php else : ?>☐<?php endif ?>
<?php if($answer['useranswer'] == $answer['tick']) : ?>✓<?php else : ?>×<?php endif ?>
<?=$answer['answer']?>
</li>
<?php endforeach ?>
</ol>
</li>
<?php endforeach ?>
</ul>
</ol>