PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/filebrowser/file_info.php

https://bitbucket.org/kudutest1/moodlegit
PHP | 455 lines | 166 code | 41 blank | 248 comment | 20 complexity | 4407ede774bb0d651153879bdaf94e0a MD5 | raw file
  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.
  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. * Base for all file browsing classes.
  18. *
  19. * @package core_files
  20. * @copyright 2008 Petr Skoda (http://skodak.org)
  21. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22. */
  23. defined('MOODLE_INTERNAL') || die();
  24. /**
  25. * Base class for things in the tree navigated by {@link file_browser}.
  26. *
  27. * @package core_files
  28. * @copyright 2008 Petr Skoda (http://skodak.org)
  29. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  30. */
  31. abstract class file_info {
  32. /** @var stdClass File context */
  33. protected $context;
  34. /** @var file_browser File browser instance */
  35. protected $browser;
  36. /**
  37. * Constructor
  38. *
  39. * @param file_browser $browser file_browser instance
  40. * @param stdClass $context
  41. */
  42. public function __construct($browser, $context) {
  43. $this->browser = $browser;
  44. $this->context = $context;
  45. }
  46. /**
  47. * Returns list of standard virtual file/directory identification.
  48. * The difference from stored_file parameters is that null values
  49. * are allowed in all fields
  50. *
  51. * @return array with keys contextid, component, filearea, itemid, filepath and filename
  52. */
  53. public function get_params() {
  54. return array('contextid' => $this->context->id,
  55. 'component' => null,
  56. 'filearea' => null,
  57. 'itemid' => null,
  58. 'filepath' => null,
  59. 'filename' => null);
  60. }
  61. /**
  62. * Returns localised visible name.
  63. *
  64. * @return string
  65. */
  66. public abstract function get_visible_name();
  67. /**
  68. * Whether or not this is a directory
  69. *
  70. * @return bool
  71. */
  72. public abstract function is_directory();
  73. /**
  74. * Returns list of children.
  75. *
  76. * @return array of file_info instances
  77. */
  78. public abstract function get_children();
  79. /**
  80. * Builds SQL sub query (WHERE clause) for selecting files with the specified extensions
  81. *
  82. * If $extensions == '*' (any file), the result is array('', array())
  83. * otherwise the result is something like array('AND filename ...', array(...))
  84. *
  85. * @param string|array $extensions - either '*' or array of lowercase extensions, i.e. array('.gif','.jpg')
  86. * @param string $prefix prefix for DB table files in the query (empty by default)
  87. * @return array of two elements: $sql - sql where clause and $params - array of parameters
  88. */
  89. protected function build_search_files_sql($extensions, $prefix = null) {
  90. global $DB;
  91. if (strlen($prefix)) {
  92. $prefix = $prefix.'.';
  93. } else {
  94. $prefix = '';
  95. }
  96. $sql = '';
  97. $params = array();
  98. if (is_array($extensions) && !in_array('*', $extensions)) {
  99. $likes = array();
  100. $cnt = 0;
  101. foreach ($extensions as $ext) {
  102. $cnt++;
  103. $likes[] = $DB->sql_like($prefix.'filename', ':filename'.$cnt, false);
  104. $params['filename'.$cnt] = '%'.$ext;
  105. }
  106. $sql .= ' AND (' . join(' OR ', $likes) . ')';
  107. }
  108. return array($sql, $params);
  109. }
  110. /**
  111. * Returns list of children which are either files matching the specified extensions
  112. * or folders that contain at least one such file.
  113. *
  114. * It is recommended to overwrite this function so it uses a proper SQL
  115. * query and does not create unnecessary file_info objects (might require a lot of time
  116. * and memory usage on big sites).
  117. *
  118. * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg')
  119. * @return array of file_info instances
  120. */
  121. public function get_non_empty_children($extensions = '*') {
  122. $list = $this->get_children();
  123. $nonemptylist = array();
  124. foreach ($list as $fileinfo) {
  125. if ($fileinfo->is_directory()) {
  126. if ($fileinfo->count_non_empty_children($extensions)) {
  127. $nonemptylist[] = $fileinfo;
  128. }
  129. } else if ($extensions === '*') {
  130. $nonemptylist[] = $fileinfo;
  131. } else {
  132. $filename = $fileinfo->get_visible_name();
  133. $extension = textlib::strtolower(pathinfo($filename, PATHINFO_EXTENSION));
  134. if (!empty($extension) && in_array('.' . $extension, $extensions)) {
  135. $nonemptylist[] = $fileinfo;
  136. }
  137. }
  138. }
  139. return $nonemptylist;
  140. }
  141. /**
  142. * Returns the number of children which are either files matching the specified extensions
  143. * or folders containing at least one such file.
  144. *
  145. * We usually don't need the exact number of non empty children if it is >=2 (see param $limit)
  146. * This function is used by repository_local to evaluate if the folder is empty. But
  147. * it also can be used to check if folder has only one subfolder because in some cases
  148. * this subfolder can be skipped.
  149. *
  150. * It is strongly recommended to overwrite this function so it uses a proper SQL
  151. * query and does not create file_info objects (later might require a lot of time
  152. * and memory usage on big sites).
  153. *
  154. * @param string|array $extensions, for example '*' or array('.gif','.jpg')
  155. * @param int $limit stop counting after at least $limit non-empty children are found
  156. * @return int
  157. */
  158. public function count_non_empty_children($extensions = '*', $limit = 1) {
  159. $list = $this->get_children();
  160. $cnt = 0;
  161. // first loop through files
  162. foreach ($list as $fileinfo) {
  163. if (!$fileinfo->is_directory()) {
  164. if ($extensions !== '*') {
  165. $filename = $fileinfo->get_visible_name();
  166. $extension = textlib::strtolower(pathinfo($filename, PATHINFO_EXTENSION));
  167. if (empty($extension) || !in_array('.' . $extension, $extensions)) {
  168. continue;
  169. }
  170. }
  171. if ((++$cnt) >= $limit) {
  172. return $cnt;
  173. }
  174. }
  175. }
  176. // now loop through directories
  177. foreach ($list as $fileinfo) {
  178. if ($fileinfo->is_directory() && $fileinfo->count_non_empty_children($extensions)) {
  179. if ((++$cnt) >= $limit) {
  180. return $cnt;
  181. }
  182. }
  183. }
  184. return $cnt;
  185. }
  186. /**
  187. * Returns parent file_info instance
  188. *
  189. * @return file_info or null for root
  190. */
  191. public abstract function get_parent();
  192. /**
  193. * Returns array of url encoded params.
  194. *
  195. * @return array with numeric keys
  196. */
  197. public function get_params_rawencoded() {
  198. $params = $this->get_params();
  199. $encoded = array();
  200. $encoded[] = 'contextid=' . $params['contextid'];
  201. $encoded[] = 'component=' . $params['component'];
  202. $encoded[] = 'filearea=' . $params['filearea'];
  203. $encoded[] = 'itemid=' . (is_null($params['itemid']) ? -1 : $params['itemid']);
  204. $encoded[] = 'filepath=' . (is_null($params['filepath']) ? '' : rawurlencode($params['filepath']));
  205. $encoded[] = 'filename=' . ((is_null($params['filename']) or $params['filename'] === '.') ? '' : rawurlencode($params['filename']));
  206. return $encoded;
  207. }
  208. /**
  209. * Returns file download url
  210. *
  211. * @param bool $forcedownload whether or not force download
  212. * @param bool $https whether or not force https
  213. * @return string url
  214. */
  215. public function get_url($forcedownload=false, $https=false) {
  216. return null;
  217. }
  218. /**
  219. * Whether or not I can read content of this file or enter directory
  220. *
  221. * @return bool
  222. */
  223. public function is_readable() {
  224. return true;
  225. }
  226. /**
  227. * Whether or not new files or directories can be added
  228. *
  229. * @return bool
  230. */
  231. public function is_writable() {
  232. return true;
  233. }
  234. /**
  235. * Is this info area and is it "empty"? Are there any files in subfolders?
  236. *
  237. * This is used mostly in repositories to reduce the
  238. * number of empty folders. This method may be very slow,
  239. * use with care.
  240. *
  241. * @return bool
  242. */
  243. public function is_empty_area() {
  244. return false;
  245. }
  246. /**
  247. * Returns file size in bytes, null for directories
  248. *
  249. * @return int bytes or null if not known
  250. */
  251. public function get_filesize() {
  252. return null;
  253. }
  254. /**
  255. * Returns mimetype
  256. *
  257. * @return string mimetype or null if not known
  258. */
  259. public function get_mimetype() {
  260. return null;
  261. }
  262. /**
  263. * Returns time created unix timestamp if known
  264. *
  265. * @return int timestamp or null
  266. */
  267. public function get_timecreated() {
  268. return null;
  269. }
  270. /**
  271. * Returns time modified unix timestamp if known
  272. *
  273. * @return int timestamp or null
  274. */
  275. public function get_timemodified() {
  276. return null;
  277. }
  278. /**
  279. * Returns the license type of the file
  280. * @return string license short name or null
  281. */
  282. public function get_license() {
  283. return null;
  284. }
  285. /**
  286. * Returns the author name of the file
  287. *
  288. * @return string author name or null
  289. */
  290. public function get_author() {
  291. return null;
  292. }
  293. /**
  294. * Returns the source of the file
  295. *
  296. * @return string a source url or null
  297. */
  298. public function get_source() {
  299. return null;
  300. }
  301. /**
  302. * Returns the sort order of the file
  303. *
  304. * @return int
  305. */
  306. public function get_sortorder() {
  307. return 0;
  308. }
  309. /**
  310. * Whether or not this is a external resource
  311. *
  312. * @return bool
  313. */
  314. public function is_external_file() {
  315. return false;
  316. }
  317. /**
  318. * Returns file status flag.
  319. *
  320. * @return int 0 means file OK, anything else is a problem and file can not be used
  321. */
  322. public function get_status() {
  323. return 0;
  324. }
  325. /**
  326. * Returns the localised human-readable name of the file together with virtual path
  327. *
  328. * @see file_info_stored::get_readable_fullname()
  329. * @return string
  330. */
  331. public function get_readable_fullname() {
  332. return null;
  333. }
  334. /**
  335. * Create new directory, may throw exception - make sure
  336. * params are valid.
  337. *
  338. * @param string $newdirname name of new directory
  339. * @param int $userid id of author, default $USER->id
  340. * @return file_info new directory
  341. */
  342. public function create_directory($newdirname, $userid = NULL) {
  343. return null;
  344. }
  345. /**
  346. * Create new file from string - make sure
  347. * params are valid.
  348. *
  349. * @param string $newfilename name of new file
  350. * @param string $content of file
  351. * @param int $userid id of author, default $USER->id
  352. * @return file_info new file
  353. */
  354. public function create_file_from_string($newfilename, $content, $userid = NULL) {
  355. return null;
  356. }
  357. /**
  358. * Create new file from pathname - make sure
  359. * params are valid.
  360. *
  361. * @param string $newfilename name of new file
  362. * @param string $pathname location of file
  363. * @param int $userid id of author, default $USER->id
  364. * @return file_info new file
  365. */
  366. public function create_file_from_pathname($newfilename, $pathname, $userid = NULL) {
  367. return null;
  368. }
  369. /**
  370. * Create new file from stored file - make sure
  371. * params are valid.
  372. *
  373. * @param string $newfilename name of new file
  374. * @param int|stored_file $fid id or stored_file of file
  375. * @param int $userid id of author, default $USER->id
  376. * @return file_info new file
  377. */
  378. public function create_file_from_storedfile($newfilename, $fid, $userid = NULL) {
  379. return null;
  380. }
  381. /**
  382. * Delete file, make sure file is deletable first.
  383. *
  384. * @return bool success
  385. */
  386. public function delete() {
  387. return false;
  388. }
  389. /**
  390. * Copy content of this file to local storage, overriding current file if needed.
  391. *
  392. * @param array|stdClass $filerecord contains contextid, component, filearea,
  393. * itemid, filepath, filename and optionally other attributes of the new file
  394. * @return bool success
  395. */
  396. public function copy_to_storage($filerecord) {
  397. return false;
  398. }
  399. /**
  400. * Copy content of this file to local storage, overriding current file if needed.
  401. *
  402. * @todo MDL-31068 implement move() rename() unzip() zip()
  403. * @param string $pathname real local full file name
  404. * @return boolean success
  405. */
  406. public function copy_to_pathname($pathname) {
  407. return false;
  408. }
  409. //TODO: following methods are not implemented yet ;-)
  410. //public abstract function move(location params);
  411. //public abstract function rename(new name);
  412. //public abstract function unzip(location params);
  413. //public abstract function zip(zip file, file info);
  414. }