📄 questiontype.php
字号:
<?php // $Id: questiontype.php,v 1.14.4.13 2009/02/19 01:09:35 tjhunt Exp $/** * @version $Id: questiontype.php,v 1.14.4.13 2009/02/19 01:09:35 tjhunt Exp $ * @author Martin Dougiamas and many others. Tim Hunt. * @license http://www.gnu.org/copyleft/gpl.html GNU Public License * @package questionbank * @subpackage questiontypes *//** */require_once("$CFG->dirroot/question/type/shortanswer/questiontype.php");/** * NUMERICAL QUESTION TYPE CLASS * * This class contains some special features in order to make the * question type embeddable within a multianswer (cloze) question * * This question type behaves like shortanswer in most cases. * Therefore, it extends the shortanswer question type... * @package questionbank * @subpackage questiontypes */class question_numerical_qtype extends question_shortanswer_qtype { function name() { return 'numerical'; } function get_question_options(&$question) { // Get the question answers and their respective tolerances // Note: question_numerical is an extension of the answer table rather than // the question table as is usually the case for qtype // specific tables. global $CFG; if (!$question->options->answers = get_records_sql( "SELECT a.*, n.tolerance " . "FROM {$CFG->prefix}question_answers a, " . " {$CFG->prefix}question_numerical n " . "WHERE a.question = $question->id " . " AND a.id = n.answer " . "ORDER BY a.id ASC")) { notify('Error: Missing question answer for numerical question ' . $question->id . '!'); return false; } $this->get_numerical_units($question); // If units are defined we strip off the default unit from the answer, if // it is present. (Required for compatibility with the old code and DB). if ($defaultunit = $this->get_default_numerical_unit($question)) { foreach($question->options->answers as $key => $val) { $answer = trim($val->answer); $length = strlen($defaultunit->unit); if ($length && substr($answer, -$length) == $defaultunit->unit) { $question->options->answers[$key]->answer = substr($answer, 0, strlen($answer)-$length); } } } return true; } function get_numerical_units(&$question) { if ($units = get_records('question_numerical_units', 'question', $question->id, 'id ASC')) { $units = array_values($units); } else { $units = array(); } foreach ($units as $key => $unit) { $units[$key]->multiplier = clean_param($unit->multiplier, PARAM_NUMBER); } $question->options->units = $units; return true; } function get_default_numerical_unit(&$question) { if (isset($question->options->units[0])) { foreach ($question->options->units as $unit) { if (abs($unit->multiplier - 1.0) < '1.0e-' . ini_get('precision')) { return $unit; } } } return false; } /** * Save the units and the answers associated with this question. */ function save_question_options($question) { // Get old versions of the objects if (!$oldanswers = get_records('question_answers', 'question', $question->id, 'id ASC')) { $oldanswers = array(); } if (!$oldoptions = get_records('question_numerical', 'question', $question->id, 'answer ASC')) { $oldoptions = array(); } // Save the units. $result = $this->save_numerical_units($question); if (isset($result->error)) { return $result; } else { $units = &$result->units; } // Insert all the new answers foreach ($question->answer as $key => $dataanswer) { // Check for, and ingore, completely blank answer from the form. if (trim($dataanswer) == '' && $question->fraction[$key] == 0 && html_is_blank($question->feedback[$key])) { continue; } $answer = new stdClass; $answer->question = $question->id; if (trim($dataanswer) === '*') { $answer->answer = '*'; } else { $answer->answer = $this->apply_unit($dataanswer, $units); if ($answer->answer === false) { $result->notice = get_string('invalidnumericanswer', 'quiz'); } } $answer->fraction = $question->fraction[$key]; $answer->feedback = trim($question->feedback[$key]); if ($oldanswer = array_shift($oldanswers)) { // Existing answer, so reuse it $answer->id = $oldanswer->id; if (! update_record("question_answers", $answer)) { $result->error = "Could not update quiz answer! (id=$answer->id)"; return $result; } } else { // This is a completely new answer if (! $answer->id = insert_record("question_answers", $answer)) { $result->error = "Could not insert quiz answer!"; return $result; } } // Set up the options object if (!$options = array_shift($oldoptions)) { $options = new stdClass; } $options->question = $question->id; $options->answer = $answer->id; if (trim($question->tolerance[$key]) == '') { $options->tolerance = ''; } else { $options->tolerance = $this->apply_unit($question->tolerance[$key], $units); if ($options->tolerance === false) { $result->notice = get_string('invalidnumerictolerance', 'quiz'); } } // Save options if (isset($options->id)) { // reusing existing record if (! update_record('question_numerical', $options)) { $result->error = "Could not update quiz numerical options! (id=$options->id)"; return $result; } } else { // new options if (! insert_record('question_numerical', $options)) { $result->error = "Could not insert quiz numerical options!"; return $result; } } } // delete old answer records if (!empty($oldanswers)) { foreach($oldanswers as $oa) { delete_records('question_answers', 'id', $oa->id); } } // delete old answer records if (!empty($oldoptions)) { foreach($oldoptions as $oo) { delete_records('question_numerical', 'id', $oo->id); } } // Report any problems. if (!empty($result->notice)) { return $result; } return true; } function save_numerical_units($question) { $result = new stdClass; // Delete the units previously saved for this question. delete_records('question_numerical_units', 'question', $question->id); // Nothing to do. if (!isset($question->multiplier)) { $result->units = array(); return $result; } // Save the new units. $units = array(); foreach ($question->multiplier as $i => $multiplier) { // Discard any unit which doesn't specify the unit or the multiplier if (!empty($question->multiplier[$i]) && !empty($question->unit[$i])) { $units[$i] = new stdClass; $units[$i]->question = $question->id; $units[$i]->multiplier = $this->apply_unit($question->multiplier[$i], array()); $units[$i]->unit = $question->unit[$i]; if (! insert_record('question_numerical_units', $units[$i])) { $result->error = 'Unable to save unit ' . $units[$i]->unit . ' to the Databse'; return $result; } } } unset($question->multiplier, $question->unit); $result->units = &$units; return $result; } /** * 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_numerical", "question", $questionid); delete_records("question_numerical_units", "question", $questionid); return true; } function compare_responses(&$question, $state, $teststate) { if (isset($state->responses['']) && isset($teststate->responses[''])) { return $state->responses[''] == $teststate->responses['']; } return false; } /** * Checks whether a response matches a given answer, taking the tolerance * and units into account. Returns a true for if a response matches the * answer, false if it doesn't. */ function test_response(&$question, &$state, $answer) { // Deal with the match anything answer. if ($answer->answer === '*') { return true; } $response = $this->apply_unit(stripslashes($state->responses['']), $question->options->units); if ($response === false) { return false; // The student did not type a number. }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -