Delete multiple users within a single context.

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

        // Sanity check that context is at the User context level, then get the userid.
        if ($context->contextlevel !== CONTEXT_USER) {
            return;
        }

        $userids = $userlist->get_userids();
        list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
        $params = [
            'contextid' => $context->id,
            'contextuser' => CONTEXT_USER,
        ];
        $params = array_merge($params, $inparams);

        // Fetch the repository_onedrive_access IDs in the context for approved users.
        $sql = "SELECT roa.id
                  FROM {repository_onedrive_access} roa
                  JOIN {context} c ON c.instanceid = roa.usermodified
                   AND c.contextlevel = :contextuser
                   AND c.id = :contextid
                 WHERE roa.usermodified {$insql}";
        $accessids = $DB->get_fieldset_sql($sql, $params);

        // Delete the relevant repository_onedrive_access data.
        list($insql, $params) = $DB->get_in_or_equal($accessids, SQL_PARAMS_NAMED);
        $DB->delete_records_select('repository_onedrive_access', "id {$insql}", $params);
    }
256281
public static function delete_data_for_users(\core_privacy\local\request\approved_userlist $userlist) {
        global $DB;

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

        if ($context->contextlevel == CONTEXT_USER) {
            // If one of the listed users matches this context then delete the blog, associations, and comments.
            if (array_search($context->instanceid, $userids) !== false) {
                self::delete_all_user_data($context);
                \core_comment\privacy\provider::delete_comments_for_all_users($context, 'blog', 'format_blog');
                return;
            }
            \core_comment\privacy\provider::delete_comments_for_users($userlist, 'blog', 'format_blog');
        } else {
            list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
            $sql = "SELECT ba.id
                      FROM {blog_association} ba
                      JOIN {post} p ON p.id = ba.blogid
                     WHERE ba.contextid = :contextid
                       AND p.userid $insql";
            $inparams['contextid'] = $context->id;
            $associds = $DB->get_fieldset_sql($sql, $inparams);

            if (!empty($associds)) {
                list($insql, $inparams) = $DB->get_in_or_equal($associds, SQL_PARAMS_NAMED, 'param', true);
                $DB->delete_records_select('blog_association', "id $insql", $inparams);
            }
        }
    }
335832
public static function delete_data_for_users(approved_userlist $userlist) {
        global $DB;
        $context = $userlist->get_context();

        if (!is_a($context, \context_module::class)) {
            return;
        }

        // Prepare SQL to gather all completed IDs.
        $userids = $userlist->get_userids();
        list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);

        $sql = "SELECT ss.id
                  FROM {%s} ss
                  JOIN {modules} m
                    ON m.name = 'scorm'
                  JOIN {course_modules} cm
                    ON cm.instance = ss.scormid
                   AND cm.module = m.id
                  JOIN {context} ctx
                    ON ctx.instanceid = cm.id
                 WHERE ctx.id = :contextid
                   AND ss.userid $insql";
        $params = array_merge($inparams, ['contextid' => $context->id]);

        static::delete_data('scorm_scoes_track', $sql, $params);
        static::delete_data('scorm_aicc_session', $sql, $params);
    }
328027
public static function delete_data_for_user(approved_contextlist $contextlist) {
        if (empty($contextlist)) {
            return;
        }

        // Delete all Calendar Events for the owner and specified contexts in batches.
        $eventdetails = self::get_calendar_event_details_by_contextlist($contextlist);
        $eventids = [];
        foreach ($eventdetails as $eventdetail) {
            $eventids[] = $eventdetail->eventid;
        }
        $eventdetails->close();
        self::delete_batch_records('event', 'id', $eventids);

        // Delete all Calendar Subscriptions for the owner and specified contexts in batches.
        $subscriptiondetails = self::get_calendar_subscription_details_by_contextlist($contextlist);
        $subscriptionids = [];
        foreach ($subscriptiondetails as $subscriptiondetail) {
            $subscriptionids[] = $subscriptiondetail->subscriptionid;
        }
        $subscriptiondetails->close();
        self::delete_batch_records('event_subscriptions', 'id', $subscriptionids);
    }
592771
public static function delete_data_for_user(approved_contextlist $contextlist) {
        global $DB;

        if ($contextlist->get_component() != 'core_portfolio') {
            return;
        }

        $correctusercontext = array_filter($contextlist->get_contexts(), function($context) use ($contextlist) {
            if ($context->contextlevel == CONTEXT_USER && $context->instanceid == $contextlist->get_user()->id) {
                return $context;
            }
        });

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

        $usercontext = array_shift($correctusercontext);

        $DB->delete_records('portfolio_instance_user', ['userid' => $usercontext->instanceid]);
        $DB->delete_records('portfolio_tempdata', ['userid' => $usercontext->instanceid]);
        $DB->delete_records('portfolio_log', ['userid' => $usercontext->instanceid]);
    }
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);
            }
        }
    }
