From ef378cdcf472532b401e8ea6268263a422d6b761 Mon Sep 17 00:00:00 2001 From: jerome Date: Thu, 23 Oct 2008 08:14:23 +0000 Subject: [PATCH] MDL-15352: doesn't use anymore mnet system function, implemeted new mnet function, remote moodle service will appear into the peer service --- admin/mnet/adminlib.php | 12 ++ lang/en_utf8/repository_remotemoodle.php | 3 + mnet/xmlrpc/client.php | 2 +- mnet/xmlrpc/server.php | 178 ++-------------- repository/remotemoodle/repository.class.php | 210 +++++++++++++++++-- 5 files changed, 231 insertions(+), 174 deletions(-) diff --git a/admin/mnet/adminlib.php b/admin/mnet/adminlib.php index 2e91159e6c..2725cfb701 100644 --- a/admin/mnet/adminlib.php +++ b/admin/mnet/adminlib.php @@ -41,6 +41,12 @@ function mnet_get_functions($type, $parentname) { $filename = $CFG->dirroot . $relname; require_once($CFG->libdir . '/portfoliolib.php'); $publishes = (array)portfolio_static_function($parentname, 'mnet_publishes'); + } else if ('repository' == $type) { + $docname = 'repository.class.php'; + $relname = '/repository/' . $parentname . '/'. $docname; + $filename = $CFG->dirroot . $relname; + require_once($CFG->dirroot . '/repository/lib.php'); + $publishes = (array)repository_static_function($parentname, 'mnet_publishes'); } else { // auth or enrol $relname = '/'.$type.'/'.$parentname.'/'.$docname; @@ -191,5 +197,11 @@ function upgrade_RPC_functions($returnurl) { mnet_get_functions('portfolio', $p); } } + + if ($plugins = get_list_of_plugins('repository')) { + foreach ($plugins as $p) { + mnet_get_functions('repository', $p); + } + } } ?> diff --git a/lang/en_utf8/repository_remotemoodle.php b/lang/en_utf8/repository_remotemoodle.php index 41b463711f..9b79b39981 100644 --- a/lang/en_utf8/repository_remotemoodle.php +++ b/lang/en_utf8/repository_remotemoodle.php @@ -6,3 +6,6 @@ $string['notitle'] = 'notitle'; $string['peer'] = 'Peer'; $string['remember'] = 'Remember me'; $string['emptyfilelist'] = 'There are no files to show'; +$string['remoterep_name'] = 'Remote Moodle Repository'; +$string['remoterep_description'] = 'Allow the service to be discovered

