]> git.mjollnir.org Git - moodle.git/commitdiff
Added xml format import. First pass for testing.
authorthepurpleblob <thepurpleblob>
Thu, 16 Dec 2004 15:54:51 +0000 (15:54 +0000)
committerthepurpleblob <thepurpleblob>
Thu, 16 Dec 2004 15:54:51 +0000 (15:54 +0000)
Just multiple choice and true/false at the moment and needs further
testing and polishing.

mod/quiz/format/xml/format.php

index ec57e6f942c78f78fb190b8a760d61eb21b4af4c..0172323e9781750fd039124cf8e44ec1f6c6da66 100755 (executable)
@@ -6,8 +6,196 @@
 //////////////////////////////////////////////////////////////////////////
 // Based on default.php, included by ../import.php
 
+
+require_once( "$CFG->libdir/xmlize.php" );
+
 class quiz_file_format extends quiz_default_format {
 
+// IMPORT FUNCTIONS START HERE
+
+function trans_format( $name ) {
+  // translate text format string to its internal code
+
+  $name = trim($name); 
+  if ($name=='moodle_auto_format') {
+    $id = 0;
+  }
+  elseif ($name=='html') {
+    $id = 1;
+  }
+  elseif ($name=='plain_text') {
+    $id = 2;
+  }
+  elseif ($name=='wiki_like') {
+    $id = 3;
+  }
+  elseif ($name=='markdown') {
+    $id = 4;
+  }
+  else {
+    $id = 0; // or maybe warning required
+  }
+  return $id;
+}
+
+function trans_single( $name ) {
+  // translate single string to its internal format
+
+  $name = trim($name);
+
+  if ($name=="true") {
+    $id = 1;
+  }
+  elseif ($name=="false") {
+    $id = 0;
+  }
+  else {
+    $id = 0; // or maybe warning required
+  }
+  return $id;
+}
+
+function import_text( $text ) {
+  // handle xml 'text' element
+  $data = $text[0]['#'];
+  $data = html_entity_decode( $data );
+  return addslashes(trim( $data ));
+}
+
+function import_headers( $question ) {
+  // read bits that are common to all questions
+
+  // this routine initialises the question object
+  $name = $this->import_text( $question['#']['name'][0]['#']['text'] );
+  $qtext = $this->import_text( $question['#']['questiontext'][0]['#']['text'] );
+  $qformat = $question['#']['questiontext'][0]['@']['format'];
+  $image = $question['#']['image'][0]['#'];
+
+  $qo = null;
+  $qo->name = $name;
+  $qo->questiontext = $qtext;
+  $qo->questiontextformat = $this->trans_format( $qformat );
+  $qo->image = $image;
+
+  return $qo;
+}
+
+
+function import_answer( $answer ) {
+  // import answer part of question
+
+  $fraction = $answer['@']['fraction'];
+  $text = $this->import_text( $answer['#']['text']);
+  $feedback = $this->import_text( $answer['#']['feedback'][0]['#']['text'] );
+
+  $ans = null;
+  $ans->answer = $text;
+  $ans->fraction = $fraction / 100;
+  $ans->feedback = $feedback;
+  
+  return $ans;
+}
+
+function import_multichoice( $question ) {
+  // import multichoice type questions
+
+  // get common parts
+  $qo = $this->import_headers( $question );
+
+  // 'header' parts particular to multichoice
+  $qo->qtype = MULTICHOICE;
+  $single = $question['#']['single'][0]['#'];
+  $qo->single = $this->trans_single( $single );
+
+  // run through the answers
+  // $qo->answer = array();
+  $answers = $question['#']['answers'][0]['#']['answer'];  
+  $a_count = 0;
+  foreach ($answers as $answer) {
+     $ans = $this->import_answer( $answer );
+     // $qo->answer[] = $ans;
+     $qo->answer[$a_count] = $ans->answer;
+     $qo->fraction[$a_count] = $ans->fraction;
+     $qo->feedback[$a_count] = $ans->feedback;
+     ++$a_count;
+  }
+
+  return $qo;
+}
+
+function import_truefalse( $question ) {
+  // import true/false type question
+
+  // get common parts
+  $qo = $this->import_headers( $question );
+
+  // 'header' parts particular to true/false
+  $qo->qtype = TRUEFALSE;
+
+  // get answer info
+  $answers = $question['#']['answer'];
+  $fraction0 = $answers[0]['@']['fraction'];
+  $feedback0 = $this->import_text($answers[0]['#']['feedback'][0]['#']['text']);
+  $fraction1 = $answers[1]['@']['fraction'];
+  $feedback1 = $this->import_text($answers[1]['#']['feedback'][0]['#']['text']);
+
+  // sort out which is true and build object accordingly
+  if ($fraction0==100) { // then 0 index is true
+    $qo->answer = 1;
+    $qo->feedbacktrue=$feedback0;
+    $qo->feedbackfalse=$feedback1;
+  }
+  else {
+    $qo->answer = 0;
+    $qo->feedbacktrue = $feedback1;
+    $qo->feedbackfalse = $feedback0;
+  }
+
+  return $qo;
+}
+
+function readquestions($lines) {
+  // parse the array of lines into an array of questions
+  // this *could* burn memory - but it won't happen that much
+  // so fingers crossed!
+
+  // we just need it as one big string
+  $text = implode($lines, " ");
+  unset( $lines );
+
+  // this converts xml to big nasty data structure
+  // print_r it if you want to see what it looks like!
+  $xml = xmlize( $text ); 
+
+  // set up array to hold all our questions
+  $questions = array();
+
+  // iterate through questions
+  foreach ($xml['quiz']['#']['question'] as $question) {
+    $question_type = $question['@']['type'];
+    echo "<b>question type = $question_type</b>"; 
+
+    if ($question_type=='multichoice') {
+      $qo = $this->import_multichoice( $question );
+    }  
+    elseif ($question_type=='truefalse') {
+      $qo = $this->import_truefalse( $question );
+    }
+    else {
+      echo "<p>Question type $question_type not currently supported for xml import</p>";
+      $qo = null;
+    }
+
+    // stick the result in the $questions array
+    $questions[] = $qo;
+  }
+
+  return $questions;
+}
+
+// EXPORT FUNCTIONS START HERE
+
 function indent_xhtml($source, $indenter = ' ') { 
     // xml tidier-upper
     // (c) Ari Koivula http://ventionline.com
@@ -126,11 +314,52 @@ function get_qtype( $type_id ) {
         $name = 'cloze';
         break;
     default:
-        $name = 'Unknown';
+        $name = 'unknown';
     }
     return $name;
 }
 
+function get_format( $id ) {
+  // translates question text format id number into something sensible
+
+  switch( $id ) {
+  case 0:
+    $name = "moodle_auto_format";
+    break;
+  case 1:
+    $name = "html";
+    break;
+  case 2:
+    $name = "plain_text";
+    break;
+  case 3:
+    $name = "wiki_like";
+    break;
+  case 4:
+    $name = "markdown";
+    break;
+  default:
+    $name = "unknown";
+  }
+  return $name;
+}
+
+function get_single( $id ) {
+  // translate single value into something sensible
+
+  switch( $id ) {
+  case 0:
+    $name = "false";
+    break;
+  case 1:
+    $name = "true";
+    break;
+  default:
+    $name = "unknown";
+  }
+  return $name;
+}
+
 function writetext( $raw ) {
     // generates <text></text> tags, processing raw text therein 
 
@@ -164,10 +393,12 @@ function writequestion( $question ) {
     // add opening tag
     $question_type = $this->get_qtype( $question->qtype );
     $name_text = $this->writetext( $question->name );
+    $qtformat = $this->get_format($question->questiontextformat);
     $question_text = $this->writetext( $question->questiontext );
     $expout .= "<question type=\"$question_type\">\n";   
     $expout .= "<name>".$this->writetext($name_text)."</name>\n";
-    $expout .= "<questiontext>".$this->writetext($question_text)."</questiontext>\n";   
+    $expout .= "<questiontext format=\"$qtformat\">".$this->writetext($question_text)."</questiontext>\n";   
+    $expout .= "<image>".$question->image."</image>\n";
 
     // output depends on question type
     switch($question->qtype) {
@@ -188,13 +419,16 @@ function writequestion( $question ) {
         $expout .= "</answer>\n";
         break;
     case MULTICHOICE:
+        $expout .= "<single>".$this->get_single($question->single)."</single>\n";
+        $expout .= "<answers>\n";
         foreach($question->answers as $answer) {
-            $percent = round( $answer->fraction * 100 );
+            $percent = $answer->fraction * 100;
             $expout .= "<answer fraction=\"$percent\">\n";
             $expout .= $this->writetext( $answer->answer );
             $expout .= "<feedback>".$this->writetext( $answer->feedback )."</feedback>\n";
             $expout .= "</answer>\n";
             }
+        $expout .= "</answers>\n";
         break;
     case SHORTANSWER:
         foreach($question->answers as $answer) {