MDL-14589 fixed incorect php docs return type
[moodle.git] / lib / file / stored_file.php
CommitLineData
16a95e8f 1<?php
2
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.
14//
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/>.
17
18
19/**
20 * Class representing filesin Moodle file storage.
21 *
64a19b38 22 * @package moodlecore
23 * @subpackage file-storage
24 * @copyright 2008 Petr Skoda (http://skodak.org)
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
16a95e8f 26 */
27
28require_once("$CFG->libdir/file/stored_file.php");
172dd12c 29
30/**
31 * Class representing local files stored in sha1 file pool
32 */
33class stored_file {
34 private $fs;
35 private $file_record;
36
37 /**
38 * Constructor
39 * @param object $fs file storage instance
40 * @param object $file_record description of file
41 */
42 public function __construct($fs, $file_record) {
43 $this->fs = $fs;
44 $this->file_record = clone($file_record);
45 }
46
47 /**
48 * Is this a directory?
49 * @return bool
50 */
51 public function is_directory() {
52 return $this->file_record->filename === '.';
53 }
54
55 /**
56 * Delete file
1aa01caf 57 * @return bool success
172dd12c 58 */
59 public function delete() {
60 global $DB;
1aa01caf 61 $DB->delete_records('files', array('id'=>$this->file_record->id));
62 // moves pool file to trash if content not needed any more
63 $this->fs->deleted_file_cleanup($this->file_record->contenthash);
64 return true;
172dd12c 65 }
66
67 /**
6c0e2d08 68 * Protected - developers must not gain direct access to this function
17d9269f 69 * NOTE: do not make this public, we must not modify or delete the pool files directly! ;-)
70 * @return ful path to pool file with file content
172dd12c 71 **/
72 protected function get_content_file_location() {
744b64ff 73 $filedir = $this->fs->get_filedir();
17d9269f 74 $contenthash = $this->file_record->contenthash;
75 $l1 = $contenthash[0].$contenthash[1];
76 $l2 = $contenthash[2].$contenthash[3];
77 $l3 = $contenthash[4].$contenthash[5];
78 return "$filedir/$l1/$l2/$l3/$contenthash";
172dd12c 79 }
80
5035a8b4 81 /**
82 * adds this file path to a curl request (POST only)
83 *
84 * @param curl $curlrequest the curl request object
85 * @param string $key what key to use in the POST request
86 */
87 public function add_to_curl_request(&$curlrequest, $key) {
88 $curlrequest->_tmp_file_post_params[$key] = '@' . $this->get_content_file_location();
89 }
90
172dd12c 91 /**
92 * Returns file handle - read only mode, no writing allowed into pool files!
93 * @return file handle
94 */
95 public function get_content_file_handle() {
96 $path = $this->get_content_file_location();
97 if (!is_readable($path)) {
1aa01caf 98 if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
99 throw new file_exception('storedfilecannotread');
100 }
172dd12c 101 }
102 return fopen($path, 'rb'); //binary reading only!!
103 }
104
105 /**
106 * Dumps file content to page
107 * @return file handle
108 */
109 public function readfile() {
110 $path = $this->get_content_file_location();
111 if (!is_readable($path)) {
1aa01caf 112 if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
113 throw new file_exception('storedfilecannotread');
114 }
172dd12c 115 }
116 readfile($path);
117 }
118
119 /**
120 * Returns file content as string
121 * @return string content
122 */
123 public function get_content() {
124 $path = $this->get_content_file_location();
125 if (!is_readable($path)) {
1aa01caf 126 if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
127 throw new file_exception('storedfilecannotread');
128 }
172dd12c 129 }
130 return file_get_contents($this->get_content_file_location());
131 }
132
6c0e2d08 133 /**
134 * Copy content of file to give npathname
17d9269f 135 * @param string $pathnema rela path to new file
6c0e2d08 136 * @return bool success
137 */
138 public function copy_content_to($pathname) {
139 $path = $this->get_content_file_location();
140 if (!is_readable($path)) {
1aa01caf 141 if (!$this->fs->try_content_recovery($this) or !is_readable($path)) {
142 throw new file_exception('storedfilecannotread');
143 }
6c0e2d08 144 }
145 return copy($path, $pathname);
146 }
147
17d9269f 148 /**
c78a0558 149 * List contents of archive
150 * @param object $file_packer
151 * @return array of file infos
152 */
153 public function list_files(file_packer $packer) {
154 $archivefile = $this->get_content_file_location();
155 return $packer->list_files($archivefile);
156 }
157
158 /**
159 * Extract file to given file path (real OS filesystem), existing files are overwrited
0b0bfa93 160 * @param object $file_packer
161 * @param string $pathname target directory
17d9269f 162 * @return mixed list of processed files; false if error
163 */
0b0bfa93 164 public function extract_to_pathname(file_packer $packer, $pathname) {
165 $archivefile = $this->get_content_file_location();
166 return $packer->extract_to_pathname($archivefile, $pathname);
17d9269f 167 }
168
169 /**
c78a0558 170 * Extract file to given file path (real OS filesystem), existing files are overwrited
0b0bfa93 171 * @param object $file_packer
17d9269f 172 * @param int $contextid
173 * @param string $filearea
174 * @param int $itemid
175 * @param string $pathbase
176 * @param int $userid
177 * @return mixed list of processed files; false if error
178 */
0b0bfa93 179 public function extract_to_storage(file_packer $packer, $contextid, $filearea, $itemid, $pathbase, $userid=null) {
180 $archivefile = $this->get_content_file_location();
181 return $packer->extract_to_storage($archivefile, $contextid, $filearea, $itemid, $pathbase);
17d9269f 182 }
183
b1897a6d 184 /**
c78a0558 185 * Add file/directory into archive
186 * @param object $filearch
187 * @param string $archivepath pathname in archive
b1897a6d 188 * @return bool success
189 */
0b0bfa93 190 public function archive_file(file_archive $filearch, $archivepath) {
b1897a6d 191 if ($this->is_directory()) {
0b0bfa93 192 return $filearch->add_directory($archivepath);
b1897a6d 193 } else {
194 $path = $this->get_content_file_location();
195 if (!is_readable($path)) {
196 return false;
197 }
0b0bfa93 198 return $filearch->add_file_from_pathname($archivepath, $path);
b1897a6d 199 }
200 }
201
797f19e8 202 /**
203 * Returns information about image,
204 * information is determined from the file content
205 * @return mixed array with width, height and mimetype; false if not an image
206 */
207 public function get_imageinfo() {
208 if (!$imageinfo = getimagesize($this->get_content_file_location())) {
209 return false;
210 }
211 $image = array('width'=>$imageinfo[0], 'height'=>$imageinfo[1], 'mimetype'=>image_type_to_mime_type($imageinfo[2]));
212 if (empty($image['width']) or empty($image['height']) or empty($image['mimetype'])) {
213 // gd can not parse it, sorry
214 return false;
215 }
216 return $image;
217 }
218
219 /**
220 * Verifies the file is a valid web image - gif, png and jpeg only.
221 * It should be ok to serve this image from server without any other security workarounds.
222 * @return bool true if file ok
223 */
224 public function is_valid_image() {
225 $mimetype = $this->get_mimetype();
226 if ($mimetype !== 'image/gif' and $mimetype !== 'image/jpeg' and $mimetype !== 'image/png') {
227 return false;
228 }
229 if (!$info = $this->get_imageinfo()) {
230 return false;
231 }
232 if ($info['mimetype'] !== $mimetype) {
233 return false;
234 }
235 // ok, GD likes this image
236 return true;
237 }
238
4b6b5ce7 239 /**
240 * Returns parent directory, creates missing parents if needed
241 * @return object stored_file
242 */
243 public function get_parent_directory() {
244 if ($this->file_record->filepath === '/' and $this->file_record->filename === '.') {
245 //root dir does not have parent
246 return null;
247 }
248
249 if ($this->file_record->filename !== '.') {
250 return $this->fs->create_directory($this->file_record->contextid, $this->file_record->filearea, $this->file_record->itemid, $this->file_record->filepath);
251 }
252
253 $filepath = $this->file_record->filepath;
254 $filepath = trim($filepath, '/');
255 $dirs = explode('/', $filepath);
256 array_pop($dirs);
257 $filepath = implode('/', $dirs);
258 $filepath = ($filepath === '') ? '/' : "/$filepath/";
259
260 return $this->fs->create_directory($this->file_record->contextid, $this->file_record->filearea, $this->file_record->itemid, $filepath);
261 }
262
16a95e8f 263 /**
264 * Returns context id of the file
265 * @return int context id
266 */
172dd12c 267 public function get_contextid() {
268 return $this->file_record->contextid;
269 }
270
16a95e8f 271 /**
272 * Returns file area name, the areas do not have to be unique,
273 * but usually have form pluginname_typeofarea such as forum_attachments
274 * @return string
275 */
172dd12c 276 public function get_filearea() {
277 return $this->file_record->filearea;
278 }
279
16a95e8f 280 /**
281 * Returns returns item id of file
282 * @return int
283 */
172dd12c 284 public function get_itemid() {
285 return $this->file_record->itemid;
286 }
287
16a95e8f 288 /**
289 * Returns file path - starts and ends with /, \ are not allowed.
290 * @return string
291 */
172dd12c 292 public function get_filepath() {
293 return $this->file_record->filepath;
294 }
295
16a95e8f 296 /**
297 * Returns file name or '.' in case of directories.
298 * @return string
299 */
172dd12c 300 public function get_filename() {
301 return $this->file_record->filename;
302 }
303
16a95e8f 304 /**
305 * Returns id of user who created the file.
306 * @return int
307 */
172dd12c 308 public function get_userid() {
309 return $this->file_record->userid;
310 }
311
16a95e8f 312 /**
313 * Returns the size of file in bytes.
314 * @return int bytes
315 */
172dd12c 316 public function get_filesize() {
317 return $this->file_record->filesize;
318 }
319
16a95e8f 320 /**
321 * Returns mime type of file
322 * @return string
323 */
172dd12c 324 public function get_mimetype() {
325 return $this->file_record->mimetype;
326 }
327
16a95e8f 328 /**
329 * Returns unix timestamp of file creation date
330 * @return int
331 */
172dd12c 332 public function get_timecreated() {
333 return $this->file_record->timecreated;
334 }
335
16a95e8f 336 /**
337 * Returns unix timestamp of last file modification
338 * @return int
339 */
172dd12c 340 public function get_timemodified() {
341 return $this->file_record->timemodified;
342 }
6c0e2d08 343
16a95e8f 344 /**
345 * Returns file status flag
346 * @return int 0 means file OK, anything else is a problem and file can not be used
347 */
6c0e2d08 348 public function get_status() {
349 return $this->file_record->status;
350 }
ee03a651 351
16a95e8f 352 /**
353 * Returns file id
354 * @return int
355 */
ee03a651 356 public function get_id() {
357 return $this->file_record->id;
358 }
4284e1cc 359
16a95e8f 360 /**
361 * Returns sha1 hash of file content
362 * @return string
363 */
4284e1cc 364 public function get_contenthash() {
365 return $this->file_record->contenthash;
366 }
6ed19c74 367
16a95e8f 368 /**
369 * Returns sha1 hash of all file path components sha1(contextid/filearea/itemid/dir/dir/filename.ext)
370 * @return string
371 */
6ed19c74 372 public function get_pathnamehash() {
373 return $this->file_record->pathnamehash;
374 }
1dce6261
DC
375
376 /**
377 * Returns the license type of the file, it is a short name referred from license table
378 * @return string
379 */
380 public function get_license() {
381 return $this->file_record->license;
382 }
383
384 /**
385 * returns the author name of the file
386 * @return string
387 */
388 public function get_author() {
389 return $this->file_record->license;
390 }
391
392 /**
393 * Returns the source of the file, usually it is a url
394 * @return string
395 */
396 public function get_source() {
397 return $this->file_record->source;
398 }
172dd12c 399}