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 tool_policy.
19
 *
20
 * @package    tool_policy
21
 * @copyright  2018 Sara Arjona <sara@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace tool_policy\privacy;
26
 
27
use core_privacy\local\metadata\collection;
28
use core_privacy\local\request\approved_contextlist;
29
use core_privacy\local\request\approved_userlist;
30
use core_privacy\local\request\contextlist;
31
use core_privacy\local\request\moodle_content_writer;
32
use core_privacy\local\request\userlist;
33
use core_privacy\local\request\transform;
34
use core_privacy\local\request\writer;
35
 
36
defined('MOODLE_INTERNAL') || die();
37
 
38
/**
39
 * Implementation of the privacy subsystem plugin provider for the policy tool.
40
 *
41
 * @copyright  2018 Sara Arjona <sara@moodle.com>
42
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43
 */
44
class provider implements
45
        // This tool stores user data.
46
        \core_privacy\local\metadata\provider,
47
 
48
        // This plugin is capable of determining which users have data within it.
49
        \core_privacy\local\request\core_userlist_provider,
50
 
51
        // This tool may provide access to and deletion of user data.
52
        \core_privacy\local\request\plugin\provider {
53
 
54
    /**
55
     * Return the fields which contain personal data.
56
     *
57
     * @param   collection $collection The initialised collection to add items to.
58
     * @return  collection A listing of user data stored through this system.
59
     */
60
    public static function get_metadata(collection $collection): collection {
61
        $collection->add_database_table(
62
            'tool_policy_acceptances',
63
            [
64
                'policyversionid' => 'privacy:metadata:acceptances:policyversionid',
65
                'userid' => 'privacy:metadata:acceptances:userid',
66
                'status' => 'privacy:metadata:acceptances:status',
67
                'lang' => 'privacy:metadata:acceptances:lang',
68
                'usermodified' => 'privacy:metadata:acceptances:usermodified',
69
                'timecreated' => 'privacy:metadata:acceptances:timecreated',
70
                'timemodified' => 'privacy:metadata:acceptances:timemodified',
71
                'note' => 'privacy:metadata:acceptances:note',
72
            ],
73
            'privacy:metadata:acceptances'
74
        );
75
 
76
        $collection->add_database_table(
77
            'tool_policy_versions',
78
            [
79
                'name' => 'privacy:metadata:versions:name',
80
                'type' => 'privacy:metadata:versions:type',
81
                'audience' => 'privacy:metadata:versions:audience',
82
                'archived' => 'privacy:metadata:versions:archived',
83
                'usermodified' => 'privacy:metadata:versions:usermodified',
84
                'timecreated' => 'privacy:metadata:versions:timecreated',
85
                'timemodified' => 'privacy:metadata:versions:timemodified',
86
                'policyid' => 'privacy:metadata:versions:policyid',
87
                'revision' => 'privacy:metadata:versions:revision',
88
                'summary' => 'privacy:metadata:versions:summary',
89
                'summaryformat' => 'privacy:metadata:versions:summaryformat',
90
                'content' => 'privacy:metadata:versions:content',
91
                'contentformat' => 'privacy:metadata:versions:contentformat',
92
            ],
93
            'privacy:metadata:versions'
94
        );
95
 
96
        $collection->add_subsystem_link('core_files', [], 'privacy:metadata:subsystem:corefiles');
97
 
98
        return $collection;
99
    }
100
 
101
    /**
102
     * Get the list of contexts that contain user information for the specified user.
103
     *
104
     * @param int $userid The userid.
105
     * @return contextlist The list of contexts containing user info for the user.
106
     */
107
    public static function get_contexts_for_userid(int $userid): contextlist {
108
        $contextlist = new contextlist();
109
 
110
        // Policies a user has modified.
111
        $sql = "SELECT c.id
112
                  FROM {context} c
113
                  JOIN {tool_policy_versions} v ON v.usermodified = :userid
114
                 WHERE c.contextlevel = :contextlevel";
115
        $params = [
116
            'contextlevel' => CONTEXT_SYSTEM,
117
            'userid' => $userid,
118
        ];
119
        $contextlist->add_from_sql($sql, $params);
120
 
121
        // Policies a user has accepted.
122
        $sql = "SELECT c.id
123
                  FROM {context} c
124
                  JOIN {tool_policy_acceptances} a ON c.instanceid = a.userid
125
                 WHERE
126
                    c.contextlevel = :contextlevel
127
                   AND (
128
                    a.userid = :userid OR a.usermodified = :usermodified
129
                   )";
130
        $params = [
131
            'contextlevel' => CONTEXT_USER,
132
            'userid' => $userid,
133
            'usermodified' => $userid,
134
        ];
135
        $contextlist->add_from_sql($sql, $params);
136
 
137
        return $contextlist;
138
    }
139
 
140
    /**
141
     * Get the list of users who have data within a context.
142
     *
143
     * @param   userlist    $userlist   The userlist containing the list of users who have data in this context/plugin combination.
144
     */
145
    public static function get_users_in_context(userlist $userlist) {
146
        $context = $userlist->get_context();
147
 
148
        // Users that have modified any policies, if fetching for system context.
149
        if (is_a($context, \context_system::class)) {
150
            $sql = "SELECT v.usermodified AS userid
151
                      FROM {tool_policy_versions} v";
152
            $userlist->add_from_sql('userid', $sql, []);
153
        }
154
 
155
        // Users that have accepted any policies, if fetching for user context.
156
        if (is_a($context, \context_user::class)) {
157
            $sql = "SELECT a.userid, a.usermodified
158
                      FROM {tool_policy_acceptances} a
159
                     WHERE a.userid = :instanceid";
160
            $params = ['instanceid' => $context->instanceid];
161
 
162
            $userlist->add_from_sql('userid', $sql, $params);
163
            $userlist->add_from_sql('usermodified', $sql, $params);
164
        }
165
    }
166
 
167
    /**
168
     * Export personal data for the given approved_contextlist. User and context information is contained within the contextlist.
169
     *
170
     * @param approved_contextlist $contextlist A list of contexts approved for export.
171
     */
172
    public static function export_user_data(approved_contextlist $contextlist) {
173
        global $DB;
174
 
175
        // Export user agreements.
176
        foreach ($contextlist->get_contexts() as $context) {
177
            if ($context->contextlevel == CONTEXT_USER) {
178
                static::export_policy_agreements_for_context($context);
179
            } else if ($context->contextlevel == CONTEXT_SYSTEM) {
180
                static::export_authored_policies($contextlist->get_user());
181
            }
182
        }
183
    }
184
 
185
    /**
186
     * Delete all data for all users in the specified context.
187
     *
188
     * We never delete user agreements to the policies because they are part of privacy data.
189
     * We never delete policy versions because they are part of privacy data.
190
     *
191
     * @param \context $context The context to delete in.
192
     */
193
    public static function delete_data_for_all_users_in_context(\context $context) {
194
    }
195
 
196
    /**
197
     * Delete all user data for the specified user, in the specified contexts.
198
     *
199
     * We never delete user agreements to the policies because they are part of privacy data.
200
     * We never delete policy versions because they are part of privacy data.
201
     *
202
     * @param approved_contextlist $contextlist A list of contexts approved for deletion.
203
     */
204
    public static function delete_data_for_user(approved_contextlist $contextlist) {
205
    }
206
 
207
    /**
208
     * Delete multiple users within a single context.
209
     *
210
     * We never delete user agreements to the policies because they are part of privacy data.
211
     * We never delete policy versions because they are part of privacy data.
212
     *
213
     * @param   approved_userlist       $userlist The approved context and user information to delete information for.
214
     */
215
    public static function delete_data_for_users(approved_userlist $userlist) {
216
    }
217
 
218
    /**
219
     * Export all policy agreements relating to the specified user context.
220
     *
221
     * @param \context_user $context The context to export
222
     */
223
    protected static function export_policy_agreements_for_context(\context_user $context) {
224
        global $DB;
225
 
226
        $sysctx = \context_system::instance();
227
        $fs = get_file_storage();
228
        $agreementsql = "
229
            SELECT
230
                a.id AS agreementid, a.userid, a.timemodified, a.note, a.status,
231
                a.policyversionid AS versionid, a.usermodified, a.timecreated,
232
                v.id, v.archived, v.name, v.revision,
233
                v.summary, v.summaryformat,
234
                v.content, v.contentformat,
235
                p.currentversionid
236
             FROM {tool_policy_acceptances} a
237
             JOIN {tool_policy_versions} v ON v.id = a.policyversionid
238
             JOIN {tool_policy} p ON v.policyid = p.id
239
            WHERE a.userid = :userid OR a.usermodified = :usermodified";
240
 
241
        // Fetch all agreements related to this user.
242
        $agreements = $DB->get_recordset_sql($agreementsql, [
243
            'userid' => $context->instanceid,
244
            'usermodified' => $context->instanceid,
245
        ]);
246
 
247
        $basecontext = [
248
            get_string('privacyandpolicies', 'admin'),
249
            get_string('useracceptances', 'tool_policy'),
250
        ];
251
 
252
        foreach ($agreements as $agreement) {
253
            $subcontext = array_merge($basecontext, [get_string('policynamedversion', 'tool_policy', $agreement)]);
254
 
255
            $summary = writer::with_context($context)->rewrite_pluginfile_urls(
256
                $subcontext,
257
                'tool_policy',
258
                'policydocumentsummary',
259
                $agreement->versionid,
260
                $agreement->summary
261
            );
262
            $content = writer::with_context($context)->rewrite_pluginfile_urls(
263
                $subcontext,
264
                'tool_policy',
265
                'policydocumentcontent',
266
                $agreement->versionid,
267
                $agreement->content
268
            );
269
            $agreementcontent = (object) [
270
                'name' => $agreement->name,
271
                'revision' => $agreement->revision,
272
                'isactive' => transform::yesno($agreement->versionid == $agreement->currentversionid),
273
                'isagreed' => transform::yesno($agreement->status),
274
                'agreedby' => transform::user($agreement->usermodified),
275
                'timecreated' => transform::datetime($agreement->timecreated),
276
                'timemodified' => transform::datetime($agreement->timemodified),
277
                'note' => $agreement->note,
278
                'summary' => format_text($summary, $agreement->summaryformat),
279
                'content' => format_text($content, $agreement->contentformat),
280
            ];
281
 
282
            writer::with_context($context)->export_data($subcontext, $agreementcontent);
283
            // Manually export the files as they reside in the system context so we can't use
284
            // the write's helper methods.
285
            foreach ($fs->get_area_files($sysctx->id, 'tool_policy', 'policydocumentsummary', $agreement->versionid) as $file) {
286
                writer::with_context($context)->export_file($subcontext, $file);
287
            }
288
            foreach ($fs->get_area_files($sysctx->id, 'tool_policy', 'policydocumentcontent', $agreement->versionid) as $file) {
289
                writer::with_context($context)->export_file($subcontext, $file);
290
            }
291
        }
292
        $agreements->close();
293
    }
294
 
295
    /**
296
     * Export all policy agreements that the user authored.
297
     *
298
     * @param stdClass $user The user who has created the policies to export.
299
     */
300
    protected static function export_authored_policies(\stdClass $user) {
301
        global $DB;
302
 
303
        // Authored policies are exported against the system.
304
        $context = \context_system::instance();
305
        $basecontext = [
306
            get_string('policydocuments', 'tool_policy'),
307
        ];
308
 
309
        $sql = "SELECT v.id,
310
                       v.name,
311
                       v.revision,
312
                       v.summary,
313
                       v.content,
314
                       v.archived,
315
                       v.usermodified,
316
                       v.timecreated,
317
                       v.timemodified,
318
                       p.currentversionid
319
                  FROM {tool_policy_versions} v
320
                  JOIN {tool_policy} p ON p.id = v.policyid
321
                 WHERE v.usermodified = :userid";
322
        $versions = $DB->get_recordset_sql($sql, ['userid' => $user->id]);
323
        foreach ($versions as $version) {
324
            $subcontext = array_merge($basecontext, [get_string('policynamedversion', 'tool_policy', $version)]);
325
 
326
            $versioncontent = (object) [
327
                'name' => $version->name,
328
                'revision' => $version->revision,
329
                'summary' => writer::with_context($context)->rewrite_pluginfile_urls(
330
                    $subcontext,
331
                    'tool_policy',
332
                    'policydocumentsummary',
333
                    $version->id,
334
                    $version->summary
335
                ),
336
                'content' => writer::with_context($context)->rewrite_pluginfile_urls(
337
                    $subcontext,
338
                    'tool_policy',
339
                    'policydocumentcontent',
340
                    $version->id,
341
                    $version->content
342
                ),
343
                'isactive' => transform::yesno($version->id == $version->currentversionid),
344
                'isarchived' => transform::yesno($version->archived),
345
                'createdbyme' => transform::yesno($version->usermodified == $user->id),
346
                'timecreated' => transform::datetime($version->timecreated),
347
                'timemodified' => transform::datetime($version->timemodified),
348
            ];
349
            writer::with_context($context)
350
                ->export_data($subcontext, $versioncontent)
351
                ->export_area_files($subcontext, 'tool_policy', 'policydocumentsummary', $version->id)
352
                ->export_area_files($subcontext, 'tool_policy', 'policydocumentcontent', $version->id);
353
        }
354
        $versions->close();
355
    }
356
}