]> git.mjollnir.org Git - moodle.git/commitdiff
Importing improved to include pre and post-processing.
authormoodler <moodler>
Thu, 10 Apr 2003 13:12:40 +0000 (13:12 +0000)
committermoodler <moodler>
Thu, 10 Apr 2003 13:12:40 +0000 (13:12 +0000)
Removal of Random Matching code from the generic case.
Implementing a particular custom import style aon.php

mod/quiz/format/aon.php [new file with mode: 0644]
mod/quiz/format/custom-template.php [new file with mode: 0644]
mod/quiz/format/default.php
mod/quiz/format/missingword.php
mod/quiz/import.php

diff --git a/mod/quiz/format/aon.php b/mod/quiz/format/aon.php
new file mode 100644 (file)
index 0000000..7e2986e
--- /dev/null
@@ -0,0 +1,209 @@
+<?PHP  // $Id$ 
+
+////////////////////////////////////////////////////////////////////////////
+/// Academy of Nursing format
+///
+/// Based on missingword.php
+///
+/// This Moodle class provides all functions necessary to import and export 
+/// one-correct-answer multiple choice questions in this format:
+///
+///    As soon as we begin to explore our body parts as infants
+///    we become students of {=anatomy and physiology ~reflexology 
+///    ~science ~experiment}, and in a sense we remain students for life.
+/// 
+/// Each answer is separated with a tilde ~, and the correct answer is 
+/// prefixed with an equals sign =
+///
+/// Afterwards, all short-answer questions are randomly packed into 
+/// 4-answer matching questions.
+///
+////////////////////////////////////////////////////////////////////////////
+
+require("default.php");
+
+class quiz_file_format extends quiz_default_format {
+
+    function readquestion($lines) {
+    /// Given an array of lines known to define a question in 
+    /// this format, this function converts it into a question 
+    /// object suitable for processing and insertion into Moodle.
+
+        $question = NULL;
+
+        $text = implode($lines, " ");
+
+        /// Find answer section
+
+        $answerstart = strpos($text, "{");
+        if ($answerstart === false) {
+            if ($this->displayerrors) {
+                echo "<P>$text<P>Could not find a {";
+            }
+            return false;
+        }
+
+        $answerfinish = strpos($text, "}");
+        if ($answerfinish === false) {
+            if ($this->displayerrors) {
+                echo "<P>$text<P>Could not find a }";
+            }
+            return false;
+        }
+
+        $answerlength = $answerfinish - $answerstart;
+        $answertext = substr($text, $answerstart + 1, $answerlength - 1);
+
+        /// Save the new question text
+        $question->questiontext = addslashes(substr_replace($text, "_____", $answerstart, $answerlength+1));
+        $question->name = substr($question->questiontext, 0, 60)." ...";
+
+
+        /// Parse the answers
+        $answers = explode("~", $answertext);
+
+        $countanswers = count($answers);
+
+        switch ($countanswers) {
+            case 0:  // invalid question
+                if ($this->displayerrors) {
+                    echo "<P>No answers found in $answertext";
+                }
+                return false;
+
+            case 1:
+                $question->qtype = SHORTANSWER;
+
+                $answer = trim($answers[0]);
+                if ($answer[0] == "=") {
+                    $answer = substr($answer, 1);
+                }
+                $question->answer[]   = addslashes($answer);
+                $question->fraction[] = 1;
+                $question->feedback[] = "";
+    
+                $question->usecase = 0;  // Ignore case
+                $question->defaultgrade = 1; 
+                $question->image = "";   // No images with this format
+                return $question;
+
+            default:
+                $question->qtype = MULTICHOICE;
+
+                $answers = swapshuffle($answers);
+                foreach ($answers as $key => $answer) {
+                    $answer = trim($answer);
+                    if ($answer[0] == "=") {
+                        $question->fraction[$key] = 1;
+                        $answer = substr($answer, 1);
+                    } else {
+                        $question->fraction[$key] = 0;
+                    }
+                    $question->answer[$key]   = addslashes($answer);
+                    $question->feedback[$key] = "";
+                }
+    
+                $question->defaultgrade = 1; 
+                $question->single = 1;   // Only one answer is allowed
+                $question->image = "";   // No images with this format
+                return $question;
+        }
+    }
+
+    function postprocess($category, $questionids) {
+    /// Goes through the questionids, looking for shortanswer questions
+    /// and converting random groups of 4 into matching questions.
+
+    /// Doesn't handle shortanswer questions with more than one answer
+
+        global $db, $CFG;
+
+        $questionids = implode(',', $questionids);
+
+        if (!$shortanswers = get_records_select("quiz_questions", 
+                                                "id IN ($questionids) AND qtype = ".SHORTANSWER,
+                                                "", "id,qtype")) {
+            return true;
+        }
+
+
+        $shortanswerids = array();
+        foreach ($shortanswers as $key => $shortanswer) {
+            $shortanswerids[] = $key;
+        }
+        
+        $strmatch = "$category->name - ".get_string("match", "quiz");
+
+        $shortanswerids = swapshuffle($shortanswerids);
+        $count = count($shortanswerids);
+        $i = 1;
+
+        $question->category = $category->id;
+        $question->qtype    = MATCH;
+        $question->questiontext = get_string("randomsamatchintro", "quiz");
+        $question->image  = "";
+
+        while ($count > 4) {
+             $question->name         = "$strmatch $i";
+             $question->subquestions = array();
+             $question->subanswers   = array();
+
+             $extractids = implode(',', array_splice($shortanswerids, -4));
+             $count = count($shortanswerids);
+
+             $extracts = get_records_sql("SELECT q.questiontext, a.answer
+                                            FROM {$CFG->prefix}quiz_questions q,
+                                                 {$CFG->prefix}quiz_shortanswer sa,
+                                                 {$CFG->prefix}quiz_answers a
+                                           WHERE q.id in ($extractids) 
+                                             AND sa.question = q.id
+                                             AND a.id = sa.answers");
+
+             if (count($extracts) != 4) {
+                 print_object($extracts);
+                 notify("Could not find exactly four shortanswer questions with ids: $extractids");
+                 continue;
+             }
+
+             if (!$question->id = insert_record("quiz_questions", $question)) {
+                 error("Could not insert new question!");
+             }
+
+             foreach ($extracts as $shortanswer) {
+                 $question->subquestions[] = addslashes($shortanswer->questiontext);
+                 $question->subanswers[] = addslashes($shortanswer->answer);
+             }
+
+             $result = quiz_save_question_options($question);
+
+             if (!empty($result->error)) {
+                 notify("Error: $result->error");
+             }
+
+             if (!empty($result->notice)) {
+                 notify($result->notice);
+             }
+
+             /// Delete the old short-answer questions
+
+             execute_sql("DELETE FROM {$CFG->prefix}quiz_questions WHERE id IN ($extractids)");
+             execute_sql("DELETE FROM {$CFG->prefix}quiz_shortanswer WHERE question IN ($extractids)");
+             execute_sql("DELETE FROM {$CFG->prefix}quiz_answers WHERE question IN ($extractids)");
+             
+        }
+
+        if ($count) {    /// Delete the remaining ones
+            foreach ($shortanswerids as $shortanswerid) {
+                delete_records("quiz_questions", "id", $shortanswerid);
+                delete_records("quiz_shortanswer", "question", $shortanswerid);
+                delete_records("quiz_answers", "question", $shortanswerid);
+            }
+        }
+        
+
+        return true;
+    }
+
+}
+
+?>
diff --git a/mod/quiz/format/custom-template.php b/mod/quiz/format/custom-template.php
new file mode 100644 (file)
index 0000000..dacb127
--- /dev/null
@@ -0,0 +1,63 @@
+<?PHP  // $Id$ 
+
+////////////////////////////////////////////////////////////////////////////
+/// CUSTOM FORMAT
+///
+/// This format provides a starting point for creating your own 
+/// import format.
+/// 
+/// If your questions are separated by blank lines, then you will 
+/// only need to modify the readquestion() function to parse the 
+/// lines into each question.  See default.php for the other 
+/// functions that you may need to override if you have different
+/// needs.
+/// 
+/// See missingword.php for an example of how it's done, and see 
+/// the top of ../lib.php for some constants you might need.
+///
+////////////////////////////////////////////////////////////////////////////
+
+require("default.php");
+
+class quiz_file_format extends quiz_default_format {
+
+    function readquestions($lines) {
+    /// Parses an array of lines into an array of questions, 
+    /// where each item is a question object as defined by 
+    /// readquestion().   Questions are defined as anything 
+    /// between blank lines.
+     
+        $questions = array();
+        $currentquestion = array();
+
+        foreach ($lines as $line) {
+           $line = trim($line);
+           if (empty($line)) {
+               if (!empty($currentquestion)) {
+                   if ($question = $this->readquestion($currentquestion)) {
+                       $questions[] = $question;
+                   }
+                   $currentquestion = array();
+               }
+           } else {
+               $currentquestion[] = $line;
+           }
+        }
+
+        return $questions;
+    }
+
+
+
+    function readquestion($lines) {
+    /// Given an array of lines known to define a question in 
+    /// this format, this function converts it into a question 
+    /// object suitable for processing and insertion into Moodle.
+
+        $question = NULL;
+
+        return $question;
+    }
+}
+
+?>
index 5dded33387c404c50cccb688372ed87fa3d3666b..91056ff697bc932c18598fa4ce3aed58140230f7 100644 (file)
@@ -13,6 +13,12 @@ class quiz_default_format {
 
 /// Importing functions
 
+    function preprocess($category) {
+    /// Does any pre-processing that may be desired
+
+        return true;
+    }
+
     function readdata($filename) {
     /// Returns complete file with an array, one item per line
 
@@ -26,7 +32,7 @@ class quiz_default_format {
     function readquestions($lines) {
     /// Parses an array of lines into an array of questions, 
     /// where each item is a question object as defined by 
-    /// readquestion().   Questions are defines as anything 
+    /// readquestion().   Questions are defined as anything 
     /// between blank lines.
      
         $questions = array();
@@ -61,6 +67,14 @@ class quiz_default_format {
     }
 
 
+    function postprocess($questionids) {
+    /// Does any post-processing that may be desired
+    /// Argument is a simple array of question ids that 
+    /// have just been added.
+
+        return true;
+    }
+
 }
 
 ?>
index 92d648a1da862fe71891ceb4bd9405e48fecadb8..fad018598f4fb93e42f136f6a4e468f2c801a736 100644 (file)
@@ -104,6 +104,15 @@ class quiz_file_format extends quiz_default_format {
                 return $question;
         }
     }
+
+    function postprocess($questionids) {
+    /// Does any post-processing that may be desired
+    /// Argument is a simple array of question ids that 
+    /// have just been added.
+
+        return true;
+    }
+
 }
 
 ?>
index d565586d4d5a80b48f5fffeaf89f6491dac83f9e..02406da469062529ae3d434f4d8f915060e743bc 100644 (file)
         if (!empty($_FILES['newfile'])) {
             $newfile = $_FILES['newfile'];
         }
+
         if (empty($newfile)) {
             notify(get_string("uploadproblem") );
+
         } else if (!is_uploaded_file($newfile['tmp_name']) or $newfile['size'] == 0) {
             notify(get_string("uploadnofilefound") );
+
         } else {
 
             if (! is_readable("format/$form->format".".php")) {
 
             $format = new quiz_file_format();
 
+            if (! $format->preprocess($category)) {
+                error("Error occurred during pre-processing.");
+            }
+
             if (! $lines = $format->readdata($newfile['tmp_name'])) {
                 error("File could not be read, or was empty");
             }
             notify("Importing ".count($questions)." questions");
 
             $count = 0;
+            $questionids = array();
+
             foreach ($questions as $question) {
                 $count++;
-                echo "<hr>";
-                echo "<p><b>$count</b>. ".stripslashes($question->questiontext)."</p>";
+
+                echo "<hr><p><b>$count</b>. ".stripslashes($question->questiontext)."</p>";
 
                 $question->category = $category->id;
 
@@ -70,6 +79,8 @@
                     error("Could not insert new question!");
                 }
 
+                $questionids[] = $question->id;
+
                 // Now to save all the answers and type-specific options
 
                 $result = quiz_save_question_options($question);
                 if (!empty($result->notice)) {
                     notice($result->notice);
                 }
-    
             }
 
-            if (!empty($form->createrandom)) {   /// Create a number of random questions
-
-                $rm->choose = 4;                 /// Always 4, for now.
-                $rm->category = $category->id;
-                $rm->questiontext =  get_string("randomsamatchintro", "quiz");
-                $rm->image = "";
-                $rm->qtype =  RANDOMSAMATCH;
-                $rm->defaultgrade = $rm->choose; 
-
-                echo "<hr>";
-
-                for ($i=1; $i<=$form->createrandom; $i++) {
-                    $rm->name =  get_string("randomsamatch", "quiz") . " $i ($rm->choose $strquestions)";
-
-                    $db->debug = true;
-                    if (!$rm->id = insert_record("quiz_questions", $rm)) {
-                        error("Could not insert new question!");
-                    }
-
-                    $result = quiz_save_question_options($rm);
-        
-                    if (!empty($result->error)) {
-                        notify($result->error);
-                    }
-
-                    if (!empty($result->notice)) {
-                        notify($result->notice);
-                    }
-                    echo "<p>$rm->name</p>";
-                }
+            if (! $format->postprocess($category, $questionids)) {
+                error("Error occurred during post-processing.");
             }
+
             echo "<hr>";
             print_continue("edit.php");
             print_footer($course);
         error("No categories!");
     }
 
+    print_heading_with_help($strimportquestions, "import", "quiz");
 
     print_simple_box_start("center", "", "$THEME->cellheading");
     echo "<FORM ENCTYPE=\"multipart/form-data\" METHOD=\"POST\" ACTION=import.php>";
     print_string("category", "quiz");
     echo ":</TD><TD>";
     choose_from_menu($categories, "category", "$category->id", "");
-    helpbutton("import", $strimportquestions, "quiz");
     echo "</TR>";
 
     echo "<TR><TD align=right>";
     print_string("fileformat", "quiz");
     echo ":</TD><TD>";
-    choose_from_menu($QUIZ_FILE_FORMAT, "format", "missingword", "");
+    choose_from_menu($QUIZ_FILE_FORMAT, "format", "custom", "");
     helpbutton("import", $strimportquestions, "quiz");
     echo "</TR><TR><TD align=right>";
-    print_string("randomsamatchcreate", "quiz");
-    echo ":</TD><TD>";
-    for ($i=0;$i<=100;$i++) {
-        $menu[$i] = $i;
-    }
-    choose_from_menu($menu, "createrandom", 0, "");
-    unset($menu);
-    echo "</TR><TR><TD align=right>";
     print_string("upload");
     echo ":</TD><TD>";
     echo " <INPUT NAME=\"newfile\" TYPE=\"file\" size=\"50\">";