From b1d47c1a43dcf7c442395c4b92a13cda26b986b0 Mon Sep 17 00:00:00 2001 From: vasanthlmsace Date: Mon, 6 Sep 2021 19:56:21 +0530 Subject: [PATCH] Privacy provider support implemented. --- classes/privacy/provider.php | 43 ++++ lang/en/local_learningtools.php | 2 +- ltool/bookmarks/classes/privacy/provider.php | 227 +++++++++++++++++++ ltool/bookmarks/lang/en/ltool_bookmarks.php | 14 ++ ltool/bookmarks/version.php | 2 +- ltool/note/classes/privacy/provider.php | 227 +++++++++++++++++++ ltool/note/lang/en/ltool_note.php | 15 ++ ltool/note/version.php | 2 +- version.php | 2 +- 9 files changed, 530 insertions(+), 4 deletions(-) create mode 100644 classes/privacy/provider.php create mode 100644 ltool/bookmarks/classes/privacy/provider.php create mode 100644 ltool/note/classes/privacy/provider.php diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php new file mode 100644 index 0000000..ba8cdf7 --- /dev/null +++ b/classes/privacy/provider.php @@ -0,0 +1,43 @@ +. + +/** + * Privacy implementation for learning tools parent plugin + * + * @package local_learningtools + * @copyright 2021, bdecent gmbh bdecent.de + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace local_learningtools\privacy; + +defined('MOODLE_INTERNAL') || die(); + +/** + * The local_learningtools parent plugin does not store any data. Subplugin stores user data. + */ +class provider implements \core_privacy\local\metadata\null_provider { + + /** + * Get the language string identifier with the component's language + * file to explain why this plugin stores no data. + * + * @return string + */ + public static function get_reason() : string { + + return 'privacy:metadata'; + } +} diff --git a/lang/en/local_learningtools.php b/lang/en/local_learningtools.php index c44235a..8528a9c 100644 --- a/lang/en/local_learningtools.php +++ b/lang/en/local_learningtools.php @@ -37,7 +37,7 @@ $string['learningtoolssettings'] = "Learning Tools Settings"; $string['ltoolsusermenu'] = "Display Learning Tools in usermenu bar"; $string['ltoolusermenu_help'] = "List of menus available to display in the user menu. copy and paste the below given menu tools path in user menu items. Go to the Appearence->Themes->Theme settings in user menu items. "; - +$string['privacy:metadata'] = 'Learning tools parent plugin don\'t store any user-related data, The learning tool sub plugins are stores the users data individually.'; $string['coursenotes'] = "Course Notes"; $string['addbookmark'] = "Add bookmark"; $string['createnote'] = "Create note"; diff --git a/ltool/bookmarks/classes/privacy/provider.php b/ltool/bookmarks/classes/privacy/provider.php new file mode 100644 index 0000000..1030cc8 --- /dev/null +++ b/ltool/bookmarks/classes/privacy/provider.php @@ -0,0 +1,227 @@ +. + +/** + * Privacy implementation for bookmarks learning tools subplugin. + * + * @package ltool_bookmarks + * @copyright bdecent GmbH 2021 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace ltool_bookmarks\privacy; + +use stdClass; +use context; + +use core_privacy\local\metadata\collection; +use \core_privacy\local\request\contextlist; +use \core_privacy\local\request\userlist; +use \core_privacy\local\request\approved_userlist; +use \core_privacy\local\request\approved_contextlist; +use core_privacy\local\request\helper; +use core_privacy\local\request\transform; +use core_privacy\local\request\writer; + +defined('MOODLE_INTERNAL') || die(); + +/** + * The ltool_note modules data export and deletion options. + */ +class provider implements + \core_privacy\local\metadata\provider, + \core_privacy\local\request\core_userlist_provider, + \core_privacy\local\request\plugin\provider { + + /** + * List of summary for the stored data. + * + * @param collection $collection + * @return collection + */ + public static function get_metadata(collection $collection): collection { + $bookmarksmetadata = [ + 'userid' => 'privacy:metadata:bookmarks:userid', + 'course' => 'privacy:metadata:bookmarks:course', + 'coursemodule' => 'privacy:metadata:bookmarks:coursemodule', + 'contextlevel' => 'privacy:metadata:bookmarks:contextlevel', + 'contextid' => 'privacy:metadata:bookmarks:contextid', + 'pagetype' => 'privacy:metadata:bookmarks:pagetype', + 'pagetitle' => 'privacy:metadata:bookmarks:pagetitle', + 'pageurl' => 'privacy:metadata:bookmarks:pageurl', + 'timemodified' => 'privacy:metadata:bookmarks:timemodified' + ]; + $collection->add_database_table('learningtools_bookmarks', $bookmarksmetadata, 'privacy:metadata:bookmarksmetadata'); + + return $collection; + } + + /** + * Check the context user has any bookmarks. + * + * @param int $userid + * @return bool + */ + public static function user_has_bookmark_data($userid) { + global $DB; + + if ($DB->count_records('learningtools_bookmarks', ['userid' => $userid])) { + return true; + } + return false; + } + + /** + * Get the list of contexts that contain user information for the specified user. + * + * @param int $userid The user to search. + * @return contextlist $contextlist The list of contexts used in this plugin. + */ + public static function get_contexts_for_userid(int $userid) : contextlist { + $contextlist = new \core_privacy\local\request\contextlist(); + + if (self::user_has_bookmark_data($userid)) { + $contextlist->add_user_context($userid); + } + + return $contextlist; + } + + /** + * Get the list of users who have data within a context. + * + * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. + */ + public static function get_users_in_context(userlist $userlist) { + $context = $userlist->get_context(); + + if (!$context instanceof \context_user) { + return; + } + + if (self::user_has_bookmark_data($context->instanceid)) { + $userlist->add_user($context->instanceid); + } + } + + /** + * Delete multiple users within a single context. + * + * @param approved_userlist $userlist The approved context and user information to delete information for. + */ + public static function delete_data_for_users(approved_userlist $userlist) { + global $DB; + $context = $userlist->get_context(); + if ($context instanceof \context_user) { + list($userinsql, $userinparams) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED); + if (!empty($userinparams)) { + $sql = "userid {$userinsql}"; + $DB->delete_records_select('learningtools_bookmarks', $sql, $userinparams); + } + } + } + + /** + * Delete user completion data for multiple context. + * + * @param approved_contextlist $contextlist The approved context and user information to delete information for. + */ + public static function delete_data_for_user(approved_contextlist $contextlist) { + global $DB; + + if (empty($contextlist->count())) { + return; + } + + foreach ($contextlist->get_contexts() as $context) { + if ($context->contextlevel == CONTEXT_USER) { + self::delete_user_data($context->instanceid); + } + } + } + + /** + * Delete all completion data for all users in the specified context. + * + * @param context $context Context to delete data from. + */ + public static function delete_data_for_all_users_in_context(\context $context) { + global $DB; + if ($context->contextlevel == CONTEXT_USER) { + self::delete_user_data($context->instanceid); + } + } + + /** + * This does the deletion of user data given a userid. + * + * @param int $userid The user ID + */ + private static function delete_user_data(int $userid) { + global $DB; + if ($DB->delete_records('learningtools_bookmarks', ['userid' => $userid])) { + return true; + } + return false; + } + + /** + * Export all user data for the specified user, in the specified contexts, using the supplied exporter instance. + * + * @param approved_contextlist $contextlist The approved contexts to export information for. + */ + public static function export_user_data(approved_contextlist $contextlist) { + global $DB; + + if (empty($contextlist->count())) { + return; + } + // Context user. + $user = $contextlist->get_user(); + + $records = $DB->get_records('learningtools_bookmarks', ['userid' => $user->id]); + + if (empty($records)) { + return; + } + + $exportdata = array_map(function($record) { + + $modulename = ($record->coursemodule) ? get_coursemodule_from_id('', $record->coursemodule)->name : '-'; + + return [ + 'contextlevel' => $record->contextlevel, + 'contextid' => $record->contextid, + 'course' => ($record->course == 1) ? 'system' : format_string(get_course($record->course)->fullname), + 'coursemodule' => format_string($modulename), + 'pagetitle' => $record->pagetitle, + 'pagetype' => $record->pagetype, + 'pageurl' => $record->pageurl, + 'timecreated' => ($record->timecreated) ? transform::datetime($record->timecreated) : '-', + ]; + }, $records); + + if (!empty($exportdata)) { + $context = \context_user::instance($user->id); + // Fetch the generic module data for the bookmarks. + $contextdata = helper::get_context_data($context, $user); + $contextdata = (object)array_merge((array)$contextdata, $exportdata); + writer::with_context($context)->export_data( + [get_string('privacybookmarks', 'ltool_bookmarks').' '.$user->id], + $contextdata + ); + } + } +} diff --git a/ltool/bookmarks/lang/en/ltool_bookmarks.php b/ltool/bookmarks/lang/en/ltool_bookmarks.php index 04acdd9..77c7769 100644 --- a/ltool/bookmarks/lang/en/ltool_bookmarks.php +++ b/ltool/bookmarks/lang/en/ltool_bookmarks.php @@ -31,3 +31,17 @@ $string['bookmarks:viewbookmarks'] = "View the others bookmarks."; $string['bookmarks:managebookmarks'] = "Manage the others boomarks."; $string['bookmarks'] = "Bookmarks"; + +// Privacy API Metadata. +$string['privacy:metadata:bookmarks:userid'] = 'The ID of the user'; +$string['privacy:metadata:bookmarks:course'] = 'The ID of the course'; +$string['privacy:metadata:bookmarks:coursemodule'] = 'The ID of the course module if user bookmarked the course modules page'; +$string['privacy:metadata:bookmarks:contextlevel'] = 'The Context level of the bookmark page'; +$string['privacy:metadata:bookmarks:contextid'] = 'The Context ID of the bookmark page'; +$string['privacy:metadata:bookmarks:pagetype'] = 'Bookmarked pagetype'; +$string['privacy:metadata:bookmarks:pagetitle'] = 'Page title of Bookmarked page'; +$string['privacy:metadata:bookmarks:pageurl'] = 'Bookmarked page url'; +$string['privacy:metadata:bookmarks:timecreated'] = 'Time of the bookmarks created'; +$string['privacy:metadata:bookmarks:timemodified'] = 'Time of the bookmarks modified'; +$string['privacy:metadata:bookmarksmetadata'] = 'List of users data stored in bookmarks subplugin'; +$string['privacybookmarks'] = 'Learning tools - Bookmarks'; diff --git a/ltool/bookmarks/version.php b/ltool/bookmarks/version.php index e195a53..852bcd4 100644 --- a/ltool/bookmarks/version.php +++ b/ltool/bookmarks/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'ltool_bookmarks'; -$plugin->version = 2021082900; +$plugin->version = 2021090600; $plugin->requires = 2020061501; diff --git a/ltool/note/classes/privacy/provider.php b/ltool/note/classes/privacy/provider.php new file mode 100644 index 0000000..d0e0af9 --- /dev/null +++ b/ltool/note/classes/privacy/provider.php @@ -0,0 +1,227 @@ +. + +/** + * Privacy implementation for notes learning tools subplugin. + * + * @package ltool_note + * @copyright bdecent GmbH 2021 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace ltool_note\privacy; + +use stdClass; +use context; + +use core_privacy\local\metadata\collection; +use \core_privacy\local\request\contextlist; +use \core_privacy\local\request\userlist; +use \core_privacy\local\request\approved_userlist; +use \core_privacy\local\request\approved_contextlist; +use core_privacy\local\request\helper; +use core_privacy\local\request\transform; +use core_privacy\local\request\writer; + +defined('MOODLE_INTERNAL') || die(); + +/** + * The ltool_note modules data export and deletion options. + */ +class provider implements + \core_privacy\local\metadata\provider, + \core_privacy\local\request\core_userlist_provider, + \core_privacy\local\request\plugin\provider { + + /** + * Get list of the data privacy summary meta strings. + * + * @param collection $collection + * @return collection + */ + public static function get_metadata(collection $collection): collection { + $notemetadata = [ + 'userid' => 'privacy:metadata:note:userid', + 'course' => 'privacy:metadata:note:course', + 'coursemodule' => 'privacy:metadata:note:coursemodule', + 'contextlevel' => 'privacy:metadata:note:contextlevel', + 'contextid' => 'privacy:metadata:note:contextid', + 'pagetype' => 'privacy:metadata:note:pagetype', + 'pagetitle' => 'privacy:metadata:note:pagetitle', + 'pageurl' => 'privacy:metadata:note:pageurl', + 'note' => 'privacy:metadata:note:note', + 'timecreated' => 'privacy:metadata:note:timecreated', + 'timemodified' => 'privacy:metadata:note:timemodified' + ]; + $collection->add_database_table('learningtools_note', $notemetadata, 'privacy:metadata:notemetadata'); + + return $collection; + } + + /** + * Check the context user has any created note. + * + * @param int $userid + * @return bool + */ + public static function user_has_note_data($userid): bool { + global $DB; + + if ($DB->count_records('learningtools_note', ['userid' => $userid])) { + return true; + } + return false; + } + + /** + * Get the list of contexts that contain user information for the specified user. + * + * @param int $userid The user to search. + * @return contextlist $contextlist The list of contexts used in this plugin. + */ + public static function get_contexts_for_userid(int $userid) : contextlist { + $contextlist = new \core_privacy\local\request\contextlist(); + // Check user has stored any notes. + if (self::user_has_note_data($userid)) { + $contextlist->add_user_context($userid); + } + + return $contextlist; + } + + /** + * Get the list of users who have data within a context. + * + * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. + */ + public static function get_users_in_context(userlist $userlist) { + $context = $userlist->get_context(); + + if (!$context instanceof \context_user) { + return; + } + // Check user has stored any notes. + if (self::user_has_note_data($context->instanceid)) { + $userlist->add_user($context->instanceid); + } + } + + /** + * Delete multiple users within a single context. + * + * @param approved_userlist $userlist The approved context and user information to delete information for. + */ + public static function delete_data_for_users(approved_userlist $userlist) { + global $DB; + $context = $userlist->get_context(); + if ($context instanceof \context_user) { + list($userinsql, $userinparams) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED); + if (!empty($userinparams)) { + $sql = "userid {$userinsql}"; + $DB->delete_records_select('learningtools_note', $sql, $userinparams); + } + } + } + + /** + * Delete user notes data for multiple context. + * + * @param approved_contextlist $contextlist The approved context and user information to delete information for. + */ + public static function delete_data_for_user(approved_contextlist $contextlist) { + if (empty($contextlist->count())) { + return; + } + foreach ($contextlist->get_contexts() as $context) { + if ($context->contextlevel == CONTEXT_USER) { + // Delete stored user notes. + self::delete_user_notedata($context->instanceid); + } + } + } + + /** + * Delete all notes data for all users in the specified context. + * + * @param context $context Context to delete data from. + */ + public static function delete_data_for_all_users_in_context(\context $context) { + global $DB; + if ($context->contextlevel == CONTEXT_USER) { + // Delete all users notes. + self::delete_user_notedata($context->instanceid); + } + } + + /** + * This does the deletion of user notes data given a userid. + * + * @param int $userid The user ID + */ + private static function delete_user_notedata(int $userid) { + global $DB; + if ($DB->delete_records('learningtools_note', ['userid' => $userid])) { + return true; + } + return false; + } + /** + * Export all user data for the specified user, in the specified contexts, using the supplied exporter instance. + * + * @param approved_contextlist $contextlist The approved contexts to export information for. + */ + public static function export_user_data(approved_contextlist $contextlist) { + global $DB; + + if (empty($contextlist->count())) { + return; + } + // Context user. + $user = $contextlist->get_user(); + + // List of user notes stored in table. + $notes = $DB->get_records('learningtools_note', ['userid' => $user->id]); + + if (empty($notes)) { + return; + } + // Generate the notes list to export. + $exportdata = array_map(function($note) { + $modulename = ($note->coursemodule) ? get_coursemodule_from_id('', $note->coursemodule)->name : '-'; + return [ + 'contextlevel' => $note->contextlevel, + 'contextid' => $note->contextid, + 'course' => ($note->course == 1) ? 'system' : format_string(get_course($note->course)->fullname), + 'coursemodule' => format_string($modulename), + 'pagetitle' => $note->pagetitle, + 'pagetype' => $note->pagetype, + 'pageurl' => $note->pageurl, + 'note' => $note->note, + 'timecreated' => ($note->timecreated) ? transform::datetime($note->timecreated) : '-', + 'timemodified' => ($note->timemodified) ? transform::datetime($note->timemodified) : '-', + ]; + }, $notes); + + if (!empty($exportdata)) { + $context = \context_user::instance($user->id); + // Fetch the generic module data for the note. + $contextdata = helper::get_context_data($context, $user); + $contextdata = (object)array_merge((array)$contextdata, $exportdata); + writer::with_context($context)->export_data([get_string('privacynote', 'ltool_note').' '.$user->id], $contextdata); + } + + } + +} diff --git a/ltool/note/lang/en/ltool_note.php b/ltool/note/lang/en/ltool_note.php index 4ca4824..a0b437a 100644 --- a/ltool/note/lang/en/ltool_note.php +++ b/ltool/note/lang/en/ltool_note.php @@ -31,3 +31,18 @@ $string['note:viewnote'] = "View the others notes."; $string['note:managenote'] = "Manage the others notes."; $string['notes'] = "Notes"; + +// Privacy Metadata. +$string['privacynote'] = 'Learning Tools - Notes'; +$string['privacy:metadata:note:userid'] = 'The ID of the user'; +$string['privacy:metadata:note:course'] = 'The ID of the course'; +$string['privacy:metadata:note:coursemodule'] = 'The ID of the course module if note created on course modules page'; +$string['privacy:metadata:note:contextlevel'] = 'The Context level of the note created page'; +$string['privacy:metadata:note:contextid'] = 'The Context ID of the note craeted page'; +$string['privacy:metadata:note:pagetype'] = 'Note created pagetype'; +$string['privacy:metadata:note:pagetitle'] = 'Page title of the note created page'; +$string['privacy:metadata:note:pageurl'] = 'Note created page url'; +$string['privacy:metadata:note:note'] = 'User entered note content.'; +$string['privacy:metadata:note:timecreated'] = 'Time of the note created'; +$string['privacy:metadata:note:timemodified'] = 'Time of the note modified'; +$string['privacy:metadata:notemetadata'] = 'List of data stored in note subplugin'; diff --git a/ltool/note/version.php b/ltool/note/version.php index 3a6cbfd..4695ab4 100644 --- a/ltool/note/version.php +++ b/ltool/note/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'ltool_note'; -$plugin->version = 2021082900; +$plugin->version = 2021090600; $plugin->requires = 2020061501; diff --git a/version.php b/version.php index de9ac3b..3c0226d 100644 --- a/version.php +++ b/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'local_learningtools'; -$plugin->version = 2021082900; +$plugin->version = 2021090600; $plugin->release = 'v1.0'; $plugin->requires = 2020061501; $plugin->maturity = MATURITY_STABLE;