web service MDL-12886 add delete + update user core function and REST ws functions

This commit is contained in:
jerome 2009-01-15 06:12:57 +00:00
parent d65c238b2c
commit 74f3622699
8 changed files with 423 additions and 209 deletions

View File

@ -12,207 +12,280 @@
*/
final class user_api {
/**
* Returns a subset of users (DO NOT COUNT)
* @global object $DB
* @param string $sort A SQL snippet for the sorting criteria to use
* @param string $recordsperpage how many records do pages have
* @param string $page which page to return (starts from 0)
* @param string $fields A comma separated list of fields to be returned from the chosen table.
* @param object $selectioncriteria:
* ->search string A simple string to search for
* ->confirmed bool A switch to allow/disallow unconfirmed users
* ->exceptions array(int) A list of IDs to ignore, eg 2,4,5,8,9,10
* ->firstinitial string ?
* ->lastinitial string ?
* @return array|false Array of {@link $USER} objects. False is returned if an error is encountered.
*/
static function tmp_namedparams_get_users($sort='firstname ASC', $recordsperpage=999999, $page=0, $fields='*', $selectioncriteria=NULL) {
global $DB;
/**
* Returns a subset of users (DO NOT COUNT)
* @global object $DB
* @param string $sort A SQL snippet for the sorting criteria to use
* @param string $recordsperpage how many records do pages have
* @param string $page which page to return (starts from 0)
* @param string $fields A comma separated list of fields to be returned from the chosen table.
* @param object $selectioncriteria:
* ->search string A simple string to search for
* ->confirmed bool A switch to allow/disallow unconfirmed users
* ->exceptions array(int) A list of IDs to ignore, eg 2,4,5,8,9,10
* ->firstinitial string ?
* ->lastinitial string ?
* @return array|false Array of {@link $USER} objects. False is returned if an error is encountered.
*/
static function tmp_namedparams_get_users($sort='firstname ASC', $recordsperpage=999999, $page=0, $fields='*', $selectioncriteria=NULL) {
global $DB;
///WS: convert array into an object
if (!empty($selectioncriteria) && is_array($selectioncriteria)) {
$selectioncriteria = (object) $selectioncriteria;
}
$LIKE = $DB->sql_ilike();
$fullname = $DB->sql_fullname();
$select = " username <> :guest AND deleted = 0";
$params = array('guest'=>'guest');
if (!empty($selectioncriteria->search)){
$selectioncriteria->search = trim($selectioncriteria->search);
$select .= " AND ($fullname $LIKE :search1 OR email $LIKE :search2 OR username = :search3)";
$params['search1'] = "%".$selectioncriteria->search."%";
$params['search2'] = "%".$selectioncriteria->search."%";
$params['search3'] = $selectioncriteria->search;
}
if (!empty($selectioncriteria->confirmed)) {
$select .= " AND confirmed = 1";
}
if (!empty($selectioncriteria->exceptions)) {
list($selectioncriteria->exceptions, $eparams) = $DB->get_in_or_equal($selectioncriteria->exceptions, SQL_PARAMS_NAMED, 'ex0000', false);
$params = $params + $eparams;
$except = " AND id ".$selectioncriteria->exceptions;
}
if (!empty($selectioncriteria->firstinitial)) {
$select .= " AND firstname $LIKE :fni";
$params['fni'] = $selectioncriteria->firstinitial."%";
}
if (!empty($selectioncriteria->lastinitial)) {
$select .= " AND lastname $LIKE :lni";
$params['lni'] = $selectioncriteria->lastinitial."%";
}
if (!empty($selectioncriteria->extraselect)) {
$select .= " AND ".$selectioncriteria->extraselect;
if (empty($selectioncriteria->extraparams)){
$params = $params + (array)$selectioncriteria->extraparams;
///WS: convert array into an object
if (!empty($selectioncriteria) && is_array($selectioncriteria)) {
$selectioncriteria = (object) $selectioncriteria;
}
}
return $DB->get_records_select('user', $select, $params, $sort, $fields, $page, $recordsperpage);
}
$LIKE = $DB->sql_ilike();
$fullname = $DB->sql_fullname();
/**
* Returns a subset of users
*
* @uses $CFG
* @param bool $get If false then only a count of the records is returned
* @param string $search A simple string to search for
* @param bool $confirmed A switch to allow/disallow unconfirmed users
* @param array(int) $exceptions A list of IDs to ignore, eg 2,4,5,8,9,10
* @param string $sort A SQL snippet for the sorting criteria to use
* @param string $firstinitial ?
* @param string $lastinitial ?
* @param string $page ?
* @param string $recordsperpage ?
* @param string $fields A comma separated list of fields to be returned from the chosen table.
* @return object|false|int {@link $USER} records unless get is false in which case the integer count of the records found is returned. False is returned if an error is encountered.
*/
static function tmp_get_users($get=true, $search='', $confirmed=false, array $exceptions=null, $sort='firstname ASC',
$firstinitial='', $lastinitial='', $page='', $recordsperpage='', $fields='*', $extraselect='', array $extraparams=null) {
global $DB;
$select = " username <> :guest AND deleted = 0";
$params = array('guest'=>'guest');
if ($get && !$recordsperpage) {
debugging('Call to get_users with $get = true no $recordsperpage limit. ' .
'On large installations, this will probably cause an out of memory error. ' .
'Please think again and change your code so that it does not try to ' .
'load so much data into memory.', DEBUG_DEVELOPER);
}
if (!empty($selectioncriteria->search)){
$selectioncriteria->search = trim($selectioncriteria->search);
$select .= " AND ($fullname $LIKE :search1 OR email $LIKE :search2 OR username = :search3)";
$params['search1'] = "%".$selectioncriteria->search."%";
$params['search2'] = "%".$selectioncriteria->search."%";
$params['search3'] = $selectioncriteria->search;
}
$LIKE = $DB->sql_ilike();
$fullname = $DB->sql_fullname();
if (!empty($selectioncriteria->confirmed)) {
$select .= " AND confirmed = 1";
}
$select = " username <> :guest AND deleted = 0";
$params = array('guest'=>'guest');
if (!empty($selectioncriteria->exceptions)) {
list($selectioncriteria->exceptions, $eparams) = $DB->get_in_or_equal($selectioncriteria->exceptions, SQL_PARAMS_NAMED, 'ex0000', false);
$params = $params + $eparams;
$except = " AND id ".$selectioncriteria->exceptions;
}
if (!empty($search)){
$search = trim($search);
$select .= " AND ($fullname $LIKE :search1 OR email $LIKE :search2 OR username = :search3)";
$params['search1'] = "%$search%";
$params['search2'] = "%$search%";
$params['search3'] = "$search";
}
if (!empty($selectioncriteria->firstinitial)) {
$select .= " AND firstname $LIKE :fni";
$params['fni'] = $selectioncriteria->firstinitial."%";
}
if (!empty($selectioncriteria->lastinitial)) {
$select .= " AND lastname $LIKE :lni";
$params['lni'] = $selectioncriteria->lastinitial."%";
}
if ($confirmed) {
$select .= " AND confirmed = 1";
}
if (!empty($selectioncriteria->extraselect)) {
$select .= " AND ".$selectioncriteria->extraselect;
if (empty($selectioncriteria->extraparams)){
$params = $params + (array)$selectioncriteria->extraparams;
}
}
if ($exceptions) {
list($exceptions, $eparams) = $DB->get_in_or_equal($exceptions, SQL_PARAMS_NAMED, 'ex0000', false);
$params = $params + $eparams;
$except = " AND id $exceptions";
}
if ($firstinitial) {
$select .= " AND firstname $LIKE :fni";
$params['fni'] = "$firstinitial%";
}
if ($lastinitial) {
$select .= " AND lastname $LIKE :lni";
$params['lni'] = "$lastinitial%";
}
if ($extraselect) {
$select .= " AND $extraselect";
$params = $params + (array)$extraparams;
}
if ($get) {
return $DB->get_records_select('user', $select, $params, $sort, $fields, $page, $recordsperpage);
} else {
return $DB->count_records_select('user', $select, $params);
}
}
/**
* Creates an User with given information. Required fields are:
* -username
* -idnumber
* -firstname
* -lastname
* -email
*
* And there's some interesting fields:
* -password
* -auth
* -confirmed
* -timezone
* -country
* -emailstop
* -theme
* -lang
* -mailformat
*
* @param assoc array or object $user
*
* @return userid or thrown exceptions
*/
static function tmp_create_user($user) {
global $CFG, $DB;
///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 = '';
}
if (!isset($user->auth)) {
$user->auth = 'manual';
}
$required = array('username','firstname','lastname','email');
foreach ($required as $req) {
if (!isset($user->{$req})) {
throw new moodle_exception('missingerequiredfield');
/**
* Returns a subset of users
*
* @uses $CFG
* @param bool $get If false then only a count of the records is returned
* @param string $search A simple string to search for
* @param bool $confirmed A switch to allow/disallow unconfirmed users
* @param array(int) $exceptions A list of IDs to ignore, eg 2,4,5,8,9,10
* @param string $sort A SQL snippet for the sorting criteria to use
* @param string $firstinitial ?
* @param string $lastinitial ?
* @param string $page ?
* @param string $recordsperpage ?
* @param string $fields A comma separated list of fields to be returned from the chosen table.
* @return object|false|int {@link $USER} records unless get is false in which case the integer count of the records found is returned. False is returned if an error is encountered.
*/
static function tmp_get_users($get=true, $search='', $confirmed=false, array $exceptions=null, $sort='firstname ASC',
$firstinitial='', $lastinitial='', $page='', $recordsperpage='', $fields='*', $extraselect='', array $extraparams=null) {
global $DB;
if ($get && !$recordsperpage) {
debugging('Call to get_users with $get = true no $recordsperpage limit. ' .
'On large installations, this will probably cause an out of memory error. ' .
'Please think again and change your code so that it does not try to ' .
'load so much data into memory.', DEBUG_DEVELOPER);
}
}
$record = create_user_record($user->username, $user->password, $user->auth);
if ($record) {
$user->id = $record->id;
if ($DB->update_record('user',$user)) {
return $record->id;
$LIKE = $DB->sql_ilike();
$fullname = $DB->sql_fullname();
$select = " username <> :guest AND deleted = 0";
$params = array('guest'=>'guest');
if (!empty($search)){
$search = trim($search);
$select .= " AND ($fullname $LIKE :search1 OR email $LIKE :search2 OR username = :search3)";
$params['search1'] = "%$search%";
$params['search2'] = "%$search%";
$params['search3'] = "$search";
}
if ($confirmed) {
$select .= " AND confirmed = 1";
}
if ($exceptions) {
list($exceptions, $eparams) = $DB->get_in_or_equal($exceptions, SQL_PARAMS_NAMED, 'ex0000', false);
$params = $params + $eparams;
$except = " AND id $exceptions";
}
if ($firstinitial) {
$select .= " AND firstname $LIKE :fni";
$params['fni'] = "$firstinitial%";
}
if ($lastinitial) {
$select .= " AND lastname $LIKE :lni";
$params['lni'] = "$lastinitial%";
}
if ($extraselect) {
$select .= " AND $extraselect";
$params = $params + (array)$extraparams;
}
if ($get) {
return $DB->get_records_select('user', $select, $params, $sort, $fields, $page, $recordsperpage);
} else {
$DB->delete_record('user',array('id' => $record->id));
return $DB->count_records_select('user', $select, $params);
}
}
throw new moodle_exception('couldnotcreateuser');
}
}
/**
* Creates an User with given information. Required fields are:
* -username
* -idnumber
* -firstname
* -lastname
* -email
*
* And there's some interesting fields:
* -password
* -auth
* -confirmed
* -timezone
* -country
* -emailstop
* -theme
* -lang
* -mailformat
*
* @param assoc array or object $user
*
* @return userid or thrown exceptions
*/
static function tmp_create_user($user) {
global $CFG, $DB;
///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 = '';
}
if (!isset($user->auth)) {
$user->auth = 'manual';
}
$required = array('username','firstname','lastname','email');
foreach ($required as $req) {
if (!isset($user->{$req})) {
throw new moodle_exception('missingerequiredfield');
}
}
$record = create_user_record($user->username, $user->password, $user->auth);
if ($record) {
$user->id = $record->id;
if ($DB->update_record('user',$user)) {
return $record->id;
} else {
$DB->delete_record('user',array('id' => $record->id));
}
}
throw new moodle_exception('couldnotcreateuser');
}
/**
* Marks user deleted in internal user database and notifies the auth plugin.
* Also unenrols user from all roles and does other cleanup.
* @param object $user Userobject before delete (without system magic quotes)
* @return boolean success
*/
static function tmp_delete_user($user) {
global $CFG, $DB;
require_once($CFG->libdir.'/grouplib.php');
require_once($CFG->libdir.'/gradelib.php');
$DB->begin_sql();
// delete all grades - backup is kept in grade_grades_history table
if ($grades = grade_grade::fetch_all(array('userid'=>$user->id))) {
foreach ($grades as $grade) {
$grade->delete('userdelete');
}
}
// remove from all groups
$DB->delete_records('groups_members', array('userid'=>$user->id));
// unenrol from all roles in all contexts
role_unassign(0, $user->id); // this might be slow but it is really needed - modules might do some extra cleanup!
// now do a final accesslib cleanup - removes all role assingments in user context and context itself
delete_context(CONTEXT_USER, $user->id);
require_once($CFG->dirroot.'/tag/lib.php');
tag_set('user', $user->id, array());
// workaround for bulk deletes of users with the same email address
$delname = "$user->email.".time();
while ($DB->record_exists('user', array('username'=>$delname))) { // no need to use mnethostid here
$delname++;
}
// mark internal user record as "deleted"
$updateuser = new object();
$updateuser->id = $user->id;
$updateuser->deleted = 1;
$updateuser->username = $delname; // Remember it just in case
$updateuser->email = ''; // Clear this field to free it up
$updateuser->idnumber = ''; // Clear this field to free it up
$updateuser->timemodified = time();
if ($DB->update_record('user', $updateuser)) {
$DB->commit_sql();
// notify auth plugin - do not block the delete even when plugin fails
$authplugin = get_auth_plugin($user->auth);
$authplugin->user_delete($user);
events_trigger('user_deleted', $user);
return true;
} else {
$DB->rollback_sql();
return false;
}
}
/**
* Update a user record from its id
* Warning: no checks are done on the data!!!
* @param object $user
*/
static function tmp_update_user($user) {
global $DB;
if ($DB->update_record('user', $user)) {
$DB->commit_sql();
events_trigger('user_updated', $user);
return true;
} else {
$DB->rollback_sql();
return false;
}
}
}
?>

View File

@ -32,7 +32,7 @@ final class user_ws_api extends moodle_ws_api {
/// Then 'paramorder'=> array('anyobjectname' => array('username' => ...));
///
///TODO: manage object->object parameter
$this->descriptions['tmp_get_users'] = array( 'wsparams' => array('search'=> PARAM_ALPHA),
$this->descriptions['tmp_get_users'] = array( 'wsparams' => array('search'=> PARAM_ALPHANUM),
'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)));
@ -45,12 +45,18 @@ final class user_ws_api extends moodle_ws_api {
'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( 'wsparams' => array('username'=> PARAM_ALPHANUM, 'mnethostid'=> PARAM_NUMBER),
'return' => array('result', PARAM_BOOL));
$this->descriptions['tmp_update_user'] = array( 'wsparams' => array('username'=> PARAM_ALPHANUM, 'mnethostid'=> PARAM_NUMBER, 'newusername' => PARAM_ALPHANUM, 'firstname' => PARAM_ALPHANUM),
'return' => array('result', PARAM_BOOL));
}
/**
*
* @param <type> $search
* @return <type>
* Retrieve all user
* @param string $search
* @return object user
*/
static function tmp_get_users($search) {
return user_api::tmp_get_users( true, $search, false, null, 'firstname ASC','', '', '', '',
@ -58,13 +64,13 @@ final class user_ws_api extends moodle_ws_api {
}
/**
*
* @param <type> $username
* @param <type> $firstname
* @param <type> $lastname
* @param <type> $email
* @param <type> $password
* @return <type>
* Create a user
* @param string $username
* @param string $firstname
* @param string $lastname
* @param string $email
* @param string $password
* @return integer id of new user
*/
static function tmp_create_user($username, $firstname, $lastname, $email, $password) {
$user = array();
@ -73,8 +79,38 @@ final class user_ws_api extends moodle_ws_api {
$user['lastname'] = $lastname;
$user['email'] = $email;
$user['password'] = $password;
return user_api::tmp_create_user($user);
return user_api::tmp_create_user($user);
}
/**
* Delete a user
* @global object $DB
* @param string $username
* @param integer $mnethostid
* @return boolean true if success
*/
static function tmp_delete_user($username, $mnethostid) {
global $DB;
$user = $DB->get_record('user', array('username'=>$username, 'mnethostid'=>$mnethostid));
return user_api::tmp_delete_user($user);
}
/**
* Update some user information
* @global object $DB
* @param string $username
* @param integer $mnethostid
* @param string $newusername
* @param string $firstname
* @return boolean true if success
*/
static function tmp_update_user($username, $mnethostid, $newusername, $firstname) {
global $DB;
$user = $DB->get_record('user', array('username'=>$username, 'mnethostid'=>$mnethostid));
$user->username = $newusername;
$user->firstname = $firstname;
return user_api::tmp_update_user($user);
}
}

View File

@ -54,8 +54,8 @@ function call_moodle_function ($rest_arguments) {
* @return <type>
*/
function retrieve_params ($description) {
$params = $description['wsparam'];
//retrieve REST param matching the description
// $params = $description['wsparams'];
//retrieve REST param matching the description (warning: PHP assign the first instanciation as the first position in the table)
foreach ($description['wsparams'] as $paramname => $paramtype) {
$value = optional_param($paramname,null,$paramtype);

View File

@ -15,10 +15,6 @@
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once('lib.php');
if (empty($CFG->enablewebservices)) {
die;
}
//retrieve path and function name from the URL
$rest_arguments = get_file_argument('server.php');

View File

@ -13,10 +13,6 @@
require_once("../../../config.php");
require_once ('lib.php');
if (empty($CFG->enablewebservices)) {
die;
}
$CFG->serverurl = $CFG->wwwroot.'/webservice/rest/server.php';
if (!function_exists('curl_init')) die ('CURL library was not found!');

View File

@ -0,0 +1,54 @@
<?php
/**
* Created on 10/17/2008
*
* Rest Test Client
*
* @author David Castro Garcia
* @author Ferran Recio Calderó
* @author Jerome Mouneyrac
*/
require_once ('config_rest.php');
$params = array('username','mnethostid');
foreach ($params as $param) {
$$param = (isset($_POST[$param]))?$_POST[$param]:'';
}
start_interface("Delete a user");
?>
<form action="deleteuser.php" method="post">
<table border="0">
<tr><td>Search: </td><td><input type="text" name="username" value="<?php echo $username; ?>"/></td></tr>
<tr><td></td><td><input type="hidden" name="mnethostid" value="1"><input type="submit" value="Find Users"></td></tr>
</table>
</form>
<?php
if ($username) {
$data['username'] = $username;
$data['mnethostid'] = $mnethostid;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $CFG->serverurl.'/user/tmp_delete_user');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, format_postdata($data));
$out = curl_exec($ch);
$res = basicxml_xml_to_object($out);
//show_object($res->user,2,'auth');
var_dump($res);
show_xml ($out);
} else {
echo "<p>Fill the form first</p>";
}
end_interface();
?>

View File

@ -13,9 +13,10 @@ require_once ('config_rest.php');
start_interface (false);
$links = array( array('getusers.php','getusers()'),
array('createuser.php','createuser()'),
array('namedparams_get_users.php','namedparams_get_users()'));
$links = array( array('getusers.php','get_users()'),
array('createuser.php','create_user()'),
array('deleteuser.php','delete_user()'),
array('updateuser.php','update_user()'));
echo '<ul>';
foreach ($links as $link) {

View File

@ -0,0 +1,58 @@
<?php
/**
* Created on 10/17/2008
*
* Rest Test Client
*
* @author David Castro Garcia
* @author Ferran Recio Calderó
* @author Jerome Mouneyrac
*/
require_once ('config_rest.php');
$params = array('username','mnethostid','newusername','firstname');
foreach ($params as $param) {
$$param = (isset($_POST[$param]))?$_POST[$param]:'';
}
start_interface("Update a user");
?>
<form action="updateuser.php" method="post">
<table border="0">
<tr><td>Old username: </td><td><input type="text" name="username" value="<?php echo $username; ?>"/></td></tr>
<tr><td>New username: </td><td><input type="text" name="newusername" value="<?php echo $newusername; ?>"/></td></tr>
<tr><td>New firstname: </td><td><input type="text" name="firstname" value="<?php echo $firstname; ?>"/></td></tr>
<tr><td></td><td><input type="hidden" name="mnethostid" value="1"><input type="submit" value="Find Users"></td></tr>
</table>
</form>
<?php
if ($username) {
$data['username'] = $username;
$data['mnethostid'] = $mnethostid;
$data['newusername'] = $newusername;
$data['firstname'] = $firstname;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $CFG->serverurl.'/user/tmp_update_user');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, format_postdata($data));
$out = curl_exec($ch);
$res = basicxml_xml_to_object($out);
//show_object($res->user,2,'auth');
var_dump($res);
show_xml ($out);
} else {
echo "<p>Fill the form first</p>";
}
end_interface();
?>