MDL-83892 core_course: log course overview events
This commit is contained in:
@@ -4832,8 +4832,32 @@ function course_output_fragment_course_overview($args) {
|
||||
}
|
||||
$modname = $args['modname'];
|
||||
$course = get_course($args['courseid']);
|
||||
$context = context_course::instance($course->id, MUST_EXIST);
|
||||
can_access_course($course);
|
||||
|
||||
// Some plugins may have a list view event.
|
||||
$eventclassname = 'mod_' . $modname . '\\event\\course_module_instance_list_viewed';
|
||||
// Do not confuse this "resource" with the "mod_resource" module.
|
||||
// This "resource" is the table that aggregate all activities considered "resources"
|
||||
// (files, folders, pages, text and media...). While the "mod_resource" is a poorly
|
||||
// named plugin representing an uploaded file, and it is also one of the activities
|
||||
// that can be aggregated in the "resource" table.
|
||||
if ($modname === 'resource') {
|
||||
$eventclassname = 'core\\event\\course_resources_list_viewed';
|
||||
}
|
||||
if (class_exists($eventclassname)) {
|
||||
try {
|
||||
$event = $eventclassname::create(['context' => $context]);
|
||||
$event->add_record_snapshot('course', $course);
|
||||
$event->trigger();
|
||||
} catch (\Throwable $th) {
|
||||
// This may happens if the plugin implements a custom event class.
|
||||
// It is highly unlikely but we should not stop the rendering because of this.
|
||||
// Instead, we will log the error and continue.
|
||||
debugging('Error while triggering the course module instance viewed event: ' . $th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$content = '';
|
||||
$format = course_get_format($course);
|
||||
$renderer = $format->get_renderer($PAGE);
|
||||
|
||||
@@ -40,6 +40,11 @@ $context = context_course::instance($course->id, MUST_EXIST);
|
||||
require_login($course);
|
||||
require_capability('moodle/course:viewoverview', $context);
|
||||
|
||||
// Trigger event, course information viewed.
|
||||
$event = \core\event\course_overview_viewed::create(['context' => $context]);
|
||||
$event->add_record_snapshot('course', $course);
|
||||
$event->trigger();
|
||||
|
||||
$format = course_get_format($course);
|
||||
$renderer = $format->get_renderer($PAGE);
|
||||
$overviewpageclass = $format->get_output_classname('overview\\overviewpage');
|
||||
|
||||
@@ -215,3 +215,38 @@ Feature: Users can access the course activities overview page
|
||||
When I am on the "Course 1" "course > activities > resource" page logged in as "student1"
|
||||
Then I should see "To do" in the "Activity 1" "table_row"
|
||||
And I should see "View" in the "Activity 1" "table_row"
|
||||
|
||||
Scenario: The course overview page should log a page event and a reource list event
|
||||
Given the following "activity" exists:
|
||||
| activity | folder |
|
||||
| name | Activity 1 |
|
||||
| course | C1 |
|
||||
And I am on the "Course 1" "course > activities" page logged in as "teacher1"
|
||||
And I am on the "Course 1" "course > activities > resource" page logged in as "student1"
|
||||
When I am on the "Course 1" "course" page logged in as "teacher1"
|
||||
And I navigate to "Reports" in current page administration
|
||||
And I click on "Logs" "link"
|
||||
Then I set the field "Select a user" to "Teacher 1"
|
||||
And I click on "Get these logs" "button"
|
||||
And I should see "Course activities overview page viewed"
|
||||
And I should not see "viewed the list of resources"
|
||||
And I set the field "Select a user" to "Student 1"
|
||||
And I click on "Get these logs" "button"
|
||||
And I should see "Course activities overview page viewed"
|
||||
And I should see "viewed the list of resources"
|
||||
|
||||
@javascript
|
||||
Scenario: The course overview page should log reource list event when loading the overview table
|
||||
Given the following "activity" exists:
|
||||
| activity | folder |
|
||||
| name | Activity 1 |
|
||||
| course | C1 |
|
||||
And I am on the "Course 1" "course > activities" page logged in as "teacher1"
|
||||
And I click on "Expand" "link" in the "resource_overview_collapsible" "region"
|
||||
When I am on the "Course 1" "course" page logged in as "teacher1"
|
||||
And I navigate to "Reports" in current page administration
|
||||
And I click on "Logs" "link"
|
||||
And I set the field "Select a user" to "Teacher 1"
|
||||
And I click on "Get these logs" "button"
|
||||
Then I should see "Course activities overview page viewed"
|
||||
And I should see "viewed the list of resources"
|
||||
|
||||
@@ -137,4 +137,37 @@ final class events_test extends \advanced_testcase {
|
||||
$sink->close();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the course activities overview page viewed.
|
||||
*
|
||||
* There is no external API for viewing course information so the unit test will simply
|
||||
* create and trigger the event and ensure data is returned as expected.
|
||||
*
|
||||
* @covers \core\event\course_overview_viewed
|
||||
*/
|
||||
public function test_course_overview_viewed_event(): void {
|
||||
|
||||
// Create a course.
|
||||
$data = new \stdClass();
|
||||
$course = $this->getDataGenerator()->create_course($data);
|
||||
|
||||
$eventparams = [
|
||||
'context' => \context_course::instance($course->id),
|
||||
];
|
||||
$event = \core\event\course_overview_viewed::create($eventparams);
|
||||
|
||||
// Trigger and capture the event.
|
||||
$sink = $this->redirectEvents();
|
||||
$event->trigger();
|
||||
$events = $sink->get_events();
|
||||
$event = reset($events);
|
||||
|
||||
// Check that the event data is valid.
|
||||
$this->assertInstanceOf('\core\event\course_overview_viewed', $event);
|
||||
$this->assertEquals($course->id, $event->courseid);
|
||||
$this->assertDebuggingNotCalled();
|
||||
$sink->close();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -834,6 +834,7 @@ $string['eventcoursemodulecreated'] = 'Course module created';
|
||||
$string['eventcoursemoduledeleted'] = 'Course module deleted';
|
||||
$string['eventcoursemoduleupdated'] = 'Course module updated';
|
||||
$string['eventcoursemoduleviewed'] = 'Course module viewed';
|
||||
$string['eventcourseoverviewviewed'] = 'Course activities overview page viewed';
|
||||
$string['eventcoursessearched'] = 'Courses searched';
|
||||
$string['eventcourseresetended'] = 'Course reset ended';
|
||||
$string['eventcourseresetstarted'] = 'Course reset started';
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core\event;
|
||||
|
||||
use core\url;
|
||||
|
||||
/**
|
||||
* Event course_overview_viewed
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2025 Ferran Recio <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class course_overview_viewed extends \core\event\base {
|
||||
|
||||
/**
|
||||
* Set basic properties for the event.
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['crud'] = 'r';
|
||||
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of what happened.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description(): string {
|
||||
return "The user with id '$this->userid' viewed the course activity overview for the course with id '$this->courseid'.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return localised event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name(): string {
|
||||
return get_string('eventcourseoverviewviewed', 'core');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL related to the action.
|
||||
*
|
||||
* @return url|null
|
||||
*/
|
||||
public function get_url() {
|
||||
return new url('/course/overview.php', ['id' => $this->courseid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user