MDL-42701 Bump all versions near 2.6 release
[moodle.git] / lib / filebrowser / file_info.php
blobb7dcc46b47cae4d47ad8757a3080792c92fe3391
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.
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/>.
18 /**
19 * Base for all file browsing classes.
21 * @package core_files
22 * @copyright 2008 Petr Skoda (http://skodak.org)
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
28 /**
29 * Base class for things in the tree navigated by {@link file_browser}.
31 * @package core_files
32 * @copyright 2008 Petr Skoda (http://skodak.org)
33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35 abstract class file_info {
37 /** @var stdClass File context */
38 protected $context;
40 /** @var file_browser File browser instance */
41 protected $browser;
43 /**
44 * Constructor
46 * @param file_browser $browser file_browser instance
47 * @param stdClass $context
49 public function __construct($browser, $context) {
50 $this->browser = $browser;
51 $this->context = $context;
54 /**
55 * Returns list of standard virtual file/directory identification.
56 * The difference from stored_file parameters is that null values
57 * are allowed in all fields
59 * @return array with keys contextid, component, filearea, itemid, filepath and filename
61 public function get_params() {
62 return array('contextid' => $this->context->id,
63 'component' => null,
64 'filearea' => null,
65 'itemid' => null,
66 'filepath' => null,
67 'filename' => null);
70 /**
71 * Returns localised visible name.
73 * @return string
75 public abstract function get_visible_name();
77 /**
78 * Whether or not this is a directory
80 * @return bool
82 public abstract function is_directory();
84 /**
85 * Returns list of children.
87 * @return array of file_info instances
89 public abstract function get_children();
91 /**
92 * Builds SQL sub query (WHERE clause) for selecting files with the specified extensions
94 * If $extensions == '*' (any file), the result is array('', array())
95 * otherwise the result is something like array('AND filename ...', array(...))
97 * @param string|array $extensions - either '*' or array of lowercase extensions, i.e. array('.gif','.jpg')
98 * @param string $prefix prefix for DB table files in the query (empty by default)
99 * @return array of two elements: $sql - sql where clause and $params - array of parameters
101 protected function build_search_files_sql($extensions, $prefix = null) {
102 global $DB;
103 if (strlen($prefix)) {
104 $prefix = $prefix.'.';
105 } else {
106 $prefix = '';
108 $sql = '';
109 $params = array();
110 if (is_array($extensions) && !in_array('*', $extensions)) {
111 $likes = array();
112 $cnt = 0;
113 foreach ($extensions as $ext) {
114 $cnt++;
115 $likes[] = $DB->sql_like($prefix.'filename', ':filename'.$cnt, false);
116 $params['filename'.$cnt] = '%'.$ext;
118 $sql .= ' AND (' . join(' OR ', $likes) . ')';
120 return array($sql, $params);
124 * Returns list of children which are either files matching the specified extensions
125 * or folders that contain at least one such file.
127 * It is recommended to overwrite this function so it uses a proper SQL
128 * query and does not create unnecessary file_info objects (might require a lot of time
129 * and memory usage on big sites).
131 * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg')
132 * @return array of file_info instances
134 public function get_non_empty_children($extensions = '*') {
135 $list = $this->get_children();
136 $nonemptylist = array();
137 foreach ($list as $fileinfo) {
138 if ($fileinfo->is_directory()) {
139 if ($fileinfo->count_non_empty_children($extensions)) {
140 $nonemptylist[] = $fileinfo;
142 } else if ($extensions === '*') {
143 $nonemptylist[] = $fileinfo;
144 } else {
145 $filename = $fileinfo->get_visible_name();
146 $extension = core_text::strtolower(pathinfo($filename, PATHINFO_EXTENSION));
147 if (!empty($extension) && in_array('.' . $extension, $extensions)) {
148 $nonemptylist[] = $fileinfo;
152 return $nonemptylist;
156 * Returns the number of children which are either files matching the specified extensions
157 * or folders containing at least one such file.
159 * We usually don't need the exact number of non empty children if it is >=2 (see param $limit)
160 * This function is used by repository_local to evaluate if the folder is empty. But
161 * it also can be used to check if folder has only one subfolder because in some cases
162 * this subfolder can be skipped.
164 * It is strongly recommended to overwrite this function so it uses a proper SQL
165 * query and does not create file_info objects (later might require a lot of time
166 * and memory usage on big sites).
168 * @param string|array $extensions, for example '*' or array('.gif','.jpg')
169 * @param int $limit stop counting after at least $limit non-empty children are found
170 * @return int
172 public function count_non_empty_children($extensions = '*', $limit = 1) {
173 $list = $this->get_children();
174 $cnt = 0;
175 // first loop through files
176 foreach ($list as $fileinfo) {
177 if (!$fileinfo->is_directory()) {
178 if ($extensions !== '*') {
179 $filename = $fileinfo->get_visible_name();
180 $extension = core_text::strtolower(pathinfo($filename, PATHINFO_EXTENSION));
181 if (empty($extension) || !in_array('.' . $extension, $extensions)) {
182 continue;
185 if ((++$cnt) >= $limit) {
186 return $cnt;
190 // now loop through directories
191 foreach ($list as $fileinfo) {
192 if ($fileinfo->is_directory() && $fileinfo->count_non_empty_children($extensions)) {
193 if ((++$cnt) >= $limit) {
194 return $cnt;
198 return $cnt;
202 * Returns parent file_info instance
204 * @return file_info or null for root
206 public abstract function get_parent();
209 * Returns array of url encoded params.
211 * @return array with numeric keys
213 public function get_params_rawencoded() {
214 $params = $this->get_params();
215 $encoded = array();
216 $encoded[] = 'contextid=' . $params['contextid'];
217 $encoded[] = 'component=' . $params['component'];
218 $encoded[] = 'filearea=' . $params['filearea'];
219 $encoded[] = 'itemid=' . (is_null($params['itemid']) ? -1 : $params['itemid']);
220 $encoded[] = 'filepath=' . (is_null($params['filepath']) ? '' : rawurlencode($params['filepath']));
221 $encoded[] = 'filename=' . ((is_null($params['filename']) or $params['filename'] === '.') ? '' : rawurlencode($params['filename']));
223 return $encoded;
227 * Returns file download url
229 * @param bool $forcedownload whether or not force download
230 * @param bool $https whether or not force https
231 * @return string url
233 public function get_url($forcedownload=false, $https=false) {
234 return null;
238 * Whether or not I can read content of this file or enter directory
240 * @return bool
242 public function is_readable() {
243 return true;
247 * Whether or not new files or directories can be added
249 * @return bool
251 public function is_writable() {
252 return true;
256 * Is this info area and is it "empty"? Are there any files in subfolders?
258 * This is used mostly in repositories to reduce the
259 * number of empty folders. This method may be very slow,
260 * use with care.
262 * @return bool
264 public function is_empty_area() {
265 return false;
269 * Returns file size in bytes, null for directories
271 * @return int bytes or null if not known
273 public function get_filesize() {
274 return null;
278 * Returns mimetype
280 * @return string mimetype or null if not known
282 public function get_mimetype() {
283 return null;
287 * Returns time created unix timestamp if known
289 * @return int timestamp or null
291 public function get_timecreated() {
292 return null;
296 * Returns time modified unix timestamp if known
298 * @return int timestamp or null
300 public function get_timemodified() {
301 return null;
305 * Returns the license type of the file
306 * @return string license short name or null
308 public function get_license() {
309 return null;
313 * Returns the author name of the file
315 * @return string author name or null
317 public function get_author() {
318 return null;
322 * Returns the source of the file
324 * @return string a source url or null
326 public function get_source() {
327 return null;
331 * Returns the sort order of the file
333 * @return int
335 public function get_sortorder() {
336 return 0;
340 * Whether or not this is a external resource
342 * @return bool
344 public function is_external_file() {
345 return false;
349 * Returns file status flag.
351 * @return int 0 means file OK, anything else is a problem and file can not be used
353 public function get_status() {
354 return 0;
358 * Returns the localised human-readable name of the file together with virtual path
360 * @see file_info_stored::get_readable_fullname()
361 * @return string
363 public function get_readable_fullname() {
364 return null;
368 * Create new directory, may throw exception - make sure
369 * params are valid.
371 * @param string $newdirname name of new directory
372 * @param int $userid id of author, default $USER->id
373 * @return file_info new directory
375 public function create_directory($newdirname, $userid = NULL) {
376 return null;
380 * Create new file from string - make sure
381 * params are valid.
383 * @param string $newfilename name of new file
384 * @param string $content of file
385 * @param int $userid id of author, default $USER->id
386 * @return file_info new file
388 public function create_file_from_string($newfilename, $content, $userid = NULL) {
389 return null;
393 * Create new file from pathname - make sure
394 * params are valid.
396 * @param string $newfilename name of new file
397 * @param string $pathname location of file
398 * @param int $userid id of author, default $USER->id
399 * @return file_info new file
401 public function create_file_from_pathname($newfilename, $pathname, $userid = NULL) {
402 return null;
406 * Create new file from stored file - make sure
407 * params are valid.
409 * @param string $newfilename name of new file
410 * @param int|stored_file $fid id or stored_file of file
411 * @param int $userid id of author, default $USER->id
412 * @return file_info new file
414 public function create_file_from_storedfile($newfilename, $fid, $userid = NULL) {
415 return null;
419 * Delete file, make sure file is deletable first.
421 * @return bool success
423 public function delete() {
424 return false;
428 * Copy content of this file to local storage, overriding current file if needed.
430 * @param array|stdClass $filerecord contains contextid, component, filearea,
431 * itemid, filepath, filename and optionally other attributes of the new file
432 * @return bool success
434 public function copy_to_storage($filerecord) {
435 return false;
439 * Copy content of this file to local storage, overriding current file if needed.
441 * @todo MDL-31068 implement move() rename() unzip() zip()
442 * @param string $pathname real local full file name
443 * @return boolean success
445 public function copy_to_pathname($pathname) {
446 return false;
450 //TODO: following methods are not implemented yet ;-)
451 //public abstract function move(location params);
452 //public abstract function rename(new name);
453 //public abstract function unzip(location params);
454 //public abstract function zip(zip file, file info);