Delete multiple users within a single context.

@param   approved_userlist   $userlist   The approved context and user information to delete information for.
493787
public static function delete_data_for_users(approved_userlist $userlist) {
        global $DB;

        // Questions are considered to be 'owned' by the institution, even if they were originally written by a specific
        // user. They are still exported in the list of a users data, but they are not removed.
        // The userid is instead anonymised.

        $context = $userlist->get_context();
        $userids = $userlist->get_userids();

        list($createdbysql, $createdbyparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
        list($modifiedbysql, $modifiedbyparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);

        $params = ['contextid' => $context->id];

        $DB->set_field_select('question', 'createdby', 0, "
                category IN (SELECT id FROM {question_categories} WHERE contextid = :contextid)
            AND createdby {$createdbysql}", $params + $createdbyparams);

        $DB->set_field_select('question', 'modifiedby', 0, "
                category IN (SELECT id FROM {question_categories} WHERE contextid = :contextid)
            AND modifiedby {$modifiedbysql}", $params + $modifiedbyparams);
    }
977285
public static function delete_data_for_users(approved_userlist $userlist) {
        $context = $userlist->get_context();

        if ($context instanceof \context_system || $context instanceof \context_coursecat) {
            foreach ($userlist->get_userids() as $userid) {
                static::delete_data($context, $userid);
            }
        }
    }
1044130
public static function delete_data_for_user(approved_contextlist $contextlist) {
        global $DB;
        $context = \context_system::instance();
        if (!$contextlist->count() || !in_array($context->id, $contextlist->get_contextids())) {
            return;
        }

        // Do not delete tags themselves in case they are used by somebody else.
        // If the user is the only one using the tag, it will be automatically deleted anyway during the next cron cleanup.
        $DB->set_field_select('tag', 'userid', 0, 'userid = ?', [$contextlist->get_user()->id]);
    }
747870
public static function delete_data_for_users(\core_privacy\local\request\approved_userlist $userlist) {
        global $DB;
        $context = $userlist->get_context();
        if ($context->contextlevel != CONTEXT_BLOCK) {
            return;
        }

        list($insql, $params) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED);
        $params['hidden'] = 'block' . $context->instanceid . 'hidden';
        $params['docked'] = 'docked_block_instance_' . $context->instanceid;

        $DB->delete_records_select('user_preferences', "(name = :hidden OR name = :docked) AND userid $insql", $params);
    }
215794
public static function delete_data_for_user(approved_contextlist $contextlist) {
        global $DB;
        $userid = $contextlist->get_user()->id;

        $courseids = [];
        foreach ($contextlist->get_contexts() as $context) {
            if ($context->contextlevel == CONTEXT_USER && $userid == $context->instanceid) {
                // User attempts to delete data in their own context.
                static::delete_orphan_historical_grades($userid);

            } else if ($context->contextlevel == CONTEXT_COURSE) {
                // Log the list of course IDs.
                $courseids[] = $context->instanceid;
            }
        }

        $itemids = static::get_item_ids_from_course_ids($courseids);
        if (empty($itemids)) {
            // Our job here is done!
            return;
        }

        // Delete all the files.
        self::delete_files($itemids, true, [$userid]);
        self::delete_files($itemids, false, [$userid]);

        // Delete all the grades.
        list($insql, $inparams) = $DB->get_in_or_equal($itemids, SQL_PARAMS_NAMED);
        $params = array_merge($inparams, ['userid' => $userid]);

        $DB->delete_records_select('grade_grades', "itemid $insql AND userid = :userid", $params);
        $DB->delete_records_select('grade_grades_history', "itemid $insql AND userid = :userid", $params);
    }
161789
public static function delete_data_for_users(approved_userlist $userlist) {
        global $DB;

        $context = $userlist->get_context();

        if ($context instanceof \context_system) {
            // Do not delete tags themselves in case they are used by somebody else.
            // If the user is the only one using the tag, it will be automatically deleted anyway during the
            // next cron cleanup.
            list($usersql, $userparams) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED);
            $DB->set_field_select('tag', 'userid', 0, "userid {$usersql}", $userparams);
        }
    }
14335
public static function get_users_in_context(userlist $userlist) {
        $context = $userlist->get_context();

        if (!$context instanceof \context_user) {
            return;
        }

        $userlist->add_user($context->instanceid);
    }
344147
public static function delete_data_for_user(approved_contextlist $contextlist) {
        global $DB;
        list($sql, $params) = static::get_sql_where_from_contexts($contextlist->get_contexts());
        if (empty($sql)) {
            return;
        }
        $userid = $contextlist->get_user()->id;
        $DB->delete_records_select('log', "$sql AND userid = :userid", array_merge($params, ['userid' => $userid]));
    }
827278
public static function delete_data_for_users(approved_userlist $userlist) {
        global $DB;

        $context = $userlist->get_context();
        if ($context->contextlevel != CONTEXT_MODULE) {
            return;
        }

        $userids = $userlist->get_userids();

        $assign = new \assign($context, null, null);
        $assignid = $assign->get_instance()->id;
        $requestdata = new assign_plugin_request_data($context, $assign);
        $requestdata->set_userids($userids);
        $requestdata->populate_submissions_and_grades();
        manager::plugintype_class_callback('assignsubmission', self::ASSIGNSUBMISSION_USER_INTERFACE, 'delete_submissions',
                [$requestdata]);
        manager::plugintype_class_callback('assignfeedback', self::ASSIGNFEEDBACK_USER_INTERFACE, 'delete_feedback_for_grades',
                [$requestdata]);

        // Update this function to delete advanced grading information.
        $gradingmanager = get_grading_manager($context, 'mod_assign', 'submissions');
        $controller = $gradingmanager->get_active_controller();
        if (isset($controller)) {
            $gradeids = $requestdata->get_gradeids();
            // Careful here, if no gradeids are provided then all data is deleted for the context.
            if (!empty($gradeids)) {
                \core_grading\privacy\provider::delete_data_for_instances($context, $gradeids);
            }
        }

        static::delete_overrides_for_users($assign, $userids);
        list($sql, $params) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
        $params['assignment'] = $assignid;
        $DB->delete_records_select('assign_user_flags', "assignment = :assignment AND userid $sql", $params);
        $DB->delete_records_select('assign_user_mapping', "assignment = :assignment AND userid $sql", $params);
        $DB->delete_records_select('assign_grades', "assignment = :assignment AND userid $sql", $params);
        $DB->delete_records_select('assign_submission', "assignment = :assignment AND userid $sql", $params);
    }
517914
public static function delete_data_for_users(approved_userlist $userlist) {
        global $DB;

        $context = $userlist->get_context();
        $models = self::get_models_with_user_data();
        $modelids = array_keys($models);
        list($usersinsql, $baseparams) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED);

        // Analytics prediction actions.
        list($sql, $apaparams) = self::analytics_prediction_actions_context_sql($context->id, $modelids, $usersinsql);
        $sql = "SELECT apa.id" . $sql;
        $predictionactionids = $DB->get_fieldset_sql($sql, $baseparams + $apaparams);

        if ($predictionactionids) {
            list ($predictionactionidssql, $params) = $DB->get_in_or_equal($predictionactionids);
            $DB->delete_records_select('analytics_prediction_actions', "id {$predictionactionidssql}", $params);
        }

        $baseparams['contextid'] = $context->id;

        foreach ($models as $modelid => $model) {
            $analyser = $model->get_analyser(['notimesplitting' => true]);

            // Analytics predictions.
            $joinusersql = $analyser->join_sample_user('ap');
            $sql = "SELECT DISTINCT ap.id
                      FROM {analytics_predictions} ap
                           {$joinusersql}
                     WHERE ap.contextid = :contextid
                       AND ap.modelid = :modelid
                       AND u.id {$usersinsql}";
            $params = $baseparams;
            $params['modelid'] = $modelid;
            $predictionids = $DB->get_fieldset_sql($sql, $params);

            if ($predictionids) {
                list($predictionidssql, $params) = $DB->get_in_or_equal($predictionids, SQL_PARAMS_NAMED);
                $DB->delete_records_select('analytics_predictions', "id {$predictionidssql}", $params);
            }

            // Indicator calculations.
            $joinusersql = $analyser->join_sample_user('aic');
            $sql = "SELECT DISTINCT aic.id
                      FROM {analytics_indicator_calc} aic
                           {$joinusersql}
                     WHERE aic.contextid = :contextid
                       AND aic.sampleorigin = :analysersamplesorigin
                       AND u.id {$usersinsql}";
            $params = $baseparams;
            $params['analysersamplesorigin'] = $analyser->get_samples_origin();
            $indicatorcalcids = $DB->get_fieldset_sql($sql, $params);

            if ($indicatorcalcids) {
                list ($indicatorcalcidssql, $params) = $DB->get_in_or_equal($indicatorcalcids, SQL_PARAMS_NAMED);
                $DB->delete_records_select('analytics_indicator_calc', "id $indicatorcalcidssql", $params);
            }
        }
    }
