Merge branch 'wip-MDL-61937-master' of git://github.com/marinaglancy/moodle
[moodle.git] / comment / classes / privacy / provider.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  * Privacy class for requesting user data.
19  *
20  * @package    core_comment
21  * @copyright  2018 Adrian Greeve <adrian@moodle.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 namespace core_comment\privacy;
27 defined('MOODLE_INTERNAL') || die();
29 use \core_privacy\local\metadata\collection;
30 use \core_privacy\local\request\transform;
32 /**
33  * Privacy class for requesting user data.
34  *
35  * @package    core_comment
36  * @copyright  2018 Adrian Greeve <adrian@moodle.com>
37  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class provider implements \core_privacy\local\metadata\provider, \core_privacy\local\request\subsystem\plugin_provider {
41     /**
42      * Returns meta data about this system.
43      *
44      * @param   collection     $collection The initialised collection to add items to.
45      * @return  collection     A listing of user data stored through this system.
46      */
47     public static function get_metadata(collection $collection) : collection {
48         $collection->add_database_table('comments', [
49                 'content' => 'privacy:metadata:comment:content',
50                 'timecreated' => 'privacy:metadata:comment:timecreated',
51                 'userid' => 'privacy:metadata:comment:userid',
52             ], 'privacy:metadata:comment');
54         return $collection;
55     }
57     /**
58      * Writes user data to the writer for the user to download.
59      *
60      * @param  \context $context The context to export data for.
61      * @param  string $component The component that is calling this function
62      * @param  string $commentarea The comment area related to the component
63      * @param  int    $itemid An identifier for a group of comments
64      * @param  array  $subcontext The sub-context in which to export this data
65      * @param  bool   $onlyforthisuser  Only return the comments this user made.
66      */
67     public static function export_comments(\context $context, string $component, string $commentarea, int $itemid,
68                                            array $subcontext, bool $onlyforthisuser = true) {
69         global $USER, $DB;
70         $params = [
71             'contextid' => $context->id,
72             'component' => $component,
73             'commentarea' => $commentarea,
74             'itemid' => $itemid
75         ];
76         $sql = "SELECT c.id, c.content, c.format, c.timecreated, c.userid
77                   FROM {comments} c
78                  WHERE c.contextid = :contextid AND
79                        c.commentarea = :commentarea AND
80                        c.itemid = :itemid AND
81                        (c.component IS NULL OR c.component = :component)";
82         if ($onlyforthisuser) {
83             $sql .= " AND c.userid = :userid";
84             $params['userid'] = $USER->id;
85         }
86         $sql .= " ORDER BY c.timecreated DESC";
88         $rs = $DB->get_recordset_sql($sql, $params);
89         $comments = [];
90         foreach ($rs as $record) {
91             if ($record->userid != $USER->id) {
92                 // Clean HTML in comments that were added by other users.
93                 $comment = ['content' => format_text($record->content, $record->format, ['context' => $context])];
94             } else {
95                 // Export comments made by this user as they are stored.
96                 $comment = ['content' => $record->content, 'contentformat' => $record->format];
97             }
98             $comment += [
99                 'time' => transform::datetime($record->timecreated),
100                 'userid' => transform::user($record->userid),
101             ];
102             $comments[] = (object)$comment;
103         }
104         $rs->close();
106         if (!empty($comments)) {
107             $subcontext[] = get_string('commentsubcontext', 'core_comment');
108             \core_privacy\local\request\writer::with_context($context)
109                 ->export_data($subcontext, (object) [
110                     'comments' => $comments,
111                 ]);
112         }
113     }
115     /**
116      * Deletes all comments for a specified context, component, and commentarea.
117      *
118      * @param  \context $context Details about which context to delete comments for.
119      * @param  string $component Component to delete.
120      * @param  string $commentarea Comment area to delete.
121      * @param  int $itemid The item ID for use with deletion.
122      */
123     public static function delete_comments_for_all_users(\context $context, string $component, string $commentarea = null,
124             int $itemid = null) {
125         global $DB;
126         $params = [
127             'contextid' => $context->id,
128             'component' => $component
129         ];
130         if (isset($commentarea)) {
131             $params['commentarea'] = $commentarea;
132         }
133         if (isset($itemid)) {
134             $params['itemid'] = $itemid;
135         }
136         $DB->delete_records('comments', $params);
137     }
139     /**
140      * Deletes all comments for a specified context, component, and commentarea.
141      *
142      * @param  \context $context Details about which context to delete comments for.
143      * @param  string $component Component to delete.
144      * @param  string $commentarea Comment area to delete.
145      * @param  string $itemidstest an SQL fragment that the itemid must match. Used
146      *      in the query like WHERE itemid $itemidstest. Must use named parameters,
147      *      and may not use named parameters called contextid, component or commentarea.
148      * @param array $params any query params used by $itemidstest.
149      */
150     public static function delete_comments_for_all_users_select(\context $context, string $component, string $commentarea,
151             $itemidstest, $params = []) {
152         global $DB;
153         $params += ['contextid' => $context->id, 'component' => $component, 'commentarea' => $commentarea];
154         $DB->delete_records_select('comments',
155             'contextid = :contextid AND component = :component AND commentarea = :commentarea AND itemid ' . $itemidstest,
156             $params);
157     }
159     /**
160      * Deletes all records for a user from a list of approved contexts.
161      *
162      * @param  \core_privacy\local\request\approved_contextlist $contextlist Contains the user ID and a list of contexts to be
163      * deleted from.
164      * @param  string $component Component to delete from.
165      * @param  string $commentarea Area to delete from.
166      * @param  int $itemid The item id to delete from.
167      */
168     public static function delete_comments_for_user(\core_privacy\local\request\approved_contextlist $contextlist,
169             string $component, string $commentarea = null, int $itemid = null) {
170         global $DB;
172         $userid = $contextlist->get_user()->id;
173         $contextids = implode(',', $contextlist->get_contextids());
174         $params = [
175             'userid' => $userid,
176             'component' => $component,
177         ];
178         $areasql = '';
179         if (isset($commentarea)) {
180             $params['commentarea'] = $commentarea;
181             $areasql = 'AND commentarea = :commentarea';
182         }
183         $itemsql = '';
184         if (isset($itemid)) {
185             $params['itemid'] = $itemid;
186             $itemsql = 'AND itemid = :itemid';
187         }
188         list($insql, $inparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
189         $params += $inparams;
191         $select = "userid = :userid AND component = :component $areasql $itemsql AND contextid $insql";
192         $DB->delete_records_select('comments', $select, $params);
193     }