MDL-17037 Lossless optimization of all PNG and JPEG images
[moodle.git] / repository / remotemoodle / repository.class.php
CommitLineData
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 10require_once($CFG->dirroot.'/repository/lib.php');
bcd41452 11
12
d3dfe9ae 13class 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?>