mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 12:32:08 +02:00
Merge branch 'MDL-63969-master-4' of git://github.com/mihailges/moodle
This commit is contained in:
commit
18b947671b
@ -55,6 +55,7 @@ class provider implements
|
||||
*/
|
||||
public static function get_metadata(collection $collection) : collection {
|
||||
$collection->add_subsystem_link('core_completion', [], 'privacy:metadata:completionsummary');
|
||||
$collection->add_subsystem_link('core_favourites', [], 'privacy:metadata:favouritessummary');
|
||||
$collection->add_user_preference('coursecat_management_perpage', 'privacy:perpage');
|
||||
return $collection;
|
||||
}
|
||||
@ -75,6 +76,9 @@ class provider implements
|
||||
$params['contextcourse'] = CONTEXT_COURSE;
|
||||
$contextlist = new contextlist();
|
||||
$contextlist->add_from_sql($sql, $params);
|
||||
|
||||
\core_favourites\privacy\provider::add_contexts_for_userid($contextlist, $userid, 'core_course', 'courses');
|
||||
|
||||
return $contextlist;
|
||||
}
|
||||
|
||||
@ -86,11 +90,12 @@ class provider implements
|
||||
public static function get_users_in_context(userlist $userlist) {
|
||||
$context = $userlist->get_context();
|
||||
|
||||
if (!is_a($context, \context_course::class)) {
|
||||
if (!$context instanceof \context_course) {
|
||||
return;
|
||||
}
|
||||
|
||||
\core_completion\privacy\provider::add_course_completion_users_to_userlist($userlist);
|
||||
\core_favourites\privacy\provider::add_userids_for_context($userlist, 'courses');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,10 +116,18 @@ class provider implements
|
||||
WHERE ctx.id $select";
|
||||
|
||||
$courses = $DB->get_recordset_sql($sql, $params);
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$coursecompletion = \core_completion\privacy\provider::get_course_completion_info($contextlist->get_user(), $course);
|
||||
writer::with_context(\context_course::instance($course->id))->export_data(
|
||||
[get_string('privacy:completionpath', 'course')], (object) $coursecompletion);
|
||||
// Get user's favourites information for the particular course.
|
||||
$coursefavourite = \core_favourites\privacy\provider::get_favourites_info_for_user($contextlist->get_user()->id,
|
||||
\context_course::instance($course->id), 'core_course', 'courses', $course->id);
|
||||
if ($coursefavourite) { // If the course has been favourited by the user, include it in the export.
|
||||
writer::with_context(\context_course::instance($course->id))->export_data(
|
||||
[get_string('privacy:favouritespath', 'course')], (object) $coursefavourite);
|
||||
}
|
||||
}
|
||||
$courses->close();
|
||||
}
|
||||
@ -217,10 +230,14 @@ class provider implements
|
||||
*/
|
||||
public static function delete_data_for_all_users_in_context(\context $context) {
|
||||
// Check what context we've been delivered.
|
||||
if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
// Delete course completion data.
|
||||
\core_completion\privacy\provider::delete_completion(null, $context->instanceid);
|
||||
if (!$context instanceof \context_course) {
|
||||
return;
|
||||
}
|
||||
// Delete course completion data.
|
||||
\core_completion\privacy\provider::delete_completion(null, $context->instanceid);
|
||||
// Delete course favourite data.
|
||||
\core_favourites\privacy\provider::delete_favourites_for_all_users($context, 'core_course',
|
||||
'courses');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,9 +247,13 @@ class provider implements
|
||||
*/
|
||||
public static function delete_data_for_user(approved_contextlist $contextlist) {
|
||||
foreach ($contextlist as $context) {
|
||||
if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
// Check what context we've been delivered.
|
||||
if ($context instanceof \context_course) {
|
||||
// Delete course completion data.
|
||||
\core_completion\privacy\provider::delete_completion($contextlist->get_user(), $context->instanceid);
|
||||
// Delete course favourite data.
|
||||
\core_favourites\privacy\provider::delete_favourites_for_user($contextlist, 'core_course',
|
||||
'courses');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -243,12 +264,15 @@ class provider implements
|
||||
* @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();
|
||||
|
||||
if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
// Delete course completion data.
|
||||
\core_completion\privacy\provider::delete_completion_by_approved_userlist($userlist, $context->instanceid);
|
||||
// Check what context we've been delivered.
|
||||
if (!$context instanceof \context_course) {
|
||||
return;
|
||||
}
|
||||
// Delete course completion data.
|
||||
\core_completion\privacy\provider::delete_completion_by_approved_userlist($userlist, $context->instanceid);
|
||||
// Delete course favourite data.
|
||||
\core_favourites\privacy\provider::delete_favourites_for_userlist($userlist, 'courses');
|
||||
}
|
||||
}
|
||||
|
@ -3823,12 +3823,14 @@ class core_course_external extends external_api {
|
||||
|
||||
$warning = [];
|
||||
|
||||
$favouriteexists = $ufservice->favourite_exists('core_course', 'courses', $course['id'], \context_system::instance());
|
||||
$favouriteexists = $ufservice->favourite_exists('core_course', 'courses', $course['id'],
|
||||
\context_course::instance($course['id']));
|
||||
|
||||
if ($course['favourite']) {
|
||||
if (!$favouriteexists) {
|
||||
try {
|
||||
$ufservice->create_favourite('core_course', 'courses', $course['id'], \context_system::instance());
|
||||
$ufservice->create_favourite('core_course', 'courses', $course['id'],
|
||||
\context_course::instance($course['id']));
|
||||
} catch (Exception $e) {
|
||||
$warning['courseid'] = $course['id'];
|
||||
if ($e instanceof moodle_exception) {
|
||||
@ -3849,7 +3851,8 @@ class core_course_external extends external_api {
|
||||
} else {
|
||||
if ($favouriteexists) {
|
||||
try {
|
||||
$ufservice->delete_favourite('core_course', 'courses', $course['id'], \context_system::instance());
|
||||
$ufservice->delete_favourite('core_course', 'courses', $course['id'],
|
||||
\context_course::instance($course['id']));
|
||||
} catch (Exception $e) {
|
||||
$warning['courseid'] = $course['id'];
|
||||
if ($e instanceof moodle_exception) {
|
||||
|
@ -27,6 +27,8 @@ defined('MOODLE_INTERNAL') || die();
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/completion/tests/fixtures/completion_creation.php');
|
||||
|
||||
use \core_privacy\local\request\transform;
|
||||
|
||||
/**
|
||||
* Unit tests for course/classes/privacy/policy
|
||||
*
|
||||
@ -43,11 +45,45 @@ class core_course_privacy_testcase extends \core_privacy\tests\provider_testcase
|
||||
*/
|
||||
public function test_get_contexts_for_userid() {
|
||||
$this->resetAfterTest();
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Make sure contexts are not being returned for user1.
|
||||
$contextlist = \core_course\privacy\provider::get_contexts_for_userid($user1->id);
|
||||
$this->assertCount(0, $contextlist->get_contextids());
|
||||
|
||||
// Make sure contexts are not being returned for user2.
|
||||
$contextlist = \core_course\privacy\provider::get_contexts_for_userid($user2->id);
|
||||
$this->assertCount(0, $contextlist->get_contextids());
|
||||
|
||||
// Create course completion data for user1.
|
||||
$this->create_course_completion();
|
||||
$this->complete_course($user);
|
||||
$contextlist = \core_course\privacy\provider::get_contexts_for_userid($user->id);
|
||||
$this->assertEquals($this->coursecontext->id, $contextlist->current()->id);
|
||||
$this->complete_course($user1);
|
||||
|
||||
// Make sure the course context is being returned for user1.
|
||||
$contextlist = \core_course\privacy\provider::get_contexts_for_userid($user1->id);
|
||||
$expected = [$this->coursecontext->id];
|
||||
$actual = $contextlist->get_contextids();
|
||||
$this->assertCount(1, $actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
// Make sure contexts are still not being returned for user2.
|
||||
$contextlist = \core_course\privacy\provider::get_contexts_for_userid($user2->id);
|
||||
$this->assertCount(0, $contextlist->get_contextids());
|
||||
|
||||
// User2 has a favourite course.
|
||||
$user2context = \context_user::instance($user2->id);
|
||||
$ufservice = \core_favourites\service_factory::get_service_for_user_context($user2context);
|
||||
$ufservice->create_favourite('core_course', 'courses', $this->coursecontext->instanceid,
|
||||
$this->coursecontext);
|
||||
|
||||
// Make sure the course context is being returned for user2.
|
||||
$contextlist = \core_course\privacy\provider::get_contexts_for_userid($user2->id);
|
||||
$expected = [$this->coursecontext->id];
|
||||
$actual = $contextlist->get_contextids();
|
||||
$this->assertCount(1, $actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,6 +96,7 @@ class core_course_privacy_testcase extends \core_privacy\tests\provider_testcase
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$user3 = $this->getDataGenerator()->create_user();
|
||||
$user4 = $this->getDataGenerator()->create_user();
|
||||
|
||||
// User1 and user2 complete course.
|
||||
$this->create_course_completion();
|
||||
@ -69,15 +106,32 @@ class core_course_privacy_testcase extends \core_privacy\tests\provider_testcase
|
||||
// User3 is enrolled but has not completed course.
|
||||
$this->getDataGenerator()->enrol_user($user3->id, $this->course->id, 'student');
|
||||
|
||||
// Ensure only users that have course completion are returned.
|
||||
// User4 has a favourited course.
|
||||
$systemcontext = \context_system::instance();
|
||||
$user4ctx = \context_user::instance($user4->id);
|
||||
$ufservice = \core_favourites\service_factory::get_service_for_user_context($user4ctx);
|
||||
$ufservice->create_favourite('core_course', 'courses', $this->coursecontext->instanceid,
|
||||
$this->coursecontext);
|
||||
|
||||
// Ensure only users that have course completion or favourites are returned.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, $component);
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$expected = [$user1->id, $user2->id];
|
||||
$expected = [
|
||||
$user1->id,
|
||||
$user2->id,
|
||||
$user4->id
|
||||
];
|
||||
$actual = $userlist->get_userids();
|
||||
sort($expected);
|
||||
sort($actual);
|
||||
$this->assertCount(2, $actual);
|
||||
$this->assertCount(3, $actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
// Ensure that users are not being returned in other contexts than the course context.
|
||||
$userlist = new \core_privacy\local\request\userlist($systemcontext, $component);
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$this->assertCount(0, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,6 +139,7 @@ class core_course_privacy_testcase extends \core_privacy\tests\provider_testcase
|
||||
*/
|
||||
public function test_export_user_data() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->create_course_completion();
|
||||
$this->complete_course($user);
|
||||
@ -95,6 +150,22 @@ class core_course_privacy_testcase extends \core_privacy\tests\provider_testcase
|
||||
$completiondata = $writer->get_data([get_string('privacy:completionpath', 'course')]);
|
||||
$this->assertEquals('In progress', $completiondata->status);
|
||||
$this->assertCount(2, $completiondata->criteria);
|
||||
|
||||
// User has a favourite course.
|
||||
$usercontext = \context_user::instance($user->id);
|
||||
$ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
|
||||
$favourite = $ufservice->create_favourite('core_course', 'courses',
|
||||
$this->coursecontext->instanceid, $this->coursecontext);
|
||||
|
||||
// Ensure that user's favourites data in the course context is being exported.
|
||||
$writer = \core_privacy\local\request\writer::with_context($this->coursecontext);
|
||||
\core_course\privacy\provider::export_user_data($approvedlist);
|
||||
$favouritedata = $writer->get_data([get_string('privacy:favouritespath', 'course')]);
|
||||
|
||||
$this->assertEquals(transform::yesno(true), $favouritedata->starred);
|
||||
$this->assertEquals('', $favouritedata->ordering);
|
||||
$this->assertEquals(transform::datetime($favourite->timecreated), $favouritedata->timecreated);
|
||||
$this->assertEquals(transform::datetime($favourite->timemodified), $favouritedata->timemodified);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -165,52 +236,169 @@ class core_course_privacy_testcase extends \core_privacy\tests\provider_testcase
|
||||
*/
|
||||
public function test_delete_data_for_all_users_in_context() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$this->create_course_completion();
|
||||
|
||||
$systemcontext = \context_system::instance();
|
||||
$user1ctx = \context_user::instance($user1->id);
|
||||
$user2ctx = \context_user::instance($user2->id);
|
||||
// User1 and user2 have a favourite course.
|
||||
$ufservice1 = \core_favourites\service_factory::get_service_for_user_context($user1ctx);
|
||||
$ufservice1->create_favourite('core_course', 'courses', $this->coursecontext->instanceid,
|
||||
$this->coursecontext);
|
||||
$ufservice2 = \core_favourites\service_factory::get_service_for_user_context($user2ctx);
|
||||
$ufservice2->create_favourite('core_course', 'courses', $this->coursecontext->instanceid,
|
||||
$this->coursecontext);
|
||||
|
||||
// Ensure only users that have course favourites are returned in the course context (user1 and user2).
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$this->assertCount(2, $actual);
|
||||
|
||||
// Ensure the users does not have a course completion data.
|
||||
$records = $DB->get_records('course_modules_completion');
|
||||
$this->assertCount(0, $records);
|
||||
$records = $DB->get_records('course_completion_crit_compl');
|
||||
$this->assertCount(0, $records);
|
||||
|
||||
// Create course completions for user1 and users.
|
||||
$this->complete_course($user1);
|
||||
$this->complete_course($user2);
|
||||
$records = $DB->get_records('course_modules_completion');
|
||||
$this->assertCount(2, $records);
|
||||
$records = $DB->get_records('course_completion_crit_compl');
|
||||
$this->assertCount(2, $records);
|
||||
|
||||
// Delete data for all users in a context different than the course context (system context).
|
||||
\core_course\privacy\provider::delete_data_for_all_users_in_context($systemcontext);
|
||||
|
||||
// Ensure the data in the course context has not been deleted.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$this->assertCount(2, $actual);
|
||||
|
||||
// Delete data for all users in the course context.
|
||||
\core_course\privacy\provider::delete_data_for_all_users_in_context($this->coursecontext);
|
||||
|
||||
// Ensure the completion data has been removed in the course context.
|
||||
$records = $DB->get_records('course_modules_completion');
|
||||
$this->assertCount(0, $records);
|
||||
$records = $DB->get_records('course_completion_crit_compl');
|
||||
$this->assertCount(0, $records);
|
||||
|
||||
// Ensure that users are not returned after the deletion in the course context.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$this->assertCount(0, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test deleting data for only one user.
|
||||
*/
|
||||
public function test_delete_data_for_user() {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$user3 = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Create course completion for user1.
|
||||
$this->create_course_completion();
|
||||
$this->complete_course($user1);
|
||||
$this->complete_course($user2);
|
||||
$records = $DB->get_records('course_modules_completion');
|
||||
$this->assertCount(2, $records);
|
||||
$records = $DB->get_records('course_completion_crit_compl');
|
||||
$this->assertCount(2, $records);
|
||||
|
||||
// Ensure user1 is returned in the course context.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$expected = [$user1->id];
|
||||
$this->assertCount(1, $actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
// User2 and user3 have a favourite course.
|
||||
$systemcontext = \context_system::instance();
|
||||
$user2ctx = \context_user::instance($user2->id);
|
||||
$user3ctx = \context_user::instance($user3->id);
|
||||
$ufservice2 = \core_favourites\service_factory::get_service_for_user_context($user2ctx);
|
||||
$ufservice2->create_favourite('core_course', 'courses', $this->coursecontext->instanceid,
|
||||
$this->coursecontext);
|
||||
$ufservice3 = \core_favourites\service_factory::get_service_for_user_context($user3ctx);
|
||||
$ufservice3->create_favourite('core_course', 'courses', $this->coursecontext->instanceid,
|
||||
$this->coursecontext);
|
||||
|
||||
// Ensure user1, user2 and user3 are returned in the course context.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$expected = [
|
||||
$user1->id,
|
||||
$user2->id,
|
||||
$user3->id
|
||||
];
|
||||
sort($expected);
|
||||
sort($actual);
|
||||
$this->assertCount(3, $actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
// Delete user1's data in the course context.
|
||||
$approvedlist = new \core_privacy\local\request\approved_contextlist($user1, 'core_course',
|
||||
[$this->coursecontext->id]);
|
||||
\core_course\privacy\provider::delete_data_for_user($approvedlist);
|
||||
$records = $DB->get_records('course_modules_completion');
|
||||
$this->assertCount(1, $records);
|
||||
$records = $DB->get_records('course_completion_crit_compl');
|
||||
$this->assertCount(1, $records);
|
||||
|
||||
// Ensure user1's data is deleted and only user2 and user3 are returned in the course context.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$expected = [
|
||||
$user2->id,
|
||||
$user3->id
|
||||
];
|
||||
sort($expected);
|
||||
sort($actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
// Delete user2's data in a context different than the course context (system context).
|
||||
$approvedlist = new \core_privacy\local\request\approved_contextlist($user2, 'core_course',
|
||||
[$systemcontext->id]);
|
||||
\core_course\privacy\provider::delete_data_for_user($approvedlist);
|
||||
|
||||
// Ensure user2 and user3 are still returned in the course context.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$expected = [
|
||||
$user2->id,
|
||||
$user3->id
|
||||
];
|
||||
sort($expected);
|
||||
sort($actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
// Delete user2's data in the course context.
|
||||
$approvedlist = new \core_privacy\local\request\approved_contextlist($user2, 'core_course',
|
||||
[$this->coursecontext->id]);
|
||||
\core_course\privacy\provider::delete_data_for_user($approvedlist);
|
||||
|
||||
// Ensure user2's is deleted and user3 is still returned in the course context.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$expected = [
|
||||
$user3->id
|
||||
];
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test deleting data within a context for an approved userlist.
|
||||
*/
|
||||
public function test_delete_data_for_users() {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
$component = 'core_course';
|
||||
@ -221,26 +409,67 @@ class core_course_privacy_testcase extends \core_privacy\tests\provider_testcase
|
||||
$this->create_course_completion();
|
||||
$this->complete_course($user1);
|
||||
$this->complete_course($user2);
|
||||
$this->complete_course($user3);
|
||||
|
||||
// Ensure records exist for all users before delete.
|
||||
$records = $DB->get_records('course_modules_completion');
|
||||
$this->assertCount(3, $records);
|
||||
$records = $DB->get_records('course_completion_crit_compl');
|
||||
$this->assertCount(3, $records);
|
||||
// Ensure user1, user2 are returned in the course context.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$expected = [
|
||||
$user1->id,
|
||||
$user2->id
|
||||
];
|
||||
sort($expected);
|
||||
sort($actual);
|
||||
$this->assertCount(2, $actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
$systemcontext = \context_system::instance();
|
||||
// User3 has a favourite course.
|
||||
$user3ctx = \context_user::instance($user3->id);
|
||||
$ufservice = \core_favourites\service_factory::get_service_for_user_context($user3ctx);
|
||||
$ufservice->create_favourite('core_course', 'courses', $this->coursecontext->instanceid,
|
||||
$this->coursecontext);
|
||||
|
||||
// Ensure user1, user2 and user3 are now returned in the course context.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$expected = [
|
||||
$user1->id,
|
||||
$user2->id,
|
||||
$user3->id
|
||||
];
|
||||
sort($expected);
|
||||
sort($actual);
|
||||
$this->assertCount(3, $actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
// Delete data for user1 and user3 in the course context.
|
||||
$approveduserids = [$user1->id, $user3->id];
|
||||
$approvedlist = new \core_privacy\local\request\approved_userlist($this->coursecontext, $component, $approveduserids);
|
||||
\core_course\privacy\provider::delete_data_for_users($approvedlist);
|
||||
|
||||
// Ensure content is only deleted for approved userlist.
|
||||
$records = $DB->get_records('course_modules_completion');
|
||||
$this->assertCount(1, $records);
|
||||
$record = reset($records);
|
||||
$this->assertEquals($user2->id, $record->userid);
|
||||
$records = $DB->get_records('course_completion_crit_compl');
|
||||
$this->assertCount(1, $records);
|
||||
$record = reset($records);
|
||||
$this->assertEquals($user2->id, $record->userid);
|
||||
// Ensure user1 and user3 are deleted and user2 is still returned in the course context.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$expected = [$user2->id];
|
||||
$this->assertCount(1, $actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
// Try to delete user2's data in a context different than course (system context).
|
||||
$approveduserids = [$user2->id];
|
||||
$approvedlist = new \core_privacy\local\request\approved_userlist($systemcontext, $component, $approveduserids);
|
||||
\core_course\privacy\provider::delete_data_for_users($approvedlist);
|
||||
|
||||
// Ensure user2 is still returned in the course context.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->coursecontext, 'core_course');
|
||||
\core_course\privacy\provider::get_users_in_context($userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
$expected = [
|
||||
$user2->id
|
||||
];
|
||||
$this->assertCount(1, $actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -28,4 +28,6 @@ $string['aria:favourite'] = 'Course is starred';
|
||||
$string['favourite'] = 'Starred course';
|
||||
$string['privacy:perpage'] = 'The number of courses to show per page.';
|
||||
$string['privacy:completionpath'] = 'Course completion';
|
||||
$string['privacy:favouritespath'] = 'Course starred information';
|
||||
$string['privacy:metadata:completionsummary'] = 'The course contains completion information about the user.';
|
||||
$string['privacy:metadata:favouritessummary'] = 'The course contains information relating to the course being starred by the user.';
|
||||
|
@ -2794,5 +2794,18 @@ function xmldb_main_upgrade($oldversion) {
|
||||
upgrade_main_savepoint(true, 2018111301.00);
|
||||
}
|
||||
|
||||
if ($oldversion < 2018111900.00) {
|
||||
// Update favourited courses, so they are saved in the particular course context instead of the system.
|
||||
$favouritedcourses = $DB->get_records('favourite', ['component' => 'core_course', 'itemtype' => 'courses']);
|
||||
|
||||
foreach ($favouritedcourses as $fc) {
|
||||
$coursecontext = \context_course::instance($fc->itemid);
|
||||
$fc->contextid = $coursecontext->id;
|
||||
$DB->update_record('favourite', $fc);
|
||||
}
|
||||
|
||||
upgrade_main_savepoint(true, 2018111900.00);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2018111800.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2018111900.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user