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
/**
18
 * Privacy provider implementation for core_contentbank.
19
 *
20
 * @package    core_contentbank
21
 * @copyright  2020 Amaia Anabitarte <amaia@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace core_contentbank\privacy;
26
 
27
use core_privacy\local\metadata\collection;
28
use core_privacy\local\request\approved_contextlist;
29
use core_privacy\local\request\contextlist;
30
use core_privacy\local\request\transform;
31
use core_privacy\local\request\writer;
32
use core_privacy\local\request\userlist;
33
use core_privacy\local\request\approved_userlist;
34
use context_system;
35
use context_coursecat;
36
use context_course;
37
 
38
/**
39
 * Privacy provider implementation for core_contentbank.
40
 *
41
 * @copyright  2020 Amaia Anabitarte <amaia@moodle.com>
42
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43
 */
44
class provider implements
45
    \core_privacy\local\metadata\provider,
46
    \core_privacy\local\request\core_userlist_provider,
47
    \core_privacy\local\request\plugin\provider,
48
    \core_privacy\local\request\user_preference_provider {
49
 
50
    /**
51
     * Returns meta data about this system.
52
     *
53
     * @param collection $collection The initialised collection to add items to.
54
     * @return collection A listing of user data stored through this system.
55
     */
56
    public static function get_metadata(collection $collection): collection {
57
        $collection->add_database_table('contentbank_content', [
58
            'name' => 'privacy:metadata:content:name',
59
            'contenttype' => 'privacy:metadata:content:contenttype',
60
            'usercreated' => 'privacy:metadata:content:usercreated',
61
            'usermodified' => 'privacy:metadata:content:usermodified',
62
            'timecreated' => 'privacy:metadata:content:timecreated',
63
            'timemodified' => 'privacy:metadata:content:timemodified',
64
        ], 'privacy:metadata:contentbankcontent');
65
 
66
        return $collection;
67
    }
68
 
69
    /**
70
     * Export all user preferences for the contentbank
71
     *
72
     * @param int $userid The userid of the user whose data is to be exported.
73
     */
74
    public static function export_user_preferences(int $userid) {
75
        $preference = get_user_preferences('core_contentbank_view_list', null, $userid);
76
        if (isset($preference)) {
77
            writer::export_user_preference(
78
                    'core_contentbank',
79
                    'core_contentbank_view_list',
80
                    $preference,
81
                    get_string('privacy:request:preference:set', 'core_contentbank', (object) [
82
                            'name' => 'core_contentbank_view_list',
83
                            'value' => $preference,
84
                    ])
85
            );
86
        }
87
    }
88
 
89
    /**
90
     * Get the list of contexts that contain user information for the specified user.
91
     *
92
     * @param   int $userid The user to search.
93
     * @return  contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
94
     */
95
    public static function get_contexts_for_userid(int $userid): contextlist {
96
        $sql = "SELECT DISTINCT ctx.id
97
                  FROM {context} ctx
98
                  JOIN {contentbank_content} cb
99
                       ON cb.contextid = ctx.id
100
                 WHERE cb.usercreated = :userid
101
                       AND (ctx.contextlevel = :contextlevel1
102
                           OR ctx.contextlevel = :contextlevel2
103
                           OR ctx.contextlevel = :contextlevel3)";
104
 
105
        $params = [
106
            'userid'        => $userid,
107
            'contextlevel1' => CONTEXT_SYSTEM,
108
            'contextlevel2' => CONTEXT_COURSECAT,
109
            'contextlevel3' => CONTEXT_COURSE,
110
        ];
111
 
112
        $contextlist = new contextlist();
113
        $contextlist->add_from_sql($sql, $params);
114
 
115
        return $contextlist;
116
    }
117
 
118
    /**
119
     * Get the list of users within a specific context.
120
     *
121
     * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
122
     */
123
    public static function get_users_in_context(userlist $userlist) {
124
        $context = $userlist->get_context();
125
 
126
        $allowedcontextlevels = [
127
            CONTEXT_SYSTEM,
128
            CONTEXT_COURSECAT,
129
            CONTEXT_COURSE,
130
        ];
131
 
132
        if (!in_array($context->contextlevel, $allowedcontextlevels)) {
133
            return;
134
        }
135
 
136
        $sql = "SELECT cb.usercreated as userid
137
                  FROM {contentbank_content} cb
138
                 WHERE cb.contextid = :contextid";
139
 
140
        $params = [
141
            'contextid' => $context->id
142
        ];
143
 
144
        $userlist->add_from_sql('userid', $sql, $params);
145
    }
146
 
147
    /**
148
     * Export all user data for the specified user, in the specified contexts.
149
     *
150
     * @param approved_contextlist $contextlist The approved contexts to export information for.
151
     */
152
    public static function export_user_data(approved_contextlist $contextlist) {
153
        global $DB;
154
 
155
        // Remove contexts different from SYSTEM, COURSECAT or COURSE.
156
        $contextids = array_reduce($contextlist->get_contexts(), function($carry, $context) {
157
            if ($context->contextlevel == CONTEXT_SYSTEM || $context->contextlevel == CONTEXT_COURSECAT
158
                || $context->contextlevel == CONTEXT_COURSE) {
159
                $carry[] = $context->id;
160
            }
161
            return $carry;
162
        }, []);
163
 
164
        if (empty($contextids)) {
165
            return;
166
        }
167
 
168
        $userid = $contextlist->get_user()->id;
169
 
170
        list($contextsql, $contextparams) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED);
171
        // Retrieve the contentbank_content records created for the user.
172
        $sql = "SELECT cb.id,
173
                       cb.name,
174
                       cb.contenttype,
175
                       cb.usercreated,
176
                       cb.usermodified,
177
                       cb.timecreated,
178
                       cb.timemodified,
179
                       cb.contextid
180
                  FROM {contentbank_content} cb
181
                 WHERE cb.usercreated = :userid
182
                       AND cb.contextid {$contextsql}
183
                 ORDER BY cb.contextid";
184
 
185
        $params = ['userid' => $userid] + $contextparams;
186
 
187
        $contents = $DB->get_recordset_sql($sql, $params);
188
        $data = [];
189
        $lastcontextid = null;
190
        $subcontext = [
191
            get_string('name', 'core_contentbank'),
192
        ];
193
        foreach ($contents as $content) {
194
            // The core_contentbank data export is organised in:
195
            // {Sytem|Course Category|Course Context Level}/Content/data.json.
196
            if ($lastcontextid && $lastcontextid != $content->contextid) {
197
                $context = \context::instance_by_id($lastcontextid);
198
                writer::with_context($context)->export_data($subcontext, (object)$data);
199
                $data = [];
200
            }
201
            $data[] = (object) [
202
                'name' => $content->name,
203
                'contenttype' => $content->contenttype,
204
                'usercreated' => transform::user($content->usercreated),
205
                'usermodified' => transform::user($content->usermodified),
206
                'timecreated' => transform::datetime($content->timecreated),
207
                'timemodified' => transform::datetime($content->timemodified)
208
            ];
209
            $lastcontextid = $content->contextid;
210
 
211
            // The core_contentbank files export is organised in:
212
            // {Sytem|Course Category|Course Context Level}/Content/_files/public/_itemid/filename.
213
            $context = \context::instance_by_id($lastcontextid);
214
            writer::with_context($context)->export_area_files($subcontext, 'contentbank', 'public', $content->id);
215
        }
216
        if (!empty($data)) {
217
            $context = \context::instance_by_id($lastcontextid);
218
            writer::with_context($context)->export_data($subcontext, (object)$data);
219
        }
220
        $contents->close();
221
    }
