diff --git a/course/lib.php b/course/lib.php index 25af452c7fa..52432a46bb3 100644 --- a/course/lib.php +++ b/course/lib.php @@ -2201,7 +2201,8 @@ function move_courses($courseids, $categoryid) { 'objectid' => $course->id, 'context' => context_course::instance($course->id), 'other' => array('shortname' => $dbcourse->shortname, - 'fullname' => $dbcourse->fullname) + 'fullname' => $dbcourse->fullname, + 'updatedfields' => array('category' => $category->id)) )); $event->set_legacy_logdata(array($course->id, 'course', 'move', 'edit.php?id=' . $course->id, $course->id)); $event->trigger(); @@ -2513,8 +2514,6 @@ function create_course($data, $editoroptions = NULL) { function update_course($data, $editoroptions = NULL) { global $DB, $CFG; - $data->timemodified = time(); - // Prevent changes on front page course. if ($data->id == SITEID) { throw new moodle_exception('invalidcourse', 'error'); @@ -2523,6 +2522,28 @@ function update_course($data, $editoroptions = NULL) { $oldcourse = course_get_format($data->id)->get_course(); $context = context_course::instance($oldcourse->id); + // Capture the updated fields for the log data. + $updatedfields = []; + foreach (get_object_vars($oldcourse) as $field => $value) { + if ($field == 'summary_editor') { + if (($data->$field)['text'] !== $value['text']) { + // The summary might be very long, we don't wan't to fill up the log record with the full text. + $updatedfields[$field] = '(updated)'; + } + } else if ($field == 'tags') { + // Tags might not have the same array keys, just check the values. + if (array_values($data->$field) !== array_values($value)) { + $updatedfields[$field] = $data->$field; + } + } else { + if (isset($data->$field) && $data->$field != $value) { + $updatedfields[$field] = $data->$field; + } + } + } + + $data->timemodified = time(); + if ($editoroptions) { $data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course', 'summary', 0); } @@ -2629,7 +2650,8 @@ function update_course($data, $editoroptions = NULL) { 'objectid' => $course->id, 'context' => context_course::instance($course->id), 'other' => array('shortname' => $course->shortname, - 'fullname' => $course->fullname) + 'fullname' => $course->fullname, + 'updatedfields' => $updatedfields) )); $event->set_legacy_logdata(array($course->id, 'course', 'update', 'edit.php?id=' . $course->id, $course->id)); diff --git a/course/tests/courselib_test.php b/course/tests/courselib_test.php index 8cd7d25a87c..7e82c061cdb 100644 --- a/course/tests/courselib_test.php +++ b/course/tests/courselib_test.php @@ -1800,6 +1800,39 @@ class core_course_courselib_testcase extends advanced_testcase { $this->assertEventContextNotUsed($event); } + /** + * Test that triggering a course_updated event logs changes. + */ + public function test_course_updated_event_with_changes() { + global $DB; + + $this->resetAfterTest(); + + // Create a course. + $course = $this->getDataGenerator()->create_course((object)['visible' => 1]); + + $editedcourse = $DB->get_record('course', ['id' => $course->id]); + $editedcourse->visible = 0; + + // Update course and catch course_updated event. + $sink = $this->redirectEvents(); + update_course($editedcourse); + $events = $sink->get_events(); + $sink->close(); + + $event = array_shift($events); + $this->assertInstanceOf('\core\event\course_updated', $event); + $otherdata = [ + 'shortname' => $course->shortname, + 'fullname' => $course->fullname, + 'updatedfields' => [ + 'visible' => 0 + ] + ]; + $this->assertEquals($otherdata, $event->other); + + } + /** * Test that triggering a course_deleted event works as expected. */ diff --git a/lib/classes/event/course_updated.php b/lib/classes/event/course_updated.php index fab46c534e9..2c9e59d42ce 100644 --- a/lib/classes/event/course_updated.php +++ b/lib/classes/event/course_updated.php @@ -34,6 +34,7 @@ defined('MOODLE_INTERNAL') || die(); * * - string shortname: (optional) shortname of course. * - string fullname: (optional) fullname of course. + * - string updatedfields: (optional) array of course table fields edited in this event, ['fieldname' => 'newvalue'] * } * * @package core