diff --git a/course/lib.php b/course/lib.php index f875317bfeb..44b41aa6ab0 100644 --- a/course/lib.php +++ b/course/lib.php @@ -4746,26 +4746,26 @@ function course_get_recent_courses(int $userid = null, int $limit = 0, int $offs JOIN {user_lastaccess} ul ON ul.courseid = c.id $favsql + LEFT JOIN {enrol} eg ON eg.courseid = c.id AND eg.status = :statusenrolg AND eg.enrol = :guestenrol WHERE ul.userid = :userid AND c.visible = :visible - AND EXISTS (SELECT e.id + AND (eg.id IS NOT NULL + OR EXISTS (SELECT e.id FROM {enrol} e - LEFT JOIN {user_enrolments} ue ON ue.enrolid = e.id + JOIN {user_enrolments} ue ON ue.enrolid = e.id WHERE e.courseid = c.id AND e.status = :statusenrol - AND ((ue.status = :status - AND ue.userid = ul.userid - AND ue.timestart < :now1 - AND (ue.timeend = 0 OR ue.timeend > :now2) - ) - OR e.enrol = :guestenrol - ) - ) + AND ue.status = :status + AND ue.userid = :userid2 + AND ue.timestart < :now1 + AND (ue.timeend = 0 OR ue.timeend > :now2) + )) $orderby"; $now = round(time(), -2); // Improves db caching. $params = ['userid' => $userid, 'contextlevel' => CONTEXT_COURSE, 'visible' => 1, 'status' => ENROL_USER_ACTIVE, - 'statusenrol' => ENROL_INSTANCE_ENABLED, 'guestenrol' => 'guest', 'now1' => $now, 'now2' => $now] + $favparams; + 'statusenrol' => ENROL_INSTANCE_ENABLED, 'guestenrol' => 'guest', 'now1' => $now, 'now2' => $now, + 'userid2' => $userid, 'statusenrolg' => ENROL_INSTANCE_ENABLED] + $favparams; $recentcourses = $DB->get_records_sql($sql, $params, $offset, $limit); diff --git a/course/tests/courselib_test.php b/course/tests/courselib_test.php index 8f00f155602..e7694fed2c6 100644 --- a/course/tests/courselib_test.php +++ b/course/tests/courselib_test.php @@ -5464,6 +5464,50 @@ class core_course_courselib_testcase extends advanced_testcase { $this->assertArrayNotHasKey($courses[0]->id, $result); } + /** + * Test the course_get_recent_courses function. + */ + public function test_course_get_recent_courses_with_guest() { + global $DB; + $this->resetAfterTest(true); + + $student = $this->getDataGenerator()->create_user(); + + // Course 1 with guest access and no direct enrolment. + $course1 = $this->getDataGenerator()->create_course(); + $context1 = context_course::instance($course1->id); + $record = $DB->get_record('enrol', ['courseid' => $course1->id, 'enrol' => 'guest']); + enrol_get_plugin('guest')->update_status($record, ENROL_INSTANCE_ENABLED); + + // Course 2 where student is enrolled with two enrolment methods. + $course2 = $this->getDataGenerator()->create_course(); + $context2 = context_course::instance($course2->id); + $record = $DB->get_record('enrol', ['courseid' => $course2->id, 'enrol' => 'self']); + enrol_get_plugin('guest')->update_status($record, ENROL_INSTANCE_ENABLED); + $this->getDataGenerator()->enrol_user($student->id, $course2->id, 'student', 'manual', 0, 0, ENROL_USER_ACTIVE); + $this->getDataGenerator()->enrol_user($student->id, $course2->id, 'student', 'self', 0, 0, ENROL_USER_ACTIVE); + + // Course 3. + $course3 = $this->getDataGenerator()->create_course(); + $context3 = context_course::instance($course3->id); + + // Student visits first two courses, course_get_recent_courses returns two courses. + $this->setUser($student); + course_view($context1); + course_view($context2); + + $result = course_get_recent_courses($student->id); + $this->assertEqualsCanonicalizing([$course2->id, $course1->id], array_column($result, 'id')); + + // Admin visits all three courses. Only the one with guest access is returned. + $this->setAdminUser(); + course_view($context1); + course_view($context2); + course_view($context3); + $result = course_get_recent_courses(get_admin()->id); + $this->assertEqualsCanonicalizing([$course1->id], array_column($result, 'id')); + } + /** * Test cases for the course_get_course_dates_for_user_ids tests. */