MDL-33741 file_info: show courses in hidden categories
authorMarina Glancy <marina@moodle.com>
Thu, 28 Jul 2016 03:42:40 +0000 (11:42 +0800)
committerMarina Glancy <marina@moodle.com>
Mon, 1 Aug 2016 01:12:36 +0000 (09:12 +0800)
This also has a couple of bugfixes:
- file_info_context_system::get_children() was looking for courses with parent=0, it is impossible, block removed;
- file_info_context_coursecat::get_area_coursecat_description() was checking the wrong capability to view files in description

lib/filebrowser/file_info_context_coursecat.php
lib/filebrowser/file_info_context_system.php

index 5b49526..7c354bd 100644 (file)
@@ -97,7 +97,10 @@ class file_info_context_coursecat extends file_info {
     protected function get_area_coursecat_description($itemid, $filepath, $filename) {
         global $CFG;
 
-        if (!has_capability('moodle/course:update', $this->context)) {
+        if (!$this->category->visible and !has_capability('moodle/category:viewhiddencategories', $this->context)) {
+            return null;
+        }
+        if (!has_capability('moodle/category:manage', $this->context)) {
             return null;
         }
 
index 18331a9..27144c0 100644 (file)
@@ -145,10 +145,11 @@ class file_info_context_system extends file_info {
      * @return array of file_info instances
      */
     public function get_children() {
-        global $DB, $USER;
+        global $DB;
 
         $children = array();
 
+        // Add course categories on the top level that are either visible or user is able to view hidden categories.
         $course_cats = $DB->get_records('course_categories', array('parent'=>0), 'sortorder', 'id,visible');
         foreach ($course_cats as $category) {
             $context = context_coursecat::instance($category->id);
@@ -160,20 +161,49 @@ class file_info_context_system extends file_info {
             }
         }
 
-        $courses = $DB->get_records('course', array('category'=>0), 'sortorder', 'id,visible');
-        foreach ($courses as $course) {
-            if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
-                continue;
-            }
-            $context = context_course::instance($course->id);
-            if ($child = $this->browser->get_file_info($context)) {
-                $children[] = $child;
+        // Add courses where user is enrolled that are located in hidden course categories because they would not
+        // be present in the above tree but user may still be able to access files in them.
+        if ($hiddencontexts = $this->get_inaccessible_coursecat_contexts()) {
+            $courses = enrol_get_my_courses();
+            foreach ($courses as $course) {
+                $context = context_course::instance($course->id);
+                $parents = $context->get_parent_context_ids();
+                if (array_intersect($hiddencontexts, $parents)) {
+                    // This course has hidden parent category.
+                    if ($child = $this->browser->get_file_info($context)) {
+                        $children[] = $child;
+                    }
+                }
             }
         }
 
         return $children;
     }
 
+    /**
+     * Returns list of course categories contexts that current user can not see
+     *
+     * @return array array of course categories contexts ids
+     */
+    protected function get_inaccessible_coursecat_contexts() {
+        global $DB;
+
+        $sql = context_helper::get_preload_record_columns_sql('ctx');
+        $records = $DB->get_records_sql("SELECT ctx.id, $sql
+            FROM {course_categories} c
+            JOIN {context} ctx ON c.id = ctx.instanceid AND ctx.contextlevel = ?
+            WHERE c.visible = ?", [CONTEXT_COURSECAT, 0]);
+        $hiddencontexts = [];
+        foreach ($records as $record) {
+            context_helper::preload_from_record($record);
+            $context = context::instance_by_id($record->id);
+            if (!has_capability('moodle/category:viewhiddencategories', $context)) {
+                $hiddencontexts[] = $record->id;
+            }
+        }
+        return $hiddencontexts;
+    }
+
     /**
      * Returns parent file_info instance
      *