MDL-43670 quiz: improve code comments a little
[moodle.git] / question / type / multianswer / edit_multianswer_form.php
CommitLineData
aeb15530 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
271ffe3f 17/**
d3603157 18 * Defines the editing form for the multi-answer question type.
271ffe3f 19 *
b04a4319
TH
20 * @package qtype
21 * @subpackage multianswer
22 * @copyright 2007 Jamie Pratt me@jamiep.org
23 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
271ffe3f 24 */
25
d3603157 26
a17b297d
TH
27defined('MOODLE_INTERNAL') || die();
28
1649a4f7 29require_once($CFG->dirroot . '/question/type/numerical/questiontype.php');
30
a17b297d 31
271ffe3f 32/**
d3603157 33 * Form for editing multi-answer questions.
b04a4319
TH
34 *
35 * @copyright 2007 Jamie Pratt me@jamiep.org
36 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
271ffe3f 37 */
ab50232b 38class qtype_multianswer_edit_form extends question_edit_form {
271ffe3f 39
1649a4f7 40 // The variable $questiondisplay will contain the qtype_multianswer_extract_question from
41 // the questiontext.
59a3fcd3 42 public $questiondisplay;
1649a4f7 43 // The variable $savedquestiondisplay will contain the qtype_multianswer_extract_question
44 // from the questiontext in database.
59a3fcd3
TH
45 public $savedquestion;
46 public $savedquestiondisplay;
47 public $used_in_quiz = false;
48 public $qtype_change = false;
49 public $negative_diff = 0;
fe6ce234
DC
50 public $nb_of_quiz = 0;
51 public $nb_of_attempts = 0;
59a3fcd3
TH
52 public $confirm = 0;
53 public $reload = false;
1649a4f7 54 /** @var qtype_numerical_answer_processor used when validating numerical answers. */
55 protected $ap = null;
56
aeb15530 57
59a3fcd3
TH
58 public function __construct($submiturl, $question, $category, $contexts, $formeditable = true) {
59 global $SESSION, $CFG, $DB;
347fb175 60 $this->regenerate = true;
7d087744 61 $this->reload = optional_param('reload', false, PARAM_BOOL);
59a3fcd3
TH
62
63 $this->used_in_quiz = false;
64
65 if (isset($question->id) && $question->id != 0) {
e5c5f52e 66 // TODO MDL-43779 should not have quiz-specific code here.
59a3fcd3 67 $this->savedquestiondisplay = fullclone($question);
dc4a3ea1
TH
68 $this->nb_of_quiz = $DB->count_records('quiz_question_instances', array('questionid' => $question->id));
69 $this->used_in_quiz = $this->nb_of_quiz > 0;
70 $this->nb_of_attempts = $DB->count_records_sql("
71 SELECT count(1)
72 FROM {quiz_question_instances} qqi
73 JOIN {quiz_attempts} quiza ON quiza.quiz = qqi.quizid
74 WHERE qqi.questionid = ?
75 AND quiza.preview = 0", array($question->id));
d3e3bd6c 76 }
77
59a3fcd3 78 parent::__construct($submiturl, $question, $category, $contexts, $formeditable);
d3e3bd6c 79 }
80
c7df5006 81 protected function definition_inner($mform) {
347fb175
PP
82 $mform->addElement('hidden', 'reload', 1);
83 $mform->setType('reload', PARAM_INT);
705b5874 84
ab50232b
TH
85 // Remove meaningless defaultmark field.
86 $mform->removeElement('defaultmark');
7d087744 87 $this->confirm = optional_param('confirm', false, PARAM_BOOL);
f34488b2 88
1649a4f7 89 // Display the questions from questiontext.
b8cc71e7
PS
90 if ($questiontext = optional_param_array('questiontext', false, PARAM_RAW)) {
91 $this->questiondisplay = fullclone(qtype_multianswer_extract_question($questiontext));
f34488b2 92
59a3fcd3
TH
93 } else {
94 if (!$this->reload && !empty($this->savedquestiondisplay->id)) {
1649a4f7 95 // Use database data as this is first pass
96 // question->id == 0 so no stored datasets.
d3e3bd6c 97 $this->questiondisplay = fullclone($this->savedquestiondisplay);
59a3fcd3
TH
98 foreach ($this->questiondisplay->options->questions as $subquestion) {
99 if (!empty($subquestion)) {
fe6ce234 100 $subquestion->answer = array('');
59a3fcd3
TH
101 foreach ($subquestion->options->answers as $ans) {
102 $subquestion->answer[] = $ans->answer;
fe6ce234 103 }
d3e3bd6c 104 }
aeb15530 105 }
59a3fcd3 106 } else {
d3e3bd6c 107 $this->questiondisplay = "";
108 }
f34488b2 109 }
705b5874 110
59a3fcd3
TH
111 if (isset($this->savedquestiondisplay->options->questions) &&
112 is_array($this->savedquestiondisplay->options->questions)) {
113 $countsavedsubquestions = 0;
114 foreach ($this->savedquestiondisplay->options->questions as $subquestion) {
115 if (!empty($subquestion)) {
fe6ce234 116 $countsavedsubquestions++;
df79079f 117 }
f34488b2 118 }
705b5874 119 } else {
59a3fcd3 120 $countsavedsubquestions = 0;
705b5874 121 }
59a3fcd3
TH
122 if ($this->reload) {
123 if (isset($this->questiondisplay->options->questions) &&
124 is_array($this->questiondisplay->options->questions)) {
125 $countsubquestions = 0;
126 foreach ($this->questiondisplay->options->questions as $subquestion) {
127 if (!empty($subquestion)) {
fe6ce234 128 $countsubquestions++;
d3e3bd6c 129 }
130 }
fe6ce234 131 } else {
59a3fcd3 132 $countsubquestions = 0;
705b5874 133 }
59a3fcd3
TH
134 } else {
135 $countsubquestions = $countsavedsubquestions;
fe6ce234 136 }
aeb15530 137
59a3fcd3
TH
138 $mform->addElement('submit', 'analyzequestion',
139 get_string('decodeverifyquestiontext', 'qtype_multianswer'));
fe6ce234 140 $mform->registerNoSubmitButton('analyzequestion');
59a3fcd3 141 if ($this->reload) {
59a3fcd3 142 for ($sub = 1; $sub <= $countsubquestions; $sub++) {
aeb15530 143
59a3fcd3 144 if (isset($this->questiondisplay->options->questions[$sub]->qtype)) {
ab50232b 145 $this->editas[$sub] = $this->questiondisplay->options->questions[$sub]->qtype;
7d087744
TH
146 } else {
147 $this->editas[$sub] = optional_param('sub_'.$sub.'_qtype', 'unknown type', PARAM_PLUGIN);
fd97082c 148 }
928e7d2a 149
d3e3bd6c 150 $storemess = '';
59a3fcd3
TH
151 if (isset($this->savedquestiondisplay->options->questions[$sub]->qtype) &&
152 $this->savedquestiondisplay->options->questions[$sub]->qtype !=
153 $this->questiondisplay->options->questions[$sub]->qtype) {
154 $this->qtype_change = true;
635971c7
TH
155 $storemess = ' ' . html_writer::tag('span', get_string(
156 'storedqtype', 'qtype_multianswer', question_bank::get_qtype_name(
157 $this->savedquestiondisplay->options->questions[$sub]->qtype)),
158 array('class' => 'error'));
59a3fcd3 159 }
aeb15530 160
5e8a85aa 161 $mform->addElement('header', 'subhdr'.$sub, get_string('questionno', 'question',
59a3fcd3
TH
162 '{#'.$sub.'}').'&nbsp;'.question_bank::get_qtype_name(
163 $this->questiondisplay->options->questions[$sub]->qtype).$storemess);
aeb15530 164
7d087744 165 $mform->addElement('static', 'sub_'.$sub.'_questiontext',
928e7d2a 166 get_string('questiondefinition', 'qtype_multianswer'));
aeb15530 167
59a3fcd3 168 if (isset ($this->questiondisplay->options->questions[$sub]->questiontext)) {
7d087744 169 $mform->setDefault('sub_'.$sub.'_questiontext',
59a3fcd3 170 $this->questiondisplay->options->questions[$sub]->questiontext['text']);
f34488b2 171 }
aeb15530 172
7d087744 173 $mform->addElement('static', 'sub_'.$sub.'_defaultmark',
ab50232b 174 get_string('defaultmark', 'question'));
7d087744 175 $mform->setDefault('sub_'.$sub.'_defaultmark',
ab50232b 176 $this->questiondisplay->options->questions[$sub]->defaultmark);
aeb15530 177
59a3fcd3 178 if ($this->questiondisplay->options->questions[$sub]->qtype == 'shortanswer') {
7d087744 179 $mform->addElement('static', 'sub_'.$sub.'_usecase',
ab50232b 180 get_string('casesensitive', 'qtype_shortanswer'));
fe6ce234 181 }
aeb15530 182
59a3fcd3 183 if ($this->questiondisplay->options->questions[$sub]->qtype == 'multichoice') {
7d087744 184 $mform->addElement('static', 'sub_'.$sub.'_layout',
928e7d2a 185 get_string('layout', 'qtype_multianswer'));
fe6ce234 186 }
aeb15530 187
928e7d2a 188 foreach ($this->questiondisplay->options->questions[$sub]->answer as $key => $ans) {
7d087744 189 $mform->addElement('static', 'sub_'.$sub.'_answer['.$key.']',
928e7d2a 190 get_string('answer', 'question'));
aeb15530 191
59a3fcd3
TH
192 if ($this->questiondisplay->options->questions[$sub]->qtype == 'numerical' &&
193 $key == 0) {
7d087744 194 $mform->addElement('static', 'sub_'.$sub.'_tolerance['.$key.']',
ab50232b 195 get_string('acceptederror', 'qtype_numerical'));
d3e3bd6c 196 }
aeb15530 197
7d087744 198 $mform->addElement('static', 'sub_'.$sub.'_fraction['.$key.']',
59a3fcd3 199 get_string('grade'));
aeb15530 200
7d087744 201 $mform->addElement('static', 'sub_'.$sub.'_feedback['.$key.']',
59a3fcd3 202 get_string('feedback', 'question'));
d3e3bd6c 203 }
f34488b2 204 }
928e7d2a 205
59a3fcd3
TH
206 $this->negative_diff = $countsavedsubquestions - $countsubquestions;
207 if (($this->negative_diff > 0) ||$this->qtype_change ||
208 ($this->used_in_quiz && $this->negative_diff != 0)) {
209 $mform->addElement('header', 'additemhdr',
210 get_string('warningquestionmodified', 'qtype_multianswer'));
fe6ce234 211 }
59a3fcd3
TH
212 if ($this->negative_diff > 0) {
213 $mform->addElement('static', 'alert1', "<strong>".
214 get_string('questiondeleted', 'qtype_multianswer')."</strong>",
215 get_string('questionsless', 'qtype_multianswer', $this->negative_diff));
d3e3bd6c 216 }
59a3fcd3
TH
217 if ($this->qtype_change) {
218 $mform->addElement('static', 'alert1', "<strong>".
219 get_string('questiontypechanged', 'qtype_multianswer')."</strong>",
220 get_string('questiontypechangedcomment', 'qtype_multianswer'));
d3e3bd6c 221 }
d3e3bd6c 222 }
59a3fcd3
TH
223 if ($this->used_in_quiz) {
224 if ($this->negative_diff < 0) {
c4979f02 225 $diff = $countsubquestions - $countsavedsubquestions;
59a3fcd3
TH
226 $mform->addElement('static', 'alert1', "<strong>".
227 get_string('questionsadded', 'qtype_multianswer')."</strong>",
228 "<strong>".get_string('questionsmore', 'qtype_multianswer', $diff).
229 "</strong>");
c4979f02 230 }
59a3fcd3 231 $a = new stdClass();
c4979f02
PP
232 $a->nb_of_quiz = $this->nb_of_quiz;
233 $a->nb_of_attempts = $this->nb_of_attempts;
59a3fcd3
TH
234 $mform->addElement('header', 'additemhdr2',
235 get_string('questionusedinquiz', 'qtype_multianswer', $a));
236 $mform->addElement('static', 'alertas',
237 get_string('youshouldnot', 'qtype_multianswer'));
d3e3bd6c 238 }
59a3fcd3
TH
239 if (($this->negative_diff > 0 || $this->used_in_quiz &&
240 ($this->negative_diff > 0 || $this->negative_diff < 0 || $this->qtype_change)) &&
241 $this->reload) {
242 $mform->addElement('header', 'additemhdr',
243 get_string('questionsaveasedited', 'qtype_multianswer'));
244 $mform->addElement('checkbox', 'confirm', '',
245 get_string('confirmquestionsaveasedited', 'qtype_multianswer'));
d3e3bd6c 246 $mform->setDefault('confirm', 0);
59a3fcd3
TH
247 } else {
248 $mform->addElement('hidden', 'confirm', 0);
e380d57f 249 $mform->setType('confirm', PARAM_BOOL);
705b5874 250 }
347fb175 251
e9af6091 252 $this->add_interactive_settings(true, true);
120e5cbf 253 }
705b5874 254
f34488b2 255
59a3fcd3 256 public function set_data($question) {
f34488b2 257 global $DB;
59a3fcd3
TH
258 $default_values = array();
259 if (isset($question->id) and $question->id and $question->qtype &&
260 $question->questiontext) {
c6fc9988 261
262 foreach ($question->options->questions as $key => $wrapped) {
59a3fcd3 263 if (!empty($wrapped)) {
fe6ce234 264 // The old way of restoring the definitions is kept to gradually
1649a4f7 265 // update all multianswer questions.
fe6ce234 266 if (empty($wrapped->questiontext)) {
ab50232b 267 $parsableanswerdef = '{' . $wrapped->defaultmark . ':';
fe6ce234 268 switch ($wrapped->qtype) {
59a3fcd3
TH
269 case 'multichoice':
270 $parsableanswerdef .= 'MULTICHOICE:';
271 break;
272 case 'shortanswer':
273 $parsableanswerdef .= 'SHORTANSWER:';
274 break;
275 case 'numerical':
276 $parsableanswerdef .= 'NUMERICAL:';
277 break;
278 default:
279 print_error('unknownquestiontype', 'question', '',
280 $wrapped->qtype);
c6fc9988 281 }
59a3fcd3 282 $separator = '';
fe6ce234
DC
283 foreach ($wrapped->options->answers as $subanswer) {
284 $parsableanswerdef .= $separator
285 . '%' . round(100*$subanswer->fraction) . '%';
c1f15d35
TH
286 if (is_array($subanswer->answer)) {
287 $parsableanswerdef .= $subanswer->answer['text'];
288 } else {
289 $parsableanswerdef .= $subanswer->answer;
290 }
fe6ce234 291 if (!empty($wrapped->options->tolerance)) {
1649a4f7 292 // Special for numerical answers.
fe6ce234
DC
293 $parsableanswerdef .= ":{$wrapped->options->tolerance}";
294 // We only want tolerance for the first alternative, it will
295 // be applied to all of the alternatives.
296 unset($wrapped->options->tolerance);
297 }
298 if ($subanswer->feedback) {
299 $parsableanswerdef .= "#$subanswer->feedback";
300 }
301 $separator = '~';
c6fc9988 302 }
fe6ce234 303 $parsableanswerdef .= '}';
1649a4f7 304 // Fix the questiontext fields of old questions.
59a3fcd3
TH
305 $DB->set_field('question', 'questiontext', $parsableanswerdef,
306 array('id' => $wrapped->id));
fe6ce234
DC
307 } else {
308 $parsableanswerdef = str_replace('&#', '&\#', $wrapped->questiontext);
c6fc9988 309 }
59a3fcd3
TH
310 $question->questiontext = str_replace("{#$key}", $parsableanswerdef,
311 $question->questiontext);
c6fc9988 312 }
c6fc9988 313 }
314 }
347fb175 315
1649a4f7 316 // Set default to $questiondisplay questions elements.
59a3fcd3 317 if ($this->reload) {
fe6ce234 318 if (isset($this->questiondisplay->options->questions)) {
59a3fcd3 319 $subquestions = fullclone($this->questiondisplay->options->questions);
fe6ce234 320 if (count($subquestions)) {
59a3fcd3 321 $sub = 1;
fe6ce234 322 foreach ($subquestions as $subquestion) {
59a3fcd3 323 $prefix = 'sub_'.$sub.'_';
fe6ce234 324
1649a4f7 325 // Validate parameters.
fe6ce234
DC
326 $answercount = 0;
327 $maxgrade = false;
328 $maxfraction = -1;
59a3fcd3 329 if ($subquestion->qtype == 'shortanswer') {
fe6ce234 330 switch ($subquestion->usecase) {
59a3fcd3
TH
331 case '1':
332 $default_values[$prefix.'usecase'] =
333 get_string('caseyes', 'qtype_shortanswer');
334 break;
335 case '0':
336 default :
337 $default_values[$prefix.'usecase'] =
338 get_string('caseno', 'qtype_shortanswer');
fe6ce234 339 }
fd97082c 340 }
fd97082c 341
59a3fcd3
TH
342 if ($subquestion->qtype == 'multichoice') {
343 $default_values[$prefix.'layout'] = $subquestion->layout;
fe6ce234 344 switch ($subquestion->layout) {
59a3fcd3
TH
345 case '0':
346 $default_values[$prefix.'layout'] =
347 get_string('layoutselectinline', 'qtype_multianswer');
348 break;
349 case '1':
350 $default_values[$prefix.'layout'] =
351 get_string('layoutvertical', 'qtype_multianswer');
352 break;
353 case '2':
354 $default_values[$prefix.'layout'] =
355 get_string('layouthorizontal', 'qtype_multianswer');
356 break;
357 default:
358 $default_values[$prefix.'layout'] =
359 get_string('layoutundefined', 'qtype_multianswer');
fe6ce234 360 }
aeb15530 361 }
59a3fcd3
TH
362 foreach ($subquestion->answer as $key => $answer) {
363 if ($subquestion->qtype == 'numerical' && $key == 0) {
e64e28d7 364 $default_values[$prefix.'tolerance['.$key.']'] =
59a3fcd3 365 $subquestion->tolerance[0];
705b5874 366 }
c1f15d35
TH
367 if (is_array($answer)) {
368 $answer = $answer['text'];
369 }
fe6ce234
DC
370 $trimmedanswer = trim($answer);
371 if ($trimmedanswer !== '') {
372 $answercount++;
59a3fcd3 373 if ($subquestion->qtype == 'numerical' &&
1649a4f7 374 !($this->is_valid_number($trimmedanswer) || $trimmedanswer == '*')) {
59a3fcd3
TH
375 $this->_form->setElementError($prefix.'answer['.$key.']',
376 get_string('answermustbenumberorstar',
377 'qtype_numerical'));
fe6ce234
DC
378 }
379 if ($subquestion->fraction[$key] == 1) {
380 $maxgrade = true;
381 }
382 if ($subquestion->fraction[$key] > $maxfraction) {
59a3fcd3 383 $maxfraction = $subquestion->fraction[$key];
fe6ce234 384 }
f34488b2 385 }
fe6ce234 386
59a3fcd3
TH
387 $default_values[$prefix.'answer['.$key.']'] =
388 htmlspecialchars($answer);
fe6ce234
DC
389 }
390 if ($answercount == 0) {
59a3fcd3
TH
391 if ($subquestion->qtype == 'multichoice') {
392 $this->_form->setElementError($prefix.'answer[0]',
393 get_string('notenoughanswers', 'qtype_multichoice', 2));
fe6ce234 394 } else {
59a3fcd3
TH
395 $this->_form->setElementError($prefix.'answer[0]',
396 get_string('notenoughanswers', 'question', 1));
705b5874 397 }
398 }
fe6ce234 399 if ($maxgrade == false) {
59a3fcd3
TH
400 $this->_form->setElementError($prefix.'fraction[0]',
401 get_string('fractionsnomax', 'question'));
705b5874 402 }
59a3fcd3 403 foreach ($subquestion->feedback as $key => $answer) {
f34488b2 404
59a3fcd3
TH
405 $default_values[$prefix.'feedback['.$key.']'] =
406 htmlspecialchars ($answer['text']);
fe6ce234 407 }
59a3fcd3
TH
408 foreach ($subquestion->fraction as $key => $answer) {
409 $default_values[$prefix.'fraction['.$key.']'] = $answer;
fe6ce234 410 }
f34488b2 411
fe6ce234
DC
412 $sub++;
413 }
705b5874 414 }
415 }
416 }
59a3fcd3
TH
417 $default_values['alertas']= "<strong>".get_string('questioninquiz', 'qtype_multianswer').
418 "</strong>";
347fb175 419
59a3fcd3 420 if ($default_values != "") {
705b5874 421 $question = (object)((array)$question + $default_values);
422 }
e9af6091 423 $question = $this->data_preprocessing_hints($question, true, true);
120e5cbf 424 parent::set_data($question);
425 }
426
1649a4f7 427 /**
428 * Validate that a string is a nubmer formatted correctly for the current locale.
429 * @param string $x a string
430 * @return bool whether $x is a number that the numerical question type can interpret.
431 */
432 protected function is_valid_number($x) {
433 if (is_null($this->ap)) {
434 $this->ap = new qtype_numerical_answer_processor(array());
435 }
436
437 list($value, $unit) = $this->ap->apply_units($x);
438
439 return !is_null($value) && !$unit;
440 }
441
442
59a3fcd3 443 public function validation($data, $files) {
a78890d5 444 $errors = parent::validation($data, $files);
8e8f9f3d 445
0bc0a265 446 $questiondisplay = qtype_multianswer_extract_question($data['questiontext']);
f34488b2 447
347fb175 448 if (isset($questiondisplay->options->questions)) {
59a3fcd3 449 $subquestions = fullclone($questiondisplay->options->questions);
705b5874 450 if (count($subquestions)) {
59a3fcd3 451 $sub = 1;
f34488b2 452 foreach ($subquestions as $subquestion) {
59a3fcd3 453 $prefix = 'sub_'.$sub.'_';
705b5874 454 $answercount = 0;
455 $maxgrade = false;
456 $maxfraction = -1;
59a3fcd3
TH
457 if (isset($this->savedquestiondisplay->options->questions[$sub]->qtype) &&
458 $this->savedquestiondisplay->options->questions[$sub]->qtype !=
459 $questiondisplay->options->questions[$sub]->qtype) {
460 $storemess = " STORED QTYPE ".question_bank::get_qtype_name(
461 $this->savedquestiondisplay->options->questions[$sub]->qtype);
462 }
463 foreach ($subquestion->answer as $key => $answer) {
c1f15d35
TH
464 if (is_array($answer)) {
465 $answer = $answer['text'];
466 }
705b5874 467 $trimmedanswer = trim($answer);
468 if ($trimmedanswer !== '') {
469 $answercount++;
e64e28d7
DP
470 if ($subquestion->qtype == 'numerical' &&
471 !($this->is_valid_number($trimmedanswer) || $trimmedanswer == '*')) {
472 $errors[$prefix.'answer['.$key.']'] =
59a3fcd3 473 get_string('answermustbenumberorstar', 'qtype_numerical');
fe6ce234 474 }
705b5874 475 if ($subquestion->fraction[$key] == 1) {
476 $maxgrade = true;
f34488b2 477 }
705b5874 478 if ($subquestion->fraction[$key] > $maxfraction) {
59a3fcd3 479 $maxfraction = $subquestion->fraction[$key];
705b5874 480 }
f34488b2 481 }
482 }
59a3fcd3
TH
483 if ($answercount == 0) {
484 if ($subquestion->qtype == 'multichoice') {
485 $errors[$prefix.'answer[0]'] =
486 get_string('notenoughanswers', 'qtype_multichoice', 2);
487 } else {
488 $errors[$prefix.'answer[0]'] =
489 get_string('notenoughanswers', 'question', 1);
705b5874 490 }
491 }
492 if ($maxgrade == false) {
59a3fcd3
TH
493 $errors[$prefix.'fraction[0]'] =
494 get_string('fractionsnomax', 'question');
f34488b2 495 }
496 $sub++;
705b5874 497 }
498 } else {
59a3fcd3 499 $errors['questiontext'] = get_string('questionsmissing', 'qtype_multianswer');
705b5874 500 }
120e5cbf 501 }
705b5874 502
59a3fcd3
TH
503 if (($this->negative_diff > 0 || $this->used_in_quiz &&
504 ($this->negative_diff > 0 || $this->negative_diff < 0 ||
7d087744 505 $this->qtype_change)) && !$this->confirm) {
59a3fcd3
TH
506 $errors['confirm'] =
507 get_string('confirmsave', 'qtype_multianswer', $this->negative_diff);
508 }
fe6ce234
DC
509
510 return $errors;
c6fc9988 511 }
271ffe3f 512
59a3fcd3 513 public function qtype() {
271ffe3f 514 return 'multianswer';
515 }
516}