diff --git a/course/lib.php b/course/lib.php index ba830ca0b15..bee61328d7a 100644 --- a/course/lib.php +++ b/course/lib.php @@ -1842,7 +1842,40 @@ function move_section_to($course, $section, $destination, $ignorenumsections = f * @return bool whether section was deleted */ function course_delete_section($course, $section, $forcedeleteifnotempty = true) { - return course_get_format($course)->delete_section($section, $forcedeleteifnotempty); + global $DB; + + // Prepare variables. + $courseid = (is_object($course)) ? $course->id : (int)$course; + $sectionnum = (is_object($section)) ? $section->section : (int)$section; + $section = $DB->get_record('course_sections', array('course' => $courseid, 'section' => $sectionnum)); + if (!$section) { + // No section exists, can't proceed. + return false; + } + $format = course_get_format($course); + $sectionname = $format->get_section_name($section); + + // Delete section. + $result = $format->delete_section($section, $forcedeleteifnotempty); + + // Trigger an event for course section deletion. + if ($result) { + $context = context_course::instance($courseid); + $event = \core\event\course_section_deleted::create( + array( + 'objectid' => $section->id, + 'courseid' => $courseid, + 'context' => $context, + 'other' => array( + 'sectionnum' => $section->section, + 'sectionname' => $sectionname, + ) + ) + ); + $event->add_record_snapshot('course_sections', $section); + $event->trigger(); + } + return $result; } /** diff --git a/course/tests/courselib_test.php b/course/tests/courselib_test.php index 110b0c48b05..421b1e4c2eb 100644 --- a/course/tests/courselib_test.php +++ b/course/tests/courselib_test.php @@ -2009,6 +2009,44 @@ class core_course_courselib_testcase extends advanced_testcase { $this->assertEventContextNotUsed($event); } + /** + * 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); + } + public function test_course_integrity_check() { global $DB; diff --git a/lang/en/moodle.php b/lang/en/moodle.php index 9a431dcdb0e..59d60802e93 100644 --- a/lang/en/moodle.php +++ b/lang/en/moodle.php @@ -738,6 +738,7 @@ $string['eventcourseresetended'] = 'Course reset ended'; $string['eventcourseresetstarted'] = 'Course reset started'; $string['eventcourserestored'] = 'Course restored'; $string['eventcourseupdated'] = 'Course updated'; +$string['eventcoursesectiondeleted'] = 'Course section deleted'; $string['eventcoursesectionupdated'] = 'Course section updated'; $string['eventcoursemoduleinstancelistviewed'] = 'Course module instance list viewed'; $string['eventcourseuserreportviewed'] = 'Course user report viewed'; diff --git a/lib/classes/event/course_section_deleted.php b/lib/classes/event/course_section_deleted.php new file mode 100644 index 00000000000..e73f1449a5c --- /dev/null +++ b/lib/classes/event/course_section_deleted.php @@ -0,0 +1,101 @@ +. + +/** + * Course section deleted event. + * + * @package core + * @copyright 2015 Ruslan Kabalin, Lancaster University. + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core\event; + +defined('MOODLE_INTERNAL') || die(); + +/** + * Course section deleted event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int sectionnum: section number. + * - string sectionname: section name. + * } + * + * @package core + * @since Moodle 3.1 + * @copyright 2015 Ruslan Kabalin, Lancaster University. + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class course_section_deleted extends base { + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['objecttable'] = 'course_sections'; + $this->data['crud'] = 'd'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventcoursesectiondeleted'); + } + + /** + * Returns non-localised event description with id's for admin use only. + * + * @return string + */ + public function get_description() { + return "The user with id '$this->userid' deleted section number '{$this->other['sectionnum']}' " . + "(section name '{$this->other['sectionname']}') for the course with id '$this->courseid'"; + } + + /** + * Return legacy data for add_to_log(). + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'course', 'delete section', 'view.php?id=' . $this->courseid, $this->other['sectionnum']); + } + + /** + * Custom validation. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->other['sectionnum'])) { + throw new \coding_exception('The \'sectionnum\' value must be set in other.'); + } + if (!isset($this->other['sectionname'])) { + throw new \coding_exception('The \'sectionname\' value must be set in other.'); + } + } +}