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 class for requesting user data for the favourites subsystem. 19 * 20 * @package core_favourites 21 * @copyright 2018 Jake Dallimore <jrhdallimore@gmail.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_favourites\privacy; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 use \core_privacy\local\metadata\collection; 30 use \core_privacy\local\request\context; 31 use \core_privacy\local\request\approved_contextlist; 32 use \core_privacy\local\request\transform; 33 34 /** 35 * Privacy class for requesting user data. 36 * 37 * @copyright 2018 Jake Dallimore <jrhdallimore@gmail.com> 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class provider implements 41 \core_privacy\local\metadata\provider, 42 \core_privacy\local\request\subsystem\plugin_provider, 43 \core_privacy\local\request\shared_userlist_provider { 44 45 /** 46 * Returns metadata about this system. 47 * 48 * @param collection $collection The initialised collection to add items to. 49 * @return collection A listing of user data stored through this system. 50 */ 51 public static function get_metadata(collection $collection) : collection { 52 return $collection->add_database_table('favourite', [ 53 'userid' => 'privacy:metadata:favourite:userid', 54 'component' => 'privacy:metadata:favourite:component', 55 'itemtype' => 'privacy:metadata:favourite:itemtype', 56 'itemid' => 'privacy:metadata:favourite:itemid', 57 'ordering' => 'privacy:metadata:favourite:ordering', 58 'timecreated' => 'privacy:metadata:favourite:timecreated', 59 'timemodified' => 'privacy:metadata:favourite:timemodified', 60 ], 'privacy:metadata:favourite'); 61 } 62 63 /** 64 * Provide a list of contexts which have favourites for the user, in the respective area (component/itemtype combination). 65 * 66 * This method is to be called by consumers of the favourites subsystem (plugins), in their get_contexts_for_userid() method, 67 * to add the contexts for items which may have been favourited, but would normally not be reported as having user data by the 68 * plugin responsible for them. 69 * 70 * Consider an example: Favourite courses. 71 * Favourite courses will be handled by the core_course subsystem and courses can be favourited at site context. 72 * 73 * Now normally, the course provider method get_contexts_for_userid() would report the context of any courses the user is in. 74 * Then, we'd export data for those contexts. This won't include courses the user has favourited, but is not a member of. 75 * 76 * To report the full list, the course provider needs to be made aware of the contexts of any courses the user may have marked 77 * as favourites. Course will need to ask th favourites subsystem for this - a call to add_contexts_for_userid($userid). 78 * 79 * Once called, if a course has been marked as a favourite, at site context, then we'd return the site context. During export, 80 * the consumer (course), just looks at all contexts and decides whether to export favourite courses for each one. 81 * 82 * @param \core_privacy\local\request\contextlist $contextlist 83 * @param int $userid The id of the user in scope. 84 * @param string $component the frankenstyle component name. 85 * @param string $itemtype the type of the favourited items. 86 */ 87 public static function add_contexts_for_userid(\core_privacy\local\request\contextlist $contextlist, int $userid, 88 string $component, string $itemtype = null) { 89 $sql = "SELECT contextid 90 FROM {favourite} f 91 WHERE userid = :userid 92 AND component = :component"; 93 94 $params = ['userid' => $userid, 'component' => $component]; 95 96 if (!is_null($itemtype)) { 97 $sql .= " AND itemtype = :itemtype"; 98 $params['itemtype'] = $itemtype; 99 } 100 101 $contextlist->add_from_sql($sql, $params); 102 } 103 104 /** 105 * Add users to a userlist who have favourites within the specified context. 106 * 107 * @param \core_privacy\local\request\userlist $userlist The userlist to add the users to. 108 * @param string $itemtype the type of the favourited items. 109 * @return void 110 */ 111 public static function add_userids_for_context(\core_privacy\local\request\userlist $userlist, 112 string $itemtype = null) { 113 if (empty($userlist)) { 114 return; 115 } 116 117 $params = [ 118 'contextid' => $userlist->get_context()->id, 119 'component' => $userlist->get_component() 120 ]; 121 122 $sql = "SELECT userid 123 FROM {favourite} 124 WHERE contextid = :contextid 125 AND component = :component"; 126 127 if (!is_null($itemtype)) { 128 $sql .= " AND itemtype = :itemtype"; 129 $params['itemtype'] = $itemtype; 130 } 131 132 $userlist->add_from_sql('userid', $sql, $params); 133 } 134 135 /** 136 * Get favourites data for the specified user in the specified component, item type and item ID. 137 * 138 * @param int $userid The id of the user in scope. 139 * @param \context $context The context to which data is scoped. 140 * @param string $component The favourite's component name. 141 * @param string $itemtype The favourite's item type. 142 * @param int $itemid The favourite's item ID. 143 * @return array|null 144 */ 145 public static function get_favourites_info_for_user(int $userid, \context $context, 146 string $component, string $itemtype, int $itemid) { 147 global $DB; 148 149 $params = [ 150 'userid' => $userid, 151 'component' => $component, 152 'itemtype' => $itemtype, 153 'itemid' => $itemid, 154 'contextid' => $context->id 155 ]; 156 157 if (!$favourited = $DB->get_record('favourite', $params)) { 158 return; 159 } 160 161 return [ 162 'starred' => transform::yesno(true), 163 'ordering' => $favourited->ordering, 164 'timecreated' => transform::datetime($favourited->timecreated), 165 'timemodified' => transform::datetime($favourited->timemodified) 166 ]; 167 } 168 169 /** 170 * Delete all favourites for all users in the specified contexts, and component area. 171 * 172 * @param \context $context The context to which deletion is scoped. 173 * @param string $component The favourite's component name. 174 * @param string $itemtype The favourite's itemtype. 175 * @param int $itemid Optional itemid associated with component. 176 * @throws \dml_exception if any errors are encountered during deletion. 177 */ 178 public static function delete_favourites_for_all_users(\context $context, string $component, string $itemtype, 179 int $itemid = 0) { 180 global $DB; 181 182 $params = [ 183 'component' => $component, 184 'itemtype' => $itemtype, 185 'contextid' => $context->id 186 ]; 187 188 $select = "component = :component AND itemtype =:itemtype AND contextid = :contextid"; 189 190 if (!empty($itemid)) { 191 $select .= " AND itemid = :itemid"; 192 $params['itemid'] = $itemid; 193 } 194 $DB->delete_records_select('favourite', $select, $params); 195 } 196 197 /** 198 * Delete all favourites for the specified users in the specified context, component area and item type. 199 * 200 * @param \core_privacy\local\request\approved_userlist $userlist The approved contexts and user information 201 * to delete information for. 202 * @param string $itemtype The favourite's itemtype. 203 * @param int $itemid Optional itemid associated with component. 204 * @throws \dml_exception if any errors are encountered during deletion. 205 */ 206 public static function delete_favourites_for_userlist(\core_privacy\local\request\approved_userlist $userlist, 207 string $itemtype, int $itemid = 0) { 208 global $DB; 209 210 $userids = $userlist->get_userids(); 211 212 if (empty($userids)) { 213 return; 214 } 215 216 $context = $userlist->get_context(); 217 list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED); 218 219 $params = [ 220 'component' => $userlist->get_component(), 221 'itemtype' => $itemtype, 222 'contextid' => $context->id 223 ]; 224 225 $params += $userparams; 226 $select = "component = :component AND itemtype = :itemtype AND contextid = :contextid AND userid $usersql"; 227 228 if (!empty($itemid)) { 229 $select .= " AND itemid = :itemid"; 230 $params['itemid'] = $itemid; 231 } 232 233 $DB->delete_records_select('favourite', $select, $params); 234 } 235 236 /** 237 * Delete all favourites for the specified user, in the specified contexts. 238 * 239 * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. 240 * @param string $component The favourite's component name. 241 * @param string $itemtype The favourite's itemtype. 242 * @param int $itemid Optional itemid associated with component. 243 * @throws \coding_exception 244 * @throws \dml_exception 245 */ 246 public static function delete_favourites_for_user(approved_contextlist $contextlist, string $component, string $itemtype, 247 int $itemid = 0) { 248 global $DB; 249 250 $userid = $contextlist->get_user()->id; 251 252 list($insql, $inparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED); 253 254 $params = [ 255 'userid' => $userid, 256 'component' => $component, 257 'itemtype' => $itemtype, 258 ]; 259 $params += $inparams; 260 261 $select = "userid = :userid AND component = :component AND itemtype =:itemtype AND contextid $insql"; 262 263 if (!empty($itemid)) { 264 $select .= " AND itemid = :itemid"; 265 $params['itemid'] = $itemid; 266 } 267 268 $DB->delete_records_select('favourite', $select, $params); 269 } 270 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body