|
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/calculated/questiontype.php'); 00030 00031 00038 class qtype_calculatedsimple extends qtype_calculated { 00039 00040 // Used by the function custom_generator_tools: 00041 public $wizard_pages_number = 1; 00042 00043 public function save_question_options($question) { 00044 global $CFG, $DB; 00045 $context = $question->context; 00046 // Get old answers: 00047 00048 if (isset($question->answer) && !isset($question->answers)) { 00049 $question->answers = $question->answer; 00050 } 00051 00052 // Get old versions of the objects 00053 if (!$oldanswers = $DB->get_records('question_answers', 00054 array('question' => $question->id), 'id ASC')) { 00055 $oldanswers = array(); 00056 } 00057 00058 if (!$oldoptions = $DB->get_records('question_calculated', 00059 array('question' => $question->id), 'answer ASC')) { 00060 $oldoptions = array(); 00061 } 00062 00063 // Save the units. 00064 $virtualqtype = $this->get_virtual_qtype(); 00065 $result = $virtualqtype->save_units($question); 00066 if (isset($result->error)) { 00067 return $result; 00068 } else { 00069 $units = &$result->units; 00070 } 00071 // Insert all the new answers 00072 if (isset($question->answer) && !isset($question->answers)) { 00073 $question->answers = $question->answer; 00074 } 00075 foreach ($question->answers as $key => $answerdata) { 00076 if (is_array($answerdata)) { 00077 $answerdata = $answerdata['text']; 00078 } 00079 if (trim($answerdata) == '') { 00080 continue; 00081 } 00082 00083 // Update an existing answer if possible. 00084 $answer = array_shift($oldanswers); 00085 if (!$answer) { 00086 $answer = new stdClass(); 00087 $answer->question = $question->id; 00088 $answer->answer = ''; 00089 $answer->feedback = ''; 00090 $answer->id = $DB->insert_record('question_answers', $answer); 00091 } 00092 00093 $answer->answer = trim($answerdata); 00094 $answer->fraction = $question->fraction[$key]; 00095 $answer->feedback = $this->import_or_save_files($question->feedback[$key], 00096 $context, 'question', 'answerfeedback', $answer->id); 00097 $answer->feedbackformat = $question->feedback[$key]['format']; 00098 00099 $DB->update_record("question_answers", $answer); 00100 00101 // Set up the options object 00102 if (!$options = array_shift($oldoptions)) { 00103 $options = new stdClass(); 00104 } 00105 $options->question = $question->id; 00106 $options->answer = $answer->id; 00107 $options->tolerance = trim($question->tolerance[$key]); 00108 $options->tolerancetype = trim($question->tolerancetype[$key]); 00109 $options->correctanswerlength = trim($question->correctanswerlength[$key]); 00110 $options->correctanswerformat = trim($question->correctanswerformat[$key]); 00111 00112 // Save options 00113 if (isset($options->id)) { 00114 // reusing existing record 00115 $DB->update_record('question_calculated', $options); 00116 } else { 00117 // new options 00118 $DB->insert_record('question_calculated', $options); 00119 } 00120 } 00121 00122 // delete old answer records 00123 if (!empty($oldanswers)) { 00124 foreach ($oldanswers as $oa) { 00125 $DB->delete_records('question_answers', array('id' => $oa->id)); 00126 } 00127 } 00128 00129 // delete old answer records 00130 if (!empty($oldoptions)) { 00131 foreach ($oldoptions as $oo) { 00132 $DB->delete_records('question_calculated', array('id' => $oo->id)); 00133 } 00134 } 00135 00136 if (isset($question->import_process) && $question->import_process) { 00137 $this->import_datasets($question); 00138 } else { 00139 //save datasets and datatitems from form i.e in question 00140 $question->dataset = $question->datasetdef; 00141 00142 // Save datasets 00143 $datasetdefinitions = $this->get_dataset_definitions($question->id, $question->dataset); 00144 $tmpdatasets = array_flip($question->dataset); 00145 $defids = array_keys($datasetdefinitions); 00146 $datasetdefs = array(); 00147 foreach ($defids as $defid) { 00148 $datasetdef = &$datasetdefinitions[$defid]; 00149 if (isset($datasetdef->id)) { 00150 if (!isset($tmpdatasets[$defid])) { 00151 // This dataset is not used any more, delete it 00152 $DB->delete_records('question_datasets', array('question' => $question->id, 00153 'datasetdefinition' => $datasetdef->id)); 00154 $DB->delete_records('question_dataset_definitions', 00155 array('id' => $datasetdef->id)); 00156 $DB->delete_records('question_dataset_items', 00157 array('definition' => $datasetdef->id)); 00158 } 00159 // This has already been saved or just got deleted 00160 unset($datasetdefinitions[$defid]); 00161 continue; 00162 } 00163 $datasetdef->id = $DB->insert_record('question_dataset_definitions', $datasetdef); 00164 $datasetdefs[] = clone($datasetdef); 00165 $questiondataset = new stdClass(); 00166 $questiondataset->question = $question->id; 00167 $questiondataset->datasetdefinition = $datasetdef->id; 00168 $DB->insert_record('question_datasets', $questiondataset); 00169 unset($datasetdefinitions[$defid]); 00170 } 00171 // Remove local obsolete datasets as well as relations 00172 // to datasets in other categories: 00173 if (!empty($datasetdefinitions)) { 00174 foreach ($datasetdefinitions as $def) { 00175 $DB->delete_records('question_datasets', array('question' => $question->id, 00176 'datasetdefinition' => $def->id)); 00177 if ($def->category == 0) { // Question local dataset 00178 $DB->delete_records('question_dataset_definitions', 00179 array('id' => $def->id)); 00180 $DB->delete_records('question_dataset_items', 00181 array('definition' => $def->id)); 00182 } 00183 } 00184 } 00185 $datasetdefs = $this->get_dataset_definitions($question->id, $question->dataset); 00186 // Handle adding and removing of dataset items 00187 $i = 1; 00188 ksort($question->definition); 00189 foreach ($question->definition as $key => $defid) { 00190 $addeditem = new stdClass(); 00191 $addeditem->definition = $datasetdefs[$defid]->id; 00192 $addeditem->value = $question->number[$i]; 00193 $addeditem->itemnumber = ceil($i / count($datasetdefs)); 00194 if (empty($question->makecopy) && $question->itemid[$i]) { 00195 // Reuse any previously used record 00196 $addeditem->id = $question->itemid[$i]; 00197 $DB->update_record('question_dataset_items', $addeditem); 00198 } else { 00199 $DB->insert_record('question_dataset_items', $addeditem); 00200 } 00201 $i++; 00202 } 00203 $maxnumber = -1; 00204 if (isset($addeditem->itemnumber) && $maxnumber < $addeditem->itemnumber) { 00205 $maxnumber = $addeditem->itemnumber; 00206 foreach ($datasetdefs as $key => $newdef) { 00207 if (isset($newdef->id) && $newdef->itemcount <= $maxnumber) { 00208 $newdef->itemcount = $maxnumber; 00209 // Save the new value for options 00210 $DB->update_record('question_dataset_definitions', $newdef); 00211 } 00212 } 00213 } 00214 } 00215 00216 $this->save_hints($question); 00217 00218 // Report any problems. 00219 if (!empty($question->makecopy) && !empty($question->convert)) { 00220 $DB->set_field('question', 'qtype', 'calculated', array('id' => $question->id)); 00221 } 00222 00223 $result = $virtualqtype->save_unit_options($question); 00224 if (isset($result->error)) { 00225 return $result; 00226 } 00227 00228 if (!empty($result->notice)) { 00229 return $result; 00230 } 00231 00232 return true; 00233 } 00234 00235 public function finished_edit_wizard($form) { 00236 return true; 00237 } 00238 00239 public function wizard_pages_number() { 00240 return 1; 00241 } 00242 00243 public function custom_generator_tools_part($mform, $idx, $j) { 00244 00245 $minmaxgrp = array(); 00246 $minmaxgrp[] = $mform->createElement('text', "calcmin[$idx]", 00247 get_string('calcmin', 'qtype_calculated')); 00248 $minmaxgrp[] = $mform->createElement('text', "calcmax[$idx]", 00249 get_string('calcmax', 'qtype_calculated')); 00250 $mform->addGroup($minmaxgrp, 'minmaxgrp', 00251 get_string('minmax', 'qtype_calculated'), ' - ', false); 00252 $mform->setType("calcmin[$idx]", PARAM_NUMBER); 00253 $mform->setType("calcmax[$idx]", PARAM_NUMBER); 00254 00255 $precisionoptions = range(0, 10); 00256 $mform->addElement('select', "calclength[$idx]", 00257 get_string('calclength', 'qtype_calculated'), $precisionoptions); 00258 00259 $distriboptions = array('uniform' => get_string('uniform', 'qtype_calculated'), 00260 'loguniform' => get_string('loguniform', 'qtype_calculated')); 00261 $mform->addElement('hidden', "calcdistribution[$idx]", 'uniform'); 00262 $mform->setType("calcdistribution[$idx]", PARAM_INT); 00263 } 00264 00265 public function comment_header($answers) { 00266 $strheader = ""; 00267 $delimiter = ''; 00268 00269 foreach ($answers as $key => $answer) { 00270 $strheader .= $delimiter.$answer->answer; 00271 $delimiter = '<br/><br/><br/>'; 00272 } 00273 return $strheader; 00274 } 00275 00276 public function tolerance_types() { 00277 return array( 00278 '1' => get_string('relative', 'qtype_numerical'), 00279 '2' => get_string('nominal', 'qtype_numerical'), 00280 ); 00281 } 00282 00283 public function dataset_options($form, $name, $mandatory = true, $renameabledatasets = false) { 00284 // Takes datasets from the parent implementation but 00285 // filters options that are currently not accepted by calculated 00286 // It also determines a default selection... 00287 //$renameabledatasets not implemented anmywhere 00288 list($options, $selected) = $this->dataset_options_from_database( 00289 $form, $name, '', 'qtype_calculated'); 00290 00291 foreach ($options as $key => $whatever) { 00292 if (!preg_match('~^1-~', $key) && $key != '0') { 00293 unset($options[$key]); 00294 } 00295 } 00296 if (!$selected) { 00297 if ($mandatory) { 00298 $selected = "1-0-$name"; // Default 00299 } else { 00300 $selected = "0"; // Default 00301 } 00302 } 00303 return array($options, $selected); 00304 } 00305 }