PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/question/format/blackboard/format.php

https://github.com/henriquecrang/e-UNI
PHP | 432 lines | 247 code | 97 blank | 88 comment | 50 complexity | 2e3f7dda4bf998df17cc970087e97d57 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0, BSD-3-Clause
  1. <?php // $Id: format.php,v 1.12.4.2 2008/08/28 10:04:23 thepurpleblob Exp $
  2. ////////////////////////////////////////////////////////////////////////////
  3. /// Blackboard 6.0 Format
  4. ///
  5. /// This Moodle class provides all functions necessary to import and export
  6. ///
  7. ///
  8. ////////////////////////////////////////////////////////////////////////////
  9. // Based on default.php, included by ../import.php
  10. /**
  11. * @package questionbank
  12. * @subpackage importexport
  13. */
  14. require_once ("$CFG->libdir/xmlize.php");
  15. require_once ("$CFG->libdir/tcpdf/html_entity_decode_php4.php");
  16. class qformat_blackboard extends qformat_default {
  17. function provide_import() {
  18. return true;
  19. }
  20. /********************************
  21. function readdata($filename) {
  22. /// Returns complete file with an array, one item per line
  23. if (is_readable($filename)) {
  24. $zip = zip_open($filename);
  25. $zip_entry = $zip_read($zip);
  26. if (strstr($zip_entry_name($zip_entry), "imsmanifest") == 0)
  27. $zip_entry = $zip_read($zip); // skip past manifest file
  28. if (zip_entry_open($zip, $zip_entry, "r")) {
  29. $strbuf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
  30. $buf = explode("\n", $strbuf);
  31. zip_entry_close($zip_entry);
  32. zip_close($zip);
  33. return $buf;
  34. } else {
  35. zip_close($zip);
  36. return false;
  37. }
  38. }
  39. return false;
  40. }
  41. ********************************/
  42. function readquestions ($lines) {
  43. /// Parses an array of lines into an array of questions,
  44. /// where each item is a question object as defined by
  45. /// readquestion().
  46. $text = implode($lines, " ");
  47. $xml = xmlize($text, 0);
  48. $questions = array();
  49. $this->process_tf($xml, $questions);
  50. $this->process_mc($xml, $questions);
  51. $this->process_ma($xml, $questions);
  52. $this->process_fib($xml, $questions);
  53. $this->process_matching($xml, $questions);
  54. $this->process_essay($xml, $questions);
  55. return $questions;
  56. }
  57. //----------------------------------------
  58. // Process Essay Questions
  59. //----------------------------------------
  60. function process_essay($xml, &$questions ) {
  61. if (isset($xml["POOL"]["#"]["QUESTION_ESSAY"])) {
  62. $essayquestions = $xml["POOL"]["#"]["QUESTION_ESSAY"];
  63. }
  64. else {
  65. return;
  66. }
  67. foreach ($essayquestions as $essayquestion) {
  68. $question = $this->defaultquestion();
  69. $question->qtype = ESSAY;
  70. // determine if the question is already escaped html
  71. $ishtml = $essayquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"];
  72. // put questiontext in question object
  73. if ($ishtml) {
  74. $question->questiontext = html_entity_decode_php4(trim($essayquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"]));
  75. }
  76. $question->questiontext = addslashes($question->questiontext);
  77. // put name in question object
  78. $question->name = substr($question->questiontext, 0, 254);
  79. $question->answer = '';
  80. $question->feedback = '';
  81. $question->fraction = 0;
  82. $questions[] = $question;
  83. }
  84. }
  85. //----------------------------------------
  86. // Process True / False Questions
  87. //----------------------------------------
  88. function process_tf($xml, &$questions) {
  89. if (isset($xml["POOL"]["#"]["QUESTION_TRUEFALSE"])) {
  90. $tfquestions = $xml["POOL"]["#"]["QUESTION_TRUEFALSE"];
  91. }
  92. else {
  93. return;
  94. }
  95. for ($i = 0; $i < sizeof ($tfquestions); $i++) {
  96. $question = $this->defaultquestion();
  97. $question->qtype = TRUEFALSE;
  98. $question->single = 1; // Only one answer is allowed
  99. $thisquestion = $tfquestions[$i];
  100. // determine if the question is already escaped html
  101. $ishtml = $thisquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"];
  102. // put questiontext in question object
  103. if ($ishtml) {
  104. $question->questiontext = html_entity_decode_php4(trim($thisquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"]));
  105. }
  106. $question->questiontext = addslashes($question->questiontext);
  107. // put name in question object
  108. $question->name = substr($question->questiontext, 0, 254);
  109. $choices = $thisquestion["#"]["ANSWER"];
  110. $correct_answer = $thisquestion["#"]["GRADABLE"][0]["#"]["CORRECTANSWER"][0]["@"]["answer_id"];
  111. // first choice is true, second is false.
  112. $id = $choices[0]["@"]["id"];
  113. if (strcmp($id, $correct_answer) == 0) { // true is correct
  114. $question->answer = 1;
  115. $question->feedbacktrue = addslashes(trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_CORRECT"][0]["#"]));
  116. $question->feedbackfalse = addslashes(trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_INCORRECT"][0]["#"]));
  117. } else { // false is correct
  118. $question->answer = 0;
  119. $question->feedbacktrue = addslashes(trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_INCORRECT"][0]["#"]));
  120. $question->feedbackfalse = addslashes(trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_CORRECT"][0]["#"]));
  121. }
  122. $question->correctanswer = $question->answer;
  123. $questions[] = $question;
  124. }
  125. }
  126. //----------------------------------------
  127. // Process Multiple Choice Questions
  128. //----------------------------------------
  129. function process_mc($xml, &$questions) {
  130. if (isset($xml["POOL"]["#"]["QUESTION_MULTIPLECHOICE"])) {
  131. $mcquestions = $xml["POOL"]["#"]["QUESTION_MULTIPLECHOICE"];
  132. }
  133. else {
  134. return;
  135. }
  136. for ($i = 0; $i < sizeof ($mcquestions); $i++) {
  137. $question = $this->defaultquestion();
  138. $question->qtype = MULTICHOICE;
  139. $question->single = 1; // Only one answer is allowed
  140. $thisquestion = $mcquestions[$i];
  141. // determine if the question is already escaped html
  142. $ishtml = $thisquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"];
  143. // put questiontext in question object
  144. if ($ishtml) {
  145. $question->questiontext = html_entity_decode_php4(trim($thisquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"]));
  146. }
  147. $question->questiontext = addslashes($question->questiontext);
  148. // put name of question in question object, careful of length
  149. $question->name = substr($question->questiontext, 0, 254);
  150. $choices = $thisquestion["#"]["ANSWER"];
  151. for ($j = 0; $j < sizeof ($choices); $j++) {
  152. $choice = trim($choices[$j]["#"]["TEXT"][0]["#"]);
  153. // put this choice in the question object.
  154. if ($ishtml) {
  155. $question->answer[$j] = html_entity_decode_php4($choice);
  156. }
  157. $question->answer[$j] = addslashes($question->answer[$j]);
  158. $id = $choices[$j]["@"]["id"];
  159. $correct_answer_id = $thisquestion["#"]["GRADABLE"][0]["#"]["CORRECTANSWER"][0]["@"]["answer_id"];
  160. // if choice is the answer, give 100%, otherwise give 0%
  161. if (strcmp ($id, $correct_answer_id) == 0) {
  162. $question->fraction[$j] = 1;
  163. if ($ishtml) {
  164. $question->feedback[$j] = html_entity_decode_php4(trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_CORRECT"][0]["#"]));
  165. }
  166. $question->feedback[$j] = addslashes($question->feedback[$j]);
  167. } else {
  168. $question->fraction[$j] = 0;
  169. if ($ishtml) {
  170. $question->feedback[$j] = html_entity_decode_php4(trim(@$thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_INCORRECT"][0]["#"]));
  171. }
  172. $question->feedback[$j] = addslashes($question->feedback[$j]);
  173. }
  174. }
  175. $questions[] = $question;
  176. }
  177. }
  178. //----------------------------------------
  179. // Process Multiple Choice Questions With Multiple Answers
  180. //----------------------------------------
  181. function process_ma($xml, &$questions) {
  182. if (isset($xml["POOL"]["#"]["QUESTION_MULTIPLEANSWER"])) {
  183. $maquestions = $xml["POOL"]["#"]["QUESTION_MULTIPLEANSWER"];
  184. }
  185. else {
  186. return;
  187. }
  188. for ($i = 0; $i < sizeof ($maquestions); $i++) {
  189. $question = $this->defaultquestion();
  190. $question->qtype = MULTICHOICE;
  191. $question->defaultgrade = 1;
  192. $question->single = 0; // More than one answers allowed
  193. $question->image = ""; // No images with this format
  194. $thisquestion = $maquestions[$i];
  195. // determine if the question is already escaped html
  196. $ishtml = $thisquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"];
  197. // put questiontext in question object
  198. if ($ishtml) {
  199. $question->questiontext = html_entity_decode_php4(trim($thisquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"]));
  200. }
  201. $question->questiontext = addslashes($question->questiontext);
  202. // put name of question in question object
  203. $question->name = substr($question->questiontext, 0, 254);
  204. $choices = $thisquestion["#"]["ANSWER"];
  205. $correctanswers = $thisquestion["#"]["GRADABLE"][0]["#"]["CORRECTANSWER"];
  206. for ($j = 0; $j < sizeof ($choices); $j++) {
  207. $choice = trim($choices[$j]["#"]["TEXT"][0]["#"]);
  208. // put this choice in the question object.
  209. $question->answer[$j] = addslashes($choice);
  210. $correctanswercount = sizeof($correctanswers);
  211. $id = $choices[$j]["@"]["id"];
  212. $iscorrect = 0;
  213. for ($k = 0; $k < $correctanswercount; $k++) {
  214. $correct_answer_id = trim($correctanswers[$k]["@"]["answer_id"]);
  215. if (strcmp ($id, $correct_answer_id) == 0) {
  216. $iscorrect = 1;
  217. }
  218. }
  219. if ($iscorrect) {
  220. $question->fraction[$j] = floor(100000/$correctanswercount)/100000; // strange behavior if we have more than 5 decimal places
  221. $question->feedback[$j] = addslashes(trim($thisquestion["#"]["GRADABLE"][$j]["#"]["FEEDBACK_WHEN_CORRECT"][0]["#"]));
  222. } else {
  223. $question->fraction[$j] = 0;
  224. $question->feedback[$j] = addslashes(trim($thisquestion["#"]["GRADABLE"][$j]["#"]["FEEDBACK_WHEN_INCORRECT"][0]["#"]));
  225. }
  226. }
  227. $questions[] = $question;
  228. }
  229. }
  230. //----------------------------------------
  231. // Process Fill in the Blank Questions
  232. //----------------------------------------
  233. function process_fib($xml, &$questions) {
  234. if (isset($xml["POOL"]["#"]["QUESTION_FILLINBLANK"])) {
  235. $fibquestions = $xml["POOL"]["#"]["QUESTION_FILLINBLANK"];
  236. }
  237. else {
  238. return;
  239. }
  240. for ($i = 0; $i < sizeof ($fibquestions); $i++) {
  241. $question = $this->defaultquestion();
  242. $question->qtype = SHORTANSWER;
  243. $question->usecase = 0; // Ignore case
  244. $thisquestion = $fibquestions[$i];
  245. // determine if the question is already escaped html
  246. $ishtml = $thisquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"];
  247. // put questiontext in question object
  248. if ($ishtml) {
  249. $question->questiontext = html_entity_decode_php4(trim($thisquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"]));
  250. }
  251. $question->questiontext = addslashes($question->questiontext);
  252. // put name of question in question object
  253. $question->name = substr($question->questiontext, 0, 254);
  254. $answer = trim($thisquestion["#"]["ANSWER"][0]["#"]["TEXT"][0]["#"]);
  255. $question->answer[] = addslashes($answer);
  256. $question->fraction[] = 1;
  257. $question->feedback = array();
  258. if (is_array( $thisquestion['#']['GRADABLE'][0]['#'] )) {
  259. $question->feedback[0] = addslashes(trim($thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_CORRECT"][0]["#"]));
  260. }
  261. else {
  262. $question->feedback[0] = '';
  263. }
  264. if (is_array( $thisquestion["#"]["GRADABLE"][0]["#"] )) {
  265. $question->feedback[1] = addslashes(trim($thisquestion["#"]["GRADABLE"][0]["#"]["FEEDBACK_WHEN_INCORRECT"][0]["#"]));
  266. }
  267. else {
  268. $question->feedback[1] = '';
  269. }
  270. $questions[] = $question;
  271. }
  272. }
  273. //----------------------------------------
  274. // Process Matching Questions
  275. //----------------------------------------
  276. function process_matching($xml, &$questions) {
  277. if (isset($xml["POOL"]["#"]["QUESTION_MATCH"])) {
  278. $matchquestions = $xml["POOL"]["#"]["QUESTION_MATCH"];
  279. }
  280. else {
  281. return;
  282. }
  283. for ($i = 0; $i < sizeof ($matchquestions); $i++) {
  284. $question = $this->defaultquestion();
  285. $question->qtype = MATCH;
  286. $thisquestion = $matchquestions[$i];
  287. // determine if the question is already escaped html
  288. $ishtml = $thisquestion["#"]["BODY"][0]["#"]["FLAGS"][0]["#"]["ISHTML"][0]["@"]["value"];
  289. // put questiontext in question object
  290. if ($ishtml) {
  291. $question->questiontext = html_entity_decode_php4(trim($thisquestion["#"]["BODY"][0]["#"]["TEXT"][0]["#"]));
  292. }
  293. $question->questiontext = addslashes($question->questiontext);
  294. // put name of question in question object
  295. $question->name = substr($question->questiontext, 0, 254);
  296. $choices = $thisquestion["#"]["CHOICE"];
  297. for ($j = 0; $j < sizeof ($choices); $j++) {
  298. $subquestion = NULL;
  299. $choice = $choices[$j]["#"]["TEXT"][0]["#"];
  300. $choice_id = $choices[$j]["@"]["id"];
  301. $question->subanswers[] = addslashes(trim($choice));
  302. $correctanswers = $thisquestion["#"]["GRADABLE"][0]["#"]["CORRECTANSWER"];
  303. for ($k = 0; $k < sizeof ($correctanswers); $k++) {
  304. if (strcmp($choice_id, $correctanswers[$k]["@"]["choice_id"]) == 0) {
  305. $answer_id = $correctanswers[$k]["@"]["answer_id"];
  306. $answers = $thisquestion["#"]["ANSWER"];
  307. for ($m = 0; $m < sizeof ($answers); $m++) {
  308. $answer = $answers[$m];
  309. $current_ans_id = $answer["@"]["id"];
  310. if (strcmp ($current_ans_id, $answer_id) == 0) {
  311. $answer = $answer["#"]["TEXT"][0]["#"];
  312. $question->subquestions[] = addslashes(trim($answer));
  313. break;
  314. }
  315. }
  316. break;
  317. }
  318. }
  319. }
  320. $questions[] = $question;
  321. }
  322. }
  323. }
  324. ?>