Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   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   * Utility class for browsing of user files.
  20   *
  21   * @package    core_files
  22   * @copyright  2008 Petr Skoda (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  /**
  29   * Represents a user context in the tree navigated by {@link file_browser}.
  30   *
  31   * @package    core_files
  32   * @copyright  2008 Petr Skoda (http://skodak.org)
  33   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  34   */
  35  class file_info_context_user extends file_info {
  36      /** @var stdClass User object */
  37      protected $user;
  38  
  39      /**
  40       * Constructor
  41       *
  42       * @param file_browser $browser
  43       * @param stdClass $context
  44       * @param stdClass $user
  45       */
  46      public function __construct($browser, $context, $user) {
  47          parent::__construct($browser, $context);
  48          $this->user = $user;
  49      }
  50  
  51      /**
  52       * Return information about this specific context level
  53       *
  54       * @param string $component componet
  55       * @param string $filearea file area
  56       * @param int $itemid item ID
  57       * @param string $filepath file path
  58       * @param string $filename file name
  59       * @return file_info|null
  60       */
  61      public function get_file_info($component, $filearea, $itemid, $filepath, $filename) {
  62          global $USER;
  63  
  64          if (!isloggedin() or isguestuser()) {
  65              return null;
  66          }
  67  
  68          if (empty($component)) {
  69              // access control: list areas only for myself
  70              if ($this->user->id != $USER->id) {
  71                  // no list of areas for other users
  72                  return null;
  73              }
  74              return $this;
  75          }
  76  
  77          $methodname = "get_area_{$component}_{$filearea}";
  78          if (method_exists($this, $methodname)) {
  79              return $this->$methodname($itemid, $filepath, $filename);
  80          }
  81  
  82          return null;
  83      }
  84  
  85      /**
  86       * Get a file from user private area
  87       *
  88       * @todo MDL-31070 this method should respect $CFG->userquota
  89       * @param int $itemid item ID
  90       * @param string $filepath file path
  91       * @param string $filename file name
  92       * @return file_info|null
  93       */
  94      protected function get_area_user_private($itemid, $filepath, $filename) {
  95          global $USER, $CFG;
  96  
  97          // access control: only my files, nobody else
  98          if ($this->user->id != $USER->id) {
  99              return null;
 100          }
 101  
 102          if (is_null($itemid)) {
 103              // go to parent, we do not use itemids here in private area
 104              return $this;
 105          }
 106  
 107          $fs = get_file_storage();
 108  
 109          $filepath = is_null($filepath) ? '/' : $filepath;
 110          $filename = is_null($filename) ? '.' : $filename;
 111  
 112          if (!$storedfile = $fs->get_file($this->context->id, 'user', 'private', 0, $filepath, $filename)) {
 113              if ($filepath === '/' and $filename === '.') {
 114                  // root dir does not exist yet
 115                  $storedfile = new virtual_root_file($this->context->id, 'user', 'private', 0);
 116              } else {
 117                  // not found
 118                  return null;
 119              }
 120          }
 121          $urlbase = $CFG->wwwroot.'/pluginfile.php';
 122  
 123          //TODO: user quota from $CFG->userquota
 124  
 125          return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areauserpersonal', 'repository'), false, true, true, false);
 126      }
 127  
 128      /**
 129       * Get a file from user profile area
 130       *
 131       * @param int $itemid item ID
 132       * @param string $filepath file path
 133       * @param string $filename file name
 134       * @return file_info|null
 135       */
 136      protected function get_area_user_profile($itemid, $filepath, $filename) {
 137          global $CFG;
 138  
 139          $readaccess = has_capability('moodle/user:update', $this->context);
 140          $writeaccess = has_capability('moodle/user:viewalldetails', $this->context);
 141  
 142          if (!$readaccess and !$writeaccess) {
 143              // the idea here is that only admins should be able to list/modify files in user profile, the rest has to use profile page
 144              return null;
 145          }
 146  
 147          if (is_null($itemid)) {
 148              // go to parent, we do not use itemids here in profile area
 149              return $this;
 150          }
 151  
 152          $fs = get_file_storage();
 153  
 154          $filepath = is_null($filepath) ? '/' : $filepath;
 155          $filename = is_null($filename) ? '.' : $filename;
 156  
 157          if (!$storedfile = $fs->get_file($this->context->id, 'user', 'profile', 0, $filepath, $filename)) {
 158              if ($filepath === '/' and $filename === '.') {
 159                  $storedfile = new virtual_root_file($this->context->id, 'user', 'profile', 0);
 160              } else {
 161                  // not found
 162                  return null;
 163              }
 164          }
 165          $urlbase = $CFG->wwwroot.'/pluginfile.php';
 166          return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase,
 167                  get_string('areauserprofile', 'repository'), false, $readaccess, $writeaccess, false);
 168      }
 169  
 170      /**
 171       * Get a file from user draft area
 172       *
 173       * @param int $itemid item ID
 174       * @param string $filepath file path
 175       * @param string $filename file name
 176       * @return file_info|null
 177       */
 178      protected function get_area_user_draft($itemid, $filepath, $filename) {
 179          global $USER, $CFG;
 180  
 181          // access control: only my files
 182          if ($this->user->id != $USER->id) {
 183              return null;
 184          }
 185  
 186          if (empty($itemid)) {
 187              // do not browse itemids - you must know the draftid to see what is there
 188              return null;
 189          }
 190  
 191          $fs = get_file_storage();
 192  
 193          $filepath = is_null($filepath) ? '/' : $filepath;
 194          $filename = is_null($filename) ? '.' : $filename;
 195  
 196          if (!$storedfile = $fs->get_file($this->context->id, 'user', 'draft', $itemid, $filepath, $filename)) {
 197              if ($filepath === '/' and $filename === '.') {
 198                  $storedfile = new virtual_root_file($this->context->id, 'user', 'draft', $itemid);
 199              } else {
 200                  // not found
 201                  return null;
 202              }
 203          }
 204          $urlbase = $CFG->wwwroot.'/draftfile.php';
 205          return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areauserdraft', 'repository'), true, true, true, true);
 206      }
 207  
 208      /**
 209       * Get a file from user backup area
 210       *
 211       * @todo MDL-31091 maybe we need new caability for access control
 212       * @param int $itemid item ID
 213       * @param string $filepath file path
 214       * @param string $filename file name
 215       * @return file_info|null
 216       */
 217      protected function get_area_user_backup($itemid, $filepath, $filename) {
 218          global $USER, $CFG;
 219  
 220          // access control: only my files, nobody else - TODO: maybe we need new capability here
 221          if ($this->context->instanceid != $USER->id) {
 222              return null;
 223          }
 224  
 225          if (is_null($itemid)) {
 226              // go to parent, we do not use itemids here in profile area
 227              return $this;
 228          }
 229  
 230          $fs = get_file_storage();
 231  
 232          $filepath = is_null($filepath) ? '/' : $filepath;
 233          $filename = is_null($filename) ? '.' : $filename;
 234  
 235          if (!$storedfile = $fs->get_file($this->context->id, 'user', 'backup', $itemid, $filepath, $filename)) {
 236              if ($filepath === '/' and $filename === '.') {
 237                  $storedfile = new virtual_root_file($this->context->id, 'user', 'backup', 0);
 238              } else {
 239                  // not found
 240                  return null;
 241              }
 242          }
 243          $urlbase = $CFG->wwwroot.'/pluginfile.php';
 244          return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areauserbackup', 'repository'), false, true, true, false);
 245      }
 246  
 247      /**
 248       * Returns localised visible name.
 249       *
 250       * @return string
 251       */
 252      public function get_visible_name() {
 253          return fullname($this->user, true);
 254      }
 255  
 256      /**
 257       * Whether or not new files or directories can be added
 258       *
 259       * @return bool
 260       */
 261      public function is_writable() {
 262          return false;
 263      }
 264  
 265      /**
 266       * Whether or not this is a directory
 267       *
 268       * @return bool
 269       */
 270      public function is_directory() {
 271          return true;
 272      }
 273  
 274      /**
 275       * Returns list of children.
 276       *
 277       * @return array of file_info instances
 278       */
 279      public function get_children() {
 280          $children = array();
 281  
 282          if ($child = $this->get_area_user_private(0, '/', '.')) {
 283              $children[] = $child;
 284          }
 285  /*
 286          if ($child = $this->get_area_user_profile(0, '/', '.')) {
 287              $children[] = $child;
 288          }
 289  */
 290          if ($child = $this->get_area_user_backup(0, '/', '.')) {
 291              $children[] = $child;
 292          }
 293          // do not list draft area here - it is browsable only if you know the draft itemid ;-)
 294  
 295          return $children;
 296      }
 297  
 298      /**
 299       * Returns parent file_info instance
 300       *
 301       * @return file_info|null file_info instance or null for root
 302       */
 303      public function get_parent() {
 304          return $this->browser->get_file_info();
 305      }
 306  }