d3dfe9ae |
1 | <?php |
2 | /** |
bcd41452 |
3 | * repository_remotemoodle class |
d3dfe9ae |
4 | * This is a subclass of repository class |
bcd41452 |
5 | * @author Jerome Mouneyrac |
d3dfe9ae |
6 | * @version $Id$ |
7 | * @license http://www.gnu.org/copyleft/gpl.html GNU Public License |
8 | */ |
bcd41452 |
9 | |
ef378cdc |
10 | require_once($CFG->dirroot.'/repository/lib.php'); |
bcd41452 |
11 | |
12 | |
d3dfe9ae |
13 | class repository_remotemoodle extends repository { |
14 | |
15 | /** |
16 | * |
17 | * @global <type> $SESSION |
18 | * @global <type> $action |
19 | * @global <type> $CFG |
20 | * @param <type> $repositoryid |
21 | * @param <type> $context |
22 | * @param <type> $options |
23 | */ |
24 | public function __construct($repositoryid, $context = SITEID, $options = array()) { |
25 | global $SESSION, $action, $CFG; |
26 | parent::__construct($repositoryid, $context, $options); |
d3dfe9ae |
27 | } |
28 | |
bcd41452 |
29 | /** |
30 | * |
31 | * @return <type> |
32 | */ |
ef378cdc |
33 | public static function mnet_publishes() { |
34 | $pf= array(); |
35 | $pf['name'] = 'remoterep'; // Name & Description go in lang file |
36 | $pf['apiversion'] = 1; |
37 | $pf['methods'] = array('getFileList', 'retrieveFile'); |
38 | |
39 | return array($pf); |
40 | } |
41 | |
bcd41452 |
42 | /** |
43 | * |
44 | * @global <type> $DB |
45 | * @global <type> $USER |
46 | * @global <type> $MNET_REMOTE_CLIENT |
47 | * @param <type> $username |
48 | * @param <type> $pathnamehash |
49 | * @return <type> |
50 | */ |
51 | public static function retrieveFile($username, $pathnamehash) { |
52 | global $DB, $USER, $MNET_REMOTE_CLIENT; |
ef378cdc |
53 | $fs = get_file_storage(); |
ef378cdc |
54 | $sf = $fs->get_file_by_hash($pathnamehash); |
ef378cdc |
55 | $contents = base64_encode($sf->get_content()); |
ef378cdc |
56 | return array($contents, $sf->get_filename()); |
57 | } |
58 | |
bcd41452 |
59 | /** |
60 | * |
61 | * @global <type> $DB |
62 | * @global <type> $USER |
63 | * @global <type> $MNET_REMOTE_CLIENT |
64 | * @global <type> $CFG |
65 | * @param <type> $username |
66 | * @return <type> |
67 | */ |
e3301494 |
68 | public function getFileList($username, $search) { |
bcd41452 |
69 | global $DB, $USER, $MNET_REMOTE_CLIENT, $CFG; |
ef378cdc |
70 | $USER = $DB->get_record('user',array('username' => $username, 'mnethostid' => $MNET_REMOTE_CLIENT->id)); |
ef378cdc |
71 | $ret = array(); |
ef378cdc |
72 | $ret['nologin'] = true; |
ef378cdc |
73 | $ret['manage'] = $CFG->wwwroot .'/files/index.php'; // temporary |
ef378cdc |
74 | $browser = get_file_browser(); |
75 | $itemid = null; |
76 | $filename = null; |
77 | $filearea = null; |
78 | $path = '/'; |
79 | $ret['dynload'] = false; |
80 | |
81 | if ($fileinfo = $browser->get_file_info(get_system_context(), $filearea, $itemid, $path, $filename)) { |
82 | |
83 | $ret['path'] = array(); |
84 | $params = $fileinfo->get_params(); |
85 | $filearea = $params['filearea']; |
db98f191 |
86 | $ret['path'][] = repository_remotemoodle::_encode_path($filearea, $path, $fileinfo->get_visible_name()); |
ef378cdc |
87 | if ($fileinfo->is_directory()) { |
88 | $level = $fileinfo->get_parent(); |
89 | while ($level) { |
90 | $params = $level->get_params(); |
db98f191 |
91 | $ret['path'][] = repository_remotemoodle::_encode_path($params['filearea'], $params['filepath'], $level->get_visible_name()); |
ef378cdc |
92 | $level = $level->get_parent(); |
93 | } |
94 | } |
db98f191 |
95 | $filecount = repository_remotemoodle::build_tree($fileinfo, $search, $ret['dynload'], $ret['list']); |
ef378cdc |
96 | $ret['path'] = array_reverse($ret['path']); |
ef378cdc |
97 | } |
98 | |
99 | if (empty($ret['list'])) { |
100 | throw new repository_exception('emptyfilelist', 'repository_local'); |
101 | } else { |
bcd41452 |
102 | return $ret; |
ef378cdc |
103 | } |
46c8e3b0 |
104 | |
ef378cdc |
105 | } |
106 | |
bcd41452 |
107 | /** |
ef378cdc |
108 | * |
109 | * @param <type> $filearea |
110 | * @param <type> $path |
111 | * @param <type> $visiblename |
112 | * @return <type> |
113 | */ |
db98f191 |
114 | public static function _encode_path($filearea, $path, $visiblename) { |
ef378cdc |
115 | return array('path'=>serialize(array($filearea, $path)), 'name'=>$visiblename); |
116 | } |
117 | |
bcd41452 |
118 | /** |
ef378cdc |
119 | * Builds a tree of files, to be used by get_listing(). This function is |
120 | * then called recursively. |
121 | * |
122 | * @param $fileinfo an object returned by file_browser::get_file_info() |
123 | * @param $search searched string |
124 | * @param $dynamicmode bool no recursive call is done when in dynamic mode |
125 | * @param $list - the array containing the files under the passed $fileinfo |
126 | * @returns int the number of files found |
127 | * |
128 | * todo: take $search into account, and respect a threshold for dynamic loading |
129 | */ |
db98f191 |
130 | public static function build_tree($fileinfo, $search, $dynamicmode, &$list) { |
ef378cdc |
131 | global $CFG; |
132 | |
133 | $filecount = 0; |
134 | $children = $fileinfo->get_children(); |
135 | |
136 | foreach ($children as $child) { |
137 | $filename = $child->get_visible_name(); |
138 | $filesize = $child->get_filesize(); |
139 | $filesize = $filesize ? display_size($filesize) : ''; |
140 | $filedate = $child->get_timemodified(); |
141 | $filedate = $filedate ? userdate($filedate) : ''; |
142 | $filetype = $child->get_mimetype(); |
143 | |
144 | if ($child->is_directory()) { |
145 | $path = array(); |
146 | $level = $child->get_parent(); |
147 | while ($level) { |
148 | $params = $level->get_params(); |
db98f191 |
149 | $path[] = repository_remotemoodle::_encode_path($params['filearea'], $params['filepath'], $level->get_visible_name()); |
ef378cdc |
150 | $level = $level->get_parent(); |
151 | } |
152 | |
153 | $tmp = array( |
154 | 'title' => $child->get_visible_name(), |
155 | 'size' => 0, |
156 | 'date' => $filedate, |
157 | 'path' => array_reverse($path), |
158 | 'thumbnail' => $CFG->pixpath .'/f/folder.gif' |
159 | ); |
160 | |
bcd41452 |
161 | $_search = $search; |
162 | if ($search && stristr($tmp['title'], $search) !== false) { |
163 | $_search = false; |
164 | } |
165 | $tmp['children'] = array(); |
166 | $_filecount = repository_remotemoodle::build_tree($child, $_search, $dynamicmode, $tmp['children']); |
167 | if ($search && $_filecount) { |
168 | $tmp['expanded'] = 1; |
169 | } |
ef378cdc |
170 | |
171 | if (!$search || $_filecount || (stristr($tmp['title'], $search) !== false)) { |
172 | $list[] = $tmp; |
173 | $filecount += $_filecount; |
174 | } |
175 | |
176 | } else { // not a directory |
177 | // skip the file, if we're in search mode and it's not a match |
178 | if ($search && (stristr($filename, $search) === false)) { |
179 | continue; |
180 | } |
181 | |
182 | //retrieve the stored file id |
bcd41452 |
183 | $fs = get_file_storage(); |
184 | $params = $child->get_params(); |
ef378cdc |
185 | |
bcd41452 |
186 | $pathnamehash = $fs->get_pathname_hash($params['contextid'], $params['filearea'], $params['itemid'], $params['filepath'], $params['filename']); |
ef378cdc |
187 | |
188 | $list[] = array( |
189 | 'title' => $filename, |
190 | 'size' => $filesize, |
191 | 'date' => $filedate, |
192 | 'source' => $pathnamehash, |
193 | 'thumbnail' => $CFG->pixpath .'/f/'. mimeinfo_from_type("icon", $filetype) |
194 | ); |
195 | |
196 | $filecount++; |
197 | } |
198 | } |
ef378cdc |
199 | return $filecount; |
200 | } |
201 | |
202 | |
d3dfe9ae |
203 | /** |
204 | * |
205 | * @global <type> $SESSION |
206 | * @param <type> $ajax |
207 | * @return <type> |
208 | */ |
209 | public function print_login($ajax = true) { |
210 | global $SESSION; |
d3dfe9ae |
211 | return $this->get_listing(); |
212 | } |
213 | |
d3dfe9ae |
214 | /** |
215 | * |
216 | * @param <type> $search_text |
217 | * @return <type> |
218 | */ |
e3301494 |
219 | public function search($search_text) { |
d3dfe9ae |
220 | return $this->get_listing('', $search_text); |
221 | } |
222 | |
a125058f |
223 | /** |
224 | * |
225 | * @global <type> $MNET |
226 | */ |
227 | private function ensure_environment() { |
bcd41452 |
228 | global $MNET; |
d3dfe9ae |
229 | if (empty($MNET)) { |
230 | $MNET = new mnet_environment(); |
231 | $MNET->init(); |
232 | } |
233 | } |
234 | |
235 | /** |
236 | * |
237 | * @global <type> $CFG |
238 | * @param <type> $encodedpath |
239 | * @param <type> $search |
240 | * @return <type> |
241 | */ |
242 | public function get_listing($encodedpath = '', $search = '') { |
243 | global $CFG, $DB, $USER; |
ef378cdc |
244 | |
245 | //check that the host has a version >2.0 |
246 | require_once($CFG->dirroot . '/mnet/xmlrpc/client.php'); |
247 | $this->ensure_environment(); |
248 | $host = $DB->get_record('mnet_host',array('id' => $this->options['peer'])); |
249 | $mnet_peer = new mnet_peer(); |
250 | $mnet_peer->set_wwwroot($host->wwwroot); |
251 | $client = new mnet_xmlrpc_client(); |
252 | $client->set_method('system/listMethods'); |
253 | $client->send($mnet_peer); |
254 | $services = $client->response; |
255 | if (array_search('repository/remotemoodle/repository.class.php/getFileList', $services) === false) { |
256 | echo json_encode(array('e'=>get_string('connectionfailure','repository_remotemoodle'))); |
257 | exit; |
258 | } |
259 | |
d3dfe9ae |
260 | require_once($CFG->dirroot . '/mnet/xmlrpc/client.php'); |
261 | //retrieve the host url |
262 | $this->ensure_environment(); |
263 | |
264 | $host = $DB->get_record('mnet_host',array('id' => $this->options['peer'])); |
a125058f |
265 | |
d3dfe9ae |
266 | $mnet_peer = new mnet_peer(); |
267 | $mnet_peer->set_wwwroot($host->wwwroot); |
268 | |
bcd41452 |
269 | //connect to the remote moodle and retrieve the list of files |
d3dfe9ae |
270 | $client = new mnet_xmlrpc_client(); |
271 | |
ef378cdc |
272 | $client->set_method('repository/remotemoodle/repository.class.php/getFileList'); |
e3301494 |
273 | $client->add_param($USER->username); |
274 | $client->add_param($search); |
d3dfe9ae |
275 | |
a1c9c2bd |
276 | if (!$client->send($mnet_peer)) { |
277 | $message =" "; |
278 | foreach ($client->error as $errormessage) { |
279 | $message .= "ERROR: $errormessage . "; |
280 | } |
281 | echo json_encode(array('e'=>$message)); |
282 | exit; |
283 | } |
d3dfe9ae |
284 | |
285 | $services = $client->response; |
286 | |
46c8e3b0 |
287 | if (empty($services)) { |
288 | echo json_encode(array('e'=>get_string('failtoretrievelist','repository_remotemoodle'))); |
289 | exit; |
290 | } |
291 | |
d3dfe9ae |
292 | return $services; |
293 | } |
294 | |
a125058f |
295 | |
d3dfe9ae |
296 | |
bcd41452 |
297 | /** |
d3dfe9ae |
298 | * Download a file |
299 | * @global object $CFG |
300 | * @param string $url the url of file |
301 | * @param string $file save location |
302 | * @return string the location of the file |
303 | * @see curl package |
304 | */ |
305 | public function get_file($url, $file = '') { |
306 | global $CFG, $DB, $USER; |
307 | require_once($CFG->dirroot . '/mnet/xmlrpc/client.php'); |
308 | //retrieve the host url |
309 | $this->ensure_environment(); |
310 | |
311 | $host = $DB->get_record('mnet_host',array('id' => $this->options['peer'])); |
312 | $mnetauth = get_auth_plugin('mnet'); |
313 | $mnetauth->start_jump_session($host->id, ''); |
314 | |
315 | $mnet_peer = new mnet_peer(); |
316 | $mnet_peer->set_wwwroot($host->wwwroot); |
317 | |
318 | //connect to the remote moodle and retrieve the list of files |
319 | $client = new mnet_xmlrpc_client(); |
320 | |
ef378cdc |
321 | $client->set_method('repository/remotemoodle/repository.class.php/retrieveFile'); |
d3dfe9ae |
322 | $client->add_param($USER->username); |
323 | $client->add_param($url); |
324 | |
325 | $client->send($mnet_peer); |
326 | |
327 | $services = $client->response; |
328 | $content = base64_decode($services[0]); |
329 | $file = $services[1]; |
330 | |
331 | if (!file_exists($CFG->dataroot.'/temp/download')) { |
332 | mkdir($CFG->dataroot.'/temp/download/', 0777, true); |
333 | } |
334 | if (is_dir($CFG->dataroot.'/temp/download')) { |
335 | $dir = $CFG->dataroot.'/temp/download/'; |
336 | } |
337 | if (empty($file)) { |
338 | $file = uniqid('repo').'_'.time().'.tmp'; |
339 | } |
340 | if (file_exists($dir.$file)) { |
341 | $file = uniqid('m').$file; |
342 | } |
343 | |
344 | $fp = fopen($dir.$file, 'w'); |
345 | fwrite($fp,$content); |
346 | fclose($fp); |
347 | |
348 | return $dir.$file; |
349 | |
350 | } |
351 | |
352 | /** |
353 | * Add Instance settings input to Moodle form |
354 | * @param <type> $ |
355 | */ |
356 | public function instance_config_form(&$mform) { |
357 | global $CFG, $DB; |
358 | |
359 | //retrieve all peers |
360 | $hosts = $DB->get_records_sql(' SELECT |
361 | h.id, |
362 | h.wwwroot, |
363 | h.ip_address, |
364 | h.name, |
365 | h.public_key, |
366 | h.public_key_expires, |
367 | h.transport, |
368 | h.portno, |
369 | h.last_connect_time, |
370 | h.last_log_id, |
371 | h.applicationid, |
372 | a.name as app_name, |
373 | a.display_name as app_display_name, |
374 | a.xmlrpc_server_url |
375 | FROM {mnet_host} h |
376 | JOIN {mnet_application} a ON h.applicationid=a.id |
377 | WHERE |
378 | h.id <> ? AND |
379 | h.deleted = 0 AND |
ef378cdc |
380 | a.name = ? AND |
381 | h.name <> ?', |
382 | array($CFG->mnet_localhost_id, 'moodle', 'All Hosts')); |
d3dfe9ae |
383 | $peers = array(); |
384 | foreach($hosts as $host) { |
385 | $peers[$host->id] = $host->name; |
386 | } |
387 | |
388 | $mform->addElement('select', 'peer', get_string('peer', 'repository_remotemoodle'),$peers); |
389 | $mform->addRule('peer', get_string('required'), 'required', null, 'client'); |
390 | } |
391 | |
392 | /** |
393 | * Names of the instance settings |
394 | * @return <type> |
395 | */ |
396 | public static function get_instance_option_names() { |
397 | return array('peer'); |
398 | } |
399 | } |
400 | ?> |