Having got the "hello World" 'wstemplate' Web-service plugin working as described in last night's post, I tried modifying it to create a function of my own, that doubles its argument. This is how. I'd unzipped the plugin into a directory called wstemplate. First, I edited wstemplate/externallib.php:
require_once($CFG->libdir . "/externallib.php");
class local_jnip_external extends external_api
{
/**
* Returns description of method parameters.
* @return external_function_parameters
*/
public static function double_parameters()
{
return new external_function_parameters(
array( 'n' => new external_value( PARAM_TEXT
, 'The number to be doubled.'
)
)
);
}
/**
* Returns welcome message.
* @return string welcome message
*/
public static function double( $n )
{
global $USER;
// Parameter validation.
// REQUIRED.
$params = self::validate_parameters( self::double_parameters()
, array( 'n' => $n )
);
// Context validation.
// OPTIONAL. Not needed for this function.
// Capability checking.
// OPTIONAL. Not needed for this function.
return $params['n'] * 2;
}
/**
* Returns description of method result value.
* @return external_description
*/
public static function double_returns()
{
return new external_value( PARAM_TEXT, 'The argument doubled.' );
}
}
In the above, I've changed the classname to local_jnip_external. (My initials are JNIP). I've replaced 'hello_world' by 'double' in the names of the three functions above. I've also altered the parameter and result descriptions so that they described double's argument and result. Unlike hello_world, double doesn't have a default value for its parameter, so I have removed that part of the parameter description. The parameter name, I've changed to 'n'.
And I've removed the capability check at the end of 'double'. I don't know how likely one would be to write some kind of arithmetic Web service in real life -- perhaps one would for a statistics add-on -- but I can't see that any security checks are needed at all. Therefore, I have also removed the context validation.
Next, I edited wstemplate/db/services.php:
// We define the Web-service functions to install.
//
$functions = array(
'local_jnip_double' => array(
'classname' => 'local_jnip_external',
'methodname' => 'double',
'classpath' => 'local/jnip/externallib.php',
'description' => 'Doubles its argument.',
'type' => 'read',
)
);
// We define the services to install as pre-built services.
// A pre-built service is not editable by the administrator.
//
$services = array(
"Jocelyn's service" => array(
'functions' => array ('local_jnip_double'),
'restrictedusers' => 0,
'enabled'=>1,
)
);
Here, I've changed the outer key in the $functions array to local_jnip_double, and the class name, method name, class path, and description in the inner array to their new values. In the $services array, I've changed the service name and function name.
I left wstemplate/version.php and wstemplate/lang/en/local_wstemplate.php alone. Then I changed the directory name from wstemplate to jnip, so that on my Moodle's Linux host, it sat at /var/www/moodle/moodle/local/jnip/ .
To make Moodle install the plugin, I went to Site administration > Notifications. Moodle had noticed the new directory, and showed it to me in a plugins table. I pressed the Upgrade button on that page, and then Continue on the next page.
I then went to Site administration > Plugins > Web services > External services, and saw a table listing my services, including a row for "Jocelyn's service". I clicked on the Functions link -- and got an error saying that the description of the return value was corrupt. I'd mistyped it. So I corrected it in externallib.php . (The code above shows the corrected one.) Then I had to make Moodle notice this update. I remembered reading that it notices when the version number in a version.php file has been increased. So I edited wstemplate/version.php. The original version, the one I'd copied from wstemplate, looked like this:
$plugin->version = 2011101202; // The (date) version of this module + 2 extra digital for daily versions
// This version number is displayed into /admin/forms.php
// TODO: if ever this plugin get branched, the old branch number
// will not be updated to the current date but just incremented. We will
// need then a $plugin->release human friendly date. For the moment, we use
// display this version number with userdate (dev friendly)
$plugin->requires = 2010112400; // Requires this Moodle version - at least 2.0
$plugin->cron = 0;
$plugin->release = '1.0 (Build: 2011101202)';
$plugin->maturity = MATURITY_STABLE;
I wasn't really sure what to do -- I've never seen a Moodle document about the correct care and feeding of version files -- but it seemed reasonable to replace both occurrences of 2011101202 by 2011101203. I then went back to Site administration > Notifications. Again, Moodle showed me the table of plugins, saying that this one needed upgrading. So it had noticed the change. I pressed Upgrade, and then Continue.
For my client, I wrote this program:
echo "Demo of Web service doubling function using REST\n"; echo "================================================\n"; $token = '401eae223b346c10c3298d74itv7ddf5'; $domain = 'http://moodle.ireson-paine.com'; $n = 5; $function_name = 'local_jnip_double'; $params = array( 'n' => $n ); $serverurl = $domain . '/webservice/rest/server.php'. '?wstoken=' . $token . '&wsfunction='.$function_name; require_once( './curl.php' ); $curl = new curl; echo "\nAbout to call function.\n"; $response = $curl->post( $serverurl, $params ); echo "\nCalled function.\n"; echo "\nResponse = $response.\n";
The token in it, I made by going to Site administration > Plugins > Web services > Manage tokens, and adding a new token for my Web-services user and the service called "Jocelyn's service".
And running the client produced this output:
Demo of Web service doubling function using REST ================================================ About to call function. Called function. Response = <?xml version="1.0" encoding="UTF-8" ?> <RESPONSE> <VALUE>10</VALUE> </RESPONSE> .
I also tried an XML-RPC version of the client, like this:
echo "Demo of Web service doubling function using XML-RPC\n"; echo "===================================================\n"; $token = '401eae223b346c10c3298d74itv7ddf5'; $domain = 'http://moodle.ireson-paine.com'; $n = 5; $function_name = 'local_jnip_double'; $params = array( $n ); $serverurl = $domain . '/webservice/xmlrpc/server.php'. '?wstoken=' . $token . '&wsfunction='.$function_name; require_once( './curl.php' ); $curl = new curl; echo "\nAbout to call function.\n"; $post = xmlrpc_encode_request( $function_name, $params ); $response = xmlrpc_decode($curl->post($serverurl, $post)); echo "\nCalled function.\n"; echo "\nResponse = "; print_r($response); echo ".\n";
But I got an error message saying that the parameter didn't match its description. This happened also when I set $params to array( n=>$n ). I haven't worked out what I should write, but because I'm likely to keep on using REST rather than XML-RPC, I'm not worrying about it.
