]> git.mjollnir.org Git - moodle.git/commitdiff
Various quiz changes. Most importantly is the new framework for importing
authormoodler <moodler>
Sun, 16 Feb 2003 07:08:57 +0000 (07:08 +0000)
committermoodler <moodler>
Sun, 16 Feb 2003 07:08:57 +0000 (07:08 +0000)
quiz questions.   Importing works but is still being tested.

15 files changed:
lang/en/help/quiz/import.html [new file with mode: 0644]
lang/en/quiz.php
lang/en/survey.php
mod/quiz/db/mysql.php
mod/quiz/db/postgres7.php
mod/quiz/format/README [new file with mode: 0644]
mod/quiz/format/custom.php [new file with mode: 0644]
mod/quiz/format/default.php [new file with mode: 0644]
mod/quiz/format/missingword.php [new file with mode: 0644]
mod/quiz/format/qti.php [new file with mode: 0644]
mod/quiz/format/webct.php [new file with mode: 0644]
mod/quiz/import.php [new file with mode: 0644]
mod/quiz/lib.php
mod/quiz/question.php
mod/quiz/version.php

diff --git a/lang/en/help/quiz/import.html b/lang/en/help/quiz/import.html
new file mode 100644 (file)
index 0000000..0ce1538
--- /dev/null
@@ -0,0 +1,49 @@
+<P ALIGN=CENTER><B>Importing new questions</B></P>
+
+<P>This function allows you to import questions from 
+   external text files.  
+
+<P>Several common file formats are supported:
+
+<P><B>Missing word format</B></P>
+<UL>
+<P>This format only supports multiple choice questions.
+Each answer is separated with a tilde (~), and the correct answer is 
+prefixed with an equals sign (=).  Here is an example:
+
+<BLOCKQUOTE>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.
+</BLOCKQUOTE>
+
+<P>More info: <? helpbutton("formatmissingword", "", "quiz") ?></P>
+</UL>
+
+
+<P><B>IMS QTI format</B></P>
+<UL>
+<P>The standard format for Question and Test Interoperability, from IMS.
+<P>Not yet implemented
+
+<P>More info: <? helpbutton("formatqti", "", "quiz") ?></P>
+</UL>
+
+
+<P><B>WebCT format</B></P>
+<UL>
+<P>The format of files exported from WebCT.
+<P>Not yet implemented
+
+<P>More info: <? helpbutton("formatwebct", "", "quiz") ?></P>
+</UL>
+
+<P><B>Custom format</B></P>
+<UL>
+<P>If you have your own format that you need to import, you can 
+   implement it yourself by editing mod/quiz/format/custom.php
+
+<P>The amount of new code needed is quite small - just enough
+   to parse a single question from given text.
+
+<P>More info: <? helpbutton("formatcustom", "", "quiz") ?></P>
+</UL>
index 9af28c6c19dd2260f033bc0d71ee052e1c5d1bbf..4ca8a6c38a198a8748048add1f2884ca09b4046f 100644 (file)
@@ -5,6 +5,7 @@ $string['modulename'] = "Quiz";
 $string['modulenameplural'] = "Quizzes";
 #------------------------------------------------------------
 
+$string['addquestions'] = "Add questions";
 $string['addselectedtoquiz'] = "Add selected to quiz";
 $string['allowreview'] = "Allow review";
 $string['alwaysavailable'] = "Always available";
@@ -35,6 +36,7 @@ $string['choices'] = "Available choices";
 $string['correctanswer'] = "Correct answer";
 $string['correctanswers'] = "Correct answers";
 $string['createnewquestion'] = "Create new question";
+$string['custom'] = "Custom format";
 $string['daysavailable'] = "Days available";
 $string['default'] = "Default";
 $string['defaultinfo'] = "The default category for questions.";
@@ -60,10 +62,12 @@ $string['gradehighest'] = "Highest grade";
 $string['grademethod'] = "Grading method";
 $string['guestsno'] = "Sorry, guests can not see or attempt quizzes";
 $string['imagedisplay'] = "Image to display";
