diff --git a/course/format/tests/behat/section_page.feature b/course/format/tests/behat/section_page.feature index 96198bd22ebef..369e177d69af2 100644 --- a/course/format/tests/behat/section_page.feature +++ b/course/format/tests/behat/section_page.feature @@ -80,3 +80,6 @@ Feature: Single section course page And I should not see "Activity sample 1.3" in the "region-main" "region" And I should not see "Activity sample 2.1" in the "region-main" "region" And I should not see "Activity sample 2.1" in the "region-main" "region" + # The section viewed has been trigered. + And I navigate to "Reports > Live logs" in current page administration + And I should see "Section viewed" diff --git a/course/lib.php b/course/lib.php index 1813d580050e2..02ffd2919e21c 100644 --- a/course/lib.php +++ b/course/lib.php @@ -5079,3 +5079,22 @@ function course_update_communication_instance_data(stdClass $data): void { $data->id = $data->instanceid; // For correct use in update_course. update_course($data); } + +/** + * Trigger course section viewed event. + * + * @param context_course $context course context object + * @param int $sectionid section number + * @since Moodle 4.4. + */ +function course_section_view(context_course $context, int $sectionid) { + + $eventdata = [ + 'objectid' => $sectionid, + 'context' => $context, + ]; + $event = \core\event\section_viewed::create($eventdata); + $event->trigger(); + + user_accesstime_log($context->instanceid); +} diff --git a/course/section.php b/course/section.php index f6b8ab5e3fe80..0bb7d9714eb47 100644 --- a/course/section.php +++ b/course/section.php @@ -181,8 +181,8 @@ echo $renderer->container_end(); -// Trigger course viewed event. -course_view($context, $section->section); +// Trigger section viewed event. +course_section_view($context, $sectionid); // Load the view JS module if completion tracking is enabled for this course. $completion = new completion_info($course); diff --git a/course/tests/courselib_test.php b/course/tests/courselib_test.php index 31f959b6fffa1..4dcc420907ae3 100644 --- a/course/tests/courselib_test.php +++ b/course/tests/courselib_test.php @@ -30,6 +30,7 @@ use context_module; use context_system; use context_coursecat; +use core\event\section_viewed; use core_completion_external; use core_external; use core_tag_index_builder; @@ -7415,4 +7416,35 @@ public function test_course_update_communication_instance_data(): void { $course = get_course($course->id); $this->assertEquals($course->fullname, $data->fullname); } + + /** + * Test course_section_view() function + * + * @covers ::course_section_view + */ + public function test_course_section_view(): void { + + $this->resetAfterTest(); + + // Course without sections. + $course = $this->getDataGenerator()->create_course(['numsections' => 5], ['createsections' => true]); + $coursecontext = context_course::instance($course->id); + $format = course_get_format($course->id); + $sections = $format->get_sections(); + $section = reset($sections); + + // Redirect events to the sink, so we can recover them later. + $sink = $this->redirectEvents(); + + course_section_view($coursecontext, $section->id); + + $events = $sink->get_events(); + $event = reset($events); + + // Check the event details are correct. + $this->assertInstanceOf('\core\event\section_viewed', $event); + $this->assertEquals(context_course::instance($course->id), $event->get_context()); + $this->assertEquals('course_sections', $event->objecttable); + $this->assertEquals($section->id, $event->objectid); + } } diff --git a/lang/en/moodle.php b/lang/en/moodle.php index 95b491e1628af..d9ce4ec44bc5d 100644 --- a/lang/en/moodle.php +++ b/lang/en/moodle.php @@ -851,6 +851,7 @@ $string['eventrecentactivityviewed'] = 'Recent activity viewed'; $string['eventsearchindexed'] = 'Search data indexed'; $string['eventsearchresultsviewed'] = 'Search results viewed'; +$string['eventsectionviewed'] = 'Section viewed'; $string['eventunknownlogged'] = 'Unknown event'; $string['eventurlblocked'] = 'The URL was blocked'; $string['eventusercreated'] = 'User created'; diff --git a/lib/classes/event/section_viewed.php b/lib/classes/event/section_viewed.php new file mode 100644 index 0000000000000..a319beebe4756 --- /dev/null +++ b/lib/classes/event/section_viewed.php @@ -0,0 +1,96 @@ +. + +namespace core\event; + +/** + * Section viewed event class. + * + * @package core + * @copyright 2023 Amaia Anabitarte + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class section_viewed extends base { + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['objecttable'] = 'course_sections'; + $this->data['crud'] = 'r'; + $this->data['edulevel'] = self::LEVEL_PARTICIPATING; + } + + /** + * Returns non-localised description of what happened. + * + * @return string + */ + public function get_description() { + return "The user with id '$this->userid' viewed the section with id '$this->objectid'."; + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventsectionviewed', 'core'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url|null + */ + public function get_url() { + global $CFG, $DB; + require_once($CFG->dirroot . '/course/lib.php'); + try { + $section = $DB->get_record($this->objecttable, ['id' => $this->objectid], '*', MUST_EXIST); + return course_get_url($this->courseid, $section, ['navigation' => true]); + } catch (\Exception $e) { + return null; + } + } + + /** + * Custom validation. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + + if ($this->contextlevel != CONTEXT_COURSE) { + throw new \coding_exception('Context level must be CONTEXT_COURSE.'); + } + } + + /** + * Used for mapping events on restore + * + * @return bool + */ + public static function get_other_mapping() { + // No mapping required. + return false; + } +}