mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 04:30:15 +01:00
MDL-34306 gift question format: allow import of general feedback
This change introduces #### as a separator for general feedback. You need to add ####General feedback goes here as the last thing inside the {...}. For example // question: 123 name: Shortanswer ::Shortanswer::Which is the best animal?{ =Frog#Good! =%50%Cat#What is it with Moodlers and cats? =%0%*#Completely wrong ####Here is some general feedback! } Note that this change is not entirely backwards compatible. It will break any existing GIFT file where the character sequence #### us used between the {} as part of the question. This seems highly unlikely.
This commit is contained in:
parent
d71c486507
commit
19de315e83
@ -213,42 +213,56 @@ class qformat_gift extends qformat_default {
|
||||
$question->name = false;
|
||||
}
|
||||
|
||||
|
||||
// FIND ANSWER section
|
||||
// no answer means its a description
|
||||
// Find the answer section.
|
||||
$answerstart = strpos($text, '{');
|
||||
$answerfinish = strpos($text, '}');
|
||||
|
||||
$description = false;
|
||||
if (($answerstart === false) and ($answerfinish === false)) {
|
||||
if ($answerstart === false && $answerfinish === false) {
|
||||
// No answer means it's a description.
|
||||
$description = true;
|
||||
$answertext = '';
|
||||
$answerlength = 0;
|
||||
} else if (!(($answerstart !== false) and ($answerfinish !== false))) {
|
||||
|
||||
} else if ($answerstart === false || $answerfinish === false) {
|
||||
$this->error(get_string('braceerror', 'qformat_gift'), $text);
|
||||
return false;
|
||||
|
||||
} else {
|
||||
$answerlength = $answerfinish - $answerstart;
|
||||
$answertext = trim(substr($text, $answerstart + 1, $answerlength - 1));
|
||||
}
|
||||
|
||||
// Format QUESTION TEXT without answer, inserting "_____" as necessary
|
||||
// Format the question text, without answer, inserting "_____" as necessary.
|
||||
if ($description) {
|
||||
$questiontext = $text;
|
||||
} else if (substr($text, -1) == "}") {
|
||||
// no blank line if answers follow question, outside of closing punctuation
|
||||
$questiontext = substr_replace($text, "", $answerstart, $answerlength+1);
|
||||
// No blank line if answers follow question, outside of closing punctuation.
|
||||
$questiontext = substr_replace($text, "", $answerstart, $answerlength + 1);
|
||||
} else {
|
||||
// inserts blank line for missing word format
|
||||
$questiontext = substr_replace($text, "_____", $answerstart, $answerlength+1);
|
||||
// Inserts blank line for missing word format.
|
||||
$questiontext = substr_replace($text, "_____", $answerstart, $answerlength + 1);
|
||||
}
|
||||
|
||||
// Get questiontext format from questiontext
|
||||
// Look to see if there is any general feedback.
|
||||
$gfseparator = strrpos($answertext, '####');
|
||||
if ($gfseparator === false) {
|
||||
$generalfeedback = '';
|
||||
} else {
|
||||
$generalfeedback = substr($answertext, $gfseparator + 4);
|
||||
$answertext = trim(substr($answertext, 0, $gfseparator));
|
||||
}
|
||||
|
||||
// Get questiontext format from questiontext.
|
||||
$text = $this->parse_text_with_format($questiontext);
|
||||
$question->questiontextformat = $text['format'];
|
||||
$question->generalfeedbackformat = $text['format'];
|
||||
$question->questiontext = $text['text'];
|
||||
|
||||
// Get generalfeedback format from questiontext.
|
||||
$text = $this->parse_text_with_format($generalfeedback, $question->questiontextformat);
|
||||
$question->generalfeedback = $text['text'];
|
||||
$question->generalfeedbackformat = $text['format'];
|
||||
|
||||
// set question name if not already set
|
||||
if ($question->name === false) {
|
||||
$question->name = $question->questiontext;
|
||||
@ -609,6 +623,27 @@ class qformat_gift extends qformat_default {
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the general feedback for the question, if any. This needs to be the
|
||||
* last thing before the }.
|
||||
* @param object $question the question data.
|
||||
* @param string $indent to put before the general feedback. Defaults to a tab.
|
||||
* If this is not blank, a newline is added after the line.
|
||||
*/
|
||||
public function write_general_feedback($question, $indent = "\t") {
|
||||
$generalfeedback = $this->write_questiontext($question->generalfeedback,
|
||||
$question->generalfeedbackformat, $question->questiontextformat);
|
||||
|
||||
if ($generalfeedback) {
|
||||
$generalfeedback = '####' . $generalfeedback;
|
||||
if ($indent) {
|
||||
$generalfeedback = $indent . $generalfeedback . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $generalfeedback;
|
||||
}
|
||||
|
||||
public function writequestion($question) {
|
||||
global $OUTPUT;
|
||||
|
||||
@ -631,7 +666,9 @@ class qformat_gift extends qformat_default {
|
||||
case ESSAY:
|
||||
$expout .= $this->write_name($question->name);
|
||||
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
|
||||
$expout .= "{}\n";
|
||||
$expout .= "{";
|
||||
$expout .= $this->write_general_feedback($question, '');
|
||||
$expout .= "}\n";
|
||||
break;
|
||||
|
||||
case TRUEFALSE:
|
||||
@ -662,6 +699,7 @@ class qformat_gift extends qformat_default {
|
||||
if ($rightfeedback) {
|
||||
$expout .= '#' . $rightfeedback;
|
||||
}
|
||||
$expout .= $this->write_general_feedback($question, '');
|
||||
$expout .= "}\n";
|
||||
break;
|
||||
|
||||
@ -686,6 +724,7 @@ class qformat_gift extends qformat_default {
|
||||
}
|
||||
$expout .= "\n";
|
||||
}
|
||||
$expout .= $this->write_general_feedback($question);
|
||||
$expout .= "}\n";
|
||||
break;
|
||||
|
||||
@ -699,6 +738,7 @@ class qformat_gift extends qformat_default {
|
||||
'#' . $this->write_questiontext($answer->feedback,
|
||||
$answer->feedbackformat, $question->questiontextformat) . "\n";
|
||||
}
|
||||
$expout .= $this->write_general_feedback($question);
|
||||
$expout .= "}\n";
|
||||
break;
|
||||
|
||||
@ -717,6 +757,7 @@ class qformat_gift extends qformat_default {
|
||||
$answer->feedbackformat, $question->questiontextformat) . "\n";
|
||||
}
|
||||
}
|
||||
$expout .= $this->write_general_feedback($question);
|
||||
$expout .= "}\n";
|
||||
break;
|
||||
|
||||
@ -729,6 +770,7 @@ class qformat_gift extends qformat_default {
|
||||
$subquestion->questiontextformat, $question->questiontextformat) .
|
||||
' -> ' . $this->repchar($subquestion->answertext) . "\n";
|
||||
}
|
||||
$expout .= $this->write_general_feedback($question);
|
||||
$expout .= "}\n";
|
||||
break;
|
||||
|
||||
|
@ -37,9 +37,10 @@
|
||||
=%0%*#Completely wrong
|
||||
}
|
||||
|
||||
// true/false
|
||||
// true/false, with general feedback
|
||||
::Q1:: 42 is the Absolute Answer to everything.{
|
||||
FALSE#42 is the Ultimate Answer.#You gave the right answer.}";
|
||||
FALSE#42 is the Ultimate Answer.#You gave the right answer.
|
||||
####This is, of course, a Hitchiker's Guide to the Galaxy reference.}";
|
||||
|
||||
// name 0-11
|
||||
::2-08 TSL::TSL is blablabla.{T}
|
||||
|
@ -673,6 +673,62 @@ class qformat_gift_test extends question_testcase {
|
||||
$this->assert(new question_check_specified_fields_expectation($expectedq), $q);
|
||||
}
|
||||
|
||||
public function test_import_shortanswer_with_general_feedback() {
|
||||
$gift = "
|
||||
// question: 666 name: Shortanswer
|
||||
::Shortanswer::Which is the best animal?{
|
||||
=Frog#Good!
|
||||
=%50%Cat#What is it with Moodlers and cats?
|
||||
=%0%*#Completely wrong
|
||||
####[html]Here is some general feedback!
|
||||
}";
|
||||
$lines = preg_split('/[\\n\\r]/', str_replace("\r\n", "\n", $gift));
|
||||
|
||||
$importer = new qformat_gift();
|
||||
$q = $importer->readquestion($lines);
|
||||
|
||||
$expectedq = (object) array(
|
||||
'name' => 'Shortanswer',
|
||||
'questiontext' => "Which is the best animal?",
|
||||
'questiontextformat' => FORMAT_MOODLE,
|
||||
'generalfeedback' => 'Here is some general feedback!',
|
||||
'generalfeedbackformat' => FORMAT_HTML,
|
||||
'qtype' => 'shortanswer',
|
||||
'defaultmark' => 1,
|
||||
'penalty' => 0.3333333,
|
||||
'length' => 1,
|
||||
'answer' => array(
|
||||
'Frog',
|
||||
'Cat',
|
||||
'*',
|
||||
),
|
||||
'fraction' => array(1, 0.5, 0),
|
||||
'feedback' => array(
|
||||
0 => array(
|
||||
'text' => 'Good!',
|
||||
'format' => FORMAT_MOODLE,
|
||||
'files' => array(),
|
||||
),
|
||||
1 => array(
|
||||
'text' => "What is it with Moodlers and cats?",
|
||||
'format' => FORMAT_MOODLE,
|
||||
'files' => array(),
|
||||
),
|
||||
2 => array(
|
||||
'text' => "Completely wrong",
|
||||
'format' => FORMAT_MOODLE,
|
||||
'files' => array(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Repeated test for better failure messages.
|
||||
$this->assertEquals($expectedq->answer, $q->answer);
|
||||
$this->assertEquals($expectedq->fraction, $q->fraction);
|
||||
$this->assertEquals($expectedq->feedback, $q->feedback);
|
||||
$this->assert(new question_check_specified_fields_expectation($expectedq), $q);
|
||||
}
|
||||
|
||||
public function test_export_shortanswer() {
|
||||
$qdata = (object) array(
|
||||
'id' => 666 ,
|
||||
@ -728,6 +784,67 @@ class qformat_gift_test extends question_testcase {
|
||||
\t=%0%*#Completely wrong
|
||||
}
|
||||
|
||||
";
|
||||
|
||||
$this->assert_same_gift($expectedgift, $gift);
|
||||
}
|
||||
|
||||
public function test_export_shortanswer_with_general_feedback() {
|
||||
$qdata = (object) array(
|
||||
'id' => 666 ,
|
||||
'name' => 'Shortanswer',
|
||||
'questiontext' => "Which is the best animal?",
|
||||
'questiontextformat' => FORMAT_MOODLE,
|
||||
'generalfeedback' => 'Here is some general feedback!',
|
||||
'generalfeedbackformat' => FORMAT_HTML,
|
||||
'defaultmark' => 1,
|
||||
'penalty' => 1,
|
||||
'length' => 1,
|
||||
'qtype' => 'shortanswer',
|
||||
'options' => (object) array(
|
||||
'id' => 123,
|
||||
'question' => 666,
|
||||
'usecase' => 1,
|
||||
'answers' => array(
|
||||
1 => (object) array(
|
||||
'id' => 1,
|
||||
'answer' => 'Frog',
|
||||
'answerformat' => 0,
|
||||
'fraction' => 1,
|
||||
'feedback' => 'Good!',
|
||||
'feedbackformat' => FORMAT_MOODLE,
|
||||
),
|
||||
2 => (object) array(
|
||||
'id' => 2,
|
||||
'answer' => 'Cat',
|
||||
'answerformat' => 0,
|
||||
'fraction' => 0.5,
|
||||
'feedback' => "What is it with Moodlers and cats?",
|
||||
'feedbackformat' => FORMAT_MOODLE,
|
||||
),
|
||||
3 => (object) array(
|
||||
'id' => 3,
|
||||
'answer' => '*',
|
||||
'answerformat' => 0,
|
||||
'fraction' => 0,
|
||||
'feedback' => "Completely wrong",
|
||||
'feedbackformat' => FORMAT_MOODLE,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$exporter = new qformat_gift();
|
||||
$gift = $exporter->writequestion($qdata);
|
||||
|
||||
$expectedgift = "// question: 666 name: Shortanswer
|
||||
::Shortanswer::Which is the best animal?{
|
||||
\t=%100%Frog#Good!
|
||||
\t=%50%Cat#What is it with Moodlers and cats?
|
||||
\t=%0%*#Completely wrong
|
||||
\t####[html]Here is some general feedback!
|
||||
}
|
||||
|
||||
";
|
||||
|
||||
$this->assert_same_gift($expectedgift, $gift);
|
||||
|
Loading…
x
Reference in New Issue
Block a user