MDL-63632 forum: Delete where not discussion author

This commit is contained in:
Andrew Nicols 2018-10-12 08:12:18 +08:00
parent 0bf20c560e
commit 951ae21309
2 changed files with 172 additions and 38 deletions

View file

@ -771,6 +771,7 @@ class provider implements
$DB->delete_records('forum_track_prefs', ['forumid' => $forumid]); $DB->delete_records('forum_track_prefs', ['forumid' => $forumid]);
$DB->delete_records('forum_subscriptions', ['forum' => $forumid]); $DB->delete_records('forum_subscriptions', ['forum' => $forumid]);
$DB->delete_records('forum_read', ['forumid' => $forumid]); $DB->delete_records('forum_read', ['forumid' => $forumid]);
$DB->delete_records('forum_digests', ['forum' => $forumid]);
// Delete all discussion items. // Delete all discussion items.
$DB->delete_records_select( $DB->delete_records_select(
@ -831,6 +832,11 @@ class provider implements
'userid' => $userid, 'userid' => $userid,
]); ]);
$DB->delete_records('forum_digests', [
'forum' => $forum->id,
'userid' => $userid,
]);
// Delete all discussion items. // Delete all discussion items.
$DB->delete_records_select( $DB->delete_records_select(
'forum_queue', 'forum_queue',
@ -846,48 +852,39 @@ class provider implements
'userid' => $userid, 'userid' => $userid,
]); ]);
$uniquediscussions = $DB->get_recordset('forum_discussions', [ // Do not delete discussion or forum posts.
'forum' => $forum->id, // Instead update them to reflect that the content has been deleted.
'userid' => $userid, $postsql = "userid = :userid AND discussion IN (SELECT id FROM {forum_discussions} WHERE forum = :forum)";
]); $postidsql = "SELECT fp.id FROM {forum_posts} fp WHERE {$postsql}";
$postparams = [
'forum' => $forum->id,
'userid' => $userid,
];
foreach ($uniquediscussions as $discussion) { // Update the subject.
// Do not delete discussion or forum posts. $DB->set_field_select('forum_posts', 'subject', '', $postsql, $postparams);
// Instead update them to reflect that the content has been deleted.
$postsql = "userid = :userid AND discussion IN (SELECT id FROM {forum_discussions} WHERE forum = :forum)";
$postidsql = "SELECT fp.id FROM {forum_posts} fp WHERE {$postsql}";
$postparams = [
'forum' => $forum->id,
'userid' => $userid,
];
// Update the subject. // Update the message and its format.
$DB->set_field_select('forum_posts', 'subject', '', $postsql, $postparams); $DB->set_field_select('forum_posts', 'message', '', $postsql, $postparams);
$DB->set_field_select('forum_posts', 'messageformat', FORMAT_PLAIN, $postsql, $postparams);
// Update the subject and its format. // Mark the post as deleted.
$DB->set_field_select('forum_posts', 'message', '', $postsql, $postparams); $DB->set_field_select('forum_posts', 'deleted', 1, $postsql, $postparams);
$DB->set_field_select('forum_posts', 'messageformat', FORMAT_PLAIN, $postsql, $postparams);
// Mark the post as deleted. // Note: Do _not_ delete ratings of other users. Only delete ratings on the users own posts.
$DB->set_field_select('forum_posts', 'deleted', 1, $postsql, $postparams); // 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)", $postparams);
// Note: Do _not_ delete ratings of other users. Only delete ratings on the users own posts. // Delete all Tags.
// Ratings are aggregate fields and deleting the rating of this post will have an effect on the rating \core_tag\privacy\provider::delete_item_tags_select($context, 'mod_forum', 'forum_posts',
// of any post. "IN ($postidsql)", $postparams);
\core_rating\privacy\provider::delete_ratings_select($context, 'mod_forum', 'post',
"IN ($postidsql)", $postparams);
// Delete all Tags. // Delete all files from the posts.
\core_tag\privacy\provider::delete_item_tags_select($context, 'mod_forum', 'forum_posts', $fs = get_file_storage();
"IN ($postidsql)", $postparams); $fs->delete_area_files_select($context->id, 'mod_forum', 'post', "IN ($postidsql)", $postparams);
$fs->delete_area_files_select($context->id, 'mod_forum', 'attachment', "IN ($postidsql)", $postparams);
// Delete all files from the posts.
$fs = get_file_storage();
$fs->delete_area_files_select($context->id, 'mod_forum', 'post', "IN ($postidsql)", $postparams);
$fs->delete_area_files_select($context->id, 'mod_forum', 'attachment', "IN ($postidsql)", $postparams);
}
$uniquediscussions->close();
} }
} }
} }

