web service MDL-12886

* Remove description array => all these information are now into the phpdoc. Remove all call/reference to moodleexternal.php
* Adapt our own REST server to these changes
* Remove Zend REST server as it's going to be deprecated in Zend Framework 1.8
* Remove our own SOAP server as we use the Zend SOAP server
This commit is contained in:
jerome 2009-02-24 05:11:04 +00:00
parent 60cd5b5a34
commit 40f024c9f3
17 changed files with 457 additions and 835 deletions

View File

@ -8,7 +8,6 @@
* @author Ferran Recio
*/
require_once(dirname(dirname(__FILE__)) . '/lib/moodleexternal.php');
require_once(dirname(dirname(__FILE__)) . '/group/lib.php');
require_once(dirname(dirname(__FILE__)) . '/lib/grouplib.php');
@ -18,11 +17,12 @@ require_once(dirname(dirname(__FILE__)) . '/lib/grouplib.php');
*
* WORK IN PROGRESS, DO NOT USE IT
*/
final class group_external extends moodle_external {
final class group_external {
/**
* Constructor - We set the description of this API in order to be access by Web service
*/
/*
function __construct () {
$this->descriptions = array();
@ -47,7 +47,7 @@ final class group_external extends moodle_external {
'optionalparams' => array( ),
'return' => array('result' => PARAM_BOOL));
}
}*/
/**
* Creates a group
@ -72,6 +72,13 @@ final class group_external extends moodle_external {
}
}
/**
* add a group member
* @param array $params
* ->groupid int
* ->userid int
* @return boolean success
*/
static function tmp_get_group($params){
// @TODO: any capability to check?

View File

@ -6,59 +6,38 @@
*
* @author Jerome Mouneyrac
*/
require_once(dirname(dirname(__FILE__)) . '/lib/moodleexternal.php');
require_once(dirname(dirname(__FILE__)) . '/user/lib.php');
/**
* WORK IN PROGRESS, DO NOT USE IT
*/
final class user_external extends moodle_external {
final class user_external {
/**
* Constructor - We set the description of this API in order to be access by Web service
*/
function __construct () {
$this->descriptions = array();
///The desciption of the web service
///
///'wsparams' and 'return' are used to described the web services to the end user (can build WSDL file from these information)
///
///Note: web services param names have not importance. However 'paramorder' must match the function params order.
///And all web services param names defined into 'wsparams' should be included into 'paramorder' (otherwise they will not be used)
$this->descriptions['tmp_create_user'] = array( 'params' => array('username'=> PARAM_RAW, 'firstname'=> PARAM_RAW, 'lastname'=> PARAM_RAW, 'email'=> PARAM_RAW, 'password'=> PARAM_RAW),
'optionalparams' => array( ),
'return' => array('userid' => PARAM_RAW));
$this->descriptions['tmp_get_users'] = array( 'params' => array('search'=> PARAM_ALPHANUM),
'optionalparams' => array( ),
'return' => array('user' => array('id' => PARAM_RAW, 'auth' => PARAM_RAW, 'confirmed' => PARAM_RAW, 'username' => PARAM_RAW, 'idnumber' => PARAM_RAW,
'firstname' => PARAM_RAW, 'lastname' => PARAM_RAW, 'email' => PARAM_RAW, 'emailstop' => PARAM_RAW,
'lang' => PARAM_RAW, 'theme' => PARAM_RAW, 'timezone' => PARAM_RAW, 'mailformat' => PARAM_RAW)));
$this->descriptions['tmp_delete_user'] = array( 'params' => array('username'=> PARAM_ALPHANUM, 'mnethostid'=> PARAM_NUMBER),
'optionalparams' => array( ),
'return' => array('result' => PARAM_BOOL));
$this->descriptions['tmp_update_user'] = array( 'params' => array('username'=> PARAM_ALPHANUM, 'mnethostid'=> PARAM_NUMBER),
'optionalparams' => array( 'newusername' => PARAM_ALPHANUM, 'firstname' => PARAM_ALPHANUM),
'return' => array('result' => PARAM_BOOL));
$this->descriptions['tmp_do_multiple_user_searches'] = array( 'params' => array(array('search'=> PARAM_RAW)),
'optionalparams' => array( ),
'return' => array('user' => array('id' => PARAM_RAW, 'auth' => PARAM_RAW, 'confirmed' => PARAM_RAW, 'username' => PARAM_RAW, 'idnumber' => PARAM_RAW,
'firstname' => PARAM_RAW, 'lastname' => PARAM_RAW, 'email' => PARAM_RAW, 'emailstop' => PARAM_RAW,
'lang' => PARAM_RAW, 'theme' => PARAM_RAW, 'timezone' => PARAM_RAW, 'mailformat' => PARAM_RAW)));
}
/**
*
* This docblock has a right syntax but it does not match the real function parameters - except @ param and @ return
* I just keep it for a while till we implement a real ws function using complex blockdoc syntax as this one
* Understand, this dockblock is a example...
* @global object $USER
* @param array|struct $params
* @return array
* @subparam string $params:searches->search - the string to search
* @subparam string $params:searches->search2 optional - the string to search
* @subparam string $params:searches->search3 - the string to search
* @subparam string $params:airport->planes:plane->company->employees:employee->name - name of a employee of a company of a plane of an airport
* @return array users
* @subreturn integer $users:user->id
* @subreturn integer $users:user->auth
* @subreturn integer $users:user->confirmed
* @subreturn string $users:user->username
* @subreturn string $users:user->idnumber
* @subreturn string $users:user->firstname
* @subreturn string $users:user->lastname
* @subreturn string $users:user->email
* @subreturn string $users:user->emailstop
* @subreturn string $users:user->lang
* @subreturn string $users:user->theme
* @subreturn string $users:user->timezone
* @subreturn string $users:user->mailformat
*/
static function tmp_do_multiple_user_searches($params) {
global $USER;
if (has_capability('moodle/user:viewdetails', get_context_instance(CONTEXT_SYSTEM))) {
@ -79,11 +58,27 @@ final class user_external extends moodle_external {
/**
* Retrieve all user
* @param array|struct $params - need to be define as struct for XMLRPC
* ->search string
* @return object user
* @subparam string $params->search - the string to search
* @return object users
* @subreturn integer $users:user->id
* @subreturn integer $users:user->auth
* @subreturn integer $users:user->confirmed
* @subreturn string $users:user->username
* @subreturn string $users:user->idnumber
* @subreturn string $users:user->firstname
* @subreturn string $users:user->lastname
* @subreturn string $users:user->email
* @subreturn string $users:user->emailstop
* @subreturn string $users:user->lang
* @subreturn string $users:user->theme
* @subreturn string $users:user->timezone
* @subreturn string $users:user->mailformat
*/
static function tmp_get_users($params) {
global $USER;
$params['search'] = clean_param($params['search'], PARAM_ALPHANUM);
if (has_capability('moodle/user:viewdetails', get_context_instance(CONTEXT_SYSTEM))) {
// return "toto";
return get_users(true, $params['search'], false, null, 'firstname ASC','', '', '', 1000, 'id, auth, confirmed, username, idnumber, firstname, lastname, email, emailstop, lang, theme, timezone, mailformat');
@ -96,10 +91,11 @@ final class user_external extends moodle_external {
/**
* Create a user
* @param array|struct $params - need to be define as struct for XMLRPC
* ->firstname string
* ->lastname string
* ->email string
* ->password string
* @subparam string $params->username
* @subparam string $params->firstname
* @subparam string $params->lastname
* @subparam string $params->email
* @subparam string $params->password
* @return integer id of new user
*/
static function tmp_create_user($params) {
@ -122,9 +118,9 @@ final class user_external extends moodle_external {
* Delete a user
* @global object $DB
* @param array|struct $params - need to be define as struct for XMLRPC
* ->username string
* ->mnethostid integer
* @return boolean true if success
* @subparam string $params->username
* @subparam integer $params->mnethostid
* @return boolean result true if success
*/
static function tmp_delete_user($params) {
global $DB,$USER;
@ -142,11 +138,11 @@ final class user_external extends moodle_external {
* Update some user information
* @global object $DB
* @param array|struct $params - need to be define as struct for XMLRPC
* ->username string
* ->mnethostid integer
* ->newusername string
* ->firstname string
* @return string true if success
* @subparam string $params->username
* @subparam integer $params->mnethostid
* @subparam string $params->newusername
* @subparam string $params->firstname
* @return boolean result true if success
*/
static function tmp_update_user($params) {
global $DB,$USER;

View File

@ -28,10 +28,16 @@
* This documentation describe how to call Moodle SOAP Web Service
*/
require_once('../config.php');
require_once('lib.php');
$protocol = optional_param('protocol',"soap",PARAM_ALPHA);
generate_documentation($protocol);
generate_functionlist();
/**
*
* @param <type> $protocol
*/
function generate_documentation($protocol) {
switch ($protocol) {
case "soap":
@ -49,7 +55,7 @@ function generate_documentation($protocol) {
<b>tmp_delete_user</b>( string username, integer mnethostid, )<br>
You will call something like:<br>
your_client->tmp_delete_user(array('username' => "username_to_delete",'mnethostid' => 1))<br>
EOF;
break;
case "xmlrpc":
@ -77,20 +83,24 @@ EOF;
}
/**
*
* @global <type> $CFG
*/
function generate_functionlist () {
global $CFG;
$documentation = <<<EOF
<H2>list of web services functions</H2>
<H2>list of web service functions</H2>
EOF;
//retrieve all external file
$externalfiles = array();
$externalfunctions = array();
setListApiFiles($externalfiles, $CFG->dirroot);
foreach ($externalfiles as $file) {
require($file);
$classpath = substr($file,strlen($CFG->dirroot)+1); //remove the dir root + / from the file path
$classpath = substr($classpath,0,strlen($classpath) - 13); //remove /external.php from the classpath
$classpath = str_replace('/','_',$classpath); //convert all / into _
@ -99,107 +109,75 @@ EOF;
$documentation .= <<<EOF
<H3>Moodle path: {$classpath}</H3>
EOF;
foreach($api->get_descriptions() as $functionname => $description) {
$documentation .= <<<EOF
<b>{$functionname}</b>(
$description = webservice_lib::generate_webservice_description($file, $classname);
foreach ($description as $functionname => $functiondescription) {
$documentation .= <<<EOF
<b>{$functionname}(</b>
EOF;
foreach ($description['params'] as $param => $paramtype) {
$wsparamtype = converterMoodleParamIntoWsParam($paramtype);
$arrayparams = array();
foreach($functiondescription['params'] as $param => $type) {
$documentation .= <<<EOF
{$wsparamtype} {$param},
{$type} {$param},
EOF;
}
$documentation .= <<<EOF
<i>
EOF;
foreach ($description['optionalparams'] as $param => $paramtype) {
$wsparamtype = converterMoodleParamIntoWsParam($paramtype);
$documentation .= <<<EOF
{$wsparamtype} {$param},
<b>)</b><br/>
EOF;
foreach($functiondescription['params'] as $param => $type) {
if (is_array($type)) {
$arraytype = "<pre>".print_r($type, true)."</pre>";
$documentation .= <<<EOF
<u>{$param}</u> : {$arraytype} <br>
EOF;
}
}
}
$documentation .= <<<EOF
</i>
EOF;
$documentation .= <<<EOF
);<br>
EOF;
}
echo $documentation;
}
echo $documentation;
}
/**
* Convert a Moodle type (PARAM_ALPHA, PARAM_NUMBER,...) as a SOAP type (string, interger,...)
* @param integer $moodleparam
* @return string SOAP type
*/
function converterMoodleParamIntoWsParam($moodleparam) {
switch ($moodleparam) {
case PARAM_NUMBER:
return "integer";
break;
case PARAM_INT:
return "integer";
break;
case PARAM_BOOL:
return "boolean";
break;
case PARAM_ALPHANUM:
return "string";
break;
case PARAM_RAW:
return "string";
break;
default:
return "object";
break;
}
}
/**
* Retrieve all external.php from Moodle
* @param <type> $
* @param <type> $directorypath
* @return boolean true if n
* @return boolean result true if n
*/
function setListApiFiles( &$files, $directorypath )
{
if(is_dir($directorypath)){ //check that we are browsing a folder not a file
function setListApiFiles( &$files, $directorypath )
{
if(is_dir($directorypath)){ //check that we are browsing a folder not a file
if( $dh = opendir($directorypath))
{
while( false !== ($file = readdir($dh)))
if( $dh = opendir($directorypath))
{
while( false !== ($file = readdir($dh)))
{
if( $file == '.' || $file == '..') { // Skip '.' and '..'
continue;
}
$path = $directorypath . '/' . $file;
///browse the subfolder
if( is_dir($path) ) {
setListApiFiles($files, $path);
}
///retrieve api.php file
else if ($file == "external.php") {
$files[] = $path;
if( $file == '.' || $file == '..') { // Skip '.' and '..'
continue;
}
$path = $directorypath . '/' . $file;
///browse the subfolder
if( is_dir($path) ) {
setListApiFiles($files, $path);
}
///retrieve api.php file
else if ($file == "external.php") {
$files[] = $path;
}
}
closedir($dh);
}
closedir($dh);
}
}
}
?>
?>

View File

@ -46,13 +46,13 @@ final class webservice_lib {
continue;
}
$path = $directorypath . '/' . $file;
///browse the subfolder
///browse the subfolder
if( is_dir($path) ) {
require_once($path."/lib.php");
$classname = $file."_server";
$protocols[] = new $classname;
require_once($path."/lib.php");
$classname = $file."_server";
$protocols[] = new $classname;
}
///retrieve api.php file
///retrieve api.php file
else {
continue;
}
@ -106,11 +106,11 @@ final class webservice_lib {
continue;
}
$path = $directorypath . '/' . $file;
///browse the subfolder
///browse the subfolder
if( is_dir($path) ) {
webservice_lib::setListApiFiles($files, $path);
webservice_lib::setListApiFiles($files, $path);
}
///retrieve api.php file
///retrieve api.php file
else if ($file == "external.php") {
$files[] = $path;
}
@ -122,6 +122,278 @@ final class webservice_lib {
}
/**
* Generate description array from the phpdoc
* TODO: works but it need serious refactoring
* @param <type> $file
* @param <type> $class
* @return <type>
*/
public static function generate_webservice_description($file, $class){
require_once($file);
require_once "Zend/Loader.php";
Zend_Loader::registerAutoload();
$reflection = Zend_Server_Reflection::reflectClass($class);
$description = array();
foreach($reflection->getMethods() as $method){
if ($method->getName()!="get_function_webservice_description"
&& $method->getName()!="get_descriptions" ) {
$docBlock = $method->getDocComment();
//retrieve the return and add it into the description if not array|object
preg_match_all('/@return\s+(\w+)\s+((?:\$)?\w+)/', $docBlock, $returnmatches);
//retrieve the subparam and subreturn
preg_match_all('/\s*\*\s*@(subparam|subreturn)\s+(\w+)\s+(\$\w+(?::\w+|->\w+)+)((?:\s+(?:optional|required|multiple))*)/', $docBlock, $matches);
for($i=0;$i<sizeof($matches[1]);$i++){
// var_dump(strpos("optional", $matches[4][$i]));
switch ($matches[1][$i]) {
case "subparam":
if (strpos($matches[4][$i], "optional")!==false) {
$descriptiontype = "optional";
} else {
$descriptiontype = "params" ;
}
break;
case "subreturn":
$descriptiontype = "return";
break;
}
if (empty($description)) {
$description[$method->getName()] = array();
}
if (strpos($returnmatches[1][0] ,"object")===false && strpos($returnmatches[1][0],"array")===false) {
$description[$method->getName()]['return'] = array($returnmatches[2][0] => $returnmatches[1][0]);
}
if ($matches[1][$i] == "subparam" || $matches[1][$i] == "subreturn") {
///algorythm parts
///1. We compare the string to the description array
/// When we find a attribut that is not in the description, we retrieve all the rest of the string
///2. We create the missing part of the description array, starting from the end of the rest of the string
///3. We add the missing part to the description array
///Part 1.
///construct the description array
if (strpos($matches[3][$i], "->")===false && strpos($matches[3][$i], ":")===false) {
//no separator
$otherparam = $matches[3][$i];
}
else if (strpos($matches[3][$i], "->")===false || (strpos($matches[3][$i], ":")!==false && (strpos($matches[3][$i], ":") < strpos($matches[3][$i], "->")))) {
$separator = ":";
$separatorsize=1;
} else {
$separator = "->";
$separatorsize=2;
}
$param = substr($matches[3][$i],1,strpos($matches[3][$i], $separator)-1);
$otherparam = substr($matches[3][$i],strpos($matches[3][$i], $separator)+$separatorsize);
$parsingdesc = $description[$method->getName()];
if (!empty($parsingdesc) && array_key_exists($descriptiontype, $parsingdesc)){
$parsingdesc = $parsingdesc[$descriptiontype];
}
$descriptionpath=array();
$creationfinished = false;
unset($type);
while(!$creationfinished && (strpos($otherparam, ":") || strpos($otherparam, "->"))) {
if (strpos($otherparam, "->")===false || (strpos($otherparam, ":")!==false && (strpos($otherparam, ":") < strpos($otherparam, "->")))) {
$type = $separator;
$separator = ":";
$separatorsize=1;
} else {
$type = $separator;
$separator = "->";
$separatorsize=2;
}
$param = substr($otherparam,0,strpos($otherparam, $separator));
$otherparam = substr($otherparam,strpos($otherparam, $separator)+$separatorsize);
if ($type==":") {
if (!array_key_exists('multiple:'.$param, $parsingdesc)){
$desctoadd = webservice_lib::create_end_of_description(":".$param.$separator.$otherparam, $matches[2][$i]);
if(empty($descriptionpath) ) {
if (empty($description[$method->getName()]) || !array_key_exists($descriptiontype, $description[$method->getName()])) {
$desctoadd = array($descriptiontype => $desctoadd);
}
$paramtoadd = $descriptiontype;
} else {
$paramtoadd = 'multiple:'.$param;
}
webservice_lib::add_end_of_description($paramtoadd, $desctoadd, $description[$method->getName()], $descriptionpath);
$creationfinished = true;
} else {
if(empty($descriptionpath)) {
$descriptionpath[] = $descriptiontype;
}
$descriptionpath[] = 'multiple:'.$param;
$parsingdesc = $parsingdesc['multiple:'.$param];
}
} else {
if (!array_key_exists($param, $parsingdesc)){
$desctoadd = webservice_lib::create_end_of_description("->".$param.$separator.$otherparam, $matches[2][$i]);
if(empty($descriptionpath)) {
if (empty($description[$method->getName()]) || !array_key_exists($descriptiontype, $description[$method->getName()])) {
$desctoadd = array($descriptiontype => $desctoadd);
}
$paramtoadd = $descriptiontype;
} else {
$paramtoadd = $param;
}
webservice_lib::add_end_of_description($paramtoadd, $desctoadd, $description[$method->getName()], $descriptionpath);
$creationfinished = true;
} else {
if(empty($descriptionpath)) {
$descriptionpath[] = $descriptiontype;
}
$descriptionpath[] = $param;
$parsingdesc = $parsingdesc[$param];
}
}
}
if (!$creationfinished) {
if (!empty($type) && $type==":") {
$desctoadd = webservice_lib::create_end_of_description($separator.$otherparam, $matches[2][$i]);
if(empty($descriptionpath)) {
if (empty($description[$method->getName()]) || !array_key_exists($descriptiontype, $description[$method->getName()])) {
$desctoadd = array($descriptiontype => $desctoadd);
}
$paramtoadd = $descriptiontype;
} else {
$paramtoadd = 'multiple:'.$param;
}
webservice_lib::add_end_of_description($paramtoadd, $desctoadd, $description[$method->getName()], $descriptionpath);
} else {
$desctoadd = webservice_lib::create_end_of_description($separator.$otherparam, $matches[2][$i]);
if(empty($descriptionpath)) {
if (empty($description[$method->getName()]) || !array_key_exists($descriptiontype, $description[$method->getName()])) {
$desctoadd = array($descriptiontype => $desctoadd);
}
$paramtoadd = $descriptiontype;
} else {
$paramtoadd = $param;
}
webservice_lib::add_end_of_description($paramtoadd, $desctoadd, $description[$method->getName()], $descriptionpath);
}
}
}
}
}
}
return $description;
}
/**
* TODO: works but it needs refactoring
* @param <type> $param
* @param <type> $desctoadd
* @param <type> $descriptionlevel
* @param <type> $descriptionpath
* @param <type> $level
*/
public static function add_end_of_description($param, $desctoadd, &$descriptionlevel, $descriptionpath, $level= 0){
if (sizeof($descriptionpath)==0 || sizeof($descriptionpath)==$level+1) {
if (is_array($descriptionlevel) && !empty($descriptionlevel)) {
foreach($desctoadd as $key=>$value) {
if ($key!="params" && $key!="optional" && $key!="return") { //TODO
$descriptionlevel[$param][$key] = $value;
} else {
$descriptionlevel[$param] = $value;
}
}
} else {
$descriptionlevel = $desctoadd;
}
} else {
webservice_lib::add_end_of_description($param, $desctoadd, &$descriptionlevel[$descriptionpath[$level]], $descriptionpath, $level+1);
}
}
/**
* TODO: works but it needs refactoring
* @param <type> $stringtoadd
* @param <type> $type
* @return <type>
*/
public static function create_end_of_description($stringtoadd, $type) {
if (strrpos($stringtoadd, "->")===false || (strrpos($stringtoadd, ":")!==false && (strrpos($stringtoadd, ":") > strrpos($stringtoadd, "->")))) {
$separator = ":";
$separatorsize=1;
} else {
$separator = "->";
$separatorsize=2;
}
$param = substr($stringtoadd,strrpos($stringtoadd, $separator)+$separatorsize);
$result = array( $param => $type);
$otherparam = substr($stringtoadd,0,strlen($stringtoadd)-strlen($param)-$separatorsize);
while(strrpos($otherparam, ":")!==false || strrpos($otherparam, "->")!==false) {
if (strrpos($otherparam, "->")===false || (strrpos($otherparam, ":")!==false && (strrpos($otherparam, ":") > strrpos($otherparam, "->")))) {
$separator = ":";
$separatorsize=1;
} else {
$separator = "->";
$separatorsize=2;
}
$param = substr($otherparam,strrpos($otherparam, $separator)+$separatorsize);
$otherparam = substr($otherparam,0,strrpos($otherparam, $separator));
if ($separator==":") {
$result = array('multiple:'.$param => $result);
} else {
$result = array($param => $result);
}
}
return $result;
}
}
/**
@ -189,7 +461,7 @@ final class wsuser_form extends moodleform {
global $DB;
$this->username = $this->_customdata['username'];
$mform =& $this->_form;
$strrequired = get_string('required');
$mform->addElement('hidden', 'username', $this->username);

View File

@ -39,7 +39,7 @@ final class rest_server extends webservice_server {
* Run REST server
*/
public function run() {
$enable = $this->get_enable();
$enable = $this->get_enable();
if (empty($enable)) {
die;
}
@ -49,47 +49,7 @@ final class rest_server extends webservice_server {
$rest_arguments = get_file_argument('server.php');
header ("Content-type: text/xml");
echo call_moodle_function($rest_arguments);
}
/**
* Run Zend REST server
* @global object $USER .
*/
public function zend_run() {
$enable = $this->get_enable();
if (empty($enable)) {
die;
}
include "Zend/Loader.php";
Zend_Loader::registerAutoload();
// retrieve the token from the url
// if the token doesn't exist, set a class containing only get_token()
$token = optional_param('token',null,PARAM_ALPHANUM);
if (empty($token)) {
$server = new Zend_Rest_Server();
$server->setClass("ws_authentication");
$server->handle();
} else { // if token exist, do the authentication here
/// TODO: following function will need to be modified
$user = webservice_lib::mock_check_token($token);
if (empty($user)) {
throw new moodle_exception('wrongidentification');
} else {
global $USER;
$USER = $user;
}
//retrieve the api name
$classpath = optional_param(classpath,null,PARAM_ALPHA);
require_once(dirname(__FILE__) . '/../../'.$classpath.'/external.php');
/// run the server
$server = new Zend_Rest_Server();
$server->setClass($classpath."_external");
$server->handle();
}
}
}
}

View File

@ -38,7 +38,7 @@
*/
function call_moodle_function ($rest_arguments) {
global $CFG, $USER;
///REST params conversion
$functionname = substr($rest_arguments,strrpos($rest_arguments,"/")+1); //retrieve the function name (it's located after the last '/') in $rest_arguments
//$rest_argument
@ -75,12 +75,11 @@ function call_moodle_function ($rest_arguments) {
}
/// load the external class
require_once($CFG->dirroot.$apipath.'external.php');
$wsapi = new $classname();
$description = $wsapi->get_function_webservice_description($functionname); //retrieve the web service description for this function
$file = $CFG->dirroot.$apipath.'external.php';
$description = webservice_lib::generate_webservice_description($file, $classname);
/// This following line is only REST protocol
$params = retrieve_params ($description); //retrieve the REST params
$params = retrieve_params ($description[$functionname]); //retrieve the REST params
/// Generic part to any protocols
if ($params === false) {
@ -94,7 +93,7 @@ function call_moodle_function ($rest_arguments) {
}
///Transform result into xml in order to send the REST response
$return = mdl_conn_rest_object_to_xml ($res,key($description['return']));
$return = mdl_conn_rest_object_to_xml ($res,key($description[$functionname]['return']));
return "<Result>$return</Result>";
}
@ -122,6 +121,34 @@ function mock_check_token($token) {
}
}
/**
* Convert into a Moodle type
* @param integer $param
* @return string
*/
function convert_paramtype($param) {
switch ($param) {
case "integer":
return PARAM_NUMBER;
break;
case "integer":
return PARAM_INT;
break;
case "boolean":
return PARAM_BOOL;
break;
case "string":
return PARAM_ALPHANUM;
break;
case "object":
return PARAM_RAW;
break;
default:
return PARAM_RAW;
break;
}
}
/**
*
* @author Jerome Mouneyrac
@ -132,19 +159,20 @@ function retrieve_params ($description) {
$params = array();
//retrieve REST param matching the description (warning: PHP assign the first instanciation as the first position in the table)
foreach ($description['params'] as $paramname => $paramtype) {
$paramtype = convert_paramtype($paramtype);
$value = optional_param($paramname,null,$paramtype);
if (!empty($value)) {
$params[$paramname] = $value;
}
}
//retrieve REST optional params
foreach ($description['optionalparams'] as $paramname => $paramtype) {
foreach ($description['optional'] as $paramname => $paramtype) {
$paramtype = convert_paramtype($paramtype);
$value = optional_param($paramname,null,$paramtype);
if (!empty($value)) {
$params[$paramname] = $value;
}
}
return $params;
}

View File

@ -41,7 +41,6 @@ if (empty($CFG->enablewebservices)) {
die;
}
$server = new rest_server();
$server->run();

View File

@ -1,7 +1,7 @@
<?php
/**
* Created on 10/17/2008
*
*
* Rest Test Client
*
* @author David Castro Garcia
@ -14,17 +14,17 @@ require_once ('config_rest.php');
$params = array('search');
foreach ($params as $param) {
$$param = (isset($_POST[$param]))?$_POST[$param]:'';
$$param = (isset($_POST[$param]))?$_POST[$param]:'';
}
start_interface("List of Users");
?>
<form action="getusers.php" method="post">
<table border="0">
<tr><td>Search: </td><td><input type="text" name="search" value="<?php echo $search; ?>"/></td></tr>
<tr><td></td><td><input type="submit" value="Find Users"></td></tr>
</table>
<table border="0">
<tr><td>Search: </td><td><input type="text" name="search" value="<?php echo $search; ?>"/></td></tr>
<tr><td></td><td><input type="submit" value="Find Users"></td></tr>
</table>
</form>
<?php
@ -34,7 +34,7 @@ if ($search) {
var_dump($CFG->serverurl.'/user/tmp_get_users');
//we are asking for a token
$connectiondata['username'] = 'wsuser';
$connectiondata['password'] = 'wspassword';
@ -45,7 +45,7 @@ if ($search) {
curl_setopt($ch, CURLOPT_POSTFIELDS, format_postdata($connectiondata));
$token = curl_exec($ch);
$data['token'] = $token;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $CFG->serverurl.'/user/tmp_get_users');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

View File

@ -1,54 +0,0 @@
<?php
/**
* Moodle - Modular Object-Oriented Dynamic Learning Environment
* http://moodle.com
*
* LICENSE
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
*
* http://www.gnu.org/copyleft/gpl.html
*
* @category Moodle
* @package webservice
* @copyright Copyright (c) 1999 onwards Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL License
*/
/*
* Moodle Zend Rest test client
*/
require_once('../../../config.php');
include "Zend/Loader.php";
Zend_Loader::registerAutoload();
//1. authentication
$client = new Zend_Rest_Client($CFG->wwwroot."/webservice/rest/zend_rest_server.php");
$token = $client->tmp_get_token(array('username' => "wsuser", 'password' => "wspassword"))->get();
echo $token->response();
$token = $token->response();
print "<pre>\n</pre>";
//2. test functions
$client = new Zend_Rest_Client($CFG->wwwroot."/webservice/rest/zend_rest_server.php/?classpath=user&token=".$token);
var_dump($client->tmp_get_users(array('search' => "admin"))->get());
print "<pre>\n</pre>";
var_dump($client->tmp_create_user(array('username' => "mockuser66",'firstname' => "firstname6",'lastname' => "lastname6",'email' => "mockuser6@mockuser6.com",'password' => "password6"))->get());
print "<pre>\n</pre>";
var_dump($client->tmp_update_user(array('username' => "mockuser66",'mnethostid' => 1,'newusername' => "mockuser6b",'firstname' => "firstname6b"))->get());
print "<pre>\n</pre>";
var_dump($client->tmp_delete_user(array('username' => "mockuser6b",'mnethostid' => 1))->get());
print "<pre>\n</pre>";
var_dump($client->tmp_do_multiple_user_searches(array(array('search' => "admin"),array('search' => 'mock')))->get());
print "<pre>\n</pre>";
?>

View File

@ -1,41 +0,0 @@
<?php
/**
* Moodle - Modular Object-Oriented Dynamic Learning Environment
* http://moodle.com
*
* LICENSE
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
*
* http://www.gnu.org/copyleft/gpl.html
*
* @category Moodle
* @package webservice
* @copyright Copyright (c) 1999 onwards Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL License
*/
/**
* Zend REST Moodle server.
*/
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once('lib.php');
if (empty($CFG->enablewebservices)) {
die;
}
$server = new rest_server();
$server->zend_run();
?>

View File

@ -1,371 +0,0 @@
<?php
/**
* Moodle - Modular Object-Oriented Dynamic Learning Environment
* http://moodle.com
*
* LICENSE
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
*
* http://www.gnu.org/copyleft/gpl.html
*
* @category Moodle
* @package webservice
* @copyright Copyright (c) 1999 onwards Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL License
*/
/*
* Generate the Moodle WSDL file
* This file is not finish but will give you a base to start
*/
require_once('../../config.php');
$token = optional_param('token',null,PARAM_ALPHANUM);
$wsdl_generator = new wsdl_generator();
$wsdl = $wsdl_generator->generate_wsdl($token);
echo $wsdl;
/**
* WORK IN PROGRESS
*/
class wsdl_generator {
private $exceptionlist;
//private $wsdl;
function __construct () {
// The exception list
// if ever there is some external.php file that are not a web service class, they need to be declared here
// example: $this->exceptionlist['/home/jerome/Projects/Moodle_HEAD/moodle/mod/scorm/external.php'] = true;
$this->exceptionlist = array();
}
/**
* Generate the WSDL for Moodle API
* @global <type> $CFG
* @param <type> $token
* @return string wsdl xml
*/
public function generate_wsdl ($token = null) {
global $CFG;
if (empty($token)) {
return $this->generate_authentication_wsdl();
}
///initialize different wsdl part
$wsdlmessage = "";
$wsdlporttype = "";
$wsdlbinding = "";
$wsdlservice = "";
///retrieve al api.php file
$listfiles = array();
$this->setListApiFiles( $listfiles, $CFG->dirroot);
///WSDL header
$wsdl = <<<EOF
<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions name='User'
targetNamespace='http://example.org/User'
xmlns:tns=' http://example.org/User '
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
EOF;
$wsdltypes = <<<EOF
<types>
<xsd:schema targetNamespace="http://example.org/User"
xmlns="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="object">
</xsd:complexType>
</xsd:schema>
</types>
EOF;
foreach ($listfiles as $fileapipath) {
require_once($fileapipath);
///load the class
$classpath = substr($fileapipath,strlen($CFG->dirroot)+1); //remove the dir root + / from the file path
$classpath = substr($classpath,0,strlen($classpath) - 13); //remove /external.php from the classpath
$classpath = str_replace('/','_',$classpath); //convert all / into _
$classname = $classpath."_external";
$api = new $classname();
$wsdlporttype .= <<<EOF
<portType name='{$classpath}PortType'>
EOF;
$wsdlbinding .= <<<EOF
<binding name='{$classpath}Binding' type='tns:{$classpath}PortType'>
<soap:binding style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'/>
EOF;
$wsdlservice .= <<<EOF
<service name='{$classpath}Service'>
<port name='{$classpath}Port' binding='{$classpath}Binding'>
<soap:address location='{$CFG->wwwroot}/webservice/soap/server.php?classpath={$classpath}&amp;token={$token}'/>
</port>
</service>
EOF;
foreach($api->get_descriptions() as $functionname => $description) {
$wsdlmessage .= <<<EOF
<message name="{$functionname}Request">
EOF;
/*
foreach ($description['params'] as $param => $paramtype) {
$wsparamtype = $this->converterMoodleParamIntoWsParam($paramtype);
$wsdlmessage .= <<<EOF
<part name="{$param}" type="xsd:{$wsparamtype}"/>
EOF;
}
foreach ($description['optionalparams'] as $param => $paramtype) {
$wsparamtype = $this->converterMoodleParamIntoWsParam($paramtype);
$wsdlmessage .= <<<EOF
<part name="{$param}" type="xsd:{$wsparamtype}"/>
EOF;
} * */
$wsdlmessage .= <<<EOF
<part name="params" type="xsd:object"/>
EOF;
$wsdlmessage .= <<<EOF
</message>
<message name="{$functionname}Response">
EOF;
foreach ($description['return'] as $param => $paramtype) {
$wsparamtype = $this->converterMoodleParamIntoWsParam($paramtype);
$wsdlmessage .= <<<EOF
<part name="{$param}" type="xsd:{$wsparamtype}"/>
EOF;
}
$wsdlmessage .= <<<EOF
</message>
EOF;
$wsdlporttype .= <<<EOF
<operation name='{$functionname}'>
<input message='tns:{$functionname}Request'/>
<output message='tns:{$functionname}Response'/>
</operation>
EOF;
$wsdlbinding .= <<<EOF
<operation name='{$functionname}'>
<soap:operation soapAction='urn:xmethods-delayed-quotes#{$functionname}'/>
<input>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
EOF;
}
$wsdlporttype .= <<<EOF
</portType>
EOF;
$wsdlbinding .= <<<EOF
</binding>
EOF;
}
///write WSDL
$wsdl .= $wsdltypes;
$wsdl .= $wsdlmessage;
$wsdl .= $wsdlporttype;
$wsdl .= $wsdlbinding;
$wsdl .= $wsdlservice;
///WSDL footer
$wsdl .= <<<EOF
</definitions>
EOF;
return $wsdl;
}
private function generate_authentication_wsdl() {
global $CFG;
$wsdl = <<<EOF
<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions name='User'
targetNamespace='http://example.org/User'
xmlns:tns=' http://example.org/User '
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
<types>
<xsd:schema targetNamespace="http://example.org/User"
xmlns="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="object">
</xsd:complexType>
</xsd:schema>
</types>
<message name="tmp_get_tokenRequest">
<part name="params" type="xsd:object"/>
</message>
<message name="tmp_get_tokenResponse">
<part name="user" type="xsd:object"/>
</message>
<portType name='userPortType'>
<operation name='tmp_get_token'>
<input message='tns:tmp_get_tokenRequest'/>
<output message='tns:tmp_get_tokenResponse'/>
</operation>
</portType>
<binding name='userBinding' type='tns:userPortType'>
<soap:binding style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='tmp_get_token'>
<soap:operation soapAction='urn:xmethods-delayed-quotes#tmp_get_token'/>
<input>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
</binding>
<service name='userService'>
<port name='userPort' binding='userBinding'>
<soap:address location='{$CFG->wwwroot}/webservice/soap/server.php'/>
</port>
</service>
</definitions>
EOF;
return $wsdl;
}
/**
* Retrieve all api.php from Moodle (except the one of the exception list)
* @param <type> $
* @param <type> $directorypath
* @return boolean true if n
*/
private function setListApiFiles( &$files, $directorypath )
{
$generatewsdl = true;
if(is_dir($directorypath)){ //check that we are browsing a folder not a file
if( $dh = opendir($directorypath))
{
while( false !== ($file = readdir($dh)))
{
if( $file == '.' || $file == '..') { // Skip '.' and '..'
continue;
}
$path = $directorypath . '/' . $file;
///browse the subfolder
if( is_dir($path) ) {
$this->setListApiFiles($files, $path);
}
///retrieve api.php file
else if ($file == "external.php" && ! $this->inExceptionList($path)) {
$files[] = $path;
}
}
closedir($dh);
}
}
return $generatewsdl;
}
/**
* Hacky function
* We need to define if we remove all external.php file from Moodle when they do not really
* are ws api file for Moodle ws API
* @param string $path
* @return boolean true if the path if in the exception list
*/
private function inExceptionList($path) {
return (!empty( $this->exceptionlist[$path]));
}
/**
* Convert a Moodle type (PARAM_ALPHA, PARAM_NUMBER,...) as a SOAP type (string, interger,...)
* @param integer $moodleparam
* @return string SOAP type
*/
private function converterMoodleParamIntoWsParam($moodleparam) {
switch ($moodleparam) {
case PARAM_NUMBER:
return "integer";
break;
case PARAM_INT:
return "integer";
break;
case PARAM_BOOL:
return "boolean";
break;
case PARAM_ALPHANUM:
return "string";
break;
case PARAM_RAW:
return "string";
break;
default:
return "object";
break;
}
}
}
?>

View File

@ -36,54 +36,14 @@ final class soap_server extends webservice_server {
$this->set_protocolname("Soap");
}
/**
* Run SOAP server
* @global <type> $CFG
* @global <type> $USER
*/
public function run() {
$enable = $this->get_enable();
if (empty($enable)) {
die;
}
global $CFG;
// retrieve the token from the url
// if the token doesn't exist, set a class containing only get_token()
$token = optional_param('token',null,PARAM_ALPHANUM);
if (empty($token)) {
$server = new SoapServer($CFG->wwwroot."/webservice/soap/generatewsdl.php");
$server->setClass("ws_authentication");
$server->handle();
} else { // if token exist, do the authentication here
/// TODO: following function will need to be modified
$user = webservice_lib::mock_check_token($token);
if (empty($user)) {
throw new moodle_exception('wrongidentification');
} else {
/// TODO: probably change this
global $USER;
$USER = $user;
}
//retrieve the api name
$classpath = optional_param(classpath,null,PARAM_ALPHA);
require_once(dirname(__FILE__) . '/../../'.$classpath.'/external.php');
/// run the server
$server = new SoapServer($CFG->wwwroot."/webservice/soap/generatewsdl.php?token=".$token);
$server->setClass($classpath."_external"); //TODO: pass $user as parameter
$server->handle();
}
}
/**
* Run Zend SOAP server
* @global <type> $CFG
* @global <type> $USER
*/
public function zend_run() {
$enable = $this->get_enable();
public function run() {
$enable = $this->get_enable();
if (empty($enable)) {
die;
}
@ -114,7 +74,7 @@ final class soap_server extends webservice_server {
$autodiscover->handle();
} else {
$soap = new Zend_Soap_Server($CFG->wwwroot."/webservice/soap/zend_soap_server.php?wsdl"); // this current file here
$soap = new Zend_Soap_Server($CFG->wwwroot."/webservice/soap/server.php?wsdl"); // this current file here
$soap->setClass('ws_authentication');
$soap->handle();
}
@ -139,11 +99,11 @@ final class soap_server extends webservice_server {
$autodiscover = new Zend_Soap_AutoDiscover();
//this is a hack, because there is a bug in Zend framework (http://framework.zend.com/issues/browse/ZF-5736)
$autodiscover->setUri($CFG->wwwroot."/webservice/soap/zend_soap_server.php/".$token."/".$classpath);
$autodiscover->setUri($CFG->wwwroot."/webservice/soap/server.php/".$token."/".$classpath);
$autodiscover->setClass($classpath."_external");
$autodiscover->handle();
} else {
$soap = new Zend_Soap_Server($CFG->wwwroot."/webservice/soap/zend_soap_server.php?token=".$token."&classpath=".$classpath."&wsdl"); // this current file here
$soap = new Zend_Soap_Server($CFG->wwwroot."/webservice/soap/server.php?token=".$token."&classpath=".$classpath."&wsdl"); // this current file here
$soap->setClass($classpath."_external");
$soap->handle();
}

View File

@ -1,71 +0,0 @@
<?php
/**
* Moodle - Modular Object-Oriented Dynamic Learning Environment
* http://moodle.com
*
* LICENSE
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
*
* http://www.gnu.org/copyleft/gpl.html
*
* @category Moodle
* @package webservice
* @copyright Copyright (c) 1999 onwards Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL License
*/
/*
* SOAP test client
*/
require_once(dirname(__FILE__) . '/../../../config.php');
//1. authentication
$client = new SoapClient($CFG->wwwroot."/webservice/soap/generatewsdl.php",array(
"trace" => 1,
"exceptions" => 0));
try {
$token = $client->tmp_get_token(array('username' => "wsuser", 'password' => "wspassword"));
printLastRequestResponse($client);
} catch (SoapFault $exception) {
echo $exception;
}
//2. test functions
$client = new SoapClient($CFG->wwwroot."/webservice/soap/generatewsdl.php?token=".$token,array(
"trace" => 1,
"exceptions" => 0));
try {
var_dump($client->tmp_get_users(array('search' => "admin")));
printLastRequestResponse($client);
var_dump($client->tmp_create_user(array('username' => "mockuser66",'firstname' => "firstname6",'lastname' => "lastname6",'email' => "mockuser6@mockuser6.com",'password' => "password6")));
printLastRequestResponse($client);
var_dump($client->tmp_update_user(array('username' => "mockuser66",'mnethostid' => 1,'newusername' => "mockuser6b",'firstname' => "firstname6b")));
printLastRequestResponse($client);
var_dump($client->tmp_delete_user(array('username' => "mockuser6b",'mnethostid' => 1)));
printLastRequestResponse($client);
} catch (SoapFault $exception) {
echo $exception;
}
function printLastRequestResponse($client) {
print "<pre>\n";
print "Request :\n".htmlspecialchars($client->__getLastRequest()) ."\n";
print "Response:\n".htmlspecialchars($client->__getLastResponse())."\n";
print "</pre>";
}
?>

View File

@ -34,7 +34,7 @@ Zend_Loader::registerAutoload();
//1. authentication
$client = new Zend_Soap_Client($CFG->wwwroot."/webservice/soap/zend_soap_server.php?wsdl");
$client = new Zend_Soap_Client($CFG->wwwroot."/webservice/soap/server.php?wsdl");
try {
$token = $client->tmp_get_token(array('username' => "wsuser", 'password' => "wspassword"));
printLastRequestResponse($client);
@ -43,7 +43,7 @@ try {
}
//2. test functions
$client = new Zend_Soap_Client($CFG->wwwroot."/webservice/soap/zend_soap_server.php?token=".$token."&classpath=user&wsdl");
$client = new Zend_Soap_Client($CFG->wwwroot."/webservice/soap/server.php?token=".$token."&classpath=user&wsdl");
var_dump($client->tmp_get_users(array('search' => "admin")));
printLastRequestResponse($client);
var_dump($client->tmp_create_user(array('username' => "mockuser66",'firstname' => "firstname6",'lastname' => "lastname6",'email' => "mockuser6@mockuser6.com",'password' => "password6")));

View File

@ -1,41 +0,0 @@
<?php
/**
* Moodle - Modular Object-Oriented Dynamic Learning Environment
* http://moodle.com
*
* LICENSE
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
*
* http://www.gnu.org/copyleft/gpl.html
*
* @category Moodle
* @package webservice
* @copyright Copyright (c) 1999 onwards Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL License
*/
/*
* Zend SOAP server
*/
require_once(dirname(__FILE__) . '/../../config.php');
require_once('lib.php');
if (empty($CFG->enablewebservices)) {
die;
}
$server = new soap_server();
$server->zend_run();
?>

View File

@ -33,12 +33,12 @@ Zend_Loader::registerAutoload();
//1. authentication
$client = new Zend_XmlRpc_Client($CFG->wwwroot."/webservice/xmlrpc/zend_xmlrpc_server.php");
$client = new Zend_XmlRpc_Client($CFG->wwwroot."/webservice/xmlrpc/server.php");
$token = $client->call('authentication.tmp_get_token', array(array('username' => "wsuser", 'password' => "wspassword")));
var_dump($token);
//2. test functions
$client = new Zend_XmlRpc_Client($CFG->wwwroot."/webservice/xmlrpc/zend_xmlrpc_server.php?classpath=user&token=".$token);
$client = new Zend_XmlRpc_Client($CFG->wwwroot."/webservice/xmlrpc/server.php?classpath=user&token=".$token);
var_dump($users = $client->call('user.tmp_get_users', array(array('search' => "admin"))));
print "<br/><br/>\n";
var_dump($users = $client->call('user.tmp_create_user', array(array('username' => "mockuser66",'firstname' => "firstname6",'lastname' => "lastname6",'email' => "mockuser6@mockuser6.com",'password' => "password6"))));