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 enrol_paypal.
19
 *
20
 * @package    enrol_paypal
21
 * @category   privacy
22
 * @copyright  2018 Shamim Rezaie <shamim@moodle.com>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
namespace enrol_paypal\privacy;
27
 
28
defined('MOODLE_INTERNAL') || die();
29
 
30
use core_privacy\local\metadata\collection;
31
use core_privacy\local\request\approved_contextlist;
32
use core_privacy\local\request\approved_userlist;
33
use core_privacy\local\request\contextlist;
34
use core_privacy\local\request\userlist;
35
use core_privacy\local\request\writer;
36
 
37
/**
38
 * Privacy Subsystem implementation for enrol_paypal.
39
 *
40
 * @copyright  2018 Shamim Rezaie <shamim@moodle.com>
41
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42
 */
43
class provider implements
44
        // Transactions store user data.
45
        \core_privacy\local\metadata\provider,
46
 
47
        // The paypal enrolment plugin contains user's transactions.
48
        \core_privacy\local\request\plugin\provider,
49
 
50
        // This plugin is capable of determining which users have data within it.
51
        \core_privacy\local\request\core_userlist_provider {
52
 
53
    /**
54
     * Returns meta data about this system.
55
     *
56
     * @param collection $collection The initialised collection to add items to.
57
     * @return collection A listing of user data stored through this system.
58
     */
59
    public static function get_metadata(collection $collection): collection {
60
        $collection->add_external_location_link(
61
            'paypal.com',
62
            [
63
                'os0'        => 'privacy:metadata:enrol_paypal:paypal_com:os0',
64
                'custom'     => 'privacy:metadata:enrol_paypal:paypal_com:custom',
65
                'first_name' => 'privacy:metadata:enrol_paypal:paypal_com:first_name',
66
                'last_name'  => 'privacy:metadata:enrol_paypal:paypal_com:last_name',
67
                'address'    => 'privacy:metadata:enrol_paypal:paypal_com:address',
68
                'city'       => 'privacy:metadata:enrol_paypal:paypal_com:city',
69
                'email'      => 'privacy:metadata:enrol_paypal:paypal_com:email',
70
                'country'    => 'privacy:metadata:enrol_paypal:paypal_com:country',
71
            ],
72
            'privacy:metadata:enrol_paypal:paypal_com'
73
        );
74
 
75
        // The enrol_paypal has a DB table that contains user data.
76
        $collection->add_database_table(
77
                'enrol_paypal',
78
                [
79
                    'business'            => 'privacy:metadata:enrol_paypal:enrol_paypal:business',
80
                    'receiver_email'      => 'privacy:metadata:enrol_paypal:enrol_paypal:receiver_email',
81
                    'receiver_id'         => 'privacy:metadata:enrol_paypal:enrol_paypal:receiver_id',
82
                    'item_name'           => 'privacy:metadata:enrol_paypal:enrol_paypal:item_name',
83
                    'courseid'            => 'privacy:metadata:enrol_paypal:enrol_paypal:courseid',
84
                    'userid'              => 'privacy:metadata:enrol_paypal:enrol_paypal:userid',
85
                    'instanceid'          => 'privacy:metadata:enrol_paypal:enrol_paypal:instanceid',
86
                    'memo'                => 'privacy:metadata:enrol_paypal:enrol_paypal:memo',
87
                    'tax'                 => 'privacy:metadata:enrol_paypal:enrol_paypal:tax',
88
                    'option_selection1_x' => 'privacy:metadata:enrol_paypal:enrol_paypal:option_selection1_x',
89
                    'payment_status'      => 'privacy:metadata:enrol_paypal:enrol_paypal:payment_status',
90
                    'pending_reason'      => 'privacy:metadata:enrol_paypal:enrol_paypal:pending_reason',
91
                    'reason_code'         => 'privacy:metadata:enrol_paypal:enrol_paypal:reason_code',
92
                    'txn_id'              => 'privacy:metadata:enrol_paypal:enrol_paypal:txn_id',
93
                    'parent_txn_id'       => 'privacy:metadata:enrol_paypal:enrol_paypal:parent_txn_id',
94
                    'payment_type'        => 'privacy:metadata:enrol_paypal:enrol_paypal:payment_type',
95
                    'timeupdated'         => 'privacy:metadata:enrol_paypal:enrol_paypal:timeupdated'
96
                ],
97
                'privacy:metadata:enrol_paypal:enrol_paypal'
98
        );
99
 
100
        return $collection;
101
    }
102
 
103
    /**
104
     * Get the list of contexts that contain user information for the specified user.
105
     *
106
     * @param int $userid The user to search.
107
     * @return contextlist The contextlist containing the list of contexts used in this plugin.
108
     */
109
    public static function get_contexts_for_userid(int $userid): contextlist {
110
        $contextlist = new contextlist();
111
 
112
        // Values of ep.receiver_email and ep.business are already normalised to lowercase characters by PayPal,
113
        // therefore there is no need to use LOWER() on them in the following query.
114
        $sql = "SELECT ctx.id
115
                  FROM {enrol_paypal} ep
116
                  JOIN {enrol} e ON ep.instanceid = e.id
117
                  JOIN {context} ctx ON e.courseid = ctx.instanceid AND ctx.contextlevel = :contextcourse
118
                  JOIN {user} u ON u.id = ep.userid OR LOWER(u.email) = ep.receiver_email OR LOWER(u.email) = ep.business
119
                 WHERE u.id = :userid";
120
        $params = [
121
            'contextcourse' => CONTEXT_COURSE,
122
            'userid'        => $userid,
123
        ];
124
 
125
        $contextlist->add_from_sql($sql, $params);
126
 
127
        return $contextlist;
128
    }
129
 
130
    /**
131
     * Get the list of users who have data within a context.
132
     *
133
     * @param   userlist    $userlist   The userlist containing the list of users who have data in this context/plugin combination.
134
     */
135
    public static function get_users_in_context(userlist $userlist) {
136
        $context = $userlist->get_context();
137
 
138
        if (!$context instanceof \context_course) {
139
            return;
140
        }
141
 
142
        // Values of ep.receiver_email and ep.business are already normalised to lowercase characters by PayPal,
143
        // therefore there is no need to use LOWER() on them in the following query.
144
        $sql = "SELECT u.id
145
                  FROM {enrol_paypal} ep
146
                  JOIN {enrol} e ON ep.instanceid = e.id
147
                  JOIN {user} u ON ep.userid = u.id OR LOWER(u.email) = ep.receiver_email OR LOWER(u.email) = ep.business
148
                 WHERE e.courseid = :courseid";
149
        $params = ['courseid' => $context->instanceid];
150
 
151
        $userlist->add_from_sql('id', $sql, $params);
152
    }
153
 
154
    /**
155
     * Export all user data for the specified user, in the specified contexts.
156
     *
157
     * @param approved_contextlist $contextlist The approved contexts to export information for.
158
     */
159
    public static function export_user_data(approved_contextlist $contextlist) {
160
        global $DB;
161
 
162
        if (empty($contextlist->count())) {
163
            return;
164
        }
165
 
166
        $user = $contextlist->get_user();
167
 
168
        list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
169
 
170
        // Values of ep.receiver_email and ep.business are already normalised to lowercase characters by PayPal,
171
        // therefore there is no need to use LOWER() on them in the following query.
172
        $sql = "SELECT ep.*
173
                  FROM {enrol_paypal} ep
174
                  JOIN {enrol} e ON ep.instanceid = e.id
175
                  JOIN {context} ctx ON e.courseid = ctx.instanceid AND ctx.contextlevel = :contextcourse
176
                  JOIN {user} u ON u.id = ep.userid OR LOWER(u.email) = ep.receiver_email OR LOWER(u.email) = ep.business
177
                 WHERE ctx.id {$contextsql} AND u.id = :userid
178
              ORDER BY e.courseid";
179
 
180
        $params = [
181
            'contextcourse' => CONTEXT_COURSE,
182
            'userid'        => $user->id,
183
            'emailuserid'   => $user->id,
184
        ];
185
        $params += $contextparams;
186
 
187
        // Reference to the course seen in the last iteration of the loop. By comparing this with the current record, and
188
        // because we know the results are ordered, we know when we've moved to the PayPal transactions for a new course
189
        // and therefore when we can export the complete data for the last course.
190
        $lastcourseid = null;
191
 
192
        $strtransactions = get_string('transactions', 'enrol_paypal');
193
        $transactions = [];
194
        $paypalrecords = $DB->get_recordset_sql($sql, $params);
195
        foreach ($paypalrecords as $paypalrecord) {
196
            if ($lastcourseid != $paypalrecord->courseid) {
197
                if (!empty($transactions)) {
198
                    $coursecontext = \context_course::instance($paypalrecord->courseid);
199
                    writer::with_context($coursecontext)->export_data(
200
                            [$strtransactions],
201
                            (object) ['transactions' => $transactions]
202
                    );
203
                }
204
                $transactions = [];
205
            }
206
 
207
            $transaction = (object) [
208
                'receiver_id'         => $paypalrecord->receiver_id,
209
                'item_name'           => $paypalrecord->item_name,
210
                'userid'              => $paypalrecord->userid,
211
                'memo'                => $paypalrecord->memo,
212
                'tax'                 => $paypalrecord->tax,
213
                'option_name1'        => $paypalrecord->option_name1,
214
                'option_selection1_x' => $paypalrecord->option_selection1_x,
215
                'option_name2'        => $paypalrecord->option_name2,
216
                'option_selection2_x' => $paypalrecord->option_selection2_x,
217
                'payment_status'      => $paypalrecord->payment_status,
218
                'pending_reason'      => $paypalrecord->pending_reason,
219
                'reason_code'         => $paypalrecord->reason_code,
220
                'txn_id'              => $paypalrecord->txn_id,
221
                'parent_txn_id'       => $paypalrecord->parent_txn_id,
222
                'payment_type'        => $paypalrecord->payment_type,
223
                'timeupdated'         => \core_privacy\local\request\transform::datetime($paypalrecord->timeupdated),
224
            ];
225
            if ($paypalrecord->userid == $user->id) {
226
                $transaction->userid = $paypalrecord->userid;
227
            }
228
            if ($paypalrecord->business == \core_text::strtolower($user->email)) {
229
                $transaction->business = $paypalrecord->business;
230
            }
231
            if ($paypalrecord->receiver_email == \core_text::strtolower($user->email)) {
232
                $transaction->receiver_email = $paypalrecord->receiver_email;
233
            }
234
 
235
            $transactions[] = $paypalrecord;
236
 
237
            $lastcourseid = $paypalrecord->courseid;
238
        }
239
        $paypalrecords->close();
240
 
241
        // The data for the last activity won't have been written yet, so make sure to write it now!
242
        if (!empty($transactions)) {
243
            $coursecontext = \context_course::instance($paypalrecord->courseid);
244
            writer::with_context($coursecontext)->export_data(
245
                    [$strtransactions],
246
                    (object) ['transactions' => $transactions]
247
            );
248
        }
249
    }
250
 
251
    /**
252
     * Delete all data for all users in the specified context.
253
     *
254
     * @param \context $context The specific context to delete data for.
255
     */
256
    public static function delete_data_for_all_users_in_context(\context $context) {
257
        global $DB;
258
 
259
        if (!$context instanceof \context_course) {
260
            return;
261
        }
262
 
263
        $DB->delete_records('enrol_paypal', array('courseid' => $context->instanceid));
264
    }
265
 
266
    /**
267
     * Delete all user data for the specified user, in the specified contexts.
268
     *
269
     * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
270
     */
271
    public static function delete_data_for_user(approved_contextlist $contextlist) {
272
        global $DB;
273
 
274
        if (empty($contextlist->count())) {
275
            return;
276
        }
277
 
278
        $user = $contextlist->get_user();
279
 
280
        $contexts = $contextlist->get_contexts();
281
        $courseids = [];
282
        foreach ($contexts as $context) {
283
            if ($context instanceof \context_course) {
284
                $courseids[] = $context->instanceid;
285
            }
286
        }
287
 
288
        list($insql, $inparams) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED);
289
 
290
        $select = "userid = :userid AND courseid $insql";
291
        $params = $inparams + ['userid' => $user->id];
292
        $DB->delete_records_select('enrol_paypal', $select, $params);
293
 
294
        // We do not want to delete the payment record when the user is just the receiver of payment.
295
        // In that case, we just delete the receiver's info from the transaction record.
296
 
297
        $select = "business = :business AND courseid $insql";
298
        $params = $inparams + ['business' => \core_text::strtolower($user->email)];
299
        $DB->set_field_select('enrol_paypal', 'business', '', $select, $params);
300
 
301
        $select = "receiver_email = :receiver_email AND courseid $insql";
302
        $params = $inparams + ['receiver_email' => \core_text::strtolower($user->email)];
303
        $DB->set_field_select('enrol_paypal', 'receiver_email', '', $select, $params);
304
    }
