Calculate and save score, then generate results page
This commit is contained in:
parent
9b401b6033
commit
2d743e8546
26
ajax.php
26
ajax.php
|
@ -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" );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
34
quiz.js
|
@ -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
63
result.php
Normal 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>
|
Loading…
Reference in a new issue