MDL-63666 logging: Add support for removal of context users.
[moodle.git] / admin / tool / log / classes / local / privacy / moodle_database_export_and_delete.php
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/>.
17 /**
18  * Moodle database: export and delete.
19  *
20  * @package    tool_log
21  * @copyright  2018 Frédéric Massart
22  * @author     Frédéric Massart <fred@branchup.tech>
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 namespace tool_log\local\privacy;
27 defined('MOODLE_INTERNAL') || die();
29 use context;
30 use core_privacy\local\request\approved_contextlist;
31 use core_privacy\local\request\writer;
33 /**
34  * Moodle database: export and delete trait.
35  *
36  * This is to be used with logstores which use a database and table with the same columns
37  * as the core plugin 'logstore_standard'.
38  *
39  * This trait expects the following methods to be present in the object:
40  *
41  * - public static function get_database_and_table(): [moodle_database|null, string|null]
42  * - public static function get_export_subcontext(): []
43  *
44  * @package    tool_log
45  * @copyright  2018 Frédéric Massart
46  * @author     Frédéric Massart <fred@branchup.tech>
47  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
48  */
49 trait moodle_database_export_and_delete {
51     /**
52      * Export all user data for the specified user, in the specified contexts.
53      *
54      * @param approved_contextlist $contextlist The approved contexts to export information for.
55      */
56     public static function export_user_data(approved_contextlist $contextlist) {
57         list($db, $table) = static::get_database_and_table();
58         if (!$db || !$table) {
59             return;
60         }
62         $userid = $contextlist->get_user()->id;
63         list($insql, $inparams) = $db->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
65         $sql = "(userid = :userid1 OR relateduserid = :userid2 OR realuserid = :userid3) AND contextid $insql";
66         $params = array_merge($inparams, [
67             'userid1' => $userid,
68             'userid2' => $userid,
69             'userid3' => $userid,
70         ]);
72         $path = static::get_export_subcontext();
73         $flush = function($lastcontextid, $data) use ($path) {
74             $context = context::instance_by_id($lastcontextid);
75             writer::with_context($context)->export_data($path, (object) ['logs' => $data]);
76         };
78         $lastcontextid = null;
79         $data = [];
80         $recordset = $db->get_recordset_select($table, $sql, $params, 'contextid, timecreated, id');
81         foreach ($recordset as $record) {
82             if ($lastcontextid && $lastcontextid != $record->contextid) {
83                 $flush($lastcontextid, $data);
84                 $data = [];
85             }
86             $data[] = helper::transform_standard_log_record_for_userid($record, $userid);
87             $lastcontextid = $record->contextid;
88         }
89         if ($lastcontextid) {
90             $flush($lastcontextid, $data);
91         }
92         $recordset->close();
93     }
95     /**
96      * Delete all data for all users in the specified context.
97      *
98      * @param context $context The specific context to delete data for.
99      */
100     public static function delete_data_for_all_users_in_context(context $context) {
101         list($db, $table) = static::get_database_and_table();
102         if (!$db || !$table) {
103             return;
104         }
105         $db->delete_records($table, ['contextid' => $context->id]);
106     }
108     /**
109      * Delete all user data for the specified user, in the specified contexts.
110      *
111      * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
112      */
113     public static function delete_data_for_user(approved_contextlist $contextlist) {
114         list($db, $table) = static::get_database_and_table();
115         if (!$db || !$table) {
116             return;
117         }
118         list($insql, $inparams) = $db->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
119         $params = array_merge($inparams, ['userid' => $contextlist->get_user()->id]);
120         $db->delete_records_select($table, "userid = :userid AND contextid $insql", $params);
121     }
123     /**
124      * Delete all user data for the specified users, in the specified context.
125      *
126      * @param \core_privacy\local\request\approved_userlist $contextlist The approved contexts and user information to delete information for.
127      */
128     public static function delete_data_for_all_users(\core_privacy\local\request\approved_userlist $userlist) {
129         list($db, $table) = static::get_database_and_table();
130         if (!$db || !$table) {
131             return;
132         }
133         list($insql, $inparams) = $db->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED);
134         $params = array_merge($inparams, ['contextid' => $userlist->get_context()->id]);
135         $db->delete_records_select($table, "contextid = :contextid AND userid $insql", $params);
136     }