From fb79269bef7fe875ff2995c74669659f68102898 Mon Sep 17 00:00:00 2001 From: jerome mouneyrac Date: Thu, 11 Feb 2010 04:02:04 +0000 Subject: [PATCH] webservice MDL-20808 add user lib.php, add web service user functions, rename $usercustomfields variable into profile_user_record() function --- admin/webservice/testclient_forms.php | 273 ++++++++++++++++++++++++++ lib/db/services.php | 14 +- user/externallib.php | 159 +++++++++------ user/lib.php | 130 ++++++++++++ user/profile/lib.php | 6 +- version.php | 2 +- 6 files changed, 519 insertions(+), 65 deletions(-) create mode 100644 user/lib.php diff --git a/admin/webservice/testclient_forms.php b/admin/webservice/testclient_forms.php index 1701d764ea7..6aa60c6c043 100644 --- a/admin/webservice/testclient_forms.php +++ b/admin/webservice/testclient_forms.php @@ -25,6 +25,279 @@ class webservice_test_client_form extends moodleform { // === Test client forms === +class moodle_user_create_users_form extends moodleform { + public function definition() { + global $CFG; + + $mform = $this->_form; + + + $mform->addElement('header', 'wstestclienthdr', get_string('testclient', 'webservice')); + + //note: these values are intentionally PARAM_RAW - we want users to test any rubbish as parameters + $data = $this->_customdata; + if ($data['authmethod'] == 'simple') { + $mform->addElement('text', 'wsusername', 'wsusername'); + $mform->addElement('text', 'wspassword', 'wspassword'); + } else if ($data['authmethod'] == 'token') { + $mform->addElement('text', 'token', 'token'); + } + + $mform->addElement('hidden', 'authmethod', $data['authmethod']); + $mform->setType('authmethod', PARAM_SAFEDIR); + + /// specific to the create users function + $mform->addElement('text', 'username', 'username'); + $mform->addElement('text', 'password', 'password'); + $mform->addElement('text', 'firstname', 'firstname'); + $mform->addElement('text', 'lastname', 'lastname'); + $mform->addElement('text', 'email', 'email'); + + $mform->addElement('hidden', 'function'); + $mform->setType('function', PARAM_SAFEDIR); + + $mform->addElement('hidden', 'protocol'); + $mform->setType('protocol', PARAM_SAFEDIR); + + + + $mform->addElement('static', 'warning', '', get_string('executewarnign', 'webservice')); + + $this->add_action_buttons(true, get_string('execute', 'webservice')); + } + + public function get_params() { + if (!$data = $this->get_data()) { + return null; + } + // remove unused from form data + unset($data->submitbutton); + unset($data->protocol); + unset($data->function); + unset($data->wsusername); + unset($data->wspassword); + unset($data->token); + unset($data->authmethod); + + $params = array(); + $params['users'] = array(); + $params['users'][] = (array)$data; + + return $params; + } +} + + +class moodle_user_update_users_form extends moodleform { + public function definition() { + global $CFG; + + $mform = $this->_form; + + + $mform->addElement('header', 'wstestclienthdr', get_string('testclient', 'webservice')); + + //note: these values are intentionally PARAM_RAW - we want users to test any rubbish as parameters + $data = $this->_customdata; + if ($data['authmethod'] == 'simple') { + $mform->addElement('text', 'wsusername', 'wsusername'); + $mform->addElement('text', 'wspassword', 'wspassword'); + } else if ($data['authmethod'] == 'token') { + $mform->addElement('text', 'token', 'token'); + } + + $mform->addElement('hidden', 'authmethod', $data['authmethod']); + $mform->setType('authmethod', PARAM_SAFEDIR); + + /// specific to the create users function + $mform->addElement('text', 'id', 'id'); + $mform->addRule('id', get_string('required'), 'required', null, 'client'); + $mform->addElement('text', 'username', 'username'); + $mform->addElement('text', 'password', 'password'); + $mform->addElement('text', 'firstname', 'firstname'); + $mform->addElement('text', 'lastname', 'lastname'); + $mform->addElement('text', 'email', 'email'); + + $mform->addElement('hidden', 'function'); + $mform->setType('function', PARAM_SAFEDIR); + + $mform->addElement('hidden', 'protocol'); + $mform->setType('protocol', PARAM_SAFEDIR); + + + + $mform->addElement('static', 'warning', '', get_string('executewarnign', 'webservice')); + + $this->add_action_buttons(true, get_string('execute', 'webservice')); + } + + public function get_params() { + if (!$data = $this->get_data()) { + return null; + } + // remove unused from form data + unset($data->submitbutton); + unset($data->protocol); + unset($data->function); + unset($data->wsusername); + unset($data->wspassword); + unset($data->token); + unset($data->authmethod); + + foreach($data as $key => $value) { + if (empty($value)) { + unset($data->{$key}); + } + } + + $params = array(); + $params['users'] = array(); + $params['users'][] = (array)$data; + + return $params; + } +} + + +class moodle_user_delete_users_form extends moodleform { + public function definition() { + global $CFG; + + $mform = $this->_form; + + + $mform->addElement('header', 'wstestclienthdr', get_string('testclient', 'webservice')); + + //note: these values are intentionally PARAM_RAW - we want users to test any rubbish as parameters + $data = $this->_customdata; + if ($data['authmethod'] == 'simple') { + $mform->addElement('text', 'wsusername', 'wsusername'); + $mform->addElement('text', 'wspassword', 'wspassword'); + } else if ($data['authmethod'] == 'token') { + $mform->addElement('text', 'token', 'token'); + } + + $mform->addElement('hidden', 'authmethod', $data['authmethod']); + $mform->setType('authmethod', PARAM_SAFEDIR); + + /// beginning of specific code to the create users function + $mform->addElement('text', 'userids[0]', 'userids[0]'); + $mform->addElement('text', 'userids[1]', 'userids[1]'); + $mform->addElement('text', 'userids[2]', 'userids[2]'); + $mform->addElement('text', 'userids[3]', 'userids[3]'); + /// end of specific code to the create users function + + $mform->addElement('hidden', 'function'); + $mform->setType('function', PARAM_SAFEDIR); + + $mform->addElement('hidden', 'protocol'); + $mform->setType('protocol', PARAM_SAFEDIR); + + + + $mform->addElement('static', 'warning', '', get_string('executewarnign', 'webservice')); + + $this->add_action_buttons(true, get_string('execute', 'webservice')); + } + + public function get_params() { + if (!$data = $this->get_data()) { + return null; + } + // remove unused from form data + unset($data->submitbutton); + unset($data->protocol); + unset($data->function); + unset($data->wsusername); + unset($data->wspassword); + unset($data->token); + unset($data->authmethod); + + /// beginning of specific code to the create users form + $params = array(); + $params['userids'] = array(); + for ($i=0; $i<10; $i++) { + if (empty($data->userids[$i])) { + continue; + } + $params['userids'][] = $data->userids[$i]; + } + /// end of specific code to the create users function + + return $params; + } +} + + +class moodle_user_get_users_by_id_form extends moodleform { + public function definition() { + global $CFG; + + $mform = $this->_form; + + + $mform->addElement('header', 'wstestclienthdr', get_string('testclient', 'webservice')); + + //note: these values are intentionally PARAM_RAW - we want users to test any rubbish as parameters + $data = $this->_customdata; + if ($data['authmethod'] == 'simple') { + $mform->addElement('text', 'wsusername', 'wsusername'); + $mform->addElement('text', 'wspassword', 'wspassword'); + } else if ($data['authmethod'] == 'token') { + $mform->addElement('text', 'token', 'token'); + } + + $mform->addElement('hidden', 'authmethod', $data['authmethod']); + $mform->setType('authmethod', PARAM_SAFEDIR); + + /// beginning of specific code to the create users function + $mform->addElement('text', 'userids[0]', 'userids[0]'); + $mform->addElement('text', 'userids[1]', 'userids[1]'); + $mform->addElement('text', 'userids[2]', 'userids[2]'); + $mform->addElement('text', 'userids[3]', 'userids[3]'); + /// end of specific code to the create users function + + $mform->addElement('hidden', 'function'); + $mform->setType('function', PARAM_SAFEDIR); + + $mform->addElement('hidden', 'protocol'); + $mform->setType('protocol', PARAM_SAFEDIR); + + + + $mform->addElement('static', 'warning', '', get_string('executewarnign', 'webservice')); + + $this->add_action_buttons(true, get_string('execute', 'webservice')); + } + + public function get_params() { + if (!$data = $this->get_data()) { + return null; + } + // remove unused from form data + unset($data->submitbutton); + unset($data->protocol); + unset($data->function); + unset($data->wsusername); + unset($data->wspassword); + unset($data->token); + unset($data->authmethod); + + /// beginning of specific code to the create users form + $params = array(); + $params['userids'] = array(); + for ($i=0; $i<10; $i++) { + if (empty($data->userids[$i])) { + continue; + } + $params['userids'][] = $data->userids[$i]; + } + /// end of specific code to the create users function + + return $params; + } +} + class moodle_group_create_groups_form extends moodleform { public function definition() { global $CFG; diff --git a/lib/db/services.php b/lib/db/services.php index c2ed8f446f2..71c2e80b600 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -85,29 +85,35 @@ $functions = array( ), // === user related functions === -/* 'moodle_user_create_users' => array( 'classname' => 'moodle_user_external', 'methodname' => 'create_users', 'classpath' => 'user/externallib.php', + 'description' => 'Create users.', + 'type' => 'write', ), - 'moodle_user_get_users' => array( + 'moodle_user_get_users_by_id' => array( 'classname' => 'moodle_user_external', - 'methodname' => 'get_users', + 'methodname' => 'get_users_by_id', 'classpath' => 'user/externallib.php', + 'description' => 'Get users by id.', + 'type' => 'read', ), 'moodle_user_delete_users' => array( 'classname' => 'moodle_user_external', 'methodname' => 'delete_users', 'classpath' => 'user/externallib.php', + 'description' => 'Delete users.', + 'type' => 'write', ), 'moodle_user_update_users' => array( 'classname' => 'moodle_user_external', 'methodname' => 'update_users', 'classpath' => 'user/externallib.php', + 'description' => 'Update users.', + 'type' => 'write', ), -*/ ); diff --git a/user/externallib.php b/user/externallib.php index 8e19ab74b9f..aa7a80631b8 100644 --- a/user/externallib.php +++ b/user/externallib.php @@ -45,30 +45,30 @@ class moodle_user_external extends external_api { 'firstname' => new external_value(PARAM_NOTAGS, 'The first name(s) of the user'), 'lastname' => new external_value(PARAM_NOTAGS, 'The family name of the user'), 'email' => new external_value(PARAM_EMAIL, 'A valid and unique email address'), - 'auth' => new external_value(PARAM_SAFEDIR, 'Auth plugins include manual, ldap, imap, etc', false, 'manual', false), - 'idnumber' => new external_value(PARAM_RAW, 'An arbitrary ID code number perhaps from the institution', false), - 'emailstop' => new external_value(PARAM_NUMBER, 'Email is blocked: 1 is blocked and 0 otherwise', false), - 'lang' => new external_value(PARAM_SAFEDIR, 'Language code such as "en_utf8", must exist on server', false, $CFG->lang, false), - 'theme' => new external_value(PARAM_SAFEDIR, 'Theme name such as "standard", must exist on server', false), - 'timezone' => new external_value(PARAM_ALPHANUMEXT, 'Timezone code such as Australia/Perth, or 99 for default', false), - 'mailformat' => new external_value(PARAM_INTEGER, 'Mail format code is 0 for plain text, 1 for HTML etc', false), - 'description' => new external_value(PARAM_TEXT, 'User profile description, as HTML', false), - 'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', false), - 'country' => new external_value(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ', false), + 'auth' => new external_value(PARAM_SAFEDIR, 'Auth plugins include manual, ldap, imap, etc', VALUE_DEFAULT, 'manual', NULL_NOT_ALLOWED), + 'idnumber' => new external_value(PARAM_RAW, 'An arbitrary ID code number perhaps from the institution', VALUE_DEFAULT, null), + 'emailstop' => new external_value(PARAM_NUMBER, 'Email is blocked: 1 is blocked and 0 otherwise', VALUE_DEFAULT, 0), + 'lang' => new external_value(PARAM_SAFEDIR, 'Language code such as "en_utf8", must exist on server', VALUE_DEFAULT, $CFG->lang, NULL_NOT_ALLOWED), + 'theme' => new external_value(PARAM_SAFEDIR, 'Theme name such as "standard", must exist on server', VALUE_OPTIONAL), + 'timezone' => new external_value(PARAM_ALPHANUMEXT, 'Timezone code such as Australia/Perth, or 99 for default', VALUE_OPTIONAL), + 'mailformat' => new external_value(PARAM_INTEGER, 'Mail format code is 0 for plain text, 1 for HTML etc', VALUE_OPTIONAL), + 'description' => new external_value(PARAM_TEXT, 'User profile description, as HTML', VALUE_OPTIONAL), + 'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', VALUE_OPTIONAL), + 'country' => new external_value(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL), 'preferences' => new external_multiple_structure( new external_single_structure( array( 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the preference'), 'value' => new external_value(PARAM_RAW, 'The value of the preference') ) - ), 'User preferences', false), + ), 'User preferences', VALUE_OPTIONAL), 'customfields' => new external_multiple_structure( new external_single_structure( array( 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the custom field'), 'value' => new external_value(PARAM_RAW, 'The value of the custom field') ) - ), 'User custom fields', false) + ), 'User custom fields', VALUE_OPTIONAL) ) ) ) @@ -84,12 +84,13 @@ class moodle_user_external extends external_api { */ public static function create_users($users) { global $CFG, $DB; + require_once($CFG->dirroot."/user/lib.php"); // Ensure the current user is allowed to run this function $context = get_context_instance(CONTEXT_SYSTEM); - require_capability('moodle/user:create', $context); self::validate_context($context); - + require_capability('moodle/user:create', $context); + // Do basic automatic PARAM checks on incoming data, using params description // If any problems are found then exceptions are thrown with helpful error messages $params = self::validate_parameters(self::create_users_parameters(), array('users'=>$users)); @@ -103,7 +104,7 @@ class moodle_user_external extends external_api { $transaction = $DB->start_delegated_transaction(); - $users = array(); + $userids = array(); foreach ($params['users'] as $user) { // Make sure that the username doesn't already exist if ($DB->record_exists('user', array('username'=>$user['username'], 'mnethostid'=>$CFG->mnet_localhost_id))) { @@ -121,7 +122,10 @@ class moodle_user_external extends external_api { } // Make sure lang is valid - if (empty($availablethemes[$user['theme']])) { + if (!empty($user['theme']) && empty($availablethemes[$user['theme']])) { //theme is VALUE_OPTIONAL, + // so no default value. + // We need to test if the client sent it + // => !empty($user['theme']) throw new invalid_parameter_exception('Invalid theme: '.$user['theme']); } @@ -133,37 +137,17 @@ class moodle_user_external extends external_api { } } - // finally create user and beter fetch from DB - $record = create_user_record($user['username'], $user['password'], $user['auth']); - $newuser = $DB->get_record('user', array('id'=>$record->id), '*', MUST_EXIST); - - // remove already used data - unset($user['username']); - unset($user['password']); - unset($user['auth']); - - // update using given data - foreach ($user as $key=>$value) { - if (is_null($value)) { - //ignore missing fields - continue; - } - if (!array_key_exists($key, $newuser)) { - // set only existing - continue; - } - $newuser->$key = $value; - } - $DB->update_record('user', $newuser); + $user['confirmed'] = true; + $newuserid = user_create_user($user); //TODO: preferences and custom fields - $users[] = array('id'=>$newuser->id, 'username'=>$newuser->username); + $userids[] = array('id'=>$newuserid, 'username'=>$user['username']); } $transaction->allow_commit(); - return $users; + return $userids; } /** @@ -196,20 +180,21 @@ class moodle_user_external extends external_api { public static function delete_users($userids) { global $CFG, $DB; + require_once($CFG->dirroot."/user/lib.php"); // Ensure the current user is allowed to run this function $context = get_context_instance(CONTEXT_SYSTEM); require_capability('moodle/user:delete', $context); self::validate_context($context); - $params = self::validate_parameters(self::delete_users_parameters(), array('useids'=>$userids)); + $params = self::validate_parameters(self::delete_users_parameters(), array('userids'=>$userids)); $transaction = $DB->start_delegated_transaction(); -// TODO: this is problematic because the DB rollback does not handle rollbacking of deleted user images! + // TODO: this is problematic because the DB rollback does not handle rollbacking of deleted user images! foreach ($params['userids'] as $userid) { $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0), '*', MUST_EXIST); - delete_user($user); + user_delete_user($user); } $transaction->allow_commit(); @@ -231,11 +216,52 @@ class moodle_user_external extends external_api { * @return external_function_parameters */ public static function update_users_parameters() { - //TODO + global $CFG; + return new external_function_parameters( + array( + 'users' => new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_NUMBER, 'ID of the user'), + 'username' => new external_value(PARAM_RAW, 'Username policy is defined in Moodle security config', VALUE_OPTIONAL, '',NULL_NOT_ALLOWED), + 'password' => new external_value(PARAM_RAW, 'Plain text password consisting of any characters', VALUE_OPTIONAL, '',NULL_NOT_ALLOWED), + 'firstname' => new external_value(PARAM_NOTAGS, 'The first name(s) of the user', VALUE_OPTIONAL, '',NULL_NOT_ALLOWED), + 'lastname' => new external_value(PARAM_NOTAGS, 'The family name of the user', VALUE_OPTIONAL), + 'email' => new external_value(PARAM_EMAIL, 'A valid and unique email address', VALUE_OPTIONAL, '',NULL_NOT_ALLOWED), + 'auth' => new external_value(PARAM_SAFEDIR, 'Auth plugins include manual, ldap, imap, etc', VALUE_OPTIONAL, '', NULL_NOT_ALLOWED), + 'idnumber' => new external_value(PARAM_RAW, 'An arbitrary ID code number perhaps from the institution', VALUE_OPTIONAL), + 'emailstop' => new external_value(PARAM_NUMBER, 'Email is blocked: 1 is blocked and 0 otherwise', VALUE_OPTIONAL), + 'lang' => new external_value(PARAM_SAFEDIR, 'Language code such as "en_utf8", must exist on server', VALUE_OPTIONAL, '', NULL_NOT_ALLOWED), + 'theme' => new external_value(PARAM_SAFEDIR, 'Theme name such as "standard", must exist on server', VALUE_OPTIONAL), + 'timezone' => new external_value(PARAM_ALPHANUMEXT, 'Timezone code such as Australia/Perth, or 99 for default', VALUE_OPTIONAL), + 'mailformat' => new external_value(PARAM_INTEGER, 'Mail format code is 0 for plain text, 1 for HTML etc', VALUE_OPTIONAL), + 'description' => new external_value(PARAM_TEXT, 'User profile description, as HTML', VALUE_OPTIONAL), + 'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', VALUE_OPTIONAL), + 'country' => new external_value(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL), + 'preferences' => new external_multiple_structure( + new external_single_structure( + array( + 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the preference'), + 'value' => new external_value(PARAM_RAW, 'The value of the preference') + ) + ), 'User preferences', VALUE_OPTIONAL), + 'customfields' => new external_multiple_structure( + new external_single_structure( + array( + 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the custom field'), + 'value' => new external_value(PARAM_RAW, 'The value of the custom field') + ) + ), 'User custom fields', VALUE_OPTIONAL) + ) + ) + ) + ) + ); } public static function update_users($users) { global $CFG, $DB; + require_once($CFG->dirroot."/user/lib.php"); // Ensure the current user is allowed to run this function $context = get_context_instance(CONTEXT_SYSTEM); @@ -247,7 +273,7 @@ class moodle_user_external extends external_api { $transaction = $DB->start_delegated_transaction(); foreach ($params['users'] as $user) { - //TODO + user_update_user($user); } $transaction->allow_commit(); @@ -267,11 +293,11 @@ class moodle_user_external extends external_api { * Returns description of method parameters * @return external_function_parameters */ - public static function get_users_parameters() { + public static function get_users_by_id_parameters() { return new external_function_parameters( array( 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user ID')), - ) + ) ); } @@ -282,22 +308,40 @@ class moodle_user_external extends external_api { * @param array $userids array of user ids * @return array An array of arrays describing users */ - public static function get_users($userids) { + public static function get_users_by_id($userids) { + global $CFG; + require_once($CFG->dirroot."/user/lib.php"); + require_once($CFG->dirroot."/user/profile/lib.php"); //required for customfields related function + //TODO: move the functions somewhere else as + //they are "user" related + $context = get_context_instance(CONTEXT_SYSTEM); require_capability('moodle/user:viewdetails', $context); self::validate_context($context); - $params = self::validate_parameters(self::get_users_parameters(), array('userids'=>$userids)); + $params = self::validate_parameters(self::get_users_by_id_parameters(), array('userids'=>$userids)); - //TODO: this search is probably useless for external systems because it is not exact - // 1/ we should specify multiple search parameters including the mnet host id + //TODO: check if there is any performance issue: we do one DB request to retrieve all user, + // then for each user the profile_load_data does at least two DB requests - $result = array(); -/* - $users = get_users(true, $params['search'], false, null, 'firstname ASC','', '', '', 1000, 'id, mnethostid, auth, confirmed, username, idnumber, firstname, lastname, email, emailstop, lang, theme, timezone, mailformat, city, description, country'); + $users = user_get_users_by_id($params['userids']); + $result =array(); foreach ($users as $user) { - $result[] = (array)$user; - }*/ + if (empty($user->deleted)) { + + $userarray = (array) $user; //we want to return an array not an object + /// now we transfert all profile_field_xxx into the customfields external_multiple_structure required by description + $userarray['customfields'] = null; + $customfields = profile_user_record($user->id); + $customfields = (array) $customfields; + foreach ($customfields as $key => $value) { + $userarray['customfields'][] = array('type' => $key, 'value' => $value); + } + + $result[] = $userarray; + } + + } return $result; } @@ -306,10 +350,11 @@ class moodle_user_external extends external_api { * Returns description of method result value * @return external_description */ - public static function get_users_returns() { + public static function get_users_by_id_returns() { return new external_multiple_structure( new external_single_structure( array( + 'id' => new external_value(PARAM_NUMBER, 'ID of the user'), 'username' => new external_value(PARAM_RAW, 'Username policy is defined in Moodle security config'), 'firstname' => new external_value(PARAM_NOTAGS, 'The first name(s) of the user'), 'lastname' => new external_value(PARAM_NOTAGS, 'The family name of the user'), diff --git a/user/lib.php b/user/lib.php new file mode 100644 index 00000000000..1f5b1b9033a --- /dev/null +++ b/user/lib.php @@ -0,0 +1,130 @@ +. + +/** + * External user API + * + * @package moodlecore + * @subpackage user + * @copyright 2009 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +/** + * Creates a user + * @param object $user user to create + * @return int id of the newly created user + */ +function user_create_user($user) { + global $DB; + +/// set the timecreate field to the current time + if (!is_object($user)) { + $user = (object)$user; + } + $user->timecreated = time(); + +/// insert the user into the database + $newuserid = $DB->insert_record('user', $user); + + return $newuserid; + +} + +/** + * Update a user with a user object (will compare against the ID) + * @param object $user - the user to update + */ +function user_update_user($user) { + global $DB; + $user->timemodified = time(); + $DB->update_record('user', $user); +} + + +/** + * Marks user deleted in internal user database and notifies the auth plugin. + * Also unenrols user from all roles and does other cleanup. + * + * @todo Decide if this transaction is really needed (look for internal TODO:) + * @param object $user Userobject before delete (without system magic quotes) + * @return boolean success + */ +function user_delete_user($user) { + global $CFG, $DB; + require_once($CFG->libdir.'/grouplib.php'); + require_once($CFG->libdir.'/gradelib.php'); + require_once($CFG->dirroot.'/message/lib.php'); + + // 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'); + } + } + + //move unread messages from this user to read + message_move_userfrom_unread2read($user->id); + + // 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 = md5($user->username);// Store hash of username, useful importing/restoring users + $updateuser->idnumber = ''; // Clear this field to free it up + $updateuser->timemodified = time(); + + $DB->update_record('user', $updateuser); + + // 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; +} + +/** + * Get users by id + * @param array $userids id of users to retrieve + * + */ +function user_get_users_by_id($userids) { + global $DB; + return $DB->get_records_list('user', 'id', $userids); +} diff --git a/user/profile/lib.php b/user/profile/lib.php index e9d969ef24b..e04afc26caf 100644 --- a/user/profile/lib.php +++ b/user/profile/lib.php @@ -471,18 +471,18 @@ function profile_signup_fields(&$mform) { function profile_user_record($userid) { global $CFG, $DB; - $user = new object(); + $usercustomfields = new object(); if ($fields = $DB->get_records('user_info_field')) { foreach ($fields as $field) { require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); $newfield = 'profile_field_'.$field->datatype; $formfield = new $newfield($field->id, $userid); - if ($formfield->is_user_object_data()) $user->{$field->shortname} = $formfield->data; + if ($formfield->is_user_object_data()) $usercustomfields->{$field->shortname} = $formfield->data; } } - return $user; + return $usercustomfields; } diff --git a/version.php b/version.php index ef26599b98e..13ce10e4957 100644 --- a/version.php +++ b/version.php @@ -6,7 +6,7 @@ // This is compared against the values stored in the database to determine // whether upgrades should be performed (see lib/db/*.php) - $version = 2010020700; // YYYYMMDD = date of the last version bump + $version = 2010020701; // YYYYMMDD = date of the last version bump // XX = daily increments $release = '2.0 dev (Build: 20100211)'; // Human-friendly version name