222
 
223
    /**
224
     * Delete all data for all users in the specified context.
225
     *
226
     * @param   context $context The specific context to delete data for.
227
     */
228
    public static function delete_data_for_all_users_in_context(\context $context) {
229
        global $DB;
230
 
231
        if (!$context instanceof context_system && !$context instanceof context_coursecat
232
                && !$context instanceof context_course) {
233
            return;
234
        }
235
 
236
        static::delete_data($context, []);
237
    }
238
 
239
    /**
240
     * Delete multiple users within a single context.
241
     *
242
     * @param approved_userlist $userlist The approved context and user information to delete information for.
243
     */
244
    public static function delete_data_for_users(approved_userlist $userlist) {
245
        $context = $userlist->get_context();
246
 
247
        if (!$context instanceof context_system && !$context instanceof context_coursecat
248
                && !$context instanceof context_course) {
249
            return;
250
        }
251
 
252
        static::delete_data($context, $userlist->get_userids());
253
    }
254
 
255
    /**
256
     * Delete all user data for the specified user, in the specified contexts.
257
     *
258
     * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
259
     */
260
    public static function delete_data_for_user(approved_contextlist $contextlist) {
261
        if (empty($contextlist->count())) {
262
            return;
263
        }
264
 
265
        $userid = $contextlist->get_user()->id;
266
        foreach ($contextlist->get_contexts() as $context) {
267
            if (!$context instanceof context_system && !$context instanceof context_coursecat
268
            && !$context instanceof context_course) {
269
                continue;
270
            }
271
            static::delete_data($context, [$userid]);
272
        }
273
    }
274
 
275
    /**
276
     * Delete data related to a context and users (if defined).
277
     *
278
     * @param context $context A context.
279
     * @param array $userids The user IDs.
280
     */
281
    protected static function delete_data(\context $context, array $userids) {
282
        global $DB;
283
 
284
        $params = ['contextid' => $context->id];
285
        $select = 'contextid = :contextid';
286
 
287
        // Delete the Content Bank files.
288
        if (!empty($userids)) {
289
            list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
290
            $params += $inparams;
291
            $select .= ' AND usercreated '.$insql;
292
        }
293
        $fs = get_file_storage();
294
        $contents = $DB->get_records_select('contentbank_content',
295
            $select, $params);
296
        foreach ($contents as $content) {
297
            $fs->delete_area_files($content->contextid, 'contentbank', 'public', $content->id);
298
        }
299
 
300
        // Delete all the contents.
301
        $DB->delete_records_select('contentbank_content', $select, $params);
302
    }
303
}