Many new additions - code not quite usable yet, but getting close
[moodle.git] / mod / quiz / lib.php
CommitLineData
730fd187 1<?PHP // $Id$
2
a5e1f35c 3/// Library of function for module quiz
730fd187 4
a5e1f35c 5/// CONSTANTS ///////////////////////////////////////////////////////////////////
730fd187 6
a5e1f35c 7define("GRADEHIGHEST", "1");
8define("GRADEAVERAGE", "2");
9define("ATTEMPTFIRST", "3");
10define("ATTEMPTLAST", "4");
11$QUIZ_GRADE_METHOD = array ( GRADEHIGHEST => get_string("gradehighest", "quiz"),
12 GRADEAVERAGE => get_string("gradeaverage", "quiz"),
13 ATTEMPTFIRST => get_string("attemptfirst", "quiz"),
14 ATTEMPTLAST => get_string("attemptlast", "quiz"));
15
16define("SHORTANSWER", "1");
17define("TRUEFALSE", "2");
18define("MULTICHOICE", "3");
19$QUIZ_QUESTION_TYPE = array ( SHORTANSWER => get_string("shortanswer", "quiz"),
20 TRUEFALSE => get_string("truefalse", "quiz"),
21 MULTICHOICE => get_string("multichoice", "quiz"));
22
23
24
25/// FUNCTIONS ///////////////////////////////////////////////////////////////////
730fd187 26
27function quiz_add_instance($quiz) {
a5e1f35c 28/// Given an object containing all the necessary data,
29/// (defined by the form in mod.html) this function
30/// will create a new instance and return the id number
31/// of the new instance.
730fd187 32
33 $quiz->timemodified = time();
34
35 # May have to add extra stuff in here #
36
37 return insert_record("quiz", $quiz);
38}
39
40
41function quiz_update_instance($quiz) {
a5e1f35c 42/// Given an object containing all the necessary data,
43/// (defined by the form in mod.html) this function
44/// will update an existing instance with new data.
730fd187 45
46 $quiz->timemodified = time();
47 $quiz->id = $quiz->instance;
48
49 # May have to add extra stuff in here #
50
51 return update_record("quiz", $quiz);
52}
53
54
55function quiz_delete_instance($id) {
a5e1f35c 56/// Given an ID of an instance of this module,
57/// this function will permanently delete the instance
58/// and any data that depends on it.
730fd187 59
60 if (! $quiz = get_record("quiz", "id", "$id")) {
61 return false;
62 }
63
64 $result = true;
65
66 # Delete any dependent records here #
67
68 if (! delete_records("quiz", "id", "$quiz->id")) {
69 $result = false;
70 }
71
72 return $result;
73}
74
75function quiz_user_outline($course, $user, $mod, $quiz) {
a5e1f35c 76/// Return a small object with summary information about what a
77/// user has done with a given particular instance of this module
78/// Used for user activity reports.
79/// $return->time = the time they did it
80/// $return->info = a short text description
730fd187 81
82 return $return;
83}
84
85function quiz_user_complete($course, $user, $mod, $quiz) {
a5e1f35c 86/// Print a detailed representation of what a user has done with
87/// a given particular instance of this module, for user activity reports.
730fd187 88
89 return true;
90}
91
92function quiz_print_recent_activity(&$logs, $isteacher=false) {
a5e1f35c 93/// Given a list of logs, assumed to be those since the last login
94/// this function prints a short list of changes related to this module
95/// If isteacher is true then perhaps additional information is printed.
96/// This function is called from course/lib.php: print_recent_activity()
730fd187 97
98 global $CFG, $COURSE_TEACHER_COLOR;
99
100 return $content; // True if anything was printed, otherwise false
101}
102
103function quiz_cron () {
a5e1f35c 104/// Function to be run periodically according to the moodle cron
105/// This function searches for things that need to be done, such
106/// as sending out mail, toggling flags etc ...
730fd187 107
108 global $CFG;
109
110 return true;
111}
112
113
114//////////////////////////////////////////////////////////////////////////////////////
a5e1f35c 115/// Any other quiz functions go here. Each of them must have a name that
116/// starts with quiz_
730fd187 117
14d8c0b4 118function quiz_print_question($number, $questionid, $grade, $courseid) {
a5e1f35c 119/// Prints a quiz question, any format
14d8c0b4 120
121 if (!$question = get_record("quiz_questions", "id", $questionid)) {
122 notify("Error: Question not found!");
123 }
124
125 $stranswer = get_string("answer", "quiz");
126 $strmarks = get_string("marks", "quiz");
127
128 echo "<TABLE WIDTH=100% CELLSPACING=10><TR><TD NOWRAP WIDTH=100 VALIGN=top>";
129 echo "<P ALIGN=CENTER><B>$number</B><BR><FONT SIZE=1>$grade $strmarks</FONT></P>";
130 print_spacer(1,100);
131 echo "</TD><TD VALIGN=TOP>";
132
133 switch ($question->type) {
a5e1f35c 134 case SHORTANSWER:
14d8c0b4 135 if (!$options = get_record("quiz_shortanswer", "question", $question->id)) {
136 notify("Error: Missing question options!");
137 }
14d8c0b4 138 echo "<P>$question->question</P>";
139 if ($question->image) {
140 print_file_picture($question->image, $courseid, 200);
141 }
142 echo "<P ALIGN=RIGHT>$stranswer: <INPUT TYPE=TEXT NAME=q$question->id SIZE=20></P>";
143 break;
144
a5e1f35c 145 case TRUEFALSE:
14d8c0b4 146 if (!$options = get_record("quiz_truefalse", "question", $question->id)) {
147 notify("Error: Missing question options!");
148 }
149 if (!$true = get_record("quiz_answers", "id", $options->true)) {
150 notify("Error: Missing question answers!");
151 }
152 if (!$false = get_record("quiz_answers", "id", $options->false)) {
153 notify("Error: Missing question answers!");
154 }
155 if (!$true->answer) {
156 $true->answer = get_string("true", "quiz");
157 }
158 if (!$false->answer) {
159 $false->answer = get_string("false", "quiz");
160 }
161 echo "<P>$question->question</P>";
162 if ($question->image) {
163 print_file_picture($question->image, $courseid, 200);
164 }
165 echo "<P ALIGN=RIGHT>$stranswer:&nbsp;&nbsp;";
166 echo "<INPUT TYPE=RADIO NAME=\"q$question->id\" VALUE=\"$true->id\">$true->answer";
167 echo "&nbsp;&nbsp;&nbsp;";
168 echo "<INPUT TYPE=RADIO NAME=\"q$question->id\" VALUE=\"$false->id\">$false->answer</P>";
169 break;
170
a5e1f35c 171 case MULTICHOICE:
14d8c0b4 172 if (!$options = get_record("quiz_multichoice", "question", $question->id)) {
173 notify("Error: Missing question options!");
174 }
a5e1f35c 175 if (!$answers = get_records_list("quiz_answers", "id", $options->answers)) {
14d8c0b4 176 notify("Error: Missing question answers!");
177 }
178 echo "<P>$question->question</P>";
179 if ($question->image) {
180 print_file_picture($question->image, $courseid, 200);
181 }
182 echo "<TABLE ALIGN=right>";
183 echo "<TR><TD valign=top>$stranswer:&nbsp;&nbsp;</TD><TD>";
184 echo "<TABLE ALIGN=right>";
185 $answerids = explode(",", $options->answers);
186 foreach ($answerids as $key => $answerid) {
187 $answer = $answers[$answerid];
188 $qnum = $key + 1;
189 echo "<TR><TD valign=top>";
a5e1f35c 190 if ($options->single) {
14d8c0b4 191 echo "<INPUT TYPE=RADIO NAME=q$question->id VALUE=\"$answer->id\">";
192 } else {
a5e1f35c 193 echo "<INPUT TYPE=CHECKBOX NAME=q$question->id"."a$answer->id VALUE=\"$answer->id\">";
14d8c0b4 194 }
195 echo "</TD>";
196 echo "<TD valign=top>$qnum. $answer->answer</TD>";
197 echo "</TR>";
198 }
199 echo "</TABLE>";
200 echo "</TABLE>";
201 break;
202
203 default:
204 notify("Error: Unknown question type!");
205 }
206
207 echo "</TD></TR></TABLE>";
3a506ca2 208}
209
a5e1f35c 210function quiz_print_quiz_questions($quiz, $results=NULL) {
211// Prints a whole quiz on one page.
212
213 if (!$quiz->questions) {
214 error("No questions have been defined!", "view.php?id=$cm->id");
215 }
216
217 $questions = explode(",", $quiz->questions);
218
219 if (!$grades = get_records_list("quiz_question_grades", "question", $quiz->questions, "", "question,grade")) {
220 error("No grades were found for these questions!");
221 }
222
223 echo "<FORM METHOD=POST ACTION=attempt.php>";
224 echo "<INPUT TYPE=hidden NAME=q VALUE=\"$quiz->id\">";
225 foreach ($questions as $key => $questionid) {
226 print_simple_box_start("CENTER", "90%");
227 quiz_print_question($key+1, $questionid, $grades[$questionid]->grade, $course->id);
228 print_simple_box_end();
229 echo "<BR>";
230 }
231 echo "<CENTER><INPUT TYPE=submit VALUE=\"".get_string("savemyanswers", "quiz")."\"></CENTER>";
232 echo "</FORM>";
233}
6a952ce7 234
235function quiz_get_default_category($courseid) {
236 if ($categories = get_records("quiz_categories", "course", $courseid, "id")) {
237 foreach ($categories as $category) {
238 return $category; // Return the first one (lowest id)
239 }
240 }
241
242 // Otherwise, we need to make one
243 $category->name = get_string("miscellaneous", "quiz");
244 $category->info = get_string("miscellaneous", "quiz");
245 $category->course = $courseid;
246 $category->publish = 0;
247
248 if (!$category->id = insert_record("quiz_categories", $category)) {
249 notify("Error creating a default category!");
250 return false;
251 }
252 return $category;
253}
254
255function quiz_print_category_form($course, $current) {
256// Prints a form to choose categories
257
258 if (!$categories = get_records_sql_menu("SELECT id,name FROM quiz_categories
259 WHERE course='$course->id' OR publish = '1'
260 ORDER by name ASC")) {
261 if (!$category = quiz_get_default_category($course->id)) {
262 notify("Error creating a default category!");
263 return false;
264 }
265 $categories[$category->id] = $category->name;
266 }
267 $strcategory = get_string("category", "quiz");
268 $strshow = get_string("show", "quiz");
269 $strrename = get_string("rename", "quiz");
270 $strdelete = get_string("delete");
271 $strnew = get_string("new");
272
273 echo "<FORM METHOD=POST ACTION=edit.php>";
274 echo "<B>$strcategory:</B>&nbsp;";
275 choose_from_menu($categories, "cat", "$current");
276 echo "<INPUT TYPE=submit NAME=catshow VALUE=\"$strshow\">";
277 echo "<INPUT TYPE=submit NAME=catrename VALUE=\"$strrename\">";
278 echo "<INPUT TYPE=submit NAME=catdelete VALUE=\"$strdelete\">";
279 echo "<INPUT TYPE=submit NAME=catnew VALUE=\"$strnew\">";
280 echo "</FORM>";
281}
282
283
284function quiz_print_question_list($questionlist) {
285// Prints a list of quiz questions in a small layout form with knobs
286
287 global $THEME;
288
289 if (!$questionlist) {
290 echo "<P align=center>";
291 print_string("noquestions", "quiz");
292 echo "</P>";
293 return;
294 }
295
296 $order = explode(",", $questionlist);
297
298 if (!$questions = get_records_sql("SELECT q.*, qg.grade FROM quiz_questions q, quiz_question_grades qg
299 WHERE q.id in ($questionlist) and qg.question = q.id")) {
300 error("No questions were found!");
301 }
302
303 $strorder = get_string("order");
304 $strquestionname = get_string("questionname", "quiz");
305 $strgrade = get_string("grade");
306 $strdelete = get_string("delete");
307 $stredit = get_string("edit");
308 $strmoveup = get_string("moveup");
309 $strmovedown = get_string("movedown");
310 $strsavegrades = get_string("savegrades", "quiz");
311
312 for ($i=100; $i>=0; $i--) {
313 $grades[$i] = $i;
314 }
315 $count = 0;
316 $sumgrade = 0;
317 $total = count($order);
318 echo "<FORM METHOD=post ACTION=edit.php>";
319 echo "<TABLE BORDER=0 CELLPADDING=5 CELLSPACING=2 WIDTH=\"100%\">";
320 echo "<TR><TH COLSPAN=3>$strorder</TH><TH align=left>$strquestionname</TH><TH>$strgrade</TH><TH>$stredit</TH></TR>";
321 foreach ($order as $qnum) {
322 $count++;
323 echo "<TR BGCOLOR=\"$THEME->cellcontent\">";
324 echo "<TD>$count</TD>";
325 echo "<TD>";
326 if ($count != 1) {
327 echo "<A TITLE=\"$strmoveup\" HREF=\"edit.php?up=$qnum\"><IMG
328 SRC=\"../../pix/t/up.gif\" BORDER=0></A>";
329 }
330 echo "</TD>";
331 echo "<TD>";
332 if ($count != $total) {
333 echo "<A TITLE=\"$strmovedown\" HREF=\"edit.php?down=$qnum\"><IMG
334 SRC=\"../../pix/t/down.gif\" BORDER=0></A>";
335 }
336 echo "</TD>";
337 echo "<TD>".$questions[$qnum]->name."</TD>";
338 echo "<TD>";
339 choose_from_menu($grades, "q$qnum", $questions[$qnum]->grade, "");
340 echo "<TD>";
341 echo "<A TITLE=\"$strdelete\" HREF=\"edit.php?delete=$qnum\"><IMG
342 SRC=\"../../pix/t/delete.gif\" BORDER=0></A>&nbsp;";
343 echo "<A TITLE=\"$stredit\" HREF=\"question.php?id=$qnum\"><IMG
344 SRC=\"../../pix/t/edit.gif\" BORDER=0></A>";
345 echo "</TD>";
346
347 $sumgrade += $questions[$qnum]->grade;
348 }
349 echo "<TR><TD COLSPAN=3><TD ALIGN=right>";
350 echo "<INPUT TYPE=submit VALUE=\"$strsavegrades:\">";
351 echo "<INPUT TYPE=hidden NAME=grade VALUE=\"save\">";
352 echo "<TD ALIGN=LEFT BGCOLOR=\"$THEME->cellcontent\">";
353 echo "<B>$sumgrade</B>";
354 echo "</TD><TD></TD></TR>";
355 echo "</TABLE>";
356 echo "</FORM>";
357}
358
359
360function quiz_print_cat_question_list($categoryid) {
361// Prints a form to choose categories
362
363 global $THEME, $QUIZ_QUESTION_TYPE;
364
365 $strquestion = get_string("question", "quiz");
366 $strnoquestions = get_string("noquestions", "quiz");
367 $strselect = get_string("select", "quiz");
368 $strcreatenewquestion = get_string("createnewquestion", "quiz");
369 $strquestionname = get_string("questionname", "quiz");
370 $strdelete = get_string("delete");
371 $stredit = get_string("edit");
372 $straddselectedtoquiz = get_string("addselectedtoquiz", "quiz");
373
374 if (!$categoryid) {
375 echo "<P align=center>";
376 print_string("selectcategoryabove", "quiz");
377 echo "</P>";
378 return;
379 }
a5e1f35c 380
6a952ce7 381 if (!$category = get_record("quiz_categories", "id", "$categoryid")) {
382 notify("Category not found!");
383 return;
384 }
385 echo "<P>$category->info</P>";
386
387 echo "<FORM METHOD=POST ACTION=question.php>";
388 echo "<B>$strquestion:</B>&nbsp;";
389 choose_from_menu($QUIZ_QUESTION_TYPE, "type", "", "");
390 echo "<INPUT TYPE=hidden NAME=category VALUE=\"$category->id\">";
391 echo "<INPUT TYPE=submit NAME=new VALUE=\"$strcreatenewquestion\">";
392 echo "</FORM>";
393
394 if (!$questions = get_records("quiz_questions", "category", $category->id)) {
395 echo "<P align=center>";
396 print_string("noquestions", "quiz");
397 echo "</P>";
398 return;
399 }
400
401 echo "<FORM METHOD=post ACTION=edit.php>";
402 echo "<TABLE BORDER=0 CELLPADDING=5 CELLSPACING=2 WIDTH=\"100%\">";
403 echo "<TR><TH width=10>$strselect</TH><TH width=* align=left>$strquestionname</TH><TH width=10>$stredit</TH></TR>";
404 foreach ($questions as $question) {
405 echo "<TR BGCOLOR=\"$THEME->cellcontent\">";
406 echo "<TD ALIGN=CENTER>";
407 echo "<INPUT TYPE=CHECKBOX NAME=q$question->id VALUE=\"1\">";
408 echo "</TD>";
409 echo "<TD>".$question->name."</TD>";
410 echo "<TD>";
411 echo "<A TITLE=\"$strdelete\" HREF=\"question.php?delete=$question->id\"><IMG
412 SRC=\"../../pix/t/delete.gif\" BORDER=0></A>&nbsp;";
413 echo "<A TITLE=\"$stredit\" HREF=\"question.php?id=$question->id\"><IMG
414 SRC=\"../../pix/t/edit.gif\" BORDER=0></A>";
415 echo "</TD></TR>";
416 }
417 echo "<TR><TD COLSPAN=3>";
418 echo "<INPUT TYPE=hidden NAME=add VALUE=\"1\">";
419 echo "<INPUT TYPE=submit VALUE=\"<< $straddselectedtoquiz\">";
420 echo "</TD></TR>";
421 echo "</TABLE>";
422 echo "</FORM>";
423}
a5e1f35c 424
3a506ca2 425
426function quiz_get_user_attempts($quizid, $userid) {
a5e1f35c 427// Returns a list of all attempts by a user
3a506ca2 428 return get_records_sql("SELECT * FROM quiz_attempts WHERE quiz = '$quizid' and user = '$userid' ORDER by attempt ASC");
429}
430
a5e1f35c 431function quiz_get_best_grade($quizid, $userid) {
432/// Get the best current grade for a particular user in a quiz
3a506ca2 433 if (!$grade = get_record_sql("SELECT * FROM quiz_grades WHERE quiz = '$quizid' and user = '$userid'")) {
434 return 0;
435 }
436
437 return $grade->grade;
438}
439
579ddad5 440function quiz_get_grade_records($quiz) {
441/// Gets all info required to display the table of quiz results
442/// for report.php
443
444 return get_records_sql("SELECT qg.*, u.firstname, u.lastname, u.picture
445 FROM quiz_grades qg, user u
446 WHERE qg.quiz = '$quiz->id'
447 AND qg.user = u.id");
448}
449
a5e1f35c 450function quiz_save_best_grade($quiz, $user) {
451/// Calculates the best grade out of all attempts at a quiz for a user,
452/// and then saves that grade in the quiz_grades table.
453
454 if (!$attempts = quiz_get_user_attempts($quiz->id, $user->id)) {
455 return false;
456 }
457
458 $bestgrade = quiz_calculate_best_grade($quiz, $attempts);
459 $bestgrade = (($bestgrade / $quiz->sumgrades) * $quiz->grade);
460
461 if ($grade = get_record_sql("SELECT * FROM quiz_grades WHERE quiz='$quiz->id' AND user='$user->id'")) {
462 $grade->grade = $bestgrade;
463 $grade->timemodified = time();
464 if (!update_record("quiz_grades", $grade)) {
465 return false;
466 }
467 } else {
468 $grade->quiz = $quiz->id;
469 $grade->user = $user->id;
470 $grade->grade = $bestgrade;
471 $grade->timemodified = time();
472 if (!insert_record("quiz_grades", $grade)) {
473 return false;
474 }
475 }
476 return true;
477}
478
479
480function quiz_get_answer($question) {
481// Given a question, returns the correct answers and grades
482 switch ($question->type) {
483 case SHORTANSWER; // Could be multiple answers
484 return get_records_sql("SELECT a.*, sa.case, g.grade
485 FROM quiz_shortanswer sa, quiz_answers a, quiz_question_grades g
486 WHERE sa.question = '$question->id'
487 AND sa.question = a.question
488 AND sa.question = g.question");
489 break;
490
491 case TRUEFALSE; // Should be always two answers
492 return get_records_sql("SELECT a.*, g.grade
493 FROM quiz_answers a, quiz_question_grades g
494 WHERE a.question = '$question->id'
495 AND a.question = g.question");
496 break;
497
498 case MULTICHOICE; // Should be multiple answers
499 return get_records_sql("SELECT a.*, mc.single, g.grade
500 FROM quiz_multichoice mc, quiz_answers a, quiz_question_grades g
501 WHERE mc.question = '$question->id'
502 AND mc.question = a.question
503 AND mc.question = g.question");
504 break;
505
506 default:
507 return false;
508 }
509}
510
3a506ca2 511function quiz_calculate_best_grade($quiz, $attempts) {
a5e1f35c 512/// Calculate the best grade for a quiz given a number of attempts by a particular user.
3a506ca2 513
514 switch ($quiz->grademethod) {
a5e1f35c 515
516 case ATTEMPTFIRST:
3a506ca2 517 foreach ($attempts as $attempt) {
a5e1f35c 518 return $attempt->sumgrades;
3a506ca2 519 }
a5e1f35c 520 break;
521
522 case ATTEMPTLAST:
523 foreach ($attempts as $attempt) {
524 $final = $attempt->sumgrades;
525 }
526 return $final;
3a506ca2 527
a5e1f35c 528 case GRADEAVERAGE:
3a506ca2 529 $sum = 0;
530 $count = 0;
531 foreach ($attempts as $attempt) {
a5e1f35c 532 $sum += $attempt->sumgrades;
3a506ca2 533 $count++;
534 }
535 return (float)$sum/$count;
536
3a506ca2 537 default:
a5e1f35c 538 case GRADEHIGHEST:
539 $max = 0;
3a506ca2 540 foreach ($attempts as $attempt) {
a5e1f35c 541 if ($attempt->sumgrades > $max) {
542 $max = $attempt->sumgrades;
543 }
3a506ca2 544 }
a5e1f35c 545 return $max;
546 }
547}
548
549function quiz_save_attempt($quiz, $questions, $result, $attemptnum) {
550/// Given a quiz, a list of attempted questions and a total grade
551/// this function saves EVERYTHING so it can be reconstructed later
552/// if necessary.
553
554 global $USER;
555
556 // First let's save the attempt record itself
557
558 $attempt->quiz = $quiz->id;
559 $attempt->user = $USER->id;
560 $attempt->attempt = $attemptnum;
561 $attempt->sumgrades = $result->sumgrades;
562 $attempt->timemodified = time();
563
564 if (!$attempt->id = insert_record("quiz_attempts", $attempt)) {
565 return false;
566 }
567
568 // Now let's save all the questions for this attempt
569
570 foreach ($questions as $question) {
571 $response->attempt = $attempt->id;
572 $response->question = $question->id;
573 $response->grade = $result->grades[$question->id];
574 if ($question->answer) {
575 $response->answer = implode(",",$question->answer);
576 } else {
577 $response->answer = "";
578 }
579 if (!insert_record("quiz_responses", $response)) {
580 return false;
581 }
3a506ca2 582 }
a5e1f35c 583 return true;
3a506ca2 584}
730fd187 585
a5e1f35c 586
587function quiz_grade_attempt_results($quiz, $questions) {
588/// Given a list of questions (including answers for each one)
589/// this function does all the hard work of calculating the
590/// grades for each question, as well as a total grade for
591/// for the whole quiz. It returns everything in a structure
592/// that looks like:
593/// $result->sumgrades (sum of all grades for all questions)
594/// $result->percentage (Percentage of grades that were correct)
595/// $result->grade (final grade result for the whole quiz)
596/// $result->grades[] (array of grades, indexed by question id)
597/// $result->feedback[] (array of feedback arrays, indexed by question id)
598
599 if (!$questions) {
600 error("No questions!");
601 }
602
603 $result->sumgrades = 0;
604
605 foreach ($questions as $question) {
606 if (!$answers = quiz_get_answer($question)) {
607 error("No answer defined for question id $question->id!");
608 }
609
610 $grade = 0; // default
611 $feedback = array ();
612
613 switch ($question->type) {
614 case SHORTANSWER:
615 if ($question->answer) {
616 $question->answer = $question->answer[0];
617 } else {
618 $question->answer = NULL;
619 }
620 foreach($answers as $answer) { // There might be multiple right answers
621 $feedback[$answer->id] = $answer->feedback;
622 if (!$answer->case) { // Don't compare case
623 $answer->answer = strtolower($answer->answer);
624 $question->answer = strtolower($question->answer);
625 }
626 if ($question->answer == $answer->answer) {
627 $grade = (float)$answer->fraction * $answer->grade;
628 }
629 }
630 break;
631
632
633 case TRUEFALSE:
634 if ($question->answer) {
635 $question->answer = $question->answer[0];
636 } else {
637 $question->answer = NULL;
638 }
639 foreach($answers as $answer) { // There should be two answers (true and false)
640 $feedback[$answer->id] = $answer->feedback;
641 if ($question->answer == $answer->id) {
642 $grade = (float)$answer->fraction * $answer->grade;
643 }
644 }
645 break;
646
647
648 case MULTICHOICE:
649 foreach($answers as $answer) { // There will be multiple answers, perhaps more than one is right
650 $feedback[$answer->id] = $answer->feedback;
651 if ($question->answer) {
652 foreach ($question->answer as $questionanswer) {
653 if ($questionanswer == $answer->id) {
654 if ($answer->single) {
655 $grade = (float)$answer->fraction * $answer->grade;
656 continue;
657 } else {
658 $grade += (float)$answer->fraction * $answer->grade;
659 }
660 }
661 }
662 }
663 }
664 break;
665
666
667 }
668 if ($grade < 0.0) { // No negative grades
669 $grade = 0.0;
670 }
671 $result->grades[$question->id] = $grade;
672 $result->sumgrades += $grade;
673 $result->feedback[$question->id] = $feedback;
674 }
675
676 $result->percentage = ($result->sumgrades / $quiz->sumgrades);
677 $result->grade = $result->percentage * $quiz->grade;
678
679 return $result;
680}
681
730fd187 682?>