MNet API: Difference between revisions
Penny Leach (talk | contribs) |
David Mudrak (talk | contribs) m (Text replacement - "<code php>" to "<syntaxhighlight lang="php">") |
||
(48 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
==Introduction== | |||
This page aims to serve as the location for documenting the Moodle NETwork API (MNET API), both the XMLRPC functions and the associated code. | |||
<br><br>''It is a work in progress, please add to it as you discover undocumented code.'' | |||
== How to use MNET == | |||
This paragraph will explain you how to setup a connection between a client and a server with mnet. It will also explain where to write the functions you want to call in the server. | |||
''Note: The following code is just here to give you a better idea of how the API works. Do not expect them to work as provided.'' | |||
=== Basic Client/Server code=== | |||
In this example we'll ask the server which methods we can access. The system server methods 'ListMethods' is already implemented, so we will only write client code: | |||
<Code php> | |||
require_once($CFG->dirroot . '/mnet/xmlrpc/client.php'); //mnet client library | |||
/// Setup MNET environment | |||
global $MNET; | |||
if (empty($MNET)) { | |||
$MNET = new mnet_environment(); | |||
$MNET->init(); | |||
} | |||
/// Setup the server | |||
$host = $DB->get_record('mnet_host',array('id' => 4)); //we retrieve the server(host) from the 'mnet_host' table | |||
$mnet_peer = new mnet_peer(); //we create a new mnet_peer (server/host) | |||
$mnet_peer->set_wwwroot($host->wwwroot); //we set this mnet_peer with the host http address | |||
/// Connect to the remote moodle and retrieve the list of methods (synchronous transmission) | |||
$client = new mnet_xmlrpc_client(); //create a new client | |||
$client->set_method('system/listMethods'); //tell it which method we're going to call | |||
$client->send($mnet_peer); //Call the server | |||
$response = $client->response; //Receive the server response | |||
var_dump($response); | |||
</Code> | |||
=== System methods === | |||
System methods are declared as available into /mnet/xmlrpc/client.php::permission_to_call(). If you add a new system method you will have to add its name to the system_methods array into this function. | |||
== | A mnet server comes with few system methods which have been implemented into /mnet/xmlrpc/server.php::mnet_system()<br> | ||
Parameters are saved into the $params array. Your first $client->add_param($param1) we'll be in $params[0] etc. | |||
=== Specific methods === | |||
Most of the time you don't want to add a system method but a method for a module/service. You also want it to be displayed by the "ListMethods" system method. | |||
Let's implement a function returning "Hello World". | |||
1. We create this function into servicefolder/services.php: | |||
<syntaxhighlight lang="php"> | |||
class services { | |||
function static helloWorld($firstname, $surname) { | |||
return "Hello World" . $firstname . $surname; //note that we could return an array, | |||
//it would still be managed by mnet without a change anywhere else | |||
} | |||
} | |||
</syntaxhighlight> | |||
2. We register this function as a mnet function into the database:<br> | |||
Into admin/mnet/adminlib.php, we add this code: | |||
<syntaxhighlight lang="php"> | |||
function mnet_get_functions($type, $parentname) { | |||
... | |||
else if ('service' == $type) { | |||
/// we're going to load the service object (after having checked it exists) | |||
/// and call mnet_publishes function | |||
$docname = 'services.php'; | |||
$relname = '/servicefolder/'. $docname; | |||
$filename = $CFG->dirroot.$relname; | |||
if (file_exists($filename)) include_once $filename; | |||
$class = "services"; | |||
if (class_exists($class)) { | |||
$object = new $class(); | |||
if (method_exists($object, 'mnet_publishes')) { | |||
(array)$publishes = $object->mnet_publishes(); //retrieve the service information | |||
} | |||
} | |||
} | |||
... | |||
///below, the retrieved information are saved into the database | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="php"> | |||
function upgrade_RPC_functions($returnurl) { | |||
... | |||
/// check other mnet_get_functions calls into the same file | |||
mnet_get_functions('service', null); | |||
} | |||
*/ | |||
</syntaxhighlight> | |||
Into the ''Service'' class of servicefolder/services.php, add | |||
<syntaxhighlight lang="php"> | |||
public static function mnet_publishes() { | |||
$service= array(); | |||
$service['name'] = 'service'; // Name & Description go in lang file | |||
$service['apiversion'] = 1; | |||
$service['methods'] = array('helloWorld'); | |||
return array($service); | |||
} | |||
</syntaxhighlight> | |||
3. The server needs to dispatch | |||
in mnet/xmlrpc/server.php::mnet_server_dispatch(), we need to add: | |||
<syntaxhighlight lang="php"> | |||
else if ($callstack[0] == 'servicefolder') { | |||
list($base, $filename, $methodname) = $callstack; // Break out the callstack into its elements | |||
if ($filename == 'services.php') { | |||
$response = mnet_server_invoke_method('/servicefolder/services.php', $methodname, $method, $payload, 'services'); | |||
$response = mnet_server_prepare_response($response); | |||
echo $response; | |||
} else { | |||
/// Generate error response - unable to locate function | |||
exit(mnet_server_fault(7012, 'nosuchfunction')); | |||
} | |||
} | |||
</syntaxhighlight> | |||
4. We add the method to the "ListMethods" system method<br> | |||
No code is needed. Just go into the Moodle Administration > Networking > Peers. Select the ''Services'' tab from the host server. There, activate your service. | |||
5. We write some client code<br> | |||
First of all test the code from the section "Client/Server" above. You should see "''servicefolder/services.php/helloworld''" function into the response. | |||
We can now call this method. Change: | |||
<syntaxhighlight lang="php"> | |||
$client->set_method('system/listMethods'); | |||
</syntaxhighlight> | |||
For: | |||
<syntaxhighlight lang="php"> | |||
$client->set_method('servicefolder/services.php/helloworld'); | |||
$client->add_param('Thierry'); | |||
$client->add_param('Henry'); | |||
</syntaxhighlight> | |||
==Entry points/XMLRPC documentation== | ==Entry points/XMLRPC documentation== | ||
Line 13: | Line 146: | ||
==Authentication Functions== | ==Authentication Functions== | ||
TODO | Documentation TODO | ||
==Enrolment Functions== | ==Enrolment Functions== | ||
TODO | Documentation TODO | ||
== Repository Functions == | |||
Documentation TODO | |||
==Portfolio Functions== | ==Portfolio Functions== | ||
Line 49: | Line 186: | ||
**** zipfilesha1: sha1 of the zipfile containing the file(s) | **** zipfilesha1: sha1 of the zipfile containing the file(s) | ||
**** zipfilesize: size of the zipfile containing the file(s) | **** zipfilesize: size of the zipfile containing the file(s) | ||
** wait: boolean. whether the remote system is expected to immediately launch a request to fetch file or queue it for cron. | ** wait: boolean. whether the remote system is expected to immediately launch a request to fetch file or queue it for cron. | ||
* Returns: Stdclass object with keys: | * Returns: Stdclass object with keys: | ||
** status: boolean, success or failure | ** status: boolean, success or failure | ||
** type: string, 'queued' or 'complete' | ** type: string, 'queued' or 'complete' | ||
** querystring: string, used for the final 'continue to portfolio' link (eg ?folder=6&file=6 to highlight new files that were added) | |||
===fetch_file=== | ===fetch_file=== | ||
Line 61: | Line 199: | ||
** token: string, same that was returned in send_content_intent and used subsequently in send_content_ready | ** token: string, same that was returned in send_content_intent and used subsequently in send_content_ready | ||
* Returns: base64 encoded file (currently a zipfile, as can include multiple files) | * Returns: base64 encoded file (currently a zipfile, as can include multiple files) | ||
[[Category:MNet]] |
Latest revision as of 13:38, 14 July 2021
Introduction
This page aims to serve as the location for documenting the Moodle NETwork API (MNET API), both the XMLRPC functions and the associated code.
It is a work in progress, please add to it as you discover undocumented code.
How to use MNET
This paragraph will explain you how to setup a connection between a client and a server with mnet. It will also explain where to write the functions you want to call in the server.
Note: The following code is just here to give you a better idea of how the API works. Do not expect them to work as provided.
Basic Client/Server code
In this example we'll ask the server which methods we can access. The system server methods 'ListMethods' is already implemented, so we will only write client code:
require_once($CFG->dirroot . '/mnet/xmlrpc/client.php'); //mnet client library
/// Setup MNET environment
global $MNET;
if (empty($MNET)) {
$MNET = new mnet_environment();
$MNET->init();
}
/// Setup the server
$host = $DB->get_record('mnet_host',array('id' => 4)); //we retrieve the server(host) from the 'mnet_host' table
$mnet_peer = new mnet_peer(); //we create a new mnet_peer (server/host)
$mnet_peer->set_wwwroot($host->wwwroot); //we set this mnet_peer with the host http address
/// Connect to the remote moodle and retrieve the list of methods (synchronous transmission)
$client = new mnet_xmlrpc_client(); //create a new client
$client->set_method('system/listMethods'); //tell it which method we're going to call
$client->send($mnet_peer); //Call the server
$response = $client->response; //Receive the server response
var_dump($response);
System methods
System methods are declared as available into /mnet/xmlrpc/client.php::permission_to_call(). If you add a new system method you will have to add its name to the system_methods array into this function.
A mnet server comes with few system methods which have been implemented into /mnet/xmlrpc/server.php::mnet_system()
Parameters are saved into the $params array. Your first $client->add_param($param1) we'll be in $params[0] etc.
Specific methods
Most of the time you don't want to add a system method but a method for a module/service. You also want it to be displayed by the "ListMethods" system method.
Let's implement a function returning "Hello World".
1. We create this function into servicefolder/services.php:
class services {
function static helloWorld($firstname, $surname) {
return "Hello World" . $firstname . $surname; //note that we could return an array,
//it would still be managed by mnet without a change anywhere else
}
}
2. We register this function as a mnet function into the database:
Into admin/mnet/adminlib.php, we add this code:
function mnet_get_functions($type, $parentname) {
...
else if ('service' == $type) {
/// we're going to load the service object (after having checked it exists)
/// and call mnet_publishes function
$docname = 'services.php';
$relname = '/servicefolder/'. $docname;
$filename = $CFG->dirroot.$relname;
if (file_exists($filename)) include_once $filename;
$class = "services";
if (class_exists($class)) {
$object = new $class();
if (method_exists($object, 'mnet_publishes')) {
(array)$publishes = $object->mnet_publishes(); //retrieve the service information
}
}
}
...
///below, the retrieved information are saved into the database
function upgrade_RPC_functions($returnurl) {
...
/// check other mnet_get_functions calls into the same file
mnet_get_functions('service', null);
}
*/
Into the Service class of servicefolder/services.php, add
public static function mnet_publishes() {
$service= array();
$service['name'] = 'service'; // Name & Description go in lang file
$service['apiversion'] = 1;
$service['methods'] = array('helloWorld');
return array($service);
}
3. The server needs to dispatch in mnet/xmlrpc/server.php::mnet_server_dispatch(), we need to add:
else if ($callstack[0] == 'servicefolder') {
list($base, $filename, $methodname) = $callstack; // Break out the callstack into its elements
if ($filename == 'services.php') {
$response = mnet_server_invoke_method('/servicefolder/services.php', $methodname, $method, $payload, 'services');
$response = mnet_server_prepare_response($response);
echo $response;
} else {
/// Generate error response - unable to locate function
exit(mnet_server_fault(7012, 'nosuchfunction'));
}
}
4. We add the method to the "ListMethods" system method
No code is needed. Just go into the Moodle Administration > Networking > Peers. Select the Services tab from the host server. There, activate your service.
5. We write some client code
First of all test the code from the section "Client/Server" above. You should see "servicefolder/services.php/helloworld" function into the response.
We can now call this method. Change:
$client->set_method('system/listMethods');
For:
$client->set_method('servicefolder/services.php/helloworld');
$client->add_param('Thierry');
$client->add_param('Henry');
Entry points/XMLRPC documentation
The entry point is wwwroot/xmlrpc/server.php, which at some point calls mnet_permit_rpc_call, which sets some member variables in the MNET_REMOTE_CLIENT object (mnet/remote_client.php) so that later when mnet_server_dummy_method is called, it can dispatch the call accordingly. I think mnet_server_dummy_method is the only way functions get called.
Currently you can call class methods, static methods and functions. However, for a class method, there is currently only support to construct the object with no constructor arguments.
Authentication Functions
Documentation TODO
Enrolment Functions
Documentation TODO
Repository Functions
Documentation TODO
Portfolio Functions
send_content_intent
- Defined in: portfolio/type/mahara/lib.php
- Implemented in: Mahara. Moodle has this function but it is not an xmlrpc function, only a helper function to call the xmlrpc function in Mahara. (See MDL-16269)
- Parameters:
- username: username of user to find or create
- Returns: Stdclass object with keys:
- sendtype: string - either 'queue' or 'immediate' depending on what the remote system has decided
- token: string - to use for all further communication
send_content_ready
- Defined in: portfolio/type/mahara/lib.php
- Implemented in: Mahara. Moodle has this function but it is not an xmlrpc function, only a helper function to call the xmlrpc function in Mahara. (See MDL-16269)
- Parameters:
- token: string, previously return from from send_content_intent
- username: string, username of user to find
- format: string: currently just 'file', could be more later
- data: keyed array, information per format
- shared keys, expected by all formats:
- totalsize: total filesize of included files (in bytes) - used for quota checks
- 'file' format keys:
- filesmanifest: keyed array of file information (keyed by filename):
- filename: desired name of file
- sha1: sha1 of file
- size: size of file (in bytes)
- zipfilesha1: sha1 of the zipfile containing the file(s)
- zipfilesize: size of the zipfile containing the file(s)
- filesmanifest: keyed array of file information (keyed by filename):
- shared keys, expected by all formats:
- wait: boolean. whether the remote system is expected to immediately launch a request to fetch file or queue it for cron.
- Returns: Stdclass object with keys:
- status: boolean, success or failure
- type: string, 'queued' or 'complete'
- querystring: string, used for the final 'continue to portfolio' link (eg ?folder=6&file=6 to highlight new files that were added)
fetch_file
- Defined in: portfolio/type/mahara/lib.php
- Implemented in: Moodle.
- Parameters:
- token: string, same that was returned in send_content_intent and used subsequently in send_content_ready
- Returns: base64 encoded file (currently a zipfile, as can include multiple files)