course/view MDL-20123 section 0 visibility and highlight
[moodle.git] / question / type / multianswer / edit_multianswer_form.php
CommitLineData
4d41f4ee 1<?php // $Id$
271ffe3f 2/**
3 * Defines the editing form for the multianswer question type.
4 *
5 * @copyright &copy; 2007 Jamie Pratt
6 * @author Jamie Pratt me@jamiep.org
7 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
830e47a8 8 * @package questionbank
9 * @subpackage questiontypes
271ffe3f 10 */
11
12/**
13 * multianswer editing form definition.
14 */
15class question_edit_multianswer_form extends question_edit_form {
16
705b5874 17 // $questiondisplay will contain the qtype_multianswer_extract_question from the questiontext
f34488b2 18 var $questiondisplay ;
705b5874 19
20 function definition_inner(&$mform) {
e2ae84a2 21 $question_type_names = question_type_menu();
120e5cbf 22 $mform->addRule('questiontext', null, 'required', null, 'client');
705b5874 23
fe648028 24 // Remove meaningless defaultgrade field.
25 $mform->removeElement('defaultgrade');
f34488b2 26
705b5874 27 // display the questions from questiontext;
28 if ( "" != optional_param('questiontext','', PARAM_RAW)) {
f34488b2 29
705b5874 30 $this->questiondisplay = fullclone(qtype_multianswer_extract_question(optional_param('questiontext','', PARAM_RAW))) ;
f34488b2 31
705b5874 32 }else {
33 $this->questiondisplay = "";
f34488b2 34 }
705b5874 35
df79079f 36 if ( isset($this->questiondisplay->options->questions) && is_array($this->questiondisplay->options->questions) ) {
37 $countsubquestions =0;
38 foreach($this->questiondisplay->options->questions as $subquestion){
103a800d 39 if (!empty($subquestion)){
df79079f 40 $countsubquestions++;
41 }
f34488b2 42 }
705b5874 43 } else {
44 $countsubquestions =0;
45 }
46
eb29fc27 47 $mform->addElement('submit', 'analyzequestion', get_string('decodeverifyquestiontext','qtype_multianswer'));
705b5874 48 $mform->registerNoSubmitButton('analyzequestion');
49
50 for ($sub =1;$sub <=$countsubquestions ;$sub++) {
51 $this->editas[$sub] = 'unknown type';
52 if (isset( $this->questiondisplay->options->questions[$sub]->qtype) ) {
f34488b2 53 $this->editas[$sub] = $this->questiondisplay->options->questions[$sub]->qtype ;
705b5874 54 } else if (optional_param('sub_'.$sub."_".'qtype', '', PARAM_RAW) != '') {
55 $this->editas[$sub] = optional_param('sub_'.$sub."_".'qtype', '', PARAM_RAW);
56 }
57 $mform->addElement('header', 'subhdr', get_string('questionno', 'quiz',
e2ae84a2 58 '{#'.$sub.'}').'&nbsp;'.$question_type_names[$this->questiondisplay->options->questions[$sub]->qtype]);
705b5874 59
665e82f8 60 $mform->addElement('static', 'sub_'.$sub."_".'questiontext', get_string('questiondefinition','qtype_multianswer'),array('cols'=>60, 'rows'=>3));
705b5874 61
62 if (isset ( $this->questiondisplay->options->questions[$sub]->questiontext)) {
63 $mform->setDefault('sub_'.$sub."_".'questiontext', $this->questiondisplay->options->questions[$sub]->questiontext);
64 }
65
66 $mform->addElement('static', 'sub_'.$sub."_".'defaultgrade', get_string('defaultgrade', 'quiz'));
67 $mform->setDefault('sub_'.$sub."_".'defaultgrade',$this->questiondisplay->options->questions[$sub]->defaultgrade);
68
fd97082c 69 if ($this->questiondisplay->options->questions[$sub]->qtype =='shortanswer' ) {
70 $mform->addElement('static', 'sub_'.$sub."_".'usecase', get_string('casesensitive', 'quiz'));
71 }
72
e5ebbd53 73 if ($this->questiondisplay->options->questions[$sub]->qtype =='multichoice' ) {
665e82f8 74 $mform->addElement('static', 'sub_'.$sub."_".'layout', get_string('layout', 'qtype_multianswer'),array('cols'=>60, 'rows'=>1)) ;//, $gradeoptions);
f34488b2 75 }
705b5874 76 foreach ($this->questiondisplay->options->questions[$sub]->answer as $key =>$ans) {
77
78 $mform->addElement('static', 'sub_'.$sub."_".'answer['.$key.']', get_string('answer', 'quiz'), array('cols'=>60, 'rows'=>1));
f34488b2 79
705b5874 80 if ($this->questiondisplay->options->questions[$sub]->qtype =='numerical' && $key == 0 ) {
81 $mform->addElement('static', 'sub_'.$sub."_".'tolerance['.$key.']', get_string('acceptederror', 'quiz')) ;//, $gradeoptions);
f34488b2 82 }
705b5874 83
84 $mform->addElement('static', 'sub_'.$sub."_".'fraction['.$key.']', get_string('grade')) ;//, $gradeoptions);
85
86 $mform->addElement('static', 'sub_'.$sub."_".'feedback['.$key.']', get_string('feedback', 'quiz'));
f34488b2 87 }
705b5874 88
89 }
90
120e5cbf 91 }
705b5874 92
f34488b2 93
32db0d42 94 function set_data($question) {
f34488b2 95 global $DB;
705b5874 96 $default_values =array();
120e5cbf 97 if (isset($question->id) and $question->id and $question->qtype and $question->questiontext) {
c6fc9988 98
99 foreach ($question->options->questions as $key => $wrapped) {
103a800d 100 if(!empty($wrapped)){
c6fc9988 101 // The old way of restoring the definitions is kept to gradually
102 // update all multianswer questions
103 if (empty($wrapped->questiontext)) {
104 $parsableanswerdef = '{' . $wrapped->defaultgrade . ':';
105 switch ($wrapped->qtype) {
106 case 'multichoice':
107 $parsableanswerdef .= 'MULTICHOICE:';
108 break;
109 case 'shortanswer':
110 $parsableanswerdef .= 'SHORTANSWER:';
111 break;
112 case 'numerical':
113 $parsableanswerdef .= 'NUMERICAL:';
114 break;
115 default:
2471ef86 116 print_error('unknownquestiontype', 'question', '', $wrapped->qtype);
c6fc9988 117 }
118 $separator= '';
119 foreach ($wrapped->options->answers as $subanswer) {
120 $parsableanswerdef .= $separator
121 . '%' . round(100*$subanswer->fraction) . '%';
122 $parsableanswerdef .= $subanswer->answer;
123 if (!empty($wrapped->options->tolerance)) {
124 // Special for numerical answers:
125 $parsableanswerdef .= ":{$wrapped->options->tolerance}";
126 // We only want tolerance for the first alternative, it will
127 // be applied to all of the alternatives.
128 unset($wrapped->options->tolerance);
129 }
130 if ($subanswer->feedback) {
131 $parsableanswerdef .= "#$subanswer->feedback";
132 }
133 $separator = '~';
134 }
135 $parsableanswerdef .= '}';
136 // Fix the questiontext fields of old questions
f34488b2 137 $DB->set_field('question', 'questiontext', $parsableanswerdef, array('id' => $wrapped->id));
c6fc9988 138 } else {
139 $parsableanswerdef = str_replace('&#', '&\#', $wrapped->questiontext);
140 }
141 $question->questiontext = str_replace("{#$key}", $parsableanswerdef, $question->questiontext);
142 }
143 }
df79079f 144 }
f34488b2 145
705b5874 146 // set default to $questiondisplay questions elements
f34488b2 147 if (isset($this->questiondisplay->options->questions)) {
148 $subquestions = fullclone($this->questiondisplay->options->questions) ;
705b5874 149 if (count($subquestions)) {
f34488b2 150 $sub =1;
151 foreach ($subquestions as $subquestion) {
705b5874 152 $prefix = 'sub_'.$sub.'_' ;
153
154 // validate parameters
155 $answercount = 0;
156 $maxgrade = false;
157 $maxfraction = -1;
fd97082c 158 if ($subquestion->qtype =='shortanswer' ) {
159 switch ($subquestion->usecase) {
160 case '1':
161 $default_values[$prefix.'usecase']= get_string('caseyes', 'quiz');
162 break;
163 case '0':
164 default :
165 $default_values[$prefix.'usecase']= get_string('caseno', 'quiz');
166 }
167 }
168
e5ebbd53 169 if ($subquestion->qtype == 'multichoice' ) {
170 $default_values[$prefix.'layout'] = $subquestion->layout ;
171 switch ($subquestion->layout) {
172 case '0':
665e82f8 173 $default_values[$prefix.'layout']= get_string('layoutselectinline', 'qtype_multianswer');
e5ebbd53 174 break;
175 case '1':
665e82f8 176 $default_values[$prefix.'layout']= get_string('layoutvertical', 'qtype_multianswer');
e5ebbd53 177 break;
178 case '2':
665e82f8 179 $default_values[$prefix.'layout']= get_string('layouthorizontal', 'qtype_multianswer');
e5ebbd53 180 break;
181 default:
665e82f8 182 $default_values[$prefix.'layout']= get_string('layoutundefined', 'qtype_multianswer');
e5ebbd53 183 }
184 }
705b5874 185 foreach ($subquestion->answer as $key=>$answer) {
186 if ( $subquestion->qtype == 'numerical' && $key == 0 ) {
187 $default_values[$prefix.'tolerance['.$key.']'] = $subquestion->tolerance[0] ;
188 }
189 $trimmedanswer = trim($answer);
190 if ($trimmedanswer !== '') {
191 $answercount++;
192 if ($subquestion->qtype == 'numerical' && !(is_numeric($trimmedanswer) || $trimmedanswer == '*')) {
193 $this->_form->setElementError($prefix.'answer['.$key.']' , get_string('answermustbenumberorstar', 'qtype_numerical'));
194 }
195 if ($subquestion->fraction[$key] == 1) {
196 $maxgrade = true;
f34488b2 197 }
705b5874 198 if ($subquestion->fraction[$key] > $maxfraction) {
199 $maxfraction = $subquestion->fraction[$key] ;
200 }
201 }
f34488b2 202
665e82f8 203 $default_values[$prefix.'answer['.$key.']'] = htmlspecialchars ($answer);
f34488b2 204 }
705b5874 205 if ($answercount == 0) {
206 if ($subquestion->qtype == 'multichoice' ) {
207 $this->_form->setElementError($prefix.'answer[0]' , get_string('notenoughanswers', 'qtype_multichoice', 2));
208 } else {
209 $this->_form->setElementError($prefix.'answer[0]' , get_string('notenoughanswers', 'quiz', 1));
210 }
211 }
212 if ($maxgrade == false) {
213 $this->_form->setElementError($prefix.'fraction[0]' ,get_string('fractionsnomax', 'question'));
f34488b2 214 }
705b5874 215 foreach ($subquestion->feedback as $key=>$answer) {
f34488b2 216
665e82f8 217 $default_values[$prefix.'feedback['.$key.']'] = htmlspecialchars ($answer);
f34488b2 218 }
705b5874 219 foreach ( $subquestion->fraction as $key=>$answer) {
220 $default_values[$prefix.'fraction['.$key.']'] = $answer;
f34488b2 221 }
222
223
224 $sub++;
705b5874 225 }
226 }
227 }
f34488b2 228 if( $default_values != "") {
705b5874 229 $question = (object)((array)$question + $default_values);
230 }
120e5cbf 231 parent::set_data($question);
232 }
233
a78890d5 234 function validation($data, $files) {
235 $errors = parent::validation($data, $files);
f34488b2 236
705b5874 237 if (isset($this->questiondisplay->options->questions)) {
f34488b2 238
239 $subquestions = fullclone($this->questiondisplay->options->questions) ;
705b5874 240 if (count($subquestions)) {
f34488b2 241 $sub =1;
242 foreach ($subquestions as $subquestion) {
705b5874 243 $prefix = 'sub_'.$sub.'_' ;
244 $answercount = 0;
245 $maxgrade = false;
246 $maxfraction = -1;
247 foreach ( $subquestion->answer as $key=>$answer) {
248 $trimmedanswer = trim($answer);
249 if ($trimmedanswer !== '') {
250 $answercount++;
251 if ($subquestion->qtype =='numerical' && !(is_numeric($trimmedanswer) || $trimmedanswer == '*')) {
252 $errors[$prefix.'answer['.$key.']']= get_string('answermustbenumberorstar', 'qtype_numerical');
253 }
254 if ($subquestion->fraction[$key] == 1) {
255 $maxgrade = true;
f34488b2 256 }
705b5874 257 if ($subquestion->fraction[$key] > $maxfraction) {
258 $maxfraction = $subquestion->fraction[$key] ;
259 }
f34488b2 260 }
261 }
705b5874 262 if ($answercount==0) {
263 if ( $subquestion->qtype =='multichoice' ) {
264 $errors[$prefix.'answer[0]']= get_string('notenoughanswers', 'qtype_multichoice', 2);
265 }else {
266 $errors[$prefix.'answer[0]'] = get_string('notenoughanswers', 'quiz', 1);
267 }
268 }
269 if ($maxgrade == false) {
270 $errors[$prefix.'fraction[0]']=get_string('fractionsnomax', 'question');
f34488b2 271 }
272 $sub++;
705b5874 273 }
274 } else {
f34488b2 275 $errors['questiontext']=get_string('questionsmissing', 'qtype_multianswer');
705b5874 276 }
120e5cbf 277 }
705b5874 278
120e5cbf 279 return $errors;
c6fc9988 280 }
271ffe3f 281
282 function qtype() {
283 return 'multianswer';
284 }
285}
2471ef86 286?>