From 294c77d8f70e2f9faa6d16a5da3d0bf74be7a51a Mon Sep 17 00:00:00 2001 From: Safat Shahin Date: Wed, 30 Mar 2022 14:02:52 +1100 Subject: [PATCH] MDL-74361 quiz: pre4.0 course restore bug fix for random question tags --- .../backup/moodle2/restore_quiz_stepslib.php | 19 ++---- mod/quiz/tests/fixtures/moodle_311_quiz.mbz | Bin 0 -> 4940 bytes mod/quiz/tests/quiz_question_restore_test.php | 57 ++++++++++++++++++ 3 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 mod/quiz/tests/fixtures/moodle_311_quiz.mbz diff --git a/mod/quiz/backup/moodle2/restore_quiz_stepslib.php b/mod/quiz/backup/moodle2/restore_quiz_stepslib.php index c8ceade0f9d..1f1b588766f 100644 --- a/mod/quiz/backup/moodle2/restore_quiz_stepslib.php +++ b/mod/quiz/backup/moodle2/restore_quiz_stepslib.php @@ -416,16 +416,16 @@ class restore_quiz_activity_structure_step extends restore_questions_activity_st } /** - * Process a quiz_slot_tags restore + * Process a quiz_slot_tags to restore the tags to the new structure. * * @param stdClass|array $data The quiz_slot_tags data */ protected function process_quiz_slot_tags($data) { global $DB; - $data = (object)$data; - + $data = (object) $data; $slotid = $this->get_new_parentid('quiz_question_instance'); + if ($this->task->is_samesite() && $tag = core_tag_tag::get($data->tagid, 'id, name')) { $data->tagname = $tag->name; } else if ($tag = core_tag_tag::get_by_name(0, $data->tagname, 'id, name')) { @@ -434,22 +434,13 @@ class restore_quiz_activity_structure_step extends restore_questions_activity_st $data->tagid = null; $data->tagname = $tag->name; } + $tagstring = "{$data->tagid},{$data->tagname}"; $setreferencedata = $DB->get_record('question_set_references', ['itemid' => $slotid, 'component' => 'mod_quiz', 'questionarea' => 'slot']); - $filtercondition = json_decode($setreferencedata->filtercondition); - $tagstrings = []; - if (isset($filtercondition->tags)) { - $tags = explode(',', $filtercondition->tags); - foreach ($tags as $tag) { - $tagstrings [] = $tag; - } - } - $tagstrings [] = $tagstring; - $filtercondition->tags = $tagstrings; + $filtercondition->tags[] = $tagstring; $setreferencedata->filtercondition = json_encode($filtercondition); - $DB->update_record('question_set_references', $setreferencedata); } diff --git a/mod/quiz/tests/fixtures/moodle_311_quiz.mbz b/mod/quiz/tests/fixtures/moodle_311_quiz.mbz new file mode 100644 index 0000000000000000000000000000000000000000..18e80361a886f39ca0df450ce4d5f16cc04d2a34 GIT binary patch literal 4940 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 literal 0 HcmV?d00001 diff --git a/mod/quiz/tests/quiz_question_restore_test.php b/mod/quiz/tests/quiz_question_restore_test.php index 0825e210d55..decf6867ad4 100644 --- a/mod/quiz/tests/quiz_question_restore_test.php +++ b/mod/quiz/tests/quiz_question_restore_test.php @@ -283,4 +283,61 @@ class quiz_question_restore_test extends \advanced_testcase { $context = \context_module::instance(get_coursemodule_from_instance("quiz", $quizobj->get_quizid(), $newcourseid)->id); $this->assertEquals(0, $this->question_count($context->id)); } + + /** + * Test pre 4.0 quiz restore for random question tags. + * + * @covers ::process_quiz_question_legacy_instance + */ + public function test_pre_4_quiz_restore_for_random_question_tags() { + global $USER, $DB; + $this->resetAfterTest(); + $randomtags = [ + '1' => ['first question', 'one', 'number one'], + '2' => ['first question', 'one', 'number one'], + '3' => ['one', 'number one', 'second question'], + ]; + $backupid = 'abc'; + $backuppath = make_backup_temp_directory($backupid); + get_file_packer('application/vnd.moodle.backup')->extract_to_pathname( + __DIR__ . "/fixtures/moodle_311_quiz.mbz", $backuppath); + + // Do the restore to new course with default settings. + $categoryid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}"); + $newcourseid = \restore_dbops::create_new_course('Test fullname', 'Test shortname', $categoryid); + $rc = new \restore_controller($backupid, $newcourseid, \backup::INTERACTIVE_NO, \backup::MODE_GENERAL, $USER->id, + \backup::TARGET_NEW_COURSE); + + $this->assertTrue($rc->execute_precheck()); + $rc->execute_plan(); + $rc->destroy(); + + // Get the information about the resulting course and check that it is set up correctly. + $modinfo = get_fast_modinfo($newcourseid); + $quiz = array_values($modinfo->get_instances_of('quiz'))[0]; + $quizobj = \quiz::create($quiz->instance); + $structure = \mod_quiz\structure::create_for_quiz($quizobj); + + // Count the questions in quiz qbank. + $context = \context_module::instance(get_coursemodule_from_instance("quiz", $quizobj->get_quizid(), $newcourseid)->id); + $this->assertEquals(2, $this->question_count($context->id)); + + // Are the correct slots returned? + $slots = $structure->get_slots(); + $this->assertCount(3, $slots); + + // Check if the tags match with the actual restored data. + foreach ($slots as $slot) { + $setreference = $DB->get_record('question_set_references', + ['itemid' => $slot->id, 'component' => 'mod_quiz', 'questionarea' => 'slot']); + $filterconditions = json_decode($setreference->filtercondition); + $tags = []; + foreach ($filterconditions->tags as $tagstring) { + $tag = explode(',', $tagstring); + $tags[] = $tag[1]; + } + $this->assertEquals([], array_diff($randomtags[$slot->slot], $tags)); + } + + } }