MDL-19519 , MDL-1728 Adding database question_calculated_options
[moodle.git] / question / type / calculated / datasetitems_form.php
CommitLineData
8fc3e643 1<?php
2class question_dataset_dependent_items_form extends moodleform {
3 /**
4 * Question object with options and answers already loaded by get_question_options
5 * Be careful how you use this it is needed sometimes to set up the structure of the
6 * form in definition_inner but data is always loaded into the form with set_defaults.
7 *
8 * @var object
9 */
f34488b2 10 public $question;
8fc3e643 11 /**
12 * Reference to question type object
13 *
14 * @var question_dataset_dependent_questiontype
15 */
f34488b2 16 public $qtypeobj;
60b5ecd3 17
f34488b2 18 public $datasetdefs;
60b5ecd3 19
f34488b2 20 public $maxnumber = -1;
60b5ecd3 21
f34488b2 22 public $regenerate;
60b5ecd3 23
f34488b2 24 public $noofitems;
450f1127 25
26 public $outsidelimit = false ;
27
28 public $commentanswers = array();
8fc3e643 29 /**
30 * Add question-type specific form fields.
31 *
32 * @param MoodleQuickForm $mform the form being built.
33 */
60b5ecd3 34 function question_dataset_dependent_items_form($submiturl, $question, $regenerate){
f34488b2 35 global $QTYPES, $SESSION, $CFG, $DB;
60b5ecd3 36 $this->regenerate = $regenerate;
8fc3e643 37 $this->question = $question;
38 $this->qtypeobj =& $QTYPES[$this->question->qtype];
315efce7 39 // Validate the question category.
40 if (!$category = $DB->get_record('question_categories', array('id' => $question->category))) {
41 print_error('categorydoesnotexist', 'question', $returnurl);
42 }
43 $this->category = $category;
44 $this->categorycontext = get_context_instance_by_id($category->contextid);
60b5ecd3 45 //get the dataset defintions for this question
46 if (empty($question->id)) {
fbe2cfea 47 $this->datasetdefs = $this->qtypeobj->get_dataset_definitions($question->id, $SESSION->calculated->definitionform->dataset);
60b5ecd3 48 } else {
49 if (empty($question->options)) {
50 $this->get_question_options($question);
51 }
52 $this->datasetdefs = $this->qtypeobj->get_dataset_definitions($question->id, array());
53 }
54
55 foreach ($this->datasetdefs as $datasetdef) {
56
57 // Get maxnumber
58 if ($this->maxnumber == -1 || $datasetdef->itemcount < $this->maxnumber) {
59 $this->maxnumber = $datasetdef->itemcount;
60 }
61 }
62 foreach ($this->datasetdefs as $defid => $datasetdef) {
63 if (isset($datasetdef->id)) {
66d0a55c 64 $this->datasetdefs[$defid]->items = $this->qtypeobj->get_database_dataset_items($datasetdef->id);
60b5ecd3 65 }
66 }
8fc3e643 67 parent::moodleform($submiturl);
68 }
69 function definition() {
70 $mform =& $this->_form;
60b5ecd3 71 $strquestionlabel = $this->qtypeobj->comment_header($this->question);
60b5ecd3 72 if ($this->maxnumber != -1){
73 $this->noofitems = $this->maxnumber;
74 } else {
75 $this->noofitems = 0;
8fc3e643 76 }
60b5ecd3 77//------------------------------------------------------------------------------------------------------------------------------
38a2212c 78 $mform->addElement('submit', 'updatedatasets', get_string('updatedatasetparam', 'qtype_datasetdependent'));
5d0b1e40 79 $mform->registerNoSubmitButton('updatedatasets');
60b5ecd3 80 $mform->addElement('header', 'additemhdr', get_string('itemtoadd', 'qtype_datasetdependent'));
81 $idx = 1;
a8d2a373 82 $j = (($this->noofitems) * count($this->datasetdefs))+1;
60b5ecd3 83 foreach ($this->datasetdefs as $defkey => $datasetdef){
84 $mform->addElement('text', "number[$j]", get_string('param', 'qtype_datasetdependent', $datasetdef->name));
87cd4f54 85 $mform->setType("number[$j]", PARAM_NUMBER);
f34488b2 86 $this->qtypeobj->custom_generator_tools_part($mform, $idx, $j);
60b5ecd3 87 $idx++;
a8d2a373 88 $mform->addElement('hidden', "definition[$j]");
89 $mform->addElement('hidden', "itemid[$j]");
60b5ecd3 90 $mform->addElement('static', "divider[$j]", '', '<hr />');
a8d2a373 91 $j++;
60b5ecd3 92 }
450f1127 93 $mform->addElement('header', 'updateanswershdr', get_string('answerstoleranceparam', 'qtype_datasetdependent'));
94 $mform->addElement('submit', 'updateanswers', get_string('updatetolerancesparam', 'qtype_datasetdependent'));
95 $mform->setAdvanced('updateanswers',true);
5d0b1e40 96 $mform->registerNoSubmitButton('updateanswers');
97
450f1127 98 $answers = fullclone($this->question->options->answers);
99 $key1 =1;
100 foreach ($answers as $key => $answer) {
101 if ('' === $answer->answer){
102 }else if ('*' === $answer->answer){
103 $mform->addElement('static', 'answercomment['.($this->noofitems+$key1).']', $answer->answer);
104 $mform->addElement('hidden', 'tolerance['.$key.']', '');
105 $mform->setAdvanced('tolerance['.$key.']',true);
106 $mform->addElement('hidden', 'tolerancetype['.$key.']', '');
107 $mform->setAdvanced('tolerancetype['.$key.']',true);
108 $mform->addElement('hidden', 'correctanswerlength['.$key.']', '');
109 $mform->setAdvanced('correctanswerlength['.$key.']',true);
110 $mform->addElement('hidden', 'correctanswerformat['.$key.']', '');
111 $mform->setAdvanced('correctanswerformat['.$key.']',true);
112 }else {
113 $mform->addElement('static', 'answercomment['.($this->noofitems+$key1).']', $answer->answer);
114 $mform->addElement('text', 'tolerance['.$key.']', get_string('tolerance', 'qtype_calculated'));
115 $mform->setAdvanced('tolerance['.$key.']',true);
116 $mform->addElement('select', 'tolerancetype['.$key.']', get_string('tolerancetype', 'quiz'), $this->qtypeobj->tolerance_types());
117 $mform->setAdvanced('tolerancetype['.$key.']',true);
118
119 $mform->addElement('select', 'correctanswerlength['.$key.']', get_string('correctanswershows', 'qtype_calculated'), range(0, 9));
120 $mform->setAdvanced('correctanswerlength['.$key.']',true);
121
122 $answerlengthformats = array('1' => get_string('decimalformat', 'quiz'), '2' => get_string('significantfiguresformat', 'quiz'));
123 $mform->addElement('select', 'correctanswerformat['.$key.']', get_string('correctanswershowsformat', 'qtype_calculated'), $answerlengthformats);
124 $mform->setAdvanced('correctanswerformat['.$key.']',true);
125 $mform->addElement('static', 'dividertolerance', '', '<hr />');
126 $mform->setAdvanced('dividertolerance',true);
127 }
128 $key1++;
129 }
60b5ecd3 130
451373ed 131 $addremoveoptions = Array();
132 $addremoveoptions['1']='1';
79bb7202 133 for ($i=10; $i<=100 ; $i+=10){
451373ed 134 $addremoveoptions["$i"]="$i";
135 }
87cd4f54 136 $mform->addElement('header', 'additemhdr', get_string('add', 'moodle'));
451373ed 137 $mform->closeHeaderBefore('additemhdr');
60b5ecd3 138
8fc3e643 139 if ($this->qtypeobj->supports_dataset_item_generation()){
140 $radiogrp = array();
60b5ecd3 141 $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('reuseifpossible', 'qtype_datasetdependent'), 0);
142 $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('forceregeneration', 'qtype_datasetdependent'), 1);
451373ed 143 $mform->addGroup($radiogrp, 'forceregenerationgrp', get_string('nextitemtoadd', 'qtype_calculated'), "<br/>", false);
8fc3e643 144 }
145
60b5ecd3 146 $mform->addElement('submit', 'getnextbutton', get_string('getnextnow', 'qtype_datasetdependent'));
451373ed 147 $mform->addElement('static', "dividera", '', '<hr />');
148 $addgrp = array();
149 $addgrp[] =& $mform->createElement('submit', 'addbutton', get_string('add', 'moodle'));
150 $addgrp[] =& $mform->createElement('select', "selectadd", get_string('additem', 'qtype_datasetdependent'), $addremoveoptions);
151 $addgrp[] = & $mform->createElement('static',"stat","Items",get_string('item(s)', 'qtype_datasetdependent'));
152 $mform->addGroup($addgrp, 'addgrp', '', ' ', false);
450f1127 153 $mform->addElement('static', "divideradd", '', '');
451373ed 154 // $mform->closeHeaderBefore('divideradd');
155 if ($this->noofitems > 0) {
156 $mform->addElement('header', 'additemhdr', get_string('delete', 'moodle'));
157 $deletegrp = array();
158 $deletegrp[] =& $mform->createElement('submit', 'deletebutton', get_string('delete', 'moodle'));
159 $deletegrp[] =& $mform->createElement('select', "selectdelete", get_string('deleteitem', 'qtype_datasetdependent')."1", $addremoveoptions);
160 $deletegrp[] = & $mform->createElement('static',"stat","Items",get_string('lastitem(s)', 'qtype_datasetdependent'));
161 $mform->addGroup($deletegrp, 'deletegrp', '', ' ', false);
162 // $mform->addElement('static', "dividerdelete", '', '<hr />');
163 // $mform->closeHeaderBefore('dividerdelete');
164 } else {
165 $mform->addElement('static','warning','','<span class="error">'.get_string('youmustaddatleastoneitem', 'qtype_datasetdependent').'</span>');
166 }
8fc3e643 167
a8d2a373 168//------------------------------------------------------------------------------------------------------------------------------
169 $j = $this->noofitems * count($this->datasetdefs);
170 for ($i = $this->noofitems; $i >= 1 ; $i--){
171 $mform->addElement('header', '', get_string('itemno', 'qtype_datasetdependent', $i));
172 foreach ($this->datasetdefs as $defkey => $datasetdef){
173 $mform->addElement('text', "number[$j]", get_string('param', 'qtype_datasetdependent', $datasetdef->name));
87cd4f54 174 $mform->setType("number[$j]", PARAM_NUMBER);
a8d2a373 175 $mform->addElement('hidden', "itemid[$j]");
87cd4f54 176 $mform->setType("itemid[$j]", PARAM_INT);
a8d2a373 177
178 $mform->addElement('hidden', "definition[$j]");
87cd4f54 179 $mform->setType("definition[$j]", PARAM_NOTAGS);
a8d2a373 180
181 $j--;
182 }
183 if ('' != $strquestionlabel){
184 $repeated[] =& $mform->addElement('static', "answercomment[$i]", $strquestionlabel);
185 }
a8d2a373 186 }
450f1127 187 // if ($this->outsidelimit){
188 $mform->addElement('static','outsidelimit','','');
189 // }
a8d2a373 190//------------------------------------------------------------------------------------------------------------------------------
60b5ecd3 191 //non standard name for button element needed so not using add_action_buttons
450f1127 192 if ( !($this->noofitems==0) ){
a8d2a373 193 $mform->addElement('submit', 'backtoquiz', get_string('savechanges'));
194 $mform->closeHeaderBefore('backtoquiz');
450f1127 195 }
60b5ecd3 196 //hidden elements
79bb7202 197 $mform->addElement('hidden', 'id');
198 $mform->setType('id', PARAM_INT);
199
271e6dec 200 $mform->addElement('hidden', 'courseid');
201 $mform->setType('courseid', PARAM_INT);
202 $mform->setDefault('courseid', 0);
79bb7202 203
315efce7 204 $mform->addElement('hidden', 'category');
205 $mform->setType('category', PARAM_RAW);
206 $mform->setDefault('category', array('contexts' => array($this->categorycontext)));
207
271e6dec 208 $mform->addElement('hidden', 'cmid');
209 $mform->setType('cmid', PARAM_INT);
210 $mform->setDefault('cmid', 0);
79bb7202 211
60b5ecd3 212 $mform->addElement('hidden', 'wizard', 'datasetitems');
213 $mform->setType('wizard', PARAM_ALPHA);
f34488b2 214
2dc8beaf 215 $mform->addElement('hidden', 'returnurl');
216 $mform->setType('returnurl', PARAM_LOCALURL);
217 $mform->setDefault('returnurl', 0);
60b5ecd3 218 }
8fc3e643 219
60b5ecd3 220 function set_data($question){
221 $formdata = array();
5d0b1e40 222 $fromform = new stdClass();
450f1127 223 if (isset($question->options)){
224 $answers = $question->options->answers;
225 if (count($answers)) {
5d0b1e40 226 if ( optional_param('updateanswers', '', PARAM_RAW) != '' || optional_param('updatedatasets', '', PARAM_RAW) != ''){
227 foreach ($answers as $key => $answer){
228 $fromform->tolerance[$key]= $this->_form->getElementValue('tolerance['.$key.']');
229 $answer->tolerance = $fromform->tolerance[$key];
230 $fromform->tolerancetype[$key]= $this->_form->getElementValue('tolerancetype['.$key.']');
231 if( is_array($fromform->tolerancetype[$key])) $fromform->tolerancetype[$key]= $fromform->tolerancetype[$key][0];
232 $answer->tolerancetype = $fromform->tolerancetype[$key];
233 $fromform->correctanswerlength[$key]= $this->_form->getElementValue('correctanswerlength['.$key.']');
234 if( is_array($fromform->correctanswerlength[$key])) $fromform->correctanswerlength[$key]= $fromform->correctanswerlength[$key][0];
235 $answer->correctanswerlength = $fromform->correctanswerlength[$key];
236 $fromform->correctanswerformat[$key]= $this->_form->getElementValue('correctanswerformat['.$key.']');
237 if( is_array($fromform->correctanswerformat[$key])) $fromform->correctanswerformat[$key]= $fromform->correctanswerformat[$key][0];
238 $answer->correctanswerformat = $fromform->correctanswerformat[$key];
239 }
240 $this->qtypeobj->save_question_calculated($question,$fromform);
241 }else {
450f1127 242 foreach ($answers as $key => $answer){
450f1127 243
244 $formdata['tolerance['.$key.']'] = $answer->tolerance;
245 $formdata['tolerancetype['.$key.']'] = $answer->tolerancetype;
246 $formdata['correctanswerlength['.$key.']'] = $answer->correctanswerlength;
247 $formdata['correctanswerformat['.$key.']'] = $answer->correctanswerformat;
5d0b1e40 248 }
450f1127 249 }
5d0b1e40 250 }
251 }
60b5ecd3 252 //fill out all data sets and also the fields for the next item to add.
a8d2a373 253 $j = $this->noofitems * count($this->datasetdefs);
5d0b1e40 254 for ($itemnumber = $this->noofitems; $itemnumber >= 1; $itemnumber--){
60b5ecd3 255 $data = array();
256 foreach ($this->datasetdefs as $defid => $datasetdef){
257 if (isset($datasetdef->items[$itemnumber])){
258 $formdata["number[$j]"] = $datasetdef->items[$itemnumber]->value;
259 $formdata["definition[$j]"] = $defid;
260 $formdata["itemid[$j]"] = $datasetdef->items[$itemnumber]->id;
261 $data[$datasetdef->name] = $datasetdef->items[$itemnumber]->value;
262 }
a8d2a373 263 $j--;
60b5ecd3 264 }
5d0b1e40 265 $comment = $this->qtypeobj->comment_on_datasetitems($question->id,$answers, $data, $itemnumber);
266 if ($comment->outsidelimit) {
450f1127 267 $this->outsidelimit=$comment->outsidelimit ;
450f1127 268 }
269 $totalcomment='';
270 foreach ($question->options->answers as $key => $answer) {
271 $totalcomment .= $comment->stranswers[$key].'<br/>';
272 }
273
274 $formdata['answercomment['.$itemnumber.']'] = $totalcomment ;
60b5ecd3 275 }
8fc3e643 276
60b5ecd3 277 $formdata['nextpageparam[forceregeneration]'] = $this->regenerate;
451373ed 278 $formdata['selectdelete'] = '1';
279 $formdata['selectadd'] = '1';
a8d2a373 280 $j = $this->noofitems * count($this->datasetdefs)+1;
60b5ecd3 281 $data = array(); // data for comment_on_datasetitems later
282 //dataset generation dafaults
283 if ($this->qtypeobj->supports_dataset_item_generation()) {
284 $itemnumber = $this->noofitems+1;
285 foreach ($this->datasetdefs as $defid => $datasetdef){
5d0b1e40 286 if( optional_param('updatedatasets', '', PARAM_RAW) == '' && optional_param('updateanswers', '', PARAM_RAW)== ''){
60b5ecd3 287 $formdata["number[$j]"] = $this->qtypeobj->generate_dataset_item($datasetdef->options);
5d0b1e40 288 }else {
289 $formdata["number[$j]"] = $this->_form->getElementValue("number[$j]") ;
290 }
60b5ecd3 291 $formdata["definition[$j]"] = $defid;
292 $formdata["itemid[$j]"] =
293 isset($datasetdef->items[$itemnumber])?$datasetdef->items[$itemnumber]->id:0;
294 $data[$datasetdef->name] = $formdata["number[$j]"];
295 $j++;
296 }
8fc3e643 297 }
60b5ecd3 298
299 //existing records override generated data depending on radio element
a8d2a373 300 $j = $this->noofitems * count($this->datasetdefs)+1;
5d0b1e40 301 if (!$this->regenerate && (optional_param('updatedatasets', '', PARAM_RAW) == '' && optional_param('updateanswers', '', PARAM_RAW)== '')){
60b5ecd3 302 $idx = 1;
303 $itemnumber = $this->noofitems+1;
304 foreach ($this->datasetdefs as $defid => $datasetdef){
305 if (isset($datasetdef->items[$itemnumber])){
306 $formdata["number[$j]"] = $datasetdef->items[$itemnumber]->value;
307 $formdata["definition[$j]"] = $defid;
308 $formdata["itemid[$j]"] = $datasetdef->items[$itemnumber]->id;
309 $data[$datasetdef->name] = $datasetdef->items[$itemnumber]->value;
310 }
311 $j++;
312 }
313
314 }
315 //default answercomment will get ignored if answer element is not in the form.
5d0b1e40 316 $comment = $this->qtypeobj->comment_on_datasetitems($question->id,$answers, $data, ($this->noofitems+1));
450f1127 317 if ($comment->outsidelimit) {
318 $this->outsidelimit=$comment->outsidelimit ;
450f1127 319 }
320 $key1 = 1;
321 foreach ($question->options->answers as $key => $answer) {
322 $formdata['answercomment['.($this->noofitems+$key1).']'] = $comment->stranswers[$key];
323 $key1++;
324 }
60b5ecd3 325
450f1127 326 if ($this->outsidelimit){
327 $formdata['outsidelimit']= '<span class="error">'.get_string('oneanswertrueansweroutsidelimits', 'qtype_datasetdependent').'</span>';
328 }
60b5ecd3 329 $formdata = $this->qtypeobj->custom_generator_set_data($this->datasetdefs, $formdata);
330
331 parent::set_data((object)($formdata + (array)$question));
8fc3e643 332 }
333
a78890d5 334 function validation($data, $files) {
60b5ecd3 335 $errors = array();
450f1127 336 if (isset($data['backtoquiz']) && ($this->noofitems==0) ){
451373ed 337 $errors['warning'] = get_string('warning', 'mnet');
450f1127 338 }
339 if ($this->outsidelimit){
340 // if(!isset($errors['warning'])) $errors['warning']=' ';
5d0b1e40 341 $errors['outsidelimits'] = get_string('oneanswertrueansweroutsidelimits','qtype_calculated');
60b5ecd3 342 }
343 return $errors;
344 }
345
346
8fc3e643 347}
f34488b2 348?>