'; +$string['connectionfailure'] = 'Failed to retrieve file listing - The host moodle has either a version older than 2.0, either its Moodle Remote Repository service hasn\'t been activated'; \ No newline at end of file diff --git a/mnet/xmlrpc/client.php b/mnet/xmlrpc/client.php index 0c34724fcf..c45c154650 100644 --- a/mnet/xmlrpc/client.php +++ b/mnet/xmlrpc/client.php @@ -293,7 +293,7 @@ class mnet_xmlrpc_client { global $DB, $CFG; // Executing any system method is permitted. - $system_methods = array('system/listMethods', 'system/methodSignature', 'system/methodHelp', 'system/listServices', 'system/listFiles', 'system/retrieveFile'); + $system_methods = array('system/listMethods', 'system/methodSignature', 'system/methodHelp', 'system/listServices'); if (in_array($this->method, $system_methods) ) { return true; } diff --git a/mnet/xmlrpc/server.php b/mnet/xmlrpc/server.php index 4b09b34022..efa100d0cc 100644 --- a/mnet/xmlrpc/server.php +++ b/mnet/xmlrpc/server.php @@ -367,7 +367,7 @@ function mnet_server_dispatch($payload) { // Whitelist characters that are permitted in a method name // The method name must not begin with a / - avoid absolute paths // A dot character . is only allowed in the filename, i.e. something.php - if (0 == preg_match("@^[A-Za-z0-9]+/[A-Za-z0-9/_-]+(\.php/)?[A-Za-z0-9_-]+$@",$method)) { + if (0 == preg_match("@^[A-Za-z0-9]+/[A-Za-z0-9/_\.-]+(\.php/)?[A-Za-z0-9_-]+$@",$method)) { exit(mnet_server_fault(713, 'nosuchfunction')); } @@ -497,6 +497,22 @@ function mnet_server_dispatch($payload) { exit(mnet_server_fault(7012, 'nosuchfunction')); } + } else if ($callstack[0] == 'repository') { + // Break out the callstack into its elements + list($base, $plugin, $filename, $methodname) = $callstack; + + if ($filename == 'repository.class.php') { + $pluginclass = 'repository_' . $plugin; + $includefile = '/repository/'.$plugin.'/repository.class.php'; + debugging(print_r($includefile,true)); + $response = mnet_server_invoke_method($includefile, $methodname, $method, $payload, $pluginclass); + $response = mnet_server_prepare_response($response); + echo $response; + } else { + // Generate error response - unable to locate function + exit(mnet_server_fault(7012, 'nosuchfunction')); + } + ////////////////////////////////////// STRICT MOD/* } elseif ($callstack[0] == 'mod' || 'dangerous' == $CFG->mnet_dispatcher_mode) { list($base, $module, $filename, $functionname) = $callstack; @@ -698,168 +714,10 @@ function mnet_system($method, $params, $hostinfo) { } return $services; - } elseif ('system/retrieveFile' == $method) { - global $DB, $USER; - - $USER = $DB->get_record('user',array('username' => $params[0], 'mnethostid' => $hostinfo->id)); - $pathnamehash = $params[1]; - $fs = get_file_storage(); - - $sf = $fs->get_file_by_hash($pathnamehash); - - $contents = base64_encode($sf->get_content()); - - return array($contents, $sf->get_filename()); - } elseif ('system/listFiles' == $method) { - - global $DB, $USER; - - $USER = $DB->get_record('user',array('username' => $params[0], 'mnethostid' => $hostinfo->id)); - - $ret = array(); - $search = ''; - // no login required - $ret['nologin'] = true; - // todo: link to file manager - $ret['manage'] = $CFG->wwwroot .'/files/index.php'; // temporary - - $browser = get_file_browser(); - $itemid = null; - $filename = null; - $filearea = null; - $path = '/'; - $ret['dynload'] = false; - - if ($fileinfo = $browser->get_file_info(get_system_context(), $filearea, $itemid, $path, $filename)) { - - $ret['path'] = array(); - $params = $fileinfo->get_params(); - $filearea = $params['filearea']; - //todo: fix this call, and similar ones here and in build_tree - encoding path works only for real folders - $ret['path'][] = _encode_path($filearea, $path, $fileinfo->get_visible_name()); - if ($fileinfo->is_directory()) { - $level = $fileinfo->get_parent(); - while ($level) { - $params = $level->get_params(); - $ret['path'][] = _encode_path($params['filearea'], $params['filepath'], $level->get_visible_name()); - $level = $level->get_parent(); - } - } - $filecount = build_tree($fileinfo, $search, $ret['dynload'], $ret['list']); - $ret['path'] = array_reverse($ret['path']); - } else { - // throw some "context/filearea/item/path/file not found" exception? - } - - if (empty($ret['list'])) { - throw new repository_exception('emptyfilelist', 'repository_local'); - } else { - return $ret; - } - } + } exit(mnet_server_fault(7019, 'nosuchfunction')); } - /** - * - * @param $filearea - * @param $path - * @param $visiblename - * @return - */ - function _encode_path($filearea, $path, $visiblename) { - return array('path'=>serialize(array($filearea, $path)), 'name'=>$visiblename); - } - - /** - * Builds a tree of files, to be used by get_listing(). This function is - * then called recursively. - * - * @param $fileinfo an object returned by file_browser::get_file_info() - * @param $search searched string - * @param $dynamicmode bool no recursive call is done when in dynamic mode - * @param $list - the array containing the files under the passed $fileinfo - * @returns int the number of files found - * - * todo: take $search into account, and respect a threshold for dynamic loading - */ - function build_tree($fileinfo, $search, $dynamicmode, &$list) { - global $CFG; - - $filecount = 0; - $children = $fileinfo->get_children(); - - foreach ($children as $child) { - $filename = $child->get_visible_name(); - $filesize = $child->get_filesize(); - $filesize = $filesize ? display_size($filesize) : ''; - $filedate = $child->get_timemodified(); - $filedate = $filedate ? userdate($filedate) : ''; - $filetype = $child->get_mimetype(); - - if ($child->is_directory()) { - $path = array(); - $level = $child->get_parent(); - while ($level) { - $params = $level->get_params(); - $path[] = _encode_path($params['filearea'], $params['filepath'], $level->get_visible_name()); - $level = $level->get_parent(); - } - - $tmp = array( - 'title' => $child->get_visible_name(), - 'size' => 0, - 'date' => $filedate, - 'path' => array_reverse($path), - 'thumbnail' => $CFG->pixpath .'/f/folder.gif' - ); - - - $_search = $search; - if ($search && stristr($tmp['title'], $search) !== false) { - $_search = false; - } - $tmp['children'] = array(); - $_filecount = build_tree($child, $_search, $dynamicmode, $tmp['children']); - if ($search && $_filecount) { - $tmp['expanded'] = 1; - } - - - - if (!$search || $_filecount || (stristr($tmp['title'], $search) !== false)) { - $list[] = $tmp; - $filecount += $_filecount; - } - - } else { // not a directory - // skip the file, if we're in search mode and it's not a match - if ($search && (stristr($filename, $search) === false)) { - continue; - } - - //retrieve the stored file id - $fs = get_file_storage(); - $params = $child->get_params(); - - $pathnamehash = $fs->get_pathname_hash($params['contextid'], $params['filearea'], $params['itemid'], $params['filepath'], $params['filename']); - - - $list[] = array( - 'title' => $filename, - 'size' => $filesize, - 'date' => $filedate, - 'source' => $pathnamehash, - 'thumbnail' => $CFG->pixpath .'/f/'. mimeinfo_from_type("icon", $filetype) - ); - - $filecount++; - } - } - - return $filecount; - } - /** * Initialize the object (if necessary), execute the method or function, and * return the response diff --git a/repository/remotemoodle/repository.class.php b/repository/remotemoodle/repository.class.php index ce5e30654c..f6abdd784a 100644 --- a/repository/remotemoodle/repository.class.php +++ b/repository/remotemoodle/repository.class.php @@ -6,7 +6,7 @@ * @version $Id$ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License */ - +require_once($CFG->dirroot.'/repository/lib.php'); /** * */ @@ -24,13 +24,180 @@ class repository_remotemoodle extends repository { public function __construct($repositoryid, $context = SITEID, $options = array()) { global $SESSION, $action, $CFG; parent::__construct($repositoryid, $context, $options); - // TODO: - // get the parameter from client side - // $this->context can be used here. - // When user upload a file, $action == 'upload' - // You can use $_FILES to find that file } + public static function mnet_publishes() { + $pf= array(); + $pf['name'] = 'remoterep'; // Name & Description go in lang file + $pf['apiversion'] = 1; + $pf['methods'] = array('getFileList', 'retrieveFile'); + + return array($pf); + } + + public static function retrieveFile($username, $pathnamehash) { + global $DB, $USER, $MNET_REMOTE_CLIENT; + + // $USER = $DB->get_record('user',array('username' => $username, 'mnethostid' => $MNET_REMOTE_CLIENT->id)); + + $fs = get_file_storage(); + + $sf = $fs->get_file_by_hash($pathnamehash); + + $contents = base64_encode($sf->get_content()); + + return array($contents, $sf->get_filename()); + } + + public static function getFileList($username) { + global $DB, $USER, $MNET_REMOTE_CLIENT; + + $USER = $DB->get_record('user',array('username' => $username, 'mnethostid' => $MNET_REMOTE_CLIENT->id)); + + $ret = array(); + $search = ''; + // no login required + $ret['nologin'] = true; + // todo: link to file manager + $ret['manage'] = $CFG->wwwroot .'/files/index.php'; // temporary + + $browser = get_file_browser(); + $itemid = null; + $filename = null; + $filearea = null; + $path = '/'; + $ret['dynload'] = false; + + if ($fileinfo = $browser->get_file_info(get_system_context(), $filearea, $itemid, $path, $filename)) { + + $ret['path'] = array(); + $params = $fileinfo->get_params(); + $filearea = $params['filearea']; + //todo: fix this call, and similar ones here and in build_tree - encoding path works only for real folders + $ret['path'][] = _encode_path($filearea, $path, $fileinfo->get_visible_name()); + if ($fileinfo->is_directory()) { + $level = $fileinfo->get_parent(); + while ($level) { + $params = $level->get_params(); + $ret['path'][] = _encode_path($params['filearea'], $params['filepath'], $level->get_visible_name()); + $level = $level->get_parent(); + } + } + $filecount = build_tree($fileinfo, $search, $ret['dynload'], $ret['list']); + $ret['path'] = array_reverse($ret['path']); + } else { + // throw some "context/filearea/item/path/file not found" exception? + } + + if (empty($ret['list'])) { + throw new repository_exception('emptyfilelist', 'repository_local'); + } else { + return $ret; + } + //return "toto"; + } + + /** + * + * @param $filearea + * @param $path + * @param $visiblename + * @return + */ + function _encode_path($filearea, $path, $visiblename) { + return array('path'=>serialize(array($filearea, $path)), 'name'=>$visiblename); + } + + /** + * Builds a tree of files, to be used by get_listing(). This function is + * then called recursively. + * + * @param $fileinfo an object returned by file_browser::get_file_info() + * @param $search searched string + * @param $dynamicmode bool no recursive call is done when in dynamic mode + * @param $list - the array containing the files under the passed $fileinfo + * @returns int the number of files found + * + * todo: take $search into account, and respect a threshold for dynamic loading + */ + function build_tree($fileinfo, $search, $dynamicmode, &$list) { + global $CFG; + + $filecount = 0; + $children = $fileinfo->get_children(); + + foreach ($children as $child) { + $filename = $child->get_visible_name(); + $filesize = $child->get_filesize(); + $filesize = $filesize ? display_size($filesize) : ''; + $filedate = $child->get_timemodified(); + $filedate = $filedate ? userdate($filedate) : ''; + $filetype = $child->get_mimetype(); + + if ($child->is_directory()) { + $path = array(); + $level = $child->get_parent(); + while ($level) { + $params = $level->get_params(); + $path[] = _encode_path($params['filearea'], $params['filepath'], $level->get_visible_name()); + $level = $level->get_parent(); + } + + $tmp = array( + 'title' => $child->get_visible_name(), + 'size' => 0, + 'date' => $filedate, + 'path' => array_reverse($path), + 'thumbnail' => $CFG->pixpath .'/f/folder.gif' + ); + + + $_search = $search; + if ($search && stristr($tmp['title'], $search) !== false) { + $_search = false; + } + $tmp['children'] = array(); + $_filecount = build_tree($child, $_search, $dynamicmode, $tmp['children']); + if ($search && $_filecount) { + $tmp['expanded'] = 1; + } + + + + if (!$search || $_filecount || (stristr($tmp['title'], $search) !== false)) { + $list[] = $tmp; + $filecount += $_filecount; + } + + } else { // not a directory + // skip the file, if we're in search mode and it's not a match + if ($search && (stristr($filename, $search) === false)) { + continue; + } + + //retrieve the stored file id + $fs = get_file_storage(); + $params = $child->get_params(); + + $pathnamehash = $fs->get_pathname_hash($params['contextid'], $params['filearea'], $params['itemid'], $params['filepath'], $params['filename']); + + + $list[] = array( + 'title' => $filename, + 'size' => $filesize, + 'date' => $filedate, + 'source' => $pathnamehash, + 'thumbnail' => $CFG->pixpath .'/f/'. mimeinfo_from_type("icon", $filetype) + ); + + $filecount++; + } + } + + return $filecount; + } + + /** * * @global $SESSION @@ -75,23 +242,39 @@ class repository_remotemoodle extends repository { */ public function get_listing($encodedpath = '', $search = '') { global $CFG, $DB, $USER; - + + //check that the host has a version >2.0 + require_once($CFG->dirroot . '/mnet/xmlrpc/client.php'); + $this->ensure_environment(); + $host = $DB->get_record('mnet_host',array('id' => $this->options['peer'])); + $mnet_peer = new mnet_peer(); + $mnet_peer->set_wwwroot($host->wwwroot); + $client = new mnet_xmlrpc_client(); + $client->set_method('system/listMethods'); + $client->send($mnet_peer); + $services = $client->response; + if (array_search('repository/remotemoodle/repository.class.php/getFileList', $services) === false) { + echo json_encode(array('e'=>get_string('connectionfailure','repository_remotemoodle'))); + exit; + } + require_once($CFG->dirroot . '/mnet/xmlrpc/client.php'); //retrieve the host url $this->ensure_environment(); $host = $DB->get_record('mnet_host',array('id' => $this->options['peer'])); - $mnetauth = get_auth_plugin('mnet'); - $url = $mnetauth->start_jump_session($host->id, ''); + // $mnetauth = get_auth_plugin('mnet'); + // $url = $mnetauth->start_jump_session($host->id, ''); $mnet_peer = new mnet_peer(); $mnet_peer->set_wwwroot($host->wwwroot); //connect to the remote moodle and retrieve the list of files + $client = new mnet_xmlrpc_client(); - $client->set_method('system/listFiles'); + $client->set_method('repository/remotemoodle/repository.class.php/getFileList'); $client->add_param($USER->username); $client->send($mnet_peer); @@ -127,7 +310,7 @@ class repository_remotemoodle extends repository { //connect to the remote moodle and retrieve the list of files $client = new mnet_xmlrpc_client(); - $client->set_method('system/retrieveFile'); + $client->set_method('repository/remotemoodle/repository.class.php/retrieveFile'); $client->add_param($USER->username); $client->add_param($url); @@ -186,8 +369,9 @@ class repository_remotemoodle extends repository { WHERE h.id <> ? AND h.deleted = 0 AND - a.name = ?', - array($CFG->mnet_localhost_id, 'moodle')); + a.name = ? AND + h.name <> ?', + array($CFG->mnet_localhost_id, 'moodle', 'All Hosts')); $peers = array(); foreach($hosts as $host) { $peers[$host->id] = $host->name; -- 2.39.5