Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

MNet API: Difference between revisions

From MoodleDocs
m (Text replacement - "<code php>" to "<syntaxhighlight lang="php">")
 
(48 intermediate revisions by 5 users not shown)
Line 1: Line 1:
[[Category:MNET]]
==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.


==Introduction==
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.


This page aims to serve as the canonical location for documenting the 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.
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)
    • 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)