MDL-86524 questions: Delegate filter condition restore to plugins

The core backup code was taking sole responsibility for conversion and
mapping of IDs in set reference filter conditions during restores.
However, it was only actually processing category conditions, not tags
or any of the more recently added conditions.

This adds a new `restore_filtercondition` method to the
`core_question\local\bank\condition` class which can be overridden by
each condition to convert IDs and add mappings during the restore
process.

It also adds a new `maptags` option to
`convert_legacy_set_reference_filter_condition`, so that if we are
doing the conversion during a restore, we don't also create or map
the tags as they are converted. We record ID mappings of the tags
as the are restored, then these can be used by the
`qbank_tagquestions` plugins later to map the converted condition.
This commit is contained in:
Mark Johnson
2026-02-23 11:38:42 +00:00
parent 15557a5fc2
commit b82be2ab8c
5 changed files with 111 additions and 38 deletions
@@ -83,9 +83,11 @@ class question_reference_manager {
* pre-4.3 filter condition structure to the new one.
*
* @param array $filtercondition Pre-4.3 filter condition.
* @param bool $maptags Map tags to tags with the same name, creating them if necessary. If not, just convert existing IDs to
* the new structure.
* @return array Post-4.3 filter condition.
*/
public static function convert_legacy_set_reference_filter_condition(array $filtercondition): array {
public static function convert_legacy_set_reference_filter_condition(array $filtercondition, bool $maptags = true): array {
global $DB;
if (!isset($filtercondition['filter'])) {
$filtercondition['filter'] = [];
@@ -103,10 +105,14 @@ class question_reference_manager {
if (isset($filtercondition['tags'])) {
// Get the names of the tags in the condition. Find or create corresponding tags,
// and set their ids in the new condition.
$oldtags = array_map(fn($oldtag) => explode(',', $oldtag)[1], $filtercondition['tags']);
$questiontagcollid = \core_tag_area::get_collection('core_question', 'question');
$newtags = \core_tag_tag::create_if_missing($questiontagcollid, $oldtags);
$newtagids = array_map(fn($newtag) => $newtag->id, $newtags);
if ($maptags) {
$oldtags = array_map(fn($oldtag) => explode(',', $oldtag)[1], $filtercondition['tags']);
$questiontagcollid = \core_tag_area::get_collection('core_question', 'question');
$newtags = \core_tag_tag::create_if_missing($questiontagcollid, $oldtags);
$newtagids = array_map(fn($newtag) => $newtag->id, $newtags);
} else {
$newtagids = array_map(fn($oldtag) => explode(',', $oldtag)[0], $filtercondition['tags']);
}
$filtercondition['filter']['qtagids'] = [
'jointype' => \qbank_tagquestion\tag_condition::JOINTYPE_DEFAULT,