Commit | Line | Data |
---|---|---|
4317f92f | 1 | <?php |
10d53fd3 DC |
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 | ||
67233725 DC |
17 | /** |
18 | * This plugin is used to access files on server file system | |
19 | * | |
20 | * @since 2.0 | |
21 | * @package repository_filesystem | |
22 | * @copyright 2010 Dongsheng Cai {@link http://dongsheng.org} | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | */ | |
25 | require_once($CFG->dirroot . '/repository/lib.php'); | |
26 | require_once($CFG->libdir . '/filelib.php'); | |
27 | ||
fdcf5320 | 28 | /** |
29 | * repository_filesystem class | |
67233725 | 30 | * |
fdcf5320 | 31 | * Create a repository from your local filesystem |
32 | * *NOTE* for security issue, we use a fixed repository path | |
33 | * which is %moodledata%/repository | |
34 | * | |
d078f6d3 | 35 | * @package repository |
67233725 | 36 | * @copyright 2009 Dongsheng Cai {@link http://dongsheng.org} |
d078f6d3 | 37 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
fdcf5320 | 38 | */ |
520de343 | 39 | class repository_filesystem extends repository { |
67233725 DC |
40 | |
41 | /** | |
42 | * Constructor | |
43 | * | |
44 | * @param int $repositoryid repository ID | |
45 | * @param int $context context ID | |
46 | * @param array $options | |
47 | */ | |
447c7a19 | 48 | public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) { |
fdcf5320 | 49 | global $CFG; |
520de343 | 50 | parent::__construct($repositoryid, $context, $options); |
873f2e0f DC |
51 | $root = $CFG->dataroot.'/repository/'; |
52 | $subdir = $this->get_option('fs_path'); | |
53 | $this->root_path = $root . $subdir . '/'; | |
e437618b | 54 | if (!empty($options['ajax'])) { |
fdcf5320 | 55 | if (!is_dir($this->root_path)) { |
8512eebe | 56 | $created = mkdir($this->root_path, $CFG->directorypermissions, true); |
520de343 | 57 | $ret = array(); |
58 | $ret['msg'] = get_string('invalidpath', 'repository_filesystem'); | |
59 | $ret['nosearch'] = true; | |
93e9aa27 | 60 | if ($options['ajax'] && !$created) { |
fdcf5320 | 61 | echo json_encode($ret); |
62 | exit; | |
520de343 | 63 | } |
64 | } | |
520de343 | 65 | } |
66 | } | |
67 | public function get_listing($path = '', $page = '') { | |
390baf46 | 68 | global $CFG, $OUTPUT; |
520de343 | 69 | $list = array(); |
70 | $list['list'] = array(); | |
71 | // process breacrumb trail | |
72 | $list['path'] = array( | |
5bdf63cc | 73 | array('name'=>get_string('root', 'repository_filesystem'), 'path'=>'') |
520de343 | 74 | ); |
75 | $trail = ''; | |
76 | if (!empty($path)) { | |
77 | $parts = explode('/', $path); | |
78 | if (count($parts) > 1) { | |
79 | foreach ($parts as $part) { | |
4a9aff79 | 80 | if (!empty($part)) { |
81 | $trail .= ('/'.$part); | |
82 | $list['path'][] = array('name'=>$part, 'path'=>$trail); | |
83 | } | |
520de343 | 84 | } |
85 | } else { | |
86 | $list['path'][] = array('name'=>$path, 'path'=>$path); | |
87 | } | |
88 | $this->root_path .= ($path.'/'); | |
89 | } | |
520de343 | 90 | $list['manage'] = false; |
520de343 | 91 | $list['dynload'] = true; |
520de343 | 92 | $list['nologin'] = true; |
520de343 | 93 | $list['nosearch'] = true; |
94 | if ($dh = opendir($this->root_path)) { | |
95 | while (($file = readdir($dh)) != false) { | |
96 | if ( $file != '.' and $file !='..') { | |
97 | if (filetype($this->root_path.$file) == 'file') { | |
98 | $list['list'][] = array( | |
99 | 'title' => $file, | |
100 | 'source' => $path.'/'.$file, | |
101 | 'size' => filesize($this->root_path.$file), | |
5bdf63cc MG |
102 | 'datecreated' => filectime($this->root_path.$file), |
103 | 'datemodified' => filemtime($this->root_path.$file), | |
559276b1 MG |
104 | 'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file, 90))->out(false), |
105 | 'icon' => $OUTPUT->pix_url(file_extension_icon($file, 24))->out(false) | |
520de343 | 106 | ); |
107 | } else { | |
108 | if (!empty($path)) { | |
109 | $current_path = $path . '/'. $file; | |
110 | } else { | |
111 | $current_path = $file; | |
112 | } | |
113 | $list['list'][] = array( | |
114 | 'title' => $file, | |
115 | 'children' => array(), | |
5bdf63cc MG |
116 | 'datecreated' => filectime($this->root_path.$file), |
117 | 'datemodified' => filemtime($this->root_path.$file), | |
559276b1 | 118 | 'thumbnail' => $OUTPUT->pix_url(file_folder_icon(90))->out(false), |
520de343 | 119 | 'path' => $current_path |
120 | ); | |
121 | } | |
122 | } | |
123 | } | |
124 | } | |
fb4ee704 | 125 | $list['list'] = array_filter($list['list'], array($this, 'filter')); |
520de343 | 126 | return $list; |
127 | } | |
520de343 | 128 | public function check_login() { |
129 | return true; | |
130 | } | |
520de343 | 131 | public function print_login() { |
132 | return true; | |
133 | } | |
520de343 | 134 | public function global_search() { |
135 | return false; | |
136 | } | |
67233725 | 137 | |
951d2d55 DC |
138 | /** |
139 | * Return file path | |
140 | * @return array | |
141 | */ | |
520de343 | 142 | public function get_file($file, $title = '') { |
143 | global $CFG; | |
144 | if ($file{0} == '/') { | |
145 | $file = $this->root_path.substr($file, 1, strlen($file)-1); | |
951d2d55 DC |
146 | } else { |
147 | $file = $this->root_path.$file; | |
520de343 | 148 | } |
149 | // this is a hack to prevent move_to_file deleteing files | |
150 | // in local repository | |
151 | $CFG->repository_no_delete = true; | |
85b5ed5d | 152 | return array('path'=>$file, 'url'=>''); |
520de343 | 153 | } |
154 | ||
155 | public function logout() { | |
156 | return true; | |
157 | } | |
158 | ||
159 | public static function get_instance_option_names() { | |
93e9aa27 | 160 | return array('fs_path'); |
520de343 | 161 | } |
162 | ||
b2f8adf4 | 163 | public function set_option($options = array()) { |
164 | $options['fs_path'] = clean_param($options['fs_path'], PARAM_PATH); | |
165 | $ret = parent::set_option($options); | |
166 | return $ret; | |
167 | } | |
8e5af6cf | 168 | |
aea5595c | 169 | public function instance_config_form($mform) { |
49d20def | 170 | global $CFG, $PAGE; |
8e5af6cf | 171 | if (has_capability('moodle/site:config', get_system_context())) { |
49d20def DC |
172 | $path = $CFG->dataroot . '/repository/'; |
173 | if (!is_dir($path)) { | |
8512eebe | 174 | mkdir($path, $CFG->directorypermissions, true); |
93e9aa27 | 175 | } |
49d20def DC |
176 | if ($handle = opendir($path)) { |
177 | $fieldname = get_string('path', 'repository_filesystem'); | |
178 | $choices = array(); | |
179 | while (false !== ($file = readdir($handle))) { | |
180 | if (is_dir($path.$file) && $file != '.' && $file!= '..') { | |
181 | $choices[$file] = $file; | |
182 | $fieldname = ''; | |
183 | } | |
184 | } | |
185 | if (empty($choices)) { | |
186 | $mform->addElement('static', '', '', get_string('nosubdir', 'repository_filesystem', $path)); | |
6b172cdc | 187 | $mform->addElement('hidden', 'fs_path', ''); |
49d20def DC |
188 | } else { |
189 | $mform->addElement('select', 'fs_path', $fieldname, $choices); | |
190 | $mform->addElement('static', null, '', get_string('information','repository_filesystem', $path)); | |
191 | } | |
192 | closedir($handle); | |
873f2e0f | 193 | } |
49d20def DC |
194 | } else { |
195 | $mform->addElement('static', null, '', get_string('nopermissions', 'error', get_string('configplugin', 'repository_filesystem'))); | |
196 | return false; | |
93e9aa27 | 197 | } |
93e9aa27 | 198 | } |
8e5af6cf | 199 | |
49d20def DC |
200 | public static function create($type, $userid, $context, $params, $readonly=0) { |
201 | global $PAGE; | |
8e5af6cf | 202 | if (has_capability('moodle/site:config', get_system_context())) { |
49d20def DC |
203 | return parent::create($type, $userid, $context, $params, $readonly); |
204 | } else { | |
8e5af6cf | 205 | require_capability('moodle/site:config', get_system_context()); |
49d20def DC |
206 | return false; |
207 | } | |
208 | } | |
6b172cdc DC |
209 | public static function instance_form_validation($mform, $data, $errors) { |
210 | if (empty($data['fs_path'])) { | |
211 | $errors['fs_path'] = get_string('invalidadminsettingname', 'error', 'fs_path'); | |
212 | } | |
213 | return $errors; | |
214 | } | |
67233725 DC |
215 | |
216 | /** | |
217 | * User cannot use the external link to dropbox | |
218 | * | |
219 | * @return int | |
220 | */ | |
221 | public function supported_returntypes() { | |
222 | return FILE_INTERNAL | FILE_REFERENCE; | |
223 | } | |
224 | ||
225 | /** | |
226 | * Get file from external repository by reference | |
227 | * {@link repository::get_file_reference()} | |
228 | * {@link repository::get_file()} | |
229 | * | |
230 | * @param stdClass $reference file reference db record | |
231 | * @return stdClass|null|false | |
232 | */ | |
233 | public function get_file_by_reference($reference) { | |
234 | $ref = $reference->reference; | |
235 | if ($ref{0} == '/') { | |
236 | $filepath = $this->root_path.substr($ref, 1, strlen($ref)-1); | |
237 | } else { | |
238 | $filepath = $this->root_path.$ref; | |
239 | } | |
240 | $fileinfo = new stdClass; | |
241 | $fileinfo->filepath = $filepath; | |
242 | return $fileinfo; | |
243 | } | |
244 | ||
245 | /** | |
246 | * Repository method to serve file | |
247 | * | |
248 | * @param stored_file $storedfile | |
249 | * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours) | |
250 | * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only | |
251 | * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin | |
252 | * @param array $options additional options affecting the file serving | |
253 | */ | |
254 | public function send_file($storedfile, $lifetime=86400 , $filter=0, $forcedownload=false, array $options = null) { | |
255 | $reference = $storedfile->get_reference(); | |
256 | if ($reference{0} == '/') { | |
257 | $file = $this->root_path.substr($reference, 1, strlen($reference)-1); | |
258 | } else { | |
259 | $file = $this->root_path.$reference; | |
260 | } | |
261 | send_file($file, $storedfile->get_filename(), 'default' , $filter, false, $forcedownload); | |
262 | } | |
520de343 | 263 | } |