Merge branch 'MDL-70106-icon-cache-310' of https://github.com/Peterburnett/moodle...
[moodle.git] / question / type / calculated / datasetitems_form.php
CommitLineData
8fc3e643 1<?php
d3603157
TH
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Defines the editing form for the calculated question data set items.
19 *
20 * @package qtype
21 * @subpackage calculated
22 * @copyright 2007 Jamie Pratt me@jamiep.org
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26
a17b297d
TH
27defined('MOODLE_INTERNAL') || die();
28
72553162
TH
29require_once($CFG->dirroot . '/question/type/edit_question_form.php');
30
a17b297d 31
d3603157
TH
32/**
33 * Calculated question data set items editing form definition.
34 *
35 * @copyright 2007 Jamie Pratt me@jamiep.org
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 */
72553162 38class question_dataset_dependent_items_form extends question_wizard_form {
8fc3e643 39 /**
40 * Question object with options and answers already loaded by get_question_options
41 * Be careful how you use this it is needed sometimes to set up the structure of the
42 * form in definition_inner but data is always loaded into the form with set_defaults.
43 *
44 * @var object
45 */
f34488b2 46 public $question;
8fc3e643 47 /**
48 * Reference to question type object
49 *
50 * @var question_dataset_dependent_questiontype
51 */
f34488b2 52 public $qtypeobj;
60b5ecd3 53
8011be18
TH
54 /** @var stdClass the question category. */
55 protected $category;
56
57 /** @var context the context of the question category. */
58 protected $categorycontext;
59
f34488b2 60 public $datasetdefs;
60b5ecd3 61
f34488b2 62 public $maxnumber = -1;
60b5ecd3 63
f34488b2 64 public $regenerate;
60b5ecd3 65
f34488b2 66 public $noofitems;
aeb15530 67
f184c65c 68 public $outsidelimit = false;
aeb15530 69
450f1127 70 public $commentanswers = array();
f184c65c 71
8fc3e643 72 /**
73 * Add question-type specific form fields.
74 *
75 * @param MoodleQuickForm $mform the form being built.
76 */
f184c65c
TH
77 public function __construct($submiturl, $question, $regenerate) {
78 global $SESSION, $CFG, $DB;
60b5ecd3 79 $this->regenerate = $regenerate;
8fc3e643 80 $this->question = $question;
18f9b2d2 81 $this->qtypeobj = question_bank::get_qtype($this->question->qtype);
4454447d 82 // Validate the question category.
f184c65c
TH
83 if (!$category = $DB->get_record('question_categories',
84 array('id' => $question->category))) {
4454447d
PS
85 print_error('categorydoesnotexist', 'question', $returnurl);
86 }
315efce7 87 $this->category = $category;
d197ea43 88 $this->categorycontext = context::instance_by_id($category->contextid);
3d9645ae 89 // Get the dataset defintions for this question.
60b5ecd3 90 if (empty($question->id)) {
f184c65c
TH
91 $this->datasetdefs = $this->qtypeobj->get_dataset_definitions(
92 $question->id, $SESSION->calculated->definitionform->dataset);
60b5ecd3 93 } else {
94 if (empty($question->options)) {
95 $this->get_question_options($question);
96 }
f184c65c
TH
97 $this->datasetdefs = $this->qtypeobj->get_dataset_definitions(
98 $question->id, array());
60b5ecd3 99 }
100
101 foreach ($this->datasetdefs as $datasetdef) {
3d9645ae 102 // Get maxnumber.
60b5ecd3 103 if ($this->maxnumber == -1 || $datasetdef->itemcount < $this->maxnumber) {
104 $this->maxnumber = $datasetdef->itemcount;
105 }
106 }
107 foreach ($this->datasetdefs as $defid => $datasetdef) {
108 if (isset($datasetdef->id)) {
f184c65c
TH
109 $this->datasetdefs[$defid]->items =
110 $this->qtypeobj->get_database_dataset_items($datasetdef->id);
60b5ecd3 111 }
112 }
f184c65c 113 parent::__construct($submiturl);
8fc3e643 114 }
f184c65c 115
c7df5006 116 protected function definition() {
8011be18
TH
117 global $PAGE;
118
3d9645ae 119 $labelsharedwildcard = get_string("sharedwildcard", "qtype_calculated");
8011be18 120 $mform = $this->_form;
d6b8e192
TH
121 $mform->setDisableShortforms();
122
60b5ecd3 123 $strquestionlabel = $this->qtypeobj->comment_header($this->question);
f184c65c 124 if ($this->maxnumber != -1 ) {
60b5ecd3 125 $this->noofitems = $this->maxnumber;
126 } else {
127 $this->noofitems = 0;
8fc3e643 128 }
5940864e 129 $label = get_string("sharedwildcards", "qtype_calculated");
f184c65c
TH
130
131 $html2 = $this->qtypeobj->print_dataset_definitions_category_shared(
132 $this->question, $this->datasetdefs);
133 $mform->addElement('static', 'listcategory', $label, $html2);
3d9645ae 134 // ...----------------------------------------------------------------------.
f184c65c
TH
135 $mform->addElement('submit', 'updatedatasets',
136 get_string('updatedatasetparam', 'qtype_calculated'));
5d0b1e40 137 $mform->registerNoSubmitButton('updatedatasets');
f184c65c
TH
138 $mform->addElement('header', 'additemhdr',
139 get_string('itemtoadd', 'qtype_calculated'));
60b5ecd3 140 $idx = 1;
ab8b5142 141 $data = array();
a8d2a373 142 $j = (($this->noofitems) * count($this->datasetdefs))+1;
f184c65c
TH
143 foreach ($this->datasetdefs as $defkey => $datasetdef) {
144 if ($datasetdef->category |= 0 ) {
6ef90fde 145 $name = get_string('sharedwildcard', 'qtype_calculated', $datasetdef->name);
f184c65c 146 } else {
d90b016b 147 $name = get_string('wildcard', 'qtype_calculated', $datasetdef->name);
ab8b5142 148 }
75dc9037 149 $mform->addElement('float', "number[{$j}]", $name);
f34488b2 150 $this->qtypeobj->custom_generator_tools_part($mform, $idx, $j);
60b5ecd3 151 $idx++;
f4fe3968
TH
152 $mform->addElement('hidden', "definition[{$j}]");
153 $mform->setType("definition[{$j}]", PARAM_RAW);
154 $mform->addElement('hidden', "itemid[{$j}]");
155 $mform->setType("itemid[{$j}]", PARAM_RAW);
156 $mform->addElement('static', "divider[{$j}]", '', '<hr />');
157 $mform->setType("divider[{$j}]", PARAM_RAW);
a8d2a373 158 $j++;
60b5ecd3 159 }
f184c65c
TH
160
161 $mform->addElement('header', 'updateanswershdr',
162 get_string('answerstoleranceparam', 'qtype_calculated'));
163 $mform->addElement('submit', 'updateanswers',
164 get_string('updatetolerancesparam', 'qtype_calculated'));
165 $mform->setAdvanced('updateanswers', true);
5d0b1e40 166 $mform->registerNoSubmitButton('updateanswers');
aeb15530 167
450f1127 168 $answers = fullclone($this->question->options->answers);
169 $key1 =1;
170 foreach ($answers as $key => $answer) {
9ddb8a56 171 $ans = shorten_text($answer->answer, 17, true);
172 if ($ans === '*') {
f184c65c 173 $mform->addElement('static',
9ddb8a56 174 'answercomment[' . ($this->noofitems+$key1) . ']', $ans);
450f1127 175 $mform->addElement('hidden', 'tolerance['.$key.']', '');
75dc9037 176 $mform->setType('tolerance['.$key.']', PARAM_FLOAT); // No need to worry about localisation, as the value of this field will not be shown to users anymore.
f184c65c 177 $mform->setAdvanced('tolerance['.$key.']', true);
450f1127 178 $mform->addElement('hidden', 'tolerancetype['.$key.']', '');
d18e0fe6 179 $mform->setType('tolerancetype['.$key.']', PARAM_RAW);
f184c65c 180 $mform->setAdvanced('tolerancetype['.$key.']', true);
450f1127 181 $mform->addElement('hidden', 'correctanswerlength['.$key.']', '');
d18e0fe6 182 $mform->setType('correctanswerlength['.$key.']', PARAM_RAW);
f184c65c 183 $mform->setAdvanced('correctanswerlength['.$key.']', true);
450f1127 184 $mform->addElement('hidden', 'correctanswerformat['.$key.']', '');
d18e0fe6 185 $mform->setType('correctanswerformat['.$key.']', PARAM_RAW);
f184c65c 186 $mform->setAdvanced('correctanswerformat['.$key.']', true);
9ddb8a56 187 } else if ( $ans !== '' ) {
f184c65c 188 $mform->addElement('static', 'answercomment[' . ($this->noofitems+$key1) . ']',
9ddb8a56 189 $ans);
75dc9037 190 $mform->addElement('float', 'tolerance['.$key.']',
f184c65c
TH
191 get_string('tolerance', 'qtype_calculated'));
192 $mform->setAdvanced('tolerance['.$key.']', true);
193 $mform->addElement('select', 'tolerancetype['.$key.']',
194 get_string('tolerancetype', 'qtype_numerical'),
195 $this->qtypeobj->tolerance_types());
196 $mform->setAdvanced('tolerancetype['.$key.']', true);
197
198 $mform->addElement('select', 'correctanswerlength['.$key.']',
199 get_string('correctanswershows', 'qtype_calculated'), range(0, 9));
200 $mform->setAdvanced('correctanswerlength['.$key.']', true);
201
202 $answerlengthformats = array(
203 '1' => get_string('decimalformat', 'qtype_numerical'),
18f9b2d2 204 '2' => get_string('significantfiguresformat', 'qtype_calculated')
f184c65c
TH
205 );
206 $mform->addElement('select', 'correctanswerformat['.$key.']',
207 get_string('correctanswershowsformat', 'qtype_calculated'),
208 $answerlengthformats);
209 $mform->setAdvanced('correctanswerformat['.$key.']', true);
450f1127 210 $mform->addElement('static', 'dividertolerance', '', '<hr />');
f184c65c 211 $mform->setAdvanced('dividertolerance', true);
450f1127 212 }
213 $key1++;
aeb15530 214 }
60b5ecd3 215
28a27ef1 216 $addremoveoptions = array();
451373ed 217 $addremoveoptions['1']='1';
f184c65c 218 for ($i=10; $i<=100; $i+=10) {
f4fe3968 219 $addremoveoptions["{$i}"] = "{$i}";
451373ed 220 }
ab8b5142
PP
221 $showoptions = Array();
222 $showoptions['1']='1';
223 $showoptions['2']='2';
224 $showoptions['5']='5';
f184c65c 225 for ($i=10; $i<=100; $i+=10) {
f4fe3968 226 $showoptions["{$i}"] = "{$i}";
ab8b5142 227 }
864ce820
DW
228 $mform->addElement('header', 'addhdr', get_string('add', 'moodle'));
229 $mform->closeHeaderBefore('addhdr');
60b5ecd3 230
f184c65c 231 if ($this->qtypeobj->supports_dataset_item_generation()) {
8fc3e643 232 $radiogrp = array();
f184c65c
TH
233 $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]',
234 null, get_string('reuseifpossible', 'qtype_calculated'), 0);
235 $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]',
236 null, get_string('forceregenerationshared', 'qtype_calculated'), 1);
237 $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]',
238 null, get_string('forceregenerationall', 'qtype_calculated'), 2);
239 $mform->addGroup($radiogrp, 'forceregenerationgrp',
240 get_string('nextitemtoadd', 'qtype_calculated'), "<br/>", false);
8fc3e643 241 }
242
5940864e 243 $mform->addElement('submit', 'getnextbutton', get_string('getnextnow', 'qtype_calculated'));
451373ed 244 $mform->addElement('static', "dividera", '', '<hr />');
245 $addgrp = array();
246 $addgrp[] =& $mform->createElement('submit', 'addbutton', get_string('add', 'moodle'));
f184c65c
TH
247 $addgrp[] =& $mform->createElement('select', "selectadd",
248 get_string('additem', 'qtype_calculated'), $addremoveoptions);
249 $addgrp[] = & $mform->createElement('static', "stat", "Items",
250 get_string('newsetwildcardvalues', 'qtype_calculatedsimple'));
251 $mform->addGroup($addgrp, 'addgrp', get_string('additem', 'qtype_calculated'), ' ', false);
450f1127 252 $mform->addElement('static', "divideradd", '', '');
451373ed 253 if ($this->noofitems > 0) {
864ce820 254 $mform->addElement('header', 'deleteitemhdr', get_string('delete', 'moodle'));
451373ed 255 $deletegrp = array();
f184c65c
TH
256 $deletegrp[] = $mform->createElement('submit', 'deletebutton',
257 get_string('delete', 'moodle'));
258 $deletegrp[] = $mform->createElement('select', 'selectdelete',
259 get_string('deleteitem', 'qtype_calculated')."1", $addremoveoptions);
260 $deletegrp[] = $mform->createElement('static', "stat", "Items",
261 get_string('setwildcardvalues', 'qtype_calculatedsimple'));
451373ed 262 $mform->addGroup($deletegrp, 'deletegrp', '', ' ', false);
451373ed 263 } else {
f184c65c
TH
264 $mform->addElement('static', 'warning', '', '<span class="error">' .
265 get_string('youmustaddatleastoneitem', 'qtype_calculated').'</span>');
451373ed 266 }
8fc3e643 267
ab8b5142 268 $addgrp1 = array();
f184c65c
TH
269 $addgrp1[] = $mform->createElement('submit', 'showbutton',
270 get_string('showitems', 'qtype_calculated'));
271 $addgrp1[] = $mform->createElement('select', "selectshow", '' , $showoptions);
272 $addgrp1[] = $mform->createElement('static', "stat", '',
273 get_string('setwildcardvalues', 'qtype_calculated'));
ab8b5142
PP
274 $mform->addGroup($addgrp1, 'addgrp1', '', ' ', false);
275 $mform->registerNoSubmitButton('showbutton');
276 $mform->closeHeaderBefore('addgrp1');
3d9645ae 277 // ...----------------------------------------------------------------------.
a8d2a373 278 $j = $this->noofitems * count($this->datasetdefs);
7d087744 279 $k = optional_param('selectshow', 1, PARAM_INT);
f184c65c
TH
280 for ($i = $this->noofitems; $i >= 1; $i--) {
281 if ($k > 0) {
864ce820 282 $mform->addElement('header', 'setnoheader' . $i, "<b>" .
f184c65c
TH
283 get_string('setno', 'qtype_calculated', $i)."</b>&nbsp;&nbsp;");
284 }
285 foreach ($this->datasetdefs as $defkey => $datasetdef) {
286 if ($k > 0) {
287 if ($datasetdef->category == 0 ) {
75dc9037 288 $mform->addElement('float', "number[{$j}]",
f184c65c
TH
289 get_string('wildcard', 'qtype_calculated', $datasetdef->name));
290 } else {
75dc9037 291 $mform->addElement('float', "number[{$j}]", get_string(
6ef90fde 292 'sharedwildcard', 'qtype_calculated', $datasetdef->name));
ab8b5142 293 }
f184c65c
TH
294
295 } else {
f4fe3968 296 $mform->addElement('hidden', "number[{$j}]" , '');
75dc9037 297 $mform->setType("number[{$j}]", PARAM_LOCALISEDFLOAT); // Localisation handling has to be done manually.
f184c65c 298 }
f4fe3968
TH
299 $mform->addElement('hidden', "itemid[{$j}]");
300 $mform->setType("itemid[{$j}]", PARAM_INT);
a8d2a373 301
f4fe3968
TH
302 $mform->addElement('hidden', "definition[{$j}]");
303 $mform->setType("definition[{$j}]", PARAM_NOTAGS);
ab8b5142 304 $data[$datasetdef->name] =$datasetdef->items[$i]->value;
a8d2a373 305
306 $j--;
307 }
f184c65c 308 if ('' != $strquestionlabel && ($k > 0 )) {
3d9645ae 309 // ... $this->outsidelimit || !empty($this->numbererrors ).
f4fe3968 310 $repeated[] = $mform->addElement('static', "answercomment[{$i}]", $strquestionlabel);
3d9645ae 311 // Decode equations in question text.
f184c65c
TH
312 $qtext = $this->qtypeobj->substitute_variables(
313 $this->question->questiontext, $data);
75aa674b 314 $textequations = $this->qtypeobj->find_formulas($qtext);
f184c65c 315 if ($textequations != '' && count($textequations) > 0 ) {
f4fe3968 316 $mform->addElement('static', "divider1[{$j}]", '',
f184c65c
TH
317 'Formulas {=..} in question text');
318 foreach ($textequations as $key => $equation) {
319 if ($formulaerrors = qtype_calculated_find_formula_errors($equation)) {
9ddb8a56 320 $str = $formulaerrors;
f184c65c
TH
321 } else {
322 eval('$str = '.$equation.';');
ab8b5142 323 }
9ddb8a56 324 $equation = shorten_text($equation, 17, true);
f4fe3968 325 $mform->addElement('static', "textequation", "{={$equation}}", "=".$str);
f184c65c
TH
326 }
327 }
328
329 }
330 $k--;
ab8b5142 331
a8d2a373 332 }
f184c65c 333 $mform->addElement('static', 'outsidelimit', '', '');
8011be18
TH
334
335 // Submit buttons.
336 if ($this->noofitems > 0) {
337 $buttonarray = array();
338 $buttonarray[] = $mform->createElement(
339 'submit', 'savechanges', get_string('savechanges'));
340
341 $previewlink = $PAGE->get_renderer('core_question')->question_preview_link(
342 $this->question->id, $this->categorycontext, true);
343 $buttonarray[] = $mform->createElement('static', 'previewlink', '', $previewlink);
344
345 $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
346 $mform->closeHeaderBefore('buttonar');
450f1127 347 }
79bb7202 348
72553162 349 $this->add_hidden_fields();
79bb7202 350
315efce7 351 $mform->addElement('hidden', 'category');
72553162 352 $mform->setType('category', PARAM_SEQUENCE);
79bb7202 353
60b5ecd3 354 $mform->addElement('hidden', 'wizard', 'datasetitems');
355 $mform->setType('wizard', PARAM_ALPHA);
356 }
8fc3e643 357
f184c65c 358 public function set_data($question) {
60b5ecd3 359 $formdata = array();
5d0b1e40 360 $fromform = new stdClass();
f184c65c 361 if (isset($question->options)) {
450f1127 362 $answers = $question->options->answers;
363 if (count($answers)) {
7d087744
TH
364 if (optional_param('updateanswers', false, PARAM_BOOL) ||
365 optional_param('updatedatasets', false, PARAM_BOOL)) {
f184c65c
TH
366 foreach ($answers as $key => $answer) {
367 $fromform->tolerance[$key]= $this->_form->getElementValue(
368 'tolerance['.$key.']');
5d0b1e40 369 $answer->tolerance = $fromform->tolerance[$key];
f184c65c
TH
370 $fromform->tolerancetype[$key]= $this->_form->getElementValue(
371 'tolerancetype['.$key.']');
372 if (is_array($fromform->tolerancetype[$key])) {
373 $fromform->tolerancetype[$key]= $fromform->tolerancetype[$key][0];
374 }
5d0b1e40 375 $answer->tolerancetype = $fromform->tolerancetype[$key];
f184c65c
TH
376 $fromform->correctanswerlength[$key]= $this->_form->getElementValue(
377 'correctanswerlength['.$key.']');
378 if (is_array($fromform->correctanswerlength[$key])) {
379 $fromform->correctanswerlength[$key] =
380 $fromform->correctanswerlength[$key][0];
381 }
5d0b1e40 382 $answer->correctanswerlength = $fromform->correctanswerlength[$key];
f184c65c
TH
383 $fromform->correctanswerformat[$key] = $this->_form->getElementValue(
384 'correctanswerformat['.$key.']');
385 if (is_array($fromform->correctanswerformat[$key])) {
386 $fromform->correctanswerformat[$key] =
387 $fromform->correctanswerformat[$key][0];
388 }
5d0b1e40 389 $answer->correctanswerformat = $fromform->correctanswerformat[$key];
390 }
f184c65c
TH
391 $this->qtypeobj->save_question_calculated($question, $fromform);
392
393 } else {
394 foreach ($answers as $key => $answer) {
395 $formdata['tolerance['.$key.']'] = $answer->tolerance;
396 $formdata['tolerancetype['.$key.']'] = $answer->tolerancetype;
397 $formdata['correctanswerlength['.$key.']'] = $answer->correctanswerlength;
398 $formdata['correctanswerformat['.$key.']'] = $answer->correctanswerformat;
399 }
400 }
450f1127 401 }
5d0b1e40 402 }
3d9645ae 403 // Fill out all data sets and also the fields for the next item to add.
a8d2a373 404 $j = $this->noofitems * count($this->datasetdefs);
f184c65c 405 for ($itemnumber = $this->noofitems; $itemnumber >= 1; $itemnumber--) {
60b5ecd3 406 $data = array();
f184c65c
TH
407 foreach ($this->datasetdefs as $defid => $datasetdef) {
408 if (isset($datasetdef->items[$itemnumber])) {
75dc9037
SR
409 $value = $datasetdef->items[$itemnumber]->value;
410 if ($this->_form->getElementType("number[{$j}]") == 'hidden') {
411 // Some of the number elements are from the float type and some are from the hidden type.
412 // We need to manually handle localised floats for hidden elements.
a1f10c5e 413 $value = format_float($value, -1);
75dc9037
SR
414 }
415 $formdata["number[{$j}]"] = $value;
f4fe3968
TH
416 $formdata["definition[{$j}]"] = $defid;
417 $formdata["itemid[{$j}]"] = $datasetdef->items[$itemnumber]->id;
60b5ecd3 418 $data[$datasetdef->name] = $datasetdef->items[$itemnumber]->value;
419 }
a8d2a373 420 $j--;
60b5ecd3 421 }
f184c65c
TH
422 $comment = $this->qtypeobj->comment_on_datasetitems($this->qtypeobj, $question->id,
423 $question->questiontext, $answers, $data, $itemnumber);
424 if ($comment->outsidelimit) {
425 $this->outsidelimit=$comment->outsidelimit;
450f1127 426 }
427 $totalcomment='';
428 foreach ($question->options->answers as $key => $answer) {
429 $totalcomment .= $comment->stranswers[$key].'<br/>';
430 }
f184c65c 431 $formdata['answercomment['.$itemnumber.']'] = $totalcomment;
60b5ecd3 432 }
8fc3e643 433
60b5ecd3 434 $formdata['nextpageparam[forceregeneration]'] = $this->regenerate;
451373ed 435 $formdata['selectdelete'] = '1';
436 $formdata['selectadd'] = '1';
a8d2a373 437 $j = $this->noofitems * count($this->datasetdefs)+1;
3d9645ae 438 $data = array(); // Data for comment_on_datasetitems later.
439 // Dataset generation defaults.
60b5ecd3 440 if ($this->qtypeobj->supports_dataset_item_generation()) {
441 $itemnumber = $this->noofitems+1;
f184c65c 442 foreach ($this->datasetdefs as $defid => $datasetdef) {
7d087744
TH
443 if (!optional_param('updatedatasets', false, PARAM_BOOL) &&
444 !optional_param('updateanswers', false, PARAM_BOOL)) {
75dc9037 445 $value = $this->qtypeobj->generate_dataset_item($datasetdef->options);
f184c65c 446 } else {
75dc9037
SR
447 $value = $this->_form->getElementValue("number[{$j}]");
448 }
449 if ($this->_form->getElementType("number[{$j}]") == 'hidden') {
450 // Some of the number elements are from the float type and some are from the hidden type.
451 // We need to manually handle localised floats for hidden elements.
a1f10c5e 452 $value = format_float($value, -1);
f184c65c 453 }
75dc9037 454 $formdata["number[{$j}]"] = $value;
f4fe3968
TH
455 $formdata["definition[{$j}]"] = $defid;
456 $formdata["itemid[{$j}]"] = isset($datasetdef->items[$itemnumber]) ?
f184c65c 457 $datasetdef->items[$itemnumber]->id : 0;
f4fe3968 458 $data[$datasetdef->name] = $formdata["number[{$j}]"];
60b5ecd3 459 $j++;
460 }
8fc3e643 461 }
60b5ecd3 462
3d9645ae 463 // Existing records override generated data depending on radio element.
7d087744
TH
464 $j = $this->noofitems * count($this->datasetdefs) + 1;
465 if (!$this->regenerate && !optional_param('updatedatasets', false, PARAM_BOOL) &&
466 !optional_param('updateanswers', false, PARAM_BOOL)) {
7d087744 467 $itemnumber = $this->noofitems + 1;
f184c65c
TH
468 foreach ($this->datasetdefs as $defid => $datasetdef) {
469 if (isset($datasetdef->items[$itemnumber])) {
f4fe3968
TH
470 $formdata["number[{$j}]"] = $datasetdef->items[$itemnumber]->value;
471 $formdata["definition[{$j}]"] = $defid;
472 $formdata["itemid[{$j}]"] = $datasetdef->items[$itemnumber]->id;
60b5ecd3 473 $data[$datasetdef->name] = $datasetdef->items[$itemnumber]->value;
474 }
475 $j++;
476 }
60b5ecd3 477 }
28a27ef1 478
f184c65c
TH
479 $comment = $this->qtypeobj->comment_on_datasetitems($this->qtypeobj, $question->id,
480 $question->questiontext, $answers, $data, ($this->noofitems + 1));
7d087744 481 if (isset($comment->outsidelimit) && $comment->outsidelimit) {
f184c65c
TH
482 $this->outsidelimit=$comment->outsidelimit;
483 }
484 $key1 = 1;
485 foreach ($question->options->answers as $key => $answer) {
486 $formdata['answercomment['.($this->noofitems+$key1).']'] = $comment->stranswers[$key];
487 $key1++;
488 }
60b5ecd3 489
f184c65c
TH
490 if ($this->outsidelimit) {
491 $formdata['outsidelimit']= '<span class="error">' .
492 get_string('oneanswertrueansweroutsidelimits', 'qtype_calculated') . '</span>';
450f1127 493 }
60b5ecd3 494 $formdata = $this->qtypeobj->custom_generator_set_data($this->datasetdefs, $formdata);
495
496 parent::set_data((object)($formdata + (array)$question));
8fc3e643 497 }
498
f184c65c 499 public function validation($data, $files) {
60b5ecd3 500 $errors = array();
f184c65c 501 if (isset($data['savechanges']) && ($this->noofitems==0) ) {
451373ed 502 $errors['warning'] = get_string('warning', 'mnet');
aeb15530 503 }
f184c65c
TH
504 if ($this->outsidelimit) {
505 $errors['outsidelimits'] =
506 get_string('oneanswertrueansweroutsidelimits', 'qtype_calculated');
60b5ecd3 507 }
ac5230fe 508 $numbers = $data['number'];
f184c65c
TH
509 foreach ($numbers as $key => $number) {
510 if (! is_numeric($number)) {
9ddb8a56 511 if (stristr($number, ',')) {
512 $errors['number['.$key.']'] = get_string('nocommaallowed', 'qtype_calculated');
f184c65c 513 } else {
9ddb8a56 514 $errors['number['.$key.']'] = get_string('notvalidnumber', 'qtype_calculated');
ac5230fe 515 }
f184c65c 516 } else if (stristr($number, 'x')) {
9ddb8a56 517 $a = new stdClass();
518 $a->name = '';
519 $a->value = $number;
520 $errors['number['.$key.']'] = get_string('hexanotallowed', 'qtype_calculated', $a);
f184c65c 521 } else if (is_nan($number)) {
9ddb8a56 522 $errors['number['.$key.']'] = get_string('notvalidnumber', 'qtype_calculated');
aeb15530 523 }
ac5230fe 524 }
60b5ecd3 525 return $errors;
526 }
8fc3e643 527}