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 Recently accessed items block. 19 * 20 * @package block_recentlyaccesseditems 21 * @copyright 2018 Victor Deniz <victor@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace block_recentlyaccesseditems\privacy; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 use \core_privacy\local\metadata\collection; 30 use \core_privacy\local\request\transform; 31 use \core_privacy\local\request\contextlist; 32 use \core_privacy\local\request\userlist; 33 use \core_privacy\local\request\approved_contextlist; 34 use \core_privacy\local\request\approved_userlist; 35 use \core_privacy\local\request\writer; 36 37 /** 38 * Privacy Subsystem for block_recentlyaccesseditems. 39 * 40 * @package block_recentlyaccesseditems 41 * @copyright 2018 Victor Deniz <victor@moodle.com> 42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 43 */ 44 class provider implements 45 \core_privacy\local\metadata\provider, 46 \core_privacy\local\request\core_userlist_provider, 47 \core_privacy\local\request\plugin\provider { 48 49 /** 50 * Returns information about the user data stored in this component. 51 * 52 * @param collection $collection A list of information about this component 53 * @return collection The collection object filled out with information about this component. 54 */ 55 public static function get_metadata(collection $collection) : collection { 56 $recentitems = [ 57 'userid' => 'privacy:metadata:userid', 58 'courseid' => 'privacy:metadata:courseid', 59 'cmid' => 'privacy:metadata:cmid', 60 'timeaccess' => 'privacy:metadata:timeaccess' 61 ]; 62 63 $collection->add_database_table('block_recentlyaccesseditems', $recentitems, 64 'privacy:metadata:block_recentlyaccesseditemstablesummary'); 65 66 return $collection; 67 } 68 69 /** 70 * Get the list of contexts that contain user information for the specified user. 71 * 72 * @param int $userid The user to search. 73 * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin. 74 */ 75 public static function get_contexts_for_userid(int $userid) : contextlist { 76 $params = ['userid' => $userid, 'contextuser' => CONTEXT_USER]; 77 $sql = "SELECT c.id 78 FROM {context} c 79 JOIN {block_recentlyaccesseditems} b 80 ON b.userid = c.instanceid 81 WHERE c.instanceid = :userid 82 AND c.contextlevel = :contextuser"; 83 $contextlist = new contextlist(); 84 $contextlist->add_from_sql($sql, $params); 85 return $contextlist; 86 } 87 88 /** 89 * Get the list of users within a specific context. 90 * 91 * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. 92 */ 93 public static function get_users_in_context(userlist $userlist) { 94 global $DB; 95 96 $context = $userlist->get_context(); 97 98 if (!$context instanceof \context_user) { 99 return; 100 } 101 102 if ($DB->record_exists('block_recentlyaccesseditems', ['userid' => $context->instanceid])) { 103 $userlist->add_user($context->instanceid); 104 } 105 } 106 107 /** 108 * Export all user data for the specified user, in the specified contexts. 109 * 110 * @param approved_contextlist $contextlist The approved contexts to export information for. 111 */ 112 public static function export_user_data(approved_contextlist $contextlist) { 113 $context = $contextlist->current(); 114 $user = \core_user::get_user($contextlist->get_user()->id); 115 static::export_recentitems($user->id, $context); 116 } 117 118 /** 119 * Export information about the most recently accessed items. 120 * 121 * @param int $userid The user ID. 122 * @param \context $context The user context. 123 */ 124 protected static function export_recentitems(int $userid, \context $context) { 125 global $DB; 126 $sql = "SELECT ra.id, c.fullname, ra.timeaccess, m.name, ra.cmid 127 FROM {block_recentlyaccesseditems} ra 128 JOIN {course} c ON c.id = ra.courseid 129 JOIN {course_modules} cm on cm.id = ra.cmid 130 JOIN {modules} m ON m.id = cm.module 131 WHERE ra.userid = :userid"; 132 133 $params = ['userid' => $userid]; 134 $records = $DB->get_records_sql($sql, $params); 135 if (!empty($records)) { 136 $recentitems = (object) array_map(function($record) use($context) { 137 return [ 138 'course_name' => format_string($record->fullname, true, ['context' => $context]), 139 'module_name' => format_string($record->name), 140 'timeaccess' => transform::datetime($record->timeaccess) 141 ]; 142 }, $records); 143 writer::with_context($context)->export_data([get_string('privacy:recentlyaccesseditemspath', 144 'block_recentlyaccesseditems')], $recentitems); 145 } 146 } 147 148 /** 149 * Delete all data for all users in the specified context. 150 * 151 * @param context $context The specific context to delete data for. 152 */ 153 public static function delete_data_for_all_users_in_context(\context $context) { 154 global $DB; 155 156 // Only delete data for a user context. 157 if ($context->contextlevel == CONTEXT_USER) { 158 // Delete recent items access. 159 $DB->delete_records('block_recentlyaccesseditems', ['userid' => $context->instanceid]); 160 } 161 } 162 163 /** 164 * Delete all user data for the specified user, in the specified contexts. 165 * 166 * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. 167 */ 168 public static function delete_data_for_user(approved_contextlist $contextlist) { 169 global $DB; 170 171 foreach ($contextlist as $context) { 172 // Let's be super certain that we have the right information for this user here. 173 if ($context->contextlevel == CONTEXT_USER && $contextlist->get_user()->id == $context->instanceid) { 174 $DB->delete_records('block_recentlyaccesseditems', ['userid' => $context->instanceid]); 175 } 176 } 177 } 178 179 /** 180 * Delete multiple users within a single context. 181 * 182 * @param approved_userlist $userlist The approved context and user information to delete information for. 183 */ 184 public static function delete_data_for_users(approved_userlist $userlist) { 185 global $DB; 186 187 $context = $userlist->get_context(); 188 189 if ($context instanceof \context_user && in_array($context->instanceid, $userlist->get_userids())) { 190 $DB->delete_records('block_recentlyaccesseditems', ['userid' => $context->instanceid]); 191 } 192 } 193 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body