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 = array_search( $quest->getID(), $questID_arr );
|
||||||
|
|
||||||
$index_int++;
|
$index_int++;
|
||||||
$nextQuest = new Question( $questID_arr[ $index_int ] );
|
if ( count( $questID_arr ) > $index_int ){
|
||||||
$ans_arr = $nextQuest->getAnswers();
|
$nextQuest = new Question( $questID_arr[ $index_int ] );
|
||||||
|
$ans_arr = $nextQuest->getAnswers();
|
||||||
|
|
||||||
$data_arr = array(
|
$data_arr = array(
|
||||||
'text' => $nextQuest->getText(),
|
'done' => false,
|
||||||
'ans' => array()
|
'text' => $nextQuest->getText(),
|
||||||
);
|
'ans' => array()
|
||||||
|
);
|
||||||
|
|
||||||
foreach( $ans_arr as $answer ){
|
foreach( $ans_arr as $answer ){
|
||||||
$data_arr['ans'][] = array( 'id' => $answer->getID(), 'text' => $answer->getText() );
|
$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" );
|
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 $userID_int ID of user
|
||||||
* @param int[] $ans_arr Array of answer IDs
|
* @param int[] $ans_arr Array of answer IDs
|
||||||
|
|
|
@ -63,4 +63,64 @@ class Quiz extends Item {
|
||||||
return $this->maxScore_int;
|
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>
|
</form>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</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>
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
34
quiz.js
34
quiz.js
|
@ -16,22 +16,28 @@ $( document ).ready( function() {
|
||||||
quest : id.quest[ questNum - 1],
|
quest : id.quest[ questNum - 1],
|
||||||
ans : ans,
|
ans : ans,
|
||||||
} ).done( function( data ){
|
} ).done( function( data ){
|
||||||
questNum++;
|
if ( data.done ){
|
||||||
$( "#question-text" ).text( data.text );
|
// Send user to results page
|
||||||
$( "#answers" ).empty();
|
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 ){
|
$.each( data.ans, function( index, value ){
|
||||||
$( "#answers" ).append( '\
|
$( "#answers" ).append( '\
|
||||||
<div class="col-md-6">\
|
<div class="col-md-6">\
|
||||||
<label class="w-100">\
|
<label class="w-100">\
|
||||||
<input type="checkbox" name="answer" value="' + value.id + '" />\
|
<input type="checkbox" name="answer" value="' + value.id + '" />\
|
||||||
' + value.text + '\
|
' + value.text + '\
|
||||||
</label>\
|
</label>\
|
||||||
</div>' );
|
</div>' );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
let progress = questNum / id.quest.length * 100;
|
let progress = questNum / id.quest.length * 100;
|
||||||
$( "#progress" ).text( questNum + ' / ' + id.quest.length ).prop( "style", "width: " + progress + "%" );
|
$( "#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