Merge branch 'w51_MDL-37281_m23_othersnav' of git://github.com/skodak/moodle into...
[moodle.git] / question / format / learnwise / format.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Examview question importer.
19  *
20  * @package    qformat
21  * @subpackage learnwise
22  * @copyright  2005 Alton College, Hampshire, UK
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
27 defined('MOODLE_INTERNAL') || die();
30 /**
31  * Examview question importer.
32  *
33  * Alton College, Hampshire, UK - Tom Flannaghan, Andrew Walker
34  *
35  * Imports learnwise multiple choice questions (single and multiple answers)
36  * currently ignores the deduct attribute for multiple answer questions
37  * deductions are currently simply found by dividing the award for the incorrect
38  * answer by the total number of options
39  *
40  * @copyright  2005 Alton College, Hampshire, UK
41  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42  */
43 class qformat_learnwise extends qformat_default {
45     function provide_import() {
46         return true;
47     }
49     protected function readquestions($lines) {
50         $questions = array();
51         $currentquestion = array();
53         foreach($lines as $line) {
54             $line = trim($line);
55             $currentquestion[] = $line;
57             if ($question = $this->readquestion($currentquestion)) {
58                 $questions[] = $question;
59                 $currentquestion = array();
60             }
61         }
62         return $questions;
63     }
65     function readquestion($lines) {
66         $text = implode(' ', $lines);
67         $text = str_replace(array('\t','\n','\r','\''), array('','','','\\\''), $text);
69         $startpos = strpos($text, '<question type');
70         $endpos = strpos($text, '</question>');
71         if ($startpos === false || $endpos === false) {
72             return false;
73         }
75         preg_match("/<question type=[\"\']([^\"\']+)[\"\']>/i", $text, $matches);
76         $type = strtolower($matches[1]); // multichoice or multianswerchoice
78         $questiontext = $this->unhtmlentities($this->stringbetween($text, '<text>', '</text>'));
79         $questionhint = $this->unhtmlentities($this->stringbetween($text, '<hint>', '</hint>'));
80         $questionaward = $this->stringbetween($text, '<award>', '</award>');
81         $optionlist = $this->stringbetween($text, '<answer>', '</answer>');
83         $optionlist = explode('<option', $optionlist);
85         $n = 0;
87         $optionscorrect = array();
88         $optionstext = array();
90         if ($type == 'multichoice') {
91             foreach ($optionlist as $option) {
92                 $correct = $this->stringbetween($option, ' correct="', '">');
93                 $answer = $this->stringbetween($option, '">', '</option>');
94                 $optionscorrect[$n] = $correct;
95                 $optionstext[$n] = $this->unhtmlentities($answer);
96                 ++$n;
97             }
98         } else if ($type == 'multianswerchoice') {
99             $numcorrect = 0;
100             $totalaward = 0;
102             $optionsaward = array();
104             foreach ($optionlist as $option) {
105                 preg_match("/correct=\"([^\"]*)\"/i", $option, $correctmatch);
106                 preg_match("/award=\"([^\"]*)\"/i", $option, $awardmatch);
108                 $correct = $correctmatch[1];
109                 $award = $awardmatch[1];
110                 if ($correct == 'yes') {
111                     $totalaward += $award;
112                     ++$numcorrect;
113                 }
115                 $answer = $this->stringbetween($option, '">', '</option>');
117                 $optionscorrect[$n] = $correct;
118                 $optionstext[$n] = $this->unhtmlentities($answer);
119                 $optionsaward[$n] = $award;
120                 ++$n;
121             }
123         } else {
124             echo "<p>I don't understand this question type (type = <strong>$type</strong>).</p>\n";
125         }
127         $question = $this->defaultquestion();
128         $question->qtype = MULTICHOICE;
129         $question->name = $this->create_default_question_name($questiontext, get_string('questionname', 'question'));
131         $question->questiontext = $questiontext;
132         $question->single = ($type == 'multichoice') ? 1 : 0;
133         $question->feedback[] = '';
135         $question->fraction = array();
136         $question->answer = array();
137         for ($n = 0; $n < count($optionstext); ++$n) {
138             if ($optionstext[$n]) {
139                 if (!isset($numcorrect)) { // single answer
140                     if ($optionscorrect[$n] == 'yes') {
141                         $fraction = (int) $questionaward;
142                     } else {
143                         $fraction = 0;
144                     }
145                 } else { // mulitple answers
146                     if ($optionscorrect[$n] == 'yes') {
147                         $fraction = $optionsaward[$n] / $totalaward;
148                     } else {
149                         $fraction = -$optionsaward[$n] / count($optionstext);
150                     }
151                 }
152                 $question->fraction[] = $fraction;
153                 $question->answer[] = $optionstext[$n];
154                 $question->feedback[] = ''; // no feedback in this type
155             }
156         }
158         return $question;
159     }
161     function stringbetween($text, $start, $end) {
162         $startpos = strpos($text, $start) + strlen($start);
163         $endpos = strpos($text, $end);
165         if ($startpos <= $endpos) {
166             return substr($text, $startpos, $endpos - $startpos);
167         }
168     }
170     function unhtmlentities($string) {
171         $transtable = get_html_translation_table(HTML_ENTITIES);
172         $transtable = array_flip($transtable);
173         return strtr($string, $transtable);
174     }