MDL-15352: first version of remote moodle plugin
[moodle.git] / repository / remotemoodle / repository.class.php
1 <?php
2 /**
3  * repository_local class
4  * This is a subclass of repository class
5  *
6  * @version $Id$
7  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
8  */
10 /**
11  *
12  */
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         // TODO:
28         // get the parameter from client side
29         // $this->context can be used here.
30         // When user upload a file, $action == 'upload'
31         // You can use $_FILES to find that file
32     }
34     /**
35      *
36      * @global <type> $SESSION
37      * @param <type> $ajax
38      * @return <type>
39      */
40     public function print_login($ajax = true) {
41         global $SESSION;
42         // TODO
43         // Return file list in moodle
44         return $this->get_listing();
45     }
47     /**
48      *
49      * @param <type> $filearea
50      * @param <type> $path
51      * @param <type> $visiblename
52      * @return <type>
53      */
54     private function _encode_path($filearea, $path, $visiblename) {
55         return array('path'=>serialize(array($filearea, $path)), 'name'=>$visiblename);
56     }
58     /**
59      *
60      * @param <type> $path
61      * @return <type>
62      */
63     private function _decode_path($path) {
64         $filearea = '';
65         $path = '';
66         if (($file = unserialize($path)) !== false) {
67             $filearea = $file[0];
68             $path = $file[1];
69         }
70         return array('filearea' => $filearea, 'path' => $path);
71     }
73     /**
74      *
75      * @param <type> $search_text
76      * @return <type>
77      */
78     public function search($search_text) {
79         return $this->get_listing('', $search_text);
80     }
82      private function ensure_environment() {
83         global $MNET;
84          
85         if (empty($MNET)) {
86             $MNET = new mnet_environment();
87             $MNET->init();
88         }
89     }
91     /**
92      *
93      * @global <type> $CFG
94      * @param <type> $encodedpath
95      * @param <type> $search
96      * @return <type>
97      */
98     public function get_listing($encodedpath = '', $search = '') {
99         global $CFG, $DB, $USER;
100         $ret = array(
101             'path'=>'/var/repo/',
102             'manage'=>'http://webmgr.moodle.com',
103             'list'=> array(
104                 array('title'=>'filename1', 'date'=>'01/01/2009', 'size'=>'10MB', 'source'=>'http://www.moodle.com/dl.rar'),
105                 array('title'=>'folder2', 'date'=>'01/01/2009', 'size'=>'0', 'children'=>array())
106              )
107         );
109         $ret['nologin'] = true;
110         
111         require_once($CFG->dirroot . '/mnet/xmlrpc/client.php');
112         //retrieve the host url
113         $this->ensure_environment();
114       
115         $host = $DB->get_record('mnet_host',array('id' => $this->options['peer']));
116         
117         
118         $mnetauth = get_auth_plugin('mnet');
119         $url      = $mnetauth->start_jump_session($host->id, '');
120      
121         $mnet_peer = new mnet_peer();
122         $mnet_peer->set_wwwroot($host->wwwroot);
123   
124         //connect to the remote moodle and retrieve the list of files
125         $client = new mnet_xmlrpc_client();
126       
127         $client->set_method('system/listFiles');
128           $client->add_param($USER->username);
129        
130          
131         $client->send($mnet_peer);
132         
133         $services = $client->response;
135         return $services;
136     }
138     /**
139      * Builds a tree of files, to be used by get_listing(). This function is 
140      * then called recursively.
141      *
142      * @param $fileinfo an object returned by file_browser::get_file_info()
143      * @param $search searched string
144      * @param $dynamicmode bool no recursive call is done when in dynamic mode
145      * @param $list - the array containing the files under the passed $fileinfo
146      * @returns int the number of files found
147      *
148      * todo: take $search into account, and respect a threshold for dynamic loading
149      */
150     private function build_tree($fileinfo, $search, $dynamicmode, &$list) {
151         global $CFG;
153         $filecount = 0;
154         $children = $fileinfo->get_children();
156         foreach ($children as $child) {
157             $filename = $child->get_visible_name();
158             $filesize = $child->get_filesize();
159             $filesize = $filesize ? display_size($filesize) : '';
160             $filedate = $child->get_timemodified();
161             $filedate = $filedate ? userdate($filedate) : '';
162             $filetype = $child->get_mimetype();
164             if ($child->is_directory()) {
165                 $path = array();
166                 $level = $child->get_parent();
167                 while ($level) {
168                     $params = $level->get_params();
169                     $path[] = $this->_encode_path($params['filearea'], $params['filepath'], $level->get_visible_name());
170                     $level = $level->get_parent();
171                 }
172                 
173                 $tmp = array(
174                     'title' => $child->get_visible_name(),
175                     'size' => 0,
176                     'date' => $filedate,
177                     'path' => array_reverse($path),
178                     'thumbnail' => $CFG->pixpath .'/f/folder.gif'
179                 );
181                 //if ($dynamicmode && $child->is_writable()) {
182                 //    $tmp['children'] = array();
183                 //} else {
184                     // if folder name matches search, we send back all files contained.
185                     $_search = $search;
186                     if ($search && stristr($tmp['title'], $search) !== false) {
187                         $_search = false;
188                     }
189                     $tmp['children'] = array();
190                     $_filecount = $this->build_tree($child, $_search, $dynamicmode, $tmp['children']);
191                     if ($search && $_filecount) {
192                         $tmp['expanded'] = 1;
193                     }
195                 //}
196                 
197                 if (!$search || $_filecount || (stristr($tmp['title'], $search) !== false)) {
198                     $list[] = $tmp;
199                     $filecount += $_filecount;
200                 }
202             } else { // not a directory
203                 // skip the file, if we're in search mode and it's not a match
204                 if ($search && (stristr($filename, $search) === false)) {
205                     continue;
206                 }
207                 $list[] = array(
208                     'title' => $filename,
209                     'size' => $filesize,
210                     'date' => $filedate,
211                     'source' => $child->get_url(),
212                     'thumbnail' => $CFG->pixpath .'/f/'. mimeinfo_from_type("icon", $filetype)
213                 );
214                 $filecount++;
215             }
216         }
218         return $filecount;
219     }
221       /**
222      * Download a file
223      * @global object $CFG
224      * @param string $url the url of file
225      * @param string $file save location
226      * @return string the location of the file
227      * @see curl package
228      */
229     public function get_file($url, $file = '') {
230         global $CFG, $DB, $USER;
231         require_once($CFG->dirroot . '/mnet/xmlrpc/client.php');
232         //retrieve the host url
233         $this->ensure_environment();
235         $host = $DB->get_record('mnet_host',array('id' => $this->options['peer']));
236         $mnetauth = get_auth_plugin('mnet');
237         $mnetauth->start_jump_session($host->id, '');
239         $mnet_peer = new mnet_peer();
240         $mnet_peer->set_wwwroot($host->wwwroot);
242         //connect to the remote moodle and retrieve the list of files
243         $client = new mnet_xmlrpc_client();
245         $client->set_method('system/retrieveFile');
246         $client->add_param($USER->username);
247         $client->add_param($url);
249         $client->send($mnet_peer);
251         $services = $client->response;
252         $content = base64_decode($services[0]);
253         $file = $services[1];
255         if (!file_exists($CFG->dataroot.'/temp/download')) {
256             mkdir($CFG->dataroot.'/temp/download/', 0777, true);
257         }
258         if (is_dir($CFG->dataroot.'/temp/download')) {
259             $dir = $CFG->dataroot.'/temp/download/';
260         }
261         if (empty($file)) {
262             $file = uniqid('repo').'_'.time().'.tmp';
263         }
264         if (file_exists($dir.$file)) {
265             $file = uniqid('m').$file;
266         }
267         
268         $fp = fopen($dir.$file, 'w');
269         fwrite($fp,$content);
270         fclose($fp);
271          
272         return $dir.$file;
273        
274     }
276     /**
277      * Add Instance settings input to Moodle form
278      * @param <type> $
279      */
280     public function instance_config_form(&$mform) {
281         global $CFG, $DB;
282         
283         //retrieve all peers
284         $hosts = $DB->get_records_sql('  SELECT
285                                     h.id,
286                                     h.wwwroot,
287                                     h.ip_address,
288                                     h.name,
289                                     h.public_key,
290                                     h.public_key_expires,
291                                     h.transport,
292                                     h.portno,
293                                     h.last_connect_time,
294                                     h.last_log_id,
295                                     h.applicationid,
296                                     a.name as app_name,
297                                     a.display_name as app_display_name,
298                                     a.xmlrpc_server_url
299                                 FROM {mnet_host} h
300                                     JOIN {mnet_application} a ON h.applicationid=a.id
301                                 WHERE
302                                     h.id <> ? AND
303                                     h.deleted = 0 AND
304                                     a.name = ?',
305                         array($CFG->mnet_localhost_id, 'moodle'));
306         $peers = array();
307         foreach($hosts as $host) {
308             $peers[$host->id] = $host->name;        
309         }
311         $mform->addElement('select', 'peer', get_string('peer', 'repository_remotemoodle'),$peers);
312         $mform->addRule('peer', get_string('required'), 'required', null, 'client');
313     }
315     /**
316      * Names of the instance settings
317      * @return <type>
318      */
319     public static function get_instance_option_names() {
320         return array('peer');
321     }
323 ?>