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