rss MDL-25076 made forum rss feeds that are displaying discussions instead of posts...
[moodle.git] / question / type / calculatedmulti / questiontype.php
CommitLineData
2d279432
PP
1<?php
2
fe6ce234
DC
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
2d279432
PP
18/////////////////
19// CALCULATED ///
20/////////////////
21
22/// QUESTION TYPE CLASS //////////////////
23
2d279432
PP
24class question_calculatedmulti_qtype extends question_calculated_qtype {
25
26 // Used by the function custom_generator_tools:
fe6ce234 27 public $calcgenerateidhasbeenadded = false;
2d279432
PP
28 public $virtualqtype = false;
29
30 function name() {
31 return 'calculatedmulti';
32 }
33
34 function has_wildcards_in_responses($question, $subqid) {
35 return true;
36 }
37
38 function requires_qtypes() {
39 return array('multichoice');
40 }
2d279432 41
2d279432
PP
42
43 function save_question_options($question) {
2d279432 44 global $CFG, $DB, $QTYPES ;
fe6ce234 45 $context = $question->context;
2d279432
PP
46 if (isset($question->answer) && !isset($question->answers)) {
47 $question->answers = $question->answer;
48 }
49 // calculated options
fe6ce234 50 $update = true ;
2d279432
PP
51 $options = $DB->get_record("question_calculated_options", array("question" => $question->id));
52 if (!$options) {
53 $update = false;
54 $options = new stdClass;
55 $options->question = $question->id;
56 }
57 $options->synchronize = $question->synchronize;
2d279432
PP
58 $options->single = $question->single;
59 $options->answernumbering = $question->answernumbering;
60 $options->shuffleanswers = $question->shuffleanswers;
fe6ce234
DC
61
62 // save question feedback files
63 foreach (array('correct', 'partiallycorrect', 'incorrect') as $feedbacktype) {
64 $feedbackname = $feedbacktype . 'feedback';
65 $feedbackformat = $feedbackname . 'format';
66 $feedback = $question->$feedbackname;
67 $options->$feedbackformat = $feedback['format'];
68 $options->$feedbackname = file_save_draft_area_files($feedback['itemid'], $context->id, 'qtype_calculatedmulti', $feedbackname, $question->id, self::$fileoptions, trim($feedback['text']));
69 }
70
2d279432 71 if ($update) {
fe6ce234 72 $DB->update_record("question_calculated_options", $options);
2d279432 73 } else {
fe6ce234 74 $DB->insert_record("question_calculated_options", $options);
2d279432
PP
75 }
76
77 // Get old versions of the objects
78 if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
79 $oldanswers = array();
80 }
81
82 if (!$oldoptions = $DB->get_records('question_calculated', array('question' => $question->id), 'answer ASC')) {
83 $oldoptions = array();
84 }
85
86 // Save the units.
fe6ce234
DC
87 $virtualqtype = $this->get_virtual_qtype($question);
88 // TODO: What is this?
89 // $result = $virtualqtype->save_numerical_units($question);
2d279432
PP
90 if (isset($result->error)) {
91 return $result;
92 } else {
93 $units = &$result->units;
94 }
95 // Insert all the new answers
96 if (isset($question->answer) && !isset($question->answers)) {
fe6ce234 97 $question->answers = $question->answer;
2d279432
PP
98 }
99 foreach ($question->answers as $key => $dataanswer) {
fe6ce234 100 if ( trim($dataanswer) != '' ) {
2d279432
PP
101 $answer = new stdClass;
102 $answer->question = $question->id;
103 $answer->answer = trim($dataanswer);
104 $answer->fraction = $question->fraction[$key];
fe6ce234
DC
105 $answer->feedback = trim($question->feedback[$key]['text']);
106 $answer->feedbackformat = $question->feedback[$key]['format'];
2d279432
PP
107
108 if ($oldanswer = array_shift($oldanswers)) { // Existing answer, so reuse it
109 $answer->id = $oldanswer->id;
fe6ce234 110 $answer->feedback = file_save_draft_area_files($question->feedback[$key]['itemid'], $context->id, 'question', 'answerfeedback', $answer->id, self::$fileoptions, $answer->feedback);
2d279432
PP
111 $DB->update_record("question_answers", $answer);
112 } else { // This is a completely new answer
113 $answer->id = $DB->insert_record("question_answers", $answer);
fe6ce234
DC
114 $feedbacktext = file_save_draft_area_files($question->feedback[$key]['itemid'], $context->id, 'question', 'answerfeedback', $answer->id, self::$fileoptions, $answer->feedback);
115 $DB->set_field('question_answers', 'feedback', $feedbacktext, array('id'=>$answer->id));
2d279432
PP
116 }
117
118 // Set up the options object
119 if (!$options = array_shift($oldoptions)) {
120 $options = new stdClass;
121 }
122 $options->question = $question->id;
123 $options->answer = $answer->id;
124 $options->tolerance = trim($question->tolerance[$key]);
125 $options->tolerancetype = trim($question->tolerancetype[$key]);
126 $options->correctanswerlength = trim($question->correctanswerlength[$key]);
127 $options->correctanswerformat = trim($question->correctanswerformat[$key]);
128
129 // Save options
130 if (isset($options->id)) { // reusing existing record
131 $DB->update_record('question_calculated', $options);
132 } else { // new options
133 $DB->insert_record('question_calculated', $options);
134 }
135 }
136 }
137 // delete old answer records
138 if (!empty($oldanswers)) {
139 foreach($oldanswers as $oa) {
140 $DB->delete_records('question_answers', array('id' => $oa->id));
141 }
142 }
143
144 // delete old answer records
145 if (!empty($oldoptions)) {
146 foreach($oldoptions as $oo) {
147 $DB->delete_records('question_calculated', array('id' => $oo->id));
148 }
149 }
2d279432
PP
150
151
152 if( isset($question->import_process)&&$question->import_process){
153 $this->import_datasets($question);
fe6ce234 154 }
2d279432
PP
155 // Report any problems.
156 if (!empty($result->notice)) {
157 return $result;
158 }
159 return true;
160 }
161
162 function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) {
163 // Find out how many datasets are available
d90b016b 164 global $CFG, $DB, $QTYPES, $OUTPUT ;
fe6ce234
DC
165 $maxnumber = (int)$DB->get_field_sql(
166 "SELECT MIN(a.itemcount)
167 FROM {question_dataset_definitions} a, {question_datasets} b
168 WHERE b.question = ? AND a.id = b.datasetdefinition", array($question->id));
169 if (!$maxnumber) {
2d279432
PP
170 print_error('cannotgetdsforquestion', 'question', '', $question->id);
171 }
fe6ce234
DC
172 $sql = "SELECT i.*
173 FROM {question_datasets} d, {question_dataset_definitions} i
174 WHERE d.question = ? AND d.datasetdefinition = i.id AND i.category != 0";
2d279432 175 if (!$question->options->synchronize || !$records = $DB->get_records_sql($sql, array($question->id))) {
fe6ce234
DC
176 $synchronize_calculated = false ;
177 } else {
178 // i.e records is true so test coherence
179 $coherence = true ;
180 $a = new stdClass ;
181 $a->qid = $question->id ;
182 $a->qcat = $question->category ;
183 foreach($records as $def ){
d90b016b
PP
184 if ($def->category != $question->category){
185 $a->name = $def->name;
186 $a->sharedcat = $def->category ;
187 $coherence = false ;
188 break;
189 }
190 }
191 if(!$coherence){
fe6ce234
DC
192 echo $OUTPUT->notification(get_string('nocoherencequestionsdatyasetcategory','qtype_calculated',$a));
193 }
194
195 $synchronize_calculated = true ;
196 }
2d279432
PP
197
198 // Choose a random dataset
d90b016b
PP
199 // maxnumber sould not be breater than 100
200 if ($maxnumber > CALCULATEDQUESTIONMAXITEMNUMBER ){
201 $maxnumber = CALCULATEDQUESTIONMAXITEMNUMBER ;
202 }
2d279432
PP
203 if ( $synchronize_calculated === false ) {
204 $state->options->datasetitem = rand(1, $maxnumber);
205 }else{
fe6ce234 206 $state->options->datasetitem = intval( $maxnumber * substr($attempt->timestart,-2) /100 ) ;
2d279432
PP
207 if ($state->options->datasetitem < 1) {
208 $state->options->datasetitem =1 ;
209 } else if ($state->options->datasetitem > $maxnumber){
210 $state->options->datasetitem = $maxnumber ;
211 }
fe6ce234
DC
212
213 };
2d279432 214 $state->options->dataset =
fe6ce234
DC
215 $this->pick_question_dataset($question,$state->options->datasetitem);
216 // create an array of answerids ??? why so complicated ???
217 $answerids = array_values(array_map(create_function('$val',
218 'return $val->id;'), $question->options->answers));
219 // Shuffle the answers if required
220 if (!empty($cmoptions->shuffleanswers) and !empty($question->options->shuffleanswers)) {
221 $answerids = swapshuffle($answerids);
222 }
223 $state->options->order = $answerids;
224 // Create empty responses
225 if ($question->options->single) {
226 $state->responses = array('' => '');
227 } else {
228 $state->responses = array();
229 }
230 return true;
2d279432 231 }
fe6ce234 232
2d279432
PP
233 function save_session_and_responses(&$question, &$state) {
234 global $DB;
fe6ce234 235 $responses = 'dataset'.$state->options->datasetitem.'-' ;
2d279432
PP
236 $responses .= implode(',', $state->options->order) . ':';
237 $responses .= implode(',', $state->responses);
fe6ce234
DC
238
239 // Set the legacy answer field
f685e830 240 $DB->set_field('question_states', 'answer', $responses, array('id'=> $state->id));
2d279432
PP
241 return true;
242 }
243
244 function create_runtime_question($question, $form) {
78a6d0ba 245 $question = default_questiontype::create_runtime_question($question, $form);
2d279432
PP
246 $question->options->answers = array();
247 foreach ($form->answers as $key => $answer) {
248 $a->answer = trim($form->answer[$key]);
249 $a->fraction = $form->fraction[$key];//new
fe6ce234 250 $a->tolerance = $form->tolerance[$key];
2d279432
PP
251 $a->tolerancetype = $form->tolerancetype[$key];
252 $a->correctanswerlength = $form->correctanswerlength[$key];
253 $a->correctanswerformat = $form->correctanswerformat[$key];
254 $question->options->answers[] = clone($a);
255 }
256
257 return $question;
258 }
259
2d279432 260 function convert_answers (&$question, &$state){
fe6ce234
DC
261 foreach ($question->options->answers as $key => $answer) {
262 $answer->answer = $this->substitute_variables($answer->answer, $state->options->dataset);
263 //evaluate the equations i.e {=5+4)
264 $qtext = "";
265 $qtextremaining = $answer->answer ;
266 // while (preg_match('~\{(=)|%[[:digit]]\.=([^[:space:]}]*)}~', $qtextremaining, $regs1)) {
267 while (preg_match('~\{=([^[:space:]}]*)}~', $qtextremaining, $regs1)) {
268
269 $qtextsplits = explode($regs1[0], $qtextremaining, 2);
270 $qtext = $qtext.$qtextsplits[0];
271 $qtextremaining = $qtextsplits[1];
272 if (empty($regs1[1])) {
273 $str = '';
274 } else {
275 if( $formulaerrors = qtype_calculated_find_formula_errors($regs1[1])){
276 $str=$formulaerrors ;
277 }else {
278 eval('$str = '.$regs1[1].';');
279 $texteval= qtype_calculated_calculate_answer(
280 $str, $state->options->dataset, $answer->tolerance,
281 $answer->tolerancetype, $answer->correctanswerlength,
282 $answer->correctanswerformat, '');
2d279432 283 $str = $texteval->answer;
fe6ce234 284 }
2d279432 285 }
fe6ce234 286 $qtext = $qtext.$str ;
2d279432 287 }
fe6ce234 288 $answer->answer = $qtext.$qtextremaining ; ;
2d279432 289 }
fe6ce234 290 }
2d279432 291
fe6ce234
DC
292 function get_default_numerical_unit($question, $virtualqtype){
293 $unit = '';
294 return $unit ;
295 }
2d279432
PP
296 function grade_responses(&$question, &$state, $cmoptions) {
297 // Forward the grading to the virtual qtype
298 // We modify the question to look like a multichoice question
fe6ce234 299 // for grading nothing to do
2d279432
PP
300/* $numericalquestion = fullclone($question);
301 foreach ($numericalquestion->options->answers as $key => $answer) {
302 $answer = $numericalquestion->options->answers[$key]->answer; // for PHP 4.x
303 $numericalquestion->options->answers[$key]->answer = $this->substitute_variables_and_eval($answer,
304 $state->options->dataset);
fe6ce234
DC
305}*/
306 $virtualqtype = $this->get_virtual_qtype( $question);
2d279432
PP
307 return $virtualqtype->grade_responses($question, $state, $cmoptions) ;
308 }
309
2d279432 310
2d279432
PP
311
312 // ULPGC ecastro
313 function get_actual_response(&$question, &$state) {
314 // Substitute variables in questiontext before giving the data to the
315 // virtual type
316 $virtualqtype = $this->get_virtual_qtype( $question);
317 $unit = '' ;//$virtualqtype->get_default_numerical_unit($question);
318
319 // We modify the question to look like a multichoice question
320 $numericalquestion = clone($question);
321 $this->convert_answers ($numericalquestion, $state);
322 $this->convert_questiontext ($numericalquestion, $state);
323 /* $numericalquestion->questiontext = $this->substitute_variables_and_eval(
fe6ce234 324 $numericalquestion->questiontext, $state->options->dataset);*/
2d279432
PP
325 $responses = $virtualqtype->get_all_responses($numericalquestion, $state);
326 $response = reset($responses->responses);
327 $correct = $response->answer.' : ';
328
329 $responses = $virtualqtype->get_actual_response($numericalquestion, $state);
330
331 foreach ($responses as $key=>$response){
332 $responses[$key] = $correct.$response;
333 }
334
335 return $responses;
336 }
337
338 function create_virtual_qtype() {
339 global $CFG;
fe6ce234
DC
340 require_once("$CFG->dirroot/question/type/multichoice/questiontype.php");
341 return new question_multichoice_qtype();
2d279432
PP
342 }
343
344
345 function comment_header($question) {
346 //$this->get_question_options($question);
347 $strheader = '';
348 $delimiter = '';
349
350 $answers = $question->options->answers;
351
352 foreach ($answers as $key => $answer) {
353 if (is_string($answer)) {
354 $strheader .= $delimiter.$answer;
355 } else {
356 $strheader .= $delimiter.$answer->answer;
357 }
fe6ce234 358 $delimiter = '<br/>';
2d279432
PP
359 }
360 return $strheader;
361 }
362
363 function comment_on_datasetitems($qtypeobj,$questionid,$questiontext, $answers,$data, $number) { //multichoice_
364 global $DB;
365 $comment = new stdClass;
366 $comment->stranswers = array();
367 $comment->outsidelimit = false ;
368 $comment->answers = array();
369 /// Find a default unit:
370 /* if (!empty($questionid) && $unit = $DB->get_record('question_numerical_units', array('question'=> $questionid, 'multiplier' => 1.0))) {
371 $unit = $unit->unit;
372 } else {
373 $unit = '';
fe6ce234 374 }*/
2d279432
PP
375
376 $answers = fullclone($answers);
377 $strmin = get_string('min', 'quiz');
378 $strmax = get_string('max', 'quiz');
379 $errors = '';
380 $delimiter = ': ';
381 foreach ($answers as $key => $answer) {
fe6ce234
DC
382 $answer->answer = $this->substitute_variables($answer->answer, $data);
383 //evaluate the equations i.e {=5+4)
384 $qtext = "";
385 $qtextremaining = $answer->answer ;
386 while (preg_match('~\{=([^[:space:]}]*)}~', $qtextremaining, $regs1)) {
387 $qtextsplits = explode($regs1[0], $qtextremaining, 2);
388 $qtext =$qtext.$qtextsplits[0];
389 $qtextremaining = $qtextsplits[1];
390 if (empty($regs1[1])) {
391 $str = '';
392 } else {
393 if( $formulaerrors = qtype_calculated_find_formula_errors($regs1[1])){
394 $str=$formulaerrors ;
395 }else {
396 eval('$str = '.$regs1[1].';');
397 }
2d279432 398 }
fe6ce234
DC
399 $qtext = $qtext.$str ;
400 }
401 $answer->answer = $qtext.$qtextremaining;
402 $comment->stranswers[$key] = $answer->answer;
403
404
2d279432
PP
405 /* $formula = $this->substitute_variables($answer->answer,$data);
406 $formattedanswer = qtype_calculated_calculate_answer(
407 $answer->answer, $data, $answer->tolerance,
408 $answer->tolerancetype, $answer->correctanswerlength,
409 $answer->correctanswerformat, $unit);
410 if ( $formula === '*'){
411 $answer->min = ' ';
412 $formattedanswer->answer = $answer->answer ;
413 }else {
414 eval('$answer->answer = '.$formula.';') ;
415 $virtualqtype->get_tolerance_interval($answer);
fe6ce234 416 }
2d279432
PP
417 if ($answer->min === '') {
418 // This should mean that something is wrong
419 $comment->stranswers[$key] = " $formattedanswer->answer".'<br/><br/>';
420 } else if ($formula === '*'){
421 $comment->stranswers[$key] = $formula.' = '.get_string('anyvalue','qtype_calculated').'<br/><br/><br/>';
422 }else{
423 $comment->stranswers[$key]= $formula.' = '.$formattedanswer->answer.'<br/>' ;
424 $comment->stranswers[$key] .= $strmin. $delimiter.$answer->min.'---';
425 $comment->stranswers[$key] .= $strmax.$delimiter.$answer->max;
426 $comment->stranswers[$key] .='<br/>';
427 $correcttrue->correct = $formattedanswer->answer ;
428 $correcttrue->true = $answer->answer ;
429 if ($formattedanswer->answer < $answer->min || $formattedanswer->answer > $answer->max){
430 $comment->outsidelimit = true ;
431 $comment->answers[$key] = $key;
432 $comment->stranswers[$key] .=get_string('trueansweroutsidelimits','qtype_calculated',$correcttrue);//<span class="error">ERROR True answer '..' outside limits</span>';
433 }else {
434 $comment->stranswers[$key] .=get_string('trueanswerinsidelimits','qtype_calculated',$correcttrue);//' True answer :'.$calculated->trueanswer.' inside limits';
435 }
436 $comment->stranswers[$key] .='';
fe6ce234 437 }*/
2d279432
PP
438 }
439 return fullclone($comment);
440 }
441
2d279432
PP
442 function get_correct_responses1(&$question, &$state) {
443 $virtualqtype = $this->get_virtual_qtype( $question);
444 /* if ($question->options->multichoice != 1 ) {
445 if($unit = $virtualqtype->get_default_numerical_unit($question)){
446 $unit = $unit->unit;
447 } else {
448 $unit = '';
449 }
450 foreach ($question->options->answers as $answer) {
451 if (((int) $answer->fraction) === 1) {
452 $answernumerical = qtype_calculated_calculate_answer(
453 $answer->answer, $state->options->dataset, $answer->tolerance,
454 $answer->tolerancetype, $answer->correctanswerlength,
455 $answer->correctanswerformat, ''); // remove unit
456 $correct = array('' => $answernumerical->answer);
457 $correct['answer']= $correct[''];
458 if (isset($correct['']) && $correct[''] != '*' && $unit ) {
459 $correct[''] .= ' '.$unit;
460 $correct['unit']= $unit;
461 }
462 return $correct;
463 }
464 }
fe6ce234
DC
465 }else{**/
466 return $virtualqtype->get_correct_responses($question, $state) ;
467 // }
2d279432
PP
468 return null;
469 }
470
2d279432
PP
471 function get_virtual_qtype() {
472 global $QTYPES;
fe6ce234
DC
473 // if ( isset($question->options->multichoice) && $question->options->multichoice == '1'){
474 $this->virtualqtype =& $QTYPES['multichoice'];
475 // }else {
476 // $this->virtualqtype =& $QTYPES['numerical'];
477 // }
2d279432
PP
478 return $this->virtualqtype;
479 }
480
481
fe6ce234
DC
482 /**
483 * Runs all the code required to set up and save an essay question for testing purposes.
484 * Alternate DB table prefix may be used to facilitate data deletion.
485 */
486 function generate_test($name, $courseid = null) {
487 global $DB;
488 list($form, $question) = parent::generate_test($name, $courseid);
489 $form->feedback = 1;
490 $form->multiplier = array(1, 1);
491 $form->shuffleanswers = 1;
492 $form->noanswers = 1;
493 $form->qtype ='calculatedmulti';
494 $question->qtype ='calculatedmulti';
495 $form->answers = array('{a} + {b}');
496 $form->fraction = array(1);
497 $form->tolerance = array(0.01);
498 $form->tolerancetype = array(1);
499 $form->correctanswerlength = array(2);
500 $form->correctanswerformat = array(1);
501 $form->questiontext = "What is {a} + {b}?";
502
503 if ($courseid) {
504 $course = $DB->get_record('course', array('id'=> $courseid));
505 }
506
507 $new_question = $this->save_question($question, $form, $course);
508
509 $dataset_form = new stdClass();
510 $dataset_form->nextpageparam["forceregeneration"]= 1;
511 $dataset_form->calcmin = array(1 => 1.0, 2 => 1.0);
512 $dataset_form->calcmax = array(1 => 10.0, 2 => 10.0);
513 $dataset_form->calclength = array(1 => 1, 2 => 1);
514 $dataset_form->number = array(1 => 5.4 , 2 => 4.9);
515 $dataset_form->itemid = array(1 => '' , 2 => '');
516 $dataset_form->calcdistribution = array(1 => 'uniform', 2 => 'uniform');
517 $dataset_form->definition = array(1 => "1-0-a",
518 2 => "1-0-b");
519 $dataset_form->nextpageparam = array('forceregeneration' => false);
520 $dataset_form->addbutton = 1;
521 $dataset_form->selectadd = 1;
522 $dataset_form->courseid = $courseid;
523 $dataset_form->cmid = 0;
524 $dataset_form->id = $new_question->id;
525 $this->save_dataset_items($new_question, $dataset_form);
526
527 return $new_question;
528 }
529
530 /**
531 * When move the category of questions, the belonging files should be moved as well
532 * @param object $question, question information
533 * @param object $newcategory, target category information
534 */
535 function move_files($question, $newcategory) {
536 global $DB;
537 // move files belonging to question component
538 parent::move_files($question, $newcategory);
539
540 // move files belonging to qtype_calculatedmulti
541 $fs = get_file_storage();
542 // process files in answer
543 if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
544 $oldanswers = array();
545 }
546 $component = 'question';
547 $filearea = 'answerfeedback';
548 foreach ($oldanswers as $answer) {
549 $files = $fs->get_area_files($question->contextid, $component, $filearea, $answer->id);
550 foreach ($files as $storedfile) {
551 if (!$storedfile->is_directory()) {
7f389342 552 $newfile = new stdClass();
fe6ce234
DC
553 $newfile->contextid = (int)$newcategory->contextid;
554 $fs->create_file_from_storedfile($newfile, $storedfile);
555 $storedfile->delete();
556 }
557 }
558 }
559
560 $component = 'qtype_calculatedmulti';
561 foreach (array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback') as $filearea) {
562 $files = $fs->get_area_files($question->contextid, $component, $filearea, $question->id);
563 foreach ($files as $storedfile) {
564 if (!$storedfile->is_directory()) {
7f389342 565 $newfile = new stdClass();
fe6ce234
DC
566 $newfile->contextid = (int)$newcategory->contextid;
567 $fs->create_file_from_storedfile($newfile, $storedfile);
568 $storedfile->delete();
569 }
570 }
571 }
572 }
573
574 function check_file_access($question, $state, $options, $contextid, $component,
575 $filearea, $args) {
576 $itemid = reset($args);
577
578 if (empty($question->maxgrade)) {
579 $question->maxgrade = $question->defaultgrade;
580 }
581
582 if (in_array($filearea, array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback'))) {
583 $result = $options->feedback && ($itemid == $question->id);
584 if (!$result) {
585 return false;
586 }
587 if ($state->raw_grade >= $question->maxgrade/1.01) {
588 $feedbacktype = 'correctfeedback';
589 } else if ($state->raw_grade > 0) {
590 $feedbacktype = 'partiallycorrectfeedback';
591 } else {
592 $feedbacktype = 'incorrectfeedback';
593 }
594 if ($feedbacktype != $filearea) {
595 return false;
596 }
597 return true;
598 } else if ($component == 'question' && $filearea == 'answerfeedback') {
599 return $options->feedback && (array_key_exists($itemid, $question->options->answers));
600 } else {
601 return parent::check_file_access($question, $state, $options, $contextid, $component,
602 $filearea, $args);
603 }
604 }
2d279432 605}
fe6ce234 606
2d279432
PP
607//// END OF CLASS ////
608
609//////////////////////////////////////////////////////////////////////////
610//// INITIATION - Without this line the question type is not in use... ///
611//////////////////////////////////////////////////////////////////////////
612question_register_questiontype(new question_calculatedmulti_qtype());
34e24cd3
PP
613
614if ( ! defined ("CALCULATEDMULTI")) {
615 define("CALCULATEDMULTI", "calculatedmulti");
616}