892643
public static function delete_data_for_user(approved_contextlist $contextlist) {
        global $DB;
        if (!static::approved_contextlist_contains_my_context($contextlist)) {
            // We only care about the user's user context.
            return;
        }

        static::delete_user_data($contextlist->get_user()->id);
    }
640107
public static function delete_data_for_user(approved_contextlist $contextlist) {
        if ($contextlist->get_component() != 'report_stats') {
            return;
        }
        foreach ($contextlist->get_contexts() as $context) {
            if ($context->contextlevel == CONTEXT_COURSE) {
                static::delete_stats($context->instanceid, $contextlist->get_user()->id);
            }
        }
    }
1202309
public static function delete_data_for_user(approved_contextlist $contextlist) {
        if (empty($contextlist->count())) {
            return;
        }
        \core_group\privacy\provider::delete_groups_for_user($contextlist, 'enrol_meta');
    }
1231340
public static function delete_data_for_user(approved_contextlist $contextlist) {
        global $DB;

        // When we process user deletions and expiries, we always delete from the user context.
        // As a result the cohort role assignments would be deleted, which has a knock-on effect with courses
        // as roles may change and data may be removed earlier than it should be.

        // Remove contexts different from SYSTEM or COURSECAT.
        $contextids = array_reduce($contextlist->get_contexts(), function($carry, $context) {
            if ($context->contextlevel == CONTEXT_SYSTEM || $context->contextlevel == CONTEXT_COURSECAT) {
                $carry[] = $context->id;
            }
            return $carry;
        }, []);

        if (empty($contextids)) {
            return;
        }

        $userid = $contextlist->get_user()->id;

        list($contextsql, $contextparams) =  $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED);
        $selectcontext = "contextid {$contextsql}";
        // Get the cohorts in the specified contexts.
        $cohortids = $DB->get_fieldset_select('cohort', 'id', $selectcontext, $contextparams);

        if (empty($cohortids)) {
            return;
        }

        list($cohortsql, $cohortparams) =  $DB->get_in_or_equal($cohortids, SQL_PARAMS_NAMED);
        $selectcohort = "cohortid {$cohortsql} AND userid = :userid";
        $params = ['userid' => $userid] + $cohortparams;

        // Delete the tool_cohortroles records created for the userid.
        $DB->delete_records_select('tool_cohortroles', $selectcohort, $params);
    }
