MDL-17037 Lossless optimization of all PNG and JPEG images
[moodle.git] / repository / remotemoodle / repository.class.php
1 <?php
2 /**
3  * repository_remotemoodle class
4  * This is a subclass of repository class
5  * @author Jerome Mouneyrac
6  * @version $Id$
7  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
8  */
10 require_once($CFG->dirroot.'/repository/lib.php');
13 class repository_remotemoodle extends repository {
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);
27     }
29     /**
30      *
31      * @return <type>
32      */
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');
39         return array($pf);
40     }
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;
53         $fs = get_file_storage();
54         $sf = $fs->get_file_by_hash($pathnamehash);
55         $contents = base64_encode($sf->get_content());
56         return array($contents, $sf->get_filename());
57     }
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      */
68     public function getFileList($username, $search) {
69         global $DB, $USER, $MNET_REMOTE_CLIENT, $CFG;
70         $USER = $DB->get_record('user',array('username' => $username, 'mnethostid' => $MNET_REMOTE_CLIENT->id));
71         $ret = array();
72         $ret['nologin'] = true;
73         $ret['manage'] = $CFG->wwwroot .'/files/index.php'; // temporary
74         $browser = get_file_browser();
75         $itemid = null;
76         $filename = null;
77         $filearea = null;
78         $path = '/';
79         $ret['dynload'] = false;
81         if ($fileinfo = $browser->get_file_info(get_system_context(), $filearea, $itemid, $path, $filename)) {
83             $ret['path'] = array();
84             $params = $fileinfo->get_params();
85             $filearea = $params['filearea'];
86             $ret['path'][] = repository_remotemoodle::_encode_path($filearea, $path, $fileinfo->get_visible_name());
87             if ($fileinfo->is_directory()) {
88                 $level = $fileinfo->get_parent();
89                 while ($level) {
90                     $params = $level->get_params();
91                     $ret['path'][] = repository_remotemoodle::_encode_path($params['filearea'], $params['filepath'], $level->get_visible_name());
92                     $level = $level->get_parent();
93                 }
94             }
95             $filecount = repository_remotemoodle::build_tree($fileinfo, $search, $ret['dynload'], $ret['list']);
96             $ret['path'] = array_reverse($ret['path']);
97         }
99         if (empty($ret['list'])) {
100             throw new repository_exception('emptyfilelist', 'repository_local');
101         } else {
102             return $ret;
103         }
104         
105     }
107     /**
108      *
109      * @param <type> $filearea
110      * @param <type> $path
111      * @param <type> $visiblename
112      * @return <type>
113      */
114     public static function _encode_path($filearea, $path, $visiblename) {
115         return array('path'=>serialize(array($filearea, $path)), 'name'=>$visiblename);
116     }
118    /**
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      */
130     public static function build_tree($fileinfo, $search, $dynamicmode, &$list) {
131         global $CFG;
133         $filecount = 0;
134         $children = $fileinfo->get_children();
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();
144             if ($child->is_directory()) {
145                 $path = array();
146                 $level = $child->get_parent();
147                 while ($level) {
148                     $params = $level->get_params();
149                     $path[] = repository_remotemoodle::_encode_path($params['filearea'], $params['filepath'], $level->get_visible_name());
150                     $level = $level->get_parent();
151                 }
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                 );
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                 }
171                 if (!$search || $_filecount || (stristr($tmp['title'], $search) !== false)) {
172                     $list[] = $tmp;
173                     $filecount += $_filecount;
174                 }
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                 }
182                 //retrieve the stored file id
183                 $fs = get_file_storage();
184                 $params = $child->get_params();
186                 $pathnamehash = $fs->get_pathname_hash($params['contextid'], $params['filearea'], $params['itemid'], $params['filepath'], $params['filename']);
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                 );
196                 $filecount++;
197             }
198         }
199         return $filecount;
200     }
203     /**
204      *
205      * @global <type> $SESSION
206      * @param <type> $ajax
207      * @return <type>
208      */
209     public function print_login($ajax = true) {
210         global $SESSION;
211         return $this->get_listing();
212     }
214     /**
215      *
216      * @param <type> $search_text
217      * @return <type>
218      */
219     public function search($search_text) {       
220         return $this->get_listing('', $search_text);
221     }
223     /**
224      *
225      * @global <type> $MNET
226      */
227     private function ensure_environment() {
228         global $MNET;      
229         if (empty($MNET)) {
230             $MNET = new mnet_environment();
231             $MNET->init();
232         }
233     }
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;
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          
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']));
265              
266         $mnet_peer = new mnet_peer();
267         $mnet_peer->set_wwwroot($host->wwwroot);
268   
269         //connect to the remote moodle and retrieve the list of files       
270         $client = new mnet_xmlrpc_client();
271       
272         $client->set_method('repository/remotemoodle/repository.class.php/getFileList');
273         $client->add_param($USER->username);
274         $client->add_param($search);
275          
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         }
284         
285         $services = $client->response;
287          if (empty($services)) {
288             echo json_encode(array('e'=>get_string('failtoretrievelist','repository_remotemoodle')));
289             exit;
290         }
292         return $services;
293     }
295    
297     /**
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();
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, '');
315         $mnet_peer = new mnet_peer();
316         $mnet_peer->set_wwwroot($host->wwwroot);
318         //connect to the remote moodle and retrieve the list of files
319         $client = new mnet_xmlrpc_client();
321         $client->set_method('repository/remotemoodle/repository.class.php/retrieveFile');
322         $client->add_param($USER->username);
323         $client->add_param($url);
325         $client->send($mnet_peer);
327         $services = $client->response;
328         $content = base64_decode($services[0]);
329         $file = $services[1];
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     }
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
380                                     a.name = ? AND
381                                     h.name <> ?',
382                         array($CFG->mnet_localhost_id, 'moodle', 'All Hosts'));
383         $peers = array();
384         foreach($hosts as $host) {
385             $peers[$host->id] = $host->name;        
386         }
388         $mform->addElement('select', 'peer', get_string('peer', 'repository_remotemoodle'),$peers);
389         $mform->addRule('peer', get_string('required'), 'required', null, 'client');
390     }
392     /**
393      * Names of the instance settings
394      * @return <type>
395      */
396     public static function get_instance_option_names() {
397         return array('peer');
398     }
400 ?>