502555
public static function delete_data_for_user(approved_contextlist $contextlist) {
        $user = $contextlist->get_user();
        foreach ($contextlist->get_contexts() as $context) {
            // Check if the context is a user context.
            if ($context->contextlevel == CONTEXT_USER && $context->instanceid == $user->id) {
                static::delete_data($context->instanceid);
            }
        }
    }
345148
public static function delete_data_for_users(approved_userlist $userlist) {
        global $DB;

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

        // Prepare SQL to gather all completed IDs.
        list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
        $completedsql = "
            SELECT fc.id
              FROM {%s} fc
              JOIN {modules} m
                ON m.name = :feedback
              JOIN {course_modules} cm
                ON cm.instance = fc.feedback
               AND cm.module = m.id
             WHERE cm.id = :instanceid
               AND fc.userid $insql";
        $completedparams = array_merge($inparams, ['instanceid' => $context->instanceid, 'feedback' => 'feedback']);

        // Delete all submissions in progress.
        $completedtmpids = $DB->get_fieldset_sql(sprintf($completedsql, 'feedback_completedtmp'), $completedparams);
        if (!empty($completedtmpids)) {
            list($insql, $inparams) = $DB->get_in_or_equal($completedtmpids, SQL_PARAMS_NAMED);
            $DB->delete_records_select('feedback_valuetmp', "completed $insql", $inparams);
            $DB->delete_records_select('feedback_completedtmp', "id $insql", $inparams);
        }

        // Delete all final submissions.
        $completedids = $DB->get_fieldset_sql(sprintf($completedsql, 'feedback_completed'), $completedparams);
        if (!empty($completedids)) {
            list($insql, $inparams) = $DB->get_in_or_equal($completedids, SQL_PARAMS_NAMED);
            $DB->delete_records_select('feedback_value', "completed $insql", $inparams);
            $DB->delete_records_select('feedback_completed', "id $insql", $inparams);
        }
    }
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);
            }
        }
    }
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);
    }
1352657
public static function delete_data_for_users(approved_userlist $userlist) {
        $context = $userlist->get_context();

        if ($context instanceof \context_block && ($blockinstance = static::get_instance_from_context($context))) {
            blocks_delete_instance($blockinstance);
        }
    }
739170
public static function delete_data_for_user(approved_contextlist $contextlist) {
        global $DB;
        $userid = $contextlist->get_user()->id;
        $prefnames = array_reduce($contextlist->get_contexts(), function($carry, $context) {
            if ($context->contextlevel == CONTEXT_BLOCK) {
                $carry[] = "block{$context->instanceid}hidden";
                $carry[] = "docked_block_instance_{$context->instanceid}";
            }
            return $carry;
        }, []);

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

        list($insql, $inparams) = $DB->get_in_or_equal($prefnames, SQL_PARAMS_NAMED);
        $sql = "userid = :userid AND name $insql";
        $params = array_merge($inparams, ['userid' => $userid]);
        $DB->delete_records_select('user_preferences', $sql, $params);
    }
1016032
public static function delete_data_for_users(approved_userlist $userlist) {
        global $DB;

        $context = $userlist->get_context();
        // If the context isn't for a module then return early.
        if ($context->contextlevel != CONTEXT_MODULE) {
            return;
        }
        // Fetch the assignment.
        $assignment = self::get_assignment_by_context($context);
        $userids = $userlist->get_userids();

        list($inorequalsql, $params) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
        $params['assignmentid'] = $assignment->id;

        // Get submission ids.
        $sql = "
            SELECT s.id
            FROM {assignment_submissions} s
            JOIN {assignment} a ON s.assignment = a.id
            WHERE a.id = :assignmentid
            AND s.userid $inorequalsql
        ";

        $submissionids = $DB->get_records_sql($sql, $params);
        list($submissionidsql, $submissionparams) = $DB->get_in_or_equal(array_keys($submissionids), SQL_PARAMS_NAMED);
        $fs = get_file_storage();
        $fs->delete_area_files_select($context->id, 'mod_assignment', 'submission', $submissionidsql, $submissionparams);
        // Delete related tables.
        $DB->delete_records_list('assignment_submissions', 'id', array_keys($submissionids));
    }
