Calculate and save score, then generate results page

This commit is contained in:
Mark Wane 2019-10-06 08:53:19 +01:00
parent 9b401b6033
commit 2d743e8546
6 changed files with 163 additions and 24 deletions

View File

@ -12,16 +12,26 @@ $questID_arr = Question::getList( $quiz->getID() );
$index_int = array_search( $quest->getID(), $questID_arr );
$index_int++;
$nextQuest = new Question( $questID_arr[ $index_int ] );
$ans_arr = $nextQuest->getAnswers();
if ( count( $questID_arr ) > $index_int ){
$nextQuest = new Question( $questID_arr[ $index_int ] );
$ans_arr = $nextQuest->getAnswers();
$data_arr = array(
'text' => $nextQuest->getText(),
'ans' => array()
);
$data_arr = array(
'done' => false,
'text' => $nextQuest->getText(),
'ans' => array()
);
foreach( $ans_arr as $answer ){
$data_arr['ans'][] = array( 'id' => $answer->getID(), 'text' => $answer->getText() );
foreach( $ans_arr as $answer ){
$data_arr['ans'][] = array( 'id' => $answer->getID(), 'text' => $answer->getText() );
}
} else {
$accessKey_str = $quiz->saveResult( $_POST['user'] );
$data_arr = array(
'done' => true,
'result' => $accessKey_str
);
}
header( "content-type: application/json" );

View File

@ -75,7 +75,7 @@ class Question extends Item {
}
/**
* Calulate user's score and save to DB
* Calculate user's score and save to DB
*
* @param int $userID_int ID of user
* @param int[] $ans_arr Array of answer IDs

View File

@ -63,4 +63,64 @@ class Quiz extends Item {
return $this->maxScore_int;
}
/**
* Calculate and save the total score of a user
*
* @param int $userID_int $userID_int ID of user
*
* @return string Access key for results page
*/
public function saveResult( int $userID_int ){
$db = DB::getDB();
$total_int = 0;
foreach( $this->questionID_arr as $questionID_int ){
$question = new Question( $questionID_int );
$total_int += $question->getScore( $userID_int );
}
$accessKey_str = hash( 'sha256', $this->id_int . $userID_int . microtime() );
$db->insert(
self::resultTb_str,
array(
'quiz' => $this->id_int,
'user' => $userID_int,
'score' => $total_int,
'access_key' => $accessKey_str
)
);
return $accessKey_str;
}
/**
* Get result for user and calculate average score
*
* @param string $acessKey_str Access key for result
*
* @return mixed[] Array of result data
*/
public static function getResult( string $accessKey_str ){
$db = DB::getDB();
$rows_arr = $db->select( self::resultTb_str, array(), array( 'access_key' => $accessKey_str ) );
if ( empty( $rows_arr ) ){
throw new \RuntimeException( 'Invalid access key' );
}
$result_arr = $rows_arr[0];
$rows_arr = $db->select( self::resultTb_str, array( 'score' ), array( 'quiz' => $result_arr['quiz'] ) );
$total_int = 0;
foreach ( $rows_arr as $row_arr ){
$total_int += $row_arr['score'];
}
$result_arr['average'] = $total_int / count( $rows_arr );
return $result_arr;
}
}

View File

@ -56,7 +56,7 @@ $quizzes_arr = Quiz::getList();
</form>
</main>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>

34
quiz.js
View File

@ -16,22 +16,28 @@ $( document ).ready( function() {
quest : id.quest[ questNum - 1],
ans : ans,
} ).done( function( data ){
questNum++;
$( "#question-text" ).text( data.text );
$( "#answers" ).empty();
if ( data.done ){
// Send user to results page
window.location.replace( "result.php?key=" + data.result );
} else {
// Display next question
questNum++;
$( "#question-text" ).text( data.text );
$( "#answers" ).empty();
$.each( data.ans, function( index, value ){
$( "#answers" ).append( '\
<div class="col-md-6">\
<label class="w-100">\
<input type="checkbox" name="answer" value="' + value.id + '" />\
' + value.text + '\
</label>\
</div>' );
} );
$.each( data.ans, function( index, value ){
$( "#answers" ).append( '\
<div class="col-md-6">\
<label class="w-100">\
<input type="checkbox" name="answer" value="' + value.id + '" />\
' + value.text + '\
</label>\
</div>' );
} );
let progress = questNum / id.quest.length * 100;
$( "#progress" ).text( questNum + ' / ' + id.quest.length ).prop( "style", "width: " + progress + "%" );
let progress = questNum / id.quest.length * 100;
$( "#progress" ).text( questNum + ' / ' + id.quest.length ).prop( "style", "width: " + progress + "%" );
}
} );
} );
} );

63
result.php Normal file
View File

@ -0,0 +1,63 @@
<?php
use TestProject\User;
use TestProject\Quiz;
require_once 'init.php';
$data_arr = Quiz::getResult( $_GET['key'] );
$quiz = new Quiz( $data_arr['quiz'] );
$user = new User( $data_arr['user'] );
$maxScore_int = $quiz->getMaxScore();
$scorePer_num = $data_arr['score'] / $maxScore_int * 100;
$averagePer_num = $data_arr['average'] / $maxScore_int * 100;
if ( $scorePer_num > $averagePer_num + 10 ){
$barColour_str = "bg-success";
} elseif ( $scorePer_num < $averagePer_num - 10 ){
$barColour_str = "bg-danger";
} else {
$barColour_str = "bg-warning";
}
?>
<!doctype html>
<html lang=en_GB>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Basic PHP Quiz</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row">
<div class="col">
<h1 class="text-center">Results</h1>
</div>
</div>
<div class="row">
<div class="col">
<h2 class="text-center">Thank you, <?php echo $user->getName(); ?></h2>
</div>
</div>
<div class="row">
<div class="col-md-6">
<p>Your score</p>
<div class="progress">
<div class="progress-bar <?php echo $barColour_str; ?>" role="progressbar" style="width: <?php echo $scorePer_num; ?>%"><?php echo $data_arr['score'] . " / " . $maxScore_int ?></div>
</div>
</div>
<div class="col-md-6">
<p>Average score</p>
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: <?php echo $averagePer_num; ?>%"><?php echo $data_arr['average'] . " / " . $maxScore_int ?></div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>