function hotpot_print_attempt_details(&$hotpot, &$attempt) { // define fields to print $textfields = array('correct', 'ignored', 'wrong'); $numfields = array('score', 'weighting', 'hints', 'clues', 'checks'); $fields = array_merge($textfields, $numfields); $q = array(); // questions $f = array(); // fields foreach ($fields as $field) { $name = get_string($field, 'hotpot'); $f[$field] = array('count' => 0, 'name' => $name); } // get questions and responses for this attempt $questions = get_records_select('hotpot_questions', "hotpot='{$hotpot->id}'", 'id'); $responses = get_records_select('hotpot_responses', "attempt='{$attempt->id}'", 'id'); if ($questions && $responses) { foreach ($responses as $response) { $id = $response->question; foreach ($fields as $field) { if (!isset($f[$field])) { $name = get_string($field, 'hotpot'); $f[$field] = array('count' => 0, 'name' => $name); } if (isset($response->{$field})) { $f[$field]['count']++; if (!isset($q[$id])) { $name = hotpot_get_question_name($questions[$id]); $q[$id] = array('name' => $name); } $q[$id][$field] = $response->{$field}; } } } } // count the number of columns required in the table $colspan = 0; foreach ($numfields as $field) { if ($f[$field]['count']) { $colspan += 2; } } $colspan = max(2, $colspan); // start table of questions and responses print_simple_box_start("center", "80%", "#ffffff", 0); print '<table width="100%" border="1" valign="top" align="center" cellpadding="2" cellspacing="2" class="generaltable">' . "\n"; if (empty($q)) { print '<tr><td align="center" class="generaltablecell"><b>' . get_string("noresponses", "hotpot") . "</b></td></tr>\n"; } else { // flag to ensure separators are only printed before the 2nd and subsequent questions $printseparator = false; foreach ($q as $i => $question) { // flag to ensure questions are only printed when there is at least one response $printedquestion = false; // add rows of text fields foreach ($textfields as $field) { if (isset($question[$field])) { $text = hotpot_strings($question[$field]); if (trim($text)) { // print question if necessary if (!$printedquestion) { if ($printseparator) { print '<tr><td colspan="' . $colspan . '"><div class="tabledivider"></div></td></tr>' . "\n"; } $printseparator = true; print '<tr><td colspan="' . $colspan . '" class="generaltablecell"><b>' . $question['name'] . '</b></td></tr>' . "\n"; $printedquestion = true; } // print response print '<tr><th align="right" width="100" class="generaltableheader" scope="row">' . $f[$field]['name'] . ':</th><td colspan="' . ($colspan - 1) . '" class="generaltablecell">' . $text . '</td></tr>' . "\n"; } } } // add row of numeric fields print '<tr>'; foreach ($numfields as $field) { if ($f[$field]['count']) { // print question if necessary if (!$printedquestion) { print '<td colspan="' . $colspan . '" class="generaltablecell"><b>' . $question['name'] . "</b></td></tr>\n<tr>"; $printedquestion = true; } // print numeric response $value = isset($question[$field]) ? $question[$field] : '-'; print '<th align="right" width="100" class="generaltableheader" scope="row">' . $f[$field]['name'] . ':</th><td class="generaltablecell">' . $value . '</td>'; } } print "</tr>\n"; } // foreach $q } // finish table print "</table>\n"; print_simple_box_end(); }
function create_clickreport_table(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions, &$options, &$tables) { global $CFG; $is_html = $options['reportformat'] == 'htm'; // time and date format strings // date format strings $strftimetime = '%H:%M:%S'; $strftimedate = get_string('strftimedate'); // get the current time and max execution time $start_report_time = microtime(); $max_execution_time = ini_get('max_execution_time'); $correct = get_string('reportcorrectsymbol', 'hotpot'); $wrong = get_string('reportwrongsymbol', 'hotpot'); $nottried = get_string('reportnottriedsymbol', 'hotpot'); // shortcuts for font tags $blank = $is_html ? ' ' : ""; // store question count $questioncount = count($questions); // array to map columns onto question ids ($col => $id) $questionids = array_keys($questions); // store exercise type $exercisetype = $this->get_exercisetype($questions, $questionids, $blank); // initialize details ('events' must go last) $details = array('checks', 'status', 'answers', 'changes', 'hints', 'clues', 'events'); // initialize $table unset($table); $table->border = 1; $table->width = '100%'; // initialize legend, if necessary if (!empty($options['reportshowlegend'])) { $table->legend = array(); } // start $table headings $this->set_head($options, $table, 'exercise'); $this->set_head($options, $table, 'user'); $this->set_head($options, $table, 'attempt'); $this->set_head($options, $table, 'click'); // store clicktype column number $clicktype_col = count($table->head) - 1; // finish $table headings $this->set_head($options, $table, 'details', $exercisetype, $details, $questioncount); $this->set_head($options, $table, 'totals', $exercisetype); // set align and wrap $this->set_align_and_wrap($table); // is link to review allowed? $allow_review = $is_html && (has_capability('mod/hotpot:viewreport', get_context_instance(CONTEXT_COURSE, $course->id)) || $hotpot->review); // initialize array of data values $this->data = array(); // set exercise data values $this->set_data_exercise($cm, $course, $hotpot, $questions, $questionids, $questioncount, $blank); // add details of users' responses foreach ($users as $user) { $this->set_data_user($options, $course, $user); unset($clickreportid); foreach ($user->attempts as $attempt) { // initialize totals for $click = array('qnumber' => array(), 'correct' => array(), 'wrong' => array(), 'answers' => array(), 'hints' => array(), 'clues' => array(), 'changes' => array(), 'checks' => array(), 'events' => array(), 'score' => array(), 'weighting' => array()); $clicktypes = array(); // is the start of a new attempt? // (clicks in the same attempt have the same clickreportid) if (!isset($clickreportid) || $clickreportid != $attempt->clickreportid) { $clickcount = 1; $clickreportid = $attempt->clickreportid; // initialize totals for all clicks in this attempt $clicks = $click; // $click has just been initialized $this->set_data_attempt($attempt, $strftimedate, $strftimetime, $blank); } $cells = array(); $this->set_data($cells, 'exercise'); $this->set_data($cells, 'user'); $this->set_data($cells, 'attempt'); // get responses to questions in this attempt foreach ($attempt->responses as $response) { // set $q(uestion number) $q = array_search($response->question, $questionids); $click['qnumber'][$q] = true; // was this question answered correctly? if ($answer = hotpot_strings($response->correct)) { // mark the question as correctly answered if (empty($clicks['correct'][$q])) { $click['correct'][$q] = true; $clicks['correct'][$q] = true; } // unset 'wrong' flags, if necessary if (isset($click['wrong'][$q])) { unset($click['wrong'][$q]); } if (isset($clicks['wrong'][$q])) { unset($clicks['wrong'][$q]); } // otherwise, was the question answered wrongly? } else { if ($answer = hotpot_strings($response->wrong)) { // mark the question as wrongly answered $click['wrong'][$q] = true; $clicks['wrong'][$q] = true; } else { // not correct or wrong (curious?!) unset($answer); } } if (!empty($click['correct'][$q]) || !empty($click['wrong'][$q])) { $click['score'][$q] = $response->score; $clicks['score'][$q] = $response->score; $weighting = isset($response->weighting) ? $response->weighting : 100; $click['weighting'][$q] = $weighting; $clicks['weighting'][$q] = $weighting; } foreach ($details as $detail) { switch ($detail) { case 'answers': if (isset($answer) && is_string($answer) && !empty($answer)) { $click[$detail][$q] = $answer; } break; case 'hints': case 'clues': case 'checks': if (isset($response->{$detail}) && is_numeric($response->{$detail}) && $response->{$detail} > 0) { if (!isset($click[$detail][$q]) || $click[$detail][$q] < $response->{$detail}) { $click[$detail][$q] = $response->{$detail}; } } break; } } // end foreach $detail } // end foreach $response $click['types'] = array(); $this->data['details'] = array(); foreach ($details as $detail) { for ($q = 0; $q < $questioncount; $q++) { switch ($detail) { case 'status': if (isset($clicks['correct'][$q])) { $this->data['details'][] = $correct; } else { if (isset($clicks['wrong'][$q])) { $this->data['details'][] = $wrong; } else { if (isset($click['qnumber'][$q])) { $this->data['details'][] = $nottried; } else { // this question did not appear in this attempt $this->data['details'][] = $blank; } } } break; case 'answers': case 'hints': case 'clues': case 'checks': if (!isset($clicks[$detail][$q])) { if (!isset($click[$detail][$q])) { $this->data['details'][] = $blank; } else { $clicks[$detail][$q] = $click[$detail][$q]; if ($detail == 'answers') { $this->set_legend($table, $q, $click[$detail][$q], $questions[$questionids[$q]]); } $this->data['details'][] = $click[$detail][$q]; $this->update_event_count($click, $detail, $q); } } else { if (!isset($click[$detail][$q])) { $this->data['details'][] = $blank; } else { $difference = ''; if ($detail == 'answers') { if ($click[$detail][$q] != $clicks[$detail][$q]) { $pattern = '/^' . preg_quote($clicks[$detail][$q], '/') . ',/'; $difference = preg_replace($pattern, '', $click[$detail][$q], 1); } } else { // hints, clues, checks if ($click[$detail][$q] > $clicks[$detail][$q]) { $difference = $click[$detail][$q] - $clicks[$detail][$q]; } } if ($difference) { $clicks[$detail][$q] = $click[$detail][$q]; $click[$detail][$q] = $difference; if ($detail == 'answers') { $this->set_legend($table, $q, $difference, $questions[$questionids[$q]]); } $this->data['details'][] = $difference; $this->update_event_count($click, $detail, $q); } else { unset($click[$detail][$q]); $this->data['details'][] = $blank; } } } break; case 'changes': case 'events': if (empty($click[$detail][$q])) { $this->data['details'][] = $blank; } else { $this->data['details'][] = $click[$detail][$q]; } break; default: // do nothing break; } // end switch } // for $q } // foreach $detail // set data cell values for $this->set_data_click($allow_review ? '<a href="review.php?hp=' . $hotpot->id . '&attempt=' . $attempt->id . '">' . $clickcount . '</a>' : $clickcount, trim(userdate($attempt->timefinish, $strftimetime)), $exercisetype, $click); $this->set_data($cells, 'click'); $this->set_data($cells, 'details'); $this->set_data_totals($click, $clicks, $questioncount, $blank, $attempt); $this->set_data($cells, 'totals'); $table->data[] = $cells; $clickcount++; } // end foreach $attempt // insert 'tabledivider' between users $table->data[] = 'hr'; } // end foreach $user // remove final 'hr' from data rows array_pop($table->data); if ($is_html && $CFG->hotpot_showtimes) { $count = count($users); $duration = sprintf("%0.3f", microtime_diff($start_report_time, microtime())); print "{$count} users processed in {$duration} seconds (" . sprintf("%0.3f", $duration / $count) . ' secs/user)<hr size="1" noshade="noshade" />' . "\n"; } $tables[] =& $table; $this->create_legend_table($tables, $table); }
function create_responses_table(&$hotpot, &$course, &$users, &$attempts, &$questions, &$options, &$tables) { global $CFG; $is_html = $options['reportformat'] == 'htm'; // shortcuts for font tags $br = $is_html ? "<br />\n" : "\n"; $blank = $is_html ? ' ' : ""; $font_end = $is_html ? '</font>' : ''; $font_red = $is_html ? '<font color="red">' : ''; $font_blue = $is_html ? '<font color="blue">' : ''; $font_brown = $is_html ? '<font color="brown">' : ''; $font_green = $is_html ? '<font color="green">' : ''; $font_small = $is_html ? '<font size="-2">' : ''; $nobr_start = $is_html ? '<nobr>' : ''; $nobr_end = $is_html ? '</nobr>' : ''; // is review allowed? (do this once here, to save time later) $allow_review = $is_html && (has_capability('mod/hotpot:viewreport', get_context_instance(CONTEXT_COURSE, $course->id)) || $hotpot->review); // assume penalties column is NOT required $show_penalties = false; // initialize $table unset($table); $table->border = 1; $table->width = '100%'; // initialize legend, if necessary if (!empty($options['reportshowlegend'])) { $table->legend = array(); } // headings for name, attempt number, score/grade and penalties $table->head = array(get_string("name"), hotpot_grade_heading($hotpot, $options), get_string('attempt', 'quiz')); $table->align = array('left', 'center', 'center'); $table->size = array(150, 80, 10); $table->wrap = array(0, 0, 0); $table->fontsize = array(0, 0, 0); // question headings $this->add_question_headings($questions, $table, 'left', 0, false, 2); // penalties (not always needed) and raw score array_push($table->head, get_string('penalties', 'hotpot'), get_string('score', 'quiz')); array_push($table->align, 'center', 'center'); array_push($table->size, 50, 50); array_push($table->wrap, 0, 0); array_push($table->fontsize, 0, 0); // message strings $strnoresponse = get_string('noresponse', 'quiz'); // array to map columns onto question ids ($col => $id) $questionids = array_keys($questions); // add details of users' responses foreach ($users as $user) { // shortcut to user info held in first attempt record $u =& $user->attempts[0]; if (function_exists("fullname")) { $name = fullname($u); } else { $name = "{$u->firstname} {$u->lastname}"; } if ($is_html) { $name = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $u->userid . '&course=' . $course->id . '">' . $name . '</a>'; } $grade = isset($user->grade) ? $user->grade : $blank; foreach ($user->attempts as $attempt) { $attemptnumber = $attempt->attempt; if ($allow_review) { $attemptnumber = ' <a href="review.php?hp=' . $hotpot->id . '&attempt=' . $attempt->id . '">' . $attemptnumber . '</a>'; } $cells = array($name, $grade, $attemptnumber); // $name and $grade are only printed on first line per user $name = $blank; $grade = $blank; $start_col = count($cells); foreach ($questionids as $col => $id) { $cells[$start_col + $col] = "{$font_brown}({$strnoresponse}){$font_end}"; } if (isset($attempt->penalties)) { $show_penalties = true; $penalties = $attempt->penalties; } else { $penalties = $blank; } array_push($cells, $penalties, hotpot_format_score($attempt)); // get responses to questions in this attempt foreach ($attempt->responses as $response) { // check this question id is OK (should be) $col = array_search($response->question, $questionids); if (is_numeric($col)) { // correct if ($value = hotpot_strings($response->correct)) { $this->set_legend($table, $col, $value, $questions[$response->question]); } else { $value = "({$strnoresponse})"; } $cell = $font_red . $value . $font_end; // wrong if ($value = hotpot_strings($response->wrong)) { if (isset($table->legend)) { $values = array(); foreach (explode(',', $value) as $v) { $this->set_legend($table, $col, $v, $questions[$response->question]); $values[] = $v; } $value = implode(',', $values); } $cell .= $br . $font_blue . $value . $font_end; } // ignored if ($value = hotpot_strings($response->ignored)) { if (isset($table->legend)) { $values = array(); foreach (explode(',', $value) as $v) { $this->set_legend($table, $col, $v, $questions[$response->question]); $values[] = $v; } $value = implode(',', $values); } $cell .= $br . $font_brown . $value . $font_end; } // numeric if (is_numeric($response->score)) { if (empty($table->caption)) { $table->caption = get_string('indivresp', 'quiz'); if ($is_html) { $table->caption .= helpbutton('responsestable', $table->caption, 'hotpot', true, false, '', true); } } $hints = empty($response->hints) ? 0 : $response->hints; $clues = empty($response->clues) ? 0 : $response->clues; $checks = empty($response->checks) ? 0 : $response->checks; $numeric = $response->score . '% ' . $blank . ' (' . $hints . ',' . $clues . ',' . $checks . ')'; $cell .= $br . $nobr_start . $font_green . $numeric . $font_end . $nobr_end; } $cells[$start_col + $col] = $cell; } } $table->data[] = $cells; } // insert 'tabledivider' between users $table->data[] = 'hr'; } // end foreach $users // remove final 'hr' from data rows array_pop($table->data); if (!$show_penalties) { $col = 3 + count($questionids); $this->remove_column($table, $col); } $tables[] =& $table; }
function hotpot_get_question_name($question) { $name = ''; if (isset($question->text)) { $name = hotpot_strings($question->text); } if (empty($name)) { $name = $question->name; } return $name; }
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'); // print_error('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("\n SELECT\n r.*\n FROM\n {$CFG->prefix}hotpot_attempts a,\n {$CFG->prefix}hotpot_questions q,\n {$CFG->prefix}hotpot_responses r\n WHERE\n a.clickreportid = {$attempt->clickreportid} AND\n a.id = r.attempt AND\n r.question = q.id AND\n q.name = '{$questionname}' AND\n q.hotpot = {$attempt->hotpot}\n ORDER BY\n a.timefinish\n "); 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 .= "<field><fieldname>{$fieldname}</fieldname><fielddata>{$questionname}</fielddata></field>"; // encode $response fields as XML $vars = get_object_vars($response); foreach ($vars as $name => $value) { if (!empty($value)) { $fieldname = $HOTPOT_QUIZTYPE[$quiztype] . "_q{$qq}_{$name}"; $attempt->details .= "<field><fieldname>{$fieldname}</fieldname><fielddata>{$value}</fielddata></field>"; } } $q++; } // end main loop through $q(uestions) // set attempt score if ($q > 0) { switch ($quiztype) { case HOTPOT_JCB: break; case HOTPOT_JCLOZE: $attempt->score = floor($attempt->score / $q); break; case HOTPOT_JCROSS: break; case HOTPOT_JMATCH: break; case HOTPOT_JMIX: break; case HOTPOT_JQUIZ: break; } } if ($attempt->details) { $attempt->details = '<?xml version="1.0"?><hpjsresult><fields>' . $attempt->details . '</fields></hpjsresult>'; } // print "forcing status to in progress ..<br/>\n"; // $attempt->status = HOTPOT_STATUS_INPROGRESS; }