['Find the missing number. {QUESTION}', "Congratulations '{USER_ANSWER}' was correct for Find the missing number '{ANSWER}'", "Sorry but '{USER_ANSWER}' was incorrect it should have been '{ANSWER}' for 'Find the missing number in {QUESTION}'"],
'addition' => ['Solve the following equation. {QUESTION}.', "Congratulations '{USER_ANSWER}' was correct for Solve the following equation. '{ANSWER}'", "Sorry but '{USER_ANSWER}' was incorrect it should have been '{ANSWER}' for 'Solve the following equation in {QUESTION}'"],
'subtraction' => ['Solve the following equation. {QUESTION}.', "Congratulations '{USER_ANSWER}' was correct for Solve the following equation. '{ANSWER}'", "Sorry but '{USER_ANSWER}' was incorrect it should have been '{ANSWER}' for 'Solve the following equation in {QUESTION}'"],
'multiplication' => ['Solve the following equation. {QUESTION}.', "Congratulations '{USER_ANSWER}' was correct for Solve the following equation. '{ANSWER}'", "Sorry but '{USER_ANSWER}' was incorrect it should have been '{ANSWER}' for 'Solve the following equation in {QUESTION}'"],
'division' => ['Solve the following equation. {QUESTION}.', "Congratulations '{USER_ANSWER}' was correct for Solve the following equation. '{ANSWER}'", "Sorry but '{USER_ANSWER}' was incorrect it should have been '{ANSWER}' for 'Solve the following equation in {QUESTION}'"],
'rounding' => [],
'worded_add' => [],
'worded_sub' => [],
'worded_mult' => [],
'worded_devi' => [],
'anagrams' => ['Unjumble the letters to find the word. {QUESTION}.', "Congratulations '{USER_ANSWER}' was correct for Unjumble the letters '{ANSWER}'", "Sorry but '{USER_ANSWER}' was incorrect it should have been '{ANSWER}' for 'Unjumble the letters in {QUESTION}'"],
'generalKnowledge' => [],
'elements' => ['Fill in the missing element information. {QUESTION}', "Congratulations '{USER_ANSWER}' was correct for Fill in the missing element information '{ANSWER}'", "Sorry but '{USER_ANSWER}' was incorrect it should have been '{ANSWER}' for 'Fill in the missing element information in {QUESTION}'"],
'continents' => [],
'countries' => [],
'flags' => [],
'capitalCities' => [],
'artists' => [],
'malaySpelling' => [],
'nameBodyParts' => [],
'nameBodyOrgans' => [],
'basicFirstAid' => []
];
/**
* Get the right answer checker for the subject
*/
public function checkQuestionSubject($subject, $user) {
$this->user = $user;
switch ($subject) {
case 'numbers':
case 'addition':
case 'subtraction':
case 'multiplication':
case 'division':
$this->checkGeneric($subject);
break;
case 'worded_add':
case 'worded_sub':
case 'worded_mult':
case 'worded_devi':
case 'spelling':
$this->checkSpelling(); //Custom checker
break;
case 'anagrams':
$this->checkAnagrams();
break;
case 'generalKnowledge':
case 'elements':
$this->checkGeneric('elements');
break;
case 'continents':
case 'countries':
case 'flags':
case 'capitalCities':
case 'artists':
case 'malaySpelling':
case 'nameBodyParts':
case 'nameBodyOrgans':
case 'basicFirstAid':
default:
print_a('An error has been detected in the answer checker. Please report this and refresh the page.');
break;
}
}
/**
* Check the answer for anything basic
*/
private function checkGeneric($subject) {
$usersAnswer = (string) filter_input(INPUT_POST, 'a1');
$answer = $this->loadPending();
if ($answer === null) {
return;
}
if (is_array($answer['question'])) {
$answer['question'] = implode('', $answer['question']);
}
if (trim($usersAnswer) === trim((string) $answer['answer1'])) {
$text = str_replace(['{ANSWER}', '{USER_ANSWER}'], [$answer['answer1'], trim($usersAnswer)], $this->messages[$subject][1]) . "
";
$this->updateScore(true);
} else {
$text = str_replace(['{ANSWER}', '{USER_ANSWER}', '{QUESTION}'], [$answer['answer1'], trim($usersAnswer), $answer['question']], $this->messages[$subject][2]) . "
";
$this->updateScore(false);
}
$this->addToReport($answer['answer1'], $usersAnswer, $subject, str_replace('{ANSWER}', $answer['answer1'], str_replace('{QUESTION}', $answer['question'], $this->messages[$subject][0])));
e107::getRender()->tablerender(ucfirst($subject) . ' answer check', $text);
}
/**
* Check the answer for anything basic
*/
private function checkAnagrams() {
$usersAnswer = (string) filter_input(INPUT_POST, 'a1');
$answer = $this->loadPending();
if ($answer === null) {
return;
}
if (is_array($answer['question'])) {
$answer['question'] = implode('', $answer['question']);
}
$words = e107::getDb()->retrieve('tk_wordList', 'word');
if (trim($usersAnswer) === trim((string) $answer['answer1']) || $this->findInList($words, $usersAnswer)) {
$text = str_replace(['{ANSWER}', '{USER_ANSWER}'], [$answer['answer1'], trim($usersAnswer)], $this->messages['anagrams'][1]) . "
";
$this->updateScore(true);
} else {
$text = str_replace(['{ANSWER}', '{USER_ANSWER}', '{QUESTION}'], [$answer['answer1'], trim($usersAnswer), $answer['question']], $this->messages['anagrams'][2]) . "
";
$this->updateScore(false);
}
$this->addToReport($answer['answer1'], $usersAnswer, 'anagrams', str_replace('{ANSWER}', $answer['answer1'], str_replace('{QUESTION}', $answer['question'], $this->messages['anagrams'][0])));
e107::getRender()->tablerender(ucfirst('anagrams') . ' answer check', $text);
}
private function findInList($list, $needle) {
foreach ($list as $listItem) {
if ($listItem == $needle) {
return true;
}
}
return false;
}
/**
* Check the answer for spelling
*/
private function checkSpelling() {
$usersAnswer = (string) filter_input(INPUT_POST, 'a1');
$answer = $this->loadPending();
if ($answer === null) {
return;
}
if (trim($usersAnswer) === trim((string) $answer['word'])) {
$text = "Congratulations '" . trim($usersAnswer) . "' was correct for 'spell the word " . $answer['word'] . "'
";
$this->updateScore(true);
//file_put_contents('debug_Spelling_data.txt','<->'.$answer['word'].'<->'.$usersAnswer.'<->True'."\n",FILE_APPEND);//=================================
} else {
$text = "Sorry but '" . trim($usersAnswer) . "' was incorrect it should have been '" . trim($answer['word']) . "' for 'spell the word " . $answer['word'] . "'
";
$this->updateScore(false);
//file_put_contents('debug_Spelling_data.txt','<->'.$answer['word'].'<->'.$usersAnswer.'<->False'."\n",FILE_APPEND);//=================================
}
$this->addToReport($answer['word'], $usersAnswer, 'spelling', "Spell the word " . $answer['word']);
e107::getRender()->tablerender('Spelling answer check', $text);
}
/**
* Add or minus the score
*/
private function updateScore($scorePoint) {
$currentScore = e107::getDb()->retrieve('timekeeperScore', 'timekeeper_lifetimecorrect, timekeeper_lifetimequestions, timekeeper_minutes', 'timekeeper_username="' . $this->user . '"');
if ($scorePoint) {
$currentScore['timekeeper_lifetimecorrect']++;
$currentScore['timekeeper_minutes'] = $currentScore['timekeeper_minutes'] + $this->scaleTimeAddition();
} else {
$currentScore['timekeeper_minutes']--;
}
$currentScore['timekeeper_lifetimequestions']++;
if ($currentScore['timekeeper_lifetimequestions'] == 1) {
$currentScore['timekeeper_lastquestiondatestamp'] = time();
$currentScore['timekeeper_yearlevel'] = 0;
$currentScore['timekeeper_username'] = $this->user;
e107::getDb()->insert('timekeeperScore', $currentScore);
} else {
$currentScore['WHERE'] = 'timekeeper_username="' . $this->user . '"';
e107::getDb()->update('timekeeperScore', $currentScore);
}
}
/**
* Return how many minutes play time to award scaled by difficulty
*/
private function scaleTimeAddition() {
//TODO look at this and fix it.
$difficulty = $this->getDifficulty($this->user); //replace with db call
$maxDifficulty = 5000000; // 5 mil is max here
//$returnMinutes = 10 - ($difficulty / $maxDifficulty * 100) / 10;
$returnMinutes = (int) $difficulty / 10;
//print_a(['diffi'=>$difficulty,'fprint'=> round($difficulty),'retmins'=>round($returnMinutes)]);
$returnMinutes = round($returnMinutes);
if ($returnMinutes <= 1) {
$returnMinutes = 1;
}
return round($returnMinutes);
}
/**
* Return users overall difficulty.
*/
private function getDifficulty($user) {
$returnArray = [];
//$returnArray['totalQuestionCount'] = e107::getDb()->count("tkReport", "(id)", "username = '" . $user . "'");
e107::getDb()->gen("SELECT COUNT(id) as cntr, CAST((SUM(correct)/COUNT(id)*100) as DECIMAL(5,2)) as percent
FROM e107.`e107_tkReport` WHERE username = '" . $user . "'
AND answereddatestamp >= unix_timestamp(CURRENT_DATE() - INTERVAL 1 MONTH)
AND answereddatestamp <= unix_timestamp(CURRENT_DATE() + INTERVAL 1 DAY)");
while ($row = e107::getDb()->fetch()) {
$returnArray = array_merge($returnArray, $row);
}
return $returnArray['percent']; //($returnArray['totalQuestionCount']*$returnArray['percent']);
}
/**
* Add the last answered question to the report DB table.
*/
private function addToReport($answer, $usersAnswer, $subject, $questionString) {
if ($answer == $usersAnswer) {
$correct = 1;
} else {
$correct = 0;
}
$insert = [
'username' => $this->user,
'question' => $questionString,
'answereddatestamp' => time(),
'userAnswer' => trim($usersAnswer),
'answer' => trim($answer),
'subject' => $subject,
'correct' => $correct
];
e107::getDb()->insert('tkReport', $insert);
}
/**
* ShortCode engine
*/
private function shortCode($keys, $message) {
$returnMessage = $message;
foreach ($keys as $key => $value) {
$returnMessage = $str;
}
}
private function loadPending(): ?array {
$token = filter_input(INPUT_POST, 'checkerData');
$answer = TkAnswerStore::consume($this->user, is_string($token) ? $token : null);
if ($answer === null) {
e107::getRender()->tablerender('Answer check',
'That question has expired or was already answered. Please answer the new question.');
}
return $answer;
}
}