MDL-62601 editor_atto: Do not use context_user
[moodle.git] / lib / editor / atto / classes / privacy / provider.php
CommitLineData
0d619f41
AN
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Privacy Subsystem implementation for editor_atto.
19 *
20 * @package editor_atto
21 * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25namespace editor_atto\privacy;
26
27defined('MOODLE_INTERNAL') || die();
28
29use \core_privacy\local\request\approved_contextlist;
30use \core_privacy\local\request\writer;
31use \core_privacy\local\request\helper;
32use \core_privacy\local\request\deletion_criteria;
33use \core_privacy\local\metadata\collection;
34
35/**
36 * Privacy Subsystem implementation for editor_atto.
37 *
38 * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 */
41class provider implements
42 // The Atto editor stores user provided data.
43 \core_privacy\local\metadata\provider,
44
45 // The Atto editor provides data directly to core.
46 \core_privacy\local\request\plugin\provider {
47
48 /**
49 * Returns information about how editor_atto stores its data.
50 *
51 * @param collection $collection The initialised collection to add items to.
52 * @return collection A listing of user data stored through this system.
53 */
54 public static function get_metadata(collection $collection) : collection {
55 // There isn't much point giving details about the pageid, etc.
56 $collection->add_database_table('editor_atto_autosave', [
57 'userid' => 'privacy:metadata:database:atto_autosave:userid',
58 'drafttext' => 'privacy:metadata:database:atto_autosave:drafttext',
59 'timemodified' => 'privacy:metadata:database:atto_autosave:timemodified',
60 ], 'privacy:metadata:database:atto_autosave');
61
62 return $collection;
63 }
64
65 /**
66 * Get the list of contexts that contain user information for the specified user.
67 *
68 * @param int $userid The user to search.
69 * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
70 */
71 public static function get_contexts_for_userid(int $userid) : \core_privacy\local\request\contextlist {
72 // This block doesn't know who information is stored against unless it
73 // is at the user context.
74 $contextlist = new \core_privacy\local\request\contextlist();
0d619f41 75
801c6bcf
AN
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]);
0d619f41 82
801c6bcf
AN
83 $sql = "SELECT contextid FROM {editor_atto_autosave} WHERE userid = :userid";
84 $contextlist->add_from_sql($sql, ['userid' => $userid]);
0d619f41
AN
85
86 return $contextlist;
87 }
88
89 /**
90 * Export all user data for the specified user, in the specified contexts.
91 *
92 * @param approved_contextlist $contextlist The approved contexts to export information for.
93 */
94 public static function export_user_data(approved_contextlist $contextlist) {
95 global $DB;
96
97 $user = $contextlist->get_user();
98
801c6bcf
AN
99 $sql = "SELECT *
100 FROM {editor_atto_autosave}
101 WHERE userid = :userid AND contextid {$contextsql}";
102
0d619f41
AN
103 list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
104 $contextparams['userid'] = $contextlist->get_user()->id;
801c6bcf
AN
105 $autosaves = $DB->get_recordset_sql($sql, $contextparams);
106 self::export_autosaves($user, $autosaves);
0d619f41
AN
107
108 $sql = "SELECT *
109 FROM {editor_atto_autosave}
801c6bcf
AN
110 JOIN {context} c ON c.id = eas.contextid
111 WHERE c.id {$contextsql} AND contextlevel = :contextuser AND c.instanceid = :userid";
0d619f41 112
801c6bcf
AN
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;
0d619f41 116 $autosaves = $DB->get_recordset_sql($sql, $contextparams);
801c6bcf
AN
117 self::export_autosaves($user, $autosaves);
118 }
0d619f41 119
801c6bcf
AN
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) {
0d619f41
AN
127 foreach ($autosaves as $autosave) {
128 $context = \context::instance_by_id($autosave->contextid);
129 $subcontext = [
130 get_string('autosaves', 'editor_atto'),
131 $autosave->id,
132 ];
133
134 $html = writer::with_context($context)
135 ->rewrite_pluginfile_urls($subcontext, 'user', 'draft', $autosave->draftid, $autosave->drafttext);
136
137 $data = (object) [
138 'drafttext' => format_text($html, FORMAT_HTML, static::get_filter_options()),
139 'timemodified' => \core_privacy\local\request\transform::datetime($autosave->timemodified),
140 ];
141
142 if ($autosave->userid != $user->id) {
143 $data->author = \core_privacy\local\request\transform::user($autosave->userid);
144 }
145
146 writer::with_context($context)
147 ->export_data($subcontext, $data)
148 ->export_area_files($subcontext, 'user', 'draft', $autosave->draftid);
149 }
150 $autosaves->close();
151 }
152
153 /**
154 * Delete all data for all users in the specified context.
155 *
156 * @param context $context The specific context to delete data for.
157 */
158 public static function delete_data_for_all_users_in_context(\context $context) {
159 global $DB;
160
161 $DB->delete_records('editor_atto_autosave', [
162 'contextid' => $context->id,
163 ]);
164 }
165
166 /**
167 * Delete all user data for the specified user, in the specified contexts.
168 *
169 * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
170 */
171 public static function delete_data_for_user(approved_contextlist $contextlist) {
172 global $DB;
173
174 $user = $contextlist->get_user();
175
176 list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
177 $contextparams['userid'] = $user->id;
178
179 $sql = "SELECT * FROM {editor_atto_autosave} WHERE contextid {$contextsql}";
180 $autosaves = $DB->delete_records_select('editor_atto_autosave', "userid = :userid AND contextid {$contextsql}",
181 $contextparams);
182 }
183
184 /**
185 * Get the filter options.
186 *
187 * This is shared to allow unit testing too.
188 *
189 * @return \stdClass
190 */
191 public static function get_filter_options() {
192 return (object) [
193 'overflowdiv' => true,
194 'noclean' => true,
195 ];
196 }
197}