MDL-33741 file_info: show courses in hidden categories
[moodle.git] / lib / filebrowser / file_info_context_coursecat.php
CommitLineData
64a19b38 1<?php
64a19b38 2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17
18/**
19 * Utility class for browsing of curse category files.
20 *
d2b7803e 21 * @package core_files
64a19b38 22 * @copyright 2008 Petr Skoda (http://skodak.org)
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
172dd12c 25
64f93798
PS
26defined('MOODLE_INTERNAL') || die();
27
b81fd01d 28/**
d2b7803e 29 * Represents a course category context in the tree navigated by {@link file_browser}.
64f93798 30 *
d2b7803e 31 * @package core_files
64f93798
PS
32 * @copyright 2008 Petr Skoda (http://skodak.org)
33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
b81fd01d 34 */
64f93798 35class file_info_context_coursecat extends file_info {
d2b7803e 36 /** @var stdClass Category object */
172dd12c 37 protected $category;
38
d2b7803e
DC
39 /**
40 * Constructor
41 *
42 * @param file_browser $browser file browser instance
43 * @param stdClass $context context object
44 * @param stdClass $category category object
45 */
172dd12c 46 public function __construct($browser, $context, $category) {
47 parent::__construct($browser, $context);
48 $this->category = $category;
49 }
50
4cd9dfda 51 /**
64f93798
PS
52 * Return information about this specific context level
53 *
d2b7803e
DC
54 * @param string $component component
55 * @param string $filearea file area
56 * @param int $itemid item ID
57 * @param string $filepath file path
58 * @param string $filename file name
59 * @return fileinfo|null
4cd9dfda 60 */
64f93798
PS
61 public function get_file_info($component, $filearea, $itemid, $filepath, $filename) {
62 global $DB;
63
64 if (!$this->category->visible and !has_capability('moodle/category:viewhiddencategories', $this->context)) {
65 if (empty($component)) {
66 // we can not list the category contents, so try parent, or top system
67 if ($this->category->parent and $pc = $DB->get_record('course_categories', array('id'=>$this->category->parent))) {
b0c6dc1c 68 $parent = context_coursecat::instance($pc->id, IGNORE_MISSING);
64f93798
PS
69 return $this->browser->get_file_info($parent);
70 } else {
71 return $this->browser->get_file_info();
72 }
73 }
74 return null;
75 }
76
77 if (empty($component)) {
78 return $this;
79 }
80
81 $methodname = "get_area_{$component}_{$filearea}";
82 if (method_exists($this, $methodname)) {
83 return $this->$methodname($itemid, $filepath, $filename);
84 }
85
86 return null;
87 }
88
d2b7803e
DC
89 /**
90 * Return a file from course category description area
91 *
92 * @param int $itemid item ID
93 * @param string $filepath file path
94 * @param string $filename file name
95 * @return fileinfo|null
96 */
64f93798
PS
97 protected function get_area_coursecat_description($itemid, $filepath, $filename) {
98 global $CFG;
99
07d47778
MG
100 if (!$this->category->visible and !has_capability('moodle/category:viewhiddencategories', $this->context)) {
101 return null;
102 }
103 if (!has_capability('moodle/category:manage', $this->context)) {
64f93798
PS
104 return null;
105 }
106
107 if (is_null($itemid)) {
108 return $this;
109 }
110
111 $fs = get_file_storage();
112
113 $filepath = is_null($filepath) ? '/' : $filepath;
114 $filename = is_null($filename) ? '.' : $filename;
115 $urlbase = $CFG->wwwroot.'/pluginfile.php';
116 if (!$storedfile = $fs->get_file($this->context->id, 'coursecat', 'description', 0, $filepath, $filename)) {
117 if ($filepath === '/' and $filename === '.') {
118 $storedfile = new virtual_root_file($this->context->id, 'coursecat', 'description', 0);
119 } else {
120 // not found
121 return null;
122 }
123 }
124
125 return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areacategoryintro', 'repository'), false, true, true, false);
172dd12c 126 }
127
4cd9dfda 128 /**
129 * Returns localised visible name.
d2b7803e 130 *
4cd9dfda 131 * @return string
132 */
172dd12c 133 public function get_visible_name() {
1bbdde13 134 return format_string($this->category->name, true, array('context'=>$this->context));
172dd12c 135 }
136
4cd9dfda 137 /**
d2b7803e
DC
138 * Whether or not new files or directories can be added
139 *
4cd9dfda 140 * @return bool
141 */
cf7ec8e9 142 public function is_writable() {
143 return false;
144 }
145
4cd9dfda 146 /**
d2b7803e
DC
147 * Whether or not this is a directory
148 *
4cd9dfda 149 * @return bool
150 */
172dd12c 151 public function is_directory() {
152 return true;
153 }
154
4cd9dfda 155 /**
156 * Returns list of children.
d2b7803e 157 *
4cd9dfda 158 * @return array of file_info instances
159 */
172dd12c 160 public function get_children() {
161 global $DB;
162
163 $children = array();
164
64f93798 165 if ($child = $this->get_area_coursecat_description(0, '/', '.')) {
172dd12c 166 $children[] = $child;
167 }
168
64f93798 169 $course_cats = $DB->get_records('course_categories', array('parent'=>$this->category->id), 'sortorder', 'id,visible');
172dd12c 170 foreach ($course_cats as $category) {
b0c6dc1c 171 $context = context_coursecat::instance($category->id);
64f93798 172 if (!$category->visible and !has_capability('moodle/category:viewhiddencategories', $context)) {
172dd12c 173 continue;
174 }
175 if ($child = $this->browser->get_file_info($context)) {
176 $children[] = $child;
177 }
178 }
179
64f93798 180 $courses = $DB->get_records('course', array('category'=>$this->category->id), 'sortorder', 'id,visible');
172dd12c 181 foreach ($courses as $course) {
b0c6dc1c 182 $context = context_course::instance($course->id);
172dd12c 183 if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
184 continue;
185 }
186 if ($child = $this->browser->get_file_info($context)) {
187 $children[] = $child;
188 }
189 }
190
191 return $children;
192 }
193
b8de2621
MG
194 /**
195 * Returns the number of children which are either files matching the specified extensions
196 * or folders containing at least one such file.
197 *
b8de2621 198 * @param string|array $extensions, for example '*' or array('.gif','.jpg')
43aadf04 199 * @param int $limit stop counting after at least $limit non-empty children are found
b8de2621
MG
200 * @return int
201 */
43aadf04 202 public function count_non_empty_children($extensions = '*', $limit = 1) {
b8de2621 203 global $DB;
43aadf04 204 $cnt = 0;
b8de2621 205 if (($child = $this->get_area_coursecat_description(0, '/', '.'))
43aadf04
MG
206 && $child->count_non_empty_children($extensions) && (++$cnt) >= $limit) {
207 return $cnt;
b8de2621
MG
208 }
209
dd9cd338 210 $rs = $DB->get_recordset_sql('SELECT ctx.id AS contextid, c.visible
43aadf04
MG
211 FROM {context} ctx, {course} c
212 WHERE ctx.instanceid = c.id
213 AND ctx.contextlevel = :courselevel
214 AND c.category = :categoryid
215 ORDER BY c.visible DESC', // retrieve visible courses first
216 array('categoryid' => $this->category->id, 'courselevel' => CONTEXT_COURSE));
217 foreach ($rs as $record) {
218 $context = context::instance_by_id($record->contextid);
219 if (!$record->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
b8de2621
MG
220 continue;
221 }
222 if (($child = $this->browser->get_file_info($context))
43aadf04
MG
223 && $child->count_non_empty_children($extensions) && (++$cnt) >= $limit) {
224 break;
b8de2621
MG
225 }
226 }
43aadf04
MG
227 $rs->close();
228 if ($cnt >= $limit) {
229 return $cnt;
230 }
b8de2621 231
dd9cd338 232 $rs = $DB->get_recordset_sql('SELECT ctx.id AS contextid, cat.visible
43aadf04
MG
233 FROM {context} ctx, {course_categories} cat
234 WHERE ctx.instanceid = cat.id
235 AND ctx.contextlevel = :catlevel
236 AND cat.parent = :categoryid
237 ORDER BY cat.visible DESC', // retrieve visible categories first
238 array('categoryid' => $this->category->id, 'catlevel' => CONTEXT_COURSECAT));
239 foreach ($rs as $record) {
240 $context = context::instance_by_id($record->contextid);
241 if (!$record->visible and !has_capability('moodle/category:viewhiddencategories', $context)) {
b8de2621
MG
242 continue;
243 }
244 if (($child = $this->browser->get_file_info($context))
43aadf04
MG
245 && $child->count_non_empty_children($extensions) && (++$cnt) >= $limit) {
246 break;
b8de2621
MG
247 }
248 }
43aadf04 249 $rs->close();
b8de2621 250
43aadf04 251 return $cnt;
b8de2621
MG
252 }
253
4cd9dfda 254 /**
255 * Returns parent file_info instance
d2b7803e
DC
256 *
257 * @return file_info|null fileinfo instance or null for root directory
4cd9dfda 258 */
172dd12c 259 public function get_parent() {
7f5b51c4 260 $parent = $this->context->get_parent_context();
172dd12c 261 return $this->browser->get_file_info($parent);
262 }
263}