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">")
 
(36 intermediate revisions by 5 users not shown)
Line 1: Line 1:
[[Category:MNET]]
==Introduction==
==Introduction==


This page aims to serve as the canonical location for documenting the MNET API, both the XMLRPC functions and the associated code.   
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.''
<br><br>''It is a work in progress, please add to it as you discover undocumented code.''


== How does work MNET ==
== 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 wanna call in the server.
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===
=== Basic Client/Server code===
Line 31: Line 31:
         $client->set_method('system/listMethods'); //tell it which method we're going to call       
         $client->set_method('system/listMethods'); //tell it which method we're going to call       
         $client->send($mnet_peer);                //Call the server
         $client->send($mnet_peer);                //Call the server
         $services = $client->response;            //Receive the server response  
         $response = $client->response;            //Receive the server response  
 
        var_dump($response);
</Code>
</Code>


=== System methods ===
=== 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 ===
=== 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 91: Line 190:
** 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 99: 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)