Skip to content
Permalink
Browse files

MDL-63495 mod_forum: Add intial support for removal of multiple conte…

…xt users

This issue is a part of the MDL-62560 Epic.
  • Loading branch information
andrewnicols committed Aug 31, 2018
1 parent e2ca422 commit 8c3124cef076144df4fd94c4daef976d6fb9b6f2
Showing with 667 additions and 1 deletion.
  1. +152 −1 mod/forum/classes/privacy/provider.php
  2. +515 −0 mod/forum/tests/privacy_provider_test.php
@@ -24,7 +24,9 @@
namespace mod_forum\privacy;
use \core_privacy\local\request\userlist;
use \core_privacy\local\request\approved_contextlist;
use \core_privacy\local\request\approved_userlist;
use \core_privacy\local\request\deletion_criteria;
use \core_privacy\local\request\writer;
use \core_privacy\local\request\helper as request_helper;
@@ -46,6 +48,9 @@ class provider implements
// This plugin currently implements the original plugin\provider interface.
\core_privacy\local\request\plugin\provider,
// This plugin is capable of determining which users have data within it.
\core_privacy\local\request\core_userlist_provider,
// This plugin has some sitewide user preferences to export.
\core_privacy\local\request\user_preference_provider
{
@@ -144,7 +149,7 @@ public static function get_metadata(collection $items) : collection {
* In the case of forum, that is any forum where the user has made any post, rated any content, or has any preferences.
*
* @param int $userid The user to search.
* @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
* @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
*/
public static function get_contexts_for_userid(int $userid) : \core_privacy\local\request\contextlist {
$ratingsql = \core_rating\privacy\provider::get_sql_join('rat', 'mod_forum', 'post', 'p.id', $userid);
@@ -192,6 +197,98 @@ public static function get_contexts_for_userid(int $userid) : \core_privacy\loca
return $contextlist;
}
/**
* Get the list of users within a specific context.
*
* @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
*/
public static function get_users_in_context(userlist $userlist) {
$context = $userlist->get_context();
if (!is_a($context, \context_module::class)) {
return;
}
$params = [
'instanceid' => $context->instanceid,
'modulename' => 'forum',
];
// Discussion authors.
$sql = "SELECT d.userid
FROM {course_modules} cm
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_discussions} d ON d.forum = f.id
WHERE cm.id = :instanceid";
$userlist->add_from_sql('userid', $sql, $params);
// Forum authors.
$sql = "SELECT p.userid
FROM {course_modules} cm
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_discussions} d ON d.forum = f.id
JOIN {forum_posts} p ON d.id = p.discussion
WHERE cm.id = :instanceid";
$userlist->add_from_sql('userid', $sql, $params);
// Forum post ratings.
$sql = "SELECT p.id
FROM {course_modules} cm
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_discussions} d ON d.forum = f.id
JOIN {forum_posts} p ON d.id = p.discussion
WHERE cm.id = :instanceid";
\core_rating\privacy\provider::get_users_in_context_from_sql($userlist, 'rat', 'mod_forum', 'post', $sql, $params);
// Forum Digest settings.
$sql = "SELECT dig.userid
FROM {course_modules} cm
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_digests} dig ON dig.forum = f.id
WHERE cm.id = :instanceid";
$userlist->add_from_sql('userid', $sql, $params);
// Forum Subscriptions.
$sql = "SELECT sub.userid
FROM {course_modules} cm
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_subscriptions} sub ON sub.forum = f.id
WHERE cm.id = :instanceid";
$userlist->add_from_sql('userid', $sql, $params);
// Discussion subscriptions.
$sql = "SELECT dsub.userid
FROM {course_modules} cm
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_discussion_subs} dsub ON dsub.forum = f.id
WHERE cm.id = :instanceid";
$userlist->add_from_sql('userid', $sql, $params);
// Read Posts.
$sql = "SELECT hasread.userid
FROM {course_modules} cm
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_read} hasread ON hasread.forumid = f.id
WHERE cm.id = :instanceid";
$userlist->add_from_sql('userid', $sql, $params);
// Tracking Preferences.
$sql = "SELECT pref.userid
FROM {course_modules} cm
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_track_prefs} pref ON pref.forumid = f.id
WHERE cm.id = :instanceid";
$userlist->add_from_sql('userid', $sql, $params);
}
/**
* Store all user preferences for the plugin.
*
@@ -890,4 +987,58 @@ public static function delete_data_for_user(approved_contextlist $contextlist) {
$uniquediscussions->close();
}
}
/**
* Delete multiple users within a single context.
*
* @param approved_userlist $userlist The approved context and user information to delete information for.
*/
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]);
$forum = $DB->get_record('forum', ['id' => $cm->instance]);
list($userinsql, $userinparams) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED);
$params = array_merge(['forumid' => $forum->id], $userinparams);
$DB->delete_records_select('forum_track_prefs', "forumid = :forumid AND userid {$userinsql}", $params);
$DB->delete_records_select('forum_subscriptions', "forum = :forumid AND userid {$userinsql}", $params);
$DB->delete_records_select('forum_read', "forumid = :forumid AND userid {$userinsql}", $params);
$DB->delete_records_select(
'forum_queue',
"userid {$userinsql} AND discussionid IN (SELECT id FROM {forum_discussions} WHERE forum = :forumid)",
$params
);
$DB->delete_records_select('forum_discussion_subs', "forum = :forumid AND userid {$userinsql}", $params);
// Do not delete discussion or forum posts.
// Instead update them to reflect that the content has been deleted.
$postsql = "userid {$userinsql} AND discussion IN (SELECT id FROM {forum_discussions} WHERE forum = :forumid)";
$postidsql = "SELECT fp.id FROM {forum_posts} fp WHERE {$postsql}";
// Update the subject.
$DB->set_field_select('forum_posts', 'subject', '', $postsql, $params);
// Update the subject and its format.
$DB->set_field_select('forum_posts', 'message', '', $postsql, $params);
$DB->set_field_select('forum_posts', 'messageformat', FORMAT_PLAIN, $postsql, $params);
// Mark the post as deleted.
$DB->set_field_select('forum_posts', 'deleted', 1, $postsql, $params);
// Note: Do _not_ delete ratings of other users. Only delete ratings on the users own posts.
// Ratings are aggregate fields and deleting the rating of this post will have an effect on the rating
// of any post.
\core_rating\privacy\provider::delete_ratings_select($context, 'mod_forum', 'post', "IN ($postidsql)", $params);
// Delete all Tags.
\core_tag\privacy\provider::delete_item_tags_select($context, 'mod_forum', 'forum_posts', "IN ($postidsql)", $params);
// Delete all files from the posts.
$fs = get_file_storage();
$fs->delete_area_files_select($context->id, 'mod_forum', 'post', "IN ($postidsql)", $params);
$fs->delete_area_files_select($context->id, 'mod_forum', 'attachment', "IN ($postidsql)", $params);
}
}

0 comments on commit 8c3124c

Please sign in to comment.
You can’t perform that action at this time.