diff --git a/mod/hotpot/attempt.php b/mod/hotpot/attempt.php
index fd495c03d13..b7d5e55a342 100644
--- a/mod/hotpot/attempt.php
+++ b/mod/hotpot/attempt.php
@@ -1,583 +1,583 @@
-ErrorMsg());
- }
- if ($attempt->userid != $USER->id) {
- error("User ID is incorrect");
- }
- if (! $hotpot = get_record("hotpot", "id", $attempt->hotpot)) {
- error("Hot Potatoes ID is incorrect (attempt id = $attempt->id)");
- }
- if (! $course = get_record("course", "id", $hotpot->course)) {
- error("Course ID is incorrect (hotpot id = $hotpot->id)");
- }
- if (! $cm = get_coursemodule_from_instance("hotpot", $hotpot->id, $course->id)) {
- error("Course Module ID is incorrect");
- }
-
- // make sure this user is enrolled in this course
- require_login($course->id);
-
- $next_url = "$CFG->wwwroot/course/view.php?id=$course->id";
- $time = time();
-
- // update attempt record fields using incoming data
- $attempt->score = optional_param('mark', NULL, PARAM_INT);
- $attempt->status = optional_param('status', NULL, PARAM_INT);
- $attempt->details = optional_param('detail', NULL, PARAM_RAW);
- $attempt->endtime = optional_param('endtime', NULL, PARAM_ALPHA);
- $attempt->starttime = optional_param('starttime', NULL, PARAM_ALPHA);
- $attempt->timefinish = $time;
-
- // convert times, if necessary
- if (empty($attempt->starttime)) {
- $attempt->starttime = 0;
- } else {
- $attempt->starttime = strtotime($attempt->starttime);
- }
- if (empty($attempt->endtime)) {
- $attempt->endtime = 0;
- } else {
- $attempt->endtime = strtotime($attempt->endtime);
- }
-
- // set clickreportid, (for click reporting)
- $attempt->clickreportid = $attempt->id;
-
- $quiztype = optional_param('quiztype', 0, PARAM_INT);
-
- if (empty($attempt->details)) {
- hotpot_set_attempt_details($attempt);
- $javascript_is_off = true;
- } else {
- $javascript_is_off = false;
- }
-
- if (empty($attempt->status)) {
- if (empty($attempt->endtime)) {
- $attempt->status = HOTPOT_STATUS_INPROGRESS;
- } else {
- $attempt->status = HOTPOT_STATUS_COMPLETED;
- }
- }
-
- // check if this is the second (or subsequent) click
- if (get_field("hotpot_attempts", "timefinish", "id", $attempt->id)) {
-
- if ($hotpot->clickreporting==HOTPOT_YES) {
- // add attempt record for each form submission
- // records are linked via the "clickreportid" field
-
- // update status in previous records in this group
- set_field("hotpot_attempts", "status", $attempt->status, "clickreportid", $attempt->clickreportid);
-
- // add new attempt record
- unset ($attempt->id);
- $attempt->id = insert_record("hotpot_attempts", $attempt);
-
- if (empty($attempt->id)) {
- error("Could not insert attempt record: ".$db->ErrorMsg(), $next_url);
- }
-
- // add attempt details record, if necessary
- if (!empty($attempt->details)) {
- unset($details);
- $details->attempt = $attempt->id;
- $details->details = $attempt->details;
- if (! insert_record("hotpot_details", $details, false)) {
- error("Could not insert attempt details record: ".$db->ErrorMsg(), $next_url);
- }
- }
- } else {
- // remove previous responses for this attempt, if required
- // (N.B. this does NOT remove the attempt record, just the responses)
- delete_records("hotpot_responses", "attempt", $attempt->id);
- }
- }
-
- // remove slashes added by lib/setup.php
- $attempt->details = stripslashes($attempt->details);
-
- // add details of this attempt
- hotpot_add_attempt_details($attempt);
-
- // add slashes again, so the details can be added to the database
- $attempt->details = addslashes($attempt->details);
-
- // update the attempt record
- if (! update_record("hotpot_attempts", $attempt)) {
- error("Could not update attempt record: ".$db->ErrorMsg(), $next_url);
- }
-
- // get previous attempt details record, if any
- $details_exist = record_exists("hotpot_details", "attempt", $attempt->id);
-
- // delete/update/add the attempt details record
- if (empty($attempt->details)) {
- if ($details_exist) {
- delete_records("hotpot_details", "attempt", $attempt->id);
- }
- } else {
- if ($details_exist) {
- set_field("hotpot_details", "details", $attempt->details, "attempt", $attempt->id);
- } else {
- unset($details);
- $details->attempt = $attempt->id;
- $details->details = $attempt->details;
- if (! insert_record("hotpot_details", $details)) {
- error("Could not insert attempt details record: ".$db->ErrorMsg(), $next_url);
- }
- }
- }
-
- if ($attempt->status==HOTPOT_STATUS_INPROGRESS) {
- if ($javascript_is_off) {
- // regenerate HTML page
- define('HOTPOT_FIRST_ATTEMPT', false);
- include ("$CFG->hotpotroot/view.php");
- } else {
- // continue without reloading the page
- header("Status: 204");
- header("HTTP/1.0 204 No Response");
- }
-
- } else { // quiz is finished
-
- add_to_log($course->id, "hotpot", "submit", "review.php?id=$cm->id&attempt=$attempt->id", "$hotpot->id", "$cm->id");
-
- if ($hotpot->shownextquiz==HOTPOT_YES) {
- if (is_numeric($next_cm = hotpot_get_next_cm($cm))) {
- $next_url = "$CFG->wwwroot/mod/hotpot/view.php?id=$next_cm";
- }
- }
-
- // redirect to the next quiz or the course page
- redirect($next_url, get_string('resultssaved', 'hotpot'));
- }
-
-// =================
-// functions
-// =================
-
-function hotpot_get_next_cm(&$cm) {
- // gets the next module in this section of the course
- // that is the same type of module as the current module
-
- $next_mod = false;
-
- // get a list of $ids of modules in this section
- if ($ids = get_field('course_sections', 'sequence', 'id', $cm->section)) {
-
- $found = false;
- $ids = explode(',', $ids);
- foreach ($ids as $id) {
- if ($found && ($cm->module==get_field('course_modules', 'module', 'id', $id))) {
- $next_mod = $id;
- break;
- } else if ($cm->id==$id) {
- $found = true;
- }
- }
- }
- return $next_mod;
-}
-function hotpot_set_attempt_details(&$attempt) {
- global $CFG, $HOTPOT_QUIZTYPE;
-
- // optional_param('showallquestions', 0, PARAM_INT);
-
- $attempt->details = '';
- $attempt->score = 0;
- $attempt->status = HOTPOT_STATUS_COMPLETED;
-
- $buttons = array('clues', 'hints', 'checks');
- $textfields = array('correct', 'wrong', 'ignored');
-
- $ok = false;
- $quiztype = optional_param('quiztype', 0, PARAM_ALPHANUM);
- if ($quiztype) {
- if (is_numeric($quiztype)) {
- $ok = array_key_exists($quiztype, $HOTPOT_QUIZTYPE);
- } else {
- $quiztype = array_search($quiztype, $HOTPOT_QUIZTYPE);
- $ok = is_numeric($quiztype);
- }
- }
- if (!$ok) {
- return;
- // error('Quiz type is missing or invalid');
- // error(get_string('error_invalidquiztype', 'hotpot'));
- //
- // script finishes here if quiztype is invalid
- //
- }
-
- // special flag to detect jquiz multiselect
- $is_jquiz_multiselect = false;
-
- // set maximum question number
- $q_max = 0;;
- do {
- switch ($quiztype) {
- case HOTPOT_JCLOZE:
- case HOTPOT_JQUIZ:
- $field="q{$q_max}_a0_text";
- break;
- case HOTPOT_JCB:
- case HOTPOT_JCROSS:
- case HOTPOT_JMATCH:
- case HOTPOT_JMIX:
- default:
- $field = '';
- }
- } while ($field && isset($_POST[$field]) && ($q_max = $q_max+1));
-
- // check JQuiz navigation buttons
- switch (true) {
- case isset($_POST['ShowAllQuestionsButton']):
- $_POST['ShowAllQuestions'] = 1;
- break;
- case isset($_POST['ShowOneByOneButton']):
- $_POST['ShowAllQuestions'] = 0;
- break;
- case isset($_POST['PrevQButton']):
- $_POST['ThisQuestion']--;
- break;
- case isset($_POST['NextQButton']):
- $_POST['ThisQuestion']++;
- break;
- }
-
- $q = 0;
- while ($q<$q_max) {
- $responsefield="q{$q}";
-
- $questiontype = optional_param("{$responsefield}_questiontype", 0, PARAM_INT);
- $is_jquiz_multiselect = ($quiztype==HOTPOT_JQUIZ && $questiontype==HOTPOT_JQUIZ_MULTISELECT);
-
- if (isset($_POST[$responsefield]) && is_array($_POST[$responsefield])) {
- $responsevalue = array();
- foreach ($_POST[$responsefield] as $key=>$value) {
- $responsevalue[$key] = clean_param($value, PARAM_CLEAN);
- }
- } else {
- $responsevalue = optional_param($responsefield, '');
- }
- if (is_array($responsevalue)) {
- // incomplete jquiz multi-select
- $responsevalues = $responsevalue;
- $responsevalue = implode('+', $responsevalue);
- } else {
- $responsevalues = explode('+', $responsevalue);
- }
-
- // initialize $response object
- $response = new stdClass();
- $response->correct = array();
- $response->wrong = array();
- $response->ignored = array();
- $response->clues = 0;
- $response->hints = 0;
- $response->checks = 0;
- $response->score = 0;
- $response->weighting = 0;
-
- // create another empty object to hold all previous responses (from database)
- $oldresponse = new stdClass();
- $vars = get_object_vars($response);
- foreach($vars as $name=>$value) {
- $oldresponse->$name = $value;
- }
-
- foreach ($buttons as $button) {
- if (($field = "q{$q}_{$button}_button") && isset($_POST[$field])) {
- $value = optional_param($field, '', PARAM_RAW);
- if (!empty($value)) {
- $response->$button++;
- }
- }
- }
-
- // loop through possible answers to this question
- $firstcorrectvalue = '';
- $percents = array();
- $a = 0;
- while (($valuefield="q{$q}_a{$a}_text") && isset($_POST[$valuefield])) {
- $value = optional_param($valuefield, '', PARAM_RAW);
-
- if (($percentfield="q{$q}_a{$a}_percent") && isset($_POST[$percentfield])) {
- $percent = optional_param($percentfield, 0, PARAM_INT);
- if ($percent) {
- $percents[$value] = $percent;
- }
- }
-
- if (($correctfield="q{$q}_a{$a}_correct") && isset($_POST[$correctfield])) {
- $correct = optional_param($correctfield, 0, PARAM_INT);
- } else {
- $correct = false;
- }
-
- if ($correct && empty($firstcorrectvalue)) {
- $firstcorrectvalue = $value;
- }
-
- if ($is_jquiz_multiselect) {
- $selected = in_array($value, $responsevalues);
- if ($correct) {
- $response->correct[] = $value;
- if (empty($selected)) {
- $response->wrong[] = true;
- }
- } else {
- if ($selected) {
- $response->wrong[] = true;
- }
- }
- } else {
- // single answer only required
- if ($responsevalue==$value) {
- if ($correct) {
- $response->correct[] = $value;
- } else {
- $response->wrong[] = $value;
- }
- } else {
- $response->ignored[] = $value;
- }
- }
- $a++;
- }
-
- // number of answers for this question
- $a_max = $a;
-
- if ($is_jquiz_multiselect) {
- if (empty($response->wrong) && count($responsevalues)==count($response->correct)) {
- $response->wrong = array();
- $response->correct = array($responsevalue);
- } else {
- $response->correct = array();
- $response->wrong = array($responsevalue);
- }
- } else {
- // if response did not match any answer, then this response is wrong
- if (empty($response->correct) && empty($response->wrong)) {
- $response->wrong[] = $responsevalue;
- }
- }
-
- // if this question has not been answered correctly, quiz is still in progress
- if (empty($response->correct)) {
-
- if (isset($_POST["q{$q}_ShowAnswers_button"])) {
- $_POST[$responsefield] = $firstcorrectvalue;
- } else {
- $attempt->status = HOTPOT_STATUS_INPROGRESS;
-
- if (isset($_POST["q{$q}_Hint_button"])) {
- // a particular hint button in JQuiz shortanswer
- $_POST['HintButton'] = true;
- }
-
- // give a hint, if necessary
- if (isset($_POST['HintButton']) && $firstcorrectvalue) {
-
- // make sure we only come through here once
- unset($_POST['HintButton']);
-
- $correctlen = strlen($firstcorrectvalue);
- $responselen = strlen($responsevalue);
-
- // check how many letters are the same
- $i = 0;
- while ($i<$responselen && $i<$correctlen && $responsevalue{$i}==$firstcorrectvalue{$i}) {
- $i++;
- }
-
- if ($i<$responselen) {
- // remove incorrect characters on the end of the response
- $responsevalue = substr($responsevalue, 0, $i);
- }
- if ($i<$correctlen) {
- // append next correct letter
- $responsevalue .= $firstcorrectvalue{$i};
- }
- $_POST[$responsefield] = $responsevalue;
- $response->hints++;
- } // end if hint
- }
- } // end if not correct
-
- // get clue text, if any
- if (($field="q{$q}_clue") && isset($_POST[$field])) {
- $response->clue_text = optional_param($field, '', PARAM_RAW);
- }
-
- // get question name
- $qq = sprintf('%02d', $q); // (a padded, two-digit version of $q)
- if (($field="q{$q}_name") && isset($_POST[$field])) {
- $questionname = optional_param($field, '', PARAM_RAW);
- $questionname = strip_tags($questionname);
- } else {
- $questionname = $qq;
- }
-
- // get previous responses to this question (if any)
- $records = get_records_sql("
- SELECT
- r.*
- FROM
- {$CFG->prefix}hotpot_attempts AS a,
- {$CFG->prefix}hotpot_questions AS q,
- {$CFG->prefix}hotpot_responses AS r
- WHERE
- a.clickreportid = $attempt->clickreportid AND
- a.id = r.attempt AND
- r.question = q.id AND
- q.name = '$questionname' AND
- q.hotpot = $attempt->hotpot
- ORDER BY
- a.timefinish
- ");
-
- if ($records) {
- foreach ($records as $record) {
- foreach ($buttons as $button) {
- $oldresponse->$button = max($oldresponse->$button, $record->$button);
- }
- foreach ($textfields as $field) {
- if ($record->$field && ($field=='correct' || $field=='wrong')) {
- $values = explode(',', hotpot_strings($record->$field));
- $oldresponse->$field = array_merge($oldresponse->$field, $values);
- }
- }
- }
- }
-
- // remove "correct" and "wrong" values from "ignored" values
- $response->ignored = array_diff($response->ignored,
- $response->correct, $response->wrong, $oldresponse->correct, $oldresponse->wrong
- );
-
- foreach ($buttons as $button) {
- $response->$button += $oldresponse->$button;
- }
-
- $value_has_changed = false;
- foreach ($textfields as $field) {
- $response->$field = array_merge($oldresponse->$field, $response->$field);
- $response->$field = array_unique($response->$field);
- $response->$field = implode(',', $response->$field);
-
- if ($field=='correct' || $field=='wrong') {
- $array = $oldresponse->$field;
- $array = array_unique($array);
- $oldresponse->$field = implode(',', $array);
- if ($response->$field<>$oldresponse->$field) {
- $value_has_changed = true;
- }
- }
- }
- if ($value_has_changed) {
- $response->checks++;
- }
-
- // $response now holds amalgamation of all responses so far to this question
-
- // set question score and weighting
- if ($response->correct) {
- switch ($quiztype) {
- case HOTPOT_JCB:
- break;
- case HOTPOT_JCLOZE:
- $strlen = strlen($response->correct);
- $response->score = 100*($strlen-($response->checks-1))/$strlen;
- $attempt->score += $response->score;
- break;
- case HOTPOT_JCROSS:
- break;
- case HOTPOT_JMATCH:
- break;
- case HOTPOT_JMIX:
- break;
- case HOTPOT_JQUIZ:
- switch ($questiontype) {
- case HOTPOT_JQUIZ_MULTICHOICE:
- $wrong = explode(',', $response->wrong);
- foreach ($wrong as $value) {
- if (isset($percents[$value])) {
- $percent = $percents[$value];
- } else {
- $percent = 0;
- }
- }
- case HOTPOT_JQUIZ_SHORTANSWER:
- $strlen = strlen($response->correct);
- $response->score = 100*($strlen-($response->checks-1))/$strlen;
- break;
- case HOTPOT_JQUIZ_MULTISELECT:
- if (isset($percents[$response->correct])) {
- $percent = $percents[$response->correct];
- } else {
- $percent = 0;
- }
- if ($a_max>0 && $response->checks>0 && $a_max>$response->checks) {
- $response->score = $percent*($a_max-($response->checks-1))/$a_max;
- }
- break;
- }
- $attempt->score += $response->score;
- break;
- }
- }
-
- $fieldname = $HOTPOT_QUIZTYPE[$quiztype]."_q{$qq}_name";
- $attempt->details .= "
\n";
-// $attempt->status = HOTPOT_STATUS_INPROGRESS;
-}
-
-?>
\ No newline at end of file
+ErrorMsg());
+ }
+ if ($attempt->userid != $USER->id) {
+ error("User ID is incorrect");
+ }
+ if (! $hotpot = get_record("hotpot", "id", $attempt->hotpot)) {
+ error("Hot Potatoes ID is incorrect (attempt id = $attempt->id)");
+ }
+ if (! $course = get_record("course", "id", $hotpot->course)) {
+ error("Course ID is incorrect (hotpot id = $hotpot->id)");
+ }
+ if (! $cm = get_coursemodule_from_instance("hotpot", $hotpot->id, $course->id)) {
+ error("Course Module ID is incorrect");
+ }
+
+ // make sure this user is enrolled in this course
+ require_login($course->id);
+
+ $next_url = "$CFG->wwwroot/course/view.php?id=$course->id";
+ $time = time();
+
+ // update attempt record fields using incoming data
+ $attempt->score = optional_param('mark', NULL, PARAM_INT);
+ $attempt->status = optional_param('status', NULL, PARAM_INT);
+ $attempt->details = optional_param('detail', NULL, PARAM_RAW);
+ $attempt->endtime = optional_param('endtime', NULL, PARAM_ALPHA);
+ $attempt->starttime = optional_param('starttime', NULL, PARAM_ALPHA);
+ $attempt->timefinish = $time;
+
+ // convert times, if necessary
+ if (empty($attempt->starttime)) {
+ $attempt->starttime = 0;
+ } else {
+ $attempt->starttime = strtotime($attempt->starttime);
+ }
+ if (empty($attempt->endtime)) {
+ $attempt->endtime = 0;
+ } else {
+ $attempt->endtime = strtotime($attempt->endtime);
+ }
+
+ // set clickreportid, (for click reporting)
+ $attempt->clickreportid = $attempt->id;
+
+ $quiztype = optional_param('quiztype', 0, PARAM_INT);
+
+ if (empty($attempt->details)) {
+ hotpot_set_attempt_details($attempt);
+ $javascript_is_off = true;
+ } else {
+ $javascript_is_off = false;
+ }
+
+ if (empty($attempt->status)) {
+ if (empty($attempt->endtime)) {
+ $attempt->status = HOTPOT_STATUS_INPROGRESS;
+ } else {
+ $attempt->status = HOTPOT_STATUS_COMPLETED;
+ }
+ }
+
+ // check if this is the second (or subsequent) click
+ if (get_field("hotpot_attempts", "timefinish", "id", $attempt->id)) {
+
+ if ($hotpot->clickreporting==HOTPOT_YES) {
+ // add attempt record for each form submission
+ // records are linked via the "clickreportid" field
+
+ // update status in previous records in this group
+ set_field("hotpot_attempts", "status", $attempt->status, "clickreportid", $attempt->clickreportid);
+
+ // add new attempt record
+ unset ($attempt->id);
+ $attempt->id = insert_record("hotpot_attempts", $attempt);
+
+ if (empty($attempt->id)) {
+ error("Could not insert attempt record: ".$db->ErrorMsg(), $next_url);
+ }
+
+ // add attempt details record, if necessary
+ if (!empty($attempt->details)) {
+ unset($details);
+ $details->attempt = $attempt->id;
+ $details->details = $attempt->details;
+ if (! insert_record("hotpot_details", $details, false)) {
+ error("Could not insert attempt details record: ".$db->ErrorMsg(), $next_url);
+ }
+ }
+ } else {
+ // remove previous responses for this attempt, if required
+ // (N.B. this does NOT remove the attempt record, just the responses)
+ delete_records("hotpot_responses", "attempt", $attempt->id);
+ }
+ }
+
+ // remove slashes added by lib/setup.php
+ $attempt->details = stripslashes($attempt->details);
+
+ // add details of this attempt
+ hotpot_add_attempt_details($attempt);
+
+ // add slashes again, so the details can be added to the database
+ $attempt->details = addslashes($attempt->details);
+
+ // update the attempt record
+ if (! update_record("hotpot_attempts", $attempt)) {
+ error("Could not update attempt record: ".$db->ErrorMsg(), $next_url);
+ }
+
+ // get previous attempt details record, if any
+ $details_exist = record_exists("hotpot_details", "attempt", $attempt->id);
+
+ // delete/update/add the attempt details record
+ if (empty($attempt->details)) {
+ if ($details_exist) {
+ delete_records("hotpot_details", "attempt", $attempt->id);
+ }
+ } else {
+ if ($details_exist) {
+ set_field("hotpot_details", "details", $attempt->details, "attempt", $attempt->id);
+ } else {
+ unset($details);
+ $details->attempt = $attempt->id;
+ $details->details = $attempt->details;
+ if (! insert_record("hotpot_details", $details)) {
+ error("Could not insert attempt details record: ".$db->ErrorMsg(), $next_url);
+ }
+ }
+ }
+
+ if ($attempt->status==HOTPOT_STATUS_INPROGRESS) {
+ if ($javascript_is_off) {
+ // regenerate HTML page
+ define('HOTPOT_FIRST_ATTEMPT', false);
+ include ("$CFG->hotpotroot/view.php");
+ } else {
+ // continue without reloading the page
+ header("Status: 204");
+ header("HTTP/1.0 204 No Response");
+ }
+
+ } else { // quiz is finished
+
+ add_to_log($course->id, "hotpot", "submit", "review.php?id=$cm->id&attempt=$attempt->id", "$hotpot->id", "$cm->id");
+
+ if ($hotpot->shownextquiz==HOTPOT_YES) {
+ if (is_numeric($next_cm = hotpot_get_next_cm($cm))) {
+ $next_url = "$CFG->wwwroot/mod/hotpot/view.php?id=$next_cm";
+ }
+ }
+
+ // redirect to the next quiz or the course page
+ redirect($next_url, get_string('resultssaved', 'hotpot'));
+ }
+
+// =================
+// functions
+// =================
+
+function hotpot_get_next_cm(&$cm) {
+ // gets the next module in this section of the course
+ // that is the same type of module as the current module
+
+ $next_mod = false;
+
+ // get a list of $ids of modules in this section
+ if ($ids = get_field('course_sections', 'sequence', 'id', $cm->section)) {
+
+ $found = false;
+ $ids = explode(',', $ids);
+ foreach ($ids as $id) {
+ if ($found && ($cm->module==get_field('course_modules', 'module', 'id', $id))) {
+ $next_mod = $id;
+ break;
+ } else if ($cm->id==$id) {
+ $found = true;
+ }
+ }
+ }
+ return $next_mod;
+}
+function hotpot_set_attempt_details(&$attempt) {
+ global $CFG, $HOTPOT_QUIZTYPE;
+
+ // optional_param('showallquestions', 0, PARAM_INT);
+
+ $attempt->details = '';
+ $attempt->score = 0;
+ $attempt->status = HOTPOT_STATUS_COMPLETED;
+
+ $buttons = array('clues', 'hints', 'checks');
+ $textfields = array('correct', 'wrong', 'ignored');
+
+ $ok = false;
+ $quiztype = optional_param('quiztype', 0, PARAM_ALPHANUM);
+ if ($quiztype) {
+ if (is_numeric($quiztype)) {
+ $ok = array_key_exists($quiztype, $HOTPOT_QUIZTYPE);
+ } else {
+ $quiztype = array_search($quiztype, $HOTPOT_QUIZTYPE);
+ $ok = is_numeric($quiztype);
+ }
+ }
+ if (!$ok) {
+ return;
+ // error('Quiz type is missing or invalid');
+ // error(get_string('error_invalidquiztype', 'hotpot'));
+ //
+ // script finishes here if quiztype is invalid
+ //
+ }
+
+ // special flag to detect jquiz multiselect
+ $is_jquiz_multiselect = false;
+
+ // set maximum question number
+ $q_max = 0;;
+ do {
+ switch ($quiztype) {
+ case HOTPOT_JCLOZE:
+ case HOTPOT_JQUIZ:
+ $field="q{$q_max}_a0_text";
+ break;
+ case HOTPOT_JCB:
+ case HOTPOT_JCROSS:
+ case HOTPOT_JMATCH:
+ case HOTPOT_JMIX:
+ default:
+ $field = '';
+ }
+ } while ($field && isset($_POST[$field]) && ($q_max = $q_max+1));
+
+ // check JQuiz navigation buttons
+ switch (true) {
+ case isset($_POST['ShowAllQuestionsButton']):
+ $_POST['ShowAllQuestions'] = 1;
+ break;
+ case isset($_POST['ShowOneByOneButton']):
+ $_POST['ShowAllQuestions'] = 0;
+ break;
+ case isset($_POST['PrevQButton']):
+ $_POST['ThisQuestion']--;
+ break;
+ case isset($_POST['NextQButton']):
+ $_POST['ThisQuestion']++;
+ break;
+ }
+
+ $q = 0;
+ while ($q<$q_max) {
+ $responsefield="q{$q}";
+
+ $questiontype = optional_param("{$responsefield}_questiontype", 0, PARAM_INT);
+ $is_jquiz_multiselect = ($quiztype==HOTPOT_JQUIZ && $questiontype==HOTPOT_JQUIZ_MULTISELECT);
+
+ if (isset($_POST[$responsefield]) && is_array($_POST[$responsefield])) {
+ $responsevalue = array();
+ foreach ($_POST[$responsefield] as $key=>$value) {
+ $responsevalue[$key] = clean_param($value, PARAM_CLEAN);
+ }
+ } else {
+ $responsevalue = optional_param($responsefield, '');
+ }
+ if (is_array($responsevalue)) {
+ // incomplete jquiz multi-select
+ $responsevalues = $responsevalue;
+ $responsevalue = implode('+', $responsevalue);
+ } else {
+ $responsevalues = explode('+', $responsevalue);
+ }
+
+ // initialize $response object
+ $response = new stdClass();
+ $response->correct = array();
+ $response->wrong = array();
+ $response->ignored = array();
+ $response->clues = 0;
+ $response->hints = 0;
+ $response->checks = 0;
+ $response->score = 0;
+ $response->weighting = 0;
+
+ // create another empty object to hold all previous responses (from database)
+ $oldresponse = new stdClass();
+ $vars = get_object_vars($response);
+ foreach($vars as $name=>$value) {
+ $oldresponse->$name = $value;
+ }
+
+ foreach ($buttons as $button) {
+ if (($field = "q{$q}_{$button}_button") && isset($_POST[$field])) {
+ $value = optional_param($field, '', PARAM_RAW);
+ if (!empty($value)) {
+ $response->$button++;
+ }
+ }
+ }
+
+ // loop through possible answers to this question
+ $firstcorrectvalue = '';
+ $percents = array();
+ $a = 0;
+ while (($valuefield="q{$q}_a{$a}_text") && isset($_POST[$valuefield])) {
+ $value = optional_param($valuefield, '', PARAM_RAW);
+
+ if (($percentfield="q{$q}_a{$a}_percent") && isset($_POST[$percentfield])) {
+ $percent = optional_param($percentfield, 0, PARAM_INT);
+ if ($percent) {
+ $percents[$value] = $percent;
+ }
+ }
+
+ if (($correctfield="q{$q}_a{$a}_correct") && isset($_POST[$correctfield])) {
+ $correct = optional_param($correctfield, 0, PARAM_INT);
+ } else {
+ $correct = false;
+ }
+
+ if ($correct && empty($firstcorrectvalue)) {
+ $firstcorrectvalue = $value;
+ }
+
+ if ($is_jquiz_multiselect) {
+ $selected = in_array($value, $responsevalues);
+ if ($correct) {
+ $response->correct[] = $value;
+ if (empty($selected)) {
+ $response->wrong[] = true;
+ }
+ } else {
+ if ($selected) {
+ $response->wrong[] = true;
+ }
+ }
+ } else {
+ // single answer only required
+ if ($responsevalue==$value) {
+ if ($correct) {
+ $response->correct[] = $value;
+ } else {
+ $response->wrong[] = $value;
+ }
+ } else {
+ $response->ignored[] = $value;
+ }
+ }
+ $a++;
+ }
+
+ // number of answers for this question
+ $a_max = $a;
+
+ if ($is_jquiz_multiselect) {
+ if (empty($response->wrong) && count($responsevalues)==count($response->correct)) {
+ $response->wrong = array();
+ $response->correct = array($responsevalue);
+ } else {
+ $response->correct = array();
+ $response->wrong = array($responsevalue);
+ }
+ } else {
+ // if response did not match any answer, then this response is wrong
+ if (empty($response->correct) && empty($response->wrong)) {
+ $response->wrong[] = $responsevalue;
+ }
+ }
+
+ // if this question has not been answered correctly, quiz is still in progress
+ if (empty($response->correct)) {
+
+ if (isset($_POST["q{$q}_ShowAnswers_button"])) {
+ $_POST[$responsefield] = $firstcorrectvalue;
+ } else {
+ $attempt->status = HOTPOT_STATUS_INPROGRESS;
+
+ if (isset($_POST["q{$q}_Hint_button"])) {
+ // a particular hint button in JQuiz shortanswer
+ $_POST['HintButton'] = true;
+ }
+
+ // give a hint, if necessary
+ if (isset($_POST['HintButton']) && $firstcorrectvalue) {
+
+ // make sure we only come through here once
+ unset($_POST['HintButton']);
+
+ $correctlen = strlen($firstcorrectvalue);
+ $responselen = strlen($responsevalue);
+
+ // check how many letters are the same
+ $i = 0;
+ while ($i<$responselen && $i<$correctlen && $responsevalue{$i}==$firstcorrectvalue{$i}) {
+ $i++;
+ }
+
+ if ($i<$responselen) {
+ // remove incorrect characters on the end of the response
+ $responsevalue = substr($responsevalue, 0, $i);
+ }
+ if ($i<$correctlen) {
+ // append next correct letter
+ $responsevalue .= $firstcorrectvalue{$i};
+ }
+ $_POST[$responsefield] = $responsevalue;
+ $response->hints++;
+ } // end if hint
+ }
+ } // end if not correct
+
+ // get clue text, if any
+ if (($field="q{$q}_clue") && isset($_POST[$field])) {
+ $response->clue_text = optional_param($field, '', PARAM_RAW);
+ }
+
+ // get question name
+ $qq = sprintf('%02d', $q); // (a padded, two-digit version of $q)
+ if (($field="q{$q}_name") && isset($_POST[$field])) {
+ $questionname = optional_param($field, '', PARAM_RAW);
+ $questionname = strip_tags($questionname);
+ } else {
+ $questionname = $qq;
+ }
+
+ // get previous responses to this question (if any)
+ $records = get_records_sql("
+ SELECT
+ r.*
+ FROM
+ {$CFG->prefix}hotpot_attempts AS a,
+ {$CFG->prefix}hotpot_questions AS q,
+ {$CFG->prefix}hotpot_responses AS r
+ WHERE
+ a.clickreportid = $attempt->clickreportid AND
+ a.id = r.attempt AND
+ r.question = q.id AND
+ q.name = '$questionname' AND
+ q.hotpot = $attempt->hotpot
+ ORDER BY
+ a.timefinish
+ ");
+
+ if ($records) {
+ foreach ($records as $record) {
+ foreach ($buttons as $button) {
+ $oldresponse->$button = max($oldresponse->$button, $record->$button);
+ }
+ foreach ($textfields as $field) {
+ if ($record->$field && ($field=='correct' || $field=='wrong')) {
+ $values = explode(',', hotpot_strings($record->$field));
+ $oldresponse->$field = array_merge($oldresponse->$field, $values);
+ }
+ }
+ }
+ }
+
+ // remove "correct" and "wrong" values from "ignored" values
+ $response->ignored = array_diff($response->ignored,
+ $response->correct, $response->wrong, $oldresponse->correct, $oldresponse->wrong
+ );
+
+ foreach ($buttons as $button) {
+ $response->$button += $oldresponse->$button;
+ }
+
+ $value_has_changed = false;
+ foreach ($textfields as $field) {
+ $response->$field = array_merge($oldresponse->$field, $response->$field);
+ $response->$field = array_unique($response->$field);
+ $response->$field = implode(',', $response->$field);
+
+ if ($field=='correct' || $field=='wrong') {
+ $array = $oldresponse->$field;
+ $array = array_unique($array);
+ $oldresponse->$field = implode(',', $array);
+ if ($response->$field<>$oldresponse->$field) {
+ $value_has_changed = true;
+ }
+ }
+ }
+ if ($value_has_changed) {
+ $response->checks++;
+ }
+
+ // $response now holds amalgamation of all responses so far to this question
+
+ // set question score and weighting
+ if ($response->correct) {
+ switch ($quiztype) {
+ case HOTPOT_JCB:
+ break;
+ case HOTPOT_JCLOZE:
+ $strlen = strlen($response->correct);
+ $response->score = 100*($strlen-($response->checks-1))/$strlen;
+ $attempt->score += $response->score;
+ break;
+ case HOTPOT_JCROSS:
+ break;
+ case HOTPOT_JMATCH:
+ break;
+ case HOTPOT_JMIX:
+ break;
+ case HOTPOT_JQUIZ:
+ switch ($questiontype) {
+ case HOTPOT_JQUIZ_MULTICHOICE:
+ $wrong = explode(',', $response->wrong);
+ foreach ($wrong as $value) {
+ if (isset($percents[$value])) {
+ $percent = $percents[$value];
+ } else {
+ $percent = 0;
+ }
+ }
+ case HOTPOT_JQUIZ_SHORTANSWER:
+ $strlen = strlen($response->correct);
+ $response->score = 100*($strlen-($response->checks-1))/$strlen;
+ break;
+ case HOTPOT_JQUIZ_MULTISELECT:
+ if (isset($percents[$response->correct])) {
+ $percent = $percents[$response->correct];
+ } else {
+ $percent = 0;
+ }
+ if ($a_max>0 && $response->checks>0 && $a_max>$response->checks) {
+ $response->score = $percent*($a_max-($response->checks-1))/$a_max;
+ }
+ break;
+ }
+ $attempt->score += $response->score;
+ break;
+ }
+ }
+
+ $fieldname = $HOTPOT_QUIZTYPE[$quiztype]."_q{$qq}_name";
+ $attempt->details .= "
\n";
+// $attempt->status = HOTPOT_STATUS_INPROGRESS;
+}
+
+?>
diff --git a/mod/hotpot/defaults.php b/mod/hotpot/defaults.php
index cd3373848b1..8e678f78c60 100644
--- a/mod/hotpot/defaults.php
+++ b/mod/hotpot/defaults.php
@@ -1,4 +1,4 @@
-hotpot_initialdisable)) {
if (!count_records('hotpot')) {
set_field('modules', 'visible', 0, 'name', 'hotpot'); // Disable it by default
diff --git a/mod/hotpot/view.php b/mod/hotpot/view.php
index 70b0dc8df1f..9d959d11fd6 100644
--- a/mod/hotpot/view.php
+++ b/mod/hotpot/view.php
@@ -1,455 +1,455 @@
-course)) {
- error("Course is misconfigured");
- }
- if (! $hotpot = get_record("hotpot", "id", $cm->instance)) {
- error("Course module is incorrect");
- }
-
- } else {
- if (! $hotpot = get_record("hotpot", "id", $hp)) {
- error("Course module is incorrect");
- }
- if (! $course = get_record("course", "id", $hotpot->course)) {
- error("Course is misconfigured");
- }
- if (! $cm = get_coursemodule_from_instance("hotpot", $hotpot->id, $course->id)) {
- error("Course Module ID was incorrect");
- }
- }
- require_login($course->id);
- }
- // set nextpage (for error messages)
- $nextpage = "$CFG->wwwroot/course/view.php?id=$course->id";
- // header strings
- $title = strip_tags($course->shortname.': '.$hotpot->name);
- $heading = "$course->fullname";
- $target = empty($CFG->framename) ? '' : ' target="'.$CFG->framename.'"';
- $navigation = ''.get_string("modulenameplural", "hotpot")." -> $hotpot->name";
- if ($course->category) {
- $navigation = ''.$course->shortname.' -> '.$navigation;
- }
- $button = update_module_button($cm->id, $course->id, get_string("modulename", "hotpot").'" style="font-size:0.75em;');
- $loggedinas = ''.user_login_string($course, $USER).'';
- $time = time();
- $hppassword = optional_param('hppassword');
- if (HOTPOT_FIRST_ATTEMPT && !isteacher($course->id)) {
- // check this quiz is available to this student
- // error message, if quiz is unavailable
- $error = '';
- // check quiz is visible
- if (!hotpot_is_visible($cm)) {
- $error = get_string("activityiscurrentlyhidden");
- // check network address
- } else if ($hotpot->subnet && !address_in_subnet($_SERVER['REMOTE_ADDR'], $hotpot->subnet)) {
- $error = get_string("subneterror", "quiz");
- // check number of attempts
- } else if ($hotpot->attempts && $hotpot->attempts <= count_records('hotpot_attempts', 'hotpot', $hotpot->id, 'userid', $USER->id)) {
- $error = get_string("nomoreattempts", "quiz");
- // get password
- } else if ($hotpot->password && empty($hppassword)) {
- print_header($title, $heading, $navigation, "", "", true, $button, $loggedinas, false);
- print_heading($hotpot->name);
- $boxalign = 'center';
- $boxwidth = 500;
- if (trim(strip_tags($hotpot->summary))) {
- print_simple_box_start($boxalign, $boxwidth);
- print '