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