mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 21:49:15 +01:00
MDL-63969 core_favourites: Add support for removal of context users
This commit is contained in:
parent
dccda6546b
commit
61fafe8127
@ -29,6 +29,7 @@ defined('MOODLE_INTERNAL') || die();
|
||||
use \core_privacy\local\metadata\collection;
|
||||
use \core_privacy\local\request\context;
|
||||
use \core_privacy\local\request\approved_contextlist;
|
||||
use \core_privacy\local\request\transform;
|
||||
|
||||
/**
|
||||
* Privacy class for requesting user data.
|
||||
@ -36,7 +37,10 @@ use \core_privacy\local\request\approved_contextlist;
|
||||
* @copyright 2018 Jake Dallimore <jrhdallimore@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements \core_privacy\local\metadata\provider, \core_privacy\local\request\subsystem\plugin_provider {
|
||||
class provider implements
|
||||
\core_privacy\local\metadata\provider,
|
||||
\core_privacy\local\request\subsystem\plugin_provider,
|
||||
\core_privacy\local\request\shared_userlist_provider {
|
||||
|
||||
/**
|
||||
* Returns metadata about this system.
|
||||
@ -86,13 +90,82 @@ class provider implements \core_privacy\local\metadata\provider, \core_privacy\l
|
||||
FROM {favourite} f
|
||||
WHERE userid = :userid
|
||||
AND component = :component";
|
||||
|
||||
$params = ['userid' => $userid, 'component' => $component];
|
||||
|
||||
if (!is_null($itemtype)) {
|
||||
$sql .= " AND itemtype = :itemtype";
|
||||
$params['itemtype'] = $itemtype;
|
||||
}
|
||||
$params = ['userid' => $userid, 'component' => $component, 'itemtype' => $itemtype];
|
||||
|
||||
$contextlist->add_from_sql($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add users to a userlist who have favourites within the specified context.
|
||||
*
|
||||
* @param \core_privacy\local\request\userlist $userlist The userlist to add the users to.
|
||||
* @param string $itemtype the type of the favourited items.
|
||||
* @return void
|
||||
*/
|
||||
public static function add_userids_for_context(\core_privacy\local\request\userlist $userlist,
|
||||
string $itemtype = null) {
|
||||
if (empty($userlist)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$params = [
|
||||
'contextid' => $userlist->get_context()->id,
|
||||
'component' => $userlist->get_component()
|
||||
];
|
||||
|
||||
$sql = "SELECT userid
|
||||
FROM {favourite}
|
||||
WHERE contextid = :contextid
|
||||
AND component = :component";
|
||||
|
||||
if (!is_null($itemtype)) {
|
||||
$sql .= " AND itemtype = :itemtype";
|
||||
$params['itemtype'] = $itemtype;
|
||||
}
|
||||
|
||||
$userlist->add_from_sql('userid', $sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get favourites data for the specified user in the specified component, item type and item ID.
|
||||
*
|
||||
* @param int $userid The id of the user in scope.
|
||||
* @param \context $context The context to which data is scoped.
|
||||
* @param string $component The favourite's component name.
|
||||
* @param string $itemtype The favourite's item type.
|
||||
* @param int $itemid The favourite's item ID.
|
||||
* @return array|null
|
||||
*/
|
||||
public static function get_favourites_info_for_user(int $userid, \context $context,
|
||||
string $component, string $itemtype, int $itemid) {
|
||||
global $DB;
|
||||
|
||||
$params = [
|
||||
'userid' => $userid,
|
||||
'component' => $component,
|
||||
'itemtype' => $itemtype,
|
||||
'itemid' => $itemid,
|
||||
'contextid' => $context->id
|
||||
];
|
||||
|
||||
if (!$favourited = $DB->get_record('favourite', $params)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return [
|
||||
'starred' => transform::yesno(true),
|
||||
'ordering' => $favourited->ordering,
|
||||
'timecreated' => transform::datetime($favourited->timecreated),
|
||||
'timemodified' => transform::datetime($favourited->timemodified)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all favourites for all users in the specified contexts, and component area.
|
||||
*
|
||||
@ -114,6 +187,39 @@ class provider implements \core_privacy\local\metadata\provider, \core_privacy\l
|
||||
$DB->delete_records_select('favourite', $select, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all favourites for the specified users in the specified context, component area and item type.
|
||||
*
|
||||
* @param \core_privacy\local\request\approved_userlist $userlist The approved contexts and user information
|
||||
* to delete information for.
|
||||
* @param string $itemtype The favourite's itemtype.
|
||||
* @throws \dml_exception if any errors are encountered during deletion.
|
||||
*/
|
||||
public static function delete_favourites_for_userlist(\core_privacy\local\request\approved_userlist $userlist,
|
||||
string $itemtype) {
|
||||
global $DB;
|
||||
|
||||
$userids = $userlist->get_userids();
|
||||
|
||||
if (empty($userids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$context = $userlist->get_context();
|
||||
list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
|
||||
|
||||
$params = [
|
||||
'component' => $userlist->get_component(),
|
||||
'itemtype' => $itemtype,
|
||||
'contextid' => $context->id
|
||||
];
|
||||
|
||||
$params += $userparams;
|
||||
$select = "component = :component AND itemtype = :itemtype AND contextid = :contextid AND userid $usersql";
|
||||
|
||||
$DB->delete_records_select('favourite', $select, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all favourites for the specified user, in the specified contexts.
|
||||
*
|
||||
|
@ -27,6 +27,7 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use \core_privacy\tests\provider_testcase;
|
||||
use \core_favourites\privacy\provider;
|
||||
use \core_privacy\local\request\transform;
|
||||
|
||||
/**
|
||||
* Unit tests for favourites/classes/privacy/provider
|
||||
@ -65,25 +66,25 @@ class privacy_test extends provider_testcase {
|
||||
$ufservice1 = \core_favourites\service_factory::get_service_for_user_context($user1context);
|
||||
$ufservice2 = \core_favourites\service_factory::get_service_for_user_context($user2context);
|
||||
$systemcontext = context_system::instance();
|
||||
$ufservice1->create_favourite('core_course', 'course', $course1context->instanceid, $systemcontext);
|
||||
$ufservice1->create_favourite('core_course', 'course', $course2context->instanceid, $systemcontext);
|
||||
$ufservice2->create_favourite('core_course', 'course', $course2context->instanceid, $systemcontext);
|
||||
$this->assertCount(2, $ufservice1->find_favourites_by_type('core_course', 'course'));
|
||||
$this->assertCount(1, $ufservice2->find_favourites_by_type('core_course', 'course'));
|
||||
$ufservice1->create_favourite('core_course', 'courses', $course1context->instanceid, $systemcontext);
|
||||
$ufservice1->create_favourite('core_course', 'courses', $course2context->instanceid, $systemcontext);
|
||||
$ufservice2->create_favourite('core_course', 'courses', $course2context->instanceid, $systemcontext);
|
||||
$this->assertCount(2, $ufservice1->find_favourites_by_type('core_course', 'courses'));
|
||||
$this->assertCount(1, $ufservice2->find_favourites_by_type('core_course', 'courses'));
|
||||
|
||||
// Now, just for variety, let's assume you can favourite a course at user context, and do so for user1.
|
||||
$ufservice1->create_favourite('core_course', 'course', $course1context->instanceid, $user1context);
|
||||
$ufservice1->create_favourite('core_course', 'courses', $course1context->instanceid, $user1context);
|
||||
|
||||
// Now, ask the favourites privacy api to export contexts for favourites of the type we just created, for user1.
|
||||
$contextlist = new \core_privacy\local\request\contextlist();
|
||||
\core_favourites\privacy\provider::add_contexts_for_userid($contextlist, $user1->id, 'core_course', 'course');
|
||||
\core_favourites\privacy\provider::add_contexts_for_userid($contextlist, $user1->id, 'core_course', 'courses');
|
||||
|
||||
// Verify we have two contexts in the list for user1.
|
||||
$this->assertCount(2, $contextlist->get_contextids());
|
||||
|
||||
// And verify we only have the system context returned for user2.
|
||||
$contextlist = new \core_privacy\local\request\contextlist();
|
||||
\core_favourites\privacy\provider::add_contexts_for_userid($contextlist, $user2->id, 'core_course', 'course');
|
||||
\core_favourites\privacy\provider::add_contexts_for_userid($contextlist, $user2->id, 'core_course', 'courses');
|
||||
$this->assertCount(1, $contextlist->get_contextids());
|
||||
}
|
||||
|
||||
@ -96,19 +97,19 @@ class privacy_test extends provider_testcase {
|
||||
// Favourite 2 courses for user1 and 1 course for user2, all at the user context.
|
||||
$ufservice1 = \core_favourites\service_factory::get_service_for_user_context($user1context);
|
||||
$ufservice2 = \core_favourites\service_factory::get_service_for_user_context($user2context);
|
||||
$ufservice1->create_favourite('core_course', 'course', $course1context->instanceid, $user1context);
|
||||
$ufservice1->create_favourite('core_course', 'course', $course2context->instanceid, $user1context);
|
||||
$ufservice2->create_favourite('core_course', 'course', $course2context->instanceid, $user2context);
|
||||
$this->assertCount(2, $ufservice1->find_favourites_by_type('core_course', 'course'));
|
||||
$this->assertCount(1, $ufservice2->find_favourites_by_type('core_course', 'course'));
|
||||
$ufservice1->create_favourite('core_course', 'courses', $course1context->instanceid, $user1context);
|
||||
$ufservice1->create_favourite('core_course', 'courses', $course2context->instanceid, $user1context);
|
||||
$ufservice2->create_favourite('core_course', 'courses', $course2context->instanceid, $user2context);
|
||||
$this->assertCount(2, $ufservice1->find_favourites_by_type('core_course', 'courses'));
|
||||
$this->assertCount(1, $ufservice2->find_favourites_by_type('core_course', 'courses'));
|
||||
|
||||
// Now, delete the favourites for user1 only.
|
||||
$approvedcontextlist = new \core_privacy\local\request\approved_contextlist($user1, 'core_course', [$user1context->id]);
|
||||
provider::delete_favourites_for_user($approvedcontextlist, 'core_course', 'course');
|
||||
provider::delete_favourites_for_user($approvedcontextlist, 'core_course', 'courses');
|
||||
|
||||
// Verify that we have no favourite courses for user1 but that the records are in tact for user2.
|
||||
$this->assertCount(0, $ufservice1->find_favourites_by_type('core_course', 'course'));
|
||||
$this->assertCount(1, $ufservice2->find_favourites_by_type('core_course', 'course'));
|
||||
$this->assertCount(0, $ufservice1->find_favourites_by_type('core_course', 'courses'));
|
||||
$this->assertCount(1, $ufservice2->find_favourites_by_type('core_course', 'courses'));
|
||||
}
|
||||
|
||||
public function test_delete_favourites_for_all_users() {
|
||||
@ -134,4 +135,170 @@ class privacy_test extends provider_testcase {
|
||||
$this->assertCount(0, $ufservice1->find_favourites_by_type('core_course', 'modules'));
|
||||
$this->assertCount(1, $ufservice2->find_favourites_by_type('core_course', 'modules'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test confirming that user ID's of favourited items can be added to the userlist.
|
||||
*/
|
||||
public function test_add_userids_for_context() {
|
||||
list($user1, $user2, $user1context, $user2context, $course1context, $course2context) = $this->set_up_courses_and_users();
|
||||
|
||||
// Favourite 2 courses for user1 and 1 course for user2, all at the site context.
|
||||
$ufservice1 = \core_favourites\service_factory::get_service_for_user_context($user1context);
|
||||
$ufservice2 = \core_favourites\service_factory::get_service_for_user_context($user2context);
|
||||
$systemcontext = context_system::instance();
|
||||
$ufservice1->create_favourite('core_course', 'courses', $course1context->instanceid, $systemcontext);
|
||||
$ufservice1->create_favourite('core_course', 'courses', $course2context->instanceid, $systemcontext);
|
||||
$ufservice2->create_favourite('core_course', 'courses', $course2context->instanceid, $systemcontext);
|
||||
$this->assertCount(2, $ufservice1->find_favourites_by_type('core_course', 'courses'));
|
||||
$this->assertCount(1, $ufservice2->find_favourites_by_type('core_course', 'courses'));
|
||||
|
||||
// Now, just for variety, let's assume you can favourite a course at user context, and do so for user1.
|
||||
$ufservice1->create_favourite('core_course', 'courses', $course1context->instanceid, $user1context);
|
||||
|
||||
// Now, ask the favourites privacy api to export userids for favourites of the type we just created, in the system context.
|
||||
$userlist = new \core_privacy\local\request\userlist($systemcontext, 'core_course');
|
||||
provider::add_userids_for_context($userlist, 'courses');
|
||||
// Verify we have two userids in the list for system context.
|
||||
$this->assertCount(2, $userlist->get_userids());
|
||||
$expected = [
|
||||
$user1->id,
|
||||
$user2->id
|
||||
];
|
||||
$this->assertEquals($expected, $userlist->get_userids(), '', 0.0, 10, true);
|
||||
|
||||
// Ask the favourites privacy api to export userids for favourites of the type we just created, in the user1 context.
|
||||
$userlist = new \core_privacy\local\request\userlist($user1context, 'core_course');
|
||||
provider::add_userids_for_context($userlist, 'courses');
|
||||
// Verify we have one userid in the list for user1 context.
|
||||
$this->assertCount(1, $userlist->get_userids());
|
||||
$expected = [$user1->id];
|
||||
$this->assertEquals($expected, $userlist->get_userids());
|
||||
|
||||
// Ask the favourites privacy api to export userids for favourites of the type we just created, in the user2 context.
|
||||
$userlist = new \core_privacy\local\request\userlist($user2context, 'core_favourites');
|
||||
provider::add_userids_for_context($userlist, 'core_course', 'courses');
|
||||
// Verify we do not have any userids in the list for user2 context.
|
||||
$this->assertCount(0, $userlist->get_userids());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test deletion of user favourites based on an approved_userlist, component area and item type.
|
||||
*/
|
||||
public function test_delete_favourites_for_userlist() {
|
||||
list($user1, $user2, $user1context, $user2context, $course1context, $course2context) = $this->set_up_courses_and_users();
|
||||
|
||||
// Favourite 2 courses for user1 and 1 course for user2.
|
||||
$systemcontext = context_system::instance();
|
||||
$ufservice1 = \core_favourites\service_factory::get_service_for_user_context($user1context);
|
||||
$ufservice2 = \core_favourites\service_factory::get_service_for_user_context($user2context);
|
||||
$ufservice1->create_favourite('core_course', 'courses', $course1context->instanceid, $systemcontext);
|
||||
$ufservice1->create_favourite('core_course', 'courses', $course2context->instanceid, $user1context);
|
||||
$ufservice2->create_favourite('core_course', 'courses', $course2context->instanceid, $systemcontext);
|
||||
$this->assertCount(2, $ufservice1->find_favourites_by_type('core_course', 'courses'));
|
||||
$this->assertCount(1, $ufservice2->find_favourites_by_type('core_course', 'courses'));
|
||||
|
||||
// Ask the favourites privacy api to export userids for favourites of the type we just created, in the system context.
|
||||
$userlist1 = new \core_privacy\local\request\userlist($systemcontext, 'core_course');
|
||||
provider::add_userids_for_context($userlist1, 'courses');
|
||||
// Verify we have two userids in the list for system context.
|
||||
$this->assertCount(2, $userlist1->get_userids());
|
||||
|
||||
// Ask the favourites privacy api to export userids for favourites of the type we just created, in the user1 context.
|
||||
$userlist2 = new \core_privacy\local\request\userlist($user1context, 'core_course');
|
||||
provider::add_userids_for_context($userlist2, 'courses');
|
||||
// Verify we have one userid in the list for user1 context.
|
||||
$this->assertCount(1, $userlist2->get_userids());
|
||||
|
||||
// Now, delete the favourites for user1 only in the system context.
|
||||
$approveduserlist = new \core_privacy\local\request\approved_userlist($systemcontext, 'core_course',
|
||||
[$user1->id]);
|
||||
provider::delete_favourites_for_userlist($approveduserlist, 'courses');
|
||||
// Ensure user1's data was deleted and user2 is still returned for system context.
|
||||
$userlist1 = new \core_privacy\local\request\userlist($systemcontext, 'core_course');
|
||||
provider::add_userids_for_context($userlist1, 'courses');
|
||||
$this->assertCount(1, $userlist1->get_userids());
|
||||
// Verify that user2 is still in the list for system context.
|
||||
$expected = [$user2->id];
|
||||
$this->assertEquals($expected, $userlist1->get_userids());
|
||||
// Verify that the data of user1 was not deleted in the user1context.
|
||||
$userlist2 = new \core_privacy\local\request\userlist($user1context, 'core_course');
|
||||
provider::add_userids_for_context($userlist2, 'courses');
|
||||
$expected = [$user1->id];
|
||||
$this->assertEquals($expected, $userlist2->get_userids());
|
||||
|
||||
// Now, delete the favourites for user2 only in the user1 context.
|
||||
// Make sure favourites are only being deleted in the right context.
|
||||
$approveduserlist = new \core_privacy\local\request\approved_userlist($user1context, 'core_course',
|
||||
[$user2->id]);
|
||||
provider::delete_favourites_for_userlist($approveduserlist, 'courses');
|
||||
// Verify we have one userid in the list for system context.
|
||||
$userlist2 = new \core_privacy\local\request\userlist($systemcontext, 'core_course');
|
||||
provider::add_userids_for_context($userlist2, 'courses');
|
||||
$this->assertCount(1, $userlist2->get_userids());
|
||||
// Verify that user2 is still in the list for system context.
|
||||
$expected = [$user2->id];
|
||||
$this->assertEquals($expected, $userlist2->get_userids());
|
||||
|
||||
// Verify that user1 is still present in the list for user1 context.
|
||||
$userlist3 = new \core_privacy\local\request\userlist($user1context, 'core_course');
|
||||
provider::add_userids_for_context($userlist3, 'courses');
|
||||
$this->assertCount(1, $userlist3->get_userids());
|
||||
// Verify that user1 is still in the list for user1 context.
|
||||
$expected = [$user1->id];
|
||||
$this->assertEquals($expected, $userlist3->get_userids());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetching the favourites data for a specified user in a specified component, item type and item ID.
|
||||
*/
|
||||
public function test_get_favourites_info_for_user() {
|
||||
list($user1, $user2, $user1context, $user2context, $course1context, $course2context) = $this->set_up_courses_and_users();
|
||||
|
||||
// Favourite 2 courses for user1 and 1 course for user2.
|
||||
$ufservice1 = \core_favourites\service_factory::get_service_for_user_context($user1context);
|
||||
$ufservice2 = \core_favourites\service_factory::get_service_for_user_context($user2context);
|
||||
$coursefavourite1 = $ufservice1->create_favourite('core_course', 'courses',
|
||||
$course1context->instanceid, $course1context);
|
||||
$this->waitForSecond();
|
||||
$coursefavourite2 = $ufservice1->create_favourite('core_course', 'courses',
|
||||
$course2context->instanceid, $course2context);
|
||||
$this->waitForSecond();
|
||||
$coursefavourite3 = $ufservice2->create_favourite('core_course', 'courses',
|
||||
$course2context->instanceid, $course2context);
|
||||
$this->assertCount(2, $ufservice1->find_favourites_by_type('core_course', 'courses'));
|
||||
$this->assertCount(1, $ufservice2->find_favourites_by_type('core_course', 'courses'));
|
||||
|
||||
// Get the favourites info for user1 in the course1 context.
|
||||
$favouriteinfo1 = (object) provider::get_favourites_info_for_user($user1->id, $course1context,
|
||||
'core_course', 'courses', $course1context->instanceid);
|
||||
// Ensure the correct data has been returned.
|
||||
$this->assertEquals(transform::yesno(true), $favouriteinfo1->starred);
|
||||
$this->assertEquals('', $favouriteinfo1->ordering);
|
||||
$this->assertEquals(transform::datetime($coursefavourite1->timecreated), $favouriteinfo1->timecreated);
|
||||
$this->assertEquals(transform::datetime($coursefavourite1->timemodified), $favouriteinfo1->timemodified);
|
||||
|
||||
// Get the favourites info for user1 in the course2 context.
|
||||
$favouriteinfo2 = (object) provider::get_favourites_info_for_user($user1->id, $course2context,
|
||||
'core_course', 'courses', $course2context->instanceid);
|
||||
// Ensure the correct data has been returned.
|
||||
$this->assertEquals(transform::yesno(true), $favouriteinfo2->starred);
|
||||
$this->assertEquals('', $favouriteinfo2->ordering);
|
||||
$this->assertEquals(transform::datetime($coursefavourite2->timecreated), $favouriteinfo2->timecreated);
|
||||
$this->assertEquals(transform::datetime($coursefavourite2->timemodified), $favouriteinfo2->timemodified);
|
||||
|
||||
// Get the favourites info for user2 in the course2 context.
|
||||
$favouriteinfo3 = (object) provider::get_favourites_info_for_user($user2->id, $course2context,
|
||||
'core_course', 'courses', $course2context->instanceid);
|
||||
// Ensure the correct data has been returned.
|
||||
$this->assertEquals(transform::yesno(true), $favouriteinfo3->starred);
|
||||
$this->assertEquals('', $favouriteinfo3->ordering);
|
||||
$this->assertEquals(transform::datetime($coursefavourite3->timecreated), $favouriteinfo3->timecreated);
|
||||
$this->assertEquals(transform::datetime($coursefavourite3->timemodified), $favouriteinfo3->timemodified);
|
||||
|
||||
// Get the favourites info for user2 in the course1 context (user2 has not favourited course1).
|
||||
$favouriteinfo4 = provider::get_favourites_info_for_user($user2->id, $course1context,
|
||||
'core_course', 'courses', $course1context->instanceid);
|
||||
// Ensure that data has not been returned.
|
||||
$this->assertEmpty($favouriteinfo4);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user