MDL-62558 tool_dataprivacy: Create a summary page for users.
authorAdrian Greeve <abgreeve@gmail.com>
Fri, 28 Sep 2018 07:13:31 +0000 (15:13 +0800)
committerAdrian Greeve <abgreeve@gmail.com>
Wed, 3 Oct 2018 02:16:25 +0000 (10:16 +0800)
admin/tool/dataprivacy/classes/output/renderer.php
admin/tool/dataprivacy/classes/output/summary_page.php [new file with mode: 0644]
admin/tool/dataprivacy/lang/en/tool_dataprivacy.php
admin/tool/dataprivacy/lib.php
admin/tool/dataprivacy/summary.php [new file with mode: 0644]
admin/tool/dataprivacy/templates/summary.mustache [new file with mode: 0644]

index 09bcb1c..341bc8a 100644 (file)
@@ -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 (file)
index 0000000..4b93b82
--- /dev/null
@@ -0,0 +1,132 @@
+<?php
+// 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 <http://www.gnu.org/licenses/>.
+
+/**
+ * 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;
+    }
+}
index 7b8aa51..5ab4dfd 100644 (file)
@@ -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';
@@ -276,6 +278,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';
index fbeb61d..a9712d1 100644 (file)
@@ -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 (file)
index 0000000..3b99ee3
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+// 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 <http://www.gnu.org/licenses/>.
+
+/**
+ * Prints the compliance data registry main page.
+ *
+ * @copyright 2018 onwards Adrian Greeve <adriangreeve.com>
+ * @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 (file)
index 0000000..22c0221
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @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": "<p>Description for category</p>"
+                },
+                "purpose":
+                {
+                    "name": "Test purpose",
+                    "description": "<p>Description for purpose</p>",
+                    "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"
+                }
+            }
+        ]
+    }
+}}
+<h2>{{#str}}dataretentionsummary, tool_dataprivacy{{/str}}</h2>
+<p>{{#str}}dataretentionexplanation, tool_dataprivacy{{/str}}</p>
+<div>
+    {{#contexts}}
+        <div class="card mb-3">
+            <div class="card-header"><h3>{{contextname}}</h3></div>
+            <div class="card-body p-l-2 p-r-2">
+
+                {{#category.name}}
+                <h4>{{#str}}category, tool_dataprivacy{{/str}}</h4>
+                <dl>
+                    <dt>{{category.name}}</dt>
+                    <dd>{{{category.description}}}</dd>
+                </dl>
+                <hr />
+                {{/category.name}}
+                <h4>{{#str}}purpose, tool_dataprivacy{{/str}}</h4>
+                <dl>
+                    <dt>{{purpose.name}}</dt>
+                    <dd>{{{purpose.description}}}</dd>
+                    <dt>{{#str}}retentionperiod, tool_dataprivacy{{/str}}</dt>
+                    <dd>{{purpose.formattedretentionperiod}}</dd>
+                </dl>
+                {{#purpose.lawfulbases}}
+                <table class="table table-bordered">
+                    <thead><tr><th colspan="2">{{#str}}lawfulbases, tool_dataprivacy{{/str}}</th></tr></thead>
+                    <tbody>
+                    {{#purpose.formattedlawfulbases}}
+                        <tr>
+                            <td>{{name}}</td>
+                            <td>{{description}}</td>
+                        </tr>
+                    {{/purpose.formattedlawfulbases}}
+                    </tbody>
+                </table>
+                {{/purpose.lawfulbases}}
+                {{#purpose.sensitivedatareasons}}
+                <table class="table table-bordered">
+                    <thead><tr><th colspan="2">{{#str}}sensitivedatareasons, tool_dataprivacy{{/str}}</th></tr></thead>
+                    <tbody>
+                    {{#purpose.formattedsensitivedatareasons}}
+                        <tr>
+                            <td>{{name}}</td>
+                            <td>{{description}}</td>
+                        </tr>
+                    {{/purpose.formattedsensitivedatareasons}}
+                    </tbody>
+                </table>
+                {{/purpose.sensitivedatareasons}}
+            </div>
+        </div>
+    {{/contexts}}
+</div>
\ No newline at end of file