Exemple #1
0
/**
 * Marks user deleted in internal user database and notifies the auth plugin.
 * Also unenrols user from all roles and does other cleanup.
 *
 * Any plugin that needs to purge user data should register the 'user_deleted' event.
 *
 * @param object $user User object before delete
 * @return boolean always true
 */
function 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';
    require_once $CFG->dirroot . '/tag/lib.php';
    // delete all grades - backup is kept in grade_grades_history table
    grade_user_delete($user->id);
    //move unread messages from this user to read
    message_move_userfrom_unread2read($user->id);
    // TODO: remove from cohorts using standard API here
    // remove user tags
    tag_set('user', $user->id, array());
    // unconditionally unenrol from all courses
    enrol_user_delete($user);
    // unenrol from all roles in all contexts
    role_unassign_all(array('userid' => $user->id));
    // this might be slow but it is really needed - modules might do some extra cleanup!
    //now do a brute force cleanup
    // remove from all cohorts
    $DB->delete_records('cohort_members', array('userid' => $user->id));
    // remove from all groups
    $DB->delete_records('groups_members', array('userid' => $user->id));
    // brute force unenrol from all courses
    $DB->delete_records('user_enrolments', array('userid' => $user->id));
    // purge user preferences
    $DB->delete_records('user_preferences', array('userid' => $user->id));
    // purge user extra profile info
    $DB->delete_records('user_info_data', array('userid' => $user->id));
    // last course access not necessary either
    $DB->delete_records('user_lastaccess', array('userid' => $user->id));
    // now do a final accesslib cleanup - removes all role assignments in user context and context itself
    delete_context(CONTEXT_USER, $user->id);
    // 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 stdClass();
    $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);
    // any plugin that needs to cleanup should register this event
    events_trigger('user_deleted', $user);
    return true;
}
Exemple #2
0
/**
 * Marks user deleted in internal user database and notifies the auth plugin.
 * Also unenrols user from all roles and does other cleanup.
 *
 * Any plugin that needs to purge user data should register the 'user_deleted' event.
 *
 * @param stdClass $user full user object before delete
 * @return boolean success
 * @throws coding_exception if invalid $user parameter detected
 */