View file

@ -165,6 +165,8 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
* information returned. * information returned.
*/ */
public function test_user_has_never_posted_subscribed_to_forum() { public function test_user_has_never_posted_subscribed_to_forum() {
global $DB;
// Create a course, with a forum, our user under test, another user, and a discussion + post from the other user. // Create a course, with a forum, our user under test, another user, and a discussion + post from the other user.
$course = $this->getDataGenerator()->create_course(); $course = $this->getDataGenerator()->create_course();
$this->getDataGenerator()->create_module('forum', ['course' => $course->id]); $this->getDataGenerator()->create_module('forum', ['course' => $course->id]);
@ -199,6 +201,17 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
// There should be data about the forum itself. // There should be data about the forum itself.
$this->assertNotEmpty($writer->get_data($subcontext)); $this->assertNotEmpty($writer->get_data($subcontext));
// Delete the data now.
// Only the post by the user under test will be removed.
$approvedcontextlist = new \core_privacy\tests\request\approved_contextlist(
\core_user::get_user($user->id),
'mod_forum',
[$context->id]
);
$this->assertCount(1, $DB->get_records('forum_subscriptions', ['userid' => $user->id]));
provider::delete_data_for_user($approvedcontextlist);
$this->assertCount(0, $DB->get_records('forum_subscriptions', ['userid' => $user->id]));
} }
/** /**
@ -207,6 +220,8 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
* information returned. * information returned.
*/ */
public function test_user_has_never_posted_subscribed_to_discussion() { public function test_user_has_never_posted_subscribed_to_discussion() {
global $DB;
// Create a course, with a forum, our user under test, another user, and a discussion + post from the other user. // Create a course, with a forum, our user under test, another user, and a discussion + post from the other user.
$course = $this->getDataGenerator()->create_course(); $course = $this->getDataGenerator()->create_course();
$this->getDataGenerator()->create_module('forum', ['course' => $course->id]); $this->getDataGenerator()->create_module('forum', ['course' => $course->id]);
@ -256,6 +271,17 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
// Post content is not exported unless the user participated. // Post content is not exported unless the user participated.
$postsubcontext = $this->get_subcontext($forum, $discussion, $post); $postsubcontext = $this->get_subcontext($forum, $discussion, $post);
$this->assertCount(0, $writer->get_data($postsubcontext)); $this->assertCount(0, $writer->get_data($postsubcontext));
// Delete the data now.
// Only the post by the user under test will be removed.
$approvedcontextlist = new \core_privacy\tests\request\approved_contextlist(
\core_user::get_user($user->id),
'mod_forum',
[$context->id]
);
$this->assertCount(1, $DB->get_records('forum_discussion_subs', ['userid' => $user->id]));
provider::delete_data_for_user($approvedcontextlist);
$this->assertCount(0, $DB->get_records('forum_discussion_subs', ['userid' => $user->id]));
} }
/** /**
@ -296,8 +322,8 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
} }
/** /**
* Test that a user who has posted a reply to another users discussion * Test that a user who has posted a reply to another users discussion will have all content returned, and
* will have all content returned. * appropriate content removed.
*/ */
public function test_user_has_posted_reply() { public function test_user_has_posted_reply() {
global $DB; global $DB;
@ -347,6 +373,25 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
// The reply will be included. // The reply will be included.
$this->assert_post_data($reply, $writer->get_data($this->get_subcontext($forum, $discussion, $reply)), $writer); $this->assert_post_data($reply, $writer->get_data($this->get_subcontext($forum, $discussion, $reply)), $writer);
// Delete the data now.
// Only the post by the user under test will be removed.
$approvedcontextlist = new \core_privacy\tests\request\approved_contextlist(
\core_user::get_user($user->id),
'mod_forum',
[$context->id]
);
provider::delete_data_for_user($approvedcontextlist);
$reply = $DB->get_record('forum_posts', ['id' => $reply->id]);
$this->assertEmpty($reply->subject);
$this->assertEmpty($reply->message);
$this->assertEquals(1, $reply->deleted);
$post = $DB->get_record('forum_posts', ['id' => $post->id]);
$this->assertNotEmpty($post->subject);
$this->assertNotEmpty($post->message);
$this->assertEquals(0, $post->deleted);
} }
/** /**
@ -354,6 +399,8 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
* rater's information returned. * rater's information returned.
*/ */
public function test_user_has_rated_others() { public function test_user_has_rated_others() {
global $DB;
$course = $this->getDataGenerator()->create_course(); $course = $this->getDataGenerator()->create_course();
$forum = $this->getDataGenerator()->create_module('forum', [ $forum = $this->getDataGenerator()->create_module('forum', [
'course' => $course->id, 'course' => $course->id,
@ -404,12 +451,26 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
// The original post will not be included. // The original post will not be included.
$this->assert_post_data($post, $writer->get_data($this->get_subcontext($forum, $discussion, $post)), $writer); $this->assert_post_data($post, $writer->get_data($this->get_subcontext($forum, $discussion, $post)), $writer);
// Delete the data of the user who rated the other user.
// The rating should not be deleted as it the rating is considered grading data.
$approvedcontextlist = new \core_privacy\tests\request\approved_contextlist(
\core_user::get_user($user->id),
'mod_forum',
[$context->id]
);
provider::delete_data_for_user($approvedcontextlist);
// Ratings should remain as they are of another user's content.
$this->assertCount(1, $DB->get_records('rating', ['itemid' => $post->id]));
} }
/** /**
* Test that ratings of a users own content will all be returned. * Test that ratings of a users own content will all be returned.
*/ */
public function test_user_has_been_rated() { public function test_user_has_been_rated() {
global $DB;
$course = $this->getDataGenerator()->create_course(); $course = $this->getDataGenerator()->create_course();
$forum = $this->getDataGenerator()->create_module('forum', [ $forum = $this->getDataGenerator()->create_module('forum', [
'course' => $course->id, 'course' => $course->id,
@ -457,12 +518,26 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
'post', 'post',
$post->id $post->id
); );
// Delete the data of the user who was rated.
// The rating should now be deleted.
$approvedcontextlist = new \core_privacy\tests\request\approved_contextlist(
\core_user::get_user($user->id),
'mod_forum',
[$context->id]
);
provider::delete_data_for_user($approvedcontextlist);
// Ratings should remain as they are of another user's content.
$this->assertCount(0, $DB->get_records('rating', ['itemid' => $post->id]));
} }
/** /**
* Test that per-user daily digest settings are included correctly. * Test that per-user daily digest settings are included correctly.
*/ */
public function test_user_forum_digest() { public function test_user_forum_digest() {
global $DB;
$course = $this->getDataGenerator()->create_course(); $course = $this->getDataGenerator()->create_course();
$forum0 = $this->getDataGenerator()->create_module('forum', ['course' => $course->id]); $forum0 = $this->getDataGenerator()->create_module('forum', ['course' => $course->id]);
@ -514,12 +589,30 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
$this->export_context_data_for_user($user->id, $context2, 'mod_forum'); $this->export_context_data_for_user($user->id, $context2, 'mod_forum');
$this->assertEquals(2, \core_privacy\local\request\writer::with_context($context2)->get_metadata([], 'digestpreference')); $this->assertEquals(2, \core_privacy\local\request\writer::with_context($context2)->get_metadata([], 'digestpreference'));
// Delete the data for one of the users in one of the forums.
$approvedcontextlist = new \core_privacy\tests\request\approved_contextlist(
\core_user::get_user($user->id),
'mod_forum',
[$context1->id]
);
$this->assertEquals(0, $DB->get_field('forum_digests', 'maildigest', ['userid' => $user->id, 'forum' => $forum0->id]));
$this->assertEquals(1, $DB->get_field('forum_digests', 'maildigest', ['userid' => $user->id, 'forum' => $forum1->id]));
$this->assertEquals(2, $DB->get_field('forum_digests', 'maildigest', ['userid' => $user->id, 'forum' => $forum2->id]));
provider::delete_data_for_user($approvedcontextlist);
$this->assertEquals(0, $DB->get_field('forum_digests', 'maildigest', ['userid' => $user->id, 'forum' => $forum0->id]));
$this->assertFalse($DB->get_field('forum_digests', 'maildigest', ['userid' => $user->id, 'forum' => $forum1->id]));
$this->assertEquals(2, $DB->get_field('forum_digests', 'maildigest', ['userid' => $user->id, 'forum' => $forum2->id]));
} }
/** /**
* Test that the per-user, per-forum user tracking data is exported. * Test that the per-user, per-forum user tracking data is exported.
*/ */
public function test_user_tracking_data() { public function test_user_tracking_data() {
global $DB;
$course = $this->getDataGenerator()->create_course(); $course = $this->getDataGenerator()->create_course();
$forumoff = $this->getDataGenerator()->create_module('forum', ['course' => $course->id]); $forumoff = $this->getDataGenerator()->create_module('forum', ['course' => $course->id]);
@ -548,6 +641,33 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
$this->export_context_data_for_user($user->id, $contextoff, 'mod_forum'); $this->export_context_data_for_user($user->id, $contextoff, 'mod_forum');
$this->assertEquals(0, $this->assertEquals(0,
\core_privacy\local\request\writer::with_context($contextoff)->get_metadata([], 'trackreadpreference')); \core_privacy\local\request\writer::with_context($contextoff)->get_metadata([], 'trackreadpreference'));
// Delete the data for one of the users in the 'on' forum.
$approvedcontextlist = new \core_privacy\tests\request\approved_contextlist(
\core_user::get_user($user->id),
'mod_forum',
[$contexton->id]
);
$this->assertTrue($DB->record_exists('forum_track_prefs', ['userid' => $user->id, 'forumid' => $forumoff->id]));
$this->assertFalse($DB->record_exists('forum_track_prefs', ['userid' => $user->id, 'forumid' => $forumon->id]));
provider::delete_data_for_user($approvedcontextlist);
$this->assertTrue($DB->record_exists('forum_track_prefs', ['userid' => $user->id, 'forumid' => $forumoff->id]));
$this->assertFalse($DB->record_exists('forum_track_prefs', ['userid' => $user->id, 'forumid' => $forumon->id]));
// Delete the data for one of the users in the 'off' forum.
$approvedcontextlist = new \core_privacy\tests\request\approved_contextlist(
\core_user::get_user($user->id),
'mod_forum',
[$contextoff->id]
);
provider::delete_data_for_user($approvedcontextlist);
$this->assertFalse($DB->record_exists('forum_track_prefs', ['userid' => $user->id, 'forumid' => $forumoff->id]));
$this->assertFalse($DB->record_exists('forum_track_prefs', ['userid' => $user->id, 'forumid' => $forumon->id]));
} }
/** /**
@ -708,6 +828,23 @@ class mod_forum_privacy_provider_testcase extends \core_privacy\tests\provider_t
$this->assertNotEmpty($readdata); $this->assertNotEmpty($readdata);
$this->assertTrue(isset($readdata->firstread)); $this->assertTrue(isset($readdata->firstread));
$this->assertTrue(isset($readdata->lastread)); $this->assertTrue(isset($readdata->lastread));
// Delete all data for one of the users in one of the forums.
$approvedcontextlist = new \core_privacy\tests\request\approved_contextlist(
\core_user::get_user($user->id),
'mod_forum',
[$context3->id]
);
$this->assertTrue($DB->record_exists('forum_read', ['userid' => $user->id, 'forumid' => $forum1->id]));
$this->assertTrue($DB->record_exists('forum_read', ['userid' => $user->id, 'forumid' => $forum2->id]));
$this->assertTrue($DB->record_exists('forum_read', ['userid' => $user->id, 'forumid' => $forum3->id]));
provider::delete_data_for_user($approvedcontextlist);
$this->assertTrue($DB->record_exists('forum_read', ['userid' => $user->id, 'forumid' => $forum1->id]));
$this->assertTrue($DB->record_exists('forum_read', ['userid' => $user->id, 'forumid' => $forum2->id]));
$this->assertFalse($DB->record_exists('forum_read', ['userid' => $user->id, 'forumid' => $forum3->id]));
} }
/** /**