PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/enrol/paypal/classes/privacy/provider.php

https://gitlab.com/unofficial-mirrors/moodle
PHP | 286 lines | 184 code | 36 blank | 66 comment | 15 complexity | 9464ce001ed3e3515a197b0bffe8e895 MD5 | raw file
  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 enrol_paypal.
  18. *
  19. * @package enrol_paypal
  20. * @category privacy
  21. * @copyright 2018 Shamim Rezaie <shamim@moodle.com>
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. namespace enrol_paypal\privacy;
  25. defined('MOODLE_INTERNAL') || die();
  26. use core_privacy\local\metadata\collection;
  27. use core_privacy\local\request\approved_contextlist;
  28. use core_privacy\local\request\contextlist;
  29. use core_privacy\local\request\helper;
  30. use core_privacy\local\request\writer;
  31. /**
  32. * Privacy Subsystem implementation for enrol_paypal.
  33. *
  34. * @copyright 2018 Shamim Rezaie <shamim@moodle.com>
  35. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36. */
  37. class provider implements
  38. \core_privacy\local\metadata\provider,
  39. \core_privacy\local\request\plugin\provider {
  40. /**
  41. * Returns meta data about this system.
  42. *
  43. * @param collection $collection The initialised collection to add items to.
  44. * @return collection A listing of user data stored through this system.
  45. */
  46. public static function get_metadata(collection $collection) : collection {
  47. $collection->add_external_location_link(
  48. 'paypal.com',
  49. [
  50. 'os0' => 'privacy:metadata:enrol_paypal:paypal_com:os0',
  51. 'custom' => 'privacy:metadata:enrol_paypal:paypal_com:custom',
  52. 'first_name' => 'privacy:metadata:enrol_paypal:paypal_com:first_name',
  53. 'last_name' => 'privacy:metadata:enrol_paypal:paypal_com:last_name',
  54. 'address' => 'privacy:metadata:enrol_paypal:paypal_com:address',
  55. 'city' => 'privacy:metadata:enrol_paypal:paypal_com:city',
  56. 'email' => 'privacy:metadata:enrol_paypal:paypal_com:email',
  57. 'country' => 'privacy:metadata:enrol_paypal:paypal_com:country',
  58. ],
  59. 'privacy:metadata:enrol_paypal:paypal_com'
  60. );
  61. // The enrol_paypal has a DB table that contains user data.
  62. $collection->add_database_table(
  63. 'enrol_paypal',
  64. [
  65. 'business' => 'privacy:metadata:enrol_paypal:enrol_paypal:business',
  66. 'receiver_email' => 'privacy:metadata:enrol_paypal:enrol_paypal:receiver_email',
  67. 'receiver_id' => 'privacy:metadata:enrol_paypal:enrol_paypal:receiver_id',
  68. 'item_name' => 'privacy:metadata:enrol_paypal:enrol_paypal:item_name',
  69. 'courseid' => 'privacy:metadata:enrol_paypal:enrol_paypal:courseid',
  70. 'userid' => 'privacy:metadata:enrol_paypal:enrol_paypal:userid',
  71. 'instanceid' => 'privacy:metadata:enrol_paypal:enrol_paypal:instanceid',
  72. 'memo' => 'privacy:metadata:enrol_paypal:enrol_paypal:memo',
  73. 'tax' => 'privacy:metadata:enrol_paypal:enrol_paypal:tax',
  74. 'option_selection1_x' => 'privacy:metadata:enrol_paypal:enrol_paypal:option_selection1_x',
  75. 'payment_status' => 'privacy:metadata:enrol_paypal:enrol_paypal:payment_status',
  76. 'pending_reason' => 'privacy:metadata:enrol_paypal:enrol_paypal:pending_reason',
  77. 'reason_code' => 'privacy:metadata:enrol_paypal:enrol_paypal:reason_code',
  78. 'txn_id' => 'privacy:metadata:enrol_paypal:enrol_paypal:txn_id',
  79. 'parent_txn_id' => 'privacy:metadata:enrol_paypal:enrol_paypal:parent_txn_id',
  80. 'payment_type' => 'privacy:metadata:enrol_paypal:enrol_paypal:payment_type',
  81. 'timeupdated' => 'privacy:metadata:enrol_paypal:enrol_paypal:timeupdated'
  82. ],
  83. 'privacy:metadata:enrol_paypal:enrol_paypal'
  84. );
  85. return $collection;
  86. }
  87. /**
  88. * Get the list of contexts that contain user information for the specified user.
  89. *
  90. * @param int $userid The user to search.
  91. * @return contextlist The contextlist containing the list of contexts used in this plugin.
  92. */
  93. public static function get_contexts_for_userid(int $userid) : contextlist {
  94. $contextlist = new contextlist();
  95. // Values of ep.receiver_email and ep.business are already normalised to lowercase characters by PayPal,
  96. // therefore there is no need to use LOWER() on them in the following query.
  97. $sql = "SELECT ctx.id
  98. FROM {enrol_paypal} ep
  99. JOIN {enrol} e ON ep.instanceid = e.id
  100. JOIN {context} ctx ON e.courseid = ctx.instanceid AND ctx.contextlevel = :contextcourse
  101. LEFT JOIN {user} u ON u.id = :emailuserid AND (
  102. LOWER(u.email) = ep.receiver_email
  103. OR
  104. LOWER(u.email) = ep.business
  105. )
  106. WHERE ep.userid = :userid
  107. OR u.id IS NOT NULL";
  108. $params = [
  109. 'contextcourse' => CONTEXT_COURSE,
  110. 'userid' => $userid,
  111. 'emailuserid' => $userid,
  112. ];
  113. $contextlist->add_from_sql($sql, $params);
  114. return $contextlist;
  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. if (empty($contextlist->count())) {
  124. return;
  125. }
  126. $user = $contextlist->get_user();
  127. list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
  128. // Values of ep.receiver_email and ep.business are already normalised to lowercase characters by PayPal,
  129. // therefore there is no need to use LOWER() on them in the following query.
  130. $sql = "SELECT ep.*
  131. FROM {enrol_paypal} ep
  132. JOIN {enrol} e ON ep.instanceid = e.id
  133. JOIN {context} ctx ON e.courseid = ctx.instanceid AND ctx.contextlevel = :contextcourse
  134. LEFT JOIN {user} u ON u.id = :emailuserid AND (
  135. LOWER(u.email) = ep.receiver_email
  136. OR
  137. LOWER(u.email) = ep.business
  138. )
  139. WHERE ctx.id {$contextsql}
  140. AND (ep.userid = :userid
  141. OR u.id IS NOT NULL)
  142. ORDER BY e.courseid";
  143. $params = [
  144. 'contextcourse' => CONTEXT_COURSE,
  145. 'userid' => $user->id,
  146. 'emailuserid' => $user->id,
  147. ];
  148. $params += $contextparams;
  149. // Reference to the course seen in the last iteration of the loop. By comparing this with the current record, and
  150. // because we know the results are ordered, we know when we've moved to the PayPal transactions for a new course
  151. // and therefore when we can export the complete data for the last course.
  152. $lastcourseid = null;
  153. $strtransactions = get_string('transactions', 'enrol_paypal');
  154. $transactions = [];
  155. $paypalrecords = $DB->get_recordset_sql($sql, $params);
  156. foreach ($paypalrecords as $paypalrecord) {
  157. if ($lastcourseid != $paypalrecord->courseid) {
  158. if (!empty($transactions)) {
  159. $coursecontext = \context_course::instance($paypalrecord->courseid);
  160. writer::with_context($coursecontext)->export_data(
  161. [$strtransactions],
  162. (object) ['transactions' => $transactions]
  163. );
  164. }
  165. $transactions = [];
  166. }
  167. $transaction = (object) [
  168. 'receiver_id' => $paypalrecord->receiver_id,
  169. 'item_name' => $paypalrecord->item_name,
  170. 'userid' => $paypalrecord->userid,
  171. 'memo' => $paypalrecord->memo,
  172. 'tax' => $paypalrecord->tax,
  173. 'option_name1' => $paypalrecord->option_name1,
  174. 'option_selection1_x' => $paypalrecord->option_selection1_x,
  175. 'option_name2' => $paypalrecord->option_name2,
  176. 'option_selection2_x' => $paypalrecord->option_selection2_x,
  177. 'payment_status' => $paypalrecord->payment_status,
  178. 'pending_reason' => $paypalrecord->pending_reason,
  179. 'reason_code' => $paypalrecord->reason_code,
  180. 'txn_id' => $paypalrecord->txn_id,
  181. 'parent_txn_id' => $paypalrecord->parent_txn_id,
  182. 'payment_type' => $paypalrecord->payment_type,
  183. 'timeupdated' => \core_privacy\local\request\transform::datetime($paypalrecord->timeupdated),
  184. ];
  185. if ($paypalrecord->userid == $user->id) {
  186. $transaction->userid = $paypalrecord->userid;
  187. }
  188. if ($paypalrecord->business == \core_text::strtolower($user->email)) {
  189. $transaction->business = $paypalrecord->business;
  190. }
  191. if ($paypalrecord->receiver_email == \core_text::strtolower($user->email)) {
  192. $transaction->receiver_email = $paypalrecord->receiver_email;
  193. }
  194. $transactions[] = $paypalrecord;
  195. $lastcourseid = $paypalrecord->courseid;
  196. }
  197. $paypalrecords->close();
  198. // The data for the last activity won't have been written yet, so make sure to write it now!
  199. if (!empty($transactions)) {
  200. $coursecontext = \context_course::instance($paypalrecord->courseid);
  201. writer::with_context($coursecontext)->export_data(
  202. [$strtransactions],
  203. (object) ['transactions' => $transactions]
  204. );
  205. }
  206. }
  207. /**
  208. * Delete all data for all users in the specified context.
  209. *
  210. * @param \context $context The specific context to delete data for.
  211. */
  212. public static function delete_data_for_all_users_in_context(\context $context) {
  213. global $DB;
  214. if (!$context instanceof \context_course) {
  215. return;
  216. }
  217. $DB->delete_records('enrol_paypal', array('courseid' => $context->instanceid));
  218. }
  219. /**
  220. * Delete all user data for the specified user, in the specified contexts.
  221. *
  222. * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
  223. */
  224. public static function delete_data_for_user(approved_contextlist $contextlist) {
  225. global $DB;
  226. if (empty($contextlist->count())) {
  227. return;
  228. }
  229. $user = $contextlist->get_user();
  230. $contexts = $contextlist->get_contexts();
  231. $courseids = [];
  232. foreach ($contexts as $context) {
  233. if ($context instanceof \context_course) {
  234. $courseids[] = $context->instanceid;
  235. }
  236. }
  237. list($insql, $inparams) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED);
  238. $select = "userid = :userid AND courseid $insql";
  239. $params = $inparams + ['userid' => $user->id];
  240. $DB->delete_records_select('enrol_paypal', $select, $params);
  241. // We do not want to delete the payment record when the user is just the receiver of payment.
  242. // In that case, we just delete the receiver's info from the transaction record.
  243. $select = "business = :business AND courseid $insql";
  244. $params = $inparams + ['business' => \core_text::strtolower($user->email)];
  245. $DB->set_field_select('enrol_paypal', 'business', '', $select, $params);
  246. $select = "receiver_email = :receiver_email AND courseid $insql";
  247. $params = $inparams + ['receiver_email' => \core_text::strtolower($user->email)];
  248. $DB->set_field_select('enrol_paypal', 'receiver_email', '', $select, $params);
  249. }
  250. }