MDL-29248 backup: take rid of the setting and code handling the 'private' user filearea
[moodle.git] / lib / filebrowser / file_info_stored.php
blob104511948c9331d625825e1915402303ee3adb73
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
19 /**
20 * Utility class for browsing of stored files.
22 * @package core
23 * @subpackage filebrowser
24 * @copyright 2008 Petr Skoda (http://skodak.org)
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28 defined('MOODLE_INTERNAL') || die();
30 /**
31 * Represents an actual file or folder - a row in the file table -
32 * in the tree navigated by @see{file_browser}.
34 * @package core
35 * @subpackage filebrowser
36 * @copyright 2008 Petr Skoda (http://skodak.org)
37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 class file_info_stored extends file_info {
40 protected $lf;
41 protected $urlbase;
42 protected $topvisiblename;
43 protected $itemidused;
44 protected $readaccess;
45 protected $writeaccess;
46 protected $areaonly;
48 /**
49 * Constructor
51 * @param file_browser $browser
52 * @param stdClass $context
53 * @param stored_file|virtual_root_file $storedfile
54 * @param string $urlbase the serving script - usually the $CFG->wwwroot/.'pluginfile.php'
55 * @param string $topvisiblename the human readable name of this area
56 * @param int|bool $itemidused false if itemid always 0 and not included in URL
57 * @param bool $readaccess allow file reading
58 * @param bool $writeaccess allow file write, delete
59 * @param string $areaonly do not show links to parent context/area
61 public function __construct(file_browser $browser, $context, $storedfile, $urlbase, $topvisiblename, $itemidused, $readaccess, $writeaccess, $areaonly) {
62 parent::__construct($browser, $context);
64 $this->lf = $storedfile;
65 $this->urlbase = $urlbase;
66 $this->topvisiblename = $topvisiblename;
67 $this->itemidused = $itemidused;
68 $this->readaccess = $readaccess;
69 $this->writeaccess = $writeaccess;
70 $this->areaonly = $areaonly;
73 /**
74 * Returns list of standard virtual file/directory identification.
75 * The difference from stored_file parameters is that null values
76 * are allowed in all fields
77 * @return array with keys contextid, component, filearea, itemid, filepath and filename
79 public function get_params() {
80 return array('contextid'=>$this->context->id,
81 'component'=>$this->lf->get_component(),
82 'filearea' =>$this->lf->get_filearea(),
83 'itemid' =>$this->lf->get_itemid(),
84 'filepath' =>$this->lf->get_filepath(),
85 'filename' =>$this->lf->get_filename());
88 /**
89 * Returns localised visible name.
90 * @return string
92 public function get_visible_name() {
93 $filename = $this->lf->get_filename();
94 $filepath = $this->lf->get_filepath();
96 if ($filename !== '.') {
97 return $filename;
99 } else {
100 $dir = trim($filepath, '/');
101 $dir = explode('/', $dir);
102 $dir = array_pop($dir);
103 if ($dir === '') {
104 return $this->topvisiblename;
105 } else {
106 return $dir;
112 * Returns file download url
113 * @param bool $forcedownload
114 * @param bool $htts force https
115 * @return string url
117 public function get_url($forcedownload=false, $https=false) {
118 if (!$this->is_readable()) {
119 return null;
122 if ($this->is_directory()) {
123 return null;
126 $this->urlbase;
127 $contextid = $this->lf->get_contextid();
128 $component = $this->lf->get_component();
129 $filearea = $this->lf->get_filearea();
130 $itemid = $this->lf->get_itemid();
131 $filepath = $this->lf->get_filepath();
132 $filename = $this->lf->get_filename();
134 if ($this->itemidused) {
135 $path = '/'.$contextid.'/'.$component.'/'.$filearea.'/'.$itemid.$filepath.$filename;
136 } else {
137 $path = '/'.$contextid.'/'.$component.'/'.$filearea.$filepath.$filename;
139 return file_encode_url($this->urlbase, $path, $forcedownload, $https);
143 * Can I read content of this file or enter directory?
144 * @return bool
146 public function is_readable() {
147 return $this->readaccess;
151 * Can I add new files or directories?
152 * @return bool
154 public function is_writable() {
155 return $this->writeaccess;
159 * Is this top of empty area?
161 * @return bool
163 public function is_empty_area() {
164 if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') {
165 // test the emptiness only in the top most level, it does not make sense at lower levels
166 $fs = get_file_storage();
167 return $fs->is_area_empty($this->lf->get_contextid(), $this->lf->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid());
168 } else {
169 return false;
174 * Returns file size in bytes, null for directories
175 * @return int bytes or null if not known
177 public function get_filesize() {
178 return $this->lf->get_filesize();
182 * Returns mimetype
183 * @return string mimetype or null if not known
185 public function get_mimetype() {
186 return $this->lf->get_mimetype();
190 * Returns time created unix timestamp if known
191 * @return int timestamp or null
193 public function get_timecreated() {
194 return $this->lf->get_timecreated();
198 * Returns time modified unix timestamp if known
199 * @return int timestamp or null
201 public function get_timemodified() {
202 return $this->lf->get_timemodified();
206 * Is directory?
207 * @return bool
209 public function is_directory() {
210 return $this->lf->is_directory();
214 * Returns the license type of the file
215 * @return string license short name or null
217 public function get_license() {
218 return $this->lf->get_license();
222 * Returns the author name of the file
223 * @return string author name or null
225 public function get_author() {
226 return $this->lf->get_author();
230 * Returns the source of the file
231 * @return string a source url or null
233 public function get_source() {
234 return $this->lf->get_source();
238 * Returns the sort order of the file
239 * @return int
241 public function get_sortorder() {
242 return $this->lf->get_sortorder();
246 * Returns list of children.
247 * @return array of file_info instances
249 public function get_children() {
250 if (!$this->lf->is_directory()) {
251 return array();
254 $result = array();
255 $fs = get_file_storage();
257 $storedfiles = $fs->get_directory_files($this->context->id, $this->lf->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid(),
258 $this->lf->get_filepath(), false, true, "filepath, filename");
259 foreach ($storedfiles as $file) {
260 $result[] = new file_info_stored($this->browser, $this->context, $file, $this->urlbase, $this->topvisiblename,
261 $this->itemidused, $this->readaccess, $this->writeaccess, false);
264 return $result;
268 * Returns parent file_info instance
269 * @return file_info or null for root
271 public function get_parent() {
272 if ($this->lf->get_filepath() === '/' and $this->lf->is_directory()) {
273 if ($this->areaonly) {
274 return null;
275 } else if ($this->itemidused) {
276 return $this->browser->get_file_info($this->context, $this->lf->get_component(), $this->lf->get_filearea());
277 } else {
278 return $this->browser->get_file_info($this->context);
282 if (!$this->lf->is_directory()) {
283 return $this->browser->get_file_info($this->context, $this->lf->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid(), $this->lf->get_filepath(), '.');
286 $filepath = $this->lf->get_filepath();
287 $filepath = trim($filepath, '/');
288 $dirs = explode('/', $filepath);
289 array_pop($dirs);
290 $filepath = implode('/', $dirs);
291 $filepath = ($filepath === '') ? '/' : "/$filepath/";
293 return $this->browser->get_file_info($this->context, $this->lf->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid(), $filepath, '.');
297 * Create new directory, may throw exception - make sure
298 * params are valid.
299 * @param string $newdirname name of new directory
300 * @param int id of author, default $USER->id
301 * @return file_info new directory
303 public function create_directory($newdirname, $userid = NULL) {
304 if (!$this->is_writable() or !$this->lf->is_directory()) {
305 return null;
308 $newdirname = clean_param($newdirname, PARAM_FILE);
309 if ($newdirname === '') {
310 return null;
313 $filepath = $this->lf->get_filepath().'/'.$newdirname.'/';
315 $fs = get_file_storage();
317 if ($file = $fs->create_directory($this->lf->get_contextid(), $this->lf->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid(), $filepath, $userid)) {
318 return $this->browser->get_file_info($this->context, $this->lf->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
320 return null;
325 * Create new file from string - make sure
326 * params are valid.
327 * @param string $newfilename name of new file
328 * @param string $content of file
329 * @param int id of author, default $USER->id
330 * @return file_info new file
332 public function create_file_from_string($newfilename, $content, $userid = NULL) {
333 if (!$this->is_writable() or !$this->lf->is_directory()) {
334 return null;
337 $newfilename = clean_param($newfilename, PARAM_FILE);
338 if ($newfilename === '') {
339 return null;
342 $fs = get_file_storage();
344 $now = time();
346 $newrecord = new stdClass();
347 $newrecord->contextid = $this->lf->get_contextid();
348 $newrecord->component = $this->lf->get_component();
349 $newrecord->filearea = $this->lf->get_filearea();
350 $newrecord->itemid = $this->lf->get_itemid();
351 $newrecord->filepath = $this->lf->get_filepath();
352 $newrecord->filename = $newfilename;
354 if ($fs->file_exists($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename)) {
355 // file already exists, sorry
356 return null;
359 $newrecord->timecreated = $now;
360 $newrecord->timemodified = $now;
361 $newrecord->mimetype = mimeinfo('type', $newfilename);
362 $newrecord->userid = $userid;
364 if ($file = $fs->create_file_from_string($newrecord, $content)) {
365 return $this->browser->get_file_info($this->context, $file->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
367 return null;
371 * Create new file from pathname - make sure
372 * params are valid.
373 * @param string $newfilename name of new file
374 * @param string $pathname location of file
375 * @param int id of author, default $USER->id
376 * @return file_info new file
378 public function create_file_from_pathname($newfilename, $pathname, $userid = NULL) {
379 if (!$this->is_writable() or !$this->lf->is_directory()) {
380 return null;
383 $newfilename = clean_param($newfilename, PARAM_FILE);
384 if ($newfilename === '') {
385 return null;
388 $fs = get_file_storage();
390 $now = time();
392 $newrecord = new stdClass();
393 $newrecord->contextid = $this->lf->get_contextid();
394 $newrecord->component = $this->lf->get_component();
395 $newrecord->filearea = $this->lf->get_filearea();
396 $newrecord->itemid = $this->lf->get_itemid();
397 $newrecord->filepath = $this->lf->get_filepath();
398 $newrecord->filename = $newfilename;
400 if ($fs->file_exists($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename)) {
401 // file already exists, sorry
402 return null;
405 $newrecord->timecreated = $now;
406 $newrecord->timemodified = $now;
407 $newrecord->mimetype = mimeinfo('type', $newfilename);
408 $newrecord->userid = $userid;
410 if ($file = $fs->create_file_from_pathname($newrecord, $pathname)) {
411 return $this->browser->get_file_info($this->context, $file->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
413 return null;
417 * Create new file from stored file - make sure
418 * params are valid.
419 * @param string $newfilename name of new file
420 * @param mixed file id or stored_file of file
421 * @param int id of author, default $USER->id
422 * @return file_info new file
424 public function create_file_from_storedfile($newfilename, $fid, $userid = NULL) {
425 if (!$this->is_writable() or $this->lf->get_filename() !== '.') {
426 return null;
429 $newfilename = clean_param($newfilename, PARAM_FILE);
430 if ($newfilename === '') {
431 return null;
434 $fs = get_file_storage();
436 $now = time();
438 $newrecord = new stdClass();
439 $newrecord->contextid = $this->lf->get_contextid();
440 $newrecord->component = $this->lf->get_component();
441 $newrecord->filearea = $this->lf->get_filearea();
442 $newrecord->itemid = $this->lf->get_itemid();
443 $newrecord->filepath = $this->lf->get_filepath();
444 $newrecord->filename = $newfilename;
446 if ($fs->file_exists($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename)) {
447 // file already exists, sorry
448 return null;
451 $newrecord->timecreated = $now;
452 $newrecord->timemodified = $now;
453 $newrecord->mimetype = mimeinfo('type', $newfilename);
454 $newrecord->userid = $userid;
456 if ($file = $fs->create_file_from_storedfile($newrecord, $fid)) {
457 return $this->browser->get_file_info($this->context, $file->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
459 return null;
463 * Delete file, make sure file is deletable first.
464 * @return bool success
466 public function delete() {
467 if (!$this->is_writable()) {
468 return false;
471 if ($this->is_directory()) {
472 $filepath = $this->lf->get_filepath();
473 $fs = get_file_storage();
474 $storedfiles = $fs->get_area_files($this->context->id, $this->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid(), "");
475 foreach ($storedfiles as $file) {
476 if (strpos($file->get_filepath(), $filepath) === 0) {
477 $file->delete();
482 return $this->lf->delete();
486 * Copy content of this file to local storage, overriding current file if needed.
487 * @param int $contextid
488 * @param string $filearea
489 * @param int $itemid
490 * @param string $filepath
491 * @param string $filename
492 * @return boolean success
494 public function copy_to_storage($contextid, $component, $filearea, $itemid, $filepath, $filename) {
495 if (!$this->is_readable() or $this->is_directory()) {
496 return false;
499 $fs = get_file_storage();
500 if ($existing = $fs->get_file($contextid, $component, $filearea, $itemid, $filepath, $filename)) {
501 $existing->delete();
503 $file_record = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath, 'filename'=>$filename);
504 $fs->create_file_from_storedfile($file_record, $this->lf);
506 return true;
510 * Copy content of this file to local storage, overriding current file if needed.
511 * @param string $pathname real local full file name
512 * @return boolean success
514 public function copy_to_pathname($pathname) {
515 if (!$this->is_readable() or $this->is_directory()) {
516 return false;
519 if (file_exists($pathname)) {
520 if (!unlink($pathname)) {
521 return false;
525 $this->lf->copy_content_to($pathname);
527 return true;