"MDL-13766, fixed context default value"
[moodle.git] / repository / remotemoodle / repository.class.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * repository_remotemoodle class
20  * This plugin allowed to connect a retrieve a file from another Moodle site
21  * This is a subclass of repository class
22  *
23  * @since 2.0
24  * @package moodlecore
25  * @subpackage repository
26  * @copyright 2009 Jerome Mouneyrac
27  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28  */
30 require_once($CFG->dirroot.'/repository/lib.php');
33 class repository_remotemoodle extends repository {
35     /**
36      * Constructor of remotemoodle plugin, used to setup mnet environment
37      * @global object $SESSION
38      * @global object $CFG
39      * @param int $repositoryid
40      * @param object $context
41      * @param array $options
42      */
43     public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
44         global $SESSION, $CFG;
45         parent::__construct($repositoryid, $context, $options);
46         $this->mnet = get_mnet_environment();
47     }
49     /**
50      * Retrieve a file for a user of the Moodle client calling this function
51      * The file is encoded in base64
52      * @global object $DB
53      * @global object $USER
54      * @param string $username
55      * @param string $source
56      * @return array
57      */
58     public function retrieveFile($username, $source) {
59         global $DB, $USER;
61         $remoteclient = get_mnet_remote_client();
63         ///check the the user is known
64         ///he has to be previously connected to the server site in order to be in the database
65         //TODO: MDL-21318 this looks problematic, because global $USER would need to be set back after this,
66         //      also is the user allowed to roam?
67         $USER = $DB->get_record('user',array('username' => $username, 'mnethostid' => $remoteclient->id));
68         if (empty($USER)) {
69             throw new mnet_server_exception(9012, get_string('usernotfound', 'repository_remotemoodle',  $username));
70         }
72         $file = unserialize(base64_decode($source));
73         $contextid = $file[0];
74         $filearea = $file[1];
75         $itemid = $file[2];
76         $filepath = $file[3];
77         $filename = $file[4];
79         ///check that the user has read permission on this file
80         $browser = get_file_browser();
81         $fileinfo = $browser->get_file_info(get_context_instance_by_id($contextid), $filearea, $itemid, $filepath, $filename);
82         if (empty($fileinfo)) {
83             throw new mnet_server_exception(9013, get_string('usercannotaccess', 'repository_remotemoodle',  $file));
84         }
86         ///retrieve the file with file API functions and return it encoded in base64
87         $fs = get_file_storage();
88         $sf = $fs->get_file($contextid, $filearea, $itemid, $filepath, $filename);
89         $contents = base64_encode($sf->get_content());
90         return array($contents, $sf->get_filename());
91     }
93     /**
94      * Retrieve file list for a user of the Moodle client calling this function
95      * @global object $DB
96      * @global object $USER
97      * @global object $CFG
98      * @param string $username
99      * @param string $search
100      * @return array
101      */
102     public function getFileList($username, $search) {
103         global $DB, $USER, $CFG;
105         $remoteclient = get_mnet_remote_client();
106         ///check the the user is known
107         ///he has to be previously connected to the server site in order to be in the database
108         //TODO: MDL-21318 this looks problematic, because global $USER would need to be set back after this,
109         //      also is the user allowed to roam?
110         $USER = $DB->get_record('user',array('username' => $username, 'mnethostid' => $remoteclient->id));
111         if (empty($USER)) {
112             throw new mnet_server_exception(9012, get_string('usernotfound', 'repository_remotemoodle',  $username));
113         }
115         try {
116             return repository::get_user_file_tree($search);
117         }
118         catch (Exception $e) {
119             throw new mnet_server_exception(9014, get_string('failtoretrievelist', 'repository_remotemoodle'));
120         }
121     }
123     /**
124      * Display the file listing - no login required
125      * @return array
126      */
127     public function print_login() {
128         return $this->get_listing();
129     }
131     /**
132      * Display the file listing for the search term
133      * @param string $search_text
134      * @return array
135      */
136     public function search($search_text) {
137         return $this->get_listing('', '', $search_text);
138     }
140     /**
141      * Retrieve the file listing - file picker function
142      * @global object $CFG
143      * @global object $DB
144      * @global object $USER
145      * @param string $encodedpath
146      * @param string $search
147      * @return array
148      */
149     public function get_listing($encodedpath = '', $page = '', $search = '') {
150         global $CFG, $DB, $USER;
152         ///check that the host has a version >2.0
153         ///for that we check that the host has the getFileList() method implemented
154         ///We also check that this method has been activated (if it is not
155         ///the method will not be returned by the system method system/listMethods)
156         require_once($CFG->dirroot . '/mnet/xmlrpc/client.php');
158         ///check that the peer has been setup
159         if (!array_key_exists('peer',$this->options)) {
160             echo json_encode(array('e'=>get_string('error').' 9010: '.get_string('hostnotfound','repository_remotemoodle')));
161             exit;
162         }
164         $host = $DB->get_record('mnet_host',array('id' => $this->options['peer'])); //need to retrieve the host url
166         ///check that the peer host exists into the database
167         if (empty($host)) {
168            echo json_encode(array('e'=>get_string('error').' 9011: '.get_string('hostnotfound','repository_remotemoodle')));
169            exit;
170         }
172         $mnet_peer = new mnet_peer();
173         $mnet_peer->set_wwwroot($host->wwwroot);
174         $client = new mnet_xmlrpc_client();
175         $client->set_method('system/listMethods');
176         $client->send($mnet_peer);
177         $services = $client->response;
178         if (array_search('repository/remotemoodle/repository.class.php/getFileList', $services) === false) {
179             echo json_encode(array('e'=>get_string('connectionfailure','repository_remotemoodle')));
180             exit;
181         }
183         ///connect to the remote moodle and retrieve the list of files
184         $client->set_method('repository/remotemoodle/repository.class.php/getFileList');
185         $client->add_param($USER->username);
186         $client->add_param($search);
188         ///call the method and manage host error
189         if (!$client->send($mnet_peer)) {
190             $message =" ";
191             foreach ($client->error as $errormessage) {
192                 $message .= "ERROR: $errormessage . ";
193             }
194             echo json_encode(array('e'=>$message)); //display all error messages
195             exit;
196         }
198         $services = $client->response;
199         ///display error message if we could retrieve the list or if nothing were returned
200         if (empty($services)) {
201             echo json_encode(array('e'=>get_string('failtoretrievelist','repository_remotemoodle')));
202             exit;
203         }
205         return $services;
206     }
210     /**
211      * Download a file
212      * @global object $CFG
213      * @param string $url the url of file
214      * @param string $file save location
215      * @return string the location of the file
216      * @see curl package
217      */
218     public function get_file($url, $file = '') {
219         global $CFG, $DB, $USER;
221         ///set mnet environment and set the mnet host
222         require_once($CFG->dirroot . '/mnet/xmlrpc/client.php');
223         $host = $DB->get_record('mnet_host',array('id' => $this->options['peer'])); //retrieve the host url
224         $mnet_peer = new mnet_peer();
225         $mnet_peer->set_wwwroot($host->wwwroot);
227         ///create the client and set the method to call
228         $client = new mnet_xmlrpc_client();
229         $client->set_method('repository/remotemoodle/repository.class.php/retrieveFile');
230         $client->add_param($USER->username);
231         $client->add_param($url);
233         ///call the method and manage host error
234         if (!$client->send($mnet_peer)) {
235             $message =" ";
236             foreach ($client->error as $errormessage) {
237                 $message .= "ERROR: $errormessage . ";
238             }
239             echo json_encode(array('e'=>$message));
240             exit;
241         }
243         $services = $client->response; //service contains the file content in the first case of the array,
244                                        //and the filename in the second
246         //the content has been encoded in base64, need to decode it
247         $content = base64_decode($services[0]);
248         $file = $services[1]; //filename
250         ///create a temporary folder with a file
251         $path = $this->prepare_file($file);
252         ///fill the file with the content
253         $fp = fopen($path, 'w');
254         fwrite($fp,$content);
255         fclose($fp);
257         return $path;
259     }
261     /**
262      * Add Instance settings input to Moodle form
263      * @global object $CFG
264      * @global object $DB
265      * @param object $mform
266      */
267     public function instance_config_form($mform) {
268         global $CFG, $DB;
270         //retrieve only Moodle peers
271         $hosts = $DB->get_records_sql('  SELECT
272                                     h.id,
273                                     h.wwwroot,
274                                     h.ip_address,
275                                     h.name,
276                                     h.public_key,
277                                     h.public_key_expires,
278                                     h.transport,
279                                     h.portno,
280                                     h.last_connect_time,
281                                     h.last_log_id,
282                                     h.applicationid,
283                                     a.name as app_name,
284                                     a.display_name as app_display_name,
285                                     a.xmlrpc_server_url
286                                 FROM {mnet_host} h
287                                     JOIN {mnet_application} a ON h.applicationid=a.id
288                                 WHERE
289                                     h.id <> ? AND
290                                     h.deleted = 0 AND
291                                     a.name = ? AND
292                                     h.name <> ?',
293                         array($CFG->mnet_localhost_id, 'moodle', 'All Hosts'));
294         $peers = array();
295         foreach($hosts as $host) {
296             $peers[$host->id] = $host->name;
297         }
300         $mform->addElement('select', 'peer', get_string('peer', 'repository_remotemoodle'),$peers);
301         $mform->addRule('peer', get_string('required'), 'required', null, 'client');
303         if (empty($peers)) {
304             $mform->addElement('static', null, '',  get_string('nopeer','repository_remotemoodle'));
305         }
306     }
308     /**
309      * Names of the instance settings
310      * @return array
311      */
312     public static function get_instance_option_names() {
313         ///the administrator just need to set a peer
314         return array('peer');
315     }
316     public function supported_returntypes() {
317         return FILE_INTERNAL;
318     }