2002-10-04 02:59:05 +00:00
|
|
|
<?PHP // $Id$
|
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
/// Library of function for module quiz
|
2002-10-04 02:59:05 +00:00
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
/// CONSTANTS ///////////////////////////////////////////////////////////////////
|
2002-10-04 02:59:05 +00:00
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
define("GRADEHIGHEST", "1");
|
|
|
|
define("GRADEAVERAGE", "2");
|
|
|
|
define("ATTEMPTFIRST", "3");
|
|
|
|
define("ATTEMPTLAST", "4");
|
|
|
|
$QUIZ_GRADE_METHOD = array ( GRADEHIGHEST => get_string("gradehighest", "quiz"),
|
|
|
|
GRADEAVERAGE => get_string("gradeaverage", "quiz"),
|
|
|
|
ATTEMPTFIRST => get_string("attemptfirst", "quiz"),
|
|
|
|
ATTEMPTLAST => get_string("attemptlast", "quiz"));
|
|
|
|
|
|
|
|
define("SHORTANSWER", "1");
|
|
|
|
define("TRUEFALSE", "2");
|
|
|
|
define("MULTICHOICE", "3");
|
2002-10-15 12:54:11 +00:00
|
|
|
$QUIZ_QUESTION_TYPE = array ( MULTICHOICE => get_string("multichoice", "quiz"),
|
2002-10-13 07:17:48 +00:00
|
|
|
TRUEFALSE => get_string("truefalse", "quiz"),
|
2002-10-15 12:54:11 +00:00
|
|
|
SHORTANSWER => get_string("shortanswer", "quiz") );
|
2002-10-13 07:17:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// FUNCTIONS ///////////////////////////////////////////////////////////////////
|
2002-10-04 02:59:05 +00:00
|
|
|
|
|
|
|
function quiz_add_instance($quiz) {
|
2002-10-13 07:17:48 +00:00
|
|
|
/// Given an object containing all the necessary data,
|
|
|
|
/// (defined by the form in mod.html) this function
|
|
|
|
/// will create a new instance and return the id number
|
|
|
|
/// of the new instance.
|
2002-10-04 02:59:05 +00:00
|
|
|
|
2002-10-15 16:22:18 +00:00
|
|
|
$quiz->created = time();
|
2002-10-04 02:59:05 +00:00
|
|
|
$quiz->timemodified = time();
|
2002-10-15 16:22:18 +00:00
|
|
|
$quiz->timeopen = make_timestamp($quiz->openyear, $quiz->openmonth, $quiz->openday,
|
|
|
|
$quiz->openhour, $quiz->openminute, $quiz->opensecond);
|
|
|
|
$quiz->timeclose = make_timestamp($quiz->closeyear, $quiz->closemonth, $quiz->closeday,
|
|
|
|
$quiz->closehour, $quiz->closeminute, $quiz->closesecond);
|
2002-10-04 02:59:05 +00:00
|
|
|
|
2002-10-14 12:21:18 +00:00
|
|
|
if (!$quiz->id = insert_record("quiz", $quiz)) {
|
|
|
|
return false; // some error occurred
|
|
|
|
}
|
|
|
|
|
2002-10-14 15:57:33 +00:00
|
|
|
// The grades for every question in this quiz are stored in an array
|
2002-10-14 12:21:18 +00:00
|
|
|
if ($quiz->grades) {
|
|
|
|
foreach ($quiz->grades as $question => $grade) {
|
2002-10-15 12:54:11 +00:00
|
|
|
if ($question and $grade) {
|
|
|
|
unset($questiongrade);
|
|
|
|
$questiongrade->quiz = $quiz->id;
|
|
|
|
$questiongrade->question = $question;
|
|
|
|
$questiongrade->grade = $grade;
|
|
|
|
if (!insert_record("quiz_question_grades", $questiongrade)) {
|
|
|
|
return false;
|
|
|
|
}
|
2002-10-14 12:21:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-10-04 02:59:05 +00:00
|
|
|
|
2002-10-14 12:21:18 +00:00
|
|
|
return $quiz->id;
|
2002-10-04 02:59:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function quiz_update_instance($quiz) {
|
2002-10-13 07:17:48 +00:00
|
|
|
/// Given an object containing all the necessary data,
|
|
|
|
/// (defined by the form in mod.html) this function
|
|
|
|
/// will update an existing instance with new data.
|
2002-10-04 02:59:05 +00:00
|
|
|
|
|
|
|
$quiz->timemodified = time();
|
2002-10-15 16:22:18 +00:00
|
|
|
$quiz->timeopen = make_timestamp($quiz->openyear, $quiz->openmonth, $quiz->openday,
|
|
|
|
$quiz->openhour, $quiz->openminute, $quiz->opensecond);
|
|
|
|
$quiz->timeclose = make_timestamp($quiz->closeyear, $quiz->closemonth, $quiz->closeday,
|
|
|
|
$quiz->closehour, $quiz->closeminute, $quiz->closesecond);
|
2002-10-04 02:59:05 +00:00
|
|
|
$quiz->id = $quiz->instance;
|
|
|
|
|
2002-10-14 12:21:18 +00:00
|
|
|
if (!update_record("quiz", $quiz)) {
|
|
|
|
return false; // some error occurred
|
|
|
|
}
|
2002-10-04 02:59:05 +00:00
|
|
|
|
2002-10-14 12:21:18 +00:00
|
|
|
|
2002-10-14 15:57:33 +00:00
|
|
|
// The grades for every question in this quiz are stored in an array
|
2002-10-14 12:21:18 +00:00
|
|
|
// Insert or update records as appropriate
|
|
|
|
|
|
|
|
$existing = get_records("quiz_question_grades", "quiz", $quiz->id, "", "question,grade,id");
|
|
|
|
|
|
|
|
if ($quiz->grades) {
|
|
|
|
foreach ($quiz->grades as $question => $grade) {
|
2002-10-15 12:54:11 +00:00
|
|
|
if ($question and $grade) {
|
|
|
|
unset($questiongrade);
|
|
|
|
$questiongrade->quiz = $quiz->id;
|
|
|
|
$questiongrade->question = $question;
|
|
|
|
$questiongrade->grade = $grade;
|
|
|
|
if (isset($existing[$question])) {
|
|
|
|
if ($existing[$question]->grade != $grade) {
|
|
|
|
$questiongrade->id = $existing[$question]->id;
|
|
|
|
if (!update_record("quiz_question_grades", $questiongrade)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!insert_record("quiz_question_grades", $questiongrade)) {
|
2002-10-14 12:21:18 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2002-10-04 02:59:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function quiz_delete_instance($id) {
|
2002-10-13 07:17:48 +00:00
|
|
|
/// Given an ID of an instance of this module,
|
|
|
|
/// this function will permanently delete the instance
|
|
|
|
/// and any data that depends on it.
|
2002-10-04 02:59:05 +00:00
|
|
|
|
|
|
|
if (! $quiz = get_record("quiz", "id", "$id")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$result = true;
|
|
|
|
|
2002-10-14 15:57:33 +00:00
|
|
|
if ($attempts = get_record("quiz_attempts", "quiz", "$quiz->id")) {
|
|
|
|
foreach ($attempts as $attempt) {
|
|
|
|
if (! delete_records("quiz_responses", "attempt", "$attempt->id")) {
|
|
|
|
$result = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! delete_records("quiz_attempts", "quiz", "$quiz->id")) {
|
|
|
|
$result = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! delete_records("quiz_grades", "quiz", "$quiz->id")) {
|
|
|
|
$result = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! delete_records("quiz_question_grades", "quiz", "$quiz->id")) {
|
|
|
|
$result = false;
|
|
|
|
}
|
2002-10-04 02:59:05 +00:00
|
|
|
|
|
|
|
if (! delete_records("quiz", "id", "$quiz->id")) {
|
|
|
|
$result = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
function quiz_user_outline($course, $user, $mod, $quiz) {
|
2002-10-13 07:17:48 +00:00
|
|
|
/// Return a small object with summary information about what a
|
|
|
|
/// user has done with a given particular instance of this module
|
|
|
|
/// Used for user activity reports.
|
|
|
|
/// $return->time = the time they did it
|
|
|
|
/// $return->info = a short text description
|
2002-10-04 02:59:05 +00:00
|
|
|
|
|
|
|
return $return;
|
|
|
|
}
|
|
|
|
|
|
|
|
function quiz_user_complete($course, $user, $mod, $quiz) {
|
2002-10-13 07:17:48 +00:00
|
|
|
/// Print a detailed representation of what a user has done with
|
|
|
|
/// a given particular instance of this module, for user activity reports.
|
2002-10-04 02:59:05 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function quiz_print_recent_activity(&$logs, $isteacher=false) {
|
2002-10-13 07:17:48 +00:00
|
|
|
/// Given a list of logs, assumed to be those since the last login
|
|
|
|
/// this function prints a short list of changes related to this module
|
|
|
|
/// If isteacher is true then perhaps additional information is printed.
|
|
|
|
/// This function is called from course/lib.php: print_recent_activity()
|
2002-10-04 02:59:05 +00:00
|
|
|
|
|
|
|
global $CFG, $COURSE_TEACHER_COLOR;
|
|
|
|
|
|
|
|
return $content; // True if anything was printed, otherwise false
|
|
|
|
}
|
|
|
|
|
|
|
|
function quiz_cron () {
|
2002-10-13 07:17:48 +00:00
|
|
|
/// Function to be run periodically according to the moodle cron
|
|
|
|
/// This function searches for things that need to be done, such
|
|
|
|
/// as sending out mail, toggling flags etc ...
|
2002-10-04 02:59:05 +00:00
|
|
|
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
2002-10-13 07:17:48 +00:00
|
|
|
/// Any other quiz functions go here. Each of them must have a name that
|
|
|
|
/// starts with quiz_
|
2002-10-04 02:59:05 +00:00
|
|
|
|
2002-10-16 09:35:04 +00:00
|
|
|
function quiz_print_comment($text) {
|
|
|
|
global $THEME;
|
|
|
|
|
|
|
|
echo "<FONT COLOR=\"$THEME->cellheading2\">".text_to_html($text, true, false)."</FONT>";
|
|
|
|
}
|
|
|
|
|
|
|
|
function quiz_print_question($number, $questionid, $grade, $courseid,
|
|
|
|
$feedback=NULL, $response=NULL, $actualgrade=NULL) {
|
2002-10-13 07:17:48 +00:00
|
|
|
/// Prints a quiz question, any format
|
2002-10-16 09:35:04 +00:00
|
|
|
global $THEME;
|
|
|
|
|
|
|
|
$comment = $THEME->cellheading2;
|
2002-10-06 17:06:54 +00:00
|
|
|
|
|
|
|
if (!$question = get_record("quiz_questions", "id", $questionid)) {
|
|
|
|
notify("Error: Question not found!");
|
|
|
|
}
|
|
|
|
|
|
|
|
$stranswer = get_string("answer", "quiz");
|
|
|
|
$strmarks = get_string("marks", "quiz");
|
|
|
|
|
|
|
|
echo "<TABLE WIDTH=100% CELLSPACING=10><TR><TD NOWRAP WIDTH=100 VALIGN=top>";
|
2002-10-16 09:35:04 +00:00
|
|
|
echo "<P ALIGN=CENTER><B>$number</B></P>";
|
2002-10-16 15:52:29 +00:00
|
|
|
if ($feedback or $response) {
|
2002-10-16 09:35:04 +00:00
|
|
|
echo "<P ALIGN=CENTER><FONT SIZE=1>$strmarks: $actualgrade/$grade</FONT></P>";
|
|
|
|
} else {
|
|
|
|
echo "<P ALIGN=CENTER><FONT SIZE=1>$grade $strmarks</FONT></P>";
|
|
|
|
}
|
2002-10-06 17:06:54 +00:00
|
|
|
print_spacer(1,100);
|
|
|
|
echo "</TD><TD VALIGN=TOP>";
|
|
|
|
|
|
|
|
switch ($question->type) {
|
2002-10-13 07:17:48 +00:00
|
|
|
case SHORTANSWER:
|
2002-10-06 17:06:54 +00:00
|
|
|
if (!$options = get_record("quiz_shortanswer", "question", $question->id)) {
|
|
|
|
notify("Error: Missing question options!");
|
|
|
|
}
|
2002-10-15 10:04:28 +00:00
|
|
|
echo text_to_html($question->questiontext);
|
2002-10-06 17:06:54 +00:00
|
|
|
if ($question->image) {
|
|
|
|
print_file_picture($question->image, $courseid, 200);
|
|
|
|
}
|
2002-10-16 09:35:04 +00:00
|
|
|
if ($response) {
|
|
|
|
$value = "VALUE=\"$response[0]\"";
|
|
|
|
}
|
|
|
|
echo "<P ALIGN=RIGHT>$stranswer: <INPUT TYPE=TEXT NAME=q$question->id SIZE=20 $value></P>";
|
|
|
|
if ($feedback) {
|
|
|
|
quiz_print_comment("<P ALIGN=right>$feedback[0]</P>");
|
|
|
|
}
|
2002-10-06 17:06:54 +00:00
|
|
|
break;
|
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
case TRUEFALSE:
|
2002-10-06 17:06:54 +00:00
|
|
|
if (!$options = get_record("quiz_truefalse", "question", $question->id)) {
|
|
|
|
notify("Error: Missing question options!");
|
|
|
|
}
|
|
|
|
if (!$true = get_record("quiz_answers", "id", $options->true)) {
|
|
|
|
notify("Error: Missing question answers!");
|
|
|
|
}
|
|
|
|
if (!$false = get_record("quiz_answers", "id", $options->false)) {
|
|
|
|
notify("Error: Missing question answers!");
|
|
|
|
}
|
|
|
|
if (!$true->answer) {
|
|
|
|
$true->answer = get_string("true", "quiz");
|
|
|
|
}
|
|
|
|
if (!$false->answer) {
|
|
|
|
$false->answer = get_string("false", "quiz");
|
|
|
|
}
|
2002-10-15 10:04:28 +00:00
|
|
|
echo text_to_html($question->questiontext);
|
2002-10-06 17:06:54 +00:00
|
|
|
if ($question->image) {
|
|
|
|
print_file_picture($question->image, $courseid, 200);
|
|
|
|
}
|
2002-10-16 09:35:04 +00:00
|
|
|
|
|
|
|
if ($response[$true->id]) {
|
|
|
|
$truechecked = "CHECKED";
|
|
|
|
$feedbackid = $true->id;
|
|
|
|
} else if ($response[$false->id]) {
|
|
|
|
$falsechecked = "CHECKED";
|
|
|
|
$feedbackid = $false->id;
|
|
|
|
}
|
2002-10-06 17:06:54 +00:00
|
|
|
echo "<P ALIGN=RIGHT>$stranswer: ";
|
2002-10-16 09:35:04 +00:00
|
|
|
echo "<INPUT $truechecked TYPE=RADIO NAME=\"q$question->id\" VALUE=\"$true->id\">$true->answer";
|
2002-10-06 17:06:54 +00:00
|
|
|
echo " ";
|
2002-10-16 09:35:04 +00:00
|
|
|
echo "<INPUT $falsechecked TYPE=RADIO NAME=\"q$question->id\" VALUE=\"$false->id\">$false->answer</P>";
|
|
|
|
if ($feedback) {
|
|
|
|
quiz_print_comment("<P ALIGN=right>$feedback[$feedbackid]</P>");
|
|
|
|
}
|
|
|
|
|
2002-10-06 17:06:54 +00:00
|
|
|
break;
|
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
case MULTICHOICE:
|
2002-10-06 17:06:54 +00:00
|
|
|
if (!$options = get_record("quiz_multichoice", "question", $question->id)) {
|
|
|
|
notify("Error: Missing question options!");
|
|
|
|
}
|
2002-10-13 07:17:48 +00:00
|
|
|
if (!$answers = get_records_list("quiz_answers", "id", $options->answers)) {
|
2002-10-06 17:06:54 +00:00
|
|
|
notify("Error: Missing question answers!");
|
|
|
|
}
|
2002-10-15 10:04:28 +00:00
|
|
|
echo text_to_html($question->questiontext);
|
2002-10-06 17:06:54 +00:00
|
|
|
if ($question->image) {
|
|
|
|
print_file_picture($question->image, $courseid, 200);
|
|
|
|
}
|
|
|
|
echo "<TABLE ALIGN=right>";
|
|
|
|
echo "<TR><TD valign=top>$stranswer: </TD><TD>";
|
|
|
|
echo "<TABLE ALIGN=right>";
|
|
|
|
$answerids = explode(",", $options->answers);
|
2002-10-16 09:35:04 +00:00
|
|
|
|
2002-10-06 17:06:54 +00:00
|
|
|
foreach ($answerids as $key => $answerid) {
|
|
|
|
$answer = $answers[$answerid];
|
|
|
|
$qnum = $key + 1;
|
2002-10-16 09:35:04 +00:00
|
|
|
|
|
|
|
if ($feedback and $response[$answerid]) {
|
|
|
|
$checked = "CHECKED";
|
|
|
|
} else {
|
|
|
|
$checked = "";
|
|
|
|
}
|
2002-10-06 17:06:54 +00:00
|
|
|
echo "<TR><TD valign=top>";
|
2002-10-13 07:17:48 +00:00
|
|
|
if ($options->single) {
|
2002-10-16 09:35:04 +00:00
|
|
|
echo "<INPUT $checked TYPE=RADIO NAME=q$question->id VALUE=\"$answer->id\">";
|
2002-10-06 17:06:54 +00:00
|
|
|
} else {
|
2002-10-16 09:35:04 +00:00
|
|
|
echo "<INPUT $checked TYPE=CHECKBOX NAME=q$question->id"."a$answer->id VALUE=\"$answer->id\">";
|
2002-10-06 17:06:54 +00:00
|
|
|
}
|
|
|
|
echo "</TD>";
|
|
|
|
echo "<TD valign=top>$qnum. $answer->answer</TD>";
|
2002-10-16 09:35:04 +00:00
|
|
|
if ($feedback) {
|
|
|
|
echo "<TD valign=top> ";
|
|
|
|
if ($response[$answerid]) {
|
|
|
|
quiz_print_comment($feedback[$answerid]);
|
|
|
|
}
|
|
|
|
echo "</TD>";
|
|
|
|
}
|
2002-10-06 17:06:54 +00:00
|
|
|
echo "</TR>";
|
|
|
|
}
|
|
|
|
echo "</TABLE>";
|
|
|
|
echo "</TABLE>";
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
notify("Error: Unknown question type!");
|
|
|
|
}
|
|
|
|
|
|
|
|
echo "</TD></TR></TABLE>";
|
2002-10-06 03:23:16 +00:00
|
|
|
}
|
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
function quiz_print_quiz_questions($quiz, $results=NULL) {
|
|
|
|
// Prints a whole quiz on one page.
|
|
|
|
|
|
|
|
if (!$quiz->questions) {
|
2002-10-14 15:57:33 +00:00
|
|
|
notify("No questions have been defined!", "view.php?id=$cm->id");
|
|
|
|
return false;
|
2002-10-13 07:17:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$questions = explode(",", $quiz->questions);
|
|
|
|
|
|
|
|
if (!$grades = get_records_list("quiz_question_grades", "question", $quiz->questions, "", "question,grade")) {
|
2002-10-14 15:57:33 +00:00
|
|
|
notify("No grades were found for these questions!");
|
|
|
|
return false;
|
2002-10-13 07:17:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
echo "<FORM METHOD=POST ACTION=attempt.php>";
|
|
|
|
echo "<INPUT TYPE=hidden NAME=q VALUE=\"$quiz->id\">";
|
2002-10-16 09:35:04 +00:00
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
foreach ($questions as $key => $questionid) {
|
2002-10-16 09:35:04 +00:00
|
|
|
if ($results) {
|
|
|
|
$feedback = $results->feedback[$questionid];
|
|
|
|
} else {
|
|
|
|
$feedback = NULL;
|
|
|
|
}
|
2002-10-13 07:17:48 +00:00
|
|
|
print_simple_box_start("CENTER", "90%");
|
2002-10-16 09:35:04 +00:00
|
|
|
quiz_print_question($key+1, $questionid, $grades[$questionid]->grade, $quiz->course,
|
|
|
|
$results->feedback[$questionid], $results->response[$questionid], $results->grades[$questionid]);
|
2002-10-13 07:17:48 +00:00
|
|
|
print_simple_box_end();
|
|
|
|
echo "<BR>";
|
|
|
|
}
|
2002-10-16 09:35:04 +00:00
|
|
|
|
|
|
|
if (!$results) {
|
|
|
|
echo "<CENTER><INPUT TYPE=submit VALUE=\"".get_string("savemyanswers", "quiz")."\"></CENTER>";
|
|
|
|
}
|
2002-10-13 07:17:48 +00:00
|
|
|
echo "</FORM>";
|
2002-10-14 15:57:33 +00:00
|
|
|
|
|
|
|
return true;
|
2002-10-13 07:17:48 +00:00
|
|
|
}
|
2002-10-14 09:07:13 +00:00
|
|
|
|
|
|
|
function quiz_get_default_category($courseid) {
|
|
|
|
if ($categories = get_records("quiz_categories", "course", $courseid, "id")) {
|
|
|
|
foreach ($categories as $category) {
|
|
|
|
return $category; // Return the first one (lowest id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, we need to make one
|
2002-10-14 15:57:33 +00:00
|
|
|
$category->name = get_string("default", "quiz");
|
|
|
|
$category->info = get_string("defaultinfo", "quiz");
|
2002-10-14 09:07:13 +00:00
|
|
|
$category->course = $courseid;
|
|
|
|
$category->publish = 0;
|
|
|
|
|
|
|
|
if (!$category->id = insert_record("quiz_categories", $category)) {
|
|
|
|
notify("Error creating a default category!");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return $category;
|
|
|
|
}
|
|
|
|
|
|
|
|
function quiz_print_category_form($course, $current) {
|
|
|
|
// Prints a form to choose categories
|
|
|
|
|
|
|
|
if (!$categories = get_records_sql_menu("SELECT id,name FROM quiz_categories
|
|
|
|
WHERE course='$course->id' OR publish = '1'
|
|
|
|
ORDER by name ASC")) {
|
|
|
|
if (!$category = quiz_get_default_category($course->id)) {
|
|
|
|
notify("Error creating a default category!");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$categories[$category->id] = $category->name;
|
|
|
|
}
|
2002-10-15 12:54:11 +00:00
|
|
|
foreach ($categories as $key => $category) {
|
|
|
|
if ($category->publish) {
|
|
|
|
if ($course = get_record_sql("course", "id", $category->course)) {
|
|
|
|
$categories[$key]->name .= " ($course->shortname)";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-10-14 09:07:13 +00:00
|
|
|
$strcategory = get_string("category", "quiz");
|
|
|
|
$strshow = get_string("show", "quiz");
|
2002-10-15 16:45:39 +00:00
|
|
|
$streditcats = get_string("editcategories", "quiz");
|
2002-10-14 09:07:13 +00:00
|
|
|
|
2002-10-15 16:45:39 +00:00
|
|
|
echo "<TABLE width=\"100%\"><TR><TD>";
|
2002-10-14 09:07:13 +00:00
|
|
|
echo "<FORM METHOD=POST ACTION=edit.php>";
|
|
|
|
echo "<B>$strcategory:</B> ";
|
|
|
|
choose_from_menu($categories, "cat", "$current");
|
2002-10-15 17:32:50 +00:00
|
|
|
echo "<INPUT TYPE=submit VALUE=\"$strshow\">";
|
2002-10-14 09:07:13 +00:00
|
|
|
echo "</FORM>";
|
2002-10-15 16:45:39 +00:00
|
|
|
echo "</TD><TD align=right>";
|
|
|
|
echo "<FORM METHOD=GET ACTION=category.php>";
|
|
|
|
echo "<INPUT TYPE=hidden NAME=id VALUE=\"$course->id\">";
|
|
|
|
echo "<INPUT TYPE=submit VALUE=\"$streditcats\">";
|
|
|
|
echo "</FORM>";
|
|
|
|
echo "</TD></TR></TABLE>";
|
2002-10-14 09:07:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-14 12:21:18 +00:00
|
|
|
function quiz_get_all_question_grades($questionlist, $quizid) {
|
|
|
|
// Given a list of question IDs, finds grades or invents them to
|
|
|
|
// create an array of matching grades
|
|
|
|
|
2002-10-15 17:32:50 +00:00
|
|
|
$questions = get_records_sql("SELECT question,grade FROM quiz_question_grades
|
2002-10-14 12:21:18 +00:00
|
|
|
WHERE quiz = '$quizid'
|
|
|
|
AND question IN ($questionlist)");
|
|
|
|
|
|
|
|
$list = explode(",", $questionlist);
|
|
|
|
$grades = array();
|
|
|
|
|
|
|
|
foreach ($list as $qid) {
|
|
|
|
if (isset($questions[$qid])) {
|
|
|
|
$grades[$qid] = $questions[$qid]->grade;
|
|
|
|
} else {
|
|
|
|
$grades[$qid] = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $grades;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function quiz_print_question_list($questionlist, $grades) {
|
2002-10-14 09:07:13 +00:00
|
|
|
// Prints a list of quiz questions in a small layout form with knobs
|
2002-10-14 12:21:18 +00:00
|
|
|
// $questionlist is comma-separated list
|
|
|
|
// $grades is an array of corresponding grades
|
2002-10-14 09:07:13 +00:00
|
|
|
|
|
|
|
global $THEME;
|
|
|
|
|
|
|
|
if (!$questionlist) {
|
|
|
|
echo "<P align=center>";
|
|
|
|
print_string("noquestions", "quiz");
|
|
|
|
echo "</P>";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$order = explode(",", $questionlist);
|
|
|
|
|
2002-10-14 12:21:18 +00:00
|
|
|
if (!$questions = get_records_list("quiz_questions", "id", $questionlist)) {
|
2002-10-14 09:07:13 +00:00
|
|
|
error("No questions were found!");
|
|
|
|
}
|
|
|
|
|
|
|
|
$strorder = get_string("order");
|
|
|
|
$strquestionname = get_string("questionname", "quiz");
|
|
|
|
$strgrade = get_string("grade");
|
|
|
|
$strdelete = get_string("delete");
|
|
|
|
$stredit = get_string("edit");
|
|
|
|
$strmoveup = get_string("moveup");
|
|
|
|
$strmovedown = get_string("movedown");
|
|
|
|
$strsavegrades = get_string("savegrades", "quiz");
|
|
|
|
|
2002-10-14 15:57:33 +00:00
|
|
|
for ($i=10; $i>=0; $i--) {
|
2002-10-14 12:21:18 +00:00
|
|
|
$gradesmenu[$i] = $i;
|
2002-10-14 09:07:13 +00:00
|
|
|
}
|
|
|
|
$count = 0;
|
|
|
|
$sumgrade = 0;
|
|
|
|
$total = count($order);
|
|
|
|
echo "<FORM METHOD=post ACTION=edit.php>";
|
|
|
|
echo "<TABLE BORDER=0 CELLPADDING=5 CELLSPACING=2 WIDTH=\"100%\">";
|
2002-10-14 15:57:33 +00:00
|
|
|
echo "<TR><TH WIDTH=10 COLSPAN=3>$strorder</TH><TH align=left WIDTH=\"100%\">$strquestionname</TH><TH WIDTH=10>$strgrade</TH><TH WIDTH=10>$stredit</TH></TR>";
|
2002-10-14 09:07:13 +00:00
|
|
|
foreach ($order as $qnum) {
|
|
|
|
$count++;
|
|
|
|
echo "<TR BGCOLOR=\"$THEME->cellcontent\">";
|
|
|
|
echo "<TD>$count</TD>";
|
|
|
|
echo "<TD>";
|
|
|
|
if ($count != 1) {
|
|
|
|
echo "<A TITLE=\"$strmoveup\" HREF=\"edit.php?up=$qnum\"><IMG
|
|
|
|
SRC=\"../../pix/t/up.gif\" BORDER=0></A>";
|
|
|
|
}
|
|
|
|
echo "</TD>";
|
|
|
|
echo "<TD>";
|
|
|
|
if ($count != $total) {
|
|
|
|
echo "<A TITLE=\"$strmovedown\" HREF=\"edit.php?down=$qnum\"><IMG
|
|
|
|
SRC=\"../../pix/t/down.gif\" BORDER=0></A>";
|
|
|
|
}
|
|
|
|
echo "</TD>";
|
|
|
|
echo "<TD>".$questions[$qnum]->name."</TD>";
|
|
|
|
echo "<TD>";
|
2002-10-15 12:54:11 +00:00
|
|
|
choose_from_menu($gradesmenu, "q$qnum", (string)$grades[$qnum], "");
|
2002-10-14 09:07:13 +00:00
|
|
|
echo "<TD>";
|
|
|
|
echo "<A TITLE=\"$strdelete\" HREF=\"edit.php?delete=$qnum\"><IMG
|
|
|
|
SRC=\"../../pix/t/delete.gif\" BORDER=0></A> ";
|
|
|
|
echo "<A TITLE=\"$stredit\" HREF=\"question.php?id=$qnum\"><IMG
|
|
|
|
SRC=\"../../pix/t/edit.gif\" BORDER=0></A>";
|
|
|
|
echo "</TD>";
|
|
|
|
|
2002-10-14 12:21:18 +00:00
|
|
|
$sumgrade += $grades[$qnum];
|
2002-10-14 09:07:13 +00:00
|
|
|
}
|
|
|
|
echo "<TR><TD COLSPAN=3><TD ALIGN=right>";
|
|
|
|
echo "<INPUT TYPE=submit VALUE=\"$strsavegrades:\">";
|
2002-10-15 12:54:11 +00:00
|
|
|
echo "<INPUT TYPE=hidden NAME=setgrades VALUE=\"save\">";
|
2002-10-14 09:07:13 +00:00
|
|
|
echo "<TD ALIGN=LEFT BGCOLOR=\"$THEME->cellcontent\">";
|
|
|
|
echo "<B>$sumgrade</B>";
|
|
|
|
echo "</TD><TD></TD></TR>";
|
|
|
|
echo "</TABLE>";
|
|
|
|
echo "</FORM>";
|
2002-10-14 15:57:33 +00:00
|
|
|
|
|
|
|
return $sumgrade;
|
2002-10-14 09:07:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function quiz_print_cat_question_list($categoryid) {
|
|
|
|
// Prints a form to choose categories
|
|
|
|
|
|
|
|
global $THEME, $QUIZ_QUESTION_TYPE;
|
|
|
|
|
2002-10-14 15:57:33 +00:00
|
|
|
$strcategory = get_string("category", "quiz");
|
2002-10-14 09:07:13 +00:00
|
|
|
$strquestion = get_string("question", "quiz");
|
|
|
|
$strnoquestions = get_string("noquestions", "quiz");
|
|
|
|
$strselect = get_string("select", "quiz");
|
|
|
|
$strcreatenewquestion = get_string("createnewquestion", "quiz");
|
|
|
|
$strquestionname = get_string("questionname", "quiz");
|
|
|
|
$strdelete = get_string("delete");
|
|
|
|
$stredit = get_string("edit");
|
|
|
|
$straddselectedtoquiz = get_string("addselectedtoquiz", "quiz");
|
|
|
|
|
|
|
|
if (!$categoryid) {
|
|
|
|
echo "<P align=center>";
|
|
|
|
print_string("selectcategoryabove", "quiz");
|
|
|
|
echo "</P>";
|
|
|
|
return;
|
|
|
|
}
|
2002-10-13 07:17:48 +00:00
|
|
|
|
2002-10-14 09:07:13 +00:00
|
|
|
if (!$category = get_record("quiz_categories", "id", "$categoryid")) {
|
|
|
|
notify("Category not found!");
|
|
|
|
return;
|
|
|
|
}
|
2002-10-15 12:54:11 +00:00
|
|
|
echo "<CENTER>";
|
2002-10-14 15:57:33 +00:00
|
|
|
echo text_to_html($category->info);
|
2002-10-14 09:07:13 +00:00
|
|
|
|
2002-10-14 15:57:33 +00:00
|
|
|
echo "<FORM METHOD=GET ACTION=question.php>";
|
2002-10-14 09:07:13 +00:00
|
|
|
echo "<B>$strquestion:</B> ";
|
|
|
|
choose_from_menu($QUIZ_QUESTION_TYPE, "type", "", "");
|
|
|
|
echo "<INPUT TYPE=hidden NAME=category VALUE=\"$category->id\">";
|
|
|
|
echo "<INPUT TYPE=submit NAME=new VALUE=\"$strcreatenewquestion\">";
|
|
|
|
echo "</FORM>";
|
2002-10-15 12:54:11 +00:00
|
|
|
echo "</CENTER>";
|
2002-10-14 09:07:13 +00:00
|
|
|
|
|
|
|
if (!$questions = get_records("quiz_questions", "category", $category->id)) {
|
|
|
|
echo "<P align=center>";
|
|
|
|
print_string("noquestions", "quiz");
|
|
|
|
echo "</P>";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2002-10-14 15:57:33 +00:00
|
|
|
$canedit = isteacher($category->course);
|
|
|
|
|
2002-10-14 09:07:13 +00:00
|
|
|
echo "<FORM METHOD=post ACTION=edit.php>";
|
|
|
|
echo "<TABLE BORDER=0 CELLPADDING=5 CELLSPACING=2 WIDTH=\"100%\">";
|
2002-10-14 15:57:33 +00:00
|
|
|
echo "<TR><TH width=10>$strselect</TH><TH width=* align=left>$strquestionname</TH>";
|
|
|
|
if ($canedit) {
|
|
|
|
echo "<TH width=10>$stredit</TH>";
|
|
|
|
}
|
|
|
|
echo "</TR>";
|
2002-10-14 09:07:13 +00:00
|
|
|
foreach ($questions as $question) {
|
|
|
|
echo "<TR BGCOLOR=\"$THEME->cellcontent\">";
|
|
|
|
echo "<TD ALIGN=CENTER>";
|
|
|
|
echo "<INPUT TYPE=CHECKBOX NAME=q$question->id VALUE=\"1\">";
|
|
|
|
echo "</TD>";
|
|
|
|
echo "<TD>".$question->name."</TD>";
|
2002-10-14 15:57:33 +00:00
|
|
|
if ($canedit) {
|
|
|
|
echo "<TD>";
|
|
|
|
echo "<A TITLE=\"$strdelete\" HREF=\"question.php?delete=$question->id\"><IMG
|
|
|
|
SRC=\"../../pix/t/delete.gif\" BORDER=0></A> ";
|
|
|
|
echo "<A TITLE=\"$stredit\" HREF=\"question.php?id=$question->id\"><IMG
|
|
|
|
SRC=\"../../pix/t/edit.gif\" BORDER=0></A>";
|
|
|
|
echo "</TD></TR>";
|
|
|
|
}
|
|
|
|
echo "</TR>";
|
2002-10-14 09:07:13 +00:00
|
|
|
}
|
|
|
|
echo "<TR><TD COLSPAN=3>";
|
|
|
|
echo "<INPUT TYPE=hidden NAME=add VALUE=\"1\">";
|
|
|
|
echo "<INPUT TYPE=submit VALUE=\"<< $straddselectedtoquiz\">";
|
|
|
|
echo "</TD></TR>";
|
|
|
|
echo "</TABLE>";
|
|
|
|
echo "</FORM>";
|
|
|
|
}
|
2002-10-13 07:17:48 +00:00
|
|
|
|
2002-10-06 03:23:16 +00:00
|
|
|
|
|
|
|
function quiz_get_user_attempts($quizid, $userid) {
|
2002-10-13 07:17:48 +00:00
|
|
|
// Returns a list of all attempts by a user
|
2002-10-06 03:23:16 +00:00
|
|
|
return get_records_sql("SELECT * FROM quiz_attempts WHERE quiz = '$quizid' and user = '$userid' ORDER by attempt ASC");
|
|
|
|
}
|
|
|
|
|
2002-10-15 12:54:11 +00:00
|
|
|
|
|
|
|
function quiz_get_user_attempts_string($quiz, $attempts, $bestgrade) {
|
|
|
|
/// Returns a simple little comma-separated list of all attempts,
|
|
|
|
/// with the best grade bolded
|
|
|
|
|
|
|
|
$bestgrade = format_float($bestgrade);
|
|
|
|
foreach ($attempts as $attempt) {
|
|
|
|
$attemptgrade = format_float(($attempt->sumgrades / $quiz->sumgrades) * $quiz->grade);
|
|
|
|
if ($attemptgrade == $bestgrade) {
|
|
|
|
$userattempts[] = "<B>$attemptgrade</B>";
|
|
|
|
} else {
|
|
|
|
$userattempts[] = "$attemptgrade";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return implode(",", $userattempts);
|
|
|
|
}
|
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
function quiz_get_best_grade($quizid, $userid) {
|
|
|
|
/// Get the best current grade for a particular user in a quiz
|
2002-10-06 03:23:16 +00:00
|
|
|
if (!$grade = get_record_sql("SELECT * FROM quiz_grades WHERE quiz = '$quizid' and user = '$userid'")) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $grade->grade;
|
|
|
|
}
|
|
|
|
|
2002-10-13 13:51:56 +00:00
|
|
|
function quiz_get_grade_records($quiz) {
|
|
|
|
/// Gets all info required to display the table of quiz results
|
|
|
|
/// for report.php
|
|
|
|
|
|
|
|
return get_records_sql("SELECT qg.*, u.firstname, u.lastname, u.picture
|
|
|
|
FROM quiz_grades qg, user u
|
|
|
|
WHERE qg.quiz = '$quiz->id'
|
|
|
|
AND qg.user = u.id");
|
|
|
|
}
|
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
function quiz_save_best_grade($quiz, $user) {
|
|
|
|
/// Calculates the best grade out of all attempts at a quiz for a user,
|
|
|
|
/// and then saves that grade in the quiz_grades table.
|
|
|
|
|
|
|
|
if (!$attempts = quiz_get_user_attempts($quiz->id, $user->id)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$bestgrade = quiz_calculate_best_grade($quiz, $attempts);
|
|
|
|
$bestgrade = (($bestgrade / $quiz->sumgrades) * $quiz->grade);
|
|
|
|
|
|
|
|
if ($grade = get_record_sql("SELECT * FROM quiz_grades WHERE quiz='$quiz->id' AND user='$user->id'")) {
|
|
|
|
$grade->grade = $bestgrade;
|
|
|
|
$grade->timemodified = time();
|
|
|
|
if (!update_record("quiz_grades", $grade)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$grade->quiz = $quiz->id;
|
|
|
|
$grade->user = $user->id;
|
|
|
|
$grade->grade = $bestgrade;
|
|
|
|
$grade->timemodified = time();
|
|
|
|
if (!insert_record("quiz_grades", $grade)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-15 10:04:28 +00:00
|
|
|
function quiz_get_answers($question) {
|
2002-10-13 07:17:48 +00:00
|
|
|
// Given a question, returns the correct answers and grades
|
|
|
|
switch ($question->type) {
|
|
|
|
case SHORTANSWER; // Could be multiple answers
|
2002-10-15 10:04:28 +00:00
|
|
|
return get_records_sql("SELECT a.*, sa.usecase, g.grade
|
2002-10-13 07:17:48 +00:00
|
|
|
FROM quiz_shortanswer sa, quiz_answers a, quiz_question_grades g
|
|
|
|
WHERE sa.question = '$question->id'
|
|
|
|
AND sa.question = a.question
|
|
|
|
AND sa.question = g.question");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TRUEFALSE; // Should be always two answers
|
|
|
|
return get_records_sql("SELECT a.*, g.grade
|
|
|
|
FROM quiz_answers a, quiz_question_grades g
|
|
|
|
WHERE a.question = '$question->id'
|
|
|
|
AND a.question = g.question");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MULTICHOICE; // Should be multiple answers
|
|
|
|
return get_records_sql("SELECT a.*, mc.single, g.grade
|
|
|
|
FROM quiz_multichoice mc, quiz_answers a, quiz_question_grades g
|
|
|
|
WHERE mc.question = '$question->id'
|
|
|
|
AND mc.question = a.question
|
|
|
|
AND mc.question = g.question");
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-10-06 03:23:16 +00:00
|
|
|
function quiz_calculate_best_grade($quiz, $attempts) {
|
2002-10-13 07:17:48 +00:00
|
|
|
/// Calculate the best grade for a quiz given a number of attempts by a particular user.
|
2002-10-06 03:23:16 +00:00
|
|
|
|
|
|
|
switch ($quiz->grademethod) {
|
2002-10-13 07:17:48 +00:00
|
|
|
|
|
|
|
case ATTEMPTFIRST:
|
2002-10-06 03:23:16 +00:00
|
|
|
foreach ($attempts as $attempt) {
|
2002-10-13 07:17:48 +00:00
|
|
|
return $attempt->sumgrades;
|
2002-10-06 03:23:16 +00:00
|
|
|
}
|
2002-10-13 07:17:48 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ATTEMPTLAST:
|
|
|
|
foreach ($attempts as $attempt) {
|
|
|
|
$final = $attempt->sumgrades;
|
|
|
|
}
|
|
|
|
return $final;
|
2002-10-06 03:23:16 +00:00
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
case GRADEAVERAGE:
|
2002-10-06 03:23:16 +00:00
|
|
|
$sum = 0;
|
|
|
|
$count = 0;
|
|
|
|
foreach ($attempts as $attempt) {
|
2002-10-13 07:17:48 +00:00
|
|
|
$sum += $attempt->sumgrades;
|
2002-10-06 03:23:16 +00:00
|
|
|
$count++;
|
|
|
|
}
|
|
|
|
return (float)$sum/$count;
|
|
|
|
|
|
|
|
default:
|
2002-10-13 07:17:48 +00:00
|
|
|
case GRADEHIGHEST:
|
|
|
|
$max = 0;
|
2002-10-06 03:23:16 +00:00
|
|
|
foreach ($attempts as $attempt) {
|
2002-10-13 07:17:48 +00:00
|
|
|
if ($attempt->sumgrades > $max) {
|
|
|
|
$max = $attempt->sumgrades;
|
|
|
|
}
|
2002-10-06 03:23:16 +00:00
|
|
|
}
|
2002-10-13 07:17:48 +00:00
|
|
|
return $max;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function quiz_save_attempt($quiz, $questions, $result, $attemptnum) {
|
|
|
|
/// Given a quiz, a list of attempted questions and a total grade
|
|
|
|
/// this function saves EVERYTHING so it can be reconstructed later
|
|
|
|
/// if necessary.
|
|
|
|
|
|
|
|
global $USER;
|
|
|
|
|
|
|
|
// First let's save the attempt record itself
|
|
|
|
|
|
|
|
$attempt->quiz = $quiz->id;
|
|
|
|
$attempt->user = $USER->id;
|
|
|
|
$attempt->attempt = $attemptnum;
|
|
|
|
$attempt->sumgrades = $result->sumgrades;
|
|
|
|
$attempt->timemodified = time();
|
|
|
|
|
|
|
|
if (!$attempt->id = insert_record("quiz_attempts", $attempt)) {
|
2002-10-15 17:13:11 +00:00
|
|
|
notify("Error while saving attempt");
|
2002-10-13 07:17:48 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now let's save all the questions for this attempt
|
|
|
|
|
|
|
|
foreach ($questions as $question) {
|
|
|
|
$response->attempt = $attempt->id;
|
|
|
|
$response->question = $question->id;
|
|
|
|
$response->grade = $result->grades[$question->id];
|
|
|
|
if ($question->answer) {
|
|
|
|
$response->answer = implode(",",$question->answer);
|
|
|
|
} else {
|
|
|
|
$response->answer = "";
|
|
|
|
}
|
|
|
|
if (!insert_record("quiz_responses", $response)) {
|
2002-10-15 17:13:11 +00:00
|
|
|
notify("Error while saving response");
|
2002-10-13 07:17:48 +00:00
|
|
|
return false;
|
|
|
|
}
|
2002-10-06 03:23:16 +00:00
|
|
|
}
|
2002-10-13 07:17:48 +00:00
|
|
|
return true;
|
2002-10-06 03:23:16 +00:00
|
|
|
}
|
2002-10-04 02:59:05 +00:00
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
|
|
|
|
function quiz_grade_attempt_results($quiz, $questions) {
|
|
|
|
/// Given a list of questions (including answers for each one)
|
|
|
|
/// this function does all the hard work of calculating the
|
|
|
|
/// grades for each question, as well as a total grade for
|
|
|
|
/// for the whole quiz. It returns everything in a structure
|
|
|
|
/// that looks like:
|
|
|
|
/// $result->sumgrades (sum of all grades for all questions)
|
|
|
|
/// $result->percentage (Percentage of grades that were correct)
|
|
|
|
/// $result->grade (final grade result for the whole quiz)
|
|
|
|
/// $result->grades[] (array of grades, indexed by question id)
|
2002-10-16 09:35:04 +00:00
|
|
|
/// $result->response[] (array of response arrays, indexed by question id)
|
2002-10-13 07:17:48 +00:00
|
|
|
/// $result->feedback[] (array of feedback arrays, indexed by question id)
|
|
|
|
|
|
|
|
if (!$questions) {
|
|
|
|
error("No questions!");
|
|
|
|
}
|
|
|
|
|
|
|
|
$result->sumgrades = 0;
|
|
|
|
|
|
|
|
foreach ($questions as $question) {
|
2002-10-15 10:04:28 +00:00
|
|
|
if (!$answers = quiz_get_answers($question)) {
|
|
|
|
error("No answers defined for question id $question->id!");
|
2002-10-13 07:17:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$grade = 0; // default
|
2002-10-16 15:52:29 +00:00
|
|
|
$feedback = array();
|
|
|
|
$response = array();
|
2002-10-13 07:17:48 +00:00
|
|
|
|
|
|
|
switch ($question->type) {
|
|
|
|
case SHORTANSWER:
|
|
|
|
if ($question->answer) {
|
|
|
|
$question->answer = $question->answer[0];
|
|
|
|
} else {
|
2002-10-16 15:52:29 +00:00
|
|
|
$question->answer = "";
|
2002-10-13 07:17:48 +00:00
|
|
|
}
|
2002-10-16 09:35:04 +00:00
|
|
|
$response[0] = $question->answer;
|
2002-10-13 07:17:48 +00:00
|
|
|
foreach($answers as $answer) { // There might be multiple right answers
|
2002-10-15 10:04:28 +00:00
|
|
|
if (!$answer->usecase) { // Don't compare case
|
2002-10-13 07:17:48 +00:00
|
|
|
$answer->answer = strtolower($answer->answer);
|
|
|
|
$question->answer = strtolower($question->answer);
|
|
|
|
}
|
|
|
|
if ($question->answer == $answer->answer) {
|
2002-10-16 09:35:04 +00:00
|
|
|
$feedback[0] = $answer->feedback;
|
2002-10-13 07:17:48 +00:00
|
|
|
$grade = (float)$answer->fraction * $answer->grade;
|
2002-10-16 09:35:04 +00:00
|
|
|
continue;
|
2002-10-13 07:17:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case TRUEFALSE:
|
|
|
|
if ($question->answer) {
|
|
|
|
$question->answer = $question->answer[0];
|
|
|
|
} else {
|
|
|
|
$question->answer = NULL;
|
|
|
|
}
|
|
|
|
foreach($answers as $answer) { // There should be two answers (true and false)
|
|
|
|
$feedback[$answer->id] = $answer->feedback;
|
|
|
|
if ($question->answer == $answer->id) {
|
|
|
|
$grade = (float)$answer->fraction * $answer->grade;
|
2002-10-16 09:35:04 +00:00
|
|
|
$response[$answer->id] = true;
|
2002-10-13 07:17:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case MULTICHOICE:
|
|
|
|
foreach($answers as $answer) { // There will be multiple answers, perhaps more than one is right
|
|
|
|
$feedback[$answer->id] = $answer->feedback;
|
|
|
|
if ($question->answer) {
|
|
|
|
foreach ($question->answer as $questionanswer) {
|
|
|
|
if ($questionanswer == $answer->id) {
|
|
|
|
if ($answer->single) {
|
|
|
|
$grade = (float)$answer->fraction * $answer->grade;
|
2002-10-16 09:35:04 +00:00
|
|
|
$response[$answer->id] = true;
|
2002-10-13 07:17:48 +00:00
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
$grade += (float)$answer->fraction * $answer->grade;
|
2002-10-16 09:35:04 +00:00
|
|
|
$response[$answer->id] = true;
|
2002-10-13 07:17:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
if ($grade < 0.0) { // No negative grades
|
|
|
|
$grade = 0.0;
|
|
|
|
}
|
2002-10-14 15:57:33 +00:00
|
|
|
|
2002-10-13 07:17:48 +00:00
|
|
|
$result->grades[$question->id] = $grade;
|
|
|
|
$result->sumgrades += $grade;
|
|
|
|
$result->feedback[$question->id] = $feedback;
|
2002-10-16 09:35:04 +00:00
|
|
|
$result->response[$question->id] = $response;
|
2002-10-13 07:17:48 +00:00
|
|
|
}
|
|
|
|
|
2002-10-15 12:54:11 +00:00
|
|
|
$fraction = (float)($result->sumgrades / $quiz->sumgrades);
|
|
|
|
$result->percentage = format_float($fraction * 100.0);
|
|
|
|
$result->grade = format_float($fraction * $quiz->grade);
|
2002-10-13 07:17:48 +00:00
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2002-10-04 02:59:05 +00:00
|
|
|
?>
|