mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 00:46:50 +02:00
MDL-39980 question engine: Attempt on last loses response files
When doing Each attempt builds on last, we need to copy any response files into a draft file area, and then re-save them. While writing the unit test for this, I had to deal with a todo in the question engine so that questions with files in the response could be unit-tested. I also found an fixed a bug with qtype_essay_question::is_same_response and fixed some notices in the existing essay/manual graded unit tests.
This commit is contained in:
parent
838d78a9ff
commit
afb1b3d03b
8 changed files with 221 additions and 18 deletions
|
@ -1379,6 +1379,35 @@ class question_file_loader implements question_response_files {
|
|||
public function get_files() {
|
||||
return $this->step->get_qt_files($this->name, $this->contextid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy these files into a draft area, and return the corresponding
|
||||
* {@link question_file_saver} that can save them again.
|
||||
*
|
||||
* This is used by {@link question_attempt::start_based_on()}, which is used
|
||||
* (for example) by the quizzes 'Each attempt builds on last' feature.
|
||||
*
|
||||
* @return question_file_saver that can re-save these files again.
|
||||
*/
|
||||
public function get_question_file_saver() {
|
||||
|
||||
// Value will be either a plain MD5 hash, or some real content, followed
|
||||
// by an MD5 hash in a HTML comment. We only want the value in the latter case.
|
||||
if (preg_match('/\s*<!-- File hash: [0-9a-zA-Z]{32} -->\s*$/', $this->value)) {
|
||||
$value = preg_replace('/\s*<!-- File hash: [0-9a-zA-Z]{32} -->\s*$/', '', $this->value);
|
||||
|
||||
} else if (preg_match('/^[0-9a-zA-Z]{32}$/', $this->value)) {
|
||||
$value = null;
|
||||
|
||||
} else {
|
||||
throw new coding_exception('$value passed to question_file_loader::get_question_file_saver' .
|
||||
' was not of the expected form.');
|
||||
}
|
||||
|
||||
list($draftid, $text) = $this->step->prepare_response_files_draft_itemid_with_text(
|
||||
$this->name, $this->contextid, $value);
|
||||
return new question_file_saver($draftid, 'question', 'response_' . $this->name, $text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -923,7 +923,13 @@ class question_attempt {
|
|||
* @return array name => value pairs.
|
||||
*/
|
||||
protected function get_resume_data() {
|
||||
return $this->behaviour->get_resume_data();
|
||||
$resumedata = $this->behaviour->get_resume_data();
|
||||
foreach ($resumedata as $name => $value) {
|
||||
if ($value instanceof question_file_loader) {
|
||||
$resumedata[$name] = $value->get_question_file_saver();
|
||||
}
|
||||
}
|
||||
return $resumedata;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -975,11 +981,12 @@ class question_attempt {
|
|||
*/
|
||||
protected function process_response_files($name, $draftidname, $postdata = null, $text = null) {
|
||||
if ($postdata) {
|
||||
// There can be no files with test data (at the moment).
|
||||
return null;
|
||||
// For simulated posts, get the draft itemid from there.
|
||||
$draftitemid = $this->get_submitted_var($draftidname, PARAM_INT, $postdata);
|
||||
} else {
|
||||
$draftitemid = file_get_submitted_draft_itemid($draftidname);
|
||||
}
|
||||
|
||||
$draftitemid = file_get_submitted_draft_itemid($draftidname);
|
||||
if (!$draftitemid) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ class question_attempt_step {
|
|||
global $USER;
|
||||
|
||||
if (!is_array($data)) {
|
||||
echo format_backtrace(debug_backtrace());
|
||||
throw new coding_exception('$data must be an array when constructing a question_attempt_step.');
|
||||
}
|
||||
$this->state = question_state::$unprocessed;
|
||||
$this->data = $data;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue