Commit | Line | Data |
---|---|---|
28f672b2 | 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/>. | |
2a439ba7 | 17 | |
28f672b2 | 18 | /** |
19 | * @package mod-resource | |
aa54ed7b | 20 | * @copyright 2009 Petr Skoda (http://skodak.org) |
28f672b2 | 21 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
22 | */ | |
23 | ||
aa54ed7b | 24 | /** |
25 | * List of features supported in Resource module | |
26 | * @param string $feature FEATURE_xx constant for requested feature | |
27 | * @return mixed True if module supports feature, false if not, null if doesn't know | |
28 | */ | |
29 | function resource_supports($feature) { | |
30 | switch($feature) { | |
31 | case FEATURE_MOD_ARCHETYPE: return MOD_ARCHETYPE_RESOURCE; | |
32 | case FEATURE_GROUPS: return false; | |
33 | case FEATURE_GROUPINGS: return false; | |
34 | case FEATURE_GROUPMEMBERSONLY: return true; | |
35 | case FEATURE_MOD_INTRO: return true; | |
36 | case FEATURE_COMPLETION_TRACKS_VIEWS: return true; | |
37 | case FEATURE_GRADE_HAS_GRADE: return false; | |
38 | case FEATURE_GRADE_OUTCOMES: return false; | |
a345de6e | 39 | case FEATURE_BACKUP_MOODLE2: return true; |
214b1cf7 | 40 | |
aa54ed7b | 41 | default: return null; |
42 | } | |
43 | } | |
713d78ea | 44 | |
28f672b2 | 45 | /** |
aa54ed7b | 46 | * Returns all other caps used in module |
47 | * @return array | |
28f672b2 | 48 | */ |
aa54ed7b | 49 | function resource_get_extra_capabilities() { |
50 | return array('moodle/site:accessallgroups'); | |
51 | } | |
3d30a455 | 52 | |
d18830fe | 53 | /** |
aa54ed7b | 54 | * This function is used by the reset_course_userdata function in moodlelib. |
55 | * @param $data the data submitted from the reset course. | |
56 | * @return array status array | |
28f672b2 | 57 | */ |
aa54ed7b | 58 | function resource_reset_userdata($data) { |
59 | return array(); | |
60 | } | |
65634a81 | 61 | |
aa54ed7b | 62 | /** |
63 | * List of view style log actions | |
64 | * @return array | |
65 | */ | |
66 | function resource_get_view_actions() { | |
67 | return array('view','view all'); | |
68 | } | |
65634a81 | 69 | |
aa54ed7b | 70 | /** |
71 | * List of update style log actions | |
72 | * @return array | |
73 | */ | |
74 | function resource_get_post_actions() { | |
75 | return array('update', 'add'); | |
76 | } | |
65634a81 | 77 | |
aa54ed7b | 78 | /** |
79 | * Add resource instance. | |
80 | * @param object $data | |
81 | * @param object $mform | |
82 | * @return int new resoruce instance id | |
83 | */ | |
84 | function resource_add_instance($data, $mform) { | |
85 | global $CFG, $DB; | |
86 | require_once("$CFG->libdir/resourcelib.php"); | |
f79321f1 | 87 | $cmid = $data->coursemodule; |
aa54ed7b | 88 | $data->timemodified = time(); |
89 | $displayoptions = array(); | |
90 | if ($data->display == RESOURCELIB_DISPLAY_POPUP) { | |
91 | $displayoptions['popupwidth'] = $data->popupwidth; | |
92 | $displayoptions['popupheight'] = $data->popupheight; | |
65634a81 | 93 | } |
aa54ed7b | 94 | if (in_array($data->display, array(RESOURCELIB_DISPLAY_AUTO, RESOURCELIB_DISPLAY_EMBED, RESOURCELIB_DISPLAY_FRAME))) { |
95 | $displayoptions['printheading'] = (int)!empty($data->printheading); | |
96 | $displayoptions['printintro'] = (int)!empty($data->printintro); | |
ec81373f | 97 | } |
aa54ed7b | 98 | $data->displayoptions = serialize($displayoptions); |
d18830fe | 99 | |
aa54ed7b | 100 | $data->id = $DB->insert_record('resource', $data); |
d18830fe | 101 | |
aa54ed7b | 102 | // we need to use context now, so we need to make sure all needed info is already in db |
103 | $DB->set_field('course_modules', 'instance', $data->id, array('id'=>$cmid)); | |
f79321f1 | 104 | resource_set_mainfile($data); |
aa54ed7b | 105 | return $data->id; |
106 | } | |
cccb016a | 107 | |
aa54ed7b | 108 | /** |
109 | * Update resource instance. | |
110 | * @param object $data | |
111 | * @param object $mform | |
112 | * @return bool true | |
113 | */ | |
114 | function resource_update_instance($data, $mform) { | |
115 | global $CFG, $DB; | |
116 | require_once("$CFG->libdir/resourcelib.php"); | |
aa54ed7b | 117 | $data->timemodified = time(); |
118 | $data->id = $data->instance; | |
119 | $data->revision++; | |
2a439ba7 | 120 | |
aa54ed7b | 121 | $displayoptions = array(); |
122 | if ($data->display == RESOURCELIB_DISPLAY_POPUP) { | |
123 | $displayoptions['popupwidth'] = $data->popupwidth; | |
124 | $displayoptions['popupheight'] = $data->popupheight; | |
65634a81 | 125 | } |
aa54ed7b | 126 | if (in_array($data->display, array(RESOURCELIB_DISPLAY_AUTO, RESOURCELIB_DISPLAY_EMBED, RESOURCELIB_DISPLAY_FRAME))) { |
127 | $displayoptions['printheading'] = (int)!empty($data->printheading); | |
128 | $displayoptions['printintro'] = (int)!empty($data->printintro); | |
3efe78df | 129 | } |
aa54ed7b | 130 | $data->displayoptions = serialize($displayoptions); |
3efe78df | 131 | |
aa54ed7b | 132 | $DB->update_record('resource', $data); |
f79321f1 | 133 | resource_set_mainfile($data); |
aa54ed7b | 134 | return true; |
d18830fe | 135 | } |
136 | ||
28f672b2 | 137 | /** |
aa54ed7b | 138 | * Delete resource instance. |
28f672b2 | 139 | * @param int $id |
aa54ed7b | 140 | * @return bool true |
28f672b2 | 141 | */ |
d18830fe | 142 | function resource_delete_instance($id) { |
aa54ed7b | 143 | global $DB; |
ec81373f | 144 | |
aa54ed7b | 145 | if (!$resource = $DB->get_record('resource', array('id'=>$id))) { |
d18830fe | 146 | return false; |
147 | } | |
79035d46 | 148 | |
aa54ed7b | 149 | // note: all context files are deleted automatically |
ec81373f | 150 | |
aa54ed7b | 151 | $DB->delete_records('resource', array('id'=>$resource->id)); |
d18830fe | 152 | |
aa54ed7b | 153 | return true; |
d18830fe | 154 | } |
155 | ||
28f672b2 | 156 | /** |
aa54ed7b | 157 | * Return use outline |
28f672b2 | 158 | * @param object $course |
159 | * @param object $user | |
160 | * @param object $mod | |
161 | * @param object $resource | |
162 | * @return object|null | |
163 | */ | |
2a439ba7 | 164 | function resource_user_outline($course, $user, $mod, $resource) { |
5f5cd33c | 165 | global $DB; |
166 | ||
aa54ed7b | 167 | if ($logs = $DB->get_records('log', array('userid'=>$user->id, 'module'=>'resource', |
168 | 'action'=>'view', 'info'=>$resource->id), 'time ASC')) { | |
2a439ba7 | 169 | |
170 | $numviews = count($logs); | |
171 | $lastlog = array_pop($logs); | |
172 | ||
9f741612 | 173 | $result = new object(); |
aa54ed7b | 174 | $result->info = get_string('numviews', '', $numviews); |
2a439ba7 | 175 | $result->time = $lastlog->time; |
176 | ||
177 | return $result; | |
178 | } | |
179 | return NULL; | |
180 | } | |
181 | ||
28f672b2 | 182 | /** |
aa54ed7b | 183 | * Return use complete |
28f672b2 | 184 | * @param object $course |
185 | * @param object $user | |
186 | * @param object $mod | |
187 | * @param object $resource | |
188 | */ | |
2a439ba7 | 189 | function resource_user_complete($course, $user, $mod, $resource) { |
5f5cd33c | 190 | global $CFG, $DB; |
2a439ba7 | 191 | |
aa54ed7b | 192 | if ($logs = $DB->get_records('log', array('userid'=>$user->id, 'module'=>'resource', |
193 | 'action'=>'view', 'info'=>$resource->id), 'time ASC')) { | |
2a439ba7 | 194 | $numviews = count($logs); |
195 | $lastlog = array_pop($logs); | |
196 | ||
aa54ed7b | 197 | $strmostrecently = get_string('mostrecently'); |
198 | $strnumviews = get_string('numviews', '', $numviews); | |
2a439ba7 | 199 | |
200 | echo "$strnumviews - $strmostrecently ".userdate($lastlog->time); | |
201 | ||
202 | } else { | |
aa54ed7b | 203 | print_string('neverseen', 'resource'); |
2a439ba7 | 204 | } |
205 | } | |
206 | ||
28f672b2 | 207 | /** |
208 | * Returns the users with data in one resource | |
28f672b2 | 209 | * |
210 | * @param int $resourceid | |
211 | * @return bool false | |
212 | */ | |
84caf038 | 213 | function resource_get_participants($resourceid) { |
84caf038 | 214 | return false; |
215 | } | |
2a439ba7 | 216 | |
28f672b2 | 217 | /** |
218 | * Given a course_module object, this function returns any | |
219 | * "extra" information that may be needed when printing | |
220 | * this activity in a course listing. | |
221 | * | |
222 | * See {@link get_array_of_activities()} in course/lib.php | |
223 | * | |
28f672b2 | 224 | * @param object $coursemodule |
225 | * @return object info | |
226 | */ | |
8dddba42 | 227 | function resource_get_coursemodule_info($coursemodule) { |
aa54ed7b | 228 | global $CFG, $DB; |
229 | require_once("$CFG->libdir/filelib.php"); | |
230 | require_once("$CFG->dirroot/mod/resource/locallib.php"); | |
f79321f1 | 231 | $context = get_context_instance(CONTEXT_MODULE, $coursemodule->id); |
ec81373f | 232 | |
f79321f1 | 233 | if (!$resource = $DB->get_record('resource', array('id'=>$coursemodule->instance), 'id, name, display, displayoptions, tobemigrated, revision')) { |
aa54ed7b | 234 | return NULL; |
af65e103 | 235 | } |
ec81373f | 236 | |
aa54ed7b | 237 | $info = new object(); |
238 | $info->name = $resource->name; | |
8dddba42 | 239 | |
aa54ed7b | 240 | if ($resource->tobemigrated) { |
241 | $info->icon ='i/cross_red_big'; | |
242 | return $info; | |
af65e103 | 243 | } |
f79321f1 DC |
244 | $fs = get_file_storage(); |
245 | $files = $fs->get_area_files($context->id, 'resource_content', 0, 'sortorder'); | |
246 | if (count($files) >= 1) { | |
247 | $mainfile = array_pop($files); | |
248 | $info->icon = str_replace(array('.gif', '.png'), '', file_extension_icon($mainfile->get_filename())); | |
249 | $resource->mainfile = $mainfile->get_filename(); | |
250 | } | |
d18830fe | 251 | |
aa54ed7b | 252 | $display = resource_get_final_display_type($resource); |
9f741612 | 253 | |
aa54ed7b | 254 | if ($display == RESOURCELIB_DISPLAY_POPUP) { |
255 | $fullurl = "$CFG->wwwroot/mod/resource/view.php?id=$coursemodule->id&redirect=1"; | |
256 | $options = empty($resource->displayoptions) ? array() : unserialize($resource->displayoptions); | |
257 | $width = empty($options['popupwidth']) ? 620 : $options['popupwidth']; | |
258 | $height = empty($options['popupheight']) ? 450 : $options['popupheight']; | |
259 | $wh = "width=$width,height=$height,toolbar=no,location=no,menubar=no,copyhistory=no,status=no,directories=no,scrollbars=yes,resizable=yes"; | |
9a9012dc | 260 | $info->extra = "onclick=\"window.open('$fullurl', '', '$wh'); return false;\""; |
6da4b261 | 261 | |
aa54ed7b | 262 | } else if ($display == RESOURCELIB_DISPLAY_NEW) { |
263 | $fullurl = "$CFG->wwwroot/mod/resource/view.php?id=$coursemodule->id&redirect=1"; | |
9a9012dc | 264 | $info->extra = "onclick=\"window.open('$fullurl'); return false;\""; |
6da4b261 | 265 | |
aa54ed7b | 266 | } else if ($display == RESOURCELIB_DISPLAY_OPEN) { |
267 | $fullurl = "$CFG->wwwroot/mod/resource/view.php?id=$coursemodule->id&redirect=1"; | |
9a9012dc | 268 | $info->extra = "onclick=\"window.location.href ='$fullurl';return false;\""; |
aa54ed7b | 269 | |
270 | } else if ($display == RESOURCELIB_DISPLAY_DOWNLOAD) { | |
f79321f1 DC |
271 | if (empty($mainfile)) { |
272 | return NULL; | |
273 | } | |
aa54ed7b | 274 | // do not open any window because it would be left there after download |
f1b8bcf7 | 275 | $path = '/'.$context->id.'/resource_content/'.$resource->revision.$mainfile->get_filepath().$mainfile->get_filename(); |
aa54ed7b | 276 | $fullurl = addslashes_js(file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, true)); |
c15a60e6 SM |
277 | |
278 | // When completion information is enabled for download files, make | |
279 | // the JavaScript version go to the view page with redirect set, | |
280 | // instead of directly to the file, otherwise we can't make it tick | |
281 | // the box for them | |
282 | if (!$course = $DB->get_record('course', array('id'=>$coursemodule->course), 'id, enablecompletion')) { | |
283 | return NULL; | |
284 | } | |
285 | $completion = new completion_info($course); | |
286 | if ($completion->is_enabled($coursemodule) == COMPLETION_TRACKING_AUTOMATIC) { | |
287 | $fullurl = "$CFG->wwwroot/mod/resource/view.php?id=$coursemodule->id&redirect=1"; | |
288 | } | |
9a9012dc | 289 | $info->extra = "onclick=\"window.open('$fullurl'); return false;\""; |
6da4b261 | 290 | } |
89bfeee0 | 291 | |
aa54ed7b | 292 | return $info; |
6da4b261 | 293 | } |
f3221af9 | 294 | |
f3221af9 | 295 | |
28f672b2 | 296 | /** |
aa54ed7b | 297 | * Lists all browsable file areas |
298 | * @param object $course | |
299 | * @param object $cm | |
300 | * @param object $context | |
28f672b2 | 301 | * @return array |
302 | */ | |
aa54ed7b | 303 | function resource_get_file_areas($course, $cm, $context) { |
304 | $areas = array(); | |
305 | if (has_capability('moodle/course:managefiles', $context)) { | |
306 | $areas['resource_content'] = get_string('resourcecontent', 'resource'); | |
307 | } | |
308 | return $areas; | |
f3221af9 | 309 | } |
310 | ||
28f672b2 | 311 | /** |
f1b8bcf7 | 312 | * File browsing support for resource module content area. |
aa54ed7b | 313 | * @param object $browser |
314 | * @param object $areas | |
28f672b2 | 315 | * @param object $course |
aa54ed7b | 316 | * @param object $cm |
317 | * @param object $context | |
318 | * @param string $filearea | |
319 | * @param int $itemid | |
320 | * @param string $filepath | |
321 | * @param string $filename | |
322 | * @return object file_info instance or null if not found | |
28f672b2 | 323 | */ |
aa54ed7b | 324 | function resource_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) { |
325 | global $CFG; | |
a69be0d8 | 326 | |
aa54ed7b | 327 | $canwrite = has_capability('moodle/course:managefiles', $context); |
a69be0d8 | 328 | |
aa54ed7b | 329 | $fs = get_file_storage(); |
a69be0d8 | 330 | |
aa54ed7b | 331 | if ($filearea === 'resource_content') { |
332 | $filepath = is_null($filepath) ? '/' : $filepath; | |
333 | $filename = is_null($filename) ? '.' : $filename; | |
a69be0d8 | 334 | |
aa54ed7b | 335 | $urlbase = $CFG->wwwroot.'/pluginfile.php'; |
336 | if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) { | |
337 | if ($filepath === '/' and $filename === '.') { | |
338 | $storedfile = new virtual_root_file($context->id, $filearea, 0); | |
a69be0d8 | 339 | } else { |
aa54ed7b | 340 | // not found |
341 | return null; | |
a69be0d8 | 342 | } |
343 | } | |
aa54ed7b | 344 | require_once("$CFG->dirroot/mod/resource/locallib.php"); |
345 | return new resource_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, $canwrite, false); | |
a69be0d8 | 346 | } |
347 | ||
aa54ed7b | 348 | // note: resource_intro handled in file_browser automatically |
a69be0d8 | 349 | |
aa54ed7b | 350 | return null; |
a69be0d8 | 351 | } |
352 | ||
0b5a80a1 | 353 | /** |
aa54ed7b | 354 | * Serves the resource files. |
355 | * @param object $course | |
356 | * @param object $cminfo | |
357 | * @param object $context | |
358 | * @param string $filearea | |
359 | * @param array $args | |
360 | * @param bool $forcedownload | |
361 | * @return bool false if file not found, does not return if found - justsend the file | |
28f672b2 | 362 | */ |
aa54ed7b | 363 | function resource_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { |
364 | global $CFG, $DB; | |
365 | require_once("$CFG->libdir/resourcelib.php"); | |
0d06b6fd | 366 | |
aa54ed7b | 367 | if (!$cminfo->uservisible) { |
368 | return false; | |
3efe78df | 369 | } |
370 | ||
aa54ed7b | 371 | if ($filearea !== 'resource_content') { |
372 | // intro is handled automatically in pluginfile.php | |
373 | return false; | |
3efe78df | 374 | } |
375 | ||
aa54ed7b | 376 | if (!$cm = get_coursemodule_from_instance('resource', $cminfo->instance, $course->id)) { |
377 | return false; | |
3efe78df | 378 | } |
379 | ||
aa54ed7b | 380 | require_course_login($course, true, $cm); |
3efe78df | 381 | |
aa54ed7b | 382 | array_shift($args); // ignore revision - designed to prevent caching problems only |
3efe78df | 383 | |
aa54ed7b | 384 | $fs = get_file_storage(); |
385 | $relativepath = '/'.implode('/', $args); | |
386 | $fullpath = $context->id.$filearea.'0'.$relativepath; | |
387 | if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { | |
388 | $resource = $DB->get_record('resource', array('id'=>$cminfo->instance), 'id, legacyfiles', MUST_EXIST); | |
389 | if ($resource->legacyfiles != RESOURCELIB_LEGACYFILES_ACTIVE) { | |
3efe78df | 390 | return false; |
391 | } | |
9b56a34f | 392 | if (!$file = resourcelib_try_file_migration($relativepath, $cminfo->id, $cminfo->course, 'resource_content', 0)) { |
aa54ed7b | 393 | return false; |
0d06b6fd | 394 | } |
aa54ed7b | 395 | // file migrate - update flag |
396 | $resource->legacyfileslast = time(); | |
397 | $DB->update_record('resource', $resource); | |
ffcfd8a7 | 398 | } |
399 | ||
aa54ed7b | 400 | // should we apply filters? |
401 | $mimetype = $file->get_mimetype(); | |
402 | if ($mimetype = 'text/html' or $mimetype = 'text/plain') { | |
403 | $filter = $DB->get_field('resource', 'filterfiles', array('id'=>$cminfo->instance)); | |
404 | } else { | |
405 | $filter = 0; | |
18a2a0cb | 406 | } |
18a2a0cb | 407 | |
aa54ed7b | 408 | // finally send the file |
409 | send_stored_file($file, 86400, $filter, $forcedownload); | |
13ca1e06 | 410 | } |