From e4990988381839093ca0b9905839b809ca23f852 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Tue, 8 Aug 2023 16:03:57 +0100 Subject: [PATCH] MDL-74610 quiz multiple grades: backup and restore of the new data --- .../backup/moodle2/backup_quiz_stepslib.php | 11 ++- .../backup/moodle2/restore_quiz_stepslib.php | 22 +++++- .../backup/restore_quiz_grade_items_test.php | 77 +++++++++++++++++++ 3 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 mod/quiz/tests/backup/restore_quiz_grade_items_test.php diff --git a/mod/quiz/backup/moodle2/backup_quiz_stepslib.php b/mod/quiz/backup/moodle2/backup_quiz_stepslib.php index 151cb7de9c6..c3914d17d39 100644 --- a/mod/quiz/backup/moodle2/backup_quiz_stepslib.php +++ b/mod/quiz/backup/moodle2/backup_quiz_stepslib.php @@ -46,10 +46,14 @@ class backup_quiz_activity_structure_step extends backup_questions_activity_stru // Define elements for access rule subplugin settings. $this->add_subplugin_structure('quizaccess', $quiz, true); + $quizgradeitems = new backup_nested_element('quiz_grade_items'); + + $quizgradeitem = new backup_nested_element('quiz_grade_item', ['id'], ['sortorder', 'name']); + $qinstances = new backup_nested_element('question_instances'); $qinstance = new backup_nested_element('question_instance', ['id'], - ['quizid', 'slot', 'page', 'displaynumber', 'requireprevious', 'maxmark']); + ['quizid', 'slot', 'page', 'displaynumber', 'requireprevious', 'maxmark', 'quizgradeitemid']); $this->add_question_references($qinstance, 'mod_quiz', 'slot'); @@ -88,6 +92,9 @@ class backup_quiz_activity_structure_step extends backup_questions_activity_stru $this->add_subplugin_structure('quizaccess', $attempt, true); // Build the tree. + $quiz->add_child($quizgradeitems); + $quizgradeitems->add_child($quizgradeitem); + $quiz->add_child($qinstances); $qinstances->add_child($qinstance); @@ -109,6 +116,8 @@ class backup_quiz_activity_structure_step extends backup_questions_activity_stru // Define sources. $quiz->set_source_table('quiz', ['id' => backup::VAR_ACTIVITYID]); + $quizgradeitem->set_source_table('quiz_grade_items', ['quizid' => backup::VAR_PARENTID]); + $qinstance->set_source_table('quiz_slots', ['quizid' => backup::VAR_PARENTID]); $section->set_source_table('quiz_sections', ['quizid' => backup::VAR_PARENTID]); diff --git a/mod/quiz/backup/moodle2/restore_quiz_stepslib.php b/mod/quiz/backup/moodle2/restore_quiz_stepslib.php index b7ff48de789..1738ea44e18 100644 --- a/mod/quiz/backup/moodle2/restore_quiz_stepslib.php +++ b/mod/quiz/backup/moodle2/restore_quiz_stepslib.php @@ -61,6 +61,7 @@ class restore_quiz_activity_structure_step extends restore_questions_activity_st // A chance for access subplugings to set up their quiz data. $this->add_subplugin_structure('quizaccess', $quiz); + $paths[] = new restore_path_element('quiz_grade_item', '/activity/quiz/quiz_grade_items/quiz_grade_item'); $quizquestioninstance = new restore_path_element('quiz_question_instance', '/activity/quiz/question_instances/question_instance'); $paths[] = $quizquestioninstance; @@ -324,6 +325,21 @@ class restore_quiz_activity_structure_step extends restore_questions_activity_st } } + /** + * Process a quiz grade items. + * + * @param stdClass|array $data + */ + protected function process_quiz_grade_item($data): void { + global $DB; + + $data = (object) $data; + $data->quizid = $this->get_new_parentid('quiz'); + $oldid = $data->id; + $newitemid = $DB->insert_record('quiz_grade_items', $data); + $this->set_mapping('quiz_grade_item', $oldid, $newitemid, true); + } + /** * Process the data for pre 4.0 quiz data where the question_references and question_set_references table introduced. * @@ -382,7 +398,7 @@ class restore_quiz_activity_structure_step extends restore_questions_activity_st * @param stdClass|array $data */ protected function process_quiz_question_instance($data) { - global $CFG, $DB; + global $DB; $data = (object)$data; $oldid = $data->id; @@ -421,6 +437,10 @@ class restore_quiz_activity_structure_step extends restore_questions_activity_st return; } + if (isset($data->quizgradeitemid)) { + $data->quizgradeitemid = $this->get_mappingid('quiz_grade_items', $data->quizgradeitemid); + } + $data->quizid = $this->get_new_parentid('quiz'); $newitemid = $DB->insert_record('quiz_slots', $data); diff --git a/mod/quiz/tests/backup/restore_quiz_grade_items_test.php b/mod/quiz/tests/backup/restore_quiz_grade_items_test.php new file mode 100644 index 00000000000..51d8b9176be --- /dev/null +++ b/mod/quiz/tests/backup/restore_quiz_grade_items_test.php @@ -0,0 +1,77 @@ +. + +namespace mod_quiz; + +use mod_quiz_generator; +use restore_date_testcase; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->libdir . "/phpunit/classes/restore_date_testcase.php"); + +/** + * Test of backup and restore of quiz grade items. + * + * @package mod_quiz + * @copyright 2023 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \backup_quiz_activity_structure_step + * @covers \restore_quiz_activity_structure_step + */ +final class restore_quiz_grade_items_test extends restore_date_testcase { + + public function test_restore_quiz_grade_items(): void { + global $DB; + $this->resetAfterTest(); + + $course = $this->getDataGenerator()->create_course(); + /** @var mod_quiz_generator $quizgen */ + $quizgen = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); + $quiz = $quizgen->create_instance(['course' => $course->id]); + + $quizgen->create_grade_item(['quizid' => $quiz->id, 'name' => 'Listening']); + $quizgen->create_grade_item(['quizid' => $quiz->id, 'name' => 'Reading']); + + // Back up and restore including group info and user info. + $newcourseid = $this->backup_and_restore($course); + + $newquiz = $DB->get_record('quiz', ['course' => $newcourseid]); + $quizobj = quiz_settings::create($newquiz->id); + $structure = $quizobj->get_structure(); + $quizgradeitems = array_values($structure->get_grade_items()); + + // Strip out the ids, since we don't care what those will be. + $quizgradeitems = array_map( + function ($quizgradeitem) { + unset($quizgradeitem->id); + return $quizgradeitem; + }, + $quizgradeitems + ); + + // Check the grade items are right in the restored quiz. + $this->assertEquals( + [ + (object) ['quizid' => $newquiz->id, 'sortorder' => 1, 'name' => 'Listening'], + (object) ['quizid' => $newquiz->id, 'sortorder' => 2, 'name' => 'Reading'], + ], + $quizgradeitems + ); + + } +}