3 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
19 * Mandatory public API of folder module
23 * @copyright 2009 Petr Skoda {@link http://skodak.org}
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') ||
die();
30 * List of features supported in Folder module
31 * @param string $feature FEATURE_xx constant for requested feature
32 * @return mixed True if module supports feature, false if not, null if doesn't know
34 function folder_supports($feature) {
36 case FEATURE_MOD_ARCHETYPE
: return MOD_ARCHETYPE_RESOURCE
;
37 case FEATURE_GROUPS
: return false;
38 case FEATURE_GROUPINGS
: return false;
39 case FEATURE_GROUPMEMBERSONLY
: return true;
40 case FEATURE_MOD_INTRO
: return true;
41 case FEATURE_COMPLETION_TRACKS_VIEWS
: return true;
42 case FEATURE_GRADE_HAS_GRADE
: return false;
43 case FEATURE_GRADE_OUTCOMES
: return false;
44 case FEATURE_BACKUP_MOODLE2
: return true;
45 case FEATURE_SHOW_DESCRIPTION
: return true;
52 * Returns all other caps used in module
55 function folder_get_extra_capabilities() {
56 return array('moodle/site:accessallgroups');
60 * This function is used by the reset_course_userdata function in moodlelib.
61 * @param $data the data submitted from the reset course.
62 * @return array status array
64 function folder_reset_userdata($data) {
69 * List of view style log actions
72 function folder_get_view_actions() {
73 return array('view', 'view all');
77 * List of update style log actions
80 function folder_get_post_actions() {
81 return array('update', 'add');
85 * Add folder instance.
87 * @param object $mform
88 * @return int new folder instance id
90 function folder_add_instance($data, $mform) {
93 $cmid = $data->coursemodule
;
94 $draftitemid = $data->files
;
96 $data->timemodified
= time();
97 $data->id
= $DB->insert_record('folder', $data);
99 // we need to use context now, so we need to make sure all needed info is already in db
100 $DB->set_field('course_modules', 'instance', $data->id
, array('id'=>$cmid));
101 $context = get_context_instance(CONTEXT_MODULE
, $cmid);
104 file_save_draft_area_files($draftitemid, $context->id
, 'mod_folder', 'content', 0, array('subdirs'=>true));
111 * Update folder instance.
112 * @param object $data
113 * @param object $mform
116 function folder_update_instance($data, $mform) {
119 $cmid = $data->coursemodule
;
120 $draftitemid = $data->files
;
122 $data->timemodified
= time();
123 $data->id
= $data->instance
;
126 $DB->update_record('folder', $data);
128 $context = get_context_instance(CONTEXT_MODULE
, $cmid);
129 if ($draftitemid = file_get_submitted_draft_itemid('files')) {
130 file_save_draft_area_files($draftitemid, $context->id
, 'mod_folder', 'content', 0, array('subdirs'=>true));
137 * Delete folder instance.
141 function folder_delete_instance($id) {
144 if (!$folder = $DB->get_record('folder', array('id'=>$id))) {
148 // note: all context files are deleted automatically
150 $DB->delete_records('folder', array('id'=>$folder->id
));
157 * @param object $course
158 * @param object $user
160 * @param object $folder
161 * @return object|null
163 function folder_user_outline($course, $user, $mod, $folder) {
166 if ($logs = $DB->get_records('log', array('userid'=>$user->id
, 'module'=>'folder',
167 'action'=>'view', 'info'=>$folder->id
), 'time ASC')) {
169 $numviews = count($logs);
170 $lastlog = array_pop($logs);
172 $result = new stdClass();
173 $result->info
= get_string('numviews', '', $numviews);
174 $result->time
= $lastlog->time
;
182 * Return use complete
183 * @param object $course
184 * @param object $user
186 * @param object $folder
188 function folder_user_complete($course, $user, $mod, $folder) {
191 if ($logs = $DB->get_records('log', array('userid'=>$user->id
, 'module'=>'folder',
192 'action'=>'view', 'info'=>$folder->id
), 'time ASC')) {
193 $numviews = count($logs);
194 $lastlog = array_pop($logs);
196 $strmostrecently = get_string('mostrecently');
197 $strnumviews = get_string('numviews', '', $numviews);
199 echo "$strnumviews - $strmostrecently ".userdate($lastlog->time
);
202 print_string('neverseen', 'folder');
207 * Lists all browsable file areas
209 * @package mod_folder
211 * @param stdClass $course course object
212 * @param stdClass $cm course module object
213 * @param stdClass $context context object
216 function folder_get_file_areas($course, $cm, $context) {
218 $areas['content'] = get_string('foldercontent', 'folder');
224 * File browsing support for folder module content area.
226 * @package mod_folder
228 * @param file_browser $browser file browser instance
229 * @param array $areas file areas
230 * @param stdClass $course course object
231 * @param stdClass $cm course module object
232 * @param stdClass $context context object
233 * @param string $filearea file area
234 * @param int $itemid item ID
235 * @param string $filepath file path
236 * @param string $filename file name
237 * @return file_info instance or null if not found
239 function folder_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
243 if ($filearea === 'content') {
244 if (!has_capability('mod/folder:view', $context)) {
247 $fs = get_file_storage();
249 $filepath = is_null($filepath) ?
'/' : $filepath;
250 $filename = is_null($filename) ?
'.' : $filename;
251 if (!$storedfile = $fs->get_file($context->id
, 'mod_folder', 'content', 0, $filepath, $filename)) {
252 if ($filepath === '/' and $filename === '.') {
253 $storedfile = new virtual_root_file($context->id
, 'mod_folder', 'content', 0);
260 require_once("$CFG->dirroot/mod/folder/locallib.php");
261 $urlbase = $CFG->wwwroot
.'/pluginfile.php';
263 // students may read files here
264 $canwrite = has_capability('mod/folder:managefiles', $context);
265 return new folder_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, $canwrite, false);
268 // note: folder_intro handled in file_browser automatically
274 * Serves the folder files.
276 * @package mod_folder
278 * @param stdClass $course course object
279 * @param stdClass $cm course module
280 * @param stdClass $context context object
281 * @param string $filearea file area
282 * @param array $args extra arguments
283 * @param bool $forcedownload whether or not force download
284 * @param array $options additional options affecting the file serving
285 * @return bool false if file not found, does not return if found - just send the file
287 function folder_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) {
290 if ($context->contextlevel
!= CONTEXT_MODULE
) {
294 require_course_login($course, true, $cm);
295 if (!has_capability('mod/folder:view', $context)) {
299 if ($filearea !== 'content') {
300 // intro is handled automatically in pluginfile.php
304 array_shift($args); // ignore revision - designed to prevent caching problems only
306 $fs = get_file_storage();
307 $relativepath = implode('/', $args);
308 $fullpath = "/$context->id/mod_folder/content/0/$relativepath";
309 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
313 // finally send the file
314 // for folder module, we force download file all the time
315 send_stored_file($file, 86400, 0, true, $options);
319 * Return a list of page types
320 * @param string $pagetype current page type
321 * @param stdClass $parentcontext Block's parent context
322 * @param stdClass $currentcontext Current context of block
324 function folder_page_type_list($pagetype, $parentcontext, $currentcontext) {
325 $module_pagetype = array('mod-folder-*'=>get_string('page-mod-folder-x', 'folder'));
326 return $module_pagetype;
330 * Export folder resource contents
332 * @return array of file content
334 function folder_export_contents($cm, $baseurl) {
337 $context = get_context_instance(CONTEXT_MODULE
, $cm->id
);
338 $folder = $DB->get_record('folder', array('id'=>$cm->instance
), '*', MUST_EXIST
);
340 $fs = get_file_storage();
341 $files = $fs->get_area_files($context->id
, 'mod_folder', 'content', 0, 'sortorder DESC, id ASC', false);
343 foreach ($files as $fileinfo) {
345 $file['type'] = 'file';
346 $file['filename'] = $fileinfo->get_filename();
347 $file['filepath'] = $fileinfo->get_filepath();
348 $file['filesize'] = $fileinfo->get_filesize();
349 $file['fileurl'] = file_encode_url("$CFG->wwwroot/" . $baseurl, '/'.$context->id
.'/mod_folder/content/'.$folder->revision
.$fileinfo->get_filepath().$fileinfo->get_filename(), true);
350 $file['timecreated'] = $fileinfo->get_timecreated();
351 $file['timemodified'] = $fileinfo->get_timemodified();
352 $file['sortorder'] = $fileinfo->get_sortorder();
353 $file['userid'] = $fileinfo->get_userid();
354 $file['author'] = $fileinfo->get_author();
355 $file['license'] = $fileinfo->get_license();
363 * Register the ability to handle drag and drop file uploads
364 * @return array containing details of the files / types the mod can handle
366 function mod_folder_dndupload_register() {
367 return array('files' => array(
368 array('extension' => 'zip', 'message' => get_string('dnduploadmakefolder', 'mod_folder'))
373 * Handle a file that has been uploaded
374 * @param object $uploadinfo details of the file / content that has been uploaded
375 * @return int instance id of the newly created mod
377 function mod_folder_dndupload_handle($uploadinfo) {
380 // Gather the required info.
381 $data = new stdClass();
382 $data->course
= $uploadinfo->course
->id
;
383 $data->name
= $uploadinfo->displayname
;
384 $data->intro
= '<p>'.$uploadinfo->displayname
.'</p>';
385 $data->introformat
= FORMAT_HTML
;
386 $data->coursemodule
= $uploadinfo->coursemodule
;
387 $data->files
= null; // We will unzip the file and sort out the contents below.
389 $data->id
= folder_add_instance($data, null);
391 // Retrieve the file from the draft file area.
392 $context = context_module
::instance($uploadinfo->coursemodule
);
393 file_save_draft_area_files($uploadinfo->draftitemid
, $context->id
, 'mod_folder', 'temp', 0, array('subdirs'=>true));
394 $fs = get_file_storage();
395 $files = $fs->get_area_files($context->id
, 'mod_folder', 'temp', 0, 'sortorder', false);
396 // Only ever one file - extract the contents.
397 $file = reset($files);
399 $success = $file->extract_to_storage(new zip_packer(), $context->id
, 'mod_folder', 'content', 0, '/', $USER->id
);
400 $fs->delete_area_files($context->id
, 'mod_folder', 'temp', 0);
406 $DB->delete_records('folder', array('id' => $data->id
));