Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

merging small modifications from head mostly for calculated questions

  • Loading branch information...
commit edaaa4665579de7bc2c2d029927d07f69169ebea 1 parent c0bea40
pichetp authored

Showing 1 changed file with 108 additions and 119 deletions. Show diff stats Hide diff stats

  1. +108 119 question/format/webct/format.php
227 question/format/webct/format.php
@@ -27,6 +27,10 @@
27 27 ///////////////////////////////////////////////////////////////////////////
28 28
29 29 // Based on format.php, included by ../../import.php
  30 +/**
  31 + * @package questionbank
  32 + * @subpackage importexport
  33 + */
30 34
31 35 function unhtmlentities($string){
32 36 $search = array ("'<script[?>]*?>.*?</script>'si", // remove javascript
@@ -58,91 +62,7 @@ function unhtmlentities($string){
58 62 return preg_replace ($search, $replace, $string);
59 63 }
60 64
61   -class qformat_webct_modified_calculated_qtype extends question_calculated_qtype {
62   -// We need to make a modification of this qtype so that
63   -// it will be able to save webct style calculated questions
64   -// The difference between webct and Moodle is that webct
65   -// pass the individual data items as part of the question
66   -// while Moodle core treat them separately
67 65
68   - function save_question_options($question, $options = false) {
69   -
70   - if (false !== $options) {
71   - // function is called from save_question...
72   - return parent::save_question_options($question, $options);
73   - }
74   -
75   - // function is called from format.php...
76   -
77   - $datasetdatas = $question->datasets;
78   -
79   - // Set dataset
80   - $form->dataset = array();
81   - foreach ($datasetdatas as $datasetname => $notimportant) {
82   - // Literal - question local - name
83   - $form->dataset[] = "1-0-$datasetname";
84   - }
85   -
86   - $subtypeoptions->answers = $question->answers;
87   - $subtypeoptions->units = $question->units;
88   -
89   - unset($question->datasets);
90   - unset($question->answers);
91   - unset($question->units);
92   -
93   - $this->save_question($question, $form, 'not used', $subtypeoptions);
94   -
95   - // Save dataset options and items...
96   -
97   - // Get datasetdefinitions
98   - global $CFG;
99   - $datasetdefs = get_records_sql(
100   - "SELECT a.*
101   - FROM {$CFG->prefix}question_dataset_definitions a,
102   - {$CFG->prefix}question_datasets b
103   - WHERE a.id = b.datasetdefinition
104   - AND b.question = '$question->id' ");
105   -
106   - foreach ($datasetdefs as $datasetdef) {
107   - $datasetdata = $datasetdatas[$datasetdef->name];
108   -
109   - // Set items and retrieve ->itemcout
110   - $item->definition = $datasetdef->id;
111   - for ($item->itemnumber=1 ; isset($datasetdata->items["$item->itemnumber"]) ; ++$item->itemnumber) {
112   - $item->value = $datasetdata->items["$item->itemnumber"];
113   - if (!insert_record('question_dataset_items', $item)) {
114   - error("Unable to insert dataset item $item->itemnumber with $item->value for $datasetdef->name");
115   - }
116   - }
117   - $datasetdef->itemcount = $item->itemnumber - 1;
118   -
119   - // Retrieve ->options
120   - if (is_numeric($datasetdata->min) && is_numeric($datasetdata->max)
121   - && $datasetdata->min <= $datasetdata->max) {
122   - if (is_numeric($datasetdata->dec)) {
123   - $dec = max(0, ceil($datasetdata->dec));
124   - } else {
125   - $dec = 1; // A try
126   - }
127   -
128   - $datasetdef->options = "uniform:$datasetdata->min:$datasetdata->max:$dec";
129   - } else {
130   - $datasetdef->options = '';
131   - }
132   -
133   - // Save definition
134   - if ($datasetdef->itemcount || $datasetdef->options) {
135   - if (!update_record('question_dataset_definitions', $datasetdef)) {
136   - error("Unable to update dataset definition $datasetdef->name on question $question->id");
137   - }
138   - }
139   - }
140   -
141   - // Done
142   - return true;
143   - }
144   -}
145   -$QTYPES[CALCULATED] = new qformat_webct_modified_calculated_qtype();
146 66
147 67 function qformat_webct_convert_formula($formula) {
148 68
@@ -246,7 +166,8 @@ function provide_import() {
246 166 }
247 167
248 168 function readquestions ($lines) {
249   - $qtypecalculated = new qformat_webct_modified_calculated_qtype();
  169 + global $QTYPES ;
  170 + // $qtypecalculated = new qformat_webct_modified_calculated_qtype();
250 171 $webctnumberregex =
251 172 '[+-]?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)((e|E|\\*10\\*\\*)([+-]?[0-9]+|\\([+-]?[0-9]+\\)))?';
252 173
@@ -305,7 +226,7 @@ function readquestions ($lines) {
305 226
306 227 if (isset($feedbacktext) and is_string($feedbacktext)) {
307 228 if (ereg("^:",$line)) {
308   - $question->feedback[$currentchoice] = addslashes(trim($feedbacktext));
  229 + $question->feedback[$currentchoice] = addslashes(trim($feedbacktext));
309 230 unset($feedbacktext);
310 231 }
311 232 else {
@@ -314,6 +235,17 @@ function readquestions ($lines) {
314 235 }
315 236 }
316 237
  238 + if (isset($generalfeedbacktext) and is_string($generalfeedbacktext)) {
  239 + if (ereg("^:",$line)) {
  240 + $question->tempgeneralfeedback= addslashes(trim($generalfeedbacktext));
  241 + unset($generalfeedbacktext);
  242 + }
  243 + else {
  244 + $generalfeedbacktext .= str_replace('\:', ':', $line);
  245 + continue;
  246 + }
  247 + }
  248 +
317 249 $line = trim($line);
318 250
319 251 if (eregi("^:(TYPE|EOF):",$line)) {
@@ -346,11 +278,26 @@ function readquestions ($lines) {
346 278 $QuestionOK = FALSE;
347 279 }
348 280 else {
349   - // Create empty feedback array
350   - $question->feedback = array();
  281 + // Create empty feedback array
351 282 foreach ($question->answer as $key => $dataanswer) {
352   - $question->feedback[$key] = '';
  283 + if(!isset( $question->feedback[$key])){
  284 + $question->feedback[$key] = '';
  285 + }
353 286 }
  287 + // this tempgeneralfeedback allows the code to work with versions from 1.6 to 1.9
  288 + // when question->generalfeedback is undefined, the webct feedback is added to each answer feedback
  289 + if (isset($question->tempgeneralfeedback)){
  290 + if (isset($question->generalfeedback)) {
  291 + $question->generalfeedback = $question->tempgeneralfeedback;
  292 + } else {
  293 + foreach ($question->answer as $key => $dataanswer) {
  294 + if ($question->tempgeneralfeedback !=''){
  295 + $question->feedback[$key] = $question->tempgeneralfeedback.'<br/>'.$question->feedback[$key];
  296 + }
  297 + }
  298 + }
  299 + unset($question->tempgeneralfeedback);
  300 + }
354 301 $maxfraction = -1;
355 302 $totalfraction = 0;
356 303 foreach($question->fraction as $fraction) {
@@ -379,8 +326,7 @@ function readquestions ($lines) {
379 326 }
380 327 } else {
381 328 $totalfraction = round($totalfraction,2);
382   - if ($totalfraction != 1) {
383   - echo "<p>$totalfraction</p>";
  329 + if ($totalfraction != 1) {
384 330 $totalfraction = $totalfraction * 100;
385 331 $errors[] = "'$question->name': ".get_string("wronggrade", "quiz", $nLineCounter).' '.get_string("fractionsaddwrong", "quiz", $totalfraction);
386 332 $QuestionOK = FALSE;
@@ -390,11 +336,27 @@ function readquestions ($lines) {
390 336
391 337 case CALCULATED:
392 338 foreach ($question->answers as $answer) {
393   - if ($formulaerror =qtype_calculated_find_formula_errors($answer->answer)) {
  339 + if ($formulaerror =qtype_calculated_find_formula_errors($answer)) { //$QTYPES['calculated']->
394 340 $warnings[] = "'$question->name': ". $formulaerror;
395 341 $QuestionOK = FALSE;
396 342 }
397 343 }
  344 + foreach ($question->dataset as $dataset) {
  345 + $dataset->itemcount=count($dataset->datasetitem);
  346 + }
  347 + $question->import_process=TRUE ;
  348 + unset($question->answer); //not used in calculated question
  349 + break;
  350 + case MATCH:
  351 + if (count($question->answer) < 3){
  352 + // add a dummy missing question
  353 + $question->name = 'Dummy question added '.$question->name ;
  354 + $question->answer[] = 'dummy';
  355 + $question->subanswers[] = 'dummy';
  356 + $question->subquestions[] = 'dummy';
  357 + $question->fraction[] = '0.0';
  358 + $question->feedback[] = '';
  359 + }
398 360 break;
399 361
400 362 default:
@@ -402,8 +364,8 @@ function readquestions ($lines) {
402 364 }
403 365 }
404 366
405   - if ($QuestionOK) {
406   - // $question->feedback = array();
  367 + if ($QuestionOK) {
  368 + // echo "<pre>"; print_r ($question);
407 369 $questions[] = $question; // store it
408 370 unset($question); // and prepare a new one
409 371 $question = $this->defaultquestion();
@@ -417,6 +379,7 @@ function readquestions ($lines) {
417 379 if (eregi("^:TYPE:MC:1(.*)",$line,$webct_options)) {
418 380 // Multiple Choice Question with only one good answer
419 381 $question = $this->defaultquestion();
  382 + $question->feedback = array();
420 383 $question->qtype = MULTICHOICE;
421 384 $question->single = 1; // Only one answer is allowed
422 385 $ignore_rest_of_question = FALSE;
@@ -426,6 +389,7 @@ function readquestions ($lines) {
426 389 if (eregi("^:TYPE:MC:N(.*)",$line,$webct_options)) {
427 390 // Multiple Choice Question with several good answers
428 391 $question = $this->defaultquestion();
  392 + $question->feedback = array();
429 393 $question->qtype = MULTICHOICE;
430 394 $question->single = 0; // Many answers allowed
431 395 $ignore_rest_of_question = FALSE;
@@ -435,6 +399,7 @@ function readquestions ($lines) {
435 399 if (eregi("^:TYPE:S",$line)) {
436 400 // Short Answer Question
437 401 $question = $this->defaultquestion();
  402 + $question->feedback = array();
438 403 $question->qtype = SHORTANSWER;
439 404 $question->usecase = 0; // Ignore case
440 405 $ignore_rest_of_question = FALSE;
@@ -443,20 +408,23 @@ function readquestions ($lines) {
443 408
444 409 if (eregi("^:TYPE:C",$line)) {
445 410 // Calculated Question
446   - $warnings[] = get_string("calculatedquestion", "quiz", $nLineCounter);
  411 + /* $warnings[] = get_string("calculatedquestion", "quiz", $nLineCounter);
447 412 unset($question);
448 413 $ignore_rest_of_question = TRUE; // Question Type not handled by Moodle
449   - /* $question->qtype = CALCULATED;
  414 + */
  415 + $question = $this->defaultquestion();
  416 + $question->qtype = CALCULATED;
450 417 $question->answers = array(); // No problem as they go as :FORMULA: from webct
451 418 $question->units = array();
452   - $question->datasets = array();
  419 + $question->dataset = array();
453 420
454 421 // To make us pass the end-of-question sanity checks
455 422 $question->answer = array('dummy');
456 423 $question->fraction = array('1.0');
  424 + $question->feedback = array();
457 425
458 426 $currentchoice = -1;
459   - $ignore_rest_of_question = FALSE;*/
  427 + $ignore_rest_of_question = FALSE;
460 428 continue;
461 429 }
462 430
@@ -464,6 +432,7 @@ function readquestions ($lines) {
464 432 // Match Question
465 433 $question = $this->defaultquestion();
466 434 $question->qtype = MATCH;
  435 + $question->feedback = array();
467 436 $ignore_rest_of_question = FALSE; // match question processing is not debugged
468 437 continue;
469 438 }
@@ -517,18 +486,20 @@ function readquestions ($lines) {
517 486 $datasetvalue = qformat_webct_convert_formula($webct_options[4]);
518 487 switch ($webct_options[2]) {
519 488 case 'MIN':
520   - $question->datasets[$datasetname]->min = $datasetvalue;
  489 + $question->dataset[$datasetname]->min = $datasetvalue;
521 490 break;
522 491 case 'MAX':
523   - $question->datasets[$datasetname]->max = $datasetvalue;
  492 + $question->dataset[$datasetname]->max = $datasetvalue;
524 493 break;
525 494 case 'DEC':
526 495 $datasetvalue = floor($datasetvalue); // int only!
527   - $question->datasets[$datasetname]->dec = max(0, $datasetvalue);
  496 + $question->dataset[$datasetname]->length = max(0, $datasetvalue);
528 497 break;
529 498 default:
530 499 // The VAL case:
531   - $question->datasets[$datasetname]->items[$webct_options[3]] = $datasetvalue;
  500 + $question->dataset[$datasetname]->datasetitem[$webct_options[3]] = new stdClass();
  501 + $question->dataset[$datasetname]->datasetitem[$webct_options[3]]->itemnumber = $webct_options[3];
  502 + $question->dataset[$datasetname]->datasetitem[$webct_options[3]]->value = $datasetvalue;
532 503 break;
533 504 }
534 505 continue;
@@ -558,19 +529,23 @@ function readquestions ($lines) {
558 529 if (eregi('^:FORMULA:(.*)', $line, $webct_options)) {
559 530 // Answer for a CALCULATED question
560 531 ++$currentchoice;
561   - $question->answers[$currentchoice]->answer =
  532 + $question->answers[$currentchoice] =
562 533 qformat_webct_convert_formula($webct_options[1]);
563 534
564 535 // Default settings:
565   - $question->answers[$currentchoice]->fraction = 1.0;
566   - $question->answers[$currentchoice]->tolerance = 0.0;
567   - $question->answers[$currentchoice]->tolerancetype = 2; // nominal (units in webct)
568   - $question->answers[$currentchoice]->feedback = '';
569   - $question->answers[$currentchoice]->correctanswerlength = 4;
  536 + $question->fraction[$currentchoice] = 1.0;
  537 + $question->tolerance[$currentchoice] = 0.0;
  538 + $question->tolerancetype[$currentchoice] = 2; // nominal (units in webct)
  539 + $question->feedback[$currentchoice] = '';
  540 + $question->correctanswerlength[$currentchoice] = 4;
570 541
571   - $datasetnames = $qtypecalculated->find_dataset_names($webct_options[1]);
  542 + $datasetnames = $QTYPES[CALCULATED]->find_dataset_names($webct_options[1]);
572 543 foreach ($datasetnames as $datasetname) {
573   - $question->datasets[$datasetname]->items = array();
  544 + $question->dataset[$datasetname] = new stdClass();
  545 + $question->dataset[$datasetname]->datesetitem = array();
  546 + $question->dataset[$datasetname]->name = $datasetname ;
  547 + $question->dataset[$datasetname]->distribution = 'uniform';
  548 + $question->dataset[$datasetname]->status ='private';
574 549 }
575 550 continue;
576 551 }
@@ -593,24 +568,38 @@ function readquestions ($lines) {
593 568 $currentchoice=$webct_options[1];
594 569 continue;
595 570 }
  571 + if (eregi("^:FEEDBACK([0-9]+):?",$line,$webct_options)) {
  572 + $generalfeedbacktext=""; // Start gathering next lines
  573 + $currentchoice=$webct_options[1];
  574 + continue;
  575 + }
  576 + if (eregi('^:FEEDBACK:(.*)',$line,$webct_options)) {
  577 + $generalfeedbacktext=""; // Start gathering next lines
  578 + continue;
  579 + }
  580 + if (eregi('^:LAYOUT:(.*)',$line,$webct_options)) {
  581 + // ignore since layout in question_multichoice is no more used in moodle
  582 + // $webct_options[1] contains either vertical or horizontal ;
  583 + continue;
  584 + }
596 585
597 586 if (isset($question->qtype ) && CALCULATED == $question->qtype && eregi('^:ANS-DEC:([1-9][0-9]*)', $line, $webct_options)) {
598 587 // We can but hope that this always appear before the ANSTYPE property
599   - $question->answers[$currentchoice]->correctanswerlength = $webct_options[1];
  588 + $question->correctanswerlength[$currentchoice] = $webct_options[1];
600 589 continue;
601 590 }
602 591
603 592 if (isset($question->qtype )&& CALCULATED == $question->qtype && eregi("^:TOL:($webctnumberregex)", $line, $webct_options)) {
604 593 // We can but hope that this always appear before the TOL property
605   - $question->answers[$currentchoice]->tolerance =
  594 + $question->tolerance[$currentchoice] =
606 595 qformat_webct_convert_formula($webct_options[1]);
607 596 continue;
608 597 }
609 598
610 599 if (isset($question->qtype )&& CALCULATED == $question->qtype && eregi('^:TOLTYPE:percent', $line)) {
611 600 // Percentage case is handled as relative in Moodle:
612   - $question->answers[$currentchoice]->tolerance /= 100;
613   - $question->answers[$currentchoice]->tolerancetype = 1; // Relative
  601 + $question->tolerance[$currentchoice] /= 100;
  602 + $question->tolerancetype[$currentchoice] = 1; // Relative
614 603 continue;
615 604 }
616 605
@@ -643,11 +632,11 @@ function readquestions ($lines) {
643 632 }
644 633
645 634 if (isset($question->qtype )&& CALCULATED == $question->qtype && eregi('^:ANSTYPE:dec', $line)) {
646   - // Houston - we have a problem
647   - // Moodle does not support this - we try something defensively by
648   - // setting the correct answer length to 5, it shoud be enough for
649   - // most cases
650   - $question->answers[$currentchoice]->correctanswerlength = 5;
  635 + $question->correctanswerformat[$currentchoice]='1';
  636 + continue;
  637 + }
  638 + if (isset($question->qtype )&& CALCULATED == $question->qtype && eregi('^:ANSTYPE:sig', $line)) {
  639 + $question->correctanswerformat[$currentchoice]='2';
651 640 continue;
652 641 }
653 642 }

0 comments on commit edaaa46

Please sign in to comment.
Something went wrong with that request. Please try again.