Skip to content

Commit

Permalink
MDL-63497 block_html: Add support for removal of context users
Browse files Browse the repository at this point in the history
This issue is a part of the MDL-62560 Epic.
  • Loading branch information
mickhawkins authored and David Monllao committed Oct 22, 2018
1 parent 464b17b commit 7b5fcbd
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 0 deletions.
44 changes: 44 additions & 0 deletions blocks/html/classes/privacy/provider.php
Expand Up @@ -26,7 +26,9 @@

defined('MOODLE_INTERNAL') || die();

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\writer;
use \core_privacy\local\request\helper;
use \core_privacy\local\request\deletion_criteria;
Expand All @@ -42,6 +44,9 @@ class provider implements
// The block_html block stores user provided data.
\core_privacy\local\metadata\provider,

// This plugin is capable of determining which users have data within it.
\core_privacy\local\request\core_userlist_provider,

// The block_html block provides data directly to core.
\core_privacy\local\request\plugin\provider {

Expand Down Expand Up @@ -87,6 +92,32 @@ public static function get_contexts_for_userid(int $userid) : \core_privacy\loca
return $contextlist;
}

/**
* Get the list of users who have data within a 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_block::class)) {
return;
}

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

$sql = "SELECT bpc.instanceid AS userid
FROM {context} c
JOIN {block_instances} bi ON bi.id = c.instanceid AND bi.blockname = 'html'
JOIN {context} bpc ON bpc.id = bi.parentcontextid AND bpc.contextlevel = :contextuser
WHERE c.id = :contextid";

$userlist->add_from_sql('userid', $sql, $params);
}

/**
* Export all user data for the specified user, in the specified contexts.
*
Expand Down Expand Up @@ -164,6 +195,19 @@ public static function delete_data_for_all_users_in_context(\context $context) {
}
}

/**
* 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) {
$context = $userlist->get_context();

if ($context instanceof \context_block && ($blockinstance = static::get_instance_from_context($context))) {
blocks_delete_instance($blockinstance);
}
}

/**
* Delete all user data for the specified user, in the specified contexts.
*
Expand Down
93 changes: 93 additions & 0 deletions blocks/html/tests/privacy_provider_test.php
Expand Up @@ -27,6 +27,7 @@

use \core_privacy\local\request\writer;
use \core_privacy\local\request\approved_contextlist;
use \core_privacy\local\request\approved_userlist;
use \block_html\privacy\provider;

/**
Expand Down Expand Up @@ -341,4 +342,96 @@ public function test_mixed_multiple_blocks_exported() {
$this->assertTrue(isset($contexts[$context->id]));
}
}

/**
* Test that only users with a user context HTML block are fetched.
*/
public function test_get_users_in_context() {
$this->resetAfterTest();

$component = 'block_html';
$title = 'Block title';
$content = 'Block content';
$blockformat = FORMAT_PLAIN;

// Create a user with a user context HTML block.
$user1 = $this->getDataGenerator()->create_user();
$this->setUser($user1);

$userblock = $this->create_user_block($title, $content, $blockformat);
$usercontext = \context_block::instance($userblock->instance->id);

// Create a user with a course context HTML block.
$user2 = $this->getDataGenerator()->create_user();
$this->setUser($user2);

$course = $this->getDataGenerator()->create_course();
$courseblock = $this->create_course_block($course, $title, $content, $blockformat);
$coursecontext = \context_block::instance($courseblock->instance->id);

// Ensure only the user with a user context HTML block is returned.
$userlist = new \core_privacy\local\request\userlist($usercontext, $component);
\block_html\privacy\provider::get_users_in_context($userlist);

$this->assertCount(1, $userlist);

$expected = [$user1->id];
$actual = $userlist->get_userids();

$this->assertEquals($expected, $actual);

// Ensure passing the course context returns no users.
$userlist = new \core_privacy\local\request\userlist($coursecontext, $component);
\mod_forum\privacy\provider::get_users_in_context($userlist);
$this->assertEmpty($userlist);
}

/**
* Test that data for users in approved userlist is deleted.
*/
public function test_delete_data_for_users() {
$this->resetAfterTest();

$component = 'block_html';
$title = 'Block title';
$content = 'Block content';
$blockformat = FORMAT_PLAIN;

// Create 2 user swith a user context HTML blocks.
$user1 = $this->getDataGenerator()->create_user();
$this->setUser($user1);

$block1 = $this->create_user_block($title, $content, $blockformat);
$context1 = \context_block::instance($block1->instance->id);

$user2 = $this->getDataGenerator()->create_user();
$this->setUser($user2);
$block2 = $this->create_user_block($title, $content, $blockformat);
$context2 = \context_block::instance($block2->instance->id);

// Create and populate the userlists.
$userlist1 = new \core_privacy\local\request\userlist($context1, $component);
\block_html\privacy\provider::get_users_in_context($userlist1);
$userlist2 = new \core_privacy\local\request\userlist($context2, $component);
\block_html\privacy\provider::get_users_in_context($userlist2);

// Ensure both members are included.
$this->assertCount(1, $userlist1);
$this->assertCount(1, $userlist2);

// Convert $userlist1 into an approved_contextlist.
$approvedlist = new approved_userlist($context1, 'block_html', $userlist1->get_userids());

// Delete using delete_data_for_user.
provider::delete_data_for_users($approvedlist);

// Re-fetch users in the contexts - only the first one should now be empty.
$userlist1 = new \core_privacy\local\request\userlist($context1, $component);
\block_html\privacy\provider::get_users_in_context($userlist1);
$this->assertCount(0, $userlist1);

$userlist2 = new \core_privacy\local\request\userlist($context2, $component);
\block_html\privacy\provider::get_users_in_context($userlist2);
$this->assertCount(1, $userlist2);
}
}

0 comments on commit 7b5fcbd

Please sign in to comment.