diff --git a/backup/moodle2/restore_stepslib.php b/backup/moodle2/restore_stepslib.php index c1c749322a4..40edbe74820 100644 --- a/backup/moodle2/restore_stepslib.php +++ b/backup/moodle2/restore_stepslib.php @@ -1859,9 +1859,13 @@ class restore_section_structure_step extends restore_structure_step { [$this->get_courseid()], 'section DESC', 'id, section' ); + // Here we add the new section to the end of the list so we make sure that all delegated sections are really + // all located after the normal sections. We can have case where delegated sections are located before the + // normal sections, so we need to move them to the end (mostly in the restore process more than in the duplicate + // process in which the order sections => delegated section is mostly there). + $sectionnum = $sectionnum + count($sectionstomove); foreach ($sectionstomove as $section) { - $sectionnum++; - $section->section = $sectionnum; + $section->section = $sectionnum--; $DB->update_record('course_sections', $section); } } diff --git a/course/format/tests/base_test.php b/course/format/tests/base_test.php index 2911ad3d1bd..7c9671516ae 100644 --- a/course/format/tests/base_test.php +++ b/course/format/tests/base_test.php @@ -570,6 +570,45 @@ final class base_test extends advanced_testcase { $this->assertEquals($originalmodcount - 1, $newmodcount); } + /** + * Test duplicate_section() with delegated section + * @covers ::duplicate_section + */ + public function test_duplicate_section_with_delegated_sections(): void { + global $DB; + + $this->setAdminUser(); + $this->resetAfterTest(); + // Add subsection. + $manager = \core_plugin_manager::resolve_plugininfo_class('mod'); + $manager::enable_plugin('subsection', 1); + $course = $this->getDataGenerator()->create_course(['format' => 'topics', 'numsections' => 1]); + $subsection1 = $this->getDataGenerator()->create_module( + 'subsection', ['course' => $course, 'section' => 1, 'name' => 'subsection1']); + $subsection2 = $this->getDataGenerator()->create_module( + 'subsection', ['course' => $course, 'section' => 1, 'name' => 'subsection2']); + $format = course_get_format($course); + + $modinfo = get_fast_modinfo($course); + $sectioninfo = $modinfo->get_section_info(1, MUST_EXIST); + $originalsectioncount = $DB->count_records('course_sections', ['course' => $course->id]); + $this->assertEquals(4, $originalsectioncount); + + $originalsection = $DB->get_record('course_sections', + ['course' => $course->id, 'section' => 0], + '*', + MUST_EXIST); + $newsection = $format->duplicate_section($sectioninfo); + foreach ($originalsection as $prop => $value) { + if ($prop == 'id' || $prop == 'sequence' || $prop == 'section' || $prop == 'timemodified') { + continue; + } + $this->assertEquals($value, $newsection->$prop); + } + $sectioncount = $DB->count_records('course_sections', ['course' => $course->id]); + $this->assertEquals(7, $sectioncount); + } + /** * Test for the default delete format data behaviour. *