Skip to content

Commit

Permalink
MDL-77625 question restore: fix pre-parsing of questions
Browse files Browse the repository at this point in the history
Restore of categories and questions happens in several phases.
First, the file is scanned for which questions and categories
it contains, to work out if these are new questions which need
to be restored, or if they already exist in the database in a
place that can be used.

That code had not been updated to copy with the Moodle 4.0
versionning changes, so it is updated here (while still keeping
the code to cope with the old backup format.)
  • Loading branch information
timhunt committed Sep 17, 2024
1 parent 49d8bab commit 259bd79
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
7 changes: 3 additions & 4 deletions backup/util/dbops/restore_dbops.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,7 @@ public static function prechek_precheck_qbanks_by_level($restoreid, $courseid, $
$questions = self::restore_get_questions($restoreid, $category->id);

// Collect all the questions for this category into memory so we only talk to the DB once.
$questioncache = $DB->get_records_sql_menu('SELECT q.id,
q.stamp
$questioncache = $DB->get_records_sql_menu('SELECT q.stamp, q.id
FROM {question} q
JOIN {question_versions} qv
ON qv.questionid = q.id
Expand All @@ -683,8 +682,8 @@ public static function prechek_precheck_qbanks_by_level($restoreid, $courseid, $
WHERE qc.id = ?', array($matchcat->id));

foreach ($questions as $question) {
if (isset($questioncache[$question->stamp." ".$question->version])) {
$matchqid = $questioncache[$question->stamp." ".$question->version];
if (isset($questioncache[$question->stamp])) {
$matchqid = $questioncache[$question->stamp];
} else {
$matchqid = false;
}
Expand Down
28 changes: 21 additions & 7 deletions backup/util/helper/restore_questions_parser_processor.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,44 @@
* TODO: Complete phpdocs
*/
class restore_questions_parser_processor extends grouped_parser_processor {
/** @var string XML path in the questions.xml backup file to question categories. */
protected const CATEGORY_PATH = '/question_categories/question_category';

protected $restoreid;
protected $lastcatid;
/** @var string XML path in the questions.xml to question elements within question_category (Moodle 4.0+). */
protected const QUESTION_SUBPATH =
'/question_bank_entries/question_bank_entry/question_version/question_versions/questions/question';

/** @var string XML path in the questions.xml to question elements within question_category (before Moodle 4.0). */
protected const LEGACY_QUESTION_SUBPATH = '/questions/question';

/** @var string identifies the current restore. */
protected string $restoreid;

/** @var int during the restore, this tracks the last category we saw. Any questions we see will be in here. */
protected int $lastcatid;

public function __construct($restoreid) {
$this->restoreid = $restoreid;
$this->lastcatid = 0;
parent::__construct(array());
parent::__construct();
// Set the paths we are interested on
$this->add_path('/question_categories/question_category');
$this->add_path('/question_categories/question_category/questions/question');
$this->add_path(self::CATEGORY_PATH);
$this->add_path(self::CATEGORY_PATH . self::QUESTION_SUBPATH);
$this->add_path(self::CATEGORY_PATH . self::LEGACY_QUESTION_SUBPATH);
}

protected function dispatch_chunk($data) {
// Prepare question_category record
if ($data['path'] == '/question_categories/question_category') {
if ($data['path'] == self::CATEGORY_PATH) {
$info = (object)$data['tags'];
$itemname = 'question_category';
$itemid = $info->id;
$parentitemid = $info->contextid;
$this->lastcatid = $itemid;

// Prepare question record
} else if ($data['path'] == '/question_categories/question_category/questions/question') {
} else if ($data['path'] == self::CATEGORY_PATH . self::QUESTION_SUBPATH ||
$data['path'] == self::CATEGORY_PATH . self::LEGACY_QUESTION_SUBPATH) {
$info = (object)$data['tags'];
$itemname = 'question';
$itemid = $info->id;
Expand Down

0 comments on commit 259bd79

Please sign in to comment.