MDL-28666, Fixed source field when download a file using filepicker
[moodle.git] / lib / filestorage / stored_file.php
CommitLineData
16a95e8f 1<?php
16a95e8f 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/**
8496fdac 19 * Definition of a class stored_file.
16a95e8f 20 *
d2b7803e
DC
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
16a95e8f 24 */
25
64f93798
PS
26defined('MOODLE_INTERNAL') || die();
27
28require_once("$CFG->libdir/filestorage/stored_file.php");
67233725 29require_once("$CFG->dirroot/repository/lib.php");
172dd12c 30
31/**
8496fdac
PS
32 * Class representing local files stored in a sha1 file pool.
33 *
34 * Since Moodle 2.0 file contents are stored in sha1 pool and
35 * all other file information is stored in new "files" database table.
36 *
d2b7803e
DC
37 * @package core_files
38 * @category files
8496fdac
PS
39 * @copyright 2008 Petr Skoda {@link http://skodak.org}
40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41 * @since Moodle 2.0
172dd12c 42 */
43class stored_file {
8496fdac 44 /** @var file_storage file storage pool instance */
172dd12c 45 private $fs;
04e3b007 46 /** @var stdClass record from the files table left join files_reference table */
172dd12c 47 private $file_record;
693ef3a8
PS
48 /** @var string location of content files */
49 private $filedir;
67233725
DC
50 /** @var repository repository plugin instance */
51 public $repository;
172dd12c 52
53 /**
8496fdac
PS
54 * Constructor, this constructor should be called ONLY from the file_storage class!
55 *
56 * @param file_storage $fs file storage instance
d2b7803e
DC
57 * @param stdClass $file_record description of file
58 * @param string $filedir location of file directory with sh1 named content files
172dd12c 59 */
693ef3a8 60 public function __construct(file_storage $fs, stdClass $file_record, $filedir) {
67233725 61 global $DB, $CFG;
8496fdac
PS
62 $this->fs = $fs;
63 $this->file_record = clone($file_record); // prevent modifications
693ef3a8 64 $this->filedir = $filedir; // keep secret, do not expose!
67233725
DC
65
66 if (!empty($file_record->repositoryid)) {
67 $this->repository = repository::get_repository_by_id($file_record->repositoryid, SYSCONTEXTID);
68 if ($this->repository->supported_returntypes() & FILE_REFERENCE != FILE_REFERENCE) {
69 // Repository cannot do file reference.
70 throw new moodle_exception('error');
71 }
72 } else {
73 $this->repository = null;
74 }
75 }
76
77 /**
78 * Whether or not this is a external resource
79 *
80 * @return bool
81 */
82 public function is_external_file() {
83 return !empty($this->repository);
84 }
85
86 /**
87 * Update some file record fields
88 * NOTE: Must remain protected
89 *
90 * @param stdClass $dataobject
91 */
92 protected function update($dataobject) {
93 global $DB;
94 $keys = array_keys((array)$this->file_record);
95 foreach ($dataobject as $field => $value) {
96 if (in_array($field, $keys)) {
97 if ($field == 'contextid' and (!is_number($value) or $value < 1)) {
98 throw new file_exception('storedfileproblem', 'Invalid contextid');
99 }
100
101 if ($field == 'component') {
102 $value = clean_param($value, PARAM_COMPONENT);
103 if (empty($value)) {
104 throw new file_exception('storedfileproblem', 'Invalid component');
105 }
106 }
107
108 if ($field == 'filearea') {
109 $value = clean_param($value, PARAM_AREA);
110 if (empty($value)) {
111 throw new file_exception('storedfileproblem', 'Invalid filearea');
112 }
113 }
114
115 if ($field == 'itemid' and (!is_number($value) or $value < 0)) {
116 throw new file_exception('storedfileproblem', 'Invalid itemid');
117 }
118
119
120 if ($field == 'filepath') {
121 $value = clean_param($value, PARAM_PATH);
122 if (strpos($value, '/') !== 0 or strrpos($value, '/') !== strlen($value)-1) {
123 // path must start and end with '/'
124 throw new file_exception('storedfileproblem', 'Invalid file path');
125 }
126 }
127
128 if ($field == 'filename') {
fc4e8034
DC
129 // folder has filename == '.', so we pass this
130 if ($value != '.') {
131 $value = clean_param($value, PARAM_FILE);
132 }
67233725
DC
133 if ($value === '') {
134 throw new file_exception('storedfileproblem', 'Invalid file name');
135 }
136 }
137
138 if ($field === 'timecreated' or $field === 'timemodified') {
139 if (!is_number($value)) {
140 throw new file_exception('storedfileproblem', 'Invalid timestamp');
141 }
142 if ($value < 0) {
143 $value = 0;
144 }
145 }
146
147 if ($field == 'referencefileid' or $field == 'referencelastsync' or $field == 'referencelifetime') {
148 $value = clean_param($value, PARAM_INT);
149 }
150
151 // adding the field
152 $this->file_record->$field = $value;
153 } else {
154 throw new coding_exception("Invalid field name, $field doesn't exist in file record");
155 }
156 }
157 $DB->update_record('files', $this->file_record);
158 }
159
160 /**
161 * Rename filename
162 *
163 * @param string $filepath file path
164 * @param string $filename file name
165 */
166 public function rename($filepath, $filename) {
7051415c
DC
167 if ($this->fs->file_exists($this->get_contextid(), $this->get_component(), $this->get_filearea(), $this->get_itemid(), $filepath, $filename)) {
168 throw new file_exception('storedfilenotcreated', '', 'file exists, cannot rename');
169 }
67233725
DC
170 $filerecord = new stdClass;
171 $filerecord->filepath = $filepath;
172 $filerecord->filename = $filename;
173 // populate the pathname hash
174 $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);
175 $this->update($filerecord);
176 }
177
178 /**
179 * Replace the content by providing another stored_file instance
180 *
181 * @param stored_file $storedfile
182 */
183 public function replace_content_with(stored_file $storedfile) {
184 $contenthash = $storedfile->get_contenthash();
185 $this->set_contenthash($contenthash);
186 }
187
188 /**
189 * Delete file reference
190 *
191 */
192 public function delete_reference() {
193 global $DB;
194 // Remove repository info.
195 $this->repository = null;
196 unset($this->file_record->repositoryid);
197 unset($this->file_record->reference);
198 unset($this->file_record->referencelastsync);
199 unset($this->file_record->referencelifetime);
200
201 // Remove reference info from DB.
202 $DB->delete_records('files_reference', array('id'=>$this->file_record->referencefileid));
172dd12c 203 }
204
205 /**
206 * Is this a directory?
8496fdac
PS
207 *
208 * Directories are only emulated, internally they are stored as empty
209 * files with a "." instead of name - this means empty directory contains
210 * exactly one empty file with name dot.
211 *
212 * @return bool true means directory, false means file
172dd12c 213 */
214 public function is_directory() {
8496fdac 215 return ($this->file_record->filename === '.');
172dd12c 216 }
217
218 /**
8496fdac
PS
219 * Delete file from files table.
220 *
221 * The content of files stored in sha1 pool is reclaimed
222 * later - the occupied disk space is reclaimed much later.
223 *
224 * @return bool always true or exception if error occurred
172dd12c 225 */
226 public function delete() {
227 global $DB;
67233725
DC
228 // If other files referring to this file, we need convert them
229 if ($files = $this->fs->get_references_by_storedfile($this)) {
230 foreach ($files as $file) {
231 $this->fs->import_external_file($file);
232 }
233 }
234 // Now delete file records in DB
1aa01caf 235 $DB->delete_records('files', array('id'=>$this->file_record->id));
67233725 236 $DB->delete_records('files_reference', array('id'=>$this->file_record->referencefileid));
1aa01caf 237 // moves pool file to trash if content not needed any more
238 $this->fs->deleted_file_cleanup($this->file_record->contenthash);
8496fdac 239 return true; // BC only
172dd12c 240 }
241
242 /**
8496fdac
PS
243 * Protected - developers must not gain direct access to this function.
244 *
17d9269f 245 * NOTE: do not make this public, we must not modify or delete the pool files directly! ;-)
8496fdac
PS
246 *
247 * @return string full path to pool file with file content
172dd12c 248 **/
249 protected function get_content_file_location() {
67233725
DC
250 $this->sync_external_file();
251 // Detect is local file or not.
17d9269f 252 $contenthash = $this->file_record->contenthash;
253 $l1 = $contenthash[0].$contenthash[1];
254 $l2 = $contenthash[2].$contenthash[3];
67233725 255 $path = "$this->filedir/$l1/$l2/$contenthash";
693ef3a8 256 return "$this->filedir/$l1/$l2/$contenthash";
172dd12c 257 }
258
5035a8b4 259 /**
260 * adds this file path to a curl request (POST only)
261 *
262 * @param curl $curlrequest the curl request object
263 * @param string $key what key to use in the POST request
8496fdac 264 * @return void
5035a8b4 265 */
266 public function add_to_curl_request(&$curlrequest, $key) {
267 $curlrequest->_tmp_file_post_params[$key] = '@' . $this->get_content_file_location();
268 }
269
172dd12c 270 /**
271 * Returns file handle - read only mode, no writing allowed into pool files!
8496fdac
PS
272 *
273 * When you want to modify a file, create a new file and delete the old one.
274 *
275 * @return resource file handle
172dd12c 276 */
277 public function get_content_file_handle() {
278 $path = $this->get_content_file_location();
279 if (!is_readable($path)) {
1aa01caf 280 if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
d610cb89 281 throw new file_exception('storedfilecannotread', '', $path);
1aa01caf 282 }
172dd12c 283 }
67233725 284 return fopen($path, 'rb'); // Binary reading only!!
172dd12c 285 }
286
287 /**
8496fdac 288 * Dumps file content to page.
172dd12c 289 */
290 public function readfile() {
291 $path = $this->get_content_file_location();
292 if (!is_readable($path)) {
1aa01caf 293 if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
d610cb89 294 throw new file_exception('storedfilecannotread', '', $path);
1aa01caf 295 }
172dd12c 296 }
297 readfile($path);
298 }
299
300 /**
8496fdac
PS
301 * Returns file content as string.
302 *
172dd12c 303 * @return string content
304 */
305 public function get_content() {
306 $path = $this->get_content_file_location();
307 if (!is_readable($path)) {
1aa01caf 308 if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
d610cb89 309 throw new file_exception('storedfilecannotread', '', $path);
1aa01caf 310 }
172dd12c 311 }
312 return file_get_contents($this->get_content_file_location());
313 }
314
6c0e2d08 315 /**
8496fdac
PS
316 * Copy content of file to given pathname.
317 *
318 * @param string $pathname real path to the new file
6c0e2d08 319 * @return bool success
320 */
321 public function copy_content_to($pathname) {
322 $path = $this->get_content_file_location();
323 if (!is_readable($path)) {
1aa01caf 324 if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
d610cb89 325 throw new file_exception('storedfilecannotread', '', $path);
1aa01caf 326 }
6c0e2d08 327 }
328 return copy($path, $pathname);
329 }
330
17d9269f 331 /**
8496fdac
PS
332 * List contents of archive.
333 *
d2b7803e 334 * @param file_packer $packer file packer instance
c78a0558 335 * @return array of file infos
336 */
337 public function list_files(file_packer $packer) {
338 $archivefile = $this->get_content_file_location();
339 return $packer->list_files($archivefile);
340 }
341
342 /**
8496fdac
PS
343 * Extract file to given file path (real OS filesystem), existing files are overwritten.
344 *
d2b7803e 345 * @param file_packer $packer file packer instance
0b0bfa93 346 * @param string $pathname target directory
8496fdac 347 * @return array|bool list of processed files; false if error
17d9269f 348 */
0b0bfa93 349 public function extract_to_pathname(file_packer $packer, $pathname) {
350 $archivefile = $this->get_content_file_location();
351 return $packer->extract_to_pathname($archivefile, $pathname);
17d9269f 352 }
353
354 /**
8496fdac
PS
355 * Extract file to given file path (real OS filesystem), existing files are overwritten.
356 *
d2b7803e
DC
357 * @param file_packer $packer file packer instance
358 * @param int $contextid context ID
359 * @param string $component component
360 * @param string $filearea file area
361 * @param int $itemid item ID
362 * @param string $pathbase path base
363 * @param int $userid user ID
8496fdac 364 * @return array|bool list of processed files; false if error
17d9269f 365 */
64f93798 366 public function extract_to_storage(file_packer $packer, $contextid, $component, $filearea, $itemid, $pathbase, $userid = NULL) {
0b0bfa93 367 $archivefile = $this->get_content_file_location();
64f93798 368 return $packer->extract_to_storage($archivefile, $contextid, $component, $filearea, $itemid, $pathbase);
17d9269f 369 }
370
b1897a6d 371 /**
8496fdac
PS
372 * Add file/directory into archive.
373 *
d2b7803e 374 * @param file_archive $filearch file archive instance
c78a0558 375 * @param string $archivepath pathname in archive
b1897a6d 376 * @return bool success
377 */
0b0bfa93 378 public function archive_file(file_archive $filearch, $archivepath) {
b1897a6d 379 if ($this->is_directory()) {
0b0bfa93 380 return $filearch->add_directory($archivepath);
b1897a6d 381 } else {
382 $path = $this->get_content_file_location();
383 if (!is_readable($path)) {
384 return false;
385 }
0b0bfa93 386 return $filearch->add_file_from_pathname($archivepath, $path);
b1897a6d 387 }
388 }
389
797f19e8 390 /**
391 * Returns information about image,
392 * information is determined from the file content
d2b7803e 393 *
797f19e8 394 * @return mixed array with width, height and mimetype; false if not an image
395 */
396 public function get_imageinfo() {
b7725e30
MG
397 $path = $this->get_content_file_location();
398 if (!is_readable($path)) {
399 if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
400 throw new file_exception('storedfilecannotread', '', $path);
401 }
402 }
403 $mimetype = $this->get_mimetype();
404 if (!preg_match('|^image/|', $mimetype) || !filesize($path) || !($imageinfo = getimagesize($path))) {
797f19e8 405 return false;
406 }
407 $image = array('width'=>$imageinfo[0], 'height'=>$imageinfo[1], 'mimetype'=>image_type_to_mime_type($imageinfo[2]));
408 if (empty($image['width']) or empty($image['height']) or empty($image['mimetype'])) {
409 // gd can not parse it, sorry
410 return false;
411 }
412 return $image;
413 }
414
415 /**
416 * Verifies the file is a valid web image - gif, png and jpeg only.
8496fdac 417 *
797f19e8 418 * It should be ok to serve this image from server without any other security workarounds.
8496fdac 419 *
797f19e8 420 * @return bool true if file ok
421 */
422 public function is_valid_image() {
423 $mimetype = $this->get_mimetype();
424 if ($mimetype !== 'image/gif' and $mimetype !== 'image/jpeg' and $mimetype !== 'image/png') {
425 return false;
426 }
427 if (!$info = $this->get_imageinfo()) {
428 return false;
429 }
430 if ($info['mimetype'] !== $mimetype) {
431 return false;
432 }
433 // ok, GD likes this image
434 return true;
435 }
436
4b6b5ce7 437 /**
8496fdac
PS
438 * Returns parent directory, creates missing parents if needed.
439 *
440 * @return stored_file
4b6b5ce7 441 */
442 public function get_parent_directory() {
443 if ($this->file_record->filepath === '/' and $this->file_record->filename === '.') {
444 //root dir does not have parent
445 return null;
446 }
447
448 if ($this->file_record->filename !== '.') {
64f93798 449 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);
4b6b5ce7 450 }
451
452 $filepath = $this->file_record->filepath;
453 $filepath = trim($filepath, '/');
454 $dirs = explode('/', $filepath);
455 array_pop($dirs);
456 $filepath = implode('/', $dirs);
457 $filepath = ($filepath === '') ? '/' : "/$filepath/";
458
64f93798 459 return $this->fs->create_directory($this->file_record->contextid, $this->file_record->component, $this->file_record->filearea, $this->file_record->itemid, $filepath);
4b6b5ce7 460 }
461
16a95e8f 462 /**
67233725
DC
463 * Sync external files
464 *
465 * @return bool true if file content changed, false if not
466 */
467 public function sync_external_file() {
468 global $CFG, $DB;
469 if (empty($this->file_record->referencefileid)) {
470 return false;
471 }
472 if (empty($this->file_record->referencelastsync) or ($this->file_record->referencelastsync + $this->file_record->referencelifetime < time())) {
473 require_once($CFG->dirroot.'/repository/lib.php');
474 if (repository::sync_external_file($this)) {
475 $prevcontent = $this->file_record->contenthash;
476 $sql = "SELECT f.*, r.repositoryid, r.reference
477 FROM {files} f
478 LEFT JOIN {files_reference} r
479 ON f.referencefileid = r.id
480 WHERE f.id = ?";
481 $this->file_record = $DB->get_record_sql($sql, array($this->file_record->id), MUST_EXIST);
482 return ($prevcontent !== $this->file_record->contenthash);
483 }
484 }
485 return false;
486 }
487
488 /**
489 * Returns context id of the file
8496fdac 490 *
16a95e8f 491 * @return int context id
492 */
172dd12c 493 public function get_contextid() {
494 return $this->file_record->contextid;
495 }
496
16a95e8f 497 /**
64f93798
PS
498 * Returns component name - this is the owner of the areas,
499 * nothing else is allowed to read or modify the files directly!!
500 *
501 * @return string
502 */
503 public function get_component() {
504 return $this->file_record->component;
505 }
506
507 /**
508 * Returns file area name, this divides files of one component into groups with different access control.
509 * All files in one area have the same access control.
8496fdac 510 *
16a95e8f 511 * @return string
512 */
172dd12c 513 public function get_filearea() {
514 return $this->file_record->filearea;
515 }
516
16a95e8f 517 /**
8496fdac
PS
518 * Returns returns item id of file.
519 *
16a95e8f 520 * @return int
521 */
172dd12c 522 public function get_itemid() {
523 return $this->file_record->itemid;
524 }
525
16a95e8f 526 /**
527 * Returns file path - starts and ends with /, \ are not allowed.
8496fdac 528 *
16a95e8f 529 * @return string
530 */
172dd12c 531 public function get_filepath() {
532 return $this->file_record->filepath;
533 }
534
16a95e8f 535 /**
536 * Returns file name or '.' in case of directories.
8496fdac 537 *
16a95e8f 538 * @return string
539 */
172dd12c 540 public function get_filename() {
541 return $this->file_record->filename;
542 }
543
16a95e8f 544 /**
545 * Returns id of user who created the file.
8496fdac 546 *
16a95e8f 547 * @return int
548 */
172dd12c 549 public function get_userid() {
550 return $this->file_record->userid;
551 }
552
16a95e8f 553 /**
554 * Returns the size of file in bytes.
8496fdac 555 *
16a95e8f 556 * @return int bytes
557 */
172dd12c 558 public function get_filesize() {
67233725 559 $this->sync_external_file();
172dd12c 560 return $this->file_record->filesize;
561 }
562
16a95e8f 563 /**
8496fdac
PS
564 * Returns mime type of file.
565 *
16a95e8f 566 * @return string
567 */
172dd12c 568 public function get_mimetype() {
569 return $this->file_record->mimetype;
570 }
571
16a95e8f 572 /**
8496fdac
PS
573 * Returns unix timestamp of file creation date.
574 *
16a95e8f 575 * @return int
576 */
172dd12c 577 public function get_timecreated() {
578 return $this->file_record->timecreated;
579 }
580
16a95e8f 581 /**
8496fdac
PS
582 * Returns unix timestamp of last file modification.
583 *
16a95e8f 584 * @return int
585 */
172dd12c 586 public function get_timemodified() {
67233725 587 $this->sync_external_file();
172dd12c 588 return $this->file_record->timemodified;
589 }
6c0e2d08 590
67233725
DC
591 /**
592 * set timemodified
593 *
594 * @param int $timemodified
595 */
596 public function set_timemodified($timemodified) {
597 $filerecord = new stdClass;
598 $filerecord->timemodified = $timemodified;
599 $this->update($filerecord);
600 }
601
16a95e8f 602 /**
8496fdac
PS
603 * Returns file status flag.
604 *
16a95e8f 605 * @return int 0 means file OK, anything else is a problem and file can not be used
606 */
6c0e2d08 607 public function get_status() {
608 return $this->file_record->status;
609 }
ee03a651 610
16a95e8f 611 /**
8496fdac
PS
612 * Returns file id.
613 *
16a95e8f 614 * @return int
615 */
ee03a651 616 public function get_id() {
617 return $this->file_record->id;
618 }
4284e1cc 619
16a95e8f 620 /**
8496fdac
PS
621 * Returns sha1 hash of file content.
622 *
16a95e8f 623 * @return string
624 */
4284e1cc 625 public function get_contenthash() {
67233725 626 $this->sync_external_file();
4284e1cc 627 return $this->file_record->contenthash;
628 }
6ed19c74 629
67233725
DC
630 /**
631 * Set contenthash
632 *
633 * @param string $contenthash
634 */
635 protected function set_contenthash($contenthash) {
636 // make sure the content exists in moodle file pool
637 if ($this->fs->content_exists($contenthash)) {
638 $filerecord = new stdClass;
639 $filerecord->contenthash = $contenthash;
640 $this->update($filerecord);
641 } else {
642 throw new file_exception('storedfileproblem', 'Invalid contenthash, content must be already in filepool', $contenthash);
643 }
644 }
645
16a95e8f 646 /**
64f93798 647 * Returns sha1 hash of all file path components sha1("contextid/component/filearea/itemid/dir/dir/filename.ext").
8496fdac 648 *
16a95e8f 649 * @return string
650 */
6ed19c74 651 public function get_pathnamehash() {
652 return $this->file_record->pathnamehash;
653 }
1dce6261
DC
654
655 /**
8496fdac
PS
656 * Returns the license type of the file, it is a short name referred from license table.
657 *
1dce6261
DC
658 * @return string
659 */
660 public function get_license() {
661 return $this->file_record->license;
662 }
663
67233725
DC
664 /**
665 * Set license
666 *
667 * @param string $license license
668 */
669 public function set_license($license) {
670 $filerecord = new stdClass;
671 $filerecord->license = $license;
672 $this->update($filerecord);
673 }
674
1dce6261 675 /**
8496fdac
PS
676 * Returns the author name of the file.
677 *
1dce6261
DC
678 * @return string
679 */
680 public function get_author() {
31cd5fe8 681 return $this->file_record->author;
1dce6261
DC
682 }
683
67233725
DC
684 /**
685 * Set author
686 *
687 * @param string $author
688 */
689 public function set_author($author) {
690 $filerecord = new stdClass;
691 $filerecord->author = $author;
692 $this->update($filerecord);
693 }
694
1dce6261 695 /**
8496fdac
PS
696 * Returns the source of the file, usually it is a url.
697 *
1dce6261
DC
698 * @return string
699 */
700 public function get_source() {
701 return $this->file_record->source;
702 }
8496fdac 703
67233725
DC
704 /**
705 * Set license
706 *
707 * @param string $license license
708 */
709 public function set_source($source) {
710 $filerecord = new stdClass;
711 $filerecord->source = $source;
712 $this->update($filerecord);
713 }
714
715
f79321f1
DC
716 /**
717 * Returns the sort order of file
718 *
719 * @return int
720 */
721 public function get_sortorder() {
722 return $this->file_record->sortorder;
723 }
67233725
DC
724
725 /**
726 * Set file sort order
727 *
728 * @param int $sortorder
729 * @return int
730 */
731 public function set_sortorder($sortorder) {
732 $filerecord = new stdClass;
733 $filerecord->sortorder = $sortorder;
734 $this->update($filerecord);
735 }
736
737 /**
738 * Returns repository id
739 *
740 * @return int|null
741 */
742 public function get_repository_id() {
743 if (!empty($this->repository)) {
744 return $this->repository->id;
745 } else {
746 return null;
747 }
748 }
749
750 /**
751 * get reference file id
752 * @return int
753 */
754 public function get_referencefileid() {
755 return $this->file_record->referencefileid;
756 }
757
758 /**
759 * Get reference last sync time
760 * @return int
761 */
762 public function get_referencelastsync() {
763 return $this->file_record->referencelastsync;
764 }
765
766 /**
767 * Get reference last sync time
768 * @return int
769 */
770 public function get_referencelifetime() {
771 return $this->file_record->referencelifetime;
772 }
773 /**
774 * Returns file reference
775 *
776 * @return string
777 */
778 public function get_reference() {
779 return $this->file_record->reference;
780 }
781
782 /**
783 * Get human readable file reference information
784 *
785 * @return string
786 */
787 public function get_reference_details() {
788 return $this->repository->get_reference_details($this->get_reference());
789 }
790
791 /**
792 * Send file references
793 *
794 * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours)
795 * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only
796 * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin
797 * @param array $options additional options affecting the file serving
798 */
799 public function send_file($lifetime, $filter, $forcedownload, $options) {
800 $this->repository->send_file($this, $lifetime, $filter, $forcedownload, $options);
801 }
f79321f1 802}