Skip to content

Commit

Permalink
MDL-62035 core_comment: Update to deletion methods.
Browse files Browse the repository at this point in the history
Also clarification with the export method to clarify that it
is only for one context.
  • Loading branch information
abgreeve committed Apr 20, 2018
1 parent c1f7e7e commit 1b33e41
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 18 deletions.
49 changes: 40 additions & 9 deletions comment/classes/privacy/provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ public static function get_metadata(collection $collection) : collection {
/**
* Writes user data to the writer for the user to download.
*
* @param array $context Contexts to run through and return data.
* @param \context $context The context to export data for.
* @param string $component The component that is calling this function
* @param string $commentarea The comment area related to the component
* @param int $itemid An identifier for a group of comments
* @param array $subcontext The sub-context in which to export this data
* @param bool $onlyforthisuser Only return the comments this user made.
*/
public static function export_comments($context, $component, $commentarea, $itemid, $subcontext, $onlyforthisuser = true) {

public static function export_comments(\context $context, string $component, string $commentarea, int $itemid,
array $subcontext, bool $onlyforthisuser = true) {
$data = new \stdClass;
$data->context = $context;
$data->area = $commentarea;
Expand Down Expand Up @@ -102,31 +102,62 @@ public static function export_comments($context, $component, $commentarea, $item
}

/**
* Deletes all comments for a specified context.
* Deletes all comments for a specified context, component, and commentarea.
*
* @param \context $context Details about which context to delete comments for.
* @param string $component Component to delete.
* @param string $commentarea Comment area to delete.
* @param int $itemid The item ID for use with deletion.
*/
public static function delete_comments_for_all_users_in_context(\context $context) {
public static function delete_comments_for_all_users(\context $context, string $component, string $commentarea = null,
int $itemid = null) {
global $DB;
$DB->delete_records('comments', ['contextid' => $context->id]);
$params = [
'contextid' => $context->id,
'component' => $component
];
if (isset($commentarea)) {
$params['commentarea'] = $commentarea;
}
if (isset($itemid)) {
$params['itemid'] = $itemid;
}
$DB->delete_records('comments', $params);
}

/**
* Deletes all records for a user from a list of approved contexts.
*
* @param \core_privacy\local\request\approved_contextlist $contextlist Contains the user ID and a list of contexts to be
* deleted from.
* @param string $component Component to delete from.
* @param string $commentarea Area to delete from.
* @param int $itemid The item id to delete from.
*/
public static function delete_comments_for_user(\core_privacy\local\request\approved_contextlist $contextlist) {
public static function delete_comments_for_user(\core_privacy\local\request\approved_contextlist $contextlist,
string $component, string $commentarea = null, int $itemid = null) {
global $DB;

$userid = $contextlist->get_user()->id;
$contextids = implode(',', $contextlist->get_contextids());
$params = ['userid' => $userid];
$params = [
'userid' => $userid,
'component' => $component,
];
$areasql = '';
if (isset($commentarea)) {
$params['commentarea'] = $commentarea;
$areasql = 'AND commentarea = :commentarea';
}
$itemsql = '';
if (isset($itemid)) {
$params['itemid'] = $itemid;
$itemsql = 'AND itemid = :itemid';
}
list($insql, $inparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
$params += $inparams;

$select = "userid = :userid and contextid $insql";
$select = "userid = :userid AND component = :component $areasql $itemsql AND contextid $insql";
$DB->delete_records_select('comments', $select, $params);
}
}
92 changes: 83 additions & 9 deletions comment/tests/privacy_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,14 @@
*/
class core_comment_privacy_testcase extends provider_testcase {

protected function setUp() {
$this->resetAfterTest();
}

/**
* Check the exporting of comments for a user id in a context.
*/
public function test_export_comments() {
$this->resetAfterTest(true);
$course = $this->getDataGenerator()->create_course();
$context = context_course::instance($course->id);

Expand Down Expand Up @@ -92,8 +95,8 @@ public function test_export_comments() {
/**
* Tests the deletion of all comments in a context.
*/
public function test_delete_comments_for_all_users_in_context() {
$this->resetAfterTest();
public function test_delete_comments_for_all_users() {
global $DB;

$course1 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course();
Expand All @@ -114,20 +117,54 @@ public function test_delete_comments_for_all_users_in_context() {
$comment1->add('First comment for user 2 on comment 1');
$comment2->add('First comment for user 2 on comment 2');

// Because of the way things are set up with validation, creating an entry with the same context in a different component
// or comment area is a huge pain. We're just going to jam entries into the table instead.
$record = (object) [
'contextid' => $coursecontext1->id,
'component' => 'block_comments',
'commentarea' => 'other_comments',
'itemid' => 2,
'content' => 'Comment user 1 different comment area',
'format' => 0,
'userid' => $user1->id,
'timecreated' => time()
];
$DB->insert_record('comments', $record);
$record = (object) [
'contextid' => $coursecontext1->id,
'component' => 'tool_dataprivacy',
'commentarea' => 'page_comments',
'itemid' => 2,
'content' => 'Comment user 1 different component',
'format' => 0,
'userid' => $user1->id,
'timecreated' => time()
];
$DB->insert_record('comments', $record);

// Delete only for the first context. All records in the comments table for this context should be removed.
\core_comment\privacy\provider::delete_comments_for_all_users_in_context($coursecontext1);
\core_comment\privacy\provider::delete_comments_for_all_users($coursecontext1, 'block_comments', 'page_comments', 0);
// No records left here.
$this->assertCount(0, $comment1->get_comments());
// All of the records are left intact here.
$this->assertCount(2, $comment2->get_comments());

// Check the other comment area.
$result = $DB->get_records('comments', ['commentarea' => 'other_comments']);
$this->assertCount(1, $result);
$data = array_shift($result);
$this->assertEquals('other_comments', $data->commentarea);
// Check the different component, same commentarea.
$result = $DB->get_records('comments', ['component' => 'tool_dataprivacy']);
$this->assertCount(1, $result);
$data = array_shift($result);
$this->assertEquals('tool_dataprivacy', $data->component);
}

/**
* Tests deletion of comments for a specified user and contexts.
*/
public function test_delete_comments_for_user() {
$this->resetAfterTest();
global $DB;

$course1 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course();
Expand All @@ -152,21 +189,58 @@ public function test_delete_comments_for_user() {
$comment2->add('User two replied in comment two');
$comment3->add('Comment three for user 2.');

// Because of the way things are set up with validation, creating an entry with the same context in a different component
// or comment area is a huge pain. We're just going to jam entries into the table instead.
$record = (object) [
'contextid' => $coursecontext1->id,
'component' => 'block_comments',
'commentarea' => 'other_comments',
'itemid' => 2,
'content' => 'Comment user 1 different comment area',
'format' => 0,
'userid' => $user1->id,
'timecreated' => time()
];
$DB->insert_record('comments', $record);
$record = (object) [
'contextid' => $coursecontext1->id,
'component' => 'tool_dataprivacy',
'commentarea' => 'page_comments',
'itemid' => 2,
'content' => 'Comment user 1 different component',
'format' => 0,
'userid' => $user1->id,
'timecreated' => time()
];
$DB->insert_record('comments', $record);

// Delete the comments for user 1.
$approvedcontextlist = new core_privacy\tests\request\approved_contextlist($user1, 'block_comments',
[$coursecontext1->id, $coursecontext2->id]);
\core_comment\privacy\provider::delete_comments_for_user($approvedcontextlist);
\core_comment\privacy\provider::delete_comments_for_user($approvedcontextlist, 'block_comments', 'page_comments', 0);

// No comments left in comments 1 as only user 1 commented there.
$this->assertCount(0, $comment1->get_comments());
// Only user 2 comments left in comments 2.
$comment2comments = $comment2->get_comments();
$this->assertCount(1, $comment2comments);
$this->assertEquals($user2->id, $comment2comments[0]->userid);
$data = array_shift($comment2comments);
$this->assertEquals($user2->id, $data->userid);
// Nothing changed here as user 1 did not leave a comment.
$comment3comments = $comment3->get_comments();
$this->assertCount(1, $comment3comments);
$this->assertEquals($user2->id, $comment3comments[0]->userid);
$data = array_shift(($comment3comments));
$this->assertEquals($user2->id, $data->userid);
// Check the other comment area.
$result = $DB->get_records('comments', ['commentarea' => 'other_comments']);
$this->assertCount(1, $result);
$data = array_shift($result);
$this->assertEquals('other_comments', $data->commentarea);
// Check the different component, same commentarea.
$result = $DB->get_records('comments', ['component' => 'tool_dataprivacy']);
$this->assertCount(1, $result);
$data = array_shift($result);
$this->assertEquals('tool_dataprivacy', $data->component);
}

/**
Expand Down

0 comments on commit 1b33e41

Please sign in to comment.