+$string['importquestions'] = "Import questions from file";
 $string['introduction'] = "Introduction";
 $string['marks'] = "Marks";
 $string['missingname'] = "Missing question name";
 $string['missingquestiontext'] = "Missing question text";
+$string['missingword'] = "Missing word format";
 $string['multichoice'] = "Multiple Choice";
 $string['noanswers'] = "No answers were selected!";
 $string['noattempts'] = "No attempts have been made on this quiz";
@@ -72,6 +76,7 @@ $string['noquestions'] = "No questions have been added yet";
 $string['noreview'] = "You are not allowed to review this quiz";
 $string['noreviewuntil'] = "You are not allowed to review this quiz until \$a";
 $string['publish'] = "Publish";
+$string['qti'] = "IMS QTI format";
 $string['question'] = "Question";
 $string['questioninuse'] = "The question '\$a' is currently being used:";
 $string['questions'] = "Questions";
@@ -106,4 +111,5 @@ $string['true'] = "True";
 $string['truefalse'] = "True/False";
 $string['type'] = "Type";
 $string['viewallanswers'] = "View \$a completed quizzes";
+$string['webct'] = "WebCT format";
 $string['yourfinalgradeis'] = "Your final grade for this quiz is \$a";
index 8081e1102c7eab0ce0eece41c7437a57648e3aeb..03416bc39c931c7cb7479c1121fff2f6a5a1063e 100644 (file)
@@ -63,6 +63,13 @@ $string['attlsmintro'] = "In discussion ...";
 $string['attlsm1'] = "Attitudes Towards Thinking and Learning";
 $string['attlsm2'] = "Connected Learning";
 $string['attlsm3'] = "Separate Learning";
+$string['ciqname'] = "Critical Incidents";
+$string['ciqintro'] = "While thinking about the events in this class over the past week, answer the questions below.";
+$string['ciq1'] = "At what moment in class were you most engaged as a learner?";
+$string['ciq2'] = "At what moment in class were you most distanced as a learner?";
+$string['ciq3'] = "What action from anyone in the forums did you find most affirming or helpful?";
+$string['ciq4'] = "What action from anyone in the forums did you find most puzzling or confusing?";
+$string['ciq5'] = "What event surprised you most?";
 $string['clicktocontinue'] = "Click here to continue";
 $string['clicktocontinuecheck'] = "Click here to check and continue";
 
index 11c787380a1efcbd2ffc08ab338b6414eaaf33e3..ccc5c766519526483811df2730a4fb90445dde92 100644 (file)
@@ -36,9 +36,9 @@ function quiz_upgrade($oldversion) {
     }
 
     if ($oldversion < 2003010301) {
-        table_column("quiz_truefalse", "true", "trueanswer", "INTEGER", "UNSIGNED", "0", "NOT NULL", "");
-        table_column("quiz_truefalse", "false", "falseanswer", "INTEGER", "UNSIGNED", "0", "NOT NULL", "");
-        table_column("quiz_questions", "type", "qtype", "INTEGER", "UNSIGNED", "0", "NOT NULL", "");
+        table_column("quiz_truefalse", "true", "trueanswer", "INTEGER", "10", "UNSIGNED", "0", "NOT NULL", "");
+        table_column("quiz_truefalse", "false", "falseanswer", "INTEGER", "10", "UNSIGNED", "0", "NOT NULL", "");
+        table_column("quiz_questions", "type", "qtype", "INTEGER", "10", "UNSIGNED", "0", "NOT NULL", "");
     }
 
     return true;
