Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.

Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402] [Versions 402 and 403]

   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   * This plugin is used to access recent used files
  20   *
  21   * @since Moodle 2.0
  22   * @package    repository_recent
  23   * @copyright  2010 Dongsheng Cai {@link http://dongsheng.org}
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  require_once($CFG->dirroot . '/repository/lib.php');
  27  
  28  /**
  29   * repository_recent class is used to browse recent used files
  30   *
  31   * @since Moodle 2.0
  32   * @package    repository_recent
  33   * @copyright  2010 Dongsheng Cai {@link http://dongsheng.org}
  34   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  define('DEFAULT_RECENT_FILES_NUM', 50);
  37  
  38  /**
  39   * DEFAULT_RECENT_FILES_TIME_LIMIT - default time limit.
  40   */
  41  define('DEFAULT_RECENT_FILES_TIME_LIMIT', 6 * 4 * WEEKSECS);
  42  class repository_recent extends repository {
  43  
  44      /** @var int only retrieve files within the time limit */
  45      protected $timelimit;
  46  
  47      /** @var int recent files number configuration. */
  48      protected $number;
  49  
  50      /**
  51       * Initialize recent plugin
  52       * @param int $repositoryid
  53       * @param int $context
  54       * @param array $options
  55       */
  56      public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
  57          parent::__construct($repositoryid, $context, $options);
  58          $number = get_config('recent', 'recentfilesnumber');
  59          $number = (int)$number;
  60          if (empty($number)) {
  61              $this->number = DEFAULT_RECENT_FILES_NUM;
  62          } else {
  63              $this->number = $number;
  64          }
  65          $timelimit = get_config('recent', 'recentfilestimelimit');
  66          $this->timelimit = (int)$timelimit;
  67      }
  68  
  69      /**
  70       * recent plugin doesn't require login, so list all files
  71       * @return mixed
  72       */
  73      public function print_login() {
  74          return $this->get_listing();
  75      }
  76  
  77      /**
  78       * Only return files within the time limit
  79       *
  80       * @param int $limitfrom retrieve the files from
  81       * @param int $limit limit number of the files
  82       * @param int $timelimit only return files with the time limit
  83       * @return array list of recent files
  84       */
  85      private function get_recent_files($limitfrom = 0, $limit = DEFAULT_RECENT_FILES_NUM, $timelimit = 0) {
  86          // XXX: get current itemid
  87          global $USER, $DB, $itemid;
  88          $timelimitsql = '';
  89          if ($timelimit > 0) {
  90              $timelimitsql = "AND timemodified >= :timelimit";
  91              $timelimitparam = ['timelimit' => time() - $timelimit];
  92          }
  93          // This SQL will ignore draft files if not owned by current user.
  94          // Ignore all file references.
  95          $sql = "SELECT files1.id, files1.contextid, files1.component, files1.filearea,
  96                         files1.itemid, files1.filepath, files1.filename, files1.pathnamehash
  97                    FROM {files} files1
  98                    JOIN (
  99                        SELECT contenthash, filename, MAX(id) AS id
 100                          FROM {files}
 101                         WHERE userid = :userid
 102                           AND referencefileid is NULL
 103                           AND filename != :filename
 104                           AND ((filearea = :filearea1 AND itemid = :itemid) OR filearea != :filearea2)
 105                           $timelimitsql
 106                      GROUP BY contenthash, filename
 107                    ) files2 ON files1.id = files2.id
 108                ORDER BY files1.timemodified DESC";
 109          $params = array(
 110              'userid' => $USER->id,
 111              'filename' => '.',
 112              'filearea1' => 'draft',
 113              'itemid' => $itemid,
 114              'filearea2' => 'draft');
 115          if (isset($timelimitparam)) {
 116              $params = array_merge($params, $timelimitparam);
 117          }
 118          $rs = $DB->get_recordset_sql($sql, $params, $limitfrom, $limit);
 119          $result = array();
 120          foreach ($rs as $file_record) {
 121              $info = array();
 122              $info['contextid'] = $file_record->contextid;
 123              $info['itemid'] = $file_record->itemid;
 124              $info['filearea'] = $file_record->filearea;
 125              $info['component'] = $file_record->component;
 126              $info['filepath'] = $file_record->filepath;
 127              $info['filename'] = $file_record->filename;
 128              $result[$file_record->pathnamehash] = $info;
 129          }
 130          $rs->close();
 131          return $result;
 132      }
 133  
 134      /**
 135       * Get file listing
 136       *
 137       * @param string $encodedpath
 138       * @param string $path not used by this plugin
 139       * @return mixed
 140       */
 141      public function get_listing($encodedpath = '', $page = '') {
 142          global $OUTPUT;
 143          $ret = array();
 144          $ret['dynload'] = true;
 145          $ret['nosearch'] = true;
 146          $ret['nologin'] = true;
 147          $list = array();
 148          $files = $this->get_recent_files(0, $this->number, $this->timelimit);
 149  
 150          try {
 151              foreach ($files as $file) {
 152                  // Check that file exists and accessible, retrieve size/date info
 153                  $browser = get_file_browser();
 154                  $context = context::instance_by_id($file['contextid']);
 155                  $fileinfo = $browser->get_file_info($context, $file['component'],
 156                          $file['filearea'], $file['itemid'], $file['filepath'], $file['filename']);
 157                  if ($fileinfo) {
 158                      $params = base64_encode(json_encode($file));
 159                      $node = array(
 160                          'title' => $fileinfo->get_visible_name(),
 161                          'size' => $fileinfo->get_filesize(),
 162                          'datemodified' => $fileinfo->get_timemodified(),
 163                          'datecreated' => $fileinfo->get_timecreated(),
 164                          'author' => $fileinfo->get_author(),
 165                          'license' => $fileinfo->get_license(),
 166                          'source'=> $params,
 167                          'icon' => $OUTPUT->image_url(file_file_icon($fileinfo, 24))->out(false),
 168                          'thumbnail' => $OUTPUT->image_url(file_file_icon($fileinfo, 90))->out(false),
 169                      );
 170                      if ($imageinfo = $fileinfo->get_imageinfo()) {
 171                          $fileurl = new moodle_url($fileinfo->get_url());
 172                          $node['realthumbnail'] = $fileurl->out(false, array('preview' => 'thumb', 'oid' => $fileinfo->get_timemodified()));
 173                          $node['realicon'] = $fileurl->out(false, array('preview' => 'tinyicon', 'oid' => $fileinfo->get_timemodified()));
 174                          $node['image_width'] = $imageinfo['width'];
 175                          $node['image_height'] = $imageinfo['height'];
 176                      }
 177                      $list[] = $node;
 178                  }
 179              }
 180          } catch (Exception $e) {
 181              throw new repository_exception('emptyfilelist', 'repository_recent');
 182          }
 183          $ret['list'] = array_filter($list, array($this, 'filter'));
 184          return $ret;
 185      }
 186  
 187      public static function get_type_option_names() {
 188          return array('recentfilesnumber', 'recentfilestimelimit', 'pluginname');
 189      }
 190  
 191      public static function type_config_form($mform, $classname = 'repository') {
 192          parent::type_config_form($mform, $classname);
 193          $number = get_config('repository_recent', 'recentfilesnumber');
 194          if (empty($number)) {
 195              $number = DEFAULT_RECENT_FILES_NUM;
 196          }
 197          $mform->addElement('text', 'recentfilesnumber', get_string('recentfilesnumber', 'repository_recent'));
 198          $mform->setType('recentfilesnumber', PARAM_INT);
 199          $mform->setDefault('recentfilesnumber', $number);
 200  
 201          $mform->addElement('duration', 'recentfilestimelimit',
 202              get_string('timelimit', 'repository_recent'), ['units' => [DAYSECS, WEEKSECS], 'optional' => true]);
 203          $mform->addHelpButton('recentfilestimelimit', 'timelimit', 'repository_recent');
 204          $mform->setDefault('recentfilestimelimit', DEFAULT_RECENT_FILES_TIME_LIMIT);
 205      }
 206  
 207      /**
 208       * This plugin doesn't support to link to external links
 209       *
 210       * @return int
 211       */
 212      public function supported_returntypes() {
 213          return FILE_INTERNAL;
 214      }
 215  
 216      /**
 217       * Repository method to make sure that user can access particular file.
 218       *
 219       * This is checked when user tries to pick the file from repository to deal with
 220       * potential parameter substitutions is request
 221       *
 222       * @todo MDL-33805 remove this function when recent files are managed correctly
 223       *
 224       * @param string $source
 225       * @return bool whether the file is accessible by current user
 226       */
 227      public function file_is_accessible($source) {
 228          global $USER;
 229          $reference = $this->get_file_reference($source);
 230          $file = self::get_moodle_file($reference);
 231          return (!empty($file) && $file->get_userid() == $USER->id);
 232      }
 233  
 234      /**
 235       * Does this repository used to browse moodle files?
 236       *
 237       * @return boolean
 238       */
 239      public function has_moodle_files() {
 240          return true;
 241      }
 242  
 243      /**
 244       * Is this repository accessing private data?
 245       *
 246       * @return bool
 247       */
 248      public function contains_private_data() {
 249          return false;
 250      }
 251  }