PageRenderTime 26ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/repository/filesystem/lib.php

https://bitbucket.org/kudutest1/moodlegit
PHP | 346 lines | 227 code | 16 blank | 103 comment | 52 complexity | c2162cfaec531161017a073db8e0b7c2 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. * This plugin is used to access files on server file system
  18. *
  19. * @since 2.0
  20. * @package repository_filesystem
  21. * @copyright 2010 Dongsheng Cai {@link http://dongsheng.org}
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. require_once($CFG->dirroot . '/repository/lib.php');
  25. require_once($CFG->libdir . '/filelib.php');
  26. /**
  27. * repository_filesystem class
  28. *
  29. * Create a repository from your local filesystem
  30. * *NOTE* for security issue, we use a fixed repository path
  31. * which is %moodledata%/repository
  32. *
  33. * @package repository
  34. * @copyright 2009 Dongsheng Cai {@link http://dongsheng.org}
  35. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36. */
  37. class repository_filesystem extends repository {
  38. /**
  39. * Constructor
  40. *
  41. * @param int $repositoryid repository ID
  42. * @param int $context context ID
  43. * @param array $options
  44. */
  45. public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
  46. global $CFG;
  47. parent::__construct($repositoryid, $context, $options);
  48. $root = $CFG->dataroot.'/repository/';
  49. $subdir = $this->get_option('fs_path');
  50. $this->root_path = $root . $subdir . '/';
  51. if (!empty($options['ajax'])) {
  52. if (!is_dir($this->root_path)) {
  53. $created = mkdir($this->root_path, $CFG->directorypermissions, true);
  54. $ret = array();
  55. $ret['msg'] = get_string('invalidpath', 'repository_filesystem');
  56. $ret['nosearch'] = true;
  57. if ($options['ajax'] && !$created) {
  58. echo json_encode($ret);
  59. exit;
  60. }
  61. }
  62. }
  63. }
  64. public function get_listing($path = '', $page = '') {
  65. global $CFG, $OUTPUT;
  66. $list = array();
  67. $list['list'] = array();
  68. // process breacrumb trail
  69. $list['path'] = array(
  70. array('name'=>get_string('root', 'repository_filesystem'), 'path'=>'')
  71. );
  72. $trail = '';
  73. if (!empty($path)) {
  74. $parts = explode('/', $path);
  75. if (count($parts) > 1) {
  76. foreach ($parts as $part) {
  77. if (!empty($part)) {
  78. $trail .= ('/'.$part);
  79. $list['path'][] = array('name'=>$part, 'path'=>$trail);
  80. }
  81. }
  82. } else {
  83. $list['path'][] = array('name'=>$path, 'path'=>$path);
  84. }
  85. $this->root_path .= ($path.'/');
  86. }
  87. $list['manage'] = false;
  88. $list['dynload'] = true;
  89. $list['nologin'] = true;
  90. $list['nosearch'] = true;
  91. // retrieve list of files and directories and sort them
  92. $fileslist = array();
  93. $dirslist = array();
  94. if ($dh = opendir($this->root_path)) {
  95. while (($file = readdir($dh)) != false) {
  96. if ( $file != '.' and $file !='..') {
  97. if (is_file($this->root_path.$file)) {
  98. $fileslist[] = $file;
  99. } else {
  100. $dirslist[] = $file;
  101. }
  102. }
  103. }
  104. }
  105. collatorlib::asort($fileslist, collatorlib::SORT_STRING);
  106. collatorlib::asort($dirslist, collatorlib::SORT_STRING);
  107. // fill the $list['list']
  108. foreach ($dirslist as $file) {
  109. if (!empty($path)) {
  110. $current_path = $path . '/'. $file;
  111. } else {
  112. $current_path = $file;
  113. }
  114. $list['list'][] = array(
  115. 'title' => $file,
  116. 'children' => array(),
  117. 'datecreated' => filectime($this->root_path.$file),
  118. 'datemodified' => filemtime($this->root_path.$file),
  119. 'thumbnail' => $OUTPUT->pix_url(file_folder_icon(90))->out(false),
  120. 'path' => $current_path
  121. );
  122. }
  123. foreach ($fileslist as $file) {
  124. $list['list'][] = array(
  125. 'title' => $file,
  126. 'source' => $path.'/'.$file,
  127. 'size' => filesize($this->root_path.$file),
  128. 'datecreated' => filectime($this->root_path.$file),
  129. 'datemodified' => filemtime($this->root_path.$file),
  130. 'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file, 90))->out(false),
  131. 'icon' => $OUTPUT->pix_url(file_extension_icon($file, 24))->out(false)
  132. );
  133. }
  134. $list['list'] = array_filter($list['list'], array($this, 'filter'));
  135. return $list;
  136. }
  137. public function check_login() {
  138. return true;
  139. }
  140. public function print_login() {
  141. return true;
  142. }
  143. public function global_search() {
  144. return false;
  145. }
  146. /**
  147. * Return file path
  148. * @return array
  149. */
  150. public function get_file($file, $title = '') {
  151. global $CFG;
  152. if ($file{0} == '/') {
  153. $file = $this->root_path.substr($file, 1, strlen($file)-1);
  154. } else {
  155. $file = $this->root_path.$file;
  156. }
  157. // this is a hack to prevent move_to_file deleteing files
  158. // in local repository
  159. $CFG->repository_no_delete = true;
  160. return array('path'=>$file, 'url'=>'');
  161. }
  162. /**
  163. * Return the source information
  164. *
  165. * @param stdClass $filepath
  166. * @return string|null
  167. */
  168. public function get_file_source_info($filepath) {
  169. return $filepath;
  170. }
  171. public function logout() {
  172. return true;
  173. }
  174. public static function get_instance_option_names() {
  175. return array('fs_path');
  176. }
  177. public function set_option($options = array()) {
  178. $options['fs_path'] = clean_param($options['fs_path'], PARAM_PATH);
  179. $ret = parent::set_option($options);
  180. return $ret;
  181. }
  182. public static function instance_config_form($mform) {
  183. global $CFG, $PAGE;
  184. if (has_capability('moodle/site:config', get_system_context())) {
  185. $path = $CFG->dataroot . '/repository/';
  186. if (!is_dir($path)) {
  187. mkdir($path, $CFG->directorypermissions, true);
  188. }
  189. if ($handle = opendir($path)) {
  190. $fieldname = get_string('path', 'repository_filesystem');
  191. $choices = array();
  192. while (false !== ($file = readdir($handle))) {
  193. if (is_dir($path.$file) && $file != '.' && $file!= '..') {
  194. $choices[$file] = $file;
  195. $fieldname = '';
  196. }
  197. }
  198. if (empty($choices)) {
  199. $mform->addElement('static', '', '', get_string('nosubdir', 'repository_filesystem', $path));
  200. $mform->addElement('hidden', 'fs_path', '');
  201. $mform->setType('fs_path', PARAM_PATH);
  202. } else {
  203. $mform->addElement('select', 'fs_path', $fieldname, $choices);
  204. $mform->addElement('static', null, '', get_string('information','repository_filesystem', $path));
  205. }
  206. closedir($handle);
  207. }
  208. } else {
  209. $mform->addElement('static', null, '', get_string('nopermissions', 'error', get_string('configplugin', 'repository_filesystem')));
  210. return false;
  211. }
  212. }
  213. public static function create($type, $userid, $context, $params, $readonly=0) {
  214. global $PAGE;
  215. if (has_capability('moodle/site:config', get_system_context())) {
  216. return parent::create($type, $userid, $context, $params, $readonly);
  217. } else {
  218. require_capability('moodle/site:config', get_system_context());
  219. return false;
  220. }
  221. }
  222. public static function instance_form_validation($mform, $data, $errors) {
  223. if (empty($data['fs_path'])) {
  224. $errors['fs_path'] = get_string('invalidadminsettingname', 'error', 'fs_path');
  225. }
  226. return $errors;
  227. }
  228. /**
  229. * User cannot use the external link to dropbox
  230. *
  231. * @return int
  232. */
  233. public function supported_returntypes() {
  234. return FILE_INTERNAL | FILE_REFERENCE;
  235. }
  236. /**
  237. * Return reference file life time
  238. *
  239. * @param string $ref
  240. * @return int
  241. */
  242. public function get_reference_file_lifetime($ref) {
  243. // Does not cost us much to synchronise within our own filesystem, set to 1 minute
  244. return 60;
  245. }
  246. /**
  247. * Return human readable reference information
  248. *
  249. * @param string $reference value of DB field files_reference.reference
  250. * @param int $filestatus status of the file, 0 - ok, 666 - source missing
  251. * @return string
  252. */
  253. public function get_reference_details($reference, $filestatus = 0) {
  254. $details = $this->get_name().': '.$reference;
  255. if ($filestatus) {
  256. return get_string('lostsource', 'repository', $details);
  257. } else {
  258. return $details;
  259. }
  260. }
  261. /**
  262. * Returns information about file in this repository by reference
  263. *
  264. * Returns null if file not found or is not readable
  265. *
  266. * @param stdClass $reference file reference db record
  267. * @return stdClass|null contains one of the following:
  268. * - 'filesize' if file should not be copied to moodle filepool
  269. * - 'filepath' if file should be copied to moodle filepool
  270. */
  271. public function get_file_by_reference($reference) {
  272. $ref = $reference->reference;
  273. if ($ref{0} == '/') {
  274. $filepath = $this->root_path.substr($ref, 1, strlen($ref)-1);
  275. } else {
  276. $filepath = $this->root_path.$ref;
  277. }
  278. if (file_exists($filepath) && is_readable($filepath)) {
  279. if (file_extension_in_typegroup($filepath, 'web_image')) {
  280. // return path to image files so it will be copied into moodle filepool
  281. // we need the file in filepool to generate an image thumbnail
  282. return (object)array('filepath' => $filepath);
  283. } else {
  284. // return just the file size so file will NOT be copied into moodle filepool
  285. return (object)array(
  286. 'filesize' => filesize($filepath)
  287. );
  288. }
  289. } else {
  290. return null;
  291. }
  292. }
  293. /**
  294. * Repository method to serve the referenced file
  295. *
  296. * @see send_stored_file
  297. *
  298. * @param stored_file $storedfile the file that contains the reference
  299. * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours)
  300. * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only
  301. * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin
  302. * @param array $options additional options affecting the file serving
  303. */
  304. public function send_file($storedfile, $lifetime=86400 , $filter=0, $forcedownload=false, array $options = null) {
  305. $reference = $storedfile->get_reference();
  306. if ($reference{0} == '/') {
  307. $file = $this->root_path.substr($reference, 1, strlen($reference)-1);
  308. } else {
  309. $file = $this->root_path.$reference;
  310. }
  311. if (is_readable($file)) {
  312. $filename = $storedfile->get_filename();
  313. if ($options && isset($options['filename'])) {
  314. $filename = $options['filename'];
  315. }
  316. $dontdie = ($options && isset($options['dontdie']));
  317. send_file($file, $filename, $lifetime , $filter, false, $forcedownload, '', $dontdie);
  318. } else {
  319. send_file_not_found();
  320. }
  321. }
  322. /**
  323. * Is this repository accessing private data?
  324. *
  325. * @return bool
  326. */
  327. public function contains_private_data() {
  328. return false;
  329. }
  330. }