diff --git a/question/type/edit_question_form.php b/question/type/edit_question_form.php index 677be4edd4e1f..b40f55055b47e 100644 --- a/question/type/edit_question_form.php +++ b/question/type/edit_question_form.php @@ -484,14 +484,21 @@ public function set_data($question) { } /** - * Any preprocessing needed for the settings form for the question type - * - * @param array $question - array to fill in with the default values + * Perform an preprocessing needed on the data passed to {@link set_data()} + * before it is used to initialise the form. + * @param object $question the data being passed to the form. + * @return object $question the modified data. */ protected function data_preprocessing($question) { return $question; } + /** + * Perform the necessary preprocessing for the fields added by + * {@link add_per_answer_fields()}. + * @param object $question the data being passed to the form. + * @return object $question the modified data. + */ protected function data_preprocessing_answers($question) { if (empty($question->options->answers)) { return $question; @@ -532,6 +539,12 @@ protected function data_preprocessing_answers($question) { return $question; } + /** + * Perform the necessary preprocessing for the fields added by + * {@link add_combined_feedback_fields()}. + * @param object $question the data being passed to the form. + * @return object $question the modified data. + */ protected function data_preprocessing_combined_feedback($question, $withshownumcorrect = false) { if (empty($question->options)) { @@ -565,6 +578,11 @@ protected function data_preprocessing_combined_feedback($question, return $question; } + /** + * Perform the necessary preprocessing for the hint fields. + * @param object $question the data being passed to the form. + * @return object $question the modified data. + */ protected function data_preprocessing_hints($question, $withclearwrong = false, $withshownumpartscorrect = false) { if (empty($question->hints)) { diff --git a/question/type/numerical/backup/moodle2/backup_qtype_numerical_plugin.class.php b/question/type/numerical/backup/moodle2/backup_qtype_numerical_plugin.class.php index 468d9e15bb82b..9c91ff0b70da7 100644 --- a/question/type/numerical/backup/moodle2/backup_qtype_numerical_plugin.class.php +++ b/question/type/numerical/backup/moodle2/backup_qtype_numerical_plugin.class.php @@ -68,7 +68,8 @@ protected function define_question_plugin_structure() { $numericalrecords->add_child($numericalrecord); // set source to populate the data - $numericalrecord->set_source_table('question_numerical', array('question' => backup::VAR_PARENTID)); + $numericalrecord->set_source_table('question_numerical', + array('question' => backup::VAR_PARENTID)); // don't need to annotate ids nor files diff --git a/question/type/numerical/backup/moodle2/restore_qtype_numerical_plugin.class.php b/question/type/numerical/backup/moodle2/restore_qtype_numerical_plugin.class.php index 6a4a53af0a6fd..16649cc7a089b 100644 --- a/question/type/numerical/backup/moodle2/restore_qtype_numerical_plugin.class.php +++ b/question/type/numerical/backup/moodle2/restore_qtype_numerical_plugin.class.php @@ -51,7 +51,7 @@ protected function define_question_plugin_structure() { // Add own qtype stuff $elename = 'numerical'; - $elepath = $this->get_pathfor('/numerical_records/numerical_record'); // we used get_recommended_name() so this works + $elepath = $this->get_pathfor('/numerical_records/numerical_record'); $paths[] = new restore_path_element($elename, $elepath); @@ -72,7 +72,8 @@ public function process_numerical($data) { $newquestionid = $this->get_new_parentid('question'); $questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false; - // If the question has been created by restore, we need to create its question_numerical too + // If the question has been created by restore, we need to create its + // question_numerical too. if ($questioncreated) { // Adjust some columns $data->question = $newquestionid; diff --git a/question/type/numerical/db/upgrade.php b/question/type/numerical/db/upgrade.php index 8470b780bebfb..447454b8c8ac6 100644 --- a/question/type/numerical/db/upgrade.php +++ b/question/type/numerical/db/upgrade.php @@ -98,5 +98,3 @@ function xmldb_qtype_numerical_upgrade($oldversion) { return true; } - - diff --git a/question/type/numerical/edit_numerical_form.php b/question/type/numerical/edit_numerical_form.php index ac79caef3959b..889f56486dc65 100644 --- a/question/type/numerical/edit_numerical_form.php +++ b/question/type/numerical/edit_numerical_form.php @@ -41,15 +41,18 @@ protected function definition_inner($mform) { $this->add_per_answer_fields($mform, get_string('answerno', 'qtype_numerical', '{no}'), $creategrades->gradeoptions); - $this->add_units_options($mform); - $this->add_units_elements($mform); + $this->add_unit_options($mform); + $this->add_unit_fields($mform); $this->add_interactive_settings(); } - protected function get_per_answer_fields($mform, $label, $gradeoptions, &$repeatedoptions, &$answersoption) { - $repeated = parent::get_per_answer_fields($mform, $label, $gradeoptions, $repeatedoptions, $answersoption); + protected function get_per_answer_fields($mform, $label, $gradeoptions, + &$repeatedoptions, &$answersoption) { + $repeated = parent::get_per_answer_fields($mform, $label, $gradeoptions, + $repeatedoptions, $answersoption); - $tolerance = $mform->createElement('text', 'tolerance', get_string('acceptederror', 'qtype_numerical')); + $tolerance = $mform->createElement('text', 'tolerance', + get_string('acceptederror', 'qtype_numerical')); $repeatedoptions['tolerance']['type'] = PARAM_NUMBER; array_splice($repeated, 3, 0, array($tolerance)); $repeated[1]->setSize(10); @@ -61,9 +64,10 @@ protected function get_per_answer_fields($mform, $label, $gradeoptions, &$repeat * Add the unit handling options to the form. * @param object $mform the form being built. */ - protected function add_units_options($mform) { + protected function add_unit_options($mform) { - $mform->addElement('header', 'unithandling', get_string('unithandling', 'qtype_numerical')); + $mform->addElement('header', 'unithandling', + get_string('unithandling', 'qtype_numerical')); $unitoptions = array( qtype_numerical::UNITNONE => get_string('onlynumerical', 'qtype_numerical'), @@ -71,38 +75,45 @@ protected function add_units_options($mform) { qtype_numerical::UNITOPTIONAL => get_string('manynumerical', 'qtype_numerical'), qtype_numerical::UNITGRADED => get_string('unitgraded', 'qtype_numerical'), ); - $mform->addElement('select', 'unitrole', get_string('unithandling', 'qtype_numerical'), $unitoptions); + $mform->addElement('select', 'unitrole', + get_string('unithandling', 'qtype_numerical'), $unitoptions); $penaltygrp = array(); - $penaltygrp[] = $mform->createElement('text', 'unitpenalty', get_string('unitpenalty', 'qtype_numerical') , - array('size' => 6)); + $penaltygrp[] = $mform->createElement('text', 'unitpenalty', + get_string('unitpenalty', 'qtype_numerical'), array('size' => 6)); $mform->setType('unitpenalty', PARAM_NUMBER); $mform->setDefault('unitpenalty', 0.1000000); $unitgradingtypes = array( - qtype_numerical::UNITGRADEDOUTOFMARK => get_string('decfractionofresponsegrade', 'qtype_numerical'), - qtype_numerical::UNITGRADEDOUTOFMAX => get_string('decfractionofquestiongrade', 'qtype_numerical'), + qtype_numerical::UNITGRADEDOUTOFMARK => + get_string('decfractionofresponsegrade', 'qtype_numerical'), + qtype_numerical::UNITGRADEDOUTOFMAX => + get_string('decfractionofquestiongrade', 'qtype_numerical'), ); - $penaltygrp[] = $mform->createElement('select', 'unitgradingtypes', '' , $unitgradingtypes ); + $penaltygrp[] = $mform->createElement('select', 'unitgradingtypes', '', $unitgradingtypes); $mform->setDefault('unitgradingtypes', 1); - $mform->addGroup($penaltygrp, 'penaltygrp', get_string('unitpenalty', 'qtype_numerical'),' ' , false); + $mform->addGroup($penaltygrp, 'penaltygrp', + get_string('unitpenalty', 'qtype_numerical'), ' ', false); $mform->addHelpButton('penaltygrp', 'unitpenalty', 'qtype_numerical'); $unitinputoptions = array( qtype_numerical::UNITINPUT => get_string('editableunittext', 'qtype_numerical'), qtype_numerical::UNITSELECT => get_string('unitchoice', 'qtype_numerical'), ); - $mform->addElement('select', 'multichoicedisplay', get_string('studentunitanswer', 'qtype_numerical'), $unitinputoptions); + $mform->addElement('select', 'multichoicedisplay', + get_string('studentunitanswer', 'qtype_numerical'), $unitinputoptions); $unitslefts = array( 0 => get_string('rightexample', 'qtype_numerical'), 1 => get_string('leftexample', 'qtype_numerical') ); - $mform->addElement('select', 'unitsleft', get_string('unitposition', 'qtype_numerical') , $unitslefts ); + $mform->addElement('select', 'unitsleft', + get_string('unitposition', 'qtype_numerical'), $unitslefts); $mform->setDefault('unitsleft', 0); - $mform->addElement('editor', 'instructions', get_string('instructions', 'qtype_numerical'), null, $this->editoroptions); + $mform->addElement('editor', 'instructions', + get_string('instructions', 'qtype_numerical'), null, $this->editoroptions); $mform->setType('instructions', PARAM_RAW); $mform->addHelpButton('instructions', 'numericalinstructions', 'qtype_numerical'); @@ -121,17 +132,20 @@ protected function add_units_options($mform) { * Add the input areas for each unit. * @param object $mform the form being built. */ - protected function add_units_elements($mform) { + protected function add_unit_fields($mform) { $repeated = array( - $mform->createElement('header', 'unithdr', get_string('unithdr', 'qtype_numerical', '{no}')), + $mform->createElement('header', 'unithdr', + get_string('unithdr', 'qtype_numerical', '{no}')), $mform->createElement('text', 'unit', get_string('unit', 'quiz')), $mform->createElement('text', 'multiplier', get_string('multiplier', 'quiz')), ); $repeatedoptions['unit']['type'] = PARAM_NOTAGS; $repeatedoptions['multiplier']['type'] = PARAM_NUMBER; - $repeatedoptions['unit']['disabledif'] = array('unitrole', 'eq', qtype_numerical::UNITNONE); - $repeatedoptions['multiplier']['disabledif'] = array('unitrole', 'eq', qtype_numerical::UNITNONE); + $repeatedoptions['unit']['disabledif'] = + array('unitrole', 'eq', qtype_numerical::UNITNONE); + $repeatedoptions['multiplier']['disabledif'] = + array('unitrole', 'eq', qtype_numerical::UNITNONE); if (isset($this->question->options->units)) { $countunits = count($this->question->options->units); @@ -143,8 +157,8 @@ protected function add_units_elements($mform) { } else { $repeatsatstart = $countunits; } - $this->repeat_elements($repeated, $repeatsatstart, $repeatedoptions, - 'nounits', 'addunits', 2, get_string('addmoreunitblanks', 'qtype_calculated', '{no}')); + $this->repeat_elements($repeated, $repeatsatstart, $repeatedoptions, 'nounits', + 'addunits', 2, get_string('addmoreunitblanks', 'qtype_calculated', '{no}')); if ($mform->elementExists('multiplier[0]')) { $firstunit = $mform->getElement('multiplier[0]'); @@ -160,7 +174,7 @@ protected function data_preprocessing($question) { $question = $this->data_preprocessing_answers($question); $question = $this->data_preprocessing_hints($question); $question = $this->data_preprocessing_units($question); - $question = $this->data_preprocessing_numerical_options($question); + $question = $this->data_preprocessing_unit_options($question); return $question; } @@ -180,9 +194,12 @@ protected function data_preprocessing_answers($question) { } /** - * TODO + * Perform the necessary preprocessing for the fields added by + * {@link add_unit_fields()}. + * @param object $question the data being passed to the form. + * @return object $question the modified data. */ - function data_preprocessing_units($question) { + protected function data_preprocessing_units($question) { if (empty($question->options->units)) { return $question; } @@ -196,9 +213,12 @@ function data_preprocessing_units($question) { } /** - * TODO + * Perform the necessary preprocessing for the fields added by + * {@link add_unit_options()}. + * @param object $question the data being passed to the form. + * @return object $question the modified data. */ - function data_preprocessing_numerical_options($question) { + protected function data_preprocessing_unit_options($question) { if (empty($question->options)) { return $question; } @@ -243,13 +263,16 @@ public function validation($data, $files) { if ($trimmedanswer != '') { $answercount++; if (!(is_numeric($trimmedanswer) || $trimmedanswer == '*')) { - $errors["answer[$key]"] = get_string('answermustbenumberorstar', 'qtype_numerical'); + $errors['answer[' . $key . ']'] = + get_string('answermustbenumberorstar', 'qtype_numerical'); } if ($data['fraction'][$key] == 1) { $maxgrade = true; } - } else if ($data['fraction'][$key] != 0 || !html_is_blank($data['feedback'][$key]['text'])) { - $errors["answer[$key]"] = get_string('answermustbenumberorstar', 'qtype_numerical'); + } else if ($data['fraction'][$key] != 0 || + !html_is_blank($data['feedback'][$key]['text'])) { + $errors['answer[' . $key . ']'] = + get_string('answermustbenumberorstar', 'qtype_numerical'); $answercount++; } } @@ -269,7 +292,6 @@ public function validation($data, $files) { * Validate the unit options. */ function validate_numerical_options($data, $errors) { - print_object($data); // DONOTCOMMIT if ($data['unitrole'] != qtype_numerical::UNITNONE && trim($data['unit'][0]) == '') { $errors['unit[0]'] = get_string('unitonerequired', 'qtype_numerical'); } diff --git a/question/type/numerical/lang/en/qtype_numerical.php b/question/type/numerical/lang/en/qtype_numerical.php index 2e7ff2ca672e5..91cb9276122e6 100644 --- a/question/type/numerical/lang/en/qtype_numerical.php +++ b/question/type/numerical/lang/en/qtype_numerical.php @@ -105,7 +105,7 @@ $string['unithandling'] = 'Unit handling'; $string['validnumberformats'] = 'Valid number formats'; $string['validnumberformats_help'] = ' -* regular numbers 13500.67 : 13 500.67 : 13500,67: 13 500,67 +* regular numbers 13500.67, 13 500.67, 13500,67 or 13 500,67 * if you use , as thousand separator *always* put the decimal . as in 13,500.67 : 13,500. @@ -113,4 +113,4 @@ * for exponent form, say 1.350067 * 104, use 1.350067 E4 : 1.350067 E04 '; -$string['validnumbers'] = ' 13500.67 : 13 500.67 : 13,500.67 : 13500,67: 13 500,67 : 1.350067 E4 : 1.350067 E04 '; +$string['validnumbers'] = '13500.67, 13 500.67, 13,500.67, 13500,67, 13 500,67, 1.350067 E4 or 1.350067 E04'; diff --git a/question/type/numerical/questiontype.php b/question/type/numerical/questiontype.php index da6af35f0f571..9f625f8acf462 100644 --- a/question/type/numerical/questiontype.php +++ b/question/type/numerical/questiontype.php @@ -70,11 +70,13 @@ public function get_question_options($question) { "WHERE a.question = ? " . " AND a.id = n.answer " . "ORDER BY a.id ASC", array($question->id))) { - echo $OUTPUT->notification('Error: Missing question answer for numerical question ' . $question->id . '!'); + echo $OUTPUT->notification('Error: Missing question answer for numerical question ' . + $question->id . '!'); return false; } - $question->hints = $DB->get_records('question_hints', array('questionid' => $question->id), 'id ASC'); + $question->hints = $DB->get_records('question_hints', + array('questionid' => $question->id), 'id ASC'); $this->get_numerical_units($question); //get_numerical_options() need to know if there are units @@ -84,7 +86,7 @@ public function get_question_options($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) { + foreach ($question->options->answers as $key => $val) { $answer = trim($val->answer); $length = strlen($defaultunit->unit); if ($length && substr($answer, -$length) == $defaultunit->unit) { @@ -113,7 +115,7 @@ public function get_numerical_units(&$question) { return true; } - public function get_default_numerical_unit(&$question) { + public 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')) { @@ -124,16 +126,17 @@ public function get_default_numerical_unit(&$question) { return false; } - public function get_numerical_options(&$question) { + public function get_numerical_options($question) { global $DB; - if (!$options = $DB->get_record('question_numerical_options', array('question' => $question->id))) { + if (!$options = $DB->get_record('question_numerical_options', + array('question' => $question->id))) { $question->options->unitgradingtype = 0; // total grade $question->options->unitpenalty = 0.1; // default for old questions // the default if ($defaultunit = $this->get_default_numerical_unit($question)) { // so units can be graded $question->options->showunits = NUMERICALQUESTIONUNITTEXTINPUTDISPLAY ; - }else { + } else { // only numerical will be graded $question->options->showunits = NUMERICALQUESTIONUNITNODISPLAY ; } @@ -166,7 +169,7 @@ public function save_question_options($question) { array('question' => $question->id), 'answer ASC'); // Save the units. - $result = $this->save_numerical_units($question); + $result = $this->save_units($question); if (isset($result->error)) { return $result; } else { @@ -228,15 +231,15 @@ public function save_question_options($question) { // Delete any left over old answer records. $fs = get_file_storage(); - foreach($oldanswers as $oldanswer) { + foreach ($oldanswers as $oldanswer) { $fs->delete_area_files($context->id, 'question', 'answerfeedback', $oldanswer->id); $DB->delete_records('question_answers', array('id' => $oldanswer->id)); } - foreach($oldoptions as $oldoption) { + foreach ($oldoptions as $oldoption) { $DB->delete_records('question_numerical', array('id' => $oldoption->id)); } - $result = $this->save_numerical_options($question); + $result = $this->save_unit_options($question); if (!empty($result->error) || !empty($result->notice)) { return $result; } @@ -249,14 +252,13 @@ public function save_question_options($question) { /** * The numerical options control the display and the grading of the unit * part of the numerical question and related types (calculateds) - * Questions previous to 2,0 do not have this table as multianswer questions - * in all versions including 2,0. The default values are set to give the same grade + * Questions previous to 2.0 do not have this table as multianswer questions + * in all versions including 2.0. The default values are set to give the same grade * as old question. * */ - function save_numerical_options($question) { + function save_unit_options($question) { global $DB; - $result = new stdClass(); $update = true ; @@ -281,6 +283,7 @@ function save_numerical_options($question) { $options->showunits = $question->unitrole; if ($question->unitrole == self::UNITGRADED) { $options->unitgradingtype = $question->unitgradingtypes; + $options->showunits = $question->multichoicedisplay; } } else if (isset($question->showunits)) { @@ -312,7 +315,7 @@ function save_numerical_options($question) { return true; } - public function save_numerical_units($question) { + public function save_units($question) { global $DB; $result = new stdClass(); @@ -330,8 +333,9 @@ public function save_numerical_units($question) { $unitalreadyinsert = 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])&& !array_key_exists($question->unit[$i],$unitalreadyinsert)) { - $unitalreadyinsert[$question->unit[$i]] = 1 ; + if (!empty($question->multiplier[$i]) && !empty($question->unit[$i]) && + !array_key_exists($question->unit[$i], $unitalreadyinsert)) { + $unitalreadyinsert[$question->unit[$i]] = 1; $units[$i] = new stdClass(); $units[$i]->question = $question->id; $units[$i]->multiplier = $this->apply_unit($question->multiplier[$i], array()); @@ -349,7 +353,7 @@ function find_unit_index($question, $value) { $length = 0; $goodkey = 0 ; foreach ($question->options->units as $key => $unit) { - if($unit->unit ==$value ) { + if ($unit->unit == $value) { return $key ; } } @@ -409,12 +413,13 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions $nameprefix = $question->name_prefix; $component = 'qtype_' . $question->qtype; // rewrite instructions text - $question->options->instructions = quiz_rewrite_question_urls($question->options->instructions, 'pluginfile.php', $context->id, $component, 'instruction', array($state->attempt, $state->question), $question->id); + $question->options->instructions = quiz_rewrite_question_urls( + $question->options->instructions, 'pluginfile.php', $context->id, $component, + 'instruction', array($state->attempt, $state->question), $question->id); /// Print question text and media $questiontext = format_text($question->questiontext, - $question->questiontextformat, - $formatoptions, $cmoptions->course); + $question->questiontextformat, $formatoptions, $cmoptions->course); /// Print input controls // as the entry is controlled the question type here is numerical @@ -1054,7 +1059,7 @@ function check_file_access($question, $state, $options, $contextid, $component, if (!$result) { return false; } - foreach($question->options->answers as $answer) { + foreach ($question->options->answers as $answer) { if ($this->test_response($question, $state, $answer)) { return true; } diff --git a/question/type/numerical/renderer.php b/question/type/numerical/renderer.php index ecbe3173c8248..12f59bebd182b 100644 --- a/question/type/numerical/renderer.php +++ b/question/type/numerical/renderer.php @@ -98,7 +98,8 @@ public function formulation_and_controls(question_attempt $qa, public function specific_feedback(question_attempt $qa) { $question = $qa->get_question(); - $answer = $question->get_matching_answer(array('answer' => $qa->get_last_qt_var('answer'))); + $answer = $question->get_matching_answer( + array('answer' => $qa->get_last_qt_var('answer'))); if (!$answer || !$answer->feedback) { return ''; } diff --git a/question/type/numerical/simpletest/testanswerprocessor.php b/question/type/numerical/simpletest/testanswerprocessor.php index 1a57e07be35ad..0d9245f4284e0 100644 --- a/question/type/numerical/simpletest/testanswerprocessor.php +++ b/question/type/numerical/simpletest/testanswerprocessor.php @@ -71,8 +71,10 @@ public function test_parse_response() { $this->assertEqual(array('1', '', '-1', 'm'), $ap->parse_response('1.e-1 m')); $this->assertEqual(array('1', '0', '0', 'cm'), $ap->parse_response('1.0e0cm')); - $this->assertEqual(array('1000000', '', '', ''), $ap->parse_response('1,000,000')); - $this->assertEqual(array('1000', '00', '', 'm'), $ap->parse_response('1,000.00 m')); + $this->assertEqual(array('1000000', '', '', ''), + $ap->parse_response('1,000,000')); + $this->assertEqual(array('1000', '00', '', 'm'), + $ap->parse_response('1,000.00 m')); $this->assertEqual(array(null, null, null, null), $ap->parse_response('frog')); $this->assertEqual(array(null, null, null, null), $ap->parse_response('3 frogs')); diff --git a/question/type/numerical/simpletest/testquestiontype.php b/question/type/numerical/simpletest/testquestiontype.php index b23d7c8aec045..7b39fa9edbe0c 100644 --- a/question/type/numerical/simpletest/testquestiontype.php +++ b/question/type/numerical/simpletest/testquestiontype.php @@ -37,7 +37,11 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class qtype_numerical_test extends UnitTestCase { - public static $includecoverage = array('question/type/questiontype.php', 'question/type/numerical/questiontype.php'); + public static $includecoverage = array( + 'question/type/questiontype.php', + 'question/type/numerical/questiontype.php' + ); + protected $tolerance = 0.00000001; protected $qtype;