|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00027 defined('MOODLE_INTERNAL') || die(); 00028 00029 require_once($CFG->dirroot . '/question/type/numerical/edit_numerical_form.php'); 00030 00031 00038 class qtype_calculated_edit_form extends qtype_numerical_edit_form { 00044 public $qtypeobj; 00045 public $questiondisplay; 00046 public $activecategory; 00047 public $categorychanged = false; 00048 public $initialname = ''; 00049 public $reload = false; 00050 00051 public function __construct($submiturl, $question, $category, $contexts, 00052 $formeditable = true) { 00053 global $CFG, $DB; 00054 $this->question = $question; 00055 $this->reload = optional_param('reload', false, PARAM_BOOL); 00056 00057 if (!$this->reload) { // use database data as this is first pass 00058 if (isset($this->question->id)) { 00059 // remove prefix #{..}# if exists 00060 $this->initialname = $question->name; 00061 $regs= array(); 00062 if (preg_match('~#\{([^[:space:]]*)#~', $question->name , $regs)) { 00063 $question->name = str_replace($regs[0], '', $question->name); 00064 }; 00065 } 00066 } 00067 parent::__construct($submiturl, $question, $category, $contexts, $formeditable); 00068 } 00069 00070 public function get_per_answer_fields($mform, $label, $gradeoptions, 00071 &$repeatedoptions, &$answersoption) { 00072 $repeated = parent::get_per_answer_fields($mform, $label, $gradeoptions, 00073 $repeatedoptions, $answersoption); 00074 00075 // 1 is the answer. 3 is tolerance. 00076 $repeated[1]->setLabel(get_string('correctanswerformula', 'qtype_calculated') . '='); 00077 $repeated[3]->setLabel(get_string('tolerance', 'qtype_calculated') . '='); 00078 $repeatedoptions['tolerance']['default'] = 0.01; 00079 00080 $addrepeated = array(); 00081 $addrepeated[] = $mform->createElement('select', 'tolerancetype', 00082 get_string('tolerancetype', 'qtype_numerical'), $this->qtypeobj->tolerance_types()); 00083 00084 $addrepeated[] = $mform->createElement('select', 'correctanswerlength', 00085 get_string('correctanswershows', 'qtype_calculated'), range(0, 9)); 00086 $repeatedoptions['correctanswerlength']['default'] = 2; 00087 00088 $answerlengthformats = array( 00089 '1' => get_string('decimalformat', 'qtype_numerical'), 00090 '2' => get_string('significantfiguresformat', 'qtype_calculated') 00091 ); 00092 $addrepeated[] = $mform->createElement('select', 'correctanswerformat', 00093 get_string('correctanswershowsformat', 'qtype_calculated'), $answerlengthformats); 00094 00095 array_splice($repeated, 4, 0, $addrepeated); 00096 00097 return $repeated; 00098 } 00099 00105 protected function definition_inner($mform) { 00106 $this->qtypeobj = question_bank::get_qtype($this->qtype()); 00107 $label = get_string('sharedwildcards', 'qtype_calculated'); 00108 $mform->addElement('hidden', 'initialcategory', 1); 00109 $mform->addElement('hidden', 'reload', 1); 00110 $mform->setType('initialcategory', PARAM_INT); 00111 $html2 = $this->qtypeobj->print_dataset_definitions_category($this->question); 00112 $mform->insertElementBefore( 00113 $mform->createElement('static', 'listcategory', $label, $html2), 'name'); 00114 if (isset($this->question->id)) { 00115 $mform->insertElementBefore($mform->createElement('static', 'initialname', 00116 get_string('questionstoredname', 'qtype_calculated'), 00117 $this->initialname), 'name'); 00118 }; 00119 $addfieldsname = 'updatecategory'; 00120 $addstring = get_string('updatecategory', 'qtype_calculated'); 00121 $mform->registerNoSubmitButton($addfieldsname); 00122 00123 $mform->insertElementBefore( 00124 $mform->createElement('submit', $addfieldsname, $addstring), 'listcategory'); 00125 $mform->registerNoSubmitButton('createoptionbutton'); 00126 00127 //editing as regular 00128 $mform->setType('single', PARAM_INT); 00129 00130 $mform->addElement('hidden', 'shuffleanswers', '1'); 00131 $mform->setType('shuffleanswers', PARAM_INT); 00132 $mform->addElement('hidden', 'answernumbering', 'abc'); 00133 $mform->setType('answernumbering', PARAM_SAFEDIR); 00134 00135 $this->add_per_answer_fields($mform, get_string('answerhdr', 'qtype_calculated', '{no}'), 00136 question_bank::fraction_options(), 1, 1); 00137 00138 $repeated = array(); 00139 00140 $this->add_unit_options($mform, $this); 00141 $this->add_unit_fields($mform, $this); 00142 $this->add_interactive_settings(); 00143 00144 // Hidden elements 00145 $mform->addElement('hidden', 'synchronize', ''); 00146 $mform->setType('synchronize', PARAM_INT); 00147 $mform->addElement('hidden', 'wizard', 'datasetdefinitions'); 00148 $mform->setType('wizard', PARAM_ALPHA); 00149 } 00150 00151 public function data_preprocessing($question) { 00152 $question = parent::data_preprocessing($question); 00153 $question = $this->data_preprocessing_answers($question); 00154 $question = $this->data_preprocessing_hints($question); 00155 $question = $this->data_preprocessing_units($question); 00156 $question = $this->data_preprocessing_unit_options($question); 00157 00158 if (isset($question->options->synchronize)) { 00159 $question->synchronize = $question->options->synchronize; 00160 } 00161 00162 return $question; 00163 } 00164 00165 protected function data_preprocessing_answers($question) { 00166 $question = parent::data_preprocessing_answers($question); 00167 if (empty($question->options->answers)) { 00168 return $question; 00169 } 00170 00171 $key = 0; 00172 foreach ($question->options->answers as $answer) { 00173 // See comment in the parent method about this hack. 00174 unset($this->_form->_defaultValues["tolerancetype[$key]"]); 00175 unset($this->_form->_defaultValues["correctanswerlength[$key]"]); 00176 unset($this->_form->_defaultValues["correctanswerformat[$key]"]); 00177 00178 $question->tolerancetype[$key] = $answer->tolerancetype; 00179 $question->correctanswerlength[$key] = $answer->correctanswerlength; 00180 $question->correctanswerformat[$key] = $answer->correctanswerformat; 00181 $key++; 00182 } 00183 00184 return $question; 00185 } 00186 00187 public function qtype() { 00188 return 'calculated'; 00189 } 00190 00191 public function validation($data, $files) { 00192 00193 // verifying for errors in {=...} in question text; 00194 $qtext = ""; 00195 $qtextremaining = $data['questiontext']['text']; 00196 $possibledatasets = $this->qtypeobj->find_dataset_names($data['questiontext']['text']); 00197 foreach ($possibledatasets as $name => $value) { 00198 $qtextremaining = str_replace('{'.$name.'}', '1', $qtextremaining); 00199 } 00200 while (preg_match('~\{=([^[:space:]}]*)}~', $qtextremaining, $regs1)) { 00201 $qtextsplits = explode($regs1[0], $qtextremaining, 2); 00202 $qtext = $qtext.$qtextsplits[0]; 00203 $qtextremaining = $qtextsplits[1]; 00204 if (!empty($regs1[1]) && $formulaerrors = 00205 qtype_calculated_find_formula_errors($regs1[1])) { 00206 if (!isset($errors['questiontext'])) { 00207 $errors['questiontext'] = $formulaerrors.':'.$regs1[1]; 00208 } else { 00209 $errors['questiontext'] .= '<br/>'.$formulaerrors.':'.$regs1[1]; 00210 } 00211 } 00212 } 00213 00214 $errors = parent::validation($data, $files); 00215 00216 // Check that the answers use datasets. 00217 $answers = $data['answer']; 00218 $mandatorydatasets = array(); 00219 foreach ($answers as $key => $answer) { 00220 $mandatorydatasets += $this->qtypeobj->find_dataset_names($answer); 00221 } 00222 if (empty($mandatorydatasets)) { 00223 foreach ($answers as $key => $answer) { 00224 $errors['answer['.$key.']'] = 00225 get_string('atleastonewildcard', 'qtype_calculated'); 00226 } 00227 } 00228 00229 // Validate the answer format. 00230 foreach ($answers as $key => $answer) { 00231 $trimmedanswer = trim($answer); 00232 if (trim($answer)) { 00233 if ($data['correctanswerformat'][$key] == 2 && 00234 $data['correctanswerlength'][$key] == '0') { 00235 $errors['correctanswerlength['.$key.']'] = 00236 get_string('zerosignificantfiguresnotallowed', 'qtype_calculated'); 00237 } 00238 } 00239 } 00240 00241 return $errors; 00242 } 00243 00244 protected function is_valid_answer($answer, $data) { 00245 return !qtype_calculated_find_formula_errors($answer); 00246 } 00247 00248 protected function valid_answer_message($answer) { 00249 if (!$answer) { 00250 return get_string('mustenteraformulaorstar', 'qtype_numerical'); 00251 } else { 00252 return qtype_calculated_find_formula_errors($answer); 00253 } 00254 } 00255 }