index bc7010d2c6fa3ddb585b9ca1c2b5338a38986138..c839413c8817036db758e6532fa5982f91602030 100644 (file)
@@ -11,9 +11,9 @@ function quiz_upgrade($oldversion) {
     }
 
     if ($oldversion < 2003010301) {
-        table_column("quiz_truefalse", "true", "trueanswer", "INTEGER", "UNSIGNED", "0", "NOT NULL", "");
-        table_column("quiz_truefalse", "false", "falseanswer", "INTEGER", "UNSIGNED", "0", "NOT NULL", "");
-        table_column("quiz_questions", "type", "qtype", "INTEGER", "UNSIGNED", "0", "NOT NULL", "");
+        table_column("quiz_truefalse", "true", "trueanswer", "INTEGER", "10", "UNSIGNED", "0", "NOT NULL", "");
+        table_column("quiz_truefalse", "false", "falseanswer", "INTEGER", "10", "UNSIGNED", "0", "NOT NULL", "");
+        table_column("quiz_questions", "type", "qtype", "INTEGER", "10", "UNSIGNED", "0", "NOT NULL", "");
     }
 
     return true;
diff --git a/mod/quiz/format/README b/mod/quiz/format/README
new file mode 100644 (file)
index 0000000..a850f67
--- /dev/null
@@ -0,0 +1,6 @@
+This directory contains plug-in sub-modules to add 
+import-export formats to Moodle quizzes.
+
+Each sub-module is a file containing a class that 
+contains functions for reading, writing, importing 
+and exporting quiz questions.
diff --git a/mod/quiz/format/custom.php b/mod/quiz/format/custom.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;
+    }
+}
+
+?>
diff --git a/mod/quiz/format/default.php b/mod/quiz/format/default.php
new file mode 100644 (file)
index 0000000..0f7b70c
--- /dev/null
@@ -0,0 +1,81 @@
+<?PHP  // $Id$ 
+
+////////////////////////////////////////////////////////////////////
+/// Default class for file imports/exports.                       //
+///                                                               //
+/// Doesn't do everything on it's own -- it needs to be extended. //
+////////////////////////////////////////////////////////////////////
+
+
+class quiz_default_format {
+
+    var $displayerrors = true;
+
+/// Importing functions
+
+    function readdata($filename) {
+    /// Returns complete file with an array, one item per line
+
+        if (is_readable($filename)) {
+            return file($filename);
+        }
+        return false;
+    }
+
+
+    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 
+    /// 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.
+
+        echo "<p>You need to override the readquestion() function";
+
+        return NULL;
+    }
+
+
+    function swapshuffle($array) {
+    /// Given a simple array, shuffles it up just like shuffle()
+    /// Unlike PHP's shuffle() ihis function works on any machine.
+
+        srand ((double) microtime() * 10000000);
+        $last = count($array) - 1;
+        for ($i=0;$i<=$last;$i++) {
+            $from = rand(0,$last);
+            $curr = $array[$i];
+            $array[$i] = $array[$from];
+            $array[$from] = $curr;
+        }  
+        return $array;
+    }
+
+}
+
+?>
diff --git a/mod/quiz/format/missingword.php b/mod/quiz/format/missingword.php
new file mode 100644 (file)
index 0000000..8add270
--- /dev/null
@@ -0,0 +1,90 @@
+<?PHP  // $Id$ 
+
+////////////////////////////////////////////////////////////////////////////
+/// MISSING WORD FORMAT
+///
+/// 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 =
+///
+////////////////////////////////////////////////////////////////////////////
+
+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 = $question->questiontext;
+
+
+        /// Parse the answers
+        $answers = explode("~", $answertext);
+
+        if (! count($answers)) {
+            if ($this->displayerrors) {
+                echo "<P>No answers found in $answertext";
+            }
+            return false;
+        }
+
+        $answers = $this->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->qtype = MULTICHOICE;
+        $question->single = 1;   // Only one answer is allowed
+        $question->image = "";   // No images with this format
+
+        return $question;
+    }
+
+}
+
+?>
diff --git a/mod/quiz/format/qti.php b/mod/quiz/format/qti.php
new file mode 100644 (file)
index 0000000..ca996ee
--- /dev/null
@@ -0,0 +1,42 @@
+<?PHP  // $Id$ 
+
+////////////////////////////////////////////////////////////////////////////
+/// IMS QTI FORMAT
+///
+/// This Moodle class provides all functions necessary to import and export 
+/// QTI-formatted XML question files.
+///
+////////////////////////////////////////////////////////////////////////////
+
+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 = array();
+
+        /// FIXME
+
+        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;
+
+        /// FIXME
+
+        return $question;
+    }
+
+}
+
+?>
diff --git a/mod/quiz/format/webct.php b/mod/quiz/format/webct.php
new file mode 100644 (file)
index 0000000..3d7bfea
--- /dev/null
@@ -0,0 +1,42 @@
+<?PHP  // $Id$ 
+
+////////////////////////////////////////////////////////////////////////////
+/// WEBCT FORMAT
+///
+/// This Moodle class provides all functions necessary to import and export 
+/// WebCT-formatted question files.
+///
+////////////////////////////////////////////////////////////////////////////
+
+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 = array();
+
+        /// FIXME
+
+        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;
+
+        /// FIXME
+
+        return $question;
+    }
+
+}
+
+?>
diff --git a/mod/quiz/import.php b/mod/quiz/import.php
new file mode 100644 (file)
index 0000000..8ca8c1d
--- /dev/null
@@ -0,0 +1,107 @@
+<?PHP // $Id$
+      // Import quiz questions into the given category
+
+    require_once("../../config.php");
+    require_once("lib.php");
+
+    require_variable($category);
+    optional_variable($format);
+
+    if (! $category = get_record("quiz_categories", "id", $category)) {
+        error("This wasn't a valid category!");
+    }
+
+    if (! $course = get_record("course", "id", $category->course)) {
+        error("This category doesn't belong to a valid course!");
+    }
+
+    require_login($course->id);
+
+    if (!isteacher($course->id)) {
+        error("Only the teacher can import quiz questions!");
+    }
+
+    $streditingquiz = get_string("editingquiz", "quiz");
+    $strimportquestions = get_string("importquestions", "quiz");
+
+    print_header("$course->shortname: $strimportquestions", "$course->shortname: $strimportquestions",
+                 "<A HREF=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</A> 
+                  -> <A HREF=\"edit.php\">$streditingquiz</A> -> $strimportquestions");
+
+    if ($form = data_submitted()) {   /// Filename
+
+        if (!empty($_FILES['newfile'])) {
+            $newfile = $_FILES['newfile'];
+        }
+        if (empty($newfile)) {
+            notify(get_string("uploadnofilefound") );
+        } else if (!is_uploaded_file($newfile['tmp_name']) or $newfile['size'] == 0) {
+            notify(get_string("uploadproblem") );
+        } else {
+
+            if (! is_readable("format/$form->format".".php")) {
+                error("Format not known ($form->format)");
+            }
+
+            require("format/$form->format".".php");
+
+            $format = new quiz_file_format();
+
+            if (! $lines = $format->readdata($newfile['tmp_name'])) {
+                error("File could not be read, or was empty");
+            }
+
+            if (! $questions = $format->readquestions($lines)) {
+                error("There are no questions in this file!");
+            }
+
+            notify("Importing ".count($questions)." questions");
+
+            $count = 0;
+            foreach ($questions as $question) {
+                $count++;
+                echo "<HR>";
+                echo "<P>$count<BR>".stripslashes($question->questiontext)."</P>";
+
+                $question->category = $category->id;
+
+                if (!$question->id = insert_record("quiz_questions", $question)) {
+                    error("Could not insert new question!");
+                }
+
+                // Now to save all the answers and type-specific options
+
+                $result = quiz_save_question_options($question);
+
+                if (!empty($result->error)) {
+                    error($result->error);
+                }
+
+                if (!empty($result->notice)) {
+                    notice($result->notice);
+                }
+    
+            }
+            print_continue("edit.php");
+            print_footer($course);
+            exit;
+        }
+    } 
+
+    /// Print upload form
+
+    echo "<DIV ALIGN=CENTER>";
+    echo "<FORM ENCTYPE=\"multipart/form-data\" METHOD=\"POST\" ACTION=import.php>";
+    choose_from_menu($QUIZ_FILE_FORMAT, "format", "missingword", "");
+    helpbutton("import", $strimportquestions, "quiz");
+    echo "<BR>";
+    echo " <INPUT TYPE=hidden NAME=category VALUE=\"$category->id\">";
+    echo " <INPUT NAME=\"newfile\" TYPE=\"file\" size=\"50\">";
+    echo " <INPUT TYPE=submit NAME=save VALUE=\"".get_string("uploadthisfile")."\">";
+    echo "</FORM>";
+    echo "</DIV>";
+
+    print_footer($course);
+
+
+?>
index f2ea641bb8d9c6df6cb4e72c375c4ee241a1b27a..481d9e487b2527905324882a2c9556725fc6f655 100644 (file)
@@ -21,6 +21,11 @@ $QUIZ_QUESTION_TYPE = array ( MULTICHOICE => get_string("multichoice", "quiz"),
                               TRUEFALSE   => get_string("truefalse", "quiz"),
                               SHORTANSWER => get_string("shortanswer", "quiz") );
 
