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