MDL-15094 fixed stats
[moodle.git] / question / type / multianswer / edit_multianswer_form.php
CommitLineData
271ffe3f 1<?php
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
18 var $questiondisplay ;
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');
705b5874 26
27 // display the questions from questiontext;
28 if ( "" != optional_param('questiontext','', PARAM_RAW)) {
29
30 $this->questiondisplay = fullclone(qtype_multianswer_extract_question(optional_param('questiontext','', PARAM_RAW))) ;
31
32 }else {
33 $this->questiondisplay = "";
34 }
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){
39 if ($subquestion != ''){
40 $countsubquestions++;
41 }
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) ) {
53 $this->editas[$sub] = $this->questiondisplay->options->questions[$sub]->qtype ;
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
60 $mform->addElement('static', 'sub_'.$sub."_".'questiontext', "subquestiontext",array('cols'=>60, 'rows'=>3));
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
df79079f 69 if ($this->questiondisplay->options->questions[$sub]->qtype =='multichoice' ) {
70 $mform->addElement('checkbox', 'sub_'.$sub."_".'layout', get_string('layout', 'quiz')) ;//, $gradeoptions);
71 }
705b5874 72 foreach ($this->questiondisplay->options->questions[$sub]->answer as $key =>$ans) {
73
74 $mform->addElement('static', 'sub_'.$sub."_".'answer['.$key.']', get_string('answer', 'quiz'), array('cols'=>60, 'rows'=>1));
75
76 if ($this->questiondisplay->options->questions[$sub]->qtype =='numerical' && $key == 0 ) {
77 $mform->addElement('static', 'sub_'.$sub."_".'tolerance['.$key.']', get_string('acceptederror', 'quiz')) ;//, $gradeoptions);
78 }
79
80 $mform->addElement('static', 'sub_'.$sub."_".'fraction['.$key.']', get_string('grade')) ;//, $gradeoptions);
81
82 $mform->addElement('static', 'sub_'.$sub."_".'feedback['.$key.']', get_string('feedback', 'quiz'));
83 }
84
85 }
86
120e5cbf 87 }
705b5874 88
89
32db0d42 90 function set_data($question) {
705b5874 91 $default_values =array();
120e5cbf 92 if (isset($question->id) and $question->id and $question->qtype and $question->questiontext) {
c6fc9988 93
94 foreach ($question->options->questions as $key => $wrapped) {
df79079f 95 if($wrapped != ''){
c6fc9988 96 // The old way of restoring the definitions is kept to gradually
97 // update all multianswer questions
98 if (empty($wrapped->questiontext)) {
99 $parsableanswerdef = '{' . $wrapped->defaultgrade . ':';
100 switch ($wrapped->qtype) {
101 case 'multichoice':
102 $parsableanswerdef .= 'MULTICHOICE:';
103 break;
104 case 'shortanswer':
105 $parsableanswerdef .= 'SHORTANSWER:';
106 break;
107 case 'numerical':
108 $parsableanswerdef .= 'NUMERICAL:';
109 break;
110 default:
2471ef86 111 print_error('unknownquestiontype', 'question', '', $wrapped->qtype);
c6fc9988 112 }
113 $separator= '';
114 foreach ($wrapped->options->answers as $subanswer) {
115 $parsableanswerdef .= $separator
116 . '%' . round(100*$subanswer->fraction) . '%';
117 $parsableanswerdef .= $subanswer->answer;
118 if (!empty($wrapped->options->tolerance)) {
119 // Special for numerical answers:
120 $parsableanswerdef .= ":{$wrapped->options->tolerance}";
121 // We only want tolerance for the first alternative, it will
122 // be applied to all of the alternatives.
123 unset($wrapped->options->tolerance);
124 }
125 if ($subanswer->feedback) {
126 $parsableanswerdef .= "#$subanswer->feedback";
127 }
128 $separator = '~';
129 }
130 $parsableanswerdef .= '}';
131 // Fix the questiontext fields of old questions
132 set_field('question', 'questiontext', addslashes($parsableanswerdef), 'id', $wrapped->id);
133 } else {
134 $parsableanswerdef = str_replace('&#', '&\#', $wrapped->questiontext);
135 }
136 $question->questiontext = str_replace("{#$key}", $parsableanswerdef, $question->questiontext);
137 }
138 }
df79079f 139 }
705b5874 140
141 // set default to $questiondisplay questions elements
142 if (isset($this->questiondisplay->options->questions)) {
143 $subquestions = fullclone($this->questiondisplay->options->questions) ;
144 if (count($subquestions)) {
145 $sub =1;
146 foreach ($subquestions as $subquestion) {
147 $prefix = 'sub_'.$sub.'_' ;
148
149 // validate parameters
150 $answercount = 0;
151 $maxgrade = false;
152 $maxfraction = -1;
153
154 foreach ($subquestion->answer as $key=>$answer) {
155 if ( $subquestion->qtype == 'numerical' && $key == 0 ) {
156 $default_values[$prefix.'tolerance['.$key.']'] = $subquestion->tolerance[0] ;
157 }
158 $trimmedanswer = trim($answer);
159 if ($trimmedanswer !== '') {
160 $answercount++;
161 if ($subquestion->qtype == 'numerical' && !(is_numeric($trimmedanswer) || $trimmedanswer == '*')) {
162 $this->_form->setElementError($prefix.'answer['.$key.']' , get_string('answermustbenumberorstar', 'qtype_numerical'));
163 }
164 if ($subquestion->fraction[$key] == 1) {
165 $maxgrade = true;
166 }
167 if ($subquestion->fraction[$key] > $maxfraction) {
168 $maxfraction = $subquestion->fraction[$key] ;
169 }
170 }
171
172 $default_values[$prefix.'answer['.$key.']'] = $answer;
173 }
174 if ($answercount == 0) {
175 if ($subquestion->qtype == 'multichoice' ) {
176 $this->_form->setElementError($prefix.'answer[0]' , get_string('notenoughanswers', 'qtype_multichoice', 2));
177 } else {
178 $this->_form->setElementError($prefix.'answer[0]' , get_string('notenoughanswers', 'quiz', 1));
179 }
180 }
181 if ($maxgrade == false) {
182 $this->_form->setElementError($prefix.'fraction[0]' ,get_string('fractionsnomax', 'question'));
183 }
184 foreach ($subquestion->feedback as $key=>$answer) {
185
186 $default_values[$prefix.'feedback['.$key.']'] = $answer;
187 }
188 foreach ( $subquestion->fraction as $key=>$answer) {
189 $default_values[$prefix.'fraction['.$key.']'] = $answer;
190 }
191
192
193 $sub++;
194 }
195 }
196 }
197 if( $default_values != "") {
198 $question = (object)((array)$question + $default_values);
199 }
120e5cbf 200 parent::set_data($question);
201 }
202
a78890d5 203 function validation($data, $files) {
204 $errors = parent::validation($data, $files);
705b5874 205
206 if (isset($this->questiondisplay->options->questions)) {
207
208 $subquestions = fullclone($this->questiondisplay->options->questions) ;
209 if (count($subquestions)) {
210 $sub =1;
211 foreach ($subquestions as $subquestion) {
212 $prefix = 'sub_'.$sub.'_' ;
213 $answercount = 0;
214 $maxgrade = false;
215 $maxfraction = -1;
216 foreach ( $subquestion->answer as $key=>$answer) {
217 $trimmedanswer = trim($answer);
218 if ($trimmedanswer !== '') {
219 $answercount++;
220 if ($subquestion->qtype =='numerical' && !(is_numeric($trimmedanswer) || $trimmedanswer == '*')) {
221 $errors[$prefix.'answer['.$key.']']= get_string('answermustbenumberorstar', 'qtype_numerical');
222 }
223 if ($subquestion->fraction[$key] == 1) {
224 $maxgrade = true;
225 }
226 if ($subquestion->fraction[$key] > $maxfraction) {
227 $maxfraction = $subquestion->fraction[$key] ;
228 }
229 }
230 }
231 if ($answercount==0) {
232 if ( $subquestion->qtype =='multichoice' ) {
233 $errors[$prefix.'answer[0]']= get_string('notenoughanswers', 'qtype_multichoice', 2);
234 }else {
235 $errors[$prefix.'answer[0]'] = get_string('notenoughanswers', 'quiz', 1);
236 }
237 }
238 if ($maxgrade == false) {
239 $errors[$prefix.'fraction[0]']=get_string('fractionsnomax', 'question');
240 }
241 $sub++;
242 }
243 } else {
df79079f 244 $errors['questiontext']=get_string('questionsmissing', 'qtype_multianswer');
705b5874 245 }
120e5cbf 246 }
705b5874 247
120e5cbf 248 return $errors;
c6fc9988 249 }
271ffe3f 250
251 function qtype() {
252 return 'multianswer';
253 }
254}
2471ef86 255?>