MDL-86691 questions: Fix incorrect set reference category contexts

During the upgrade to 5.x, question categories are moved to new
mod_qbank module contexts, and any set references using those categories
are updated using `move_question_set_references()`. However, this
function wasn't updating the `cat` arribute of the set reference's
filter condition, leaving it pointing at the original context ID.

This change update `move_question_set_references()` so that when a set
reference is moved (during the 5.x upgrade, or otherwise) the `cat`
parameter will be updated correctly.

For sites that have already gone through the 5.x upgrade, this fix also
adds a CLI script to find and fix incorrect question_set_reference
records. I considered adding this as an upgrade step, but it potentially
has a lot of records to check, and it's redundant if the site is being
upgraded to 5.x with this fix already in place.
This commit is contained in:
Mark Johnson
2026-02-26 15:50:02 +00:00
parent 15557a5fc2
commit b5fd7946f0
6 changed files with 181 additions and 2 deletions
@@ -136,4 +136,33 @@ class question_reference_manager {
}
return $filtercondition;
}
/**
* Ensure consistency of filter 'cat' parameter and questioncontextid in all set references.
*
* Some set references may have been moved to a different context, but the filter condition not updated with the context ID.
* Since the filter condition is JSON-encoded, we have to check each set reference record for inconsistencies.
*
* This is used in a CLI script to fix bad data due to MDL-86691.
*
* @return int The number of records that were updated.
* @todo Deprecate in Moodle 6.0 (MDL-87844) for removal in 7.0 (MDL-87845).
*/
public static function fix_set_references_category_context(): int {
global $DB;
$updates = 0;
$sets = $DB->get_recordset('question_set_references');
foreach ($sets as $set) {
$filtercondition = json_decode($set->filtercondition, true);
[$catid, $catcontext] = explode(',', $filtercondition['cat']);
if ($catcontext != $set->questionscontextid) {
$filtercondition['cat'] = implode(',', [$catid, $set->questionscontextid]);
$set->filtercondition = json_encode($filtercondition);
$DB->update_record('question_set_references', $set);
$updates++;
}
}
$sets->close();
return $updates;
}
}