+$QUIZ_FILE_FORMAT = array ( "custom"   => get_string("custom", "quiz"),
+                            "webct"    => get_string("webct", "quiz"),
+                            "qti"      => get_string("qti", "quiz"),
+                            "missingword" => get_string("missingword", "quiz") );
+
 define("QUIZ_PICTURE_DEFAULT_HEIGHT", "200");
 
 /// FUNCTIONS ///////////////////////////////////////////////////////////////////
@@ -738,6 +743,8 @@ function quiz_print_cat_question_list($categoryid) {
 
     $strcategory = get_string("category", "quiz");
     $strquestion = get_string("question", "quiz");
+    $straddquestions = get_string("addquestions", "quiz");
+    $strimportquestions = get_string("importquestions", "quiz");
     $strnoquestions = get_string("noquestions", "quiz");
     $strselect = get_string("select", "quiz");
     $strcreatenewquestion = get_string("createnewquestion", "quiz");
@@ -761,13 +768,24 @@ function quiz_print_cat_question_list($categoryid) {
     echo "<CENTER>";
     echo text_to_html($category->info);
 
+    echo "<TABLE><TR>";
+    echo "<TD valign=top><B>$straddquestions:</B></TD>";
+    echo "<TD valign=top align=right>";
     echo "<FORM METHOD=GET ACTION=question.php>"; 
-    echo "<B>$strquestion:</B>&nbsp;";
     choose_from_menu($QUIZ_QUESTION_TYPE, "qtype", "", "");
     echo "<INPUT TYPE=hidden NAME=category VALUE=\"$category->id\">";
     echo "<INPUT TYPE=submit VALUE=\"$strcreatenewquestion\">";
     helpbutton("questiontypes", $strcreatenewquestion, "quiz");
     echo "</FORM>";
+
+    echo "<FORM METHOD=GET ACTION=import.php>"; 
+    echo "<INPUT TYPE=hidden NAME=category VALUE=\"$category->id\">";
+    echo "<INPUT TYPE=submit VALUE=\"$strimportquestions\">";
+    helpbutton("import", $strimportquestions, "quiz");
+    echo "</FORM>";
+
+    echo "</TR></TABLE>";
+
     echo "</CENTER>";
 
     if (!$questions = get_records("quiz_questions", "category", $category->id)) {
@@ -1106,5 +1124,159 @@ function quiz_grade_attempt_results($quiz, $questions) {
 }
 
 
+function quiz_save_question_options($question) {
+/// Given some question info and some data about the the answers
+/// this function parses, organises and saves the question
+/// It is used by question.php when saving new data from a 
+/// form, and also by import.php when importing questions
+///
+/// Returns $result->error or $result->notice
     
+    switch ($question->qtype) {
+        case SHORTANSWER:
+            // Delete all the old answers
+            // FIXME - instead of deleting, update existing answers
+            //         so as not to break existing references to them
+            delete_records("quiz_answers", "question", $question->id);
+            delete_records("quiz_shortanswer", "question", $question->id);
+
+            $answers = array();
+            $maxfraction = -1;
+
+            // Insert all the new answers
+            foreach ($question->answer as $key => $dataanswer) {
+                if ($dataanswer != "") {
+                    unset($answer);
+                    $answer->answer   = $dataanswer;
+                    $answer->question = $question->id;
+                    $answer->fraction = $question->fraction[$key];
+                    $answer->feedback = $question->feedback[$key];
+                    if (!$answer->id = insert_record("quiz_answers", $answer)) {
+                        $result->error = "Could not insert quiz answer!";
+                        return $result;
+                    }
+                    $answers[] = $answer->id;
+                    if ($question->fraction[$key] > $maxfraction) {
+                        $maxfraction = $question->fraction[$key];
+                    }
+                }
+            }
+
+            unset($options);
+            $options->question = $question->id;
+            $options->answers = implode(",",$answers);
+            $options->usecase = $question->usecase;
+            if (!insert_record("quiz_shortanswer", $options)) {
+                $result->error = "Could not insert quiz shortanswer options!";
+                return $result;
+            }
+
+            /// Perform sanity checks on fractional grades
+            if ($maxfraction != 1) {
+                $maxfraction = $maxfraction * 100;
+                $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
+                return $result;
+            }
+        break;
+        case TRUEFALSE:
+            // FIXME - instead of deleting, update existing answers
+            //         so as not to break existing references to them
+            delete_records("quiz_answers", "question", $question->id);
+            delete_records("quiz_truefalse", "question", $question->id);
+
+            $true->answer   = get_string("true", "quiz");
+            $true->question = $question->id;
+            $true->fraction = $question->answer;
+            $true->feedback = $question->feedbacktrue;
+            if (!$true->id = insert_record("quiz_answers", $true)) {
+                $result->error = "Could not insert quiz answer \"true\")!";
+                return $result;
+            }
+
+            $false->answer   = get_string("false", "quiz");
+            $false->question = $question->id;
+            $false->fraction = 1 - (int)$question->answer;
+            $false->feedback = $question->feedbackfalse;
+            if (!$false->id = insert_record("quiz_answers", $false)) {
+                $result->error = "Could not insert quiz answer \"false\")!";
+                return $result;
+            }
+
+            unset($options);
+            $options->question    = $question->id;
+            $options->trueanswer  = $true->id;
+            $options->falseanswer = $false->id;
+            if (!insert_record("quiz_truefalse", $options)) {
+                $result->error = "Could not insert quiz truefalse options!";
+                return $result;
+            }
+        break;
+        case MULTICHOICE:
+            // FIXME - instead of deleting, update existing answers
+            //         so as not to break existing references to them
+            delete_records("quiz_answers", "question", $question->id);
+            delete_records("quiz_multichoice", "question", $question->id);
+
+            $totalfraction = 0;
+            $maxfraction = -1;
+
+            $answers = array();
+
+            // Insert all the new answers
+            foreach ($question->answer as $key => $dataanswer) {
+                if ($dataanswer != "") {
+                    unset($answer);
+                    $answer->answer   = $dataanswer;
+                    $answer->question = $question->id;
+                    $answer->fraction = $question->fraction[$key];
+                    $answer->feedback = $question->feedback[$key];
+                    if (!$answer->id = insert_record("quiz_answers", $answer)) {
+                        $result->error = "Could not insert quiz answer!";
+                        return $result;
+                    }
+                    $answers[] = $answer->id;
+
+                    if ($question->fraction[$key] > 0) {                 // Sanity checks
+                        $totalfraction += $question->fraction[$key];
+                    }
+                    if ($question->fraction[$key] > $maxfraction) {
+                        $maxfraction = $question->fraction[$key];
+                    }
+                }
+            }
+
+            unset($options);
+            $options->question = $question->id;
+            $options->answers = implode(",",$answers);
+            $options->single = $question->single;
+            if (!insert_record("quiz_multichoice", $options)) {
+                $result->error = "Could not insert quiz multichoice options!";
+                return $result;
+            }
+
+            /// Perform sanity checks on fractional grades
+            if ($options->single) {
+                if ($maxfraction != 1) {
+                    $maxfraction = $maxfraction * 100;
+                    $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
+                    return $result;
+                }
+            } else {
+                $totalfraction = round($totalfraction,2);
+                if ($totalfraction != 1) {
+                    $totalfraction = $totalfraction * 100;
+                    $result->notice = get_string("fractionsaddwrong", "quiz", $totalfraction);
+                    return $result;
+                }
+            }
+        break;
+        default:
+            $result->error = "Unsupported question type ($question->qtype)!";
+            return $result;
+        break;
+    }
+    return true;
+}
+
+
 ?>
index a27873274d41dc5c0078788d260395f5da5b20b1..7cd5df1afdac8d14ffe7e53e6112923d83213ffe 100644 (file)
@@ -34,7 +34,7 @@
         }
 
         $question->category = $category->id;
-        $question->qtype     = $qtype;
+        $question->qtype    = $qtype;
 
     } else {
         error("Must specify question id or category");
     if ($form = data_submitted()) { 
 
         // First, save the basic question itself
+
         $question->name         = $form->name;
         $question->questiontext = $form->questiontext;
+
         if (empty($form->image)) {
             $question->image = "";
         } else {
             $question->image = $form->image;
         }
-        $question->category     = $form->category;
 
-        if (!$err = formcheck($question)) {
+        if ($err = formcheck($question)) {
+            notify(get_string("someerrorswerefound"));
+
+        } else {
 
             if (!empty($question->id)) { // Question already exists
                 if (!update_record("quiz_questions", $question)) {
             }
     
             // Now to save all the answers and type-specific options
-    
-            switch ($question->qtype) {
-                case SHORTANSWER:
-                    // Delete all the old answers
-                    // FIXME - instead of deleting, update existing answers
-                    //         so as not to break existing references to them
-                    delete_records("quiz_answers", "question", $question->id);
-                    delete_records("quiz_shortanswer", "question", $question->id);
-    
-                    $answers = array();
-                    $maxfraction = -1;
-    
-                    // Insert all the new answers
-                    foreach ($form->answer as $key => $formanswer) {
-                        if ($formanswer != "") {
-                            unset($answer);
-                            $answer->answer   = $formanswer;
-                            $answer->question = $question->id;
-                            $answer->fraction = $fraction[$key];
-                            $answer->feedback = $feedback[$key];
-                            if (!$answer->id = insert_record("quiz_answers", $answer)) {
-                                error("Could not insert quiz answer!");
-                            }
-                            $answers[] = $answer->id;
-                            if ($fraction[$key] > $maxfraction) {
-                                $maxfraction = $fraction[$key];
-                            }
-                        }
-                    }
-    
-                    unset($options);
-                    $options->question = $question->id;
-                    $options->answers = implode(",",$answers);
-                    $options->usecase = $form->usecase;
-                    if (!insert_record("quiz_shortanswer", $options)) {
-                        error("Could not insert quiz shortanswer options!");
-                    }
-    
-                    /// Perform sanity checks on fractional grades
-                    if ($maxfraction != 1) {
-                        $maxfraction = $maxfraction * 100;
-                        notice_yesno(get_string("fractionsnomax", "quiz", $maxfraction), "question.php?id=$question->id", "edit.php");
-                        print_footer($course);
-                        exit;
-                    }
-                break;
-                case TRUEFALSE:
-                    // FIXME - instead of deleting, update existing answers
-                    //         so as not to break existing references to them
-                    delete_records("quiz_answers", "question", $question->id);
-                    delete_records("quiz_truefalse", "question", $question->id);
-    
-                    $true->answer   = get_string("true", "quiz");
-                    $true->question = $question->id;
-                    $true->fraction = $form->answer;
-                    $true->feedback = $form->feedbacktrue;
-                    if (!$true->id = insert_record("quiz_answers", $true)) {
-                        error("Could not insert quiz answer \"true\")!");
-                    }
-    
-                    $false->answer   = get_string("false", "quiz");
-                    $false->question = $question->id;
-                    $false->fraction = 1 - (int)$form->answer;
-                    $false->feedback = $form->feedbackfalse;
-                    if (!$false->id = insert_record("quiz_answers", $false)) {
-                        error("Could not insert quiz answer \"false\")!");
-                    }
-    
-                    unset($options);
-                    $options->question    = $question->id;
-                    $options->trueanswer  = $true->id;
-                    $options->falseanswer = $false->id;
-                    if (!insert_record("quiz_truefalse", $options)) {
-                        error("Could not insert quiz truefalse options!");
-                    }
-                break;
-                case MULTICHOICE:
-                    // FIXME - instead of deleting, update existing answers
-                    //         so as not to break existing references to them
-                    delete_records("quiz_answers", "question", $question->id);
-                    delete_records("quiz_multichoice", "question", $question->id);
-    
-                    $totalfraction = 0;
-                    $maxfraction = -1;
-    
-                    $answers = array();
-    
-                    // Insert all the new answers
-                    foreach ($form->answer as $key => $formanswer) {
-                        if ($formanswer != "") {
-                            unset($answer);
-                            $answer->answer   = $formanswer;
-                            $answer->question = $question->id;
-                            $answer->fraction = $fraction[$key];
-                            $answer->feedback = $feedback[$key];
-                            if (!$answer->id = insert_record("quiz_answers", $answer)) {
-                                error("Could not insert quiz answer!");
-                            }
-                            $answers[] = $answer->id;
-    
-                            if ($fraction[$key] > 0) {                 // Sanity checks
-                                $totalfraction += $fraction[$key];
-                            }
-                            if ($fraction[$key] > $maxfraction) {
-                                $maxfraction = $fraction[$key];
-                            }
-                        }
-                    }
-    
-                    unset($options);
-                    $options->question = $question->id;
-                    $options->answers = implode(",",$answers);
-                    $options->single = $form->single;
-                    if (!insert_record("quiz_multichoice", $options)) {
-                        error("Could not insert quiz multichoice options!");
-                    }
-    
-                    /// Perform sanity checks on fractional grades
-                    if ($options->single) {
-                        if ($maxfraction != 1) {
-                            $maxfraction = $maxfraction * 100;
-                            notice_yesno(get_string("fractionsnomax", "quiz", $maxfraction), "question.php?id=$question->id", "edit.php");
-                            print_footer($course);
-                            exit;
-                        }
-                    } else {
-                        $totalfraction = round($totalfraction,2);
-                        if ($totalfraction != 1) {
-                            $totalfraction = $totalfraction * 100;
-                            notice_yesno(get_string("fractionsaddwrong", "quiz", $totalfraction), "question.php?id=$question->id", "edit.php");
-                            print_footer($course);
-                            exit;
-                        }
-                    }
-                break;
-                case RANDOM:
-                    echo "<P>Not supported yet</P>";
-                break;
-                default:
-                    error("Non-existent question type!");
-                break;
+
+            $form->id       = $question->id;
+            $form->qtype    = $question->qtype;
+            $form->category = $question->category;
+
+            $result = quiz_save_question_options($form);
+
+            if (!empty($result->error)) {
+                error($result->error);
+            }
+
+            if (!empty($result->notice)) {
+                notice_yesno($result->notice, "question.php?id=$question->id", "edit.php");
+                print_footer($course);
+                exit;
             }
     
             redirect("edit.php");
index 55847316e2de448cb688628397b178d62e70bd16..2c47acbdb53297a3f0d52e693394615ee9962c34 100644 (file)
@@ -5,7 +5,7 @@
 //  This fragment is called by moodle_needs_upgrading() and /admin/index.php
 ////////////////////////////////////////////////////////////////////////////////
 
-$module->version  = 2003010301;   // The (date) version of this module
+$module->version  = 2003021600;   // The (date) version of this module
 $module->cron     = 0;            // How often should cron check this module (seconds)?
 
 ?>