--- /dev/null
+<?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;
+ }
+
+}
+
+?>
--- /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;
+ }
+}
+
+?>
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;
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\">";