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
 * Privacy Subsystem implementation for core_enrol.
18
 *
19
 * @package    core_enrol
20
 * @copyright  2018 Carlos Escobedo <carlos@moodle.com>
21
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 */
23
 
24
namespace core_enrol\privacy;
25
 
26
defined('MOODLE_INTERNAL') || die();
27
 
28
use core_privacy\local\metadata\collection;
29
use core_privacy\local\request\approved_contextlist;
30
use core_privacy\local\request\context;
31
use core_privacy\local\request\contextlist;
32
use core_privacy\local\request\transform;
33
use core_privacy\local\request\writer;
34
use core_privacy\local\request\userlist;
35
use \core_privacy\local\request\approved_userlist;
36
 
37
/**
38
 * Privacy Subsystem for core_enrol implementing metadata and plugin providers.
39
 *
40
 * @copyright  2018 Carlos Escobedo <carlos@moodle.com>
41
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42
 */
43
class provider implements
44
        \core_privacy\local\metadata\provider,
45
        \core_privacy\local\request\core_userlist_provider,
46
        \core_privacy\local\request\subsystem\provider {
47
    /**
48
     * Returns meta data about this system.
49
     *
50
     * @param   collection $collection The initialised collection to add items to.
51
     * @return  collection     A listing of user data stored through this system.
52
     */
53
    public static function get_metadata(collection $collection): collection {
54
        $collection->add_database_table(
55
            'user_enrolments',
56
            [
57
                'status' => 'privacy:metadata:user_enrolments:status',
58
                'enrolid' => 'privacy:metadata:user_enrolments:enrolid',
59
                'userid' => 'privacy:metadata:user_enrolments:userid',
60
                'timestart' => 'privacy:metadata:user_enrolments:timestart',
61
                'timeend' => 'privacy:metadata:user_enrolments:timeend',
62
                'modifierid' => 'privacy:metadata:user_enrolments:modifierid',
63
                'timecreated' => 'privacy:metadata:user_enrolments:timecreated',
64
                'timemodified' => 'privacy:metadata:user_enrolments:timemodified'
65
            ],
66
            'privacy:metadata:user_enrolments:tableexplanation'
67
        );
68
 
69
        return $collection;
70
    }
71
    /**
72
     * Get the list of contexts that contain user information for the specified user.
73
     *
74
     * @param   int $userid The user to search.
75
     * @return  contextlist   $contextlist  The contextlist containing the list of contexts used in this plugin.
76
     */
77
    public static function get_contexts_for_userid(int $userid): contextlist {
78
        $sql = "SELECT ctx.id
79
                  FROM {user_enrolments} ue
80
                  JOIN {enrol} e
81
                    ON e.id = ue.enrolid
82
                   AND ue.userid = :userid
83
                  JOIN {context} ctx
84
                    ON ctx.instanceid = e.courseid
85
                   AND ctx.contextlevel = :contextlevel";
86
        $params = [
87
            'contextlevel' => CONTEXT_COURSE,
88
            'userid'       => $userid
89
        ];
90
        $contextlist = new contextlist();
91
        $contextlist->add_from_sql($sql, $params);
92
 
93
        return $contextlist;
94
    }
95
 
96
    /**
97
     * Get the list of users within a specific context.
98
     *
99
     * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
100
     */
101
    public static function get_users_in_context(userlist $userlist) {
102
        $context = $userlist->get_context();
103
 
104
        if (!$context instanceof \context_course) {
105
            return;
106
        }
107
 
108
        $sql = "SELECT ue.userid as userid
109
                  FROM {user_enrolments} ue
110
                  JOIN {enrol} e ON e.id = ue.enrolid
111
                 WHERE e.courseid = ?";
112
        $params = [$context->instanceid];
113
        $userlist->add_from_sql('userid', $sql, $params);
114
    }
115
 
116
    /**
117
     * Export all user data for the specified user, in the specified contexts.
118
     *
119
     * @param   approved_contextlist $contextlist The approved contexts to export information for.
120
     */
121
    public static function export_user_data(approved_contextlist $contextlist) {
122
        global $DB;
123
 
124
        if (empty($contextlist->count())) {
125
            return;
126
        }
127
        $userid = $contextlist->get_user()->id;
128
        list($insql, $inparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
129
        $params = [
130
            'contextlevel' => CONTEXT_COURSE,
131
            'userid' => $userid
132
         ];
133
        $params += $inparams;
134
        $sql = "SELECT ue.id,
135
                       ue.status,
136
                       ue.timestart,
137
                       ue.timeend,
138
                       ue.timecreated,
139
                       ue.timemodified,
140
                       e.enrol,
141
                       ctx.id as contextid
142
                  FROM {user_enrolments} ue
143
                  JOIN {enrol} e
144
                    ON e.id = ue.enrolid
145
                   AND ue.userid = :userid
146
                  JOIN {context} ctx
147
                    ON ctx.instanceid = e.courseid
148
                   AND ctx.contextlevel = :contextlevel
149
                 WHERE ctx.id $insql
150
                 ORDER BY ctx.id, e.enrol";
151
        $data = [];
152
        $lastcontextid = null;
153
        $lastenrol = null;
154
        $path = [get_string('privacy:metadata:user_enrolments', 'core_enrol')];
155
        $flush = function($lastcontextid, $lastenrol, $data) use ($path) {
156
            $context = \context::instance_by_id($lastcontextid);
157
            writer::with_context($context)->export_related_data(
158
                $path,
159
                $lastenrol,
160
                (object)$data
161
            );
162
        };
163
        $userenrolments = $DB->get_recordset_sql($sql, $params);
164
        foreach ($userenrolments as $userenrolment) {
165
            if (($lastcontextid && $lastcontextid != $userenrolment->contextid) ||
166
                    ($lastenrol && $lastenrol != $userenrolment->enrol)) {
167
                $flush($lastcontextid, $lastenrol, $data);
168
                $data = [];
169
            }
170
            $data[] = (object) [
171
                'status' => $userenrolment->status,
172
                'timecreated' => transform::datetime($userenrolment->timecreated),
173
                'timemodified' => transform::datetime($userenrolment->timemodified),
174
                'timestart' => transform::datetime($userenrolment->timestart),
175
                'timeend' => transform::datetime($userenrolment->timeend)
176
            ];
177
            $lastcontextid = $userenrolment->contextid;
178
            $lastenrol = $userenrolment->enrol;
179
        }
180
        if (!empty($data)) {
181
            $flush($lastcontextid, $lastenrol, $data);
182
        }
183
        $userenrolments->close();
184
    }
185
    /**
186
     * Delete all data for all users in the specified context.
187
     *
188
     * @param   \context $context The specific context to delete data for.
189
     */
190
    public static function delete_data_for_all_users_in_context(\context $context) {
191
        global $DB;
192
 
193
        // Sanity check that context is at the User context level.
194
        if ($context->contextlevel == CONTEXT_COURSE) {
195
            $sql = "SELECT ue.id
196
                      FROM {user_enrolments} ue
197
                      JOIN {enrol} e ON e.id = ue.enrolid
198
                     WHERE e.courseid = :courseid";
199
            $params = ['courseid' => $context->instanceid];
200
            $enrolsids = $DB->get_fieldset_sql($sql, $params);
201
            if (!empty($enrolsids)) {
202
                list($insql, $inparams) = $DB->get_in_or_equal($enrolsids, SQL_PARAMS_NAMED);
203
                static::delete_user_data($insql, $inparams);
204
            }
205
        }
206
    }
207
 
208
    /**
209
     * Delete multiple users within a single context.
210
     *
211
     * @param approved_userlist $userlist The approved context and user information to delete information for.
212
     */
213
    public static function delete_data_for_users(approved_userlist $userlist) {
214
        global $DB;
215
 
216
        $context = $userlist->get_context();
217
 
218
        if ($context instanceof \context_course) {
219
            list($usersql, $userparams) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED);
220
 
221
            $sql = "SELECT ue.id
222
                      FROM {user_enrolments} ue
223
                      JOIN {enrol} e ON e.id = ue.enrolid
224
                     WHERE e.courseid = :courseid
225
                           AND ue.userid {$usersql}";
226
 
227
            $params = ['courseid' => $context->instanceid] + $userparams;
228
            $enrolsids = $DB->get_fieldset_sql($sql, $params);
229
 
230
            if (!empty($enrolsids)) {
231
                list($insql, $inparams) = $DB->get_in_or_equal($enrolsids, SQL_PARAMS_NAMED);
232
                static::delete_user_data($insql, $inparams);
233
            }
234
        }
235
    }
236
 
237
    /**
238
     * Delete all user data for the specified user, in the specified contexts.
239
     *
240
     * @param   approved_contextlist $contextlist The approved contexts and user information to delete information for.
241
     */
242
    public static function delete_data_for_user(approved_contextlist $contextlist) {
243
        global $DB;
244
 
245
        if (empty($contextlist->count())) {
246
            return;
247
        }
248
        $userid = $contextlist->get_user()->id;
249
        list($insql, $inparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
250
        $params = [
251
            'contextlevel' => CONTEXT_COURSE,
252
            'userid' => $userid
253
         ];
254
        $params += $inparams;
255
        $sql = "SELECT ue.id
256
                  FROM {user_enrolments} ue
257
                  JOIN {enrol} e
258
                    ON e.id = ue.enrolid
259
                   AND ue.userid = :userid
260
                  JOIN {context} ctx
261
                    ON ctx.instanceid = e.courseid
262
                   AND ctx.contextlevel = :contextlevel
263
                 WHERE ctx.id $insql";
264
        $enrolsids = $DB->get_fieldset_sql($sql, $params);
265
        if (!empty($enrolsids)) {
266
            list($insql, $inparams) = $DB->get_in_or_equal($enrolsids, SQL_PARAMS_NAMED);
267
            static::delete_user_data($insql, $inparams);
268
        }
269
    }
270
 
271
    /**
272
     * Delete data from $tablename with the IDs returned by $sql query.
273
     *
274
     * @param  string $sql    SQL query for getting the IDs of the uer enrolments entries to delete.
275
     * @param  array  $params SQL params for the query.
276
     */
277
    protected static function delete_user_data(string $sql, array $params) {
278
        global $DB;
279
 
280
        $DB->delete_records_select('user_enrolments', "id $sql", $params);
281
    }
282
 
283
    /**
284
     * Get the subcontext for export.
285
     *
286
     * @param array $subcontext Any additional subcontext to use.
287
     * @return array The array containing the full subcontext, i.e. [enrolments, subcontext]
288
     */
289
    public static function get_subcontext(array $subcontext) {
290
        return array_merge(
291
            [get_string('privacy:metadata:user_enrolments', 'core_enrol')],
292
            $subcontext
293
        );
294
    }
295
}