1242533
public static function delete_data_for_userlist(\core_privacy\local\request\approved_userlist $userlist) {
        global $DB;
        list($sql, $params) = static::get_sql_where_from_contexts([$userlist->get_context()]);
        if (empty($sql)) {
            return;
        }
        list($usersql, $userparams) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED);
        $params = array_merge($params, $userparams);
        $DB->delete_records_select('log', "$sql AND userid $usersql", $params);
    }
1050433
public static function delete_data_for_users(approved_userlist $userlist) {
        global $DB;

        $context = $userlist->get_context();
        $lessonid = static::get_lesson_id_from_context($context);
        $userids = $userlist->get_userids();

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

        // Prepare the SQL we'll need below.
        list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
        $sql = "lessonid = :lessonid AND userid {$insql}";
        $params = array_merge($inparams, ['lessonid' => $lessonid]);

        // Delete the attempt files.
        $fs = get_file_storage();
        $recordset = $DB->get_recordset_select('lesson_attempts', $sql, $params, '', 'id, lessonid');
        foreach ($recordset as $record) {
            $fs->delete_area_files($context->id, 'mod_lesson', 'essay_responses', $record->id);
            $fs->delete_area_files($context->id, 'mod_lesson', 'essay_answers', $record->id);
        }
        $recordset->close();

        // Delete all the things.
        $DB->delete_records_select('lesson_attempts', $sql, $params);
        $DB->delete_records_select('lesson_branch', $sql, $params);
        $DB->delete_records_select('lesson_grades', $sql, $params);
        $DB->delete_records_select('lesson_timer', $sql, $params);
        $DB->delete_records_select('lesson_overrides', $sql, $params);
    }
1024737
public static function delete_data_for_user(approved_contextlist $contextlist) {
        global $DB;

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

        $userid = $contextlist->get_user()->id;
        foreach ($contextlist->get_contexts() as $context) {
            if ($context->contextlevel == CONTEXT_MODULE) {

                $instanceid = $DB->get_field('course_modules', 'instance', ['id' => $context->instanceid], MUST_EXIST);

                $entries = $DB->get_records('glossary_entries', ['glossaryid' => $instanceid, 'userid' => $userid],
                        '', 'id');

                if (!$entries) {
                    continue;
                }

                list($insql, $inparams) = $DB->get_in_or_equal(array_keys($entries), SQL_PARAMS_NAMED);
                // Delete related entry aliases.
                $DB->delete_records_list('glossary_alias', 'entryid', array_keys($entries));

                // Delete related entry categories.
                $DB->delete_records_list('glossary_entries_categories', 'entryid', array_keys($entries));

                // Delete related entry and attachment files.
                get_file_storage()->delete_area_files_select($context->id, 'mod_glossary', 'entry', $insql, $inparams);
                get_file_storage()->delete_area_files_select($context->id, 'mod_glossary', 'attachment', $insql, $inparams);

                // Delete user tags related to this glossary.
                \core_tag\privacy\provider::delete_item_tags_select($context, 'mod_glossary', 'glossary_entries', $insql, $inparams);

                // Delete related ratings.
                \core_rating\privacy\provider::delete_ratings_select($context, 'mod_glossary', 'entry', $insql, $inparams);

                // Delete comments.
                \core_comment\privacy\provider::delete_comments_for_user($contextlist, 'mod_glossary', 'glossary_entry');

                // Now delete all user related entries.
                $DB->delete_records('glossary_entries', ['glossaryid' => $instanceid, 'userid' => $userid]);
            }
        }
    }
431896
public static function delete_data_for_users(\core_privacy\local\request\approved_userlist $userlist) {
        global $DB;

        $context = $userlist->get_context();
        $userids = $userlist->get_userids();
        if ($context->contextlevel == CONTEXT_USER) {
            if (array_search($context->instanceid, $userids) !== false) {
                static::delete_orphan_historical_grades($context->instanceid);
            }
            return;
        }

        if ($context->contextlevel != CONTEXT_COURSE) {
            return;
        }

        $itemids = static::get_item_ids_from_course_ids([$context->instanceid]);
        if (empty($itemids)) {
            // Our job here is done!
            return;
        }

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

        // Delete all the grades.
        list($itemsql, $itemparams) = $DB->get_in_or_equal($itemids, SQL_PARAMS_NAMED);
        list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
        $params = array_merge($itemparams, $userparams);

        $DB->delete_records_select('grade_grades', "itemid $itemsql AND userid $usersql", $params);
        $DB->delete_records_select('grade_grades_history', "itemid $itemsql AND userid $usersql", $params);
    }