In passing, I fixed MDL-6297 Export of multichoice questions in Moodle XML format doesn't save shuffle option too.
--- /dev/null
+<?php
+/*
+ * Created on Aug 20, 2006
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - PHPeclipse - PHP - Code Templates
+ */
+
+$string['answersingleno'] = 'Multiple answers allowed';
+$string['answersingleyes'] = 'One answer only';
+$string['choiceno'] = 'Choice $a';
+$string['choices'] = 'Available choices';
+$string['editingmultichoice'] = 'Editing a Multiple Choice question';
+$string['fillouttwochoices'] = 'You must fill out at least two choices. Choices left blank will not be used.';
+$string['fractionsaddwrong'] = 'The positive grades you have chosen do not add up to 100%%<br />Instead, they add up to $a%%<br />Do you want to go back and fix this question?';
+$string['fractionsnomax'] = 'One of the answers should be 100%%, so that it is<br />possible to get a full grade for this question.<br />Do you want to go back and fix this question?';
+$string['feedback'] = 'Feedback';
+$string['notenoughanswers'] = 'This type of question requires at least $a answers';
+$string['overallcorrectfeedback'] = 'Feedback for any correct answer';
+$string['overallpartiallycorrectfeedback'] = 'Feedback for any partially correct answer';
+$string['overallincorrectfeedback'] = 'Feedback for any incorrect answer';
+$string['shuffleanswers'] = 'Shuffle answers';
+$string['singleanswer'] = 'Choose one answer.';
+
+?>
return addslashes(trim( $data ));
}
+ /**
+ * Process text from an element in the XML that may or not be there.
+ * @param string $subelement the name of the element which is either present or missing.
+ * @param array $question a bit of xml tree, this method looks for $question['#'][$subelement][0]['#']['text'].
+ * @return string If $subelement is present, return the content of the text tag inside it.
+ * Otherwise returns an empty string.
+ */
+ function import_optional_text($subelement, $question) {
+ if (array_key_exists($subelement, $question['#'])) {
+ return $this->import_text($question['#'][$subelement][0]['#']['text']);
+ } else {
+ return '';
+ }
+ }
+
/**
* import parts of question common to all types
* @param array question question array from xml tree
$qo->qtype = MULTICHOICE;
$single = $question['#']['single'][0]['#'];
$qo->single = $this->trans_single( $single );
-
+ if (array_key_exists('shuffleanswers', $question['#'])) {
+ $shuffleanswers = $question['#']['shuffleanswers'][0]['#'];
+ } else {
+ $shuffleanswers = 'false';
+ }
+ $qo->$shuffleanswers = $this->trans_single($shuffleanswers);
+ $qo->correctfeedback = $this->import_optional_text('correctfeedback', $question);
+ $qo->partiallycorrectfeedback = $this->import_optional_text('partiallycorrectfeedback', $question);
+ $qo->incorrectfeedback = $this->import_optional_text('incorrectfeedback', $question);
+
// run through the answers
$answers = $question['#']['answer'];
$a_count = 0;
break;
case MULTICHOICE:
$expout .= " <single>".$this->get_single($question->options->single)."</single>\n";
+ $expout .= " <shuffleanswers>".$this->get_single($question->options->shuffleanswers)."</shuffleanswers>\n";
+ $expout .= " <correctfeedback>".$this->writetext($question->options->correctfeedback, 3)."</correctfeedback>\n";
+ $expout .= " <partiallycorrectfeedback>".$this->writetext($question->options->partiallycorrectfeedback, 3)."</partiallycorrectfeedback>\n";
+ $expout .= " <incorrectfeedback>".$this->writetext($question->options->incorrectfeedback, 3)."</incorrectfeedback>\n";
foreach($question->options->answers as $answer) {
$percent = $answer->fraction * 100;
$expout .= " <answer fraction=\"$percent\">\n";
$state->grade = backup_todb($res_info['#']['GRADE']['0']['#']);
$state->raw_grade = backup_todb($res_info['#']['RAW_GRADE']['0']['#']);
$state->penalty = backup_todb($res_info['#']['PENALTY']['0']['#']);
+ $state->oldid = $oldid; // So it is available to restore_recode_answer.
//We have to recode the question field
$question = backup_getid($restore->backup_unique_code,"question",$state->question);
function qtype_multichoice_upgrade($oldversion=0) {
global $CFG;
-
- return true;
+ $success = true;
+
+ if ($success && $oldversion < 2006081900) {
+ $success = $success && table_column('question_multichoice', '', 'correctfeedback', 'text', '', '', '');
+ $success = $success && table_column('question_multichoice', '', 'partiallycorrectfeedback', 'text', '', '', '');
+ $success = $success && table_column('question_multichoice', '', 'incorrectfeedback', 'text', '', '', '');
+ }
+
+ return $success;
}
?>
answers varchar(255) NOT NULL default '',
single tinyint(4) NOT NULL default '0',
shuffleanswers tinyint(4) NOT NULL default '1',
+ correctfeedback text NOT NULL default '',
+ partiallycorrectfeedback text NOT NULL default '',
+ incorrectfeedback text NOT NULL default '',
PRIMARY KEY (id),
KEY question (question)
) TYPE=MyISAM COMMENT='Options for multiple choice questions';
function qtype_multichoice_upgrade($oldversion=0) {
global $CFG;
-
- return true;
+ $success = true;
+
+ if ($success && $oldversion < 2006081900) {
+ $success = $success && table_column('question_multichoice', '', 'correctfeedback', 'text', '', '', '');
+ $success = $success && table_column('question_multichoice', '', 'partiallycorrectfeedback', 'text', '', '', '');
+ $success = $success && table_column('question_multichoice', '', 'incorrectfeedback', 'text', '', '', '');
+ }
+
+ return $success;
}
?>
layout integer NOT NULL default '0',
answers varchar(255) NOT NULL default '',
single integer NOT NULL default '0',
- shuffleanswers integer NOT NULL default '1'
+ shuffleanswers integer NOT NULL default '1',
+ correctfeedback text NOT NULL default '',
+ partiallycorrectfeedback text NOT NULL default '',
+ incorrectfeedback text NOT NULL default ''
);
CREATE INDEX prefix_question_multichoice_question_idx ON prefix_question_multichoice (question);
</tr>
<?php } ?>
</table>
+ <?php if ($feedback) { ?>
+ <div class="feedback">
+ <?php echo $feedback ?>
+ </div>
+ <?php } ?>
<?php $this->print_question_submit_buttons($question, $state, $cmoptions, $options); ?>
</div>
$QTYPES[$question->qtype]->print_question_form_start($question, array(), $course, $usehtmleditor);
?>
<tr valign="top">
- <td align="right"><b><?php print_string("answerhowmany", "quiz") ?>:</b></td>
+ <td align="right"><b><?php print_string("answerhowmany", "qtype_multichoice") ?>:</b></td>
<td align="left">
<?php
- $menu[0] = get_string("answersingleno", "quiz");
- $menu[1] = get_string("answersingleyes", "quiz");
+ $menu[0] = get_string("answersingleno", "qtype_multichoice");
+ $menu[1] = get_string("answersingleyes", "qtype_multichoice");
choose_from_menu($menu, "single", "$options->single", "");
unset($menu);
?>
</td>
</tr>
<tr valign="top">
- <td align="right"><b><?php print_string("shuffleanswers", "quiz") ?>:</b></td>
+ <td align="right"><b><?php print_string("shuffleanswers", "qtype_multichoice") ?>:</b></td>
<td align="left">
<?php
choose_from_menu($yesnooptions, "shuffleanswers", "$options->shuffleanswers", "");
- helpbutton("multichoiceshuffle", get_string("shuffleanswers","quiz"), "quiz");
+ helpbutton("multichoiceshuffle", get_string("shuffleanswers","qtype_multichoice"), "quiz");
?>
</td>
</tr>
<tr valign="top">
- <td align="right"><b><?php print_string("choices", "quiz") ?></b>:</td>
- <td align="left"><?php print_string("fillouttwochoices", "quiz") ?></td>
+ <td align="right"><b><?php print_string("choices", "qtype_multichoice") ?></b>:</td>
+ <td align="left"><?php print_string("fillouttwochoices", "qtype_multichoice") ?></td>
</tr>
<?php
?>
<tr valign="top">
- <td align="right"><b><?php echo get_string("choice", "quiz")." $i"; ?>:</b></td>
+ <td align="right"><b><?php print_string("choiceno", "qtype_multichoice", $i); ?>:</b></td>
<td align="left">
- <input type="text" name="answer[]" size="50" value="<?php p($answers[$i-1]->answer) ?>" alt="<?php echo get_string("choice", "quiz")." $i"; ?>"/>
+ <input type="text" name="answer[]" size="50" value="<?php p($answers[$i-1]->answer) ?>" />
<?php
print_string("grade");
echo ": ";
</tr>
<tr valign="top">
- <td align="right"><b><?php print_string("feedback", "quiz") ?>:</b></td>
+ <td align="right"><b><?php print_string("feedback", "qtype_multichoice") ?>:</b></td>
<td align="left">
<textarea name="feedback[]" rows="2" cols="50"><?php p($answers[$i-1]->feedback) ?></textarea>
</td>
<?php
} /// End of loop, printing answers
+?>
+ <tr valign="top">
+ <td align="right"><b><?php print_string("overallcorrectfeedback", "qtype_multichoice") ?>:</b></td>
+ <td align="left">
+ <textarea name="correctfeedback" rows="4" cols="50"><?php p($options->correctfeedback) ?></textarea>
+ </td>
+ </tr>
+
+ <tr valign="top">
+ <td align="right"><b><?php print_string("overallpartiallycorrectfeedback", "qtype_multichoice") ?>:</b></td>
+ <td align="left">
+ <textarea name="partiallycorrectfeedback" rows="4" cols="50"><?php p($options->partiallycorrectfeedback) ?></textarea>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td align="right"><b><?php print_string("overallincorrectfeedback", "qtype_multichoice") ?>:</b></td>
+ <td align="left">
+ <textarea name="incorrectfeedback" rows="4" cols="50"><?php p($options->incorrectfeedback) ?></textarea>
+ </td>
+ </tr>
+
+ <tr valign="top">
+ <td colspan="2"> </td>
+ </tr>
+
+<?php
$QTYPES[$question->qtype]->print_replacement_options($question, $course, $contextquiz);
$QTYPES[$question->qtype]->print_question_form_end($question);
?>
} else {
$options->single = 1;
$options->shuffleanswers = 1;
+ $options->correctfeedback = '';
+ $options->partiallycorrectfeedback = '';
+ $options->incorrectfeedback = '';
}
if (!empty($options->answers)) {
$answersraw = get_records_list("question_answers", "id", $options->answers);
$yesnooptions[0] = get_string("no");
$yesnooptions[1] = get_string("yes");
- print_heading_with_help(get_string("editingmultichoice", "quiz"), "multichoice", "quiz");
+ print_heading_with_help(get_string("editingmultichoice", "qtype_multichoice"), "multichoice", "quiz");
require("$CFG->dirroot/question/type/multichoice/editquestion.html");
?>
}
function save_question_options($question) {
-
+ $result = new stdClass;
if (!$oldanswers = get_records("question_answers", "question",
$question->id, "id ASC")) {
$oldanswers = array();
}
$answercount += count($oldanswers);
if ($answercount < 2) { // check there are at lest 2 answers for multiple choice
- $result->notice = get_string("notenoughanswers", "quiz", "2");
+ $result->notice = get_string("notenoughanswers", "qtype_multichoice", "2");
return $result;
}
}
}
- if ($options = get_record("question_multichoice", "question", $question->id)) {
- $options->answers = implode(",",$answers);
- $options->single = $question->single;
- $options->shuffleanswers = $question->shuffleanswers;
+ $update = true;
+ $options = get_record("question_multichoice", "question", $question->id);
+ if (!$options) {
+ $update = false;
+ $options = new stdClass;
+ $options->question = $question->id;
+
+ }
+ $options->answers = implode(",",$answers);
+ $options->single = $question->single;
+ $options->shuffleanswers = $question->shuffleanswers;
+ $options->correctfeedback = trim($question->correctfeedback);
+ $options->partiallycorrectfeedback = trim($question->partiallycorrectfeedback);
+ $options->incorrectfeedback = trim($question->incorrectfeedback);
+ if ($update) {
if (!update_record("question_multichoice", $options)) {
$result->error = "Could not update quiz multichoice options! (id=$options->id)";
return $result;
}
} else {
- unset($options);
- $options->question = $question->id;
- $options->answers = implode(",",$answers);
- $options->single = $question->single;
- $options->shuffleanswers = $question->shuffleanswers;
if (!insert_record("question_multichoice", $options)) {
$result->error = "Could not insert quiz multichoice options!";
return $result;
if ($options->single) {
if ($maxfraction != 1) {
$maxfraction = $maxfraction * 100;
- $result->noticeyesno = get_string("fractionsnomax", "quiz", $maxfraction);
+ $result->noticeyesno = get_string("fractionsnomax", "qtype_multichoice", $maxfraction);
return $result;
}
} else {
$totalfraction = round($totalfraction,2);
if ($totalfraction != 1) {
$totalfraction = $totalfraction * 100;
- $result->noticeyesno = get_string("fractionsaddwrong", "quiz", $totalfraction);
+ $result->noticeyesno = get_string("fractionsaddwrong", "qtype_multichoice", $totalfraction);
return $result;
}
}
? 'checked="checked"' : '';
}
+ $a = new stdClass;
$a->id = $question->name_prefix . $aid;
// Print the control
$anss[] = clone($a);
}
+
+ $feedback = '';
+ if ($options->feedback) {
+ if ($state->raw_grade >= $question->maxgrade/1.01) {
+ $feedback = $question->options->correctfeedback;
+ } else if ($state->raw_grade > 0) {
+ $feedback = $question->options->partiallycorrectfeedback;
+ } else {
+ $feedback = $question->options->incorrectfeedback;
+ }
+ $feedback = format_text($feedback,
+ $question->questiontextformat,
+ $formatoptions, $cmoptions->course);
+ }
+
include("$CFG->dirroot/question/type/multichoice/display.html");
}
fwrite ($bf,full_tag("ANSWERS",$level+1,false,$multichoice->answers));
fwrite ($bf,full_tag("SINGLE",$level+1,false,$multichoice->single));
fwrite ($bf,full_tag("SHUFFLEANSWERS",$level+1,false,$multichoice->shuffleanswers));
+ fwrite ($bf,full_tag("CORRECTFEEDBACK",$level+1,false,$multichoice->correctfeedback));
+ fwrite ($bf,full_tag("PARTIALLYCORRECTFEEDBACK",$level+1,false,$multichoice->partiallycorrectfeedback));
+ fwrite ($bf,full_tag("INCORRECTFEEDBACK",$level+1,false,$multichoice->incorrectfeedback));
$status = fwrite ($bf,end_tag("MULTICHOICE",$level,true));
}
$mul_info = $multichoices[$i];
//Now, build the question_multichoice record structure
+ $multichoice = new stdClass;
$multichoice->question = $new_question_id;
$multichoice->layout = backup_todb($mul_info['#']['LAYOUT']['0']['#']);
$multichoice->answers = backup_todb($mul_info['#']['ANSWERS']['0']['#']);
$multichoice->single = backup_todb($mul_info['#']['SINGLE']['0']['#']);
$multichoice->shuffleanswers = backup_todb($mul_info['#']['SHUFFLEANSWERS']['0']['#']);
+ if (array_key_exists("CORRECTFEEDBACK", $mul_info['#'])) {
+ $multichoice->correctfeedback = backup_todb($mul_info['#']['CORRECTFEEDBACK']['0']['#']);
+ } else {
+ $multichoice->correctfeedback = '';
+ }
+ if (array_key_exists("PARTIALLYCORRECTFEEDBACK", $mul_info['#'])) {
+ $multichoice->partiallycorrectfeedback = backup_todb($mul_info['#']['PARTIALLYCORRECTFEEDBACK']['0']['#']);
+ } else {
+ $multichoice->partiallycorrectfeedback = '';
+ }
+ if (array_key_exists("INCORRECTFEEDBACK", $mul_info['#'])) {
+ $multichoice->incorrectfeedback = backup_todb($mul_info['#']['INCORRECTFEEDBACK']['0']['#']);
+ } else {
+ $multichoice->incorrectfeedback = '';
+ }
//We have to recode the answers field (a list of answers id)
//Extracts answer id from sequence
if ($answer) {
$order[$key] = $answer->new_id;
} else {
- echo 'Could not recode multichoice answer id '.$oldansid.' for state '.$oldid.'<br />';
+ echo 'Could not recode multichoice answer id '.$oldansid.' for state '.$state->oldid.'<br />';
}
}
}
if ($answer) {
$responses[$key] = $answer->new_id;
} else {
- echo 'Could not recode multichoice response answer id '.$oldansid.' for state '.$oldid.'<br />';
+ echo 'Could not recode multichoice response answer id '.$oldansid.' for state '.$state->oldid.'<br />';
}
}
}
<?PHP // $Id$
-$plugin->version = 2006032200;
+$plugin->version = 2006081900;
$plugin->requires = 2006032200;
?>
.truefalse .answer {
background-color: #EEE;
}
-.calculated .feedback,
-.numerical .feedback,
-.shortanswer .feedback,
-.truefalse .feedback {
+.que .feedback {
border-color: #DDD;
}
.que.multianswer .incorrect {
padding: 0 0 0.3em 0.3em;
border: 1px solid;
}
-.multichoice .feedback {
+.multichoice td.feedback {
width: auto;
vertical-align: top;
padding-top: 0.3em;