From df3cc8c9c5ee428fe668017dbff219f8eb6ab292 Mon Sep 17 00:00:00 2001 From: Adrian Greeve Date: Fri, 28 Sep 2018 15:13:31 +0800 Subject: [PATCH] MDL-62558 tool_dataprivacy: Create a summary page for users. --- .../dataprivacy/classes/output/renderer.php | 11 ++ .../classes/output/summary_page.php | 132 ++++++++++++++++++ .../dataprivacy/lang/en/tool_dataprivacy.php | 3 + admin/tool/dataprivacy/lib.php | 19 +++ admin/tool/dataprivacy/summary.php | 41 ++++++ .../dataprivacy/templates/summary.mustache | 123 ++++++++++++++++ 6 files changed, 329 insertions(+) create mode 100644 admin/tool/dataprivacy/classes/output/summary_page.php create mode 100644 admin/tool/dataprivacy/summary.php create mode 100644 admin/tool/dataprivacy/templates/summary.mustache diff --git a/admin/tool/dataprivacy/classes/output/renderer.php b/admin/tool/dataprivacy/classes/output/renderer.php index 09bcb1c45a1..341bc8a4440 100644 --- a/admin/tool/dataprivacy/classes/output/renderer.php +++ b/admin/tool/dataprivacy/classes/output/renderer.php @@ -139,4 +139,15 @@ class renderer extends plugin_renderer_base { $data = $page->export_for_template($this); return parent::render_from_template('tool_dataprivacy/data_deletion', $data); } + + /** + * Render the user data retention summary page. + * + * @param summary_page $page + * @return string html for the page. + */ + public function render_summary_page(summary_page $page) { + $data = $page->export_for_template($this); + return parent::render_from_template('tool_dataprivacy/summary', $data); + } } diff --git a/admin/tool/dataprivacy/classes/output/summary_page.php b/admin/tool/dataprivacy/classes/output/summary_page.php new file mode 100644 index 00000000000..4b93b8272c9 --- /dev/null +++ b/admin/tool/dataprivacy/classes/output/summary_page.php @@ -0,0 +1,132 @@ +. + +/** + * Summary page renderable. + * + * @package tool_dataprivacy + * @copyright 2018 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace tool_dataprivacy\output; +defined('MOODLE_INTERNAL') || die(); + +use renderable; +use renderer_base; +use templatable; + + +/** + * Class containing the summary page renderable. + * + * @copyright 2018 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class summary_page implements renderable, templatable { + + /** + * Export this data so it can be used as the context for a mustache template. + * + * @param renderer_base $output + * @return array + */ + public function export_for_template(renderer_base $output) { + $contextlevels = [ + 'contextlevelname10' => CONTEXT_SYSTEM, + 'contextlevelname30' => CONTEXT_USER, + 'contextlevelname40' => CONTEXT_COURSECAT, + 'contextlevelname50' => CONTEXT_COURSE, + 'contextlevelname70' => CONTEXT_MODULE, + 'contextlevelname80' => CONTEXT_BLOCK + ]; + + $data = []; + $context = \context_system::instance(); + + foreach ($contextlevels as $levelname => $level) { + $classname = \context_helper::get_class_for_level($level); + list($purposevar, $categoryvar) = \tool_dataprivacy\data_registry::var_names_from_context($classname); + $purposeid = get_config('tool_dataprivacy', $purposevar); + $categoryid = get_config('tool_dataprivacy', $categoryvar); + + $section = []; + $section['contextname'] = get_string($levelname, 'tool_dataprivacy'); + + if (empty($purposeid)) { + list($purposeid, $categoryid) = + \tool_dataprivacy\data_registry::get_effective_default_contextlevel_purpose_and_category($level); + } + if ($purposeid == -1) { + $purposeid = 0; + } + $purpose = new \tool_dataprivacy\purpose($purposeid); + $export = new \tool_dataprivacy\external\purpose_exporter($purpose, ['context' => $context]); + $purposedata = $export->export($output); + $section['purpose'] = $purposedata; + + if (empty($categoryid)) { + list($purposeid, $categoryid) = + \tool_dataprivacy\data_registry::get_effective_default_contextlevel_purpose_and_category($level); + } + if ($categoryid == -1) { + $categoryid = 0; + } + $category = new \tool_dataprivacy\category($categoryid); + $export = new \tool_dataprivacy\external\category_exporter($category, ['context' => $context]); + $categorydata = $export->export($output); + $section['category'] = $categorydata; + $data['contexts'][] = $section; + } + + // Get activity module plugin info. + $pluginmanager = \core_plugin_manager::instance(); + $modplugins = $pluginmanager->get_enabled_plugins('mod'); + + foreach ($modplugins as $name) { + $classname = \context_helper::get_class_for_level($contextlevels['contextlevelname70']); + list($purposevar, $categoryvar) = \tool_dataprivacy\data_registry::var_names_from_context($classname, $name); + $categoryid = get_config('tool_dataprivacy', $categoryvar); + $purposeid = get_config('tool_dataprivacy', $purposevar); + if ($categoryid === false && $purposeid === false) { + // If no purpose and category has been set for this plugin, then there's no need to show this on the list. + continue; + } + + $section = []; + $section['contextname'] = $pluginmanager->plugin_name('mod_' . $name); + + if ($purposeid == -1) { + $purposeid = 0; + } + $purpose = new \tool_dataprivacy\purpose($purposeid); + $export = new \tool_dataprivacy\external\purpose_exporter($purpose, ['context' => $context]); + $purposedata = $export->export($output); + $section['purpose'] = $purposedata; + + if ($categoryid == -1) { + $categoryid = 0; + } + $category = new \tool_dataprivacy\category($categoryid); + $export = new \tool_dataprivacy\external\category_exporter($category, ['context' => $context]); + $categorydata = $export->export($output); + $section['category'] = $categorydata; + + $data['contexts'][] = $section; + } + + return $data; + } +} diff --git a/admin/tool/dataprivacy/lang/en/tool_dataprivacy.php b/admin/tool/dataprivacy/lang/en/tool_dataprivacy.php index 5a770917606..a08d20d3d59 100644 --- a/admin/tool/dataprivacy/lang/en/tool_dataprivacy.php +++ b/admin/tool/dataprivacy/lang/en/tool_dataprivacy.php @@ -76,6 +76,8 @@ $string['dataprivacy:downloadownrequest'] = 'Download your own exported data'; $string['dataprivacy:downloadallrequests'] = 'Download exported data for everyone'; $string['dataregistry'] = 'Data registry'; $string['dataregistryinfo'] = 'The data registry enables categories (types of data) and purposes (the reasons for processing data) to be set for all content on the site - from users and courses down to activities and blocks. For each purpose, a retention period may be set. When a retention period has expired, the data is flagged and listed for deletion, awaiting admin confirmation.'; +$string['dataretentionexplanation'] = 'This summary shows the default categories and purposes for retaining user\'s information on this system. Certain areas of the system may have more specific categories and purposes than those listed here.'; +$string['dataretentionsummary'] = 'Data retention summary'; $string['datarequestcreatedforuser'] = 'Data request created for {$a}'; $string['datarequestemailsubject'] = 'Data request: {$a}'; $string['datarequests'] = 'Data requests'; @@ -274,6 +276,7 @@ $string['statuspending'] = 'Pending'; $string['statusrejected'] = 'Rejected'; $string['subjectscope'] = 'Subject scope'; $string['subjectscope_help'] = 'The subject scope lists the roles which may be assigned in this context.'; +$string['summary'] = 'Registry configuration summary'; $string['user'] = 'User'; $string['viewrequest'] = 'View the request'; $string['visible'] = 'Expand all'; diff --git a/admin/tool/dataprivacy/lib.php b/admin/tool/dataprivacy/lib.php index fbeb61d7d96..a9712d17378 100644 --- a/admin/tool/dataprivacy/lib.php +++ b/admin/tool/dataprivacy/lib.php @@ -65,6 +65,11 @@ function tool_dataprivacy_myprofile_navigation(tree $tree, $user, $iscurrentuser $category->add_node($node); } + $summaryurl = new moodle_url('/admin/tool/dataprivacy/summary.php'); + $summarynode = new core_user\output\myprofile\node('privacyandpolicies', 'retentionsummary', + get_string('dataretentionsummary', 'tool_dataprivacy'), null, $summaryurl); + $category->add_node($summarynode); + // Add the Privacy category to the tree if it's not empty and it doesn't exist. $nodes = $category->nodes; if (!empty($nodes)) { @@ -77,6 +82,20 @@ function tool_dataprivacy_myprofile_navigation(tree $tree, $user, $iscurrentuser return false; } +/** + * Callback to add footer elements. + * + * @return string HTML footer content + */ +function tool_dataprivacy_standard_footer_html() { + + $url = new moodle_url('/admin/tool/dataprivacy/summary.php'); + $output = html_writer::link($url, get_string('dataretentionsummary', 'tool_dataprivacy')); + $output = html_writer::div($output, 'summaryfooter'); + + return $output; +} + /** * Fragment to add a new purpose. * diff --git a/admin/tool/dataprivacy/summary.php b/admin/tool/dataprivacy/summary.php new file mode 100644 index 00000000000..3b99ee3bcef --- /dev/null +++ b/admin/tool/dataprivacy/summary.php @@ -0,0 +1,41 @@ +. + +/** + * Prints the compliance data registry main page. + * + * @copyright 2018 onwards Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU Public License + * @package tool_dataprivacy + */ + +require_once(__DIR__ . '/../../../config.php'); +require_once($CFG->dirroot . '/' . $CFG->admin . '/tool/dataprivacy/lib.php'); + +$url = new moodle_url('/' . $CFG->admin . '/tool/dataprivacy/summary.php'); +$title = get_string('summary', 'tool_dataprivacy'); + +$context = \context_system::instance(); +$PAGE->set_url($url); +$PAGE->set_context($context); +$PAGE->set_title($title); +$PAGE->set_heading($SITE->fullname); + +$output = $PAGE->get_renderer('tool_dataprivacy'); +echo $output->header(); +$summarypage = new \tool_dataprivacy\output\summary_page(); +echo $output->render($summarypage); +echo $output->footer(); diff --git a/admin/tool/dataprivacy/templates/summary.mustache b/admin/tool/dataprivacy/templates/summary.mustache new file mode 100644 index 00000000000..22c02212041 --- /dev/null +++ b/admin/tool/dataprivacy/templates/summary.mustache @@ -0,0 +1,123 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template tool_dataprivacy/summary + + Summary + + Classes required for JS: + + Data attributes required for JS: + + Context variables required for this template: + + Example context (json): + { + + "contexts": [ + { + "contextname": "Site", + "category": + { + "name": "Test category", + "description": "

Description for category

" + }, + "purpose": + { + "name": "Test purpose", + "description": "

Description for purpose

", + "lawfulbases": "gdpr_art_6_1_c", + "sensitivedatareasons": "gdpr_art_9_2_f", + "formattedlawfulbases": [ + { + "name": "Lawful base 1(a)", + "description": "We need your information" + }, + { + "name": "Lawful base 1(b)", + "description": "We really do need your information" + } + ], + "formattedsensitivedatareasons": [ + { + "name": "Sensitive data reason number 1", + "description": "Number 1" + }, + { + "name": "Sensitive data reason number 1", + "description": "Number 2" + } + ], + "formattedretentionperiod": "10 Years" + } + } + ] + } +}} +

{{#str}}dataretentionsummary, tool_dataprivacy{{/str}}

+

{{#str}}dataretentionexplanation, tool_dataprivacy{{/str}}

+
+ {{#contexts}} +
+

{{contextname}}

+
+ + {{#category.name}} +

{{#str}}category, tool_dataprivacy{{/str}}

+
+
{{category.name}}
+
{{{category.description}}}
+
+
+ {{/category.name}} +

{{#str}}purpose, tool_dataprivacy{{/str}}

+
+
{{purpose.name}}
+
{{{purpose.description}}}
+
{{#str}}retentionperiod, tool_dataprivacy{{/str}}
+
{{purpose.formattedretentionperiod}}
+
+ {{#purpose.lawfulbases}} + + + + {{#purpose.formattedlawfulbases}} + + + + + {{/purpose.formattedlawfulbases}} + +
{{#str}}lawfulbases, tool_dataprivacy{{/str}}
{{name}}{{description}}
+ {{/purpose.lawfulbases}} + {{#purpose.sensitivedatareasons}} + + + + {{#purpose.formattedsensitivedatareasons}} + + + + + {{/purpose.formattedsensitivedatareasons}} + +
{{#str}}sensitivedatareasons, tool_dataprivacy{{/str}}
{{name}}{{description}}
+ {{/purpose.sensitivedatareasons}} +
+
+ {{/contexts}} +
\ No newline at end of file