|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00027 defined('MOODLE_INTERNAL') || die(); 00028 00029 require_once ($CFG->libdir . '/xmlize.php'); 00030 00031 00038 class qformat_blackboard extends qformat_default { 00039 00040 public function provide_import() { 00041 return true; 00042 } 00043 00044 function readquestions ($lines) { 00048 00049 $text = implode($lines, " "); 00050 $xml = xmlize($text, 0); 00051 00052 $questions = array(); 00053 00054 $this->process_tf($xml, $questions); 00055 $this->process_mc($xml, $questions); 00056 $this->process_ma($xml, $questions); 00057 $this->process_fib($xml, $questions); 00058 $this->process_matching($xml, $questions); 00059 $this->process_essay($xml, $questions); 00060 00061 return $questions; 00062 } 00063 00064 //---------------------------------------- 00065 // Process Essay Questions 00066 //---------------------------------------- 00067 function process_essay($xml, &$questions ) { 00068 00069 if (isset($xml["POOL"]["#"]["QUESTION_ESSAY"])) { 00070 $essayquestions = $xml["POOL"]["#"]["QUESTION_ESSAY"]; 00071 } 00072 else { 00073 return; 00074 } 00075 00076 foreach ($essayquestions as $essayquestion) { 00077 00078 $question = $this->defaultquestion(); 00079 00080 $question->qtype = ESSAY; 00081 00082 // determine if the question is already escaped html 00083 $ishtml = $essayquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"]; 00084 00085 // put questiontext in question object 00086 if ($ishtml) { 00087 $question->questiontext = html_entity_decode(trim($essayquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"])); 00088 } 00089 00090 // put name in question object 00091 $question->name = substr($question->questiontext, 0, 254); 00092 $question->answer = ''; 00093 $question->feedback = ''; 00094 $question->fraction = 0; 00095 00096 $questions[] = $question; 00097 } 00098 } 00099 00100 //---------------------------------------- 00101 // Process True / False Questions 00102 //---------------------------------------- 00103 function process_tf($xml, &$questions) { 00104 00105 if (isset($xml["POOL"]["#"]["QUESTION_TRUEFALSE"])) { 00106 $tfquestions = $xml["POOL"]["#"]["QUESTION_TRUEFALSE"]; 00107 } 00108 else { 00109 return; 00110 } 00111 00112 for ($i = 0; $i < sizeof ($tfquestions); $i++) { 00113 00114 $question = $this->defaultquestion(); 00115 00116 $question->qtype = TRUEFALSE; 00117 $question->single = 1; // Only one answer is allowed 00118 00119 $thisquestion = $tfquestions[$i]; 00120 00121 // determine if the question is already escaped html 00122 $ishtml = $thisquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"]; 00123 00124 // put questiontext in question object 00125 if ($ishtml) { 00126 $question->questiontext = html_entity_decode(trim($thisquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"]),ENT_QUOTES,'UTF-8'); 00127 } 00128 // put name in question object 00129 $question->name = shorten_text($question->questiontext, 254); 00130 00131 $choices = $thisquestion["#"]["ANSWER"]; 00132 00133 $correct_answer = $thisquestion["#"]["GRADABLE"][0]["#"]["CORRECTANSWER"][0]["@"]["answer_id"]; 00134 00135 // first choice is true, second is false. 00136 $id = $choices[0]["@"]["id"]; 00137 00138 if (strcmp($id, $correct_answer) == 0) { // true is correct 00139 $question->answer = 1; 00140 $question->feedbacktrue = trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_CORRECT"][0]["#"]); 00141 $question->feedbackfalse = trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_INCORRECT"][0]["#"]); 00142 } else { // false is correct 00143 $question->answer = 0; 00144 $question->feedbacktrue = trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_INCORRECT"][0]["#"]); 00145 $question->feedbackfalse = trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_CORRECT"][0]["#"]); 00146 } 00147 $question->correctanswer = $question->answer; 00148 $questions[] = $question; 00149 } 00150 } 00151 00152 //---------------------------------------- 00153 // Process Multiple Choice Questions 00154 //---------------------------------------- 00155 function process_mc($xml, &$questions) { 00156 00157 if (isset($xml["POOL"]["#"]["QUESTION_MULTIPLECHOICE"])) { 00158 $mcquestions = $xml["POOL"]["#"]["QUESTION_MULTIPLECHOICE"]; 00159 } 00160 else { 00161 return; 00162 } 00163 00164 for ($i = 0; $i < sizeof ($mcquestions); $i++) { 00165 00166 $question = $this->defaultquestion(); 00167 00168 $question->qtype = MULTICHOICE; 00169 $question->single = 1; // Only one answer is allowed 00170 00171 $thisquestion = $mcquestions[$i]; 00172 00173 // determine if the question is already escaped html 00174 $ishtml = $thisquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"]; 00175 00176 // put questiontext in question object 00177 if ($ishtml) { 00178 $question->questiontext = html_entity_decode(trim($thisquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"]),ENT_QUOTES,'UTF-8'); 00179 } 00180 00181 // put name of question in question object, careful of length 00182 $question->name = shorten_text($question->questiontext, 254); 00183 00184 $choices = $thisquestion["#"]["ANSWER"]; 00185 for ($j = 0; $j < sizeof ($choices); $j++) { 00186 00187 $choice = trim($choices[$j]["#"]["TEXT"][0]["#"]); 00188 // put this choice in the question object. 00189 if ($ishtml) { 00190 $question->answer[$j] = html_entity_decode($choice,ENT_QUOTES,'UTF-8'); 00191 } 00192 $question->answer[$j] = $question->answer[$j]; 00193 00194 $id = $choices[$j]["@"]["id"]; 00195 $correct_answer_id = $thisquestion["#"]["GRADABLE"][0]["#"]["CORRECTANSWER"][0]["@"]["answer_id"]; 00196 // if choice is the answer, give 100%, otherwise give 0% 00197 if (strcmp ($id, $correct_answer_id) == 0) { 00198 $question->fraction[$j] = 1; 00199 if ($ishtml) { 00200 $question->feedback[$j] = html_entity_decode(trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_CORRECT"][0]["#"]),ENT_QUOTES,'UTF-8'); 00201 } 00202 $question->feedback[$j] = $question->feedback[$j]; 00203 } else { 00204 $question->fraction[$j] = 0; 00205 if ($ishtml) { 00206 $question->feedback[$j] = html_entity_decode(trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_INCORRECT"][0]["#"]),ENT_QUOTES,'UTF-8'); 00207 } 00208 $question->feedback[$j] = $question->feedback[$j]; 00209 } 00210 } 00211 $questions[] = $question; 00212 } 00213 } 00214 00215 //---------------------------------------- 00216 // Process Multiple Choice Questions With Multiple Answers 00217 //---------------------------------------- 00218 function process_ma($xml, &$questions) { 00219 00220 if (isset($xml["POOL"]["#"]["QUESTION_MULTIPLEANSWER"])) { 00221 $maquestions = $xml["POOL"]["#"]["QUESTION_MULTIPLEANSWER"]; 00222 } 00223 else { 00224 return; 00225 } 00226 00227 for ($i = 0; $i < sizeof ($maquestions); $i++) { 00228 00229 $question = $this->defaultquestion(); 00230 00231 $question->qtype = MULTICHOICE; 00232 $question->defaultmark = 1; 00233 $question->single = 0; // More than one answers allowed 00234 $question->image = ""; // No images with this format 00235 00236 $thisquestion = $maquestions[$i]; 00237 00238 // determine if the question is already escaped html 00239 $ishtml = $thisquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"]; 00240 00241 // put questiontext in question object 00242 if ($ishtml) { 00243 $question->questiontext = html_entity_decode(trim($thisquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"]),ENT_QUOTES,'UTF-8'); 00244 } 00245 // put name of question in question object 00246 $question->name = shorten_text($question->questiontext, 254); 00247 00248 $choices = $thisquestion["#"]["ANSWER"]; 00249 $correctanswers = $thisquestion["#"]["GRADABLE"][0]["#"]["CORRECTANSWER"]; 00250 00251 for ($j = 0; $j < sizeof ($choices); $j++) { 00252 00253 $choice = trim($choices[$j]["#"]["TEXT"][0]["#"]); 00254 // put this choice in the question object. 00255 $question->answer[$j] = $choice; 00256 00257 $correctanswercount = sizeof($correctanswers); 00258 $id = $choices[$j]["@"]["id"]; 00259 $iscorrect = 0; 00260 for ($k = 0; $k < $correctanswercount; $k++) { 00261 00262 $correct_answer_id = trim($correctanswers[$k]["@"]["answer_id"]); 00263 if (strcmp ($id, $correct_answer_id) == 0) { 00264 $iscorrect = 1; 00265 } 00266 00267 } 00268 if ($iscorrect) { 00269 $question->fraction[$j] = floor(100000/$correctanswercount)/100000; // strange behavior if we have more than 5 decimal places 00270 $question->feedback[$j] = trim($thisquestion["#"]["GRADABLE"][$j]["#"]["FEEDBACK_WHEN_CORRECT"][0]["#"]); 00271 } else { 00272 $question->fraction[$j] = 0; 00273 $question->feedback[$j] = trim($thisquestion["#"]["GRADABLE"][$j]["#"]["FEEDBACK_WHEN_INCORRECT"][0]["#"]); 00274 } 00275 } 00276 00277 $questions[] = $question; 00278 } 00279 } 00280 00281 //---------------------------------------- 00282 // Process Fill in the Blank Questions 00283 //---------------------------------------- 00284 function process_fib($xml, &$questions) { 00285 00286 if (isset($xml["POOL"]["#"]["QUESTION_FILLINBLANK"])) { 00287 $fibquestions = $xml["POOL"]["#"]["QUESTION_FILLINBLANK"]; 00288 } 00289 else { 00290 return; 00291 } 00292 00293 for ($i = 0; $i < sizeof ($fibquestions); $i++) { 00294 $question = $this->defaultquestion(); 00295 00296 $question->qtype = SHORTANSWER; 00297 $question->usecase = 0; // Ignore case 00298 00299 $thisquestion = $fibquestions[$i]; 00300 00301 // determine if the question is already escaped html 00302 $ishtml = $thisquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"]; 00303 00304 // put questiontext in question object 00305 if ($ishtml) { 00306 $question->questiontext = html_entity_decode(trim($thisquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"]),ENT_QUOTES,'UTF-8'); 00307 } 00308 // put name of question in question object 00309 $question->name = shorten_text($question->questiontext, 254); 00310 00311 $answer = trim($thisquestion["#"]["ANSWER"][0]["#"]["TEXT"][0]["#"]); 00312 00313 $question->answer[] = $answer; 00314 $question->fraction[] = 1; 00315 $question->feedback = array(); 00316 00317 if (is_array( $thisquestion['#']['GRADABLE'][0]['#'] )) { 00318 $question->feedback[0] = trim($thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_CORRECT"][0]["#"]); 00319 } 00320 else { 00321 $question->feedback[0] = ''; 00322 } 00323 if (is_array( $thisquestion["#"]["GRADABLE"][0]["#"] )) { 00324 $question->feedback[1] = trim($thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_INCORRECT"][0]["#"]); 00325 } 00326 else { 00327 $question->feedback[1] = ''; 00328 } 00329 00330 $questions[] = $question; 00331 } 00332 } 00333 00334 //---------------------------------------- 00335 // Process Matching Questions 00336 //---------------------------------------- 00337 function process_matching($xml, &$questions) { 00338 00339 if (isset($xml["POOL"]["#"]["QUESTION_MATCH"])) { 00340 $matchquestions = $xml["POOL"]["#"]["QUESTION_MATCH"]; 00341 } 00342 else { 00343 return; 00344 } 00345 00346 for ($i = 0; $i < sizeof ($matchquestions); $i++) { 00347 00348 $question = $this->defaultquestion(); 00349 00350 $question->qtype = MATCH; 00351 00352 $thisquestion = $matchquestions[$i]; 00353 00354 // determine if the question is already escaped html 00355 $ishtml = $thisquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"]; 00356 00357 // put questiontext in question object 00358 if ($ishtml) { 00359 $question->questiontext = html_entity_decode(trim($thisquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"]),ENT_QUOTES,'UTF-8'); 00360 } 00361 // put name of question in question object 00362 $question->name = shorten_text($question->questiontext, 254); 00363 00364 $choices = $thisquestion["#"]["CHOICE"]; 00365 for ($j = 0; $j < sizeof ($choices); $j++) { 00366 00367 $subquestion = NULL; 00368 00369 $choice = $choices[$j]["#"]["TEXT"][0]["#"]; 00370 $choice_id = $choices[$j]["@"]["id"]; 00371 00372 $question->subanswers[] = trim($choice); 00373 00374 $correctanswers = $thisquestion["#"]["GRADABLE"][0]["#"]["CORRECTANSWER"]; 00375 for ($k = 0; $k < sizeof ($correctanswers); $k++) { 00376 00377 if (strcmp($choice_id, $correctanswers[$k]["@"]["choice_id"]) == 0) { 00378 00379 $answer_id = $correctanswers[$k]["@"]["answer_id"]; 00380 00381 $answers = $thisquestion["#"]["ANSWER"]; 00382 for ($m = 0; $m < sizeof ($answers); $m++) { 00383 00384 $answer = $answers[$m]; 00385 $current_ans_id = $answer["@"]["id"]; 00386 if (strcmp ($current_ans_id, $answer_id) == 0) { 00387 00388 $answer = $answer["#"]["TEXT"][0]["#"]; 00389 $question->subquestions[] = trim($answer); 00390 break; 00391 } 00392 } 00393 break; 00394 } 00395 } 00396 } 00397 00398 $questions[] = $question; 00399 00400 } 00401 } 00402 }