[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/folder/ -> lib.php (source)

   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  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1