1299852
public static function delete_data_for_user(approved_contextlist $contextlist) {
        global $DB;

        if (empty($contextlist->count())) {
            return;
        }

        $user = $contextlist->get_user();
        $recordstobedeleted = [];

        foreach ($contextlist->get_contexts() as $context) {
            $sql = "SELECT " . self::sql_fields() . "
                FROM {context} ctx
                JOIN {course_modules} cm ON cm.id = ctx.instanceid
                JOIN {modules} m ON m.id = cm.module AND m.name = :modname
                JOIN {data} d ON d.id = cm.instance
                JOIN {data_records} dr ON dr.dataid = d.id AND dr.userid = :userid
                LEFT JOIN {data_content} dc ON dc.recordid = dr.id
                LEFT JOIN {data_fields} df ON df.id = dc.fieldid
                WHERE ctx.id = :ctxid AND ctx.contextlevel = :contextlevel
                ORDER BY dr.id";
            $rs = $DB->get_recordset_sql($sql, ['ctxid' => $context->id, 'contextlevel' => CONTEXT_MODULE,
                'modname' => 'data', 'userid' => $user->id]);
            foreach ($rs as $row) {
                self::mark_data_content_for_deletion($context, $row);
                $recordstobedeleted[$row->recordid] = $row->recordid;
            }
            $rs->close();
            self::delete_data_records($context, $recordstobedeleted);
        }

        // Additionally remove comments this user made on other entries.
        \core_comment\privacy\provider::delete_comments_for_user($contextlist, 'mod_data', 'database_entry');

        // We do not delete ratings made by this user on other records because it may change grades.
    }
966289
public static function delete_data_for_users(approved_userlist $userlist) {
        $context = $userlist->get_context();
        $userids = $userlist->get_userids();

        // Since this falls within a user context, only that user should be valid.
        if ($context->contextlevel != CONTEXT_USER || count($userids) != 1 || $context->instanceid != $userids[0]) {
            return;
        }

        static::delete_user_data($userids[0]);
    }
838152
public static function delete_data_for_users(approved_userlist $userlist) {
        global $DB;

        $context = $userlist->get_context();
        $cm = $DB->get_record('course_modules', ['id' => $context->instanceid]);
        $chat = $DB->get_record('chat', ['id' => $cm->instance]);

        list($userinsql, $userinparams) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED);
        $params = array_merge(['chatid' => $chat->id], $userinparams);
        $sql = "chatid = :chatid AND userid {$userinsql}";

        $DB->delete_records_select('chat_messages', $sql, $params);
        $DB->delete_records_select('chat_messages_current', $sql, $params);
        $DB->delete_records_select('chat_users', $sql, $params);
    }