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 Subsystem implementation for core_notes.
19
 *
20
 * @package    core_notes
21
 * @copyright  2018 Zig Tan <zig@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace core_notes\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
 
35
defined('MOODLE_INTERNAL') || die();
36
 
37
global $CFG;
38
require_once($CFG->dirroot . '/notes/lib.php');
39
 
40
/**
41
 * Implementation of the privacy subsystem plugin provider for core_notes.
42
 *
43
 * @copyright  2018 Zig Tan <zig@moodle.com>
44
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45
 */
46
class provider implements
47
        \core_privacy\local\metadata\provider,
48
        \core_privacy\local\request\core_userlist_provider,
49
        \core_privacy\local\request\plugin\provider {
50
 
51
    /**
52
     * Return the fields which contain personal data.
53
     *
54
     * @param collection $items a reference to the collection to use to store the metadata.
55
     * @return collection the updated collection of metadata items.
56
     */
57
    public static function get_metadata(collection $items): collection {
58
        // The core_notes components utilises the shared mdl_post table.
59
        $items->add_database_table(
60
            'post',
61
            [
62
                'content' => 'privacy:metadata:core_notes:content',
63
                'courseid' => 'privacy:metadata:core_notes:courseid',
64
                'created' => 'privacy:metadata:core_notes:created',
65
                'lastmodified' => 'privacy:metadata:core_notes:lastmodified',
66
                'publishstate' => 'privacy:metadata:core_notes:publishstate',
67
                'userid' => 'privacy:metadata:core_notes:userid'
68
            ],
69
            'privacy:metadata:core_notes'
70
        );
71
 
72
        return $items;
73
    }
74
 
75
    /**
76
     * Get the list of contexts that contain user information for the specified user.
77
     *
78
     * @param int $userid the userid.
79
     * @return contextlist the list of contexts containing user info for the user.
80
     */
81
    public static function get_contexts_for_userid(int $userid): contextlist {
82
        global $DB;
83
 
84
        $contextlist = new contextlist();
85
 
86
        $publishstates = [
87
            NOTES_STATE_PUBLIC,
88
            NOTES_STATE_SITE
89
        ];
90
        list($publishstatesql, $publishstateparams) = $DB->get_in_or_equal($publishstates, SQL_PARAMS_NAMED);
91
 
92
        // Retrieve all the Course contexts associated with notes written by the user, and also written about the user.
93
        // Only notes written about the user that are public or site wide will be exported.
94
        $sql = "SELECT c.id
95
                  FROM {context} c
96
            INNER JOIN {post} p ON p.courseid = c.instanceid AND c.contextlevel = :contextcoursewrittenby
97
                 WHERE p.module = 'notes'
98
                   AND p.usermodified = :usermodified";
99
 
100
        $params = [
101
            'contextcoursewrittenby'  => CONTEXT_COURSE,
102
            'usermodified'            => $userid,
103
        ];
104
 
105
        $contextlist->add_from_sql($sql, $params);
106
 
107
        $sql = "SELECT c.id
108
                  FROM {context} c
109
            INNER JOIN {post} p ON p.courseid = c.instanceid AND c.contextlevel = :contextcoursewrittenfor
110
                 WHERE p.module = 'notes'
111
                   AND p.userid = :userid
112
                   AND p.publishstate {$publishstatesql}";
113
 
114
        $params = [
115
            'contextcoursewrittenfor' => CONTEXT_COURSE,
116
            'userid'                  => $userid
117
        ];
118
        $params += $publishstateparams;
119
 
120
        $contextlist->add_from_sql($sql, $params);
121
 
122
        return $contextlist;
123
    }
124
 
125
    /**
126
     * Get the list of users who have data within a context.
127
     *
128
     * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
129
     */
130
    public static function get_users_in_context(userlist $userlist) {
131
        global $DB;
132
 
133
        $context = $userlist->get_context();
134
 
135
        if (!$context instanceof \context_course) {
136
            return;
137
        }
138
 
139
        $params = [
140
            'instanceid' => $context->instanceid
141
        ];
142
 
143
        $sql = "SELECT usermodified as userid
144
                  FROM {post}
145
                 WHERE module = 'notes'
146
                       AND courseid = :instanceid";
147
 
148
        $userlist->add_from_sql('userid', $sql, $params);
149
 
150
        $publishstates = [
151
            NOTES_STATE_PUBLIC,
152
            NOTES_STATE_SITE
153
        ];
154
 
155
        list($publishstatesql, $publishstateparams) = $DB->get_in_or_equal($publishstates, SQL_PARAMS_NAMED);
156
        $params += $publishstateparams;
157
 
158
        $sql = "SELECT userid
159
                  FROM {post}
160
                 WHERE module = 'notes'
161
                       AND courseid = :instanceid
162
                       AND publishstate {$publishstatesql}";
163
 
164
        $userlist->add_from_sql('userid', $sql, $params);
165
    }
166
 
167
    /**
168
     * Export personal data for the given approved_contextlist.
169
     * User and context information is contained within the contextlist.
170
     *
171
     * @param approved_contextlist $contextlist a list of contexts approved for export.
172
     */
173
    public static function export_user_data(approved_contextlist $contextlist) {
174
        global $DB;
175
 
176
        if (empty($contextlist->count())) {
177
            return;
178
        }
179
 
180
        $userid = $contextlist->get_user()->id;
181
 
182
        list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
183
 
184
        // Export all notes written by and written about the user, and organize it by the associated Course context(s).
185
        $sql = "SELECT p.courseid as courseid,
186
                       p.content as content,
187
                       p.publishstate as publishstate,
188
                       p.userid as userid,
189
                       p.usermodified as usermodified,
190
                       p.created as datecreated,
191
                       p.lastmodified as datemodified
192
                  FROM {context} c
193
            INNER JOIN {post} p ON p.courseid = c.instanceid AND c.contextlevel = :contextcourse
194
                 WHERE p.module = 'notes'
195
                   AND (p.usermodified = :usermodified OR p.userid = :userid)
196
                   AND c.id {$contextsql}";
197
 
198
        $params = [
199
            'contextcourse' => CONTEXT_COURSE,
200
            'usermodified'  => $userid,
201
            'userid'        => $userid
202
        ];
203
        $params += $contextparams;
204
 
205
        $notes = $DB->get_recordset_sql($sql, $params);
206
        foreach ($notes as $note) {
207
            $contextcourse = \context_course::instance($note->courseid);
208
 
209
            // The exported notes will be organized in {Course Context}/Notes/{publishstate}/usernote-{userid}.json.
210
            $subcontext = [
211
                get_string('notes', 'notes'),
212
                $note->publishstate
213
            ];
214
 
215
            $name = 'usernote-' . transform::user($note->userid);
216
 
217
            $notecontent = (object) [
218
               'content' => $note->content,
219
               'publishstate' => $note->publishstate,
220
               'userid' => transform::user($note->userid),
221
               'usermodified' => transform::user($note->usermodified),
222
               'datecreated' => transform::datetime($note->datecreated),
223
               'datemodified' => transform::datetime($note->datemodified)
224
            ];
225
 
226
            writer::with_context($contextcourse)->export_related_data($subcontext, $name, $notecontent);
227
        }
228
        $notes->close();
229
    }
230
 
231
    /**
232
     * Delete all data for all users in the specified context.
233
     *
234
     * @param \context $context the context to delete in.
235
     */
236
    public static function delete_data_for_all_users_in_context(\context $context) {
237
        global $DB;
238
 
239
        if ($context->contextlevel != CONTEXT_COURSE) {
240
            return;
241
        }
242
 
243
        $DB->delete_records('post', ['module' => 'notes', 'courseid' => $context->instanceid]);
244
    }
245
 
246
    /**
247
     * Delete multiple users within a single context.
248
     *
249
     * @param approved_userlist $userlist The approved context and user information to delete information for.
250
     */
251
    public static function delete_data_for_users(approved_userlist $userlist) {
252
        global $DB;
253
 
254
        $context = $userlist->get_context();
255
        if ($context->contextlevel != CONTEXT_COURSE) {
256
            return;
257
        }
258
 
259
        $userids = $userlist->get_userids();
260
        if (empty($userids)) {
261
            return;
262
        }
263
 
264
        list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
265
        $select = "module = :module AND courseid = :courseid AND usermodified {$usersql}";
266
        $params = ['module' => 'notes', 'courseid' => $context->instanceid] + $userparams;
267
 
268
        $DB->delete_records_select('post', $select, $params);
269
    }
270
 
271
    /**
272
     * Delete all user data for the specified user, in the specified contexts.
273
     *
274
     * @param approved_contextlist $contextlist a list of contexts approved for deletion.
275
     */
276
    public static function delete_data_for_user(approved_contextlist $contextlist) {
277
        global $DB;
278
 
279
        if (empty($contextlist->count())) {
280
            return;
281
        }
282
 
283
        $userid = $contextlist->get_user()->id;
284
 
285
        foreach ($contextlist->get_contexts() as $context) {
286
            $conditions = [
287
                'module'        => 'notes',
288
                'courseid'      => $context->instanceid,
289
                'usermodified'  => $userid
290
            ];
291
 
292
            $DB->delete_records('post', $conditions);
293
        }
294
    }
295
}