Search moodle.org's
Developer Documentation


  • Bug fixes for general core bugs in 2.8.x ended 9 November 2015 (12 months).
  • Bug fixes for security issues in 2.8.x ended 9 May 2016 (18 months).
  • minimum PHP 5.4.4 (always use latest PHP 5.4.x or 5.5.x on Windows - http://windows.php.net/download/), PHP 7 is NOT supported
  • Differences Between: [Versions 28 and 31] [Versions 28 and 32] [Versions 28 and 33] [Versions 28 and 34] [Versions 28 and 35] [Versions 28 and 36] [Versions 28 and 37]

       1  <?php
       2  // This file is part of Moodle - http://moodle.org/
       3  //
       4  // Moodle is free software: you can redistribute it and/or modify
       5  // it under the terms of the GNU General Public License as published by
       6  // the Free Software Foundation, either version 3 of the License, or
       7  // (at your option) any later version.
       8  //
       9  // Moodle is distributed in the hope that it will be useful,
      10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12  // GNU General Public License for more details.
      13  //
      14  // You should have received a copy of the GNU General Public License
      15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
      16  
      17  
      18  /**
      19   * The Web service script that is called from the filepicker front end
      20   *
      21   * @since Moodle 2.0
      22   * @package    repository
      23   * @copyright  2009 Dongsheng Cai {@link http://dongsheng.org}
      24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      25   */
      26  
      27  define('AJAX_SCRIPT', true);
      28  
      29  require_once(dirname(dirname(__FILE__)).'/config.php');
      30  require_once(dirname(dirname(__FILE__)).'/lib/filelib.php');
      31  require_once(dirname(__FILE__).'/lib.php');
      32  
      33  $err = new stdClass();
      34  
      35  // Parameters
      36  $action    = optional_param('action', '', PARAM_ALPHA);
      37  $repo_id   = optional_param('repo_id', 0, PARAM_INT);           // Repository ID
      38  $contextid = optional_param('ctx_id', SYSCONTEXTID, PARAM_INT); // Context ID
      39  $env       = optional_param('env', 'filepicker', PARAM_ALPHA);  // Opened in editor or moodleform
      40  $license   = optional_param('license', $CFG->sitedefaultlicense, PARAM_TEXT);
      41  $author    = optional_param('author', '', PARAM_TEXT);          // File author
      42  $source    = optional_param('source', '', PARAM_RAW);           // File to download
      43  $itemid    = optional_param('itemid', 0, PARAM_INT);            // Itemid
      44  $page      = optional_param('page', '', PARAM_RAW);             // Page
      45  $maxbytes  = optional_param('maxbytes', 0, PARAM_INT);          // Maxbytes
      46  $req_path  = optional_param('p', '', PARAM_RAW);                // Path
      47  $accepted_types  = optional_param_array('accepted_types', '*', PARAM_RAW);
      48  $saveas_filename = optional_param('title', '', PARAM_FILE);     // save as file name
      49  $areamaxbytes  = optional_param('areamaxbytes', FILE_AREA_MAX_BYTES_UNLIMITED, PARAM_INT); // Area max bytes.
      50  $saveas_path   = optional_param('savepath', '/', PARAM_PATH);   // save as file path
      51  $search_text   = optional_param('s', '', PARAM_CLEANHTML);
      52  $linkexternal  = optional_param('linkexternal', '', PARAM_ALPHA);
      53  $usefilereference  = optional_param('usefilereference', false, PARAM_BOOL);
      54  
      55  list($context, $course, $cm) = get_context_info_array($contextid);
      56  require_login($course, false, $cm, false, true);
      57  $PAGE->set_context($context);
      58  
      59  echo $OUTPUT->header(); // send headers
      60  
      61  // If uploaded file is larger than post_max_size (php.ini) setting, $_POST content will be empty.
      62  if (empty($_POST) && !empty($action)) {
      63      $err->error = get_string('errorpostmaxsize', 'repository');
      64      die(json_encode($err));
      65  }
      66  
      67  if (!confirm_sesskey()) {
      68      $err->error = get_string('invalidsesskey', 'error');
      69      die(json_encode($err));
      70  }
      71  
      72  // Get repository instance information
      73  $repooptions = array(
      74      'ajax' => true,
      75      'mimetypes' => $accepted_types
      76  );
      77  
      78  ajax_capture_output();
      79  $repo = repository::get_repository_by_id($repo_id, $contextid, $repooptions);
      80  
      81  // Check permissions
      82  $repo->check_capability();
      83  
      84  $coursemaxbytes = 0;
      85  if (!empty($course)) {
      86      $coursemaxbytes = $course->maxbytes;
      87  }
      88  // Make sure maxbytes passed is within site filesize limits.
      89  $maxbytes = get_user_max_upload_file_size($context, $CFG->maxbytes, $coursemaxbytes, $maxbytes);
      90  
      91  // Wait as long as it takes for this script to finish
      92  core_php_time_limit::raise();
      93  
      94  // These actions all occur on the currently active repository instance
      95  switch ($action) {
      96      case 'sign':
      97      case 'signin':
      98      case 'list':
      99          if ($repo->check_login()) {
     100              $listing = repository::prepare_listing($repo->get_listing($req_path, $page));
     101              $listing['repo_id'] = $repo_id;
     102              ajax_check_captured_output();
     103              echo json_encode($listing);
     104              break;
     105          } else {
     106              $action = 'login';
     107          }
     108      case 'login':
     109          $listing = $repo->print_login();
     110          $listing['repo_id'] = $repo_id;
     111          ajax_check_captured_output();
     112          echo json_encode($listing);
     113          break;
     114      case 'logout':
     115          $logout = $repo->logout();
     116          $logout['repo_id'] = $repo_id;
     117          ajax_check_captured_output();
     118          echo json_encode($logout);
     119          break;
     120      case 'searchform':
     121          $search_form['repo_id'] = $repo_id;
     122          $search_form['form'] = $repo->print_search();
     123          $search_form['allowcaching'] = true;
     124          ajax_check_captured_output();
     125          echo json_encode($search_form);
     126          break;
     127      case 'search':
     128          $search_result = repository::prepare_listing($repo->search($search_text, (int)$page));
     129          $search_result['repo_id'] = $repo_id;
     130          $search_result['issearchresult'] = true;
     131          ajax_check_captured_output();
     132          echo json_encode($search_result);
     133          break;
     134      case 'download':
     135          // validate mimetype
     136          $mimetypes = array();
     137          if ((is_array($accepted_types) and in_array('*', $accepted_types)) or $accepted_types == '*') {
     138              $mimetypes = '*';
     139          } else {
     140              foreach ($accepted_types as $type) {
     141                  $mimetypes[] = mimeinfo('type', $type);
     142              }
     143              if (!in_array(mimeinfo('type', $saveas_filename), $mimetypes)) {
     144                  throw new moodle_exception('invalidfiletype', 'repository', '', get_mimetype_description(array('filename' => $saveas_filename)));
     145              }
     146          }
     147  
     148          // We have two special repository type need to deal with
     149          // local and recent plugins don't added new files to moodle, just add new records to database
     150          // so we don't check user quota and maxbytes here
     151          $allowexternallink = (int)get_config(null, 'repositoryallowexternallinks');
     152          if (!empty($allowexternallink)) {
     153              $allowexternallink = true;
     154          } else {
     155              $allowexternallink = false;
     156          }
     157          // allow external links in url element all the time
     158          $allowexternallink = ($allowexternallink || ($env == 'url'));
     159  
     160          $reference = $repo->get_file_reference($source);
     161  
     162          // Use link of the files
     163          if ($allowexternallink and $linkexternal === 'yes' and ($repo->supported_returntypes() & FILE_EXTERNAL)) {
     164              // use external link
     165              $link = $repo->get_link($reference);
     166              $info = array();
     167              $info['file'] = $saveas_filename;
     168              $info['type'] = 'link';
     169              $info['url'] = $link;
     170              ajax_check_captured_output();
     171              echo json_encode($info);
     172              die;
     173          } else {
     174              $fs = get_file_storage();
     175  
     176              // Prepare file record.
     177              $record = new stdClass();
     178              $record->filepath = $saveas_path;
     179              $record->filename = $saveas_filename;
     180              $record->component = 'user';
     181              $record->filearea = 'draft';
     182              $record->itemid = $itemid;
     183              $record->license = $license;
     184              $record->author = $author;
     185  
     186              if ($record->filepath !== '/') {
     187                  $record->filepath = trim($record->filepath, '/');
     188                  $record->filepath = '/'.$record->filepath.'/';
     189              }
     190              $usercontext = context_user::instance($USER->id);
     191              $now = time();
     192              $record->contextid = $usercontext->id;
     193              $record->timecreated = $now;
     194              $record->timemodified = $now;
     195              $record->userid = $USER->id;
     196              $record->sortorder = 0;
     197  
     198              // Check that user has permission to access this file
     199              if (!$repo->file_is_accessible($source)) {
     200                  throw new file_exception('storedfilecannotread');
     201              }
     202  
     203              // {@link repository::build_source_field()}
     204              $sourcefield = $repo->get_file_source_info($source);
     205              $record->source = $repo::build_source_field($sourcefield);
     206  
     207              // If file is already a reference, set $source = file source, $repo = file repository
     208              // note that in this case user may not have permission to access the source file directly
     209              // so no file_browser/file_info can be used below
     210              if ($repo->has_moodle_files()) {
     211                  $file = repository::get_moodle_file($reference);
     212                  if ($file && $file->is_external_file()) {
     213                      $sourcefield = $file->get_source(); // remember the original source
     214                      $record->source = $repo::build_source_field($sourcefield);
     215                      $record->contenthash = $file->get_contenthash();
     216                      $record->filesize = $file->get_filesize();
     217                      $reference = $file->get_reference();
     218                      $repo_id = $file->get_repository_id();
     219                      $repo = repository::get_repository_by_id($repo_id, $contextid, $repooptions);
     220                  }
     221              }
     222  
     223              if ($usefilereference) {
     224                  if ($repo->has_moodle_files()) {
     225                      $sourcefile = repository::get_moodle_file($reference);
     226                      $record->contenthash = $sourcefile->get_contenthash();
     227                      $record->filesize = $sourcefile->get_filesize();
     228                  }
     229                  // Check if file exists.
     230                  if (repository::draftfile_exists($itemid, $saveas_path, $saveas_filename)) {
     231                      // File name being used, rename it.
     232                      $unused_filename = repository::get_unused_filename($itemid, $saveas_path, $saveas_filename);
     233                      $record->filename = $unused_filename;
     234                      // Create a file copy using unused filename.
     235                      $storedfile = $fs->create_file_from_reference($record, $repo_id, $reference);
     236  
     237                      $event = array();
     238                      $event['event'] = 'fileexists';
     239                      $event['newfile'] = new stdClass;
     240                      $event['newfile']->filepath = $saveas_path;
     241                      $event['newfile']->filename = $unused_filename;
     242                      $event['newfile']->url = moodle_url::make_draftfile_url($itemid, $saveas_path, $unused_filename)->out();
     243  
     244                      $event['existingfile'] = new stdClass;
     245                      $event['existingfile']->filepath = $saveas_path;
     246                      $event['existingfile']->filename = $saveas_filename;
     247                      $event['existingfile']->url      = moodle_url::make_draftfile_url($itemid, $saveas_path, $saveas_filename)->out();
     248                  } else {
     249  
     250                      $storedfile = $fs->create_file_from_reference($record, $repo_id, $reference);
     251                      $event = array(
     252                          'url'=>moodle_url::make_draftfile_url($storedfile->get_itemid(), $storedfile->get_filepath(), $storedfile->get_filename())->out(),
     253                          'id'=>$storedfile->get_itemid(),
     254                          'file'=>$storedfile->get_filename(),
     255                          'icon' => $OUTPUT->pix_url(file_file_icon($storedfile, 32))->out(),
     256                      );
     257                  }
     258                  // Repository plugin callback
     259                  // You can cache reository file in this callback
     260                  // or complete other tasks.
     261                  $repo->cache_file_by_reference($reference, $storedfile);
     262                  ajax_check_captured_output();
     263                  echo json_encode($event);
     264                  die;
     265              } else if ($repo->has_moodle_files()) {
     266                  // Some repository plugins (local, user, coursefiles, recent) are hosting moodle
     267                  // internal files, we cannot use get_file method, so we use copy_to_area method
     268  
     269                  // If the moodle file is an alias we copy this alias, otherwise we copy the file
     270                  // {@link repository::copy_to_area()}.
     271                  $fileinfo = $repo->copy_to_area($reference, $record, $maxbytes, $areamaxbytes);
     272  
     273                  ajax_check_captured_output();
     274                  echo json_encode($fileinfo);
     275                  die;
     276              } else {
     277                  // Download file to moodle.
     278                  $downloadedfile = $repo->get_file($reference, $saveas_filename);
     279                  if (empty($downloadedfile['path'])) {
     280                      $err->error = get_string('cannotdownload', 'repository');
     281                      die(json_encode($err));
     282                  }
     283  
     284                  // Check if exceed maxbytes.
     285                  if ($maxbytes != -1 && filesize($downloadedfile['path']) > $maxbytes) {
     286                      throw new file_exception('maxbytes');
     287                  }
     288  
     289                  // Check if we exceed the max bytes of the area.
     290                  if (file_is_draft_area_limit_reached($itemid, $areamaxbytes, filesize($downloadedfile['path']))) {
     291                      throw new file_exception('maxareabytes');
     292                  }
     293  
     294                  $info = repository::move_to_filepool($downloadedfile['path'], $record);
     295                  if (empty($info)) {
     296                      $info['e'] = get_string('error', 'moodle');
     297                  }
     298              }
     299              ajax_check_captured_output();
     300              echo json_encode($info);
     301              die;
     302          }
     303          break;
     304      case 'upload':
     305          $result = $repo->upload($saveas_filename, $maxbytes);
     306          ajax_check_captured_output();
     307          echo json_encode($result);
     308          break;
     309  
     310      case 'overwrite':
     311          // existing file
     312          $filepath    = required_param('existingfilepath', PARAM_PATH);
     313          $filename    = required_param('existingfilename', PARAM_FILE);
     314          // user added file which needs to replace the existing file
     315          $newfilepath = required_param('newfilepath', PARAM_PATH);
     316          $newfilename = required_param('newfilename', PARAM_FILE);
     317  
     318          $info = repository::overwrite_existing_draftfile($itemid, $filepath, $filename, $newfilepath, $newfilename);
     319          ajax_check_captured_output();
     320          echo json_encode($info);
     321          break;
     322  
     323      case 'deletetmpfile':
     324          // delete tmp file
     325          $newfilepath = required_param('newfilepath', PARAM_PATH);
     326          $newfilename = required_param('newfilename', PARAM_FILE);
     327          ajax_check_captured_output();
     328          echo json_encode(repository::delete_tempfile_from_draft($itemid, $newfilepath, $newfilename));
     329  
     330          break;
     331  }
    

    Search This Site: