Change most of User web service functions to support multiple operation in one call. Adapt SOAP and XMLRPC test client. (REST User test clients wont work anymore till REST server supports array parameter)
<?php
/**
- * Created on 05/03/2008
+ * Moodle - Modular Object-Oriented Dynamic Learning Environment
+ * http://moodle.com
*
- * users webservice api
+ * LICENSE
*
- * @author Jerome Mouneyrac
+ * 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 user
+ * @copyright Copyright (c) 1999 onwards Martin Dougiamas http://dougiamas.com
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL License
*/
require_once(dirname(dirname(__FILE__)) . '/user/lib.php');
/**
* WORK IN PROGRESS, DO NOT USE IT
+ * users webservice api
+ *
+ * @author Jerome Mouneyrac
*/
final class user_external {
- /**
- * 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
- * @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 object $return
- * @subreturn integer $return:user->id
- * @subreturn integer $return:user->auth
- * @subreturn integer $return:user->confirmed
- * @subreturn string $return:user->username
- * @subreturn string $return:user->idnumber
- * @subreturn string $return:user->firstname
- * @subreturn string $return:user->lastname
- * @subreturn string $return:user->email
- * @subreturn string $return:user->emailstop
- * @subreturn string $return:user->lang
- * @subreturn string $return:user->theme
- * @subreturn string $return:user->timezone
- * @subreturn string $return:user->mailformat
- */
- static function tmp_do_multiple_user_searches($params) {
- global $USER;
- if (has_capability('moodle/user:viewdetails', get_context_instance(CONTEXT_SYSTEM))) {
- $users = array();
- foreach($params as $searchparams) {
- $searchusers = get_users(true, $searchparams['search'], false, null, 'firstname ASC','', '', '', 1000, 'id, auth, confirmed, username, idnumber, firstname, lastname, email, emailstop, lang, theme, timezone, mailformat');
- foreach ($searchusers as $user) {
- $users[] = $user;
- }
- }
- return $users;
- }
- else {
- throw new moodle_exception('wscouldnotvieweuser');
- }
- }
-
/**
* Retrieve all user
* @param array|struct $params - need to be define as struct for XMLRPC
$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');
+ return get_users(true, $params['search'], false, null, 'firstname ASC','', '', '', 1000, 'id, auth, confirmed, username, idnumber, firstname, lastname, email, emailstop, lang, theme, timezone, mailformat, city, description, country');
}
else {
throw new moodle_exception('wscouldnotvieweuser');
}
}
- /**
- * Create a user
+ /**
+ * Create multiple users
* @param array|struct $params - need to be define as struct for XMLRPC
- * @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
+ * @subparam string $params:user->username
+ * @subparam string $params:user->firstname
+ * @subparam string $params:user->lastname
+ * @subparam string $params:user->email
+ * @subparam string $params:user->password
+ * @return array $return ids of new user
+ * @subreturn integer $return:id user id
*/
- static function tmp_create_user($params) {
+ static function tmp_create_users($params) {
global $USER;
if (has_capability('moodle/user:create', get_context_instance(CONTEXT_SYSTEM))) {
- $user = array();
- $user['username'] = $params['username'];
- $user['firstname'] = $params['firstname'];
- $user['lastname'] = $params['lastname'];
- $user['email'] = $params['email'];
- $user['password'] = $params['password'];
- return tmp_create_user($user);
+ $userids = array();
+ foreach ($params as $userparams) {
+
+ $user = array();
+ foreach (array_keys($userparams) as $key) {
+ $user[$key] = clean_param($userparams[$key], PARAM_ALPHANUMEXT);
+ }
+
+ if (array_key_exists('email', $userparams)) {
+ $user['email'] = clean_param($userparams['email'], PARAM_NOTAGS);
+ }
+
+ if (array_key_exists('description', $userparams)) {
+ $user['description'] = clean_param($userparams['description'], PARAM_TEXT);
+ }
+
+ try {
+ $userids[$userparams['username']] = tmp_create_user($user);
+ }
+ catch (dml_write_exception $e) {
+ throw new moodle_exception('wscouldnotcreateeuserindb');
+ }
+ }
+ return $userids;
}
else {
throw new moodle_exception('wscouldnotcreateeuser');
- }
+ }
}
- /**
- * Delete a user
+ /**
+ * Delete multiple users
* @global object $DB
* @param array|struct $params - need to be define as struct for XMLRPC
- * @subparam string $params->username
- * @subparam integer $params->mnethostid
+ * @subparam string $params:user->username
+ * @subparam integer $params:user->mnethostid
* @return boolean result true if success
*/
- static function tmp_delete_user($params) {
+ static function tmp_delete_users($params) {
global $DB,$USER;
+ $deletionsuccessfull = true;
if (has_capability('moodle/user:delete', get_context_instance(CONTEXT_SYSTEM))) {
- $user = $DB->get_record('user', array('username'=>$params['username'], 'mnethostid'=>$params['mnethostid']));
- return delete_user($user); //this function is in moodlelib.php
+ foreach ($params as $userparams) {
+
+ $username = clean_param($userparams['username'], PARAM_ALPHANUMEXT);
+
+ $user = $DB->get_record('user', array('username'=>$username, 'mnethostid'=>1));
+
+ if (empty($user)) {
+ throw new moodle_exception('wscouldnotdeletenoexistinguser');
+ }
+
+ if (!delete_user($user)) {
+ $deletionsuccessfull = false; //this function is in moodlelib.php
+ }
+ }
+ return $deletionsuccessfull;
}
else {
throw new moodle_exception('wscouldnotdeleteuser');
}
}
-
- /**
- * Update some user information
+ /**
+ * Update some users information
* @global object $DB
* @param array|struct $params - need to be define as struct for XMLRPC
- * @subparam string $params->username
- * @subparam integer $params->mnethostid
- * @subparam string $params->newusername
- * @subparam string $params->firstname
+ * @subparam string $params:user->username
+ * @subparam integer $params:user->mnethostid
+ * @subparam string $params:user->newusername
+ * @subparam string $params:user->firstname
* @return boolean result true if success
*/
- static function tmp_update_user($params) {
+ static function tmp_update_users($params) {
global $DB,$USER;
if (has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM))) {
- $user = $DB->get_record('user', array('username'=>$params['username'], 'mnethostid'=>$params['mnethostid']));
+ $updatesuccessfull = true;
- if (!empty($params['newusername'])) {
- $user->username = $params['newusername'];
- }
- if (!empty($params['firstname'])) {
- $user->firstname = $params['firstname'];
+ foreach ($params as $userparams) {
+ if (array_key_exists('username', $userparams)) {
+ $username = clean_param($userparams['username'], PARAM_NOTAGS);
+ }
+
+ $user = $DB->get_record('user', array('username'=>$username, 'mnethostid'=>1));
+
+ if (empty($user)) {
+ throw new moodle_exception('wscouldnotupdatenoexistinguser');
+ }
+
+ foreach (array_keys($userparams) as $key) {
+ $user->$key = clean_param($userparams[$key], PARAM_ALPHANUMEXT);
+ }
+
+ if (array_key_exists('email', $userparams)) {
+ $user->email = clean_param($userparams['email'], PARAM_NOTAGS);
+ }
+
+ if (array_key_exists('description', $userparams)) {
+ $user->description = clean_param($userparams['description'], PARAM_TEXT);
+ }
+
+ if (array_key_exists('newusername', $userparams)) {
+ $user->username = clean_param($userparams['newusername'], PARAM_ALPHANUMEXT);
+ }
+
+ try {
+ if( !tmp_update_user($user)) {
+ $updatesuccessfull = false;
+ }
+ }
+ catch (dml_write_exception $e) {
+ throw new moodle_exception('wscouldnotupdateuserindb');
+ }
}
- return tmp_update_user($user);
+ return $updatesuccessfull;
}
else {
throw new moodle_exception('wscouldnotupdateuser');
}
-
+
}
}
*
* @param assoc array or object $user
*
- * @return userid or thrown exceptions
+ * @return string or thrown exceptions
*/
function tmp_create_user($user) {
global $CFG, $DB;
- ///WS: convert user array into an user object
+ /// WS: convert user array into an user object
if (is_array($user)) {
$user = (object) $user;
}
- ///check password and auth fields
- if (!isset($user->password)) {
- $user->password = '';
- }
+ /// check auth fields
if (!isset($user->auth)) {
$user->auth = 'manual';
+ } else {
+ /// check that the auth value exists
+ $authplugin = get_directory_list($CFG->dirroot."/auth", '', false, true, false);
+ if (array_search($user->auth, $authplugin)===false) {
+ throw new moodle_exception('authnotexisting');
+ }
}
- $required = array('username','firstname','lastname','email');
+ $required = array('username','firstname','lastname','email', 'password');
foreach ($required as $req) {
if (!isset($user->{$req})) {
throw new moodle_exception('missingerequiredfield');
}
}
-
- $record = create_user_record($user->username, $user->password, $user->auth);
+ $password = hash_internal_user_password($user->password);
+ $record = create_user_record($user->username, $password, $user->auth);
if ($record) {
$user->id = $record->id;
if ($DB->update_record('user',$user)) {
return $record->id;
} else {
+ //we could not update properly the newly created user, we need to delete it
$DB->delete_record('user',array('id' => $record->id));
+ throw new moodle_exception('couldnotcreateuser');
}
}
throw new moodle_exception('couldnotcreateuser');
/**
* Update a user record from its id
* Warning: no checks are done on the data!!!
- * @param object $user
+ * @param object $user
+ * @return boolean
*/
function tmp_update_user($user) {
global $DB;
--- /dev/null
+<?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 user
+ * @copyright Copyright (c) 1999 onwards Martin Dougiamas http://dougiamas.com
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL License
+ */
+
+/**
+ * Unit tests for (some of) user/external.php.
+ * WARNING: DO NOT RUN THIS TEST ON A PRODUCTION SITE
+ * => DO NOT UNCOMMENT THESE TEST FUNCTIONS EXCEPT IF U R DEV
+ * => NONE OF THESE TEST FUNCTIONS SHOULD BE UNCOMMENT BY DEFAULT
+ * => THESE TEST FUNCTIONS ARE DEPENDENT BETWEEEN EACH OTHER
+ * => THE FUNCTION ORDER CAN NOT BE CHANGE
+ *
+ *
+ * THESE TEST NEED TO BE RUN AS ADMIN!!!
+ * @author Jerome Mouneyrac
+ */
+
+require_once($CFG->dirroot . '/user/external.php');
+
+class user_external_test extends UnitTestCase {
+ var $realDB;
+
+ function setUp() {
+
+ }
+
+ function tearDown() {
+
+ }
+/*
+ function testTmp_create_users() {
+ /// test that we create multiple users
+ $params = array();
+ for ($i=0;$i<2;$i=$i+1) {
+ $user = array();
+ $user['username'] = 'mockuserfortesting'.$i;
+ $user['firstname'] = 'mockuserfortesting'.$i.'_firstname';
+ $user['lastname'] = 'mockuserfortesting'.$i.'_lastname';
+ $user['email'] = 'mockuserfortesting'.$i.'@moodle.com';
+ $user['password'] = 'mockuserfortesting'.$i.'_password';
+ $params[] = $user;
+ }
+ $result = user_external::tmp_create_users($params);
+ $this->assertEqual(sizeof($result), 2);
+ //just test that value are integer and not null
+ $this->assertIsA($result[key($result)], "integer");
+ $this->assertNotNull($result[key($result)]);
+
+ /// test that we create one user with all optional fields
+ $params = array();
+ $user = array();
+ $user['username'] = 'mockuserfortestingXX';
+ $user['firstname'] = 'mockuserfortesting_firstname';
+ $user['lastname'] = 'mockuserfortesting_lastname';
+ $user['email'] = 'mockuserfortesting@moodle.com';
+ $user['password'] = 'mockuserfortesting_password';
+ $user['city'] = 'mockuserfortesting_city';
+ $user['description'] = 'mockuserfortesting description';
+ $user['country'] = 'AU';
+ $user['lang']='en_utf8';
+ $user['auth']='manual';
+ $params[] = $user;
+ $result = user_external::tmp_create_users($params);
+ $this->assertEqual($result, true);
+
+
+ /// test we cannot create a user with some missing mandatory field
+ $params = array();
+ $user = array();
+ $user['username'] = 'mockuserfortestingY';
+ $params[] = $user;
+ $this->expectException(new moodle_exception('missingerequiredfield'));
+ $result = user_external::tmp_create_users($params);
+
+ }
+
+ function testTmp_create_users_2() {
+ /// test we cannot create a user because the username already exist
+ $params = array();
+ $user = array();
+ $user['username'] = 'mockuserfortestingXX';
+ $user['firstname'] = 'mockuserfortestingX_firstname';
+ $user['lastname'] = 'mockuserfortestingX_lastname';
+ $user['email'] = 'mockuserfortestingX@moodle.com';
+ $user['password'] = 'mockuserfortestingX_password';
+ $params[] = $user;
+
+ $this->expectException(new moodle_exception('wscouldnotcreateeuserindb'));
+ $result = user_external::tmp_create_users($params);
+ }
+
+ function testTmp_get_users() {
+ $params = array('search' => 'mockuserfortestingXX');
+ $users = user_external::tmp_get_users($params);
+ foreach ($users as $user) {
+ $this->assertEqual($user->username, 'mockuserfortestingXX');
+ $this->assertEqual($user->firstname, 'mockuserfortesting_firstname');
+ $this->assertEqual($user->lastname, 'mockuserfortesting_lastname');
+ $this->assertEqual($user->email, 'mockuserfortesting@moodle.com');
+ // $this->assertEqual($user->password, 'mockuserfortesting_password');
+ $this->assertEqual($user->city, 'mockuserfortesting_c');
+ $this->assertEqual($user->description, 'mockuserfortesting description');
+ $this->assertEqual($user->country, 'AU');
+ $this->assertEqual($user->lang, 'en_utf8');
+ }
+
+ }
+
+ function testTmp_update_users() {
+ /// update several users with full information
+ $params = array();
+ $user = array();
+ $user['username'] = 'mockuserfortestingXX';
+ $user['newusername'] = 'mockuserfortestingXY';
+ $user['firstname'] = 'mockuserfortestingY_firstname';
+ $user['lastname'] = 'mockuserfortestingY_lastname';
+ $user['email'] = 'mockuserfortestingY@moodle.com';
+ $user['password'] = 'mockuserfortestingY_password';
+ $user['city'] = 'mockuserfortestingY_city';
+ $user['description'] = 'mockuserfortestingY description';
+ $user['country'] = 'AU';
+ $user['lang']='en_utf8';
+ $user['auth']='manual';
+ $params[] = $user;
+ $user = array();
+ $user['username'] = 'mockuserfortesting0';
+ $user['newusername'] = 'mockuserfortesting0Y';
+ $user['firstname'] = 'mockuserfortesting0Y_firstname';
+ $user['lastname'] = 'mockuserfortesting0Y_lastname';
+ $user['email'] = 'mockuserfortesting0Y@moodle.com';
+ $user['password'] = 'mockuserfortesting0Y_password';
+ $user['city'] = 'mockuserfortesting0Y_city';
+ $user['description'] = 'mockuserfortesting0Y description';
+ $user['country'] = 'AU';
+ $user['lang']='en_utf8';
+ $user['auth']='manual';
+ $params[] = $user;
+ $result = user_external::tmp_update_users($params);
+ $this->assertEqual($result, true);
+
+ /// Exception: update non existing user
+ $params = array();
+ $user = array();
+ $user['username'] = 'mockuserfortesting000';
+ $user['newusername'] = 'mockuserfortesting0Y';
+ $params[] = $user;
+ $this->expectException(new moodle_exception('wscouldnotupdatenoexistinguser')); //TODO catch the write exception
+ $result = user_external::tmp_update_users($params);
+ }
+
+ function testTmp_update_users_2() {
+ /// update an existing user with an already existing username
+ $params = array();
+ $user = array();
+ $user['username'] = 'mockuserfortesting0Y';
+ $user['newusername'] = 'mockuserfortestingXY';
+ $params[] = $user;
+
+ $this->expectException(new moodle_exception('wscouldnotupdateuserindb'));
+ $result = user_external::tmp_update_users($params);
+ }
+
+ function testTmp_delete_users() {
+ /// we delete all previously created users
+ $params = array();
+ $user = array();
+ $user['username'] = 'mockuserfortestingXY';
+ $params[] = $user;
+ $user = array();
+ $user['username'] = 'mockuserfortesting0Y';
+ $params[] = $user;
+ $user = array();
+ $user['username'] = 'mockuserfortesting1';
+ $params[] = $user;
+ $result = user_external::tmp_delete_users($params);
+ $this->assertEqual($result, true);
+
+ /// try to delete them a new time, should return exception
+ $this->expectException(new moodle_exception('wscouldnotdeletenoexistinguser'));
+ $result = user_external::tmp_delete_users($params);
+ }
+*/
+}
+?>
\ No newline at end of file
}
}
- // echo "<pre>";
- // var_dump($description);
- // echo "</pre>";
+// echo "<pre>";
+// var_dump($description);
+// echo "</pre>";
return $description;
}
//call_soap_function($client,$functionname,$param,$expectedresult);
print "<pre>\n";
-var_dump($client->tmp_create_user(array('username' => "mockuser66",'firstname' => "firstname6",'lastname' => "lastname6",'email' => "mockuser6@mockuser6.com",'password' => "password6")));
+var_dump($client->tmp_create_users(array(array('username' => "mockuser66",'firstname' => "firstname6",'lastname' => "lastname6",'email' => "mockuser6@mockuser6.com",'password' => "password6"))));
print "</pre>";
print "<pre>\n";
-var_dump($client->tmp_update_user(array('mnethostid' => 1,'username' => "mockuser66",'newusername' => "mockuser6b",'firstname' => "firstname6b")));
+var_dump($client->tmp_update_users(array(array('username' => "mockuser66",'newusername' => "mockuser6b",'firstname' => "firstname6b"))));
print "</pre>";
print "<pre>\n";
-var_dump($client->tmp_delete_user(array('username' => "mockuser6b",'mnethostid' => 1)));
+var_dump($client->tmp_delete_users(array(array('username' => "mockuser6b"))));
print "</pre>";
-print "<pre>\n";
-var_dump($client->tmp_do_multiple_user_searches(array(array('search' => "jerome"),array('search' => "mock"))));
-print "</pre>";
+//print "<pre>\n";
+//var_dump($client->tmp_do_multiple_user_searches(array(array('search' => "jerome"),array('search' => "mock"))));
+//print "</pre>";
print_footer();
-//function call_soap_function($client,$functionname,$param,$expectedresult) {
-// print "<pre>\n";
-// var_dump($client->$functionname($param));
-// print "</pre>";
-//}
+function call_soap_function($client,$functionname,$param,$expectedresult) {
+ print "<pre>\n";
+ var_dump($client->$functionname($param));
+ print "</pre>";
+}
function printLastRequestResponse($client) {
$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"))));
+var_dump($users = $client->call('user.tmp_create_users', array(array(array('firstname' => "firstname6",'username' => "mockuser66",'lastname' => "lastname6",'email' => "mockuser6@mockuser6.com",'password' => "password6")))));
print "<br/><br/>\n";
-var_dump($users = $client->call('user.tmp_update_user', array(array('username' => "mockuser66",'mnethostid' => 1,'newusername' => "mockuser6b",'firstname' => "firstname6b"))));
-print "<br/><br/>\n";
-var_dump($users = $client->call('user.tmp_delete_user', array(array('username' => "mockuser6b",'mnethostid' => 1))));
-print "<br/><br/>\n";
-var_dump($users = $client->call('user.tmp_do_multiple_user_searches', array(array(array('search' => "jerome"),array('search' => "admin")))));
+var_dump($users = $client->call('user.tmp_update_users', array(array(array('username' => "mockuser66",'newusername' => "mockuser6b",'firstname' => "firstname6b")))));
print "<br/><br/>\n";
+var_dump($users = $client->call('user.tmp_delete_users', array(array(array('username' => "mockuser6b")))));
+//print "<br/><br/>\n";
+//var_dump($users = $client->call('user.tmp_do_multiple_user_searches', array(array(array('search' => "jerome"),array('search' => "admin")))));
+//print "<br/><br/>\n";
?>
\ No newline at end of file