[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 * Mandatory public API of folder module 20 * 21 * @package mod_folder 22 * @copyright 2009 Petr Skoda {@link http://skodak.org} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 /** Display folder contents on a separate page */ 29 define('FOLDER_DISPLAY_PAGE', 0); 30 /** Display folder contents inline in a course */ 31 define('FOLDER_DISPLAY_INLINE', 1); 32 33 /** 34 * List of features supported in Folder module 35 * @param string $feature FEATURE_xx constant for requested feature 36 * @return mixed True if module supports feature, false if not, null if doesn't know 37 */ 38 function folder_supports($feature) { 39 switch($feature) { 40 case FEATURE_MOD_ARCHETYPE: return MOD_ARCHETYPE_RESOURCE; 41 case FEATURE_GROUPS: return false; 42 case FEATURE_GROUPINGS: return false; 43 case FEATURE_MOD_INTRO: return true; 44 case FEATURE_COMPLETION_TRACKS_VIEWS: return true; 45 case FEATURE_GRADE_HAS_GRADE: return false; 46 case FEATURE_GRADE_OUTCOMES: return false; 47 case FEATURE_BACKUP_MOODLE2: return true; 48 case FEATURE_SHOW_DESCRIPTION: return true; 49 50 default: return null; 51 } 52 } 53 54 /** 55 * Returns all other caps used in module 56 * @return array 57 */ 58 function folder_get_extra_capabilities() { 59 return array('moodle/site:accessallgroups'); 60 } 61 62 /** 63 * This function is used by the reset_course_userdata function in moodlelib. 64 * @param $data the data submitted from the reset course. 65 * @return array status array 66 */ 67 function folder_reset_userdata($data) { 68 return array(); 69 } 70 71 /** 72 * List the actions that correspond to a view of this module. 73 * This is used by the participation report. 74 * 75 * Note: This is not used by new logging system. Event with 76 * crud = 'r' and edulevel = LEVEL_PARTICIPATING will 77 * be considered as view action. 78 * 79 * @return array 80 */ 81 function folder_get_view_actions() { 82 return array('view', 'view all'); 83 } 84 85 /** 86 * List the actions that correspond to a post of this module. 87 * This is used by the participation report. 88 * 89 * Note: This is not used by new logging system. Event with 90 * crud = ('c' || 'u' || 'd') and edulevel = LEVEL_PARTICIPATING 91 * will be considered as post action. 92 * 93 * @return array 94 */ 95 function folder_get_post_actions() { 96 return array('update', 'add'); 97 } 98 99 /** 100 * Add folder instance. 101 * @param object $data 102 * @param object $mform 103 * @return int new folder instance id 104 */ 105 function folder_add_instance($data, $mform) { 106 global $DB; 107 108 $cmid = $data->coursemodule; 109 $draftitemid = $data->files; 110 111 $data->timemodified = time(); 112 $data->id = $DB->insert_record('folder', $data); 113 114 // we need to use context now, so we need to make sure all needed info is already in db 115 $DB->set_field('course_modules', 'instance', $data->id, array('id'=>$cmid)); 116 $context = context_module::instance($cmid); 117 118 if ($draftitemid) { 119 file_save_draft_area_files($draftitemid, $context->id, 'mod_folder', 'content', 0, array('subdirs'=>true)); 120 } 121 122 return $data->id; 123 } 124 125 /** 126 * Update folder instance. 127 * @param object $data 128 * @param object $mform 129 * @return bool true 130 */ 131 function folder_update_instance($data, $mform) { 132 global $CFG, $DB; 133 134 $cmid = $data->coursemodule; 135 $draftitemid = $data->files; 136 137 $data->timemodified = time(); 138 $data->id = $data->instance; 139 $data->revision++; 140 141 $DB->update_record('folder', $data); 142 143 $context = context_module::instance($cmid); 144 if ($draftitemid = file_get_submitted_draft_itemid('files')) { 145 file_save_draft_area_files($draftitemid, $context->id, 'mod_folder', 'content', 0, array('subdirs'=>true)); 146 } 147 148 return true; 149 } 150 151 /** 152 * Delete folder instance. 153 * @param int $id 154 * @return bool true 155 */ 156 function folder_delete_instance($id) { 157 global $DB; 158 159 if (!$folder = $DB->get_record('folder', array('id'=>$id))) { 160 return false; 161 } 162 163 // note: all context files are deleted automatically 164 165 $DB->delete_records('folder', array('id'=>$folder->id)); 166 167 return true; 168 } 169 170 /** 171 * Lists all browsable file areas 172 * 173 * @package mod_folder 174 * @category files 175 * @param stdClass $course course object 176 * @param stdClass $cm course module object 177 * @param stdClass $context context object 178 * @return array 179 */ 180 function folder_get_file_areas($course, $cm, $context) { 181 $areas = array(); 182 $areas['content'] = get_string('foldercontent', 'folder'); 183 184 return $areas; 185 } 186 187 /** 188 * File browsing support for folder module content area. 189 * 190 * @package mod_folder 191 * @category files 192 * @param file_browser $browser file browser instance 193 * @param array $areas file areas 194 * @param stdClass $course course object 195 * @param stdClass $cm course module object 196 * @param stdClass $context context object 197 * @param string $filearea file area 198 * @param int $itemid item ID 199 * @param string $filepath file path 200 * @param string $filename file name 201 * @return file_info instance or null if not found 202 */ 203 function folder_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) { 204 global $CFG; 205 206 207 if ($filearea === 'content') { 208 if (!has_capability('mod/folder:view', $context)) { 209 return NULL; 210 } 211 $fs = get_file_storage(); 212 213 $filepath = is_null($filepath) ? '/' : $filepath; 214 $filename = is_null($filename) ? '.' : $filename; 215 if (!$storedfile = $fs->get_file($context->id, 'mod_folder', 'content', 0, $filepath, $filename)) { 216 if ($filepath === '/' and $filename === '.') { 217 $storedfile = new virtual_root_file($context->id, 'mod_folder', 'content', 0); 218 } else { 219 // not found 220 return null; 221 } 222 } 223 224 require_once("$CFG->dirroot/mod/folder/locallib.php"); 225 $urlbase = $CFG->wwwroot.'/pluginfile.php'; 226 227 // students may read files here 228 $canwrite = has_capability('mod/folder:managefiles', $context); 229 return new folder_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, $canwrite, false); 230 } 231 232 // note: folder_intro handled in file_browser automatically 233 234 return null; 235 } 236 237 /** 238 * Serves the folder files. 239 * 240 * @package mod_folder 241 * @category files 242 * @param stdClass $course course object 243 * @param stdClass $cm course module 244 * @param stdClass $context context object 245 * @param string $filearea file area 246 * @param array $args extra arguments 247 * @param bool $forcedownload whether or not force download 248 * @param array $options additional options affecting the file serving 249 * @return bool false if file not found, does not return if found - just send the file 250 */ 251 function folder_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) { 252 global $CFG, $DB; 253 254 if ($context->contextlevel != CONTEXT_MODULE) { 255 return false; 256 } 257 258 require_course_login($course, true, $cm); 259 if (!has_capability('mod/folder:view', $context)) { 260 return false; 261 } 262 263 if ($filearea !== 'content') { 264 // intro is handled automatically in pluginfile.php 265 return false; 266 } 267 268 array_shift($args); // ignore revision - designed to prevent caching problems only 269 270 $fs = get_file_storage(); 271 $relativepath = implode('/', $args); 272 $fullpath = "/$context->id/mod_folder/content/0/$relativepath"; 273 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { 274 return false; 275 } 276 277 // finally send the file 278 // for folder module, we force download file all the time 279 send_stored_file($file, 0, 0, true, $options); 280 } 281 282 /** 283 * Return a list of page types 284 * @param string $pagetype current page type 285 * @param stdClass $parentcontext Block's parent context 286 * @param stdClass $currentcontext Current context of block 287 */ 288 function folder_page_type_list($pagetype, $parentcontext, $currentcontext) { 289 $module_pagetype = array('mod-folder-*'=>get_string('page-mod-folder-x', 'folder')); 290 return $module_pagetype; 291 } 292 293 /** 294 * Export folder resource contents 295 * 296 * @return array of file content 297 */ 298 function folder_export_contents($cm, $baseurl) { 299 global $CFG, $DB; 300 $contents = array(); 301 $context = context_module::instance($cm->id); 302 $folder = $DB->get_record('folder', array('id'=>$cm->instance), '*', MUST_EXIST); 303 304 $fs = get_file_storage(); 305 $files = $fs->get_area_files($context->id, 'mod_folder', 'content', 0, 'sortorder DESC, id ASC', false); 306 307 foreach ($files as $fileinfo) { 308 $file = array(); 309 $file['type'] = 'file'; 310 $file['filename'] = $fileinfo->get_filename(); 311 $file['filepath'] = $fileinfo->get_filepath(); 312 $file['filesize'] = $fileinfo->get_filesize(); 313 $file['fileurl'] = file_encode_url("$CFG->wwwroot/" . $baseurl, '/'.$context->id.'/mod_folder/content/'.$folder->revision.$fileinfo->get_filepath().$fileinfo->get_filename(), true); 314 $file['timecreated'] = $fileinfo->get_timecreated(); 315 $file['timemodified'] = $fileinfo->get_timemodified(); 316 $file['sortorder'] = $fileinfo->get_sortorder(); 317 $file['userid'] = $fileinfo->get_userid(); 318 $file['author'] = $fileinfo->get_author(); 319 $file['license'] = $fileinfo->get_license(); 320 $contents[] = $file; 321 } 322 323 return $contents; 324 } 325 326 /** 327 * Register the ability to handle drag and drop file uploads 328 * @return array containing details of the files / types the mod can handle 329 */ 330 function folder_dndupload_register() { 331 return array('files' => array( 332 array('extension' => 'zip', 'message' => get_string('dnduploadmakefolder', 'mod_folder')) 333 )); 334 } 335 336 /** 337 * Handle a file that has been uploaded 338 * @param object $uploadinfo details of the file / content that has been uploaded 339 * @return int instance id of the newly created mod 340 */ 341 function folder_dndupload_handle($uploadinfo) { 342 global $DB, $USER; 343 344 // Gather the required info. 345 $data = new stdClass(); 346 $data->course = $uploadinfo->course->id; 347 $data->name = $uploadinfo->displayname; 348 $data->intro = '<p>'.$uploadinfo->displayname.'</p>'; 349 $data->introformat = FORMAT_HTML; 350 $data->coursemodule = $uploadinfo->coursemodule; 351 $data->files = null; // We will unzip the file and sort out the contents below. 352 353 $data->id = folder_add_instance($data, null); 354 355 // Retrieve the file from the draft file area. 356 $context = context_module::instance($uploadinfo->coursemodule); 357 file_save_draft_area_files($uploadinfo->draftitemid, $context->id, 'mod_folder', 'temp', 0, array('subdirs'=>true)); 358 $fs = get_file_storage(); 359 $files = $fs->get_area_files($context->id, 'mod_folder', 'temp', 0, 'sortorder', false); 360 // Only ever one file - extract the contents. 361 $file = reset($files); 362 363 $success = $file->extract_to_storage(new zip_packer(), $context->id, 'mod_folder', 'content', 0, '/', $USER->id); 364 $fs->delete_area_files($context->id, 'mod_folder', 'temp', 0); 365 366 if ($success) { 367 return $data->id; 368 } 369 370 $DB->delete_records('folder', array('id' => $data->id)); 371 return false; 372 } 373 374 /** 375 * Given a coursemodule object, this function returns the extra 376 * information needed to print this activity in various places. 377 * 378 * If folder needs to be displayed inline we store additional information 379 * in customdata, so functions {@link folder_cm_info_dynamic()} and 380 * {@link folder_cm_info_view()} do not need to do DB queries 381 * 382 * @param cm_info $cm 383 * @return cached_cm_info info 384 */ 385 function folder_get_coursemodule_info($cm) { 386 global $DB; 387 if (!($folder = $DB->get_record('folder', array('id' => $cm->instance), 388 'id, name, display, showexpanded, intro, introformat'))) { 389 return NULL; 390 } 391 $cminfo = new cached_cm_info(); 392 $cminfo->name = $folder->name; 393 if ($folder->display == FOLDER_DISPLAY_INLINE) { 394 // prepare folder object to store in customdata 395 $fdata = new stdClass(); 396 $fdata->showexpanded = $folder->showexpanded; 397 if ($cm->showdescription && strlen(trim($folder->intro))) { 398 $fdata->intro = $folder->intro; 399 if ($folder->introformat != FORMAT_MOODLE) { 400 $fdata->introformat = $folder->introformat; 401 } 402 } 403 $cminfo->customdata = $fdata; 404 } else { 405 if ($cm->showdescription) { 406 // Convert intro to html. Do not filter cached version, filters run at display time. 407 $cminfo->content = format_module_intro('folder', $folder, $cm->id, false); 408 } 409 } 410 return $cminfo; 411 } 412 413 /** 414 * Sets dynamic information about a course module 415 * 416 * This function is called from cm_info when displaying the module 417 * mod_folder can be displayed inline on course page and therefore have no course link 418 * 419 * @param cm_info $cm 420 */ 421 function folder_cm_info_dynamic(cm_info $cm) { 422 if ($cm->customdata) { 423 // the field 'customdata' is not empty IF AND ONLY IF we display contens inline 424 $cm->set_no_view_link(); 425 } 426 } 427 428 /** 429 * Overwrites the content in the course-module object with the folder files list 430 * if folder.display == FOLDER_DISPLAY_INLINE 431 * 432 * @param cm_info $cm 433 */ 434 function folder_cm_info_view(cm_info $cm) { 435 global $PAGE; 436 if ($cm->uservisible && $cm->customdata && 437 has_capability('mod/folder:view', $cm->context)) { 438 // Restore folder object from customdata. 439 // Note the field 'customdata' is not empty IF AND ONLY IF we display contens inline. 440 // Otherwise the content is default. 441 $folder = $cm->customdata; 442 $folder->id = (int)$cm->instance; 443 $folder->course = (int)$cm->course; 444 $folder->display = FOLDER_DISPLAY_INLINE; 445 $folder->name = $cm->name; 446 if (empty($folder->intro)) { 447 $folder->intro = ''; 448 } 449 if (empty($folder->introformat)) { 450 $folder->introformat = FORMAT_MOODLE; 451 } 452 // display folder 453 $renderer = $PAGE->get_renderer('mod_folder'); 454 $cm->set_content($renderer->display_folder($folder)); 455 } 456 } 457 458 /** 459 * Mark the activity completed (if required) and trigger the course_module_viewed event. 460 * 461 * @param stdClass $folder folder object 462 * @param stdClass $course course object 463 * @param stdClass $cm course module object 464 * @param stdClass $context context object 465 * @since Moodle 3.0 466 */ 467 function folder_view($folder, $course, $cm, $context) { 468 469 // Trigger course_module_viewed event. 470 $params = array( 471 'context' => $context, 472 'objectid' => $folder->id 473 ); 474 475 $event = \mod_folder\event\course_module_viewed::create($params); 476 $event->add_record_snapshot('course_modules', $cm); 477 $event->add_record_snapshot('course', $course); 478 $event->add_record_snapshot('folder', $folder); 479 $event->trigger(); 480 481 // Completion. 482 $completion = new completion_info($course); 483 $completion->set_module_viewed($cm); 484 } 485 486 /** 487 * Check if the folder can be zipped and downloaded. 488 * @param stdClass $folder 489 * @param context_module $cm 490 * @return bool True if the folder can be zipped and downloaded. 491 * @throws \dml_exception 492 */ 493 function folder_archive_available($folder, $cm) { 494 if (!$folder->showdownloadfolder) { 495 return false; 496 } 497 498 $context = context_module::instance($cm->id); 499 $fs = get_file_storage(); 500 $dir = $fs->get_area_tree($context->id, 'mod_folder', 'content', 0); 501 502 $size = folder_get_directory_size($dir); 503 $maxsize = get_config('folder', 'maxsizetodownload') * 1024 * 1024; 504 505 if ($size == 0) { 506 return false; 507 } 508 509 if (!empty($maxsize) && $size > $maxsize) { 510 return false; 511 } 512 513 return true; 514 } 515 516 /** 517 * Recursively measure the size of the files in a directory. 518 * @param array $directory 519 * @return int size of directory contents in bytes 520 */ 521 function folder_get_directory_size($directory) { 522 $size = 0; 523 524 foreach ($directory['files'] as $file) { 525 $size += $file->get_filesize(); 526 } 527 528 foreach ($directory['subdirs'] as $subdirectory) { 529 $size += folder_get_directory_size($subdirectory); 530 } 531 532 return $size; 533 } 534 535 /** 536 * Mark the activity completed (if required) and trigger the all_files_downloaded event. 537 * 538 * @param stdClass $folder folder object 539 * @param stdClass $course course object 540 * @param stdClass $cm course module object 541 * @param stdClass $context context object 542 * @since Moodle 3.1 543 */ 544 function folder_downloaded($folder, $course, $cm, $context) { 545 $params = array( 546 'context' => $context, 547 'objectid' => $folder->id 548 ); 549 $event = \mod_folder\event\all_files_downloaded::create($params); 550 $event->add_record_snapshot('course_modules', $cm); 551 $event->add_record_snapshot('course', $course); 552 $event->add_record_snapshot('folder', $folder); 553 $event->trigger(); 554 555 // Completion. 556 $completion = new completion_info($course); 557 $completion->set_module_viewed($cm); 558 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |