MDL-77625 question restore: fix pre-parsing of questions

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 cope with the Moodle 4.0
versioning changes, so it is updated here (while still keeping
the code to cope with the old backup format.)
This commit is contained in:
Tim Hunt 2024-09-03 17:07:58 +02:00
parent f6141a67d8
commit bab665dd40
2 changed files with 24 additions and 11 deletions

View File

@ -671,8 +671,7 @@ abstract class restore_dbops {
$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
@ -683,8 +682,8 @@ abstract class restore_dbops {
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;
}

View File

@ -35,22 +35,35 @@ require_once($CFG->dirroot.'/backup/util/xml/parser/processors/grouped_parser_pr
* 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;
@ -58,7 +71,8 @@ class restore_questions_parser_processor extends grouped_parser_processor {
$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;