MDL-63457 block_myoverview: Update getters for enrolled courses
authorPeter <peter@moodle.com>
Fri, 26 Oct 2018 04:37:31 +0000 (12:37 +0800)
committerPeter <peter@moodle.com>
Mon, 29 Oct 2018 00:36:59 +0000 (08:36 +0800)
* Update the enrol courses getter to accept an 'exclude course' id array
* Use the db query to filter hidden courses

course/externallib.php
course/lib.php
enrol/tests/enrollib_test.php
lib/enrollib.php

index f315f8b..13c53cb 100644 (file)
@@ -3675,7 +3675,17 @@ class core_course_external extends external_api {
 
         $requiredproperties = course_summary_exporter::define_properties();
         $fields = join(',', array_keys($requiredproperties));
-        $courses = course_get_enrolled_courses_for_logged_in_user(0, $offset, $sort, $fields);
+        $hiddencourses = get_hidden_courses_on_timeline();
+        $courses = [];
+
+        // If the timeline requires the hidden courses then restrict the result to only $hiddencourses else exclude.
+        if ($classification == COURSE_TIMELINE_HIDDEN) {
+            $courses = course_get_enrolled_courses_for_logged_in_user(0, $offset, $sort, $fields,
+                COURSE_DB_QUERY_LIMIT, $hiddencourses);
+        } else {
+            $courses = course_get_enrolled_courses_for_logged_in_user(0, $offset, $sort, $fields,
+                COURSE_DB_QUERY_LIMIT, [], $hiddencourses);
+        }
 
         $favouritecourseids = [];
         $ufservice = \core_favourites\service_factory::get_service_for_user_context(\context_user::instance($USER->id));
index e24ca5f..d7b9245 100644 (file)
@@ -4191,6 +4191,8 @@ function course_classify_courses_for_timeline(array $courses) {
  * @param string|null $sort SQL string for sorting
  * @param string|null $fields SQL string for fields to be returned
  * @param int $dbquerylimit The number of records to load per DB request
+ * @param array $includecourses courses ids to be restricted
+ * @param array $hiddencourses courses ids to be excluded
  * @return Generator
  */
 function course_get_enrolled_courses_for_logged_in_user(
@@ -4198,14 +4200,16 @@ function course_get_enrolled_courses_for_logged_in_user(
     int $offset = 0,
     string $sort = null,
     string $fields = null,
-    int $dbquerylimit = COURSE_DB_QUERY_LIMIT
+    int $dbquerylimit = COURSE_DB_QUERY_LIMIT,
+    array $includecourses = [],
+    array $hiddencourses = []
 ) : Generator {
 
     $haslimit = !empty($limit);
     $recordsloaded = 0;
     $querylimit = (!$haslimit || $limit > $dbquerylimit) ? $dbquerylimit : $limit;
 
-    while ($courses = enrol_get_my_courses($fields, $sort, $querylimit, [], false, $offset)) {
+    while ($courses = enrol_get_my_courses($fields, $sort, $querylimit, $includecourses, false, $offset, $hiddencourses)) {
         yield from $courses;
 
         $recordsloaded += $querylimit;
@@ -4304,9 +4308,8 @@ function course_filter_courses_by_favourites(
 
     foreach ($courses as $course) {
         $numberofcoursesprocessed++;
-        $pref = get_user_preferences('block_myoverview_hidden_course_' . $course->id, 0);
 
-        if (in_array($course->id, $favouritecourseids) && !$pref) {
+        if (in_array($course->id, $favouritecourseids)) {
             $filteredcourses[] = $course;
             $filtermatches++;
         }
@@ -4500,3 +4503,29 @@ function can_download_from_backup_filearea($filearea, \context $context, stdClas
     }
     return $candownload;
 }
+
+/**
+ * Get a list of hidden courses
+ *
+ * @param int|object|null $user User override to get the filter from. Defaults to current user
+ * @return array $ids List of hidden courses
+ * @throws coding_exception
+ */
+function get_hidden_courses_on_timeline($user = null) {
+    global $USER;
+
+    if (empty($user)) {
+        $user = $USER->id;
+    }
+
+    $preferences = get_user_preferences(null, null, $user);
+    $ids = [];
+    foreach ($preferences as $key => $value) {
+        if (preg_match('/block_myoverview_hidden_course_(\d)+/', $key)) {
+            $id = preg_split('/block_myoverview_hidden_course_/', $key);
+            $ids[] = $id[1];
+        }
+    }
+
+    return $ids;
+}
index 34b5b48..1f3ff6b 100644 (file)
@@ -604,6 +604,60 @@ class core_enrollib_testcase extends advanced_testcase {
         $this->assertEquals($course2->id, $courses[$course2->id]->id);
     }
 
+    /**
+     * Tests the enrol_get_my_courses function when using the $includehidden parameter, which
+     * should remove any courses hidden from the user's timeline
+     *
+     * @throws coding_exception
+     * @throws dml_exception
+     */
+    public function test_enrol_get_my_courses_include_hidden() {
+        global $DB, $CFG;
+
+        $this->resetAfterTest(true);
+
+        // Create test user and 4 courses, two of which have guest access enabled.
+        $user = $this->getDataGenerator()->create_user();
+        $course1 = $this->getDataGenerator()->create_course(
+            (object)array('shortname' => 'X',
+                'enrol_guest_status_0' => ENROL_INSTANCE_DISABLED,
+                'enrol_guest_password_0' => ''));
+        $course2 = $this->getDataGenerator()->create_course(
+            (object)array('shortname' => 'Z',
+                'enrol_guest_status_0' => ENROL_INSTANCE_ENABLED,
+                'enrol_guest_password_0' => ''));
+        $course3 = $this->getDataGenerator()->create_course(
+            (object)array('shortname' => 'Y',
+                'enrol_guest_status_0' => ENROL_INSTANCE_ENABLED,
+                'enrol_guest_password_0' => 'frog'));
+        $course4 = $this->getDataGenerator()->create_course(
+            (object)array('shortname' => 'W',
+                'enrol_guest_status_0' => ENROL_INSTANCE_DISABLED,
+                'enrol_guest_password_0' => ''));
+
+        // User is enrolled in first course.
+        $this->getDataGenerator()->enrol_user($user->id, $course1->id);
+        $this->getDataGenerator()->enrol_user($user->id, $course2->id);
+        $this->getDataGenerator()->enrol_user($user->id, $course3->id);
+        $this->getDataGenerator()->enrol_user($user->id, $course4->id);
+
+        // Check enrol_get_my_courses basic use (without include hidden provided).
+        $this->setUser($user);
+        $courses = enrol_get_my_courses();
+        $this->assertEquals([$course4->id, $course3->id, $course2->id, $course1->id], array_keys($courses));
+
+        // Hide a course.
+        set_user_preference('block_myoverview_hidden_course_' . $course3->id, true);
+
+        // Hidden course shouldn't be returned.
+        $courses = enrol_get_my_courses(null, null, 0, [], false, 0, [$course3->id]);
+        $this->assertEquals([$course4->id, $course2->id, $course1->id], array_keys($courses));
+
+        // Offset should take into account hidden course.
+        $courses = enrol_get_my_courses(null, null, 0, [], false, 2, [$course3->id]);
+        $this->assertEquals([$course1->id], array_keys($courses));
+    }
+
     /**
      * Tests the enrol_get_my_courses function when using the $allaccessible parameter, which
      * includes a wider range of courses (enrolled courses + other accessible ones).
index 5ddf497..ad2b0b9 100644 (file)
@@ -560,9 +560,11 @@ function enrol_add_course_navigation(navigation_node $coursenode, $course) {
  * @param array $courseids the list of course ids to filter by
  * @param bool $allaccessible Include courses user is not enrolled in, but can access
  * @param int $offset Offset the result set by this number
+ * @param array $excludecourses IDs of hidden courses to exclude from search
  * @return array
  */
-function enrol_get_my_courses($fields = null, $sort = null, $limit = 0, $courseids = [], $allaccessible = false, $offset = 0) {
+function enrol_get_my_courses($fields = null, $sort = null, $limit = 0, $courseids = [], $allaccessible = false,
+    $offset = 0, $excludecourses = []) {
     global $DB, $USER, $CFG;
 
     if ($sort === null) {
@@ -654,6 +656,12 @@ function enrol_get_my_courses($fields = null, $sort = null, $limit = 0, $coursei
         $params = array_merge($params, $courseidsparams);
     }
 
+    if (!empty($excludecourses)) {
+        list($courseidssql, $courseidsparams) = $DB->get_in_or_equal($excludecourses, SQL_PARAMS_NAMED, 'param', false);
+        $wheres = sprintf("%s AND c.id %s", $wheres, $courseidssql);
+        $params = array_merge($params, $courseidsparams);
+    }
+
     $courseidsql = "";
     // Logged-in, non-guest users get their enrolled courses.
     if (!isguestuser() && isloggedin()) {