Added privacy provider

This commit is contained in:
PMKuipers 2023-07-18 22:14:52 +02:00
parent 44eaff8bb8
commit a036cf1106
3 changed files with 298 additions and 0 deletions

View File

@ -0,0 +1,274 @@
<?php
namespace local_treestudyplan\privacy;
use core_privacy\local\metadata\collection;
use \core_privacy\local\request\userlist;
use core_privacy\local\request\contextlist;
use \core_privacy\local\request\approved_contextlist;
use \core_privacy\local\request\approved_userlist;
use \core_privacy\local\request\deletion_criteria;
use \core_privacy\local\request\writer;
use \core_privacy\local\request\helper;
use \core_privacy\local\request\transform;
use tool_dataprivacy\context_instance;
class provider implements \core_privacy\local\metadata\provider,
\core_privacy\local\request\plugin\provider,
\core_privacy\local\request\core_userlist_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';
}
public static function get_metadata(collection $collection): collection {
$collection->add_database_table(
'local_treestudyplan_invit',
[
'user_id' => 'privacy:metadata:invit:user_id',
'name' => 'privacy:metadata:invit:name',
'email' => 'privacy:metadata:invit:email',
'date' => 'privacy:metadata:invit:date',
],
'privacy:metadata:invit'
);
$collection->add_database_table(
'local_treestudyplan_user',
[
'user_id' => 'privacy:metadata:user:user_id',
'studyplan_id' => 'privacy:metadata:user:studyplan_id',
],
'privacy:metadata:user'
);
return $collection;
}
/**
* Get the list of contexts that contain user information for the specified user.
*
* @param int $userid The user to search.
* @return contextlist $contextlist The contextlist containing 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();
$contextlist->add_system_context(); // For invitations
// add contexts for linked studyplans
$sql = "SELECT s.context_id FROM {local_treestudyplan} s
INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
WHERE ( a.user_id = :userid )
";
$contextlist->add_from_sql($sql, ['userid' => $userid]);
return $contextlist;
}
/**
* Export all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts to export information for.
*/
public static function export_user_data(approved_contextlist $contextlist){
global $DB;
foreach ($contextlist->get_contexts() as $context) {
$user = $contextlist->get_user();
if($context instanceof \context_system){
// Export invitations
$sql = "SELECT * FROM {local_treestudyplan_invit} i
WHERE ( aiuser_id = :userid )
";
$records = $DB->get_records_sql($sql,["userid" => $user->id]);
foreach($records as $r) {
static::export_invitation_data_for_user($r);
}
// Export empty associations
$sql = "SELECT * FROM {local_treestudyplan} s
INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
WHERE ( a.user_id = :userid AND (s.context_id IS NULL or s.context_id = 0)
";
$records = $DB->get_records_sql($sql,["userid" => $user->id, "contextid" => $context->id]);
foreach($records as $r) {
static::export_studyplan_data_for_user($r);
}
} else if ($context->contextlevel == CONTEXT_COURSECAT){
// Export studyplan associations
$sql = "SELECT * FROM {local_treestudyplan} s
INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
WHERE ( a.user_id = :userid AND s.context_id = :contextid)
";
$records = $DB->get_records_sql($sql,["userid" => $user->id, "contextid" => $context->id]);
foreach($records as $r) {
static::export_studyplan_data_for_user($r);
}
}
}
}
/**
* Export the supplied personal data for an invitation.
*
* @param $invit The invitation record.
*/
protected static function export_invitation_data_for_user($invit) {
$context = \context_system::instance();
$subcontext = ["invitations"];
writer::with_context($context)
->export_data($subcontext, (object)["recipient" => $invit->name, "email" => $invit->email]);
}
/**
* Export the supplied personal data for an invitation.
*
* @param $invit The invitation record.
*/
protected static function export_studyplan_data_for_user($studyplan) {
$context = \context_system::instance();
$subcontext = ["studyplans"];
writer::with_context($context)
->export_data($subcontext, (object)["fullname" => $studyplan->fullname, "shortname" => $studyplan->shortname]);
}
/**
* Delete all data for all users in the specified context.
* Used when a context is past it's data retention period
*
* @param context $context The specific context to delete data for.
*/
public static function delete_data_for_all_users_in_context(\context $context){
global $DB;
// find studyplans in context
if($context->contextlevel == CONTEXT_COURSECAT){
$sql = "SELECT s.id FROM {local_treestudyplan} WHERE ( a.user_id = :userid AND s.context_id = :contextid)";
$plan_ids = $DB->get_fieldset_sql($sql,["contextid"=>$context->id]);
foreach($plan_ids as $plan_id){
$DB->delete_records("local_treestudyplan_user",["studyplan_id" => $plan_id]);
}
}
}
/**
* Delete all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
*/
public static function delete_data_for_user(approved_contextlist $contextlist){
global $DB;
$user = $contextlist->get_user();
foreach ($contextlist->get_contexts() as $context) {
if($context->contextlevel == CONTEXT_SYSTEM){
$sql = "SELECT s.id FROM {local_treestudyplan} INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
WHERE ( a.user_id = :userid AND ( s.context_id IS NULL OR s.context_id == 0 OR s.context_id = :contextid))";
$plan_ids = $DB->get_fieldset_sql($sql,["contextid"=>$context->id, "userid" => $user->id]);
foreach($plan_ids as $plan_id){
$DB->delete_records("local_treestudyplan_user",["studyplan_id" => $plan_id,"user_id" => $user->id]);
}
// Also delete all invitations for this user
$DB->delete_records("local_treestudyplan_invit",["user_id" => $user->id]);
} else if ($context->contextlevel == CONTEXT_COURSECAT){
$sql = "SELECT s.id FROM {local_treestudyplan} INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
WHERE ( a.user_id = :userid AND s.context_id = :contextid)";
$plan_ids = $DB->get_fieldset_sql($sql,["contextid"=>$context->id, "userid" => $user->id]);
foreach($plan_ids as $plan_id){
$DB->delete_records("local_treestudyplan_user",["studyplan_id" => $plan_id,"user_id" => $user->id]);
}
}
}
}
/**
* 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_system) {
// Add all invitations
$sql = "SELECT i.user_id as userid
FROM {local_treestudyplan_invit} i;";
$userlist->add_from_sql('userid', $sql, []);
// also add "contextless studyplans, they are considered in system context"
$sql = "SELECT a.user_id as userid FROM {local_treestudyplan_user} a
INNER JOIN {local_treestudyplan} s ON a.studyplan_id = s.id
WHERE ( a.context_id is NULL or a.context_id = 0)
";
$userlist->add_from_sql('userid', $sql, []);
}
// add the links to all study plans in this context
$sql = "SELECT a.user_id as userid FROM {local_treestudyplan_user} a
INNER JOIN {local_treestudyplan} s ON a.studyplan_id = s.id
WHERE ( a.context_id = :contextid )
";
$userlist->add_from_sql('userid', $sql, ["contextid" => $context->id]);
}
/**
* 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();
$users = $userlist->get_userids();
list($userinsql, $userinparams) = $DB->get_in_or_equal($users, SQL_PARAMS_NAMED,'user');
$plan_ids = [];
if($context->contextlevel == CONTEXT_SYSTEM){
// Determine the relevant plan_ids for this context
$sql = "SELECT s.id FROM {local_treestudyplan}
WHERE ( s.context_id IS NULL OR s.context_id == 0 OR s.context_id = :contextid)) ";
$plan_ids = $DB->get_fieldset_sql($sql,["contextid"=>$context->id,]);
// If plan ids not empty, they will be processed later
// Also delete all invitations for these users
$sql = "user_id {$userinsql}";
$DB->delete_records_select("local_treestudyplan_invit",$sql,$userinparams);
} else if ($context->contextlevel == CONTEXT_COURSECAT){
$sql = "SELECT s.id FROM {local_treestudyplan}
WHERE (s.context_id = :contextid)";
$plan_ids = $DB->get_fieldset_sql($sql,["contextid"=>$context->id,]);
// If plan ids not empty, they will be processed later
}
// Now delete the studyplan associations if relevant
if(count($plan_ids) >0 && count($users) >0){
list($planinsql,$planinputparams) = $DB->get_in_or_equal($plan_ids, SQL_PARAMS_NAMED,'plan');
$params = $userinparams+$planinputparams;
$sql = "user_id {$userinsql} and studyplan_id {$planinsql}";
$DB->delete_records_select('local_treestudyplan_user', $sql, $params);
}
}
}

View File

@ -1,5 +1,17 @@
<?php
$string['pluginname'] = 'Studyplans';
$string['privacy:metadata'] = 'This plugin stores a link between users and their associated study plans. It also needs to store an email address and user provided handle, which may be a name, to send invitations to view the study plan to whomever the user chooses by email.';
$string['privacy:metadata:invit'] = 'The currently active invitations to view the study plan';
$string['privacy:metadata:invit:user_id'] = 'UserID of the user who shared their studyplan';
$string['privacy:metadata:invit:name'] = 'Name/Handle entered by the user for the invitations recipient';
$string['privacy:metadata:invit:email'] = 'Email address of the invitations recipient';
$string['privacy:metadata:invit:date'] = 'Date the invitation was created';
$string['privacy:metadata:user'] = 'Links between individual users and studyplans';
$string['privacy:metadata:user:user_id'] = 'The UserID of the user';
$string['privacy:metadata:user:studyplan_id'] = 'The studyplan';
$string['treestudyplan:editstudyplan'] = "Manage studyplans";
$string['treestudyplan:configure'] = "Configure studyplans";
$string['treestudyplan:viewuserreports'] = "View study plan of others";

View File

@ -1,6 +1,18 @@
<?php
$string['pluginname'] = 'Studieplannen';
$string['privacy:metadata'] = 'Deze plugin slaat een koppeling op tussen de gebruiker en diens persoonlijk gekoppelde studieplannen. Ook kan een gebruiker op basis van uitnodiging diens studieplan delen met een ander daarvoor worden gebruikersid en emailadres en door de gebruiker opgegeven naam van de ontvanger opgeslagen.';
$string['privacy:metadata:invit'] = 'De gegevens van actieve uitnodigingen om iemands studieplannen te bekijken';
$string['privacy:metadata:invit:user_id'] = 'Gebruikers-ID van de gebruiker';
$string['privacy:metadata:invit:name'] = 'Naam/Beschrijving die de gebruiker opgeeft voor de ontvanger';
$string['privacy:metadata:invit:email'] = 'E-Mail adres van de ontvanger';
$string['privacy:metadata:invit:date'] = 'Datum waarop de uitnodiging is aangemaakt';
$string['privacy:metadata:user'] = 'Persoonlijke koppelingen tussen gebruiker en studieplan';
$string['privacy:metadata:user:user_id'] = 'Gebruikers-ID';
$string['privacy:metadata:user:studyplan_id'] = 'ID van gekoppeld studieplan';
$string['treestudyplan:editstudyplan'] = "Studieplanen beheren";
$string['treestudyplan:configure'] = "Studieplannen configureren";
$string['treestudyplan:viewuserreports'] = "Studieplannen van anderen bekijken";