function delete_user(stdClass $user)
{
    global $CFG, $DB;
    require_once $CFG->libdir . '/grouplib.php';
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->dirroot . '/message/lib.php';
    require_once $CFG->dirroot . '/user/lib.php';
    // Make sure nobody sends bogus record type as parameter.
    if (!property_exists($user, 'id') or !property_exists($user, 'username')) {
        throw new coding_exception('Invalid $user parameter in delete_user() detected');
    }
    // Better not trust the parameter and fetch the latest info this will be very expensive anyway.
    if (!($user = $DB->get_record('user', array('id' => $user->id)))) {
        debugging('Attempt to delete unknown user account.');
        return false;
    }
    // There must be always exactly one guest record, originally the guest account was identified by username only,
    // now we use $CFG->siteguest for performance reasons.
    if ($user->username === 'guest' or isguestuser($user)) {
        debugging('Guest user account can not be deleted.');
        return false;
    }
    // Admin can be theoretically from different auth plugin, but we want to prevent deletion of internal accoutns only,
    // if anything goes wrong ppl may force somebody to be admin via config.php setting $CFG->siteadmins.
    if ($user->auth === 'manual' and is_siteadmin($user)) {
        debugging('Local administrator accounts can not be deleted.');
        return false;
    }
    // Allow plugins to use this user object before we completely delete it.
    if ($pluginsfunction = get_plugins_with_function('pre_user_delete')) {
        foreach ($pluginsfunction as $plugintype => $plugins) {
            foreach ($plugins as $pluginfunction) {
                $pluginfunction($user);
            }
        }
    }
    // Keep user record before updating it, as we have to pass this to user_deleted event.
    $olduser = clone $user;
    // Keep a copy of user context, we need it for event.
    $usercontext = context_user::instance($user->id);
    // Delete all grades - backup is kept in grade_grades_history table.
    grade_user_delete($user->id);
    // Move unread messages from this user to read.
    message_move_userfrom_unread2read($user->id);
    // TODO: remove from cohorts using standard API here.
    // Remove user tags.
    core_tag_tag::remove_all_item_tags('core', 'user', $user->id);
    // Unconditionally unenrol from all courses.
    enrol_user_delete($user);
    // Unenrol from all roles in all contexts.
    // This might be slow but it is really needed - modules might do some extra cleanup!
    role_unassign_all(array('userid' => $user->id));
    // Now do a brute force cleanup.
    // Remove from all cohorts.
    $DB->delete_records('cohort_members', array('userid' => $user->id));
    // Remove from all groups.
    $DB->delete_records('groups_members', array('userid' => $user->id));
    // Brute force unenrol from all courses.
    $DB->delete_records('user_enrolments', array('userid' => $user->id));
    // Purge user preferences.
    $DB->delete_records('user_preferences', array('userid' => $user->id));
    // Purge user extra profile info.
    $DB->delete_records('user_info_data', array('userid' => $user->id));
    // Purge log of previous password hashes.
    $DB->delete_records('user_password_history', array('userid' => $user->id));
    // Last course access not necessary either.
    $DB->delete_records('user_lastaccess', array('userid' => $user->id));
    // Remove all user tokens.
    $DB->delete_records('external_tokens', array('userid' => $user->id));
    // Unauthorise the user for all services.
    $DB->delete_records('external_services_users', array('userid' => $user->id));
    // Remove users private keys.
    $DB->delete_records('user_private_key', array('userid' => $user->id));
    // Remove users customised pages.
    $DB->delete_records('my_pages', array('userid' => $user->id, 'private' => 1));
    // Force logout - may fail if file based sessions used, sorry.
    \core\session\manager::kill_user_sessions($user->id);
    // Generate username from email address, or a fake email.
    $delemail = !empty($user->email) ? $user->email : $user->username . '.' . $user->id . '@unknownemail.invalid';
    $delname = clean_param($delemail . "." . time(), PARAM_USERNAME);
    // Workaround for bulk deletes of users with the same email address.
    while ($DB->record_exists('user', array('username' => $delname))) {
        // No need to use mnethostid here.
        $delname++;
    }
    // Mark internal user record as "deleted".
    $updateuser = new stdClass();
    $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->picture = 0;
    $updateuser->timemodified = time();
    // Don't trigger update event, as user is being deleted.
    user_update_user($updateuser, false, false);
    // Now do a final accesslib cleanup - removes all role assignments in user context and context itself.
    context_helper::delete_instance(CONTEXT_USER, $user->id);
    // Any plugin that needs to cleanup should register this event.
    // Trigger event.
    $event = \core\event\user_deleted::create(array('objectid' => $user->id, 'relateduserid' => $user->id, 'context' => $usercontext, 'other' => array('username' => $user->username, 'email' => $user->email, 'idnumber' => $user->idnumber, 'picture' => $user->picture, 'mnethostid' => $user->mnethostid)));
    $event->add_record_snapshot('user', $olduser);
    $event->trigger();
    // We will update the user's timemodified, as it will be passed to the user_deleted event, which
    // should know about this updated property persisted to the user's table.
    $user->timemodified = $updateuser->timemodified;
    // Notify auth plugin - do not block the delete even when plugin fails.
    $authplugin = get_auth_plugin($user->auth);
    $authplugin->user_delete($user);
    return true;
}
/**
 * Marks user deleted in internal user database and notifies the auth plugin.
 * Also unenrols user from all roles and does other cleanup.
 *
 * Any plugin that needs to purge user data should register the 'user_deleted' event.
 *
 * @param stdClass $user full user object before delete
 * @return boolean success
 * @throws coding_exception if invalid $user parameter detected
 */
