📄 questiontype.php
字号:
<?php // $Id: questiontype.php,v 1.29.2.9 2008/11/27 05:13:41 tjhunt Exp $/** * The questiontype class for the multiple choice question type. * * Note, This class contains some special features in order to make the * question type embeddable within a multianswer (cloze) question * * @package questionbank * @subpackage questiontypes */class question_multichoice_qtype extends default_questiontype { function name() { return 'multichoice'; } function has_html_answers() { return true; } function get_question_options(&$question) { // Get additional information from database // and attach it to the question object if (!$question->options = get_record('question_multichoice', 'question', $question->id)) { notify('Error: Missing question options for multichoice question'.$question->id.'!'); return false; } if (!$question->options->answers = get_records_select('question_answers', 'id IN ('.$question->options->answers.')', 'id')) { notify('Error: Missing question answers for multichoice question'.$question->id.'!'); return false; } return true; } function save_question_options($question) { $result = new stdClass; if (!$oldanswers = get_records("question_answers", "question", $question->id, "id ASC")) { $oldanswers = array(); } // following hack to check at least two answers exist $answercount = 0; foreach ($question->answer as $key=>$dataanswer) { if ($dataanswer != "") { $answercount++; } } $answercount += count($oldanswers); if ($answercount < 2) { // check there are at lest 2 answers for multiple choice $result->notice = get_string("notenoughanswers", "qtype_multichoice", "2"); return $result; } // Insert all the new answers $totalfraction = 0; $maxfraction = -1; $answers = array(); foreach ($question->answer as $key => $dataanswer) { if ($dataanswer != "") { if ($answer = array_shift($oldanswers)) { // Existing answer, so reuse it $answer->answer = $dataanswer; $answer->fraction = $question->fraction[$key]; $answer->feedback = $question->feedback[$key]; if (!update_record("question_answers", $answer)) { $result->error = "Could not update quiz answer! (id=$answer->id)"; return $result; } } else { unset($answer); $answer->answer = $dataanswer; $answer->question = $question->id; $answer->fraction = $question->fraction[$key]; $answer->feedback = $question->feedback[$key]; if (!$answer->id = insert_record("question_answers", $answer)) { $result->error = "Could not insert quiz answer! "; return $result; } } $answers[] = $answer->id; if ($question->fraction[$key] > 0) { // Sanity checks $totalfraction += $question->fraction[$key]; } if ($question->fraction[$key] > $maxfraction) { $maxfraction = $question->fraction[$key]; } } } $update = true; $options = get_record("question_multichoice", "question", $question->id); if (!$options) { $update = false; $options = new stdClass; $options->question = $question->id; } $options->answers = implode(",",$answers); $options->single = $question->single; if(isset($question->layout)){ $options->layout = $question->layout; } $options->answernumbering = $question->answernumbering; $options->shuffleanswers = $question->shuffleanswers; $options->correctfeedback = trim($question->correctfeedback); $options->partiallycorrectfeedback = trim($question->partiallycorrectfeedback); $options->incorrectfeedback = trim($question->incorrectfeedback); if ($update) { if (!update_record("question_multichoice", $options)) { $result->error = "Could not update quiz multichoice options! (id=$options->id)"; return $result; } } else { if (!insert_record("question_multichoice", $options)) { $result->error = "Could not insert quiz multichoice options!"; return $result; } } // delete old answer records if (!empty($oldanswers)) { foreach($oldanswers as $oa) { delete_records('question_answers', 'id', $oa->id); } } /// Perform sanity checks on fractional grades if ($options->single) { if ($maxfraction != 1) { $maxfraction = $maxfraction * 100; $result->noticeyesno = get_string("fractionsnomax", "qtype_multichoice", $maxfraction); return $result; } } else { $totalfraction = round($totalfraction,2); if ($totalfraction != 1) { $totalfraction = $totalfraction * 100; $result->noticeyesno = get_string("fractionsaddwrong", "qtype_multichoice", $totalfraction); return $result; } } return true; } /** * Deletes question from the question-type specific tables * * @return boolean Success/Failure * @param object $question The question being deleted */ function delete_question($questionid) { delete_records("question_multichoice", "question", $questionid); return true; } function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) { // create an array of answerids ??? why so complicated ??? $answerids = array_values(array_map(create_function('$val', 'return $val->id;'), $question->options->answers)); // Shuffle the answers if required if (!empty($cmoptions->shuffleanswers) and !empty($question->options->shuffleanswers)) { $answerids = swapshuffle($answerids); } $state->options->order = $answerids; // Create empty responses if ($question->options->single) { $state->responses = array('' => ''); } else { $state->responses = array(); } return true; } function restore_session_and_responses(&$question, &$state) { // The serialized format for multiple choice quetsions // is an optional comma separated list of answer ids (the order of the // answers) followed by a colon, followed by another comma separated // list of answer ids, which are the radio/checkboxes that were // ticked. // E.g. 1,3,2,4:2,4 means that the answers were shown in the order // 1, 3, 2 and then 4 and the answers 2 and 4 were checked. $pos = strpos($state->responses[''], ':'); if (false === $pos) { // No order of answers is given, so use the default $state->options->order = array_keys($question->options->answers); } else { // Restore the order of the answers $state->options->order = explode(',', substr($state->responses[''], 0, $pos)); $state->responses[''] = substr($state->responses[''], $pos + 1); } // Restore the responses // This is done in different ways if only a single answer is allowed or // if multiple answers are allowed. For single answers the answer id is // saved in $state->responses[''], whereas for the multiple answers case // the $state->responses array is indexed by the answer ids and the // values are also the answer ids (i.e. key = value). if (empty($state->responses[''])) { // No previous responses $state->responses = array('' => ''); } else { if ($question->options->single) { $state->responses = array('' => $state->responses['']); } else { // Get array of answer ids $state->responses = explode(',', $state->responses['']); // Create an array indexed by these answer ids $state->responses = array_flip($state->responses); // Set the value of each element to be equal to the index array_walk($state->responses, create_function('&$a, $b', '$a = $b;')); } } return true; } function save_session_and_responses(&$question, &$state) { // Bundle the answer order and the responses into the legacy answer // field. // The serialized format for multiple choice quetsions // is (optionally) a comma separated list of answer ids // followed by a colon, followed by another comma separated // list of answer ids, which are the radio/checkboxes that were // ticked. // E.g. 1,3,2,4:2,4 means that the answers were shown in the order // 1, 3, 2 and then 4 and the answers 2 and 4 were checked. $responses = implode(',', $state->options->order) . ':'; $responses .= implode(',', $state->responses); // Set the legacy answer field if (!set_field('question_states', 'answer', $responses, 'id', $state->id)) { return false; } return true; } function get_correct_responses(&$question, &$state) { if ($question->options->single) { foreach ($question->options->answers as $answer) { if (((int) $answer->fraction) === 1) { return array('' => $answer->id); } } return null; } else { $responses = array(); foreach ($question->options->answers as $answer) { if (((float) $answer->fraction) > 0.0) { $responses[$answer->id] = (string) $answer->id; } } return empty($responses) ? null : $responses; } } function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options) { global $CFG; $answers = &$question->options->answers; $correctanswers = $this->get_correct_responses($question, $state); $readonly = empty($options->readonly) ? '' : 'disabled="disabled"'; $formatoptions = new stdClass; $formatoptions->noclean = true; $formatoptions->para = false; // Print formulation $questiontext = format_text($question->questiontext, $question->questiontextformat, $formatoptions, $cmoptions->course); $image = get_question_image($question); $answerprompt = ($question->options->single) ? get_string('singleanswer', 'quiz') : get_string('multipleanswers', 'quiz'); // Print each answer in a separate row foreach ($state->options->order as $key => $aid) { $answer = &$answers[$aid]; $checked = ''; $chosen = false; if ($question->options->single) { $type = 'type="radio"'; $name = "name=\"{$question->name_prefix}\""; if (isset($state->responses['']) and $aid == $state->responses['']) { $checked = 'checked="checked"'; $chosen = true; } } else { $type = ' type="checkbox" '; $name = "name=\"{$question->name_prefix}{$aid}\""; if (isset($state->responses[$aid])) { $checked = 'checked="checked"'; $chosen = true; } } $a = new stdClass; $a->id = $question->name_prefix . $aid; $a->class = ''; $a->feedbackimg = ''; // Print the control $a->control = "<input $readonly id=\"$a->id\" $name $checked $type value=\"$aid\" />"; if ($options->correct_responses && $answer->fraction > 0) { $a->class = question_get_feedback_class(1); } if (($options->feedback && $chosen) || $options->correct_responses) { if ($type == ' type="checkbox" ') { $a->feedbackimg = question_get_feedback_image($answer->fraction > 0 ? 1 : 0, $chosen && $options->feedback); } else { $a->feedbackimg = question_get_feedback_image($answer->fraction, $chosen && $options->feedback); } } // Print the answer text $a->text = $this->number_in_style($key, $question->options->answernumbering) . format_text($answer->answer, FORMAT_MOODLE, $formatoptions, $cmoptions->course); // Print feedback if feedback is on if (($options->feedback || $options->correct_responses) && $checked) { $a->feedback = format_text($answer->feedback, true, $formatoptions, $cmoptions->course); } else { $a->feedback = ''; } $anss[] = clone($a); } $feedback = ''; if ($options->feedback) { if ($state->raw_grade >= $question->maxgrade/1.01) { $feedback = $question->options->correctfeedback; } else if ($state->raw_grade > 0) { $feedback = $question->options->partiallycorrectfeedback; } else { $feedback = $question->options->incorrectfeedback; } $feedback = format_text($feedback, $question->questiontextformat, $formatoptions, $cmoptions->course); } include("$CFG->dirroot/question/type/multichoice/display.html"); } function grade_responses(&$question, &$state, $cmoptions) { $state->raw_grade = 0; if($question->options->single) { $response = reset($state->responses); if ($response) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -