quiz questions. Importing works but is still being tested.
--- /dev/null
+<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>
$string['modulenameplural'] = "Quizzes";
#------------------------------------------------------------
+$string['addquestions'] = "Add questions";
$string['addselectedtoquiz'] = "Add selected to quiz";
$string['allowreview'] = "Allow review";
$string['alwaysavailable'] = "Always available";
$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.";
$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";
$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";
$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";
$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";
}
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;
}
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;
--- /dev/null
+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.
--- /dev/null
+<?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;
+ }
+}
+
+?>
--- /dev/null
+<?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;
+ }
+
+}
+
+?>
--- /dev/null
+<?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;
+ }
+
+}
+
+?>
--- /dev/null
+<?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;
+ }
+
+}
+
+?>
--- /dev/null
+<?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;
+ }
+
+}
+
+?>
--- /dev/null
+<?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);
+
+
+?>
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 ///////////////////////////////////////////////////////////////////
$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");
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> ";
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)) {
}
+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;
+}
+
+
?>
}
$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");
// 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)?
?>