From b3e2e81b0d91cc8ca01f457dbccd7f9aa2d00aae Mon Sep 17 00:00:00 2001 From: Benjamin Walker Date: Thu, 19 Sep 2024 10:49:31 +1000 Subject: [PATCH] MDL-72133 report_loglive: Display logs filtered by deleted course ids --- report/loglive/classes/renderable.php | 19 +++++++++++--- report/loglive/classes/table_log.php | 6 +++++ report/loglive/index.php | 21 +++++++++------ report/loglive/loglive_ajax.php | 14 ++++++---- report/loglive/tests/table_log_test.php | 35 +++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 16 deletions(-) diff --git a/report/loglive/classes/renderable.php b/report/loglive/classes/renderable.php index 4c094c19ab0..8ccb195440a 100644 --- a/report/loglive/classes/renderable.php +++ b/report/loglive/classes/renderable.php @@ -64,6 +64,9 @@ class report_loglive_renderable implements renderable { /** @var int group id */ public $groupid; + /** @var int forces the use of a course filter in site context */ + public $sitecoursefilter; + /** @var report_loglive_table_log table log which will be used for rendering logs */ public $tablelog; @@ -80,11 +83,12 @@ class report_loglive_renderable implements renderable { * @param int $page (optional) page number. * @param int $perpage (optional) number of records to show per page. * @param string $order (optional) sortorder of fetched records + * @param int $sitecoursefilter (optional) use a course filter in site context. */ public function __construct($logreader = "", $course = 0, $url = "", $date = 0, $page = 0, $perpage = 100, - $order = "timecreated DESC") { + $order = "timecreated DESC", $sitecoursefilter = 0) { - global $PAGE; + global $PAGE, $SITE; // Use first reader as selected reader, if not passed. if (empty($logreader)) { @@ -108,7 +112,14 @@ class report_loglive_renderable implements renderable { // Use site course id, if course is empty. if (!empty($course) && is_int($course)) { - $course = get_course($course); + $courseid = $course; + try { + $course = get_course($courseid); + } catch (dml_missing_record_exception) { + // Missing courses may have be deleted, so display them in site context. + $course = 0; + $sitecoursefilter = $courseid; + } } $this->course = $course; @@ -120,6 +131,7 @@ class report_loglive_renderable implements renderable { $this->page = $page; $this->perpage = $perpage; $this->order = $order; + $this->sitecoursefilter = $sitecoursefilter; $this->set_refresh_rate(); } @@ -184,6 +196,7 @@ class report_loglive_renderable implements renderable { $filter->logreader = $readers[$this->selectedlogreader]; $filter->date = $this->date; $filter->orderby = $this->order; + $filter->sitecoursefilter = $this->sitecoursefilter; return $filter; } diff --git a/report/loglive/classes/table_log.php b/report/loglive/classes/table_log.php index f9ed1a0fb70..1337bbe7808 100644 --- a/report/loglive/classes/table_log.php +++ b/report/loglive/classes/table_log.php @@ -308,6 +308,12 @@ class report_loglive_table_log extends table_sql { $params['courseid'] = $this->filterparams->courseid; } + // Add filters for missing/deleted courses in site context. + if (!empty($this->filterparams->sitecoursefilter)) { + $joins[] = "courseid = :courseid"; + $params['courseid'] = $this->filterparams->sitecoursefilter; + } + // Getting all members of a group. [ 'joins' => $groupjoins, diff --git a/report/loglive/index.php b/report/loglive/index.php index ffe45342e80..c0b1c23c559 100644 --- a/report/loglive/index.php +++ b/report/loglive/index.php @@ -34,15 +34,20 @@ $id = optional_param('id', 0, PARAM_INT); $page = optional_param('page', 0, PARAM_INT); $logreader = optional_param('logreader', '', PARAM_COMPONENT); // Reader which will be used for displaying logs. -if (empty($id)) { - admin_externalpage_setup('reportloglive', '', null, '', array('pagelayout' => 'report')); +// Get course details. +if (!empty($id)) { + $course = $DB->get_record('course', ['id' => $id], '*'); + if ($course) { + require_login($course); + $context = context_course::instance($course->id); + $coursename = format_string($course->fullname, true, ['context' => $context]); + } +} + +if (empty($course)) { + admin_externalpage_setup('reportloglive', '', null, '', ['pagelayout' => 'report']); $context = context_system::instance(); - $coursename = format_string($SITE->fullname, true, array('context' => $context)); -} else { - $course = get_course($id); - require_login($course); - $context = context_course::instance($course->id); - $coursename = format_string($course->fullname, true, array('context' => $context)); + $coursename = format_string($SITE->fullname, true, ['context' => $context]); } require_capability('report/loglive:view', $context); diff --git a/report/loglive/loglive_ajax.php b/report/loglive/loglive_ajax.php index aef3a313f6b..cd66bd4135b 100644 --- a/report/loglive/loglive_ajax.php +++ b/report/loglive/loglive_ajax.php @@ -33,14 +33,18 @@ $logreader = optional_param('logreader', '', PARAM_COMPONENT); // Reader which w $PAGE->set_url('/report/loglive/loglive_ajax.php'); // Capability checks. -if (empty($id)) { +if (!empty($id)) { + $course = $DB->get_record('course', ['id' => $id], '*'); + if ($course) { + require_login($course); + $context = context_course::instance($course->id); + } +} + +if (empty($course)) { require_login(); $context = context_system::instance(); $PAGE->set_context($context); -} else { - $course = get_course($id); - require_login($course); - $context = context_course::instance($course->id); } require_capability('report/loglive:view', $context); diff --git a/report/loglive/tests/table_log_test.php b/report/loglive/tests/table_log_test.php index 02b31bc0018..5f08210369c 100644 --- a/report/loglive/tests/table_log_test.php +++ b/report/loglive/tests/table_log_test.php @@ -318,4 +318,39 @@ final class table_log_test extends advanced_testcase { sort($usernames); $this->assertEquals($expectedusers, $usernames); } + + /** + * Test getting logs for deleted courses. + * + * @covers \report_loglive_renderable::get_table + * @return void + */ + public function test_get_deleted_course_logs(): void { + global $DB, $PAGE; + $this->preventResetByRollback(); // Ensure events can be recorded in log store. + + // Configure log store and user. + $manager = get_log_manager(); + $stores = $manager->get_readers(); + $store = $stores['logstore_standard']; + $this->setUser(get_admin()); + + // Set and delete course. + $course = reset($this->courses); + $deletedcourseid = $course->id; + delete_course($course, false); + $this->assertFalse($DB->record_exists('course', ['id' => $deletedcourseid])); + + // Test rendering. + $PAGE->set_url('/report/loglive/index.php?id=' . $deletedcourseid); + $renderable = new \report_loglive_renderable('', (int) $deletedcourseid); + $table = $renderable->get_table(); + $store->flush(); + $table->query_db(100); + + // Confirm we have logs for the course deletion and that the filtering is correct. + $this->assertNotEmpty($table->totalrows); + $expectedrows = count($DB->get_records('logstore_standard_log', ['courseid' => $deletedcourseid])); + $this->assertEquals($expectedrows, $table->totalrows); + } }