Skip to content

Commit 2709ae4

Browse files
author
David Monllao
committed
Merge branch 'MDL-62601-33' of git://github.com/andrewnicols/moodle into MOODLE_33_STABLE
2 parents 3d1949a + 9aa05cc commit 2709ae4

File tree

2 files changed

+65
-13
lines changed

2 files changed

+65
-13
lines changed

lib/editor/atto/classes/privacy/provider.php

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,16 @@ public static function get_contexts_for_userid($userid) {
7272
// This block doesn't know who information is stored against unless it
7373
// is at the user context.
7474
$contextlist = new \core_privacy\local\request\contextlist();
75-
$contextuser = \context_user::instance($userid);
7675

77-
$sql = "SELECT contextid FROM {editor_atto_autosave} WHERE userid = :userid OR contextid = :contextid";
78-
$params = [
79-
'userid' => $userid,
80-
'contextid' => $contextuser->id,
81-
];
76+
$sql = "SELECT
77+
c.id
78+
FROM {editor_atto_autosave} eas
79+
JOIN {context} c ON c.id = eas.contextid
80+
WHERE contextlevel = :contextuser AND c.instanceid = :userid";
81+
$contextlist->add_from_sql($sql, ['contextuser' => CONTEXT_USER, 'userid' => $userid]);
8282

83-
$contextlist->add_from_sql($sql, $params);
83+
$sql = "SELECT contextid FROM {editor_atto_autosave} WHERE userid = :userid";
84+
$contextlist->add_from_sql($sql, ['userid' => $userid]);
8485

8586
return $contextlist;
8687
}
@@ -95,20 +96,34 @@ public static function export_user_data(approved_contextlist $contextlist) {
9596

9697
$user = $contextlist->get_user();
9798

99+
$sql = "SELECT *
100+
FROM {editor_atto_autosave}
101+
WHERE userid = :userid AND contextid {$contextsql}";
102+
98103
list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
99104
$contextparams['userid'] = $contextlist->get_user()->id;
105+
$autosaves = $DB->get_recordset_sql($sql, $contextparams);
106+
self::export_autosaves($user, $autosaves);
100107

101108
$sql = "SELECT *
102109
FROM {editor_atto_autosave}
103-
WHERE
104-
(userid = :userid AND contextid {$contextsql})
105-
OR
106-
(contextid = :usercontext)";
110+
JOIN {context} c ON c.id = eas.contextid
111+
WHERE c.id {$contextsql} AND contextlevel = :contextuser AND c.instanceid = :userid";
107112

108-
$usercontext = \context_user::instance($user->id);
109-
$contextparams['usercontext'] = $usercontext->id;
113+
list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
114+
$contextparams['userid'] = $contextlist->get_user()->id;
115+
$contextparams['contextuser'] = CONTEXT_USER;
110116
$autosaves = $DB->get_recordset_sql($sql, $contextparams);
117+
self::export_autosaves($user, $autosaves);
118+
}
111119

120+
/**
121+
* Export all autosave records in the recordset, and close the recordset when finished.
122+
*
123+
* @param \stdClass $user The user whose data is to be exported
124+
* @param \moodle_recordset $autosaves The recordset containing the data to export
125+
*/
126+
protected static function export_autosaves(\stdClass $user, \moodle_recordset $autosaves) {
112127
foreach ($autosaves as $autosave) {
113128
$context = \context::instance_by_id($autosave->contextid);
114129
$subcontext = [

privacy/tests/provider_test.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,29 @@ public function test_all_providers_compliant($component, $classname) {
178178
$this->assertTrue($manager->component_is_compliant($component));
179179
}
180180

181+
/**
182+
* Ensure that providers do not throw an error when processing a deleted user.
183+
*
184+
* @dataProvider is_user_data_provider
185+
* @param string $component
186+
*/
187+
public function test_component_understands_deleted_users($component) {
188+
$this->resetAfterTest();
189+
190+
// Create a user.
191+
$user = $this->getDataGenerator()->create_user();
192+
193+
// Delete the user and their context.
194+
delete_user($user);
195+
$usercontext = \context_user::instance($user->id);
196+
$usercontext->delete();
197+
198+
$contextlist = manager::component_class_callback($component, \core_privacy\local\request\core_user_data_provider::class,
199+
'get_contexts_for_userid', [$user->id]);
200+
201+
$this->assertInstanceOf(\core_privacy\local\request\contextlist::class, $contextlist);
202+
}
203+
181204
/**
182205
* Data provider for the metadata\provider tests.
183206
*
@@ -192,6 +215,20 @@ public function metadata_provider_provider() {
192215
});
193216
}
194217

218+
/**
219+
* List of providers which implement the core_user_data_provider.
220+
*
221+
* @return array
222+
*/
223+
public function is_user_data_provider() {
224+
return array_filter($this->get_component_list(), function($component) {
225+
return static::component_implements(
226+
$component['classname'],
227+
\core_privacy\local\request\core_user_data_provider::class
228+
);
229+
});
230+
}
231+
195232
/**
196233
* Checks whether the component's provider class implements the specified interface, either directly or as a grandchild.
197234
*

0 commit comments

Comments
 (0)