]> git.mjollnir.org Git - moodle.git/commitdiff
Addition code to handle 'multianswerchoice' type Learnwise questions.
authorthepurpleblob <thepurpleblob>
Thu, 27 Jan 2005 11:22:45 +0000 (11:22 +0000)
committerthepurpleblob <thepurpleblob>
Thu, 27 Jan 2005 11:22:45 +0000 (11:22 +0000)
mod/quiz/format/learnwise/format.php

index ce0fcc0816a96dca8b2b7c2d933b61b3c10e4f8e..363f69e9e205b452c276dc20eb0078aeda59e509 100755 (executable)
-<?PHP  // $Id$ \r
-// Alton College, Hampshire, UK - Tom Flannaghan\r
-// Imports learnwise multiple choice quizzes\r
+<?php    // $Id$ \r
+// Alton College, Hampshire, UK - Tom Flannaghan, Andrew Walker\r
+// Imports learnwise multiple choice quizzes (single and multiple answers)\r
+// currently ignores the deduct attribute for multiple answer questions\r
+// deductions are currently simply found by dividing the award for the incorrect \r
+// answer by the total number of options\r
 // Based on format.php, included by ../../import.php\r
 \r
-function string_between($text, $start, $end)\r
-{\r
-       $startpos = strpos($text, $start) + strlen($start);\r
-       $endpos = strpos($text, $end);\r
-       \r
-       if($startpos <= $endpos) return substr($text, $startpos, $endpos - $startpos);\r
-}\r
-       \r
-       \r
-\r
 class quiz_file_format extends quiz_default_format {\r
 \r
-       function readquestions($lines) {\r
+    function readquestions($lines) {\r
         $questions = array();\r
         $currentquestion = array();\r
                \r
-               foreach($lines as $line) {\r
-                       $line = trim($line);\r
-                       $currentquestion[] = $line;\r
+        foreach($lines as $line) {\r
+            $line = trim($line);\r
+            $currentquestion[] = $line;\r
                        \r
-                       if($question = $this->readquestion($currentquestion)) {\r
-                               $questions[] = $question;\r
-                               $currentquestion = array();\r
-                       }\r
-               }\r
-                               \r
-               return $questions;\r
-       }\r
-\r
-        function unhtmlentities($string)\r
-        // puts all the &gt; etc stuff back to 'normal' \r
-        // good for PHP 4.1.0 on\r
-        {\r
-          $trans_tbl = get_html_translation_table(HTML_ENTITIES);\r
-          $trans_tbl = array_flip($trans_tbl);\r
-          return strtr($string, $trans_tbl);\r
-        }\r
+            if ($question = $this->readquestion($currentquestion)) {\r
+                $questions[] = $question;\r
+                $currentquestion = array();\r
+            }\r
+        }                              \r
+        return $questions;\r
+    }\r
 \r
     function readquestion($lines) {\r
-               $text = '';\r
-               foreach ($lines as $line) $text .= $line;\r
-               $text = str_replace(array('\t','\n','\r','\''), array('','','','\\\''), $text);\r
-               $len = strlen($text);\r
-\r
-               $question = NULL;\r
-\r
-               if($questiontype = sscanf($text, '<question type="%s">'))\r
-               {\r
-                       if($pos = stripos($text, '</question>'))\r
-                       {\r
-                               $text = substr($text, 0, $pos);\r
-                               $text = stristr($text, '<question');\r
-                               \r
-                               $questiontext = '';\r
-                               $questionaward = '';\r
-                               $questionhint = '';\r
-                               $optionlist = '';\r
-                               $questiontext = string_between($text, '<text>', '</text>');\r
-                               $questionaward = string_between($text, '<award>', '</award>');\r
-                               $questionhint = string_between($text, '<hint>', '</hint>');\r
-                               $optionlist = string_between($text, '<answer>', '</answer>');\r
-                               \r
-                               $optionlist = explode('<option', $optionlist);\r
-                               $n=0;\r
-                               \r
-                               foreach($optionlist as $option)\r
-                               {\r
-                                       $a = string_between($option, ' correct="', '">');\r
-                                       $b = string_between($option, '">', '</option>');\r
-                                       \r
-                                       $options_correct[$n] = $a; $options_text[$n] = $b;\r
-                                       //echo "$a, $b<br>";\r
-                                       $n++;\r
-                                       \r
-                               }\r
-                               \r
-                               $question->qtype = MULTICHOICE;\r
-                               $question->name = substr($this->unhtmlentities($questiontext),0,30);\r
-                               if(strlen($questionlen)<30) $question->name .= '...';\r
-                               $question->questiontext = $this->unhtmlentities($questiontext);\r
-                               $question->single = 1;\r
-                               $question->feedback[] = '';\r
-                               $question->usecase = 0;\r
-                               $question->defaultgrade = 1;\r
-                               $question->image = '';\r
-                               \r
-                               for($n=0; $n<sizeof($options_text); $n++)\r
-                               {\r
-                                       if($options_text[$n])\r
-                                       {\r
-                                               if($options_correct[$n]=='yes') $fraction = (int) $questionaward; else $fraction = 0;\r
-                                               $question->fraction[] = $fraction;\r
-                                               $question->answer[] = $this->unhtmlentities($options_text[$n]);\r
-                                               //echo "hello: $options_text[$n], $fraction<br>";\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-               \r
+        $text = implode(' ', $lines);\r
+        $text = str_replace(array('\t','\n','\r','\''), array('','','','\\\''), $text);\r
+\r
+        $startpos = strpos($text, '<question type');\r
+        $endpos = strpos($text, '</question>');\r
+        if ($startpos === false || $endpos === false) {\r
+            return false;\r
+        }\r
+\r
+        preg_match("/<question type=[\"\']([^\"\']+)[\"\']>/i", $text, $matches);\r
+        $type = strtolower($matches[1]); // multichoice or multianswerchoice\r
+\r
+        $questiontext = $this->unhtmlentities($this->stringbetween($text, '<text>', '</text>'));\r
+        $questionhint = $this->unhtmlentities($this->stringbetween($text, '<hint>', '</hint>'));\r
+        $questionaward = $this->stringbetween($text, '<award>', '</award>');\r
+        $optionlist = $this->stringbetween($text, '<answer>', '</answer>');\r
+\r
+        $optionlist = explode('<option', $optionlist);\r
+\r
+        $n = 0;\r
+\r
+        $optionscorrect = array();\r
+        $optionstext = array();\r
+\r
+        if ($type == 'multichoice') {\r
+            foreach ($optionlist as $option) {\r
+                $correct = $this->stringbetween($option, ' correct="', '">');\r
+                $answer = $this->stringbetween($option, '">', '</option>');\r
+                $optionscorrect[$n] = $correct; \r
+                $optionstext[$n] = $this->unhtmlentities($answer);\r
+                ++$n;\r
+            }\r
+        } else if ($type == 'multianswerchoice') {\r
+            $numcorrect = 0;\r
+            $totalaward = 0;\r
+\r
+            $optionsaward = array();\r
+\r
+            foreach ($optionlist as $option) {\r
+                preg_match("/correct=\"([^\"]*)\"/i", $option, $correctmatch);\r
+                preg_match("/award=\"([^\"]*)\"/i", $option, $awardmatch);\r
+\r
+                $correct = $correctmatch[1];\r
+                $award = $awardmatch[1];\r
+                if ($correct == 'yes') {\r
+                    $totalaward += $award;\r
+                    ++$numcorrect;\r
+                }\r
+\r
+                $answer = $this->stringbetween($option, '">', '</option>');\r
+\r
+                $optionscorrect[$n] = $correct; \r
+                $optionstext[$n] = $this->unhtmlentities($answer);\r
+                $optionsaward[$n] = $award;\r
+                ++$n;\r
+            }\r
+\r
+        } else {\r
+            echo "<p>I don't understand this question type (type = <strong>$type</strong>).</p>\n";\r
+        }\r
+\r
+        $question->qtype = MULTICHOICE;\r
+        $question->name = substr($questiontext, 0, 30);\r
+        if (strlen($questiontext) > 30) {\r
+            $question->name .= '...';\r
+        }\r
+\r
+        $question->questiontext = $questiontext;\r
+        $question->single = ($type == 'multichoice') ? 1 : 0;\r
+        $question->feedback[] = '';\r
+        $question->usecase = 0;\r
+        $question->defaultgrade = 1;\r
+        $question->image = '';\r
+                       \r
+        $question->fraction = array();\r
+        $question->answer = array();\r
+        for ($n = 0; $n < count($optionstext); ++$n) {\r
+            if ($optionstext[$n]) {\r
+                if (!isset($numcorrect)) { // single answer\r
+                    if ($optionscorrect[$n] == 'yes') {\r
+                        $fraction = (int) $questionaward; \r
+                    } else {\r
+                        $fraction = 0;\r
+                    } \r
+                } else { // mulitple answers\r
+                    if ($optionscorrect[$n] == 'yes') {\r
+                        $fraction = $optionsaward[$n] / $totalaward; \r
+                    } else {\r
+                        $fraction = -$optionsaward[$n] / count($optionstext);\r
+                    }\r
+                }\r
+                $question->fraction[] = $fraction;\r
+                $question->answer[] = $optionstext[$n];\r
+            }\r
+        }\r
+\r
         return $question;\r
     }\r
+\r
+    function stringbetween($text, $start, $end) {\r
+        $startpos = strpos($text, $start) + strlen($start);\r
+        $endpos = strpos($text, $end);\r
+       \r
+        if ($startpos <= $endpos) {\r
+            return substr($text, $startpos, $endpos - $startpos);\r
+        }\r
+    }\r
+\r
+    function unhtmlentities($string) {\r
+        $transtable = get_html_translation_table(HTML_ENTITIES);\r
+        $transtable = array_flip($transtable);\r
+        return strtr($string, $transtable);\r
+    } \r
+\r
 }\r
 \r
 ?>\r