305
 
306
    /**
307
     * Delete multiple users within a single context.
308
     *
309
     * @param   approved_userlist       $userlist The approved context and user information to delete information for.
310
     */
311
    public static function delete_data_for_users(approved_userlist $userlist) {
312
        global $DB;
313
 
314
        $context = $userlist->get_context();
315
 
316
        if ($context->contextlevel != CONTEXT_COURSE) {
317
            return;
318
        }
319
 
320
        $userids = $userlist->get_userids();
321
 
322
        list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
323
 
324
        $params = ['courseid' => $context->instanceid] + $userparams;
325
 
326
        $select = "courseid = :courseid AND userid $usersql";
327
        $DB->delete_records_select('enrol_paypal', $select, $params);
328
 
329
        // We do not want to delete the payment record when the user is just the receiver of payment.
330
        // In that case, we just delete the receiver's info from the transaction record.
331
 
332
        $select = "courseid = :courseid AND business IN (SELECT LOWER(email) FROM {user} WHERE id $usersql)";
333
        $DB->set_field_select('enrol_paypal', 'business', '', $select, $params);
334
 
335
        $select = "courseid = :courseid AND receiver_email IN (SELECT LOWER(email) FROM {user} WHERE id $usersql)";
336
        $DB->set_field_select('enrol_paypal', 'receiver_email', '', $select, $params);
337
    }
338
}