MDL-27586 fix file_browser access control
[moodle.git] / lib / filebrowser / file_info_context_module.php
CommitLineData
64f93798
PS
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18
19/**
20 * Utility class for browsing of module files.
21 *
22 * @package core
23 * @subpackage filebrowser
24 * @copyright 2008 Petr Skoda (http://skodak.org)
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 */
27
28defined('MOODLE_INTERNAL') || die();
29
30/**
31 * Represents a module context in the tree navigated by @see{file_browser}.
32 *
33 * @package core
34 * @subpackage filebrowser
35 * @copyright 2008 Petr Skoda (http://skodak.org)
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 */
38class file_info_context_module extends file_info {
39 protected $course;
40 protected $cm;
41 protected $modname;
42 protected $areas;
43
44 public function __construct($browser, $context, $course, $cm, $modname) {
08b4939b 45 global $CFG;
64f93798
PS
46
47 parent::__construct($browser, $context);
48 $this->course = $course;
49 $this->cm = $cm;
50 $this->modname = $modname;
51
52 include_once("$CFG->dirroot/mod/$modname/lib.php");
53
54 //find out all supported areas
55 $functionname = 'mod_'.$modname.'_get_file_areas';
56 $functionname_old = $modname.'_get_file_areas';
57
58 if (function_exists($functionname)) {
59 $this->areas = $functionname($course, $cm, $context);
60 } else if (function_exists($functionname_old)) {
61 $this->areas = $functionname_old($course, $cm, $context);
62 } else {
63 $this->areas = array();
64 }
65 unset($this->areas['intro']); // hardcoded, ignore attempts to override it
66 }
67
68 /**
69 * Return information about this specific context level
70 *
71 * @param $component
72 * @param $filearea
73 * @param $itemid
74 * @param $filepath
75 * @param $filename
76 */
77 public function get_file_info($component, $filearea, $itemid, $filepath, $filename) {
f6b07c4d
PS
78 // try to emulate require_login() tests here
79 if (!isloggedin()) {
80 return null;
81 }
82
83 $coursecontext = get_course_context($this->context);
84 if (!$this->course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
85 return null;
86 }
87
88 if (!is_viewing($this->context) and !is_enrolled($this->context)) {
64f93798
PS
89 // no peaking here if not enrolled or inspector
90 return null;
91 }
92
f6b07c4d
PS
93 $modinfo = get_fast_modinfo($this->course);
94 $cminfo = $modinfo->get_cm($this->cm->id);
95 if (!$cminfo->uservisible) {
96 // activity hidden sorry
97 return null;
98 }
99
64f93798
PS
100 if (empty($component)) {
101 return $this;
102 }
103
104 if ($component == 'mod_'.$this->modname and $filearea === 'intro') {
105 return $this->get_area_intro($itemid, $filepath, $filename);
106 } else if ($component == 'backup' and $filearea === 'activity') {
107 return $this->get_area_backup($itemid, $filepath, $filename);
108 }
109
110 $functionname = 'mod_'.$this->modname.'_get_file_info';
111 $functionname_old = $this->modname.'_get_file_info';
112
113 if (function_exists($functionname)) {
114 return $functionname($this->browser, $this->areas, $this->course, $this->cm, $this->context, $filearea, $itemid, $filepath, $filename);
115 } else if (function_exists($functionname_old)) {
116 return $functionname_old($this->browser, $this->areas, $this->course, $this->cm, $this->context, $filearea, $itemid, $filepath, $filename);
117 }
118
119 return null;
120 }
121
122 protected function get_area_intro($itemid, $filepath, $filename) {
123 global $CFG;
124
125 if (!plugin_supports('mod', $this->modname, FEATURE_MOD_INTRO, true) or !has_capability('moodle/course:managefiles', $this->context)) {
126 return null;
127 }
128
64f93798
PS
129 $fs = get_file_storage();
130
131 $filepath = is_null($filepath) ? '/' : $filepath;
132 $filename = is_null($filename) ? '.' : $filename;
133 if (!$storedfile = $fs->get_file($this->context->id, 'mod_'.$this->modname, 'intro', 0, $filepath, $filename)) {
134 if ($filepath === '/' and $filename === '.') {
135 $storedfile = new virtual_root_file($this->context->id, 'mod_'.$this->modname, 'intro', 0);
136 } else {
137 // not found
138 return null;
139 }
140 }
141
142 $urlbase = $CFG->wwwroot.'/pluginfile.php';
143 return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('moduleintro'), false, true, true, false);
144 }
145
146 protected function get_area_backup($itemid, $filepath, $filename) {
147 global $CFG;
148
149 if (!has_capability('moodle/backup:backupactivity', $this->context)) {
150 return null;
151 }
152
64f93798
PS
153 $fs = get_file_storage();
154
155 $filepath = is_null($filepath) ? '/' : $filepath;
156 $filename = is_null($filename) ? '.' : $filename;
157 if (!$storedfile = $fs->get_file($this->context->id, 'backup', 'activity', 0, $filepath, $filename)) {
158 if ($filepath === '/' and $filename === '.') {
159 $storedfile = new virtual_root_file($this->context->id, 'backup', 'activity', 0);
160 } else {
161 // not found
162 return null;
163 }
164 }
165
166 $downloadable = has_capability('moodle/backup:downloadfile', $this->context);
167 $uploadable = has_capability('moodle/restore:uploadfile', $this->context);
168
169 $urlbase = $CFG->wwwroot.'/pluginfile.php';
170 return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('activitybackup', 'repository'), false, $downloadable, $uploadable, false);
171 }
172
173 /**
174 * Returns localised visible name.
175 * @return string
176 */
177 public function get_visible_name() {
178 return $this->cm->name.' ('.get_string('modulename', $this->cm->modname).')';
179 }
180
181 /**
182 * Can I add new files or directories?
183 * @return bool
184 */
185 public function is_writable() {
186 return false;
187 }
188
16741cac
PS
189 /**
190 * Is this empty area?
191 *
192 * @return bool
193 */
194 public function is_empty_area() {
195 if ($child = $this->get_area_backup(0, '/', '.')) {
196 if (!$child->is_empty_area()) {
197 return false;
198 }
199 }
200 if ($child = $this->get_area_intro(0, '/', '.')) {
201 if (!$child->is_empty_area()) {
202 return false;
203 }
204 }
205
206 foreach ($this->areas as $area=>$desctiption) {
207 if ($child = $this->get_file_info('mod_'.$this->modname, $area, null, null, null)) {
208 if (!$child->is_empty_area()) {
209 return false;
210 }
211 }
212 }
213
214 return true;
215 }
216
64f93798
PS
217 /**
218 * Is directory?
219 * @return bool
220 */
221 public function is_directory() {
222 return true;
223 }
224
225 /**
226 * Returns list of children.
227 * @return array of file_info instances
228 */
229 public function get_children() {
230 $children = array();
231
232 if ($child = $this->get_area_backup(0, '/', '.')) {
233 $children[] = $child;
234 }
235 if ($child = $this->get_area_intro(0, '/', '.')) {
236 $children[] = $child;
237 }
238
239 foreach ($this->areas as $area=>$desctiption) {
240 if ($child = $this->get_file_info('mod_'.$this->modname, $area, null, null, null)) {
241 $children[] = $child;
242 }
243 }
8b32a7aa 244
64f93798
PS
245 return $children;
246 }
247
248 /**
249 * Returns parent file_info instance
250 * @return file_info or null for root
251 */
252 public function get_parent() {
253 $pcid = get_parent_contextid($this->context);
254 $parent = get_context_instance_by_id($pcid);
255 return $this->browser->get_file_info($parent);
256 }
257}