Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
namespace tiny_autosave\privacy;
18
 
19
use core_privacy\local\request\approved_contextlist;
20
use core_privacy\local\request\writer;
21
use core_privacy\local\metadata\collection;
22
use core_privacy\local\request\userlist;
23
use core_privacy\local\request\approved_userlist;
24
use stdClass;
25
 
26
/**
27
 * Privacy Subsystem implementation for tiny_autosave.
28
 *
29
 * @package    tiny_autosave
30
 * @copyright  2022 Andrew Nicols <andrew@nicols.co.uk>
31
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
32
 */
33
class provider implements
34
    // The tiny editor stores user provided data.
35
    \core_privacy\local\metadata\provider,
36
 
37
    // The tiny editor provides data directly to core.
38
    \core_privacy\local\request\plugin\provider,
39
 
40
    // The tiny editor is capable of determining which users have data within it.
41
    \core_privacy\local\request\core_userlist_provider {
42
 
43
    /**
44
     * Returns information about how tiny_autosave stores its data.
45
     *
46
     * @param collection $collection The initialised collection to add items to.
47
     * @return collection A listing of user data stored through this system.
48
     */
49
    public static function get_metadata(collection $collection): collection {
50
        // There isn't much point giving details about the pageid, etc.
51
        $collection->add_database_table('tiny_autosave', [
52
            'userid' => 'privacy:metadata:database:tiny_autosave:userid',
53
            'drafttext' => 'privacy:metadata:database:tiny_autosave:drafttext',
54
            'timemodified' => 'privacy:metadata:database:tiny_autosave:timemodified',
55
        ], 'privacy:metadata:database:tiny_autosave');
56
 
57
        return $collection;
58
    }
59
 
60
    /**
61
     * Get the list of contexts that contain user information for the specified user.
62
     *
63
     * @param int $userid The user to search.
64
     * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
65
     */
66
    public static function get_contexts_for_userid(int $userid): \core_privacy\local\request\contextlist {
67
        $contextlist = new \core_privacy\local\request\contextlist();
68
 
69
        // Data may be saved in the user context.
70
        $sql = "SELECT
71
                    c.id
72
                  FROM {tiny_autosave} eas
73
                  JOIN {context} c ON c.id = eas.contextid
74
                 WHERE contextlevel = :contextuser AND c.instanceid = :userid";
75
        $contextlist->add_from_sql($sql, ['contextuser' => CONTEXT_USER, 'userid' => $userid]);
76
 
77
        // Data may be saved against the userid.
78
        $sql = "SELECT contextid FROM {tiny_autosave} WHERE userid = :userid";
79
        $contextlist->add_from_sql($sql, ['userid' => $userid]);
80
 
81
        return $contextlist;
82
    }
83
 
84
    /**
85
     * Get the list of users within a specific context.
86
     *
87
     * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
88
     */
89
    public static function get_users_in_context(userlist $userlist) {
90
        $context = $userlist->get_context();
91
 
92
        $params = [
93
            'contextid' => $context->id
94
        ];
95
 
96
        $sql = "SELECT userid
97
                  FROM {tiny_autosave}
98
                 WHERE contextid = :contextid";
99
 
100
        $userlist->add_from_sql('userid', $sql, $params);
101
    }
102
 
103
    /**
104
     * Export all user data for the specified user, in the specified contexts.
105
     *
106
     * @param   approved_contextlist    $contextlist    The approved contexts to export information for.
107
     */
108
    public static function export_user_data(approved_contextlist $contextlist) {
109
        global $DB;
110
 
111
        $user = $contextlist->get_user();
112
 
113
        // Firstly export all autosave records from all contexts in the list owned by the given user.
114
        list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
115
        $contextparams['userid'] = $user->id;
116
 
117
        $sql = "SELECT *
118
                  FROM {tiny_autosave}
119
                 WHERE userid = :userid AND contextid {$contextsql}";
120
 
121
        $autosaves = $DB->get_recordset_sql($sql, $contextparams);
122
        self::export_autosaves($user, $autosaves);
123
 
124
        // Additionally export all eventual records in the given user's context regardless the actual owner.
125
        // We still consider them to be the user's personal data even when edited by someone else.
126
        [$contextsql, $contextparams] = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
127
        $contextparams['userid'] = $user->id;
128
        $contextparams['contextuser'] = CONTEXT_USER;
129
 
130
        $sql = "SELECT eas.*
131
                  FROM {tiny_autosave} eas
132
                  JOIN {context} c ON c.id = eas.contextid
133
                 WHERE c.id {$contextsql} AND c.contextlevel = :contextuser AND c.instanceid = :userid";
134
 
135
        $autosaves = $DB->get_recordset_sql($sql, $contextparams);
136
        self::export_autosaves($user, $autosaves);
137
    }
138
 
139
    /**
140
     * Export all autosave records in the recordset, and close the recordset when finished.
141
     *
142
     * @param   stdClass   $user The user whose data is to be exported
143
     * @param   \moodle_recordset $autosaves The recordset containing the data to export
144
     */
145
    protected static function export_autosaves(stdClass $user, \moodle_recordset $autosaves) {
146
        foreach ($autosaves as $autosave) {
147
            $context = \context::instance_by_id($autosave->contextid);
148
            $subcontext = [
149
                get_string('pluginname', 'tiny_autosave'),
150
                $autosave->id,
151
            ];
152
 
153
            $html = writer::with_context($context)
154
                ->rewrite_pluginfile_urls($subcontext, 'user', 'draft', $autosave->draftid, $autosave->drafttext);
155
 
156
            $data = (object) [
157
                'drafttext' => format_text($html, FORMAT_HTML, static::get_filter_options()),
158
                'timemodified' => \core_privacy\local\request\transform::datetime($autosave->timemodified),
159
            ];
160
 
161
            if ($autosave->userid != $user->id) {
162
                $data->author = \core_privacy\local\request\transform::user($autosave->userid);
163
            }
164
 
165
            writer::with_context($context)
166
                ->export_data($subcontext, $data)
167
                ->export_area_files($subcontext, 'user', 'draft', $autosave->draftid);
168
        }
169
        $autosaves->close();
170
    }
171
 
172
    /**
173
     * Delete all data for all users in the specified context.
174
     *
175
     * @param \context $context The specific context to delete data for.
176
     */
177
    public static function delete_data_for_all_users_in_context(\context $context) {
178
        global $DB;
179
 
180
        $DB->delete_records('tiny_autosave', [
181
            'contextid' => $context->id,
182
        ]);
183
    }
184
 
185
    /**
186
     * Delete multiple users within a single context.
187
     *
188
     * @param approved_userlist $userlist The approved context and user information to delete information for.
189
     */
190
    public static function delete_data_for_users(approved_userlist $userlist) {
191
        global $DB;
192
 
193
        $context = $userlist->get_context();
194
        $userids = $userlist->get_userids();
195
 
196
        [$useridsql, $useridsqlparams] = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
197
        $params = ['contextid' => $context->id] + $useridsqlparams;
198
 
199
        $DB->delete_records_select('tiny_autosave', "contextid = :contextid AND userid {$useridsql}",
200
            $params);
201
    }
202
 
203
    /**
204
     * Delete all user data for the specified user, in the specified contexts.
205
     *
206
     * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
207
     */
208
    public static function delete_data_for_user(approved_contextlist $contextlist) {
209
        global $DB;
210
 
211
        $user = $contextlist->get_user();
212
 
213
        [$contextsql, $contextparams] = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
214
        $contextparams['userid'] = $user->id;
215
 
216
        $sql = "SELECT * FROM {tiny_autosave} WHERE contextid {$contextsql}";
217
        $autosaves = $DB->delete_records_select(
218
            'tiny_autosave',
219
            "userid = :userid AND contextid {$contextsql}",
220
            $contextparams
221
        );
222
    }
223
 
224
    /**
225
     * Get the filter options.
226
     *
227
     * This is shared to allow unit testing too.
228
     *
229
     * @return stdClass
230
     */
231
    public static function get_filter_options() {
232
        return (object) [
233
            'overflowdiv' => true,
234
            'noclean' => true,
235
        ];
236
    }
237
}