[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/filestorage/ -> stored_file.php (source)

   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   * Definition of a class stored_file.
  20   *
  21   * @package   core_files
  22   * @copyright 2008 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  require_once($CFG->dirroot . '/lib/filestorage/file_progress.php');
  29  
  30  /**
  31   * Class representing local files stored in a sha1 file pool.
  32   *
  33   * Since Moodle 2.0 file contents are stored in sha1 pool and
  34   * all other file information is stored in new "files" database table.
  35   *
  36   * @package   core_files
  37   * @category  files
  38   * @copyright 2008 Petr Skoda {@link http://skodak.org}
  39   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  40   * @since     Moodle 2.0
  41   */
  42  class stored_file {
  43      /** @var file_storage file storage pool instance */
  44      private $fs;
  45      /** @var stdClass record from the files table left join files_reference table */
  46      private $file_record;
  47      /** @var string location of content files */
  48      private $filedir;
  49      /** @var repository repository plugin instance */
  50      private $repository;
  51  
  52      /**
  53       * @var int Indicates a file handle of the type returned by fopen.
  54       */
  55      const FILE_HANDLE_FOPEN = 0;
  56  
  57      /**
  58       * @var int Indicates a file handle of the type returned by gzopen.
  59       */
  60      const FILE_HANDLE_GZOPEN = 1;
  61  
  62  
  63      /**
  64       * Constructor, this constructor should be called ONLY from the file_storage class!
  65       *
  66       * @param file_storage $fs file  storage instance
  67       * @param stdClass $file_record description of file
  68       * @param string $filedir location of file directory with sh1 named content files
  69       */
  70      public function __construct(file_storage $fs, stdClass $file_record, $filedir) {
  71          global $DB, $CFG;
  72          $this->fs          = $fs;
  73          $this->file_record = clone($file_record); // prevent modifications
  74          $this->filedir     = $filedir; // keep secret, do not expose!
  75  
  76          if (!empty($file_record->repositoryid)) {
  77              require_once("$CFG->dirroot/repository/lib.php");
  78              $this->repository = repository::get_repository_by_id($file_record->repositoryid, SYSCONTEXTID);
  79              if ($this->repository->supported_returntypes() & FILE_REFERENCE != FILE_REFERENCE) {
  80                  // Repository cannot do file reference.
  81                  throw new moodle_exception('error');
  82              }
  83          } else {
  84              $this->repository = null;
  85          }
  86          // make sure all reference fields exist in file_record even when it is not a reference
  87          foreach (array('referencelastsync', 'referencefileid', 'reference', 'repositoryid') as $key) {
  88              if (empty($this->file_record->$key)) {
  89                  $this->file_record->$key = null;
  90              }
  91          }
  92      }
  93  
  94      /**
  95       * Whether or not this is a external resource
  96       *
  97       * @return bool
  98       */
  99      public function is_external_file() {
 100          return !empty($this->repository);
 101      }
 102  
 103      /**
 104       * Update some file record fields
 105       * NOTE: Must remain protected
 106       *
 107       * @param stdClass $dataobject
 108       */
 109      protected function update($dataobject) {
 110          global $DB;
 111          $updatereferencesneeded = false;
 112          $keys = array_keys((array)$this->file_record);
 113          foreach ($dataobject as $field => $value) {
 114              if (in_array($field, $keys)) {
 115                  if ($field == 'contextid' and (!is_number($value) or $value < 1)) {
 116                      throw new file_exception('storedfileproblem', 'Invalid contextid');
 117                  }
 118  
 119                  if ($field == 'component') {
 120                      $value = clean_param($value, PARAM_COMPONENT);
 121                      if (empty($value)) {
 122                          throw new file_exception('storedfileproblem', 'Invalid component');
 123                      }
 124                  }
 125  
 126                  if ($field == 'filearea') {
 127                      $value = clean_param($value, PARAM_AREA);
 128                      if (empty($value)) {
 129                          throw new file_exception('storedfileproblem', 'Invalid filearea');
 130                      }
 131                  }
 132  
 133                  if ($field == 'itemid' and (!is_number($value) or $value < 0)) {
 134                      throw new file_exception('storedfileproblem', 'Invalid itemid');
 135                  }
 136  
 137  
 138                  if ($field == 'filepath') {
 139                      $value = clean_param($value, PARAM_PATH);
 140                      if (strpos($value, '/') !== 0 or strrpos($value, '/') !== strlen($value)-1) {
 141                          // path must start and end with '/'
 142                          throw new file_exception('storedfileproblem', 'Invalid file path');
 143                      }
 144                  }
 145  
 146                  if ($field == 'filename') {
 147                      // folder has filename == '.', so we pass this
 148                      if ($value != '.') {
 149                          $value = clean_param($value, PARAM_FILE);
 150                      }
 151                      if ($value === '') {
 152                          throw new file_exception('storedfileproblem', 'Invalid file name');
 153                      }
 154                  }
 155  
 156                  if ($field === 'timecreated' or $field === 'timemodified') {
 157                      if (!is_number($value)) {
 158                          throw new file_exception('storedfileproblem', 'Invalid timestamp');
 159                      }
 160                      if ($value < 0) {
 161                          $value = 0;
 162                      }
 163                  }
 164  
 165                  if ($field === 'referencefileid') {
 166                      if (!is_null($value) and !is_number($value)) {
 167                          throw new file_exception('storedfileproblem', 'Invalid reference info');
 168                      }
 169                  }
 170  
 171                  if (($field == 'contenthash' || $field == 'filesize') && $this->file_record->$field != $value) {
 172                      $updatereferencesneeded = true;
 173                  }
 174  
 175                  // adding the field
 176                  $this->file_record->$field = $value;
 177              } else {
 178                  throw new coding_exception("Invalid field name, $field doesn't exist in file record");
 179              }
 180          }
 181          // Validate mimetype field
 182          // we don't use {@link stored_file::get_content_file_location()} here becaues it will try to update file_record
 183          $pathname = $this->get_pathname_by_contenthash();
 184          // try to recover the content from trash
 185          if (!is_readable($pathname)) {
 186              if (!$this->fs->try_content_recovery($this) or !is_readable($pathname)) {
 187                  throw new file_exception('storedfilecannotread', '', $pathname);
 188              }
 189          }
 190          $mimetype = $this->fs->mimetype($pathname, $this->file_record->filename);
 191          $this->file_record->mimetype = $mimetype;
 192  
 193          $DB->update_record('files', $this->file_record);
 194          if ($updatereferencesneeded) {
 195              // Either filesize or contenthash of this file have changed. Update all files that reference to it.
 196              $this->fs->update_references_to_storedfile($this);
 197          }
 198      }
 199  
 200      /**
 201       * Rename filename
 202       *
 203       * @param string $filepath file path
 204       * @param string $filename file name
 205       */
 206      public function rename($filepath, $filename) {
 207          if ($this->fs->file_exists($this->get_contextid(), $this->get_component(), $this->get_filearea(), $this->get_itemid(), $filepath, $filename)) {
 208              $a = new stdClass();
 209              $a->contextid = $this->get_contextid();
 210              $a->component = $this->get_component();
 211              $a->filearea  = $this->get_filearea();
 212              $a->itemid    = $this->get_itemid();
 213              $a->filepath  = $filepath;
 214              $a->filename  = $filename;
 215              throw new file_exception('storedfilenotcreated', $a, 'file exists, cannot rename');
 216          }
 217          $filerecord = new stdClass;
 218          $filerecord->filepath = $filepath;
 219          $filerecord->filename = $filename;
 220          // populate the pathname hash
 221          $filerecord->pathnamehash = $this->fs->get_pathname_hash($this->file_record->contextid, $this->file_record->component, $this->file_record->filearea, $this->file_record->itemid, $filepath, $filename);
 222          $this->update($filerecord);
 223      }
 224  
 225      /**
 226       * Replace the content by providing another stored_file instance
 227       *
 228       * @deprecated since 2.6
 229       * @see stored_file::replace_file_with()
 230       * @param stored_file $storedfile
 231       */
 232      public function replace_content_with(stored_file $storedfile) {
 233          debugging('Function stored_file::replace_content_with() is deprecated. Please use stored_file::replace_file_with()', DEBUG_DEVELOPER);
 234          $filerecord = new stdClass;
 235          $contenthash = $storedfile->get_contenthash();
 236          if ($this->fs->content_exists($contenthash)) {
 237              $filerecord->contenthash = $contenthash;
 238          } else {
 239              throw new file_exception('storedfileproblem', 'Invalid contenthash, content must be already in filepool', $contenthash);
 240          }
 241          $filerecord->filesize = $storedfile->get_filesize();
 242          $this->update($filerecord);
 243      }
 244  
 245      /**
 246       * Replaces the fields that might have changed when file was overriden in filepicker:
 247       * reference, contenthash, filesize, userid
 248       *
 249       * Note that field 'source' must be updated separately because
 250       * it has different format for draft and non-draft areas and
 251       * this function will usually be used to replace non-draft area
 252       * file with draft area file.
 253       *
 254       * @param stored_file $newfile
 255       * @throws coding_exception
 256       */
 257      public function replace_file_with(stored_file $newfile) {
 258          if ($newfile->get_referencefileid() &&
 259                  $this->fs->get_references_count_by_storedfile($this)) {
 260              // The new file is a reference.
 261              // The current file has other local files referencing to it.
 262              // Double reference is not allowed.
 263              throw new moodle_exception('errordoublereference', 'repository');
 264          }
 265  
 266          $filerecord = new stdClass;
 267          $contenthash = $newfile->get_contenthash();
 268          if ($this->fs->content_exists($contenthash)) {
 269              $filerecord->contenthash = $contenthash;
 270          } else {
 271              throw new file_exception('storedfileproblem', 'Invalid contenthash, content must be already in filepool', $contenthash);
 272          }
 273          $filerecord->filesize = $newfile->get_filesize();
 274          $filerecord->referencefileid = $newfile->get_referencefileid();
 275          $filerecord->userid = $newfile->get_userid();
 276          $this->update($filerecord);
 277      }
 278  
 279      /**
 280       * Unlink the stored file from the referenced file
 281       *
 282       * This methods destroys the link to the record in files_reference table. This effectively
 283       * turns the stored file from being an alias to a plain copy. However, the caller has
 284       * to make sure that the actual file's content has beed synced prior to calling this method.
 285       */
 286      public function delete_reference() {
 287          global $DB;
 288  
 289          if (!$this->is_external_file()) {
 290              throw new coding_exception('An attempt to unlink a non-reference file.');
 291          }
 292  
 293          $transaction = $DB->start_delegated_transaction();
 294  
 295          // Are we the only one referring to the original file? If so, delete the
 296          // referenced file record. Note we do not use file_storage::search_references_count()
 297          // here because we want to count draft files too and we are at a bit lower access level here.
 298          $countlinks = $DB->count_records('files',
 299              array('referencefileid' => $this->file_record->referencefileid));
 300          if ($countlinks == 1) {
 301              $DB->delete_records('files_reference', array('id' => $this->file_record->referencefileid));
 302          }
 303  
 304          // Update the underlying record in the database.
 305          $update = new stdClass();
 306          $update->referencefileid = null;
 307          $this->update($update);
 308  
 309          $transaction->allow_commit();
 310  
 311          // Update our properties and the record in the memory.
 312          $this->repository = null;
 313          $this->file_record->repositoryid = null;
 314          $this->file_record->reference = null;
 315          $this->file_record->referencefileid = null;
 316          $this->file_record->referencelastsync = null;
 317      }
 318  
 319      /**
 320       * Is this a directory?
 321       *
 322       * Directories are only emulated, internally they are stored as empty
 323       * files with a "." instead of name - this means empty directory contains
 324       * exactly one empty file with name dot.
 325       *
 326       * @return bool true means directory, false means file
 327       */
 328      public function is_directory() {
 329          return ($this->file_record->filename === '.');
 330      }
 331  
 332      /**
 333       * Delete file from files table.
 334       *
 335       * The content of files stored in sha1 pool is reclaimed
 336       * later - the occupied disk space is reclaimed much later.
 337       *
 338       * @return bool always true or exception if error occurred
 339       */
 340      public function delete() {
 341          global $DB;
 342  
 343          if ($this->is_directory()) {
 344              // Directories can not be referenced, just delete the record.
 345              $DB->delete_records('files', array('id'=>$this->file_record->id));
 346  
 347          } else {
 348              $transaction = $DB->start_delegated_transaction();
 349  
 350              // If there are other files referring to this file, convert them to copies.
 351              if ($files = $this->fs->get_references_by_storedfile($this)) {
 352                  foreach ($files as $file) {
 353                      $this->fs->import_external_file($file);
 354                  }
 355              }
 356  
 357              // If this file is a reference (alias) to another file, unlink it first.
 358              if ($this->is_external_file()) {
 359                  $this->delete_reference();
 360              }
 361  
 362              // Now delete the file record.
 363              $DB->delete_records('files', array('id'=>$this->file_record->id));
 364  
 365              $transaction->allow_commit();
 366          }
 367  
 368          // Move pool file to trash if content not needed any more.
 369          $this->fs->deleted_file_cleanup($this->file_record->contenthash);
 370          return true; // BC only
 371      }
 372  
 373      /**
 374       * Get file pathname by contenthash
 375       *
 376       * NOTE, this function is not calling sync_external_file, it assume the contenthash is current
 377       * Protected - developers must not gain direct access to this function.
 378       *
 379       * @return string full path to pool file with file content
 380       */
 381      protected function get_pathname_by_contenthash() {
 382          // Detect is local file or not.
 383          $contenthash = $this->file_record->contenthash;
 384          $l1 = $contenthash[0].$contenthash[1];
 385          $l2 = $contenthash[2].$contenthash[3];
 386          return "$this->filedir/$l1/$l2/$contenthash";
 387      }
 388  
 389      /**
 390       * Get file pathname by given contenthash, this method will try to sync files
 391       *
 392       * Protected - developers must not gain direct access to this function.
 393       *
 394       * NOTE: do not make this public, we must not modify or delete the pool files directly! ;-)
 395       *
 396       * @return string full path to pool file with file content
 397       **/
 398      protected function get_content_file_location() {
 399          $this->sync_external_file();
 400          return $this->get_pathname_by_contenthash();
 401      }
 402  
 403      /**
 404      * adds this file path to a curl request (POST only)
 405      *
 406      * @param curl $curlrequest the curl request object
 407      * @param string $key what key to use in the POST request
 408      * @return void
 409      */
 410      public function add_to_curl_request(&$curlrequest, $key) {
 411          if (function_exists('curl_file_create')) {
 412              // As of PHP 5.5, the usage of the @filename API for file uploading is deprecated.
 413              $value = curl_file_create($this->get_content_file_location());
 414          } else {
 415              $value = '@' . $this->get_content_file_location();
 416          }
 417          $curlrequest->_tmp_file_post_params[$key] = $value;
 418      }
 419  
 420      /**
 421       * Returns file handle - read only mode, no writing allowed into pool files!
 422       *
 423       * When you want to modify a file, create a new file and delete the old one.
 424       *
 425       * @param int $type Type of file handle (FILE_HANDLE_xx constant)
 426       * @return resource file handle
 427       */
 428      public function get_content_file_handle($type = self::FILE_HANDLE_FOPEN) {
 429          $path = $this->get_content_file_location();
 430          if (!is_readable($path)) {
 431              if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
 432                  throw new file_exception('storedfilecannotread', '', $path);
 433              }
 434          }
 435          switch ($type) {
 436              case self::FILE_HANDLE_FOPEN:
 437                  // Binary reading.
 438                  return fopen($path, 'rb');
 439              case self::FILE_HANDLE_GZOPEN:
 440                  // Binary reading of file in gz format.
 441                  return gzopen($path, 'rb');
 442              default:
 443                  throw new coding_exception('Unexpected file handle type');
 444          }
 445      }
 446  
 447      /**
 448       * Dumps file content to page.
 449       */
 450      public function readfile() {
 451          $path = $this->get_content_file_location();
 452          if (!is_readable($path)) {
 453              if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
 454                  throw new file_exception('storedfilecannotread', '', $path);
 455              }
 456          }
 457          readfile_allow_large($path, $this->get_filesize());
 458      }
 459  
 460      /**
 461       * Returns file content as string.
 462       *
 463       * @return string content
 464       */
 465      public function get_content() {
 466          $path = $this->get_content_file_location();
 467          if (!is_readable($path)) {
 468              if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
 469                  throw new file_exception('storedfilecannotread', '', $path);
 470              }
 471          }
 472          return file_get_contents($this->get_content_file_location());
 473      }
 474  
 475      /**
 476       * Copy content of file to given pathname.
 477       *
 478       * @param string $pathname real path to the new file
 479       * @return bool success
 480       */
 481      public function copy_content_to($pathname) {
 482          $path = $this->get_content_file_location();
 483          if (!is_readable($path)) {
 484              if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
 485                  throw new file_exception('storedfilecannotread', '', $path);
 486              }
 487          }
 488          return copy($path, $pathname);
 489      }
 490  
 491      /**
 492       * Copy content of file to temporary folder and returns file path
 493       *
 494       * @param string $dir name of the temporary directory
 495       * @param string $fileprefix prefix of temporary file.
 496       * @return string|bool path of temporary file or false.
 497       */
 498      public function copy_content_to_temp($dir = 'files', $fileprefix = 'tempup_') {
 499          $tempfile = false;
 500          if (!$dir = make_temp_directory($dir)) {
 501              return false;
 502          }
 503          if (!$tempfile = tempnam($dir, $fileprefix)) {
 504              return false;
 505          }
 506          if (!$this->copy_content_to($tempfile)) {
 507              // something went wrong
 508              @unlink($tempfile);
 509              return false;
 510          }
 511          return $tempfile;
 512      }
 513  
 514      /**
 515       * List contents of archive.
 516       *
 517       * @param file_packer $packer file packer instance
 518       * @return array of file infos
 519       */
 520      public function list_files(file_packer $packer) {
 521          $archivefile = $this->get_content_file_location();
 522          return $packer->list_files($archivefile);
 523      }
 524  
 525      /**
 526       * Extract file to given file path (real OS filesystem), existing files are overwritten.
 527       *
 528       * @param file_packer $packer file packer instance
 529       * @param string $pathname target directory
 530       * @param file_progress $progress Progress indicator callback or null if not required
 531       * @return array|bool list of processed files; false if error
 532       */
 533      public function extract_to_pathname(file_packer $packer, $pathname,
 534              file_progress $progress = null) {
 535          $archivefile = $this->get_content_file_location();
 536          return $packer->extract_to_pathname($archivefile, $pathname, null, $progress);
 537      }
 538  
 539      /**
 540       * Extract file to given file path (real OS filesystem), existing files are overwritten.
 541       *
 542       * @param file_packer $packer file packer instance
 543       * @param int $contextid context ID
 544       * @param string $component component
 545       * @param string $filearea file area
 546       * @param int $itemid item ID
 547       * @param string $pathbase path base
 548       * @param int $userid user ID
 549       * @param file_progress $progress Progress indicator callback or null if not required
 550       * @return array|bool list of processed files; false if error
 551       */
 552      public function extract_to_storage(file_packer $packer, $contextid,
 553              $component, $filearea, $itemid, $pathbase, $userid = null, file_progress $progress = null) {
 554          $archivefile = $this->get_content_file_location();
 555          return $packer->extract_to_storage($archivefile, $contextid,
 556                  $component, $filearea, $itemid, $pathbase, $userid, $progress);
 557      }
 558  
 559      /**
 560       * Add file/directory into archive.
 561       *
 562       * @param file_archive $filearch file archive instance
 563       * @param string $archivepath pathname in archive
 564       * @return bool success
 565       */
 566      public function archive_file(file_archive $filearch, $archivepath) {
 567          if ($this->is_directory()) {
 568              return $filearch->add_directory($archivepath);
 569          } else {
 570              $path = $this->get_content_file_location();
 571              if (!is_readable($path)) {
 572                  return false;
 573              }
 574              return $filearch->add_file_from_pathname($archivepath, $path);
 575          }
 576      }
 577  
 578      /**
 579       * Returns information about image,
 580       * information is determined from the file content
 581       *
 582       * @return mixed array with width, height and mimetype; false if not an image
 583       */
 584      public function get_imageinfo() {
 585          $path = $this->get_content_file_location();
 586          if (!is_readable($path)) {
 587              if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
 588                  throw new file_exception('storedfilecannotread', '', $path);
 589              }
 590          }
 591          $mimetype = $this->get_mimetype();
 592          if (!preg_match('|^image/|', $mimetype) || !filesize($path) || !($imageinfo = getimagesize($path))) {
 593              return false;
 594          }
 595          $image = array('width'=>$imageinfo[0], 'height'=>$imageinfo[1], 'mimetype'=>image_type_to_mime_type($imageinfo[2]));
 596          if (empty($image['width']) or empty($image['height']) or empty($image['mimetype'])) {
 597              // gd can not parse it, sorry
 598              return false;
 599          }
 600          return $image;
 601      }
 602  
 603      /**
 604       * Verifies the file is a valid web image - gif, png and jpeg only.
 605       *
 606       * It should be ok to serve this image from server without any other security workarounds.
 607       *
 608       * @return bool true if file ok
 609       */
 610      public function is_valid_image() {
 611          $mimetype = $this->get_mimetype();
 612          if (!file_mimetype_in_typegroup($mimetype, 'web_image')) {
 613              return false;
 614          }
 615          if (!$info = $this->get_imageinfo()) {
 616              return false;
 617          }
 618          if ($info['mimetype'] !== $mimetype) {
 619              return false;
 620          }
 621          // ok, GD likes this image
 622          return true;
 623      }
 624  
 625      /**
 626       * Returns parent directory, creates missing parents if needed.
 627       *
 628       * @return stored_file
 629       */
 630      public function get_parent_directory() {
 631          if ($this->file_record->filepath === '/' and $this->file_record->filename === '.') {
 632              //root dir does not have parent
 633              return null;
 634          }
 635  
 636          if ($this->file_record->filename !== '.') {
 637              return $this->fs->create_directory($this->file_record->contextid, $this->file_record->component, $this->file_record->filearea, $this->file_record->itemid, $this->file_record->filepath);
 638          }
 639  
 640          $filepath = $this->file_record->filepath;
 641          $filepath = trim($filepath, '/');
 642          $dirs = explode('/', $filepath);
 643          array_pop($dirs);
 644          $filepath = implode('/', $dirs);
 645          $filepath = ($filepath === '') ? '/' : "/$filepath/";
 646  
 647          return $this->fs->create_directory($this->file_record->contextid, $this->file_record->component, $this->file_record->filearea, $this->file_record->itemid, $filepath);
 648      }
 649  
 650      /**
 651       * Synchronize file if it is a reference and needs synchronizing
 652       *
 653       * Updates contenthash and filesize
 654       */
 655      public function sync_external_file() {
 656          if (!empty($this->repository)) {
 657              $this->repository->sync_reference($this);
 658          }
 659      }
 660  
 661      /**
 662       * Returns context id of the file
 663       *
 664       * @return int context id
 665       */
 666      public function get_contextid() {
 667          return $this->file_record->contextid;
 668      }
 669  
 670      /**
 671       * Returns component name - this is the owner of the areas,
 672       * nothing else is allowed to read or modify the files directly!!
 673       *
 674       * @return string
 675       */
 676      public function get_component() {
 677          return $this->file_record->component;
 678      }
 679  
 680      /**
 681       * Returns file area name, this divides files of one component into groups with different access control.
 682       * All files in one area have the same access control.
 683       *
 684       * @return string
 685       */
 686      public function get_filearea() {
 687          return $this->file_record->filearea;
 688      }
 689  
 690      /**
 691       * Returns returns item id of file.
 692       *
 693       * @return int
 694       */
 695      public function get_itemid() {
 696          return $this->file_record->itemid;
 697      }
 698  
 699      /**
 700       * Returns file path - starts and ends with /, \ are not allowed.
 701       *
 702       * @return string
 703       */
 704      public function get_filepath() {
 705          return $this->file_record->filepath;
 706      }
 707  
 708      /**
 709       * Returns file name or '.' in case of directories.
 710       *
 711       * @return string
 712       */
 713      public function get_filename() {
 714          return $this->file_record->filename;
 715      }
 716  
 717      /**
 718       * Returns id of user who created the file.
 719       *
 720       * @return int
 721       */
 722      public function get_userid() {
 723          return $this->file_record->userid;
 724      }
 725  
 726      /**
 727       * Returns the size of file in bytes.
 728       *
 729       * @return int bytes
 730       */
 731      public function get_filesize() {
 732          $this->sync_external_file();
 733          return $this->file_record->filesize;
 734      }
 735  
 736       /**
 737       * Returns the size of file in bytes.
 738       *
 739       * @param int $filesize bytes
 740       */
 741      public function set_filesize($filesize) {
 742          debugging('Function stored_file::set_filesize() is deprecated. Please use stored_file::replace_file_with()', DEBUG_DEVELOPER);
 743          $filerecord = new stdClass;
 744          $filerecord->filesize = $filesize;
 745          $this->update($filerecord);
 746      }
 747  
 748      /**
 749       * Returns mime type of file.
 750       *
 751       * @return string
 752       */
 753      public function get_mimetype() {
 754          return $this->file_record->mimetype;
 755      }
 756  
 757      /**
 758       * Returns unix timestamp of file creation date.
 759       *
 760       * @return int
 761       */
 762      public function get_timecreated() {
 763          return $this->file_record->timecreated;
 764      }
 765  
 766      /**
 767       * Returns unix timestamp of last file modification.
 768       *
 769       * @return int
 770       */
 771      public function get_timemodified() {
 772          $this->sync_external_file();
 773          return $this->file_record->timemodified;
 774      }
 775  
 776      /**
 777       * set timemodified
 778       *
 779       * @param int $timemodified
 780       */
 781      public function set_timemodified($timemodified) {
 782          $filerecord = new stdClass;
 783          $filerecord->timemodified = $timemodified;
 784          $this->update($filerecord);
 785      }
 786  
 787      /**
 788       * Returns file status flag.
 789       *
 790       * @return int 0 means file OK, anything else is a problem and file can not be used
 791       */
 792      public function get_status() {
 793          return $this->file_record->status;
 794      }
 795  
 796      /**
 797       * Returns file id.
 798       *
 799       * @return int
 800       */
 801      public function get_id() {
 802          return $this->file_record->id;
 803      }
 804  
 805      /**
 806       * Returns sha1 hash of file content.
 807       *
 808       * @return string
 809       */
 810      public function get_contenthash() {
 811          $this->sync_external_file();
 812          return $this->file_record->contenthash;
 813      }
 814  
 815      /**
 816       * Returns sha1 hash of all file path components sha1("contextid/component/filearea/itemid/dir/dir/filename.ext").
 817       *
 818       * @return string
 819       */
 820      public function get_pathnamehash() {
 821          return $this->file_record->pathnamehash;
 822      }
 823  
 824      /**
 825       * Returns the license type of the file, it is a short name referred from license table.
 826       *
 827       * @return string
 828       */
 829      public function get_license() {
 830          return $this->file_record->license;
 831      }
 832  
 833      /**
 834       * Set license
 835       *
 836       * @param string $license license
 837       */
 838      public function set_license($license) {
 839          $filerecord = new stdClass;
 840          $filerecord->license = $license;
 841          $this->update($filerecord);
 842      }
 843  
 844      /**
 845       * Returns the author name of the file.
 846       *
 847       * @return string
 848       */
 849      public function get_author() {
 850          return $this->file_record->author;
 851      }
 852  
 853      /**
 854       * Set author
 855       *
 856       * @param string $author
 857       */
 858      public function set_author($author) {
 859          $filerecord = new stdClass;
 860          $filerecord->author = $author;
 861          $this->update($filerecord);
 862      }
 863  
 864      /**
 865       * Returns the source of the file, usually it is a url.
 866       *
 867       * @return string
 868       */
 869      public function get_source() {
 870          return $this->file_record->source;
 871      }
 872  
 873      /**
 874       * Set license
 875       *
 876       * @param string $license license
 877       */
 878      public function set_source($source) {
 879          $filerecord = new stdClass;
 880          $filerecord->source = $source;
 881          $this->update($filerecord);
 882      }
 883  
 884  
 885      /**
 886       * Returns the sort order of file
 887       *
 888       * @return int
 889       */
 890      public function get_sortorder() {
 891          return $this->file_record->sortorder;
 892      }
 893  
 894      /**
 895       * Set file sort order
 896       *
 897       * @param int $sortorder
 898       * @return int
 899       */
 900      public function set_sortorder($sortorder) {
 901          $filerecord = new stdClass;
 902          $filerecord->sortorder = $sortorder;
 903          $this->update($filerecord);
 904      }
 905  
 906      /**
 907       * Returns repository id
 908       *
 909       * @return int|null
 910       */
 911      public function get_repository_id() {
 912          if (!empty($this->repository)) {
 913              return $this->repository->id;
 914          } else {
 915              return null;
 916          }
 917      }
 918  
 919      /**
 920       * get reference file id
 921       * @return int
 922       */
 923      public function get_referencefileid() {
 924          return $this->file_record->referencefileid;
 925      }
 926  
 927      /**
 928       * Get reference last sync time
 929       * @return int
 930       */
 931      public function get_referencelastsync() {
 932          return $this->file_record->referencelastsync;
 933      }
 934  
 935      /**
 936       * Get reference life time (in seconds) after which sync is required
 937       *
 938       * This data is no longer stored in DB or returned by repository. Each
 939       * repository should decide by itself when to synchronise the references.
 940       *
 941       * @deprecated since 2.6
 942       * @see repository::sync_reference()
 943       * @return int
 944       */
 945      public function get_referencelifetime() {
 946          debugging('Function stored_file::get_referencelifetime() is deprecated.', DEBUG_DEVELOPER);
 947          if ($this->repository) {
 948              if (method_exists($this->repository, 'get_reference_file_lifetime')) {
 949                  return $this->repository->get_reference_file_lifetime($this->get_reference());
 950              } else {
 951                  return 24 * 60 * 60;
 952              }
 953          } else {
 954              return 0;
 955          }
 956      }
 957      /**
 958       * Returns file reference
 959       *
 960       * @return string
 961       */
 962      public function get_reference() {
 963          return $this->file_record->reference;
 964      }
 965  
 966      /**
 967       * Get human readable file reference information
 968       *
 969       * @return string
 970       */
 971      public function get_reference_details() {
 972          return $this->repository->get_reference_details($this->get_reference(), $this->get_status());
 973      }
 974  
 975      /**
 976       * Called after reference-file has been synchronized with the repository
 977       *
 978       * We update contenthash, filesize and status in files table if changed
 979       * and we always update lastsync in files_reference table
 980       *
 981       * @param null|string $contenthash if set to null contenthash is not changed
 982       * @param int $filesize new size of the file
 983       * @param int $status new status of the file (0 means OK, 666 - source missing)
 984       */
 985      public function set_synchronized($contenthash, $filesize, $status = 0) {
 986          if (!$this->is_external_file()) {
 987              return;
 988          }
 989          $now = time();
 990          if ($contenthash === null) {
 991              $contenthash = $this->file_record->contenthash;
 992          }
 993          if ($contenthash != $this->file_record->contenthash) {
 994              $oldcontenthash = $this->file_record->contenthash;
 995          }
 996          // this will update all entries in {files} that have the same filereference id
 997          $this->fs->update_references($this->file_record->referencefileid, $now, null, $contenthash, $filesize, $status);
 998          // we don't need to call update() for this object, just set the values of changed fields
 999          $this->file_record->contenthash = $contenthash;
1000          $this->file_record->filesize = $filesize;
1001          $this->file_record->status = $status;
1002          $this->file_record->referencelastsync = $now;
1003          if (isset($oldcontenthash)) {
1004              $this->fs->deleted_file_cleanup($oldcontenthash);
1005          }
1006      }
1007  
1008      /**
1009       * Sets the error status for a file that could not be synchronised
1010       */
1011      public function set_missingsource() {
1012          $this->set_synchronized($this->file_record->contenthash, $this->file_record->filesize, 666);
1013      }
1014  
1015      /**
1016       * Send file references
1017       *
1018       * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours)
1019       * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only
1020       * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin
1021       * @param array $options additional options affecting the file serving
1022       */
1023      public function send_file($lifetime, $filter, $forcedownload, $options) {
1024          $this->repository->send_file($this, $lifetime, $filter, $forcedownload, $options);
1025      }
1026  
1027      /**
1028       * Imports the contents of an external file into moodle filepool.
1029       *
1030       * @throws moodle_exception if file could not be downloaded or is too big
1031       * @param int $maxbytes throw an exception if file size is bigger than $maxbytes (0 means no limit)
1032       */
1033      public function import_external_file_contents($maxbytes = 0) {
1034          if ($this->repository) {
1035              $this->repository->import_external_file_contents($this, $maxbytes);
1036          }
1037      }
1038  
1039      /**
1040       * Gets a file relative to this file in the repository and sends it to the browser.
1041       * Checks the function repository::supports_relative_file() to make sure it can be used.
1042       *
1043       * @param string $relativepath the relative path to the file we are trying to access
1044       */
1045      public function send_relative_file($relativepath) {
1046          if ($this->repository && $this->repository->supports_relative_file()) {
1047              $relativepath = clean_param($relativepath, PARAM_PATH);
1048              $this->repository->send_relative_file($this, $relativepath);
1049          } else {
1050              send_file_not_found();
1051          }
1052      }
1053  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1