public function test_course_delete_section() { global $DB; $this->resetAfterTest(true); $generator = $this->getDataGenerator(); $course = $generator->create_course(array('numsections' => 6, 'format' => 'topics'), array('createsections' => true)); $assign0 = $generator->create_module('assign', array('course' => $course, 'section' => 0)); $assign1 = $generator->create_module('assign', array('course' => $course, 'section' => 1)); $assign21 = $generator->create_module('assign', array('course' => $course, 'section' => 2)); $assign22 = $generator->create_module('assign', array('course' => $course, 'section' => 2)); $assign3 = $generator->create_module('assign', array('course' => $course, 'section' => 3)); $assign5 = $generator->create_module('assign', array('course' => $course, 'section' => 5)); $assign6 = $generator->create_module('assign', array('course' => $course, 'section' => 6)); $this->setAdminUser(); // Attempt to delete non-existing section. $this->assertFalse(course_delete_section($course, 10, false)); $this->assertFalse(course_delete_section($course, 9, true)); // Attempt to delete 0-section. $this->assertFalse(course_delete_section($course, 0, true)); $this->assertTrue($DB->record_exists('course_modules', array('id' => $assign0->cmid))); // Delete last section. $this->assertTrue(course_delete_section($course, 6, true)); $this->assertFalse($DB->record_exists('course_modules', array('id' => $assign6->cmid))); $this->assertEquals(5, course_get_format($course)->get_course()->numsections); // Delete empty section. $this->assertTrue(course_delete_section($course, 4, false)); $this->assertEquals(4, course_get_format($course)->get_course()->numsections); // Delete section in the middle (2). $this->assertFalse(course_delete_section($course, 2, false)); $this->assertTrue(course_delete_section($course, 2, true)); $this->assertFalse($DB->record_exists('course_modules', array('id' => $assign21->cmid))); $this->assertFalse($DB->record_exists('course_modules', array('id' => $assign22->cmid))); $this->assertEquals(3, course_get_format($course)->get_course()->numsections); $this->assertEquals(array(0 => array($assign0->cmid), 1 => array($assign1->cmid), 2 => array($assign3->cmid), 3 => array($assign5->cmid)), get_fast_modinfo($course)->sections); // Make last section orphaned. update_course((object) array('id' => $course->id, 'numsections' => 2)); $this->assertEquals(2, course_get_format($course)->get_course()->numsections); // Remove orphaned section. $this->assertTrue(course_delete_section($course, 3, true)); $this->assertEquals(2, course_get_format($course)->get_course()->numsections); // Remove marked section. course_set_marker($course->id, 1); $this->assertTrue(course_get_format($course)->is_section_current(1)); $this->assertTrue(course_delete_section($course, 1, true)); $this->assertFalse(course_get_format($course)->is_section_current(1)); }
/** * Test that triggering a course_section_deleted event works as expected. */ public function test_course_section_deleted_event() { global $USER, $DB; $this->resetAfterTest(); $sink = $this->redirectEvents(); // Create the course with sections. $course = $this->getDataGenerator()->create_course(array('numsections' => 10), array('createsections' => true)); $sections = $DB->get_records('course_sections', array('course' => $course->id)); $coursecontext = context_course::instance($course->id); $section = array_pop($sections); course_delete_section($course, $section); $events = $sink->get_events(); $event = array_pop($events); // Delete section event. $sink->close(); // Validate event data. $this->assertInstanceOf('\\core\\event\\course_section_deleted', $event); $this->assertEquals('course_sections', $event->objecttable); $this->assertEquals($section->id, $event->objectid); $this->assertEquals($course->id, $event->courseid); $this->assertEquals($coursecontext->id, $event->contextid); $this->assertEquals($section->section, $event->other['sectionnum']); $expecteddesc = "The user with id '{$event->userid}' deleted section number '{$event->other['sectionnum']}' " . "(section name '{$event->other['sectionname']}') for the course with id '{$event->courseid}'"; $this->assertEquals($expecteddesc, $event->get_description()); $this->assertEquals($section, $event->get_record_snapshot('course_sections', $event->objectid)); $this->assertNull($event->get_url()); // Test legacy data. $sectionnum = $section->section; $expectedlegacydata = array($course->id, "course", "delete section", 'view.php?id=' . $course->id, $sectionnum); $this->assertEventLegacyLogData($expectedlegacydata, $event); $this->assertEventContextNotUsed($event); }
$PAGE->set_url('/course/editsection.php', array('id' => $id, 'sr' => $sectionreturn)); $section = $DB->get_record('course_sections', array('id' => $id), '*', MUST_EXIST); $course = $DB->get_record('course', array('id' => $section->course), '*', MUST_EXIST); $sectionnum = $section->section; require_login($course); $context = context_course::instance($course->id); require_capability('moodle/course:update', $context); // Get section_info object with all availability options. $sectioninfo = get_fast_modinfo($course)->get_section_info($sectionnum); // Deleting the section. if ($deletesection) { $cancelurl = course_get_url($course, $sectioninfo, array('sr' => $sectionreturn)); if (course_can_delete_section($course, $sectioninfo)) { $confirm = optional_param('confirm', false, PARAM_BOOL) && confirm_sesskey(); if ($confirm) { course_delete_section($course, $sectioninfo, true); $courseurl = course_get_url($course, 0, array('sr' => $sectionreturn)); redirect($courseurl); } else { if (get_string_manager()->string_exists('deletesection', 'format_' . $course->format)) { $strdelete = get_string('deletesection', 'format_' . $course->format); } else { $strdelete = get_string('deletesection'); } $PAGE->navbar->add($strdelete); $PAGE->set_title($strdelete); $PAGE->set_heading($course->fullname); echo $OUTPUT->header(); echo $OUTPUT->box_start('noticebox'); $optionsyes = array('id' => $id, 'confirm' => 1, 'delete' => 1, 'sesskey' => sesskey()); $deleteurl = new moodle_url('/course/editsection.php', $optionsyes);
public function test_async_section_deletion_hook_not_implemented() { // If no plugins advocate async removal, then normal synchronous removal will take place. // Only proceed if we are sure that no plugin is going to advocate async removal of a module. I.e. no plugin returns // 'true' from the 'course_module_adhoc_deletion_recommended' hook. // In the case of core, only recyclebin implements this hook, and it will only return true if enabled, so disable it. global $DB, $USER; $this->resetAfterTest(true); $this->setAdminUser(); set_config('coursebinenable', false, 'tool_recyclebin'); // Non-core plugins might implement the 'course_module_adhoc_deletion_recommended' hook and spoil this test. // If at least one plugin still returns true, then skip this test. if ($pluginsfunction = get_plugins_with_function('course_module_background_deletion_recommended')) { foreach ($pluginsfunction as $plugintype => $plugins) { foreach ($plugins as $pluginfunction) { if ($pluginfunction()) { $this->markTestSkipped(); } } } } // Create course, module and context. $generator = $this->getDataGenerator(); $course = $generator->create_course(['numsections' => 4, 'format' => 'topics'], ['createsections' => true]); $assign0 = $generator->create_module('assign', ['course' => $course, 'section' => 2]); $assign1 = $generator->create_module('assign', ['course' => $course, 'section' => 2]); // Delete empty section. No difference from normal, synchronous behaviour. $this->assertTrue(course_delete_section($course, 4, false, true)); $this->assertEquals(3, course_get_format($course)->get_course()->numsections); // Delete section in the middle (2). $section = $DB->get_record('course_sections', ['course' => $course->id, 'section' => '2']); // For event comparison. $this->assertFalse(course_delete_section($course, 2, false, true)); // Non-empty section, no forcedelete, so no change. $sink = $this->redirectEvents(); // To capture the event. $this->assertTrue(course_delete_section($course, 2, true, true)); // Now, confirm that: // a) The section's modules have deleted and; // b) the section has been deleted and; // c) course_section_deleted event has been fired and; // d) course_module_deleted events have both been fired. // Confirm modules have been deleted. list($insql, $assignids) = $DB->get_in_or_equal([$assign0->cmid, $assign1->cmid]); $cmcount = $DB->count_records_select('course_modules', 'id ' . $insql, $assignids); $this->assertEmpty($cmcount); // Confirm the section has been deleted. $this->assertEquals(2, course_get_format($course)->get_course()->numsections); // Confirm the course_section_deleted event has been generated. $events = $sink->get_events(); $event = array_pop($events); $sink->close(); $this->assertInstanceOf('\\core\\event\\course_section_deleted', $event); $this->assertEquals($section->id, $event->objectid); $this->assertEquals($USER->id, $event->userid); $this->assertEquals('course_sections', $event->objecttable); $this->assertEquals(null, $event->get_url()); $this->assertEquals($section, $event->get_record_snapshot('course_sections', $section->id)); // Confirm that the course_module_deleted events have both been generated. $count = 0; while (!empty($events)) { $event = array_pop($events); if ($event instanceof \core\event\course_module_deleted && in_array($event->objectid, [$assign0->cmid, $assign1->cmid])) { $count++; } } $this->assertEquals(2, $count); }
/** * Empty out this section. */ public function empty_content($courses) { $sectionident = $this->get_identifier(); // We have a section number, delete that section. foreach ($courses as $course) { $modinfo = get_fast_modinfo($course); $section = $modinfo->get_section_info($sectionident); course_delete_section($course, $section); static::create_section($course, array('section' => $section->section, 'name' => $section->name, 'visible' => $section->visible, 'summary' => $section->summary, 'summaryformat' => $section->summaryformat, 'availability' => $section->availability)); } }