function delete_user(stdClass $user)
{
    global $CFG, $DB;
    require_once $CFG->libdir . '/grouplib.php';
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->dirroot . '/message/lib.php';
    require_once $CFG->dirroot . '/tag/lib.php';
    // Make sure nobody sends bogus record type as parameter.
    if (!property_exists($user, 'id') or !property_exists($user, 'username')) {
        throw new coding_exception('Invalid $user parameter in delete_user() detected');
    }
    // Better not trust the parameter and fetch the latest info,
    // this will be very expensive anyway.
    if (!($user = $DB->get_record('user', array('id' => $user->id)))) {
        debugging('Attempt to delete unknown user account.');
        return false;
    }
    // There must be always exactly one guest record,
    // originally the guest account was identified by username only,
    // now we use $CFG->siteguest for performance reasons.
    if ($user->username === 'guest' or isguestuser($user)) {
        debugging('Guest user account can not be deleted.');
        return false;
    }
    // Admin can be theoretically from different auth plugin,
    // but we want to prevent deletion of internal accoutns only,
    // if anything goes wrong ppl may force somebody to be admin via
    // config.php setting $CFG->siteadmins.
    if ($user->auth === 'manual' and is_siteadmin($user)) {
        debugging('Local administrator accounts can not be deleted.');
        return false;
    }
    // delete all grades - backup is kept in grade_grades_history table
    grade_user_delete($user->id);
    //move unread messages from this user to read
    message_move_userfrom_unread2read($user->id);
    // TODO: remove from cohorts using standard API here
    // remove user tags
    tag_set('user', $user->id, array());
    // unconditionally unenrol from all courses
    enrol_user_delete($user);
    // unenrol from all roles in all contexts
    role_unassign_all(array('userid' => $user->id));
    // this might be slow but it is really needed - modules might do some extra cleanup!
    //now do a brute force cleanup
    // remove from all cohorts
    $DB->delete_records('cohort_members', array('userid' => $user->id));
    // remove from all groups
    $DB->delete_records('groups_members', array('userid' => $user->id));
    // brute force unenrol from all courses
    $DB->delete_records('user_enrolments', array('userid' => $user->id));
    // purge user preferences
    $DB->delete_records('user_preferences', array('userid' => $user->id));
    // purge user extra profile info
    $DB->delete_records('user_info_data', array('userid' => $user->id));
    // last course access not necessary either
    $DB->delete_records('user_lastaccess', array('userid' => $user->id));
    // remove all user tokens
    $DB->delete_records('external_tokens', array('userid' => $user->id));
    // unauthorise the user for all services
    $DB->delete_records('external_services_users', array('userid' => $user->id));
    // Remove users private keys.
    $DB->delete_records('user_private_key', array('userid' => $user->id));
    // Remove users customised pages.
    $DB->delete_records('my_pages', array('userid' => $user->id, 'private' => 1));
    // force logout - may fail if file based sessions used, sorry
    session_kill_user($user->id);
    // now do a final accesslib cleanup - removes all role assignments in user context and context itself
    delete_context(CONTEXT_USER, $user->id);
    // 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 stdClass();
    $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->picture = 0;
    $updateuser->timemodified = time();
    $DB->update_record('user', $updateuser);
    // Add this action to log
    add_to_log(SITEID, 'user', 'delete', "view.php?id={$user->id}", $user->firstname . ' ' . $user->lastname);
    // We will update the user's timemodified, as it will be passed to the user_deleted event, which
    // should know about this updated property persisted to the user's table.
    $user->timemodified = $updateuser->timemodified;
    // notify auth plugin - do not block the delete even when plugin fails
    $authplugin = get_auth_plugin($user->auth);
    $authplugin->user_delete($user);
    // any plugin that needs to cleanup should register this event
    events_trigger('user_deleted', $user);
    return true;
}