mirror of
https://github.com/moodle/moodle.git
synced 2025-04-19 07:25:30 +02:00
MDL-61899 tool_dataprivacy: Addition of plugin compliance registry.
Includes MDL-61489
This commit is contained in:
parent
e95f0def95
commit
d6ff9edd4f
145
admin/tool/dataprivacy/classes/metadata_registry.php
Normal file
145
admin/tool/dataprivacy/classes/metadata_registry.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Class containing helper methods for processing data requests.
|
||||
*
|
||||
* @package tool_dataprivacy
|
||||
* @copyright 2018 Adrian Greeve
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace tool_dataprivacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Class containing helper methods for processing data requests.
|
||||
*
|
||||
* @copyright 2018 Adrian Greeve
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class metadata_registry {
|
||||
|
||||
/**
|
||||
* Returns plugin types / plugins and the user data that it stores in a format that can be sent to a template.
|
||||
*
|
||||
* @return array An array with all of the plugin types / plugins and the user data they store.
|
||||
*/
|
||||
public function get_registry_metadata() {
|
||||
$manager = new \core_privacy\manager();
|
||||
$pluginman = \core_plugin_manager::instance();
|
||||
$contributedplugins = $this->get_contrib_list();
|
||||
$metadata = $manager->get_metadata_for_components();
|
||||
$fullyrichtree = $this->get_full_component_list();
|
||||
foreach ($fullyrichtree as $branch => $leaves) {
|
||||
$plugintype = $leaves['plugin_type'];
|
||||
$plugins = array_map(function($component) use ($manager, $metadata, $contributedplugins, $plugintype, $pluginman) {
|
||||
// Use the plugin name for the plugins, ignore for core subsystems.
|
||||
$internaldata = ($plugintype == 'core') ? ['component' => $component] :
|
||||
['component' => $pluginman->plugin_name($component)];
|
||||
$internaldata['raw_component'] = $component;
|
||||
if ($manager->component_is_compliant($component)) {
|
||||
$internaldata['compliant'] = true;
|
||||
if (isset($metadata[$component])) {
|
||||
$collection = $metadata[$component]->get_collection();
|
||||
$internaldata = $this->format_metadata($collection, $component, $internaldata);
|
||||
} else {
|
||||
// Call get_reason for null provider.
|
||||
$internaldata['nullprovider'] = get_string($manager->get_null_provider_reason($component), $component);
|
||||
}
|
||||
} else {
|
||||
$internaldata['compliant'] = false;
|
||||
}
|
||||
// Check to see if we are an external plugin.
|
||||
$componentshortname = explode('_', $component);
|
||||
$shortname = array_pop($componentshortname);
|
||||
if (isset($contributedplugins[$plugintype][$shortname])) {
|
||||
$internaldata['external'] = true;
|
||||
}
|
||||
return $internaldata;
|
||||
}, $leaves['plugins']);
|
||||
$fullyrichtree[$branch]['plugin_type_raw'] = $plugintype;
|
||||
// We're done using the plugin type. Convert it to a readable string.
|
||||
$fullyrichtree[$branch]['plugin_type'] = $pluginman->plugintype_name($plugintype);
|
||||
$fullyrichtree[$branch]['plugins'] = $plugins;
|
||||
}
|
||||
return $fullyrichtree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the metadata for use with a template.
|
||||
*
|
||||
* @param array $collection The collection associated with the component that we want to expand and format.
|
||||
* @param string $component The component that we are dealing in
|
||||
* @param array $internaldata The array to add the formatted metadata to.
|
||||
* @return array The internal data array with the formatted metadata.
|
||||
*/
|
||||
protected function format_metadata($collection, $component, $internaldata) {
|
||||
foreach ($collection as $collectioninfo) {
|
||||
$privacyfields = $collectioninfo->get_privacy_fields();
|
||||
$fields = '';
|
||||
if (!empty($privacyfields)) {
|
||||
$fields = array_map(function($key, $field) use ($component) {
|
||||
return [
|
||||
'field_name' => $key,
|
||||
'field_summary' => get_string($field, $component)
|
||||
];
|
||||
}, array_keys($privacyfields), $privacyfields);
|
||||
}
|
||||
// Can the metadata types be located somewhere else besides core?
|
||||
$items = explode('\\', get_class($collectioninfo));
|
||||
$type = array_pop($items);
|
||||
$typedata = [
|
||||
'name' => $collectioninfo->get_name(),
|
||||
'type' => $type,
|
||||
'fields' => $fields,
|
||||
'summary' => get_string($collectioninfo->get_summary(), $component)
|
||||
];
|
||||
if (strpos($type, 'subsystem_link') === 0 || strpos($type, 'plugintype_link') === 0) {
|
||||
$typedata['link'] = true;
|
||||
}
|
||||
$internaldata['metadata'][] = $typedata;
|
||||
}
|
||||
return $internaldata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the full list of components.
|
||||
*
|
||||
* @return array An array of plugin types which contain plugin data.
|
||||
*/
|
||||
protected function get_full_component_list() {
|
||||
$list = \core_component::get_component_list();
|
||||
$formattedlist = [];
|
||||
foreach ($list as $plugintype => $plugin) {
|
||||
$formattedlist[] = ['plugin_type' => $plugintype, 'plugins' => array_keys($plugin)];
|
||||
}
|
||||
return $formattedlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of contributed plugins installed on the system.
|
||||
*
|
||||
* @return array A list of contributed plugins installed.
|
||||
*/
|
||||
protected function get_contrib_list() {
|
||||
return array_map(function($plugins) {
|
||||
return array_filter($plugins, function($plugindata) {
|
||||
return !$plugindata->is_standard();
|
||||
});
|
||||
}, \core_plugin_manager::instance()->get_plugins());
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Data registry renderable.
|
||||
*
|
||||
* @package tool_dataprivacy
|
||||
* @copyright 2018 David Monllao
|
||||
* @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 stdClass;
|
||||
use templatable;
|
||||
|
||||
require_once($CFG->libdir . '/coursecatlib.php');
|
||||
require_once($CFG->dirroot . '/' . $CFG->admin . '/tool/dataprivacy/lib.php');
|
||||
require_once($CFG->libdir . '/blocklib.php');
|
||||
|
||||
/**
|
||||
* Class containing the data registry compliance renderable
|
||||
*
|
||||
* @copyright 2018 Adrian Greeve
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class data_registry_compliance_page implements renderable, templatable {
|
||||
|
||||
protected $metadata;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct($metadata) {
|
||||
$this->metadata = $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export this data so it can be used as the context for a mustache template.
|
||||
*
|
||||
* @param renderer_base $output
|
||||
* @return stdClass
|
||||
*/
|
||||
public function export_for_template(renderer_base $output) {
|
||||
global $PAGE;
|
||||
|
||||
$data = ['types' => $this->metadata];
|
||||
// print_object($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -91,6 +91,18 @@ class renderer extends plugin_renderer_base {
|
||||
return parent::render_from_template('tool_dataprivacy/data_registry', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the data compliance registry.
|
||||
*
|
||||
* @param data_registry_page $page
|
||||
* @return string html for the page
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public function render_data_registry_compliance_page(data_registry_compliance_page $page) {
|
||||
$data = $page->export_for_template($this);
|
||||
return parent::render_from_template('tool_dataprivacy/data_registry_compliance', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the purposes management page.
|
||||
*
|
||||
|
46
admin/tool/dataprivacy/dataregistry2.php
Normal file
46
admin/tool/dataprivacy/dataregistry2.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?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');
|
||||
|
||||
$contextlevel = optional_param('contextlevel', CONTEXT_SYSTEM, PARAM_INT);
|
||||
$contextid = optional_param('contextid', 0, PARAM_INT);
|
||||
|
||||
$url = new moodle_url('/admin/tool/dataprivacy/dataregistry2.php');
|
||||
$title = get_string('dataregistry2', 'tool_dataprivacy');
|
||||
|
||||
\tool_dataprivacy\page_helper::setup($url, $title);
|
||||
|
||||
$output = $PAGE->get_renderer('tool_dataprivacy');
|
||||
echo $output->header();
|
||||
|
||||
// Get data!
|
||||
$metadatatool = new \tool_dataprivacy\metadata_registry();
|
||||
$metadata = $metadatatool->get_registry_metadata();
|
||||
|
||||
$dataregistry = new tool_dataprivacy\output\data_registry_compliance_page($metadata);
|
||||
|
||||
echo $output->render($dataregistry);
|
||||
echo $OUTPUT->footer();
|
@ -41,6 +41,7 @@ $string['categorycreated'] = 'Category created';
|
||||
$string['categorieslist'] = 'List of data categories';
|
||||
$string['categoryupdated'] = 'Category updated';
|
||||
$string['close'] = 'Close';
|
||||
$string['compliant'] = 'Compliant';
|
||||
$string['confirmapproval'] = 'Do you really want to approve this data request?';
|
||||
$string['confirmcontextdeletion'] = 'Do you really want to confirm the deletion of the selected contexts? This will also delete all of the user data for their respective sub-contexts.';
|
||||
$string['confirmdenial'] = 'Do you really want deny this data request?';
|
||||
@ -61,7 +62,10 @@ $string['datadeletionpagehelp'] = 'This page lists the contexts that are already
|
||||
$string['dataprivacy:makedatarequestsforchildren'] = 'Make data requests for children';
|
||||
$string['dataprivacy:managedatarequests'] = 'Manage data requests';
|
||||
$string['dataprivacy:managedataregistry'] = 'Manage data registry';
|
||||
$string['dataprivacysettings'] = 'Data privacy settings';
|
||||
$string['dataregistry'] = 'Data registry';
|
||||
$string['dataregistry2'] = 'Plugin privacy registry';
|
||||
$string['dataregistrysetup'] = 'Settings';
|
||||
$string['datarequestemailsubject'] = 'Data request: {$a}';
|
||||
$string['datarequests'] = 'Data requests';
|
||||
$string['daterequested'] = 'Date requested';
|
||||
@ -97,6 +101,12 @@ $string['errorsendingmessagetodpo'] = 'An error was encountered while trying to
|
||||
$string['expiredretentionperiodtask'] = 'Expired retention period';
|
||||
$string['expiry'] = 'Expiry';
|
||||
$string['frontpagecourse'] = 'Front page course';
|
||||
$string['expandplugin'] = 'Expand and collapse plugin.';
|
||||
$string['expandplugintype'] = 'Expand and collapse plugin type.';
|
||||
$string['explanationtitle'] = 'Icons used on this page and what they mean.';
|
||||
$string['external'] = 'External';
|
||||
$string['externalexplanation'] = 'An additional plugin installed on this site.';
|
||||
$string['hide'] = 'Collapse all';
|
||||
$string['inherit'] = 'Inherit';
|
||||
$string['messageprovider:contactdataprotectionofficer'] = 'Data requests';
|
||||
$string['messageprovider:datarequestprocessingresults'] = 'Data request processing results';
|
||||
@ -120,6 +130,7 @@ $string['nopurposes'] = 'There are no purposes yet';
|
||||
$string['nosubjectaccessrequests'] = 'There are no data requests that you need to act on';
|
||||
$string['nosystemdefaults'] = 'Site purpose and category have not yet been defined.';
|
||||
$string['notset'] = 'Not set (use the default value)';
|
||||
$string['pluginregistrytitle'] = 'Plugin privacy compliance registry';
|
||||
$string['privacy'] = 'Privacy';
|
||||
$string['privacy:metadata:request'] = 'Information from personal data requests (subject access and deletion requests) made for this site.';
|
||||
$string['privacy:metadata:request:comments'] = 'Any user comments accompanying the request.';
|
||||
@ -151,6 +162,8 @@ $string['requesttypeexport'] = 'Export all of my personal data';
|
||||
$string['requesttypeexportshort'] = 'Export';
|
||||
$string['requesttypeothers'] = 'General inquiry';
|
||||
$string['requesttypeothersshort'] = 'Others';
|
||||
$string['requiresattention'] = 'Requires attention.';
|
||||
$string['requiresattentionexplanation'] = 'This plugin does not implement the Moodle privacy API. If this plugin stores any personal data it will not be able to be exported or deleted through Moodle\'s privacy system.';
|
||||
$string['resultdeleted'] = 'You recently requested to have your account and personal data in {$a} to be deleted. This process has been completed and you will no longer be able to log in.';
|
||||
$string['resultdownloadready'] = 'Your copy of your personal data in {$a} that you recently requested is now available for download. Please click on the link below to go to the download page.';
|
||||
$string['reviewdata'] = 'Review data';
|
||||
@ -171,3 +184,4 @@ $string['statusrejected'] = 'Rejected';
|
||||
$string['subjectscope'] = 'Subject scope';
|
||||
$string['user'] = 'User';
|
||||
$string['viewrequest'] = 'View the request';
|
||||
$string['visible'] = 'Expand all';
|
||||
|
@ -70,4 +70,8 @@ $ADMIN->add('privacy', new admin_externalpage('dataregistry', get_string('datare
|
||||
// Link that leads to the review page of expired contexts that are up for deletion.
|
||||
$ADMIN->add('privacy', new admin_externalpage('datadeletion', get_string('datadeletion', 'tool_dataprivacy'),
|
||||
new moodle_url('/admin/tool/dataprivacy/datadeletion.php'), 'tool/dataprivacy:managedataregistry')
|
||||
|
||||
// Link that leads to the other data registry management page.
|
||||
$ADMIN->add('dataprivacysettings', new admin_externalpage('dataregistry2', get_string('dataregistry2', 'tool_dataprivacy'),
|
||||
new moodle_url('/admin/tool/dataprivacy/dataregistry2.php'), 'tool/dataprivacy:managedataregistry')
|
||||
);
|
||||
|
127
admin/tool/dataprivacy/templates/component_status.mustache
Normal file
127
admin/tool/dataprivacy/templates/component_status.mustache
Normal file
@ -0,0 +1,127 @@
|
||||
{{!
|
||||
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 comments.
|
||||
|
||||
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/component_status
|
||||
|
||||
Data registry main page.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
* none
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"compliant" : "True",
|
||||
"raw_component" : "core_comment",
|
||||
"component" : "Core comment",
|
||||
"external" : "True",
|
||||
"metadata" : {
|
||||
"name" : "comments",
|
||||
"type" : "database_table",
|
||||
"summary" : "Stores comments of users",
|
||||
"fields" : {
|
||||
"field_name" : "content",
|
||||
"field_summary" : "Stores the text of the content."
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
{{#compliant}}
|
||||
<a class="expand" data-component="{{raw_component}}" href='#'>
|
||||
<h4 class="d-inline p-r-1 p-l-1" id="{{raw_component}}">{{#pix}}t/collapsed, moodle, {{#str}}expandplugin, tool_dataprivacy{{/str}}{{/pix}}{{component}}</h4>
|
||||
</a>
|
||||
<!-- <span class="badge badge-pill badge-success">{{#str}}compliant, tool_dataprivacy{{/str}}</span> -->
|
||||
{{/compliant}}
|
||||
{{^compliant}}
|
||||
<h4 class="d-inline p-r-1 p-l-1" id="{{raw_component}}">{{component}}</h4>
|
||||
<span>{{#pix}}i/risk_xss, moodle, {{#str}}requiresattention, tool_dataprivacy{{/str}}{{/pix}}</span>
|
||||
{{/compliant}}
|
||||
{{#external}}
|
||||
<span class="badge badge-pill badge-notice">{{#str}}external, tool_dataprivacy{{/str}}</span>
|
||||
{{/external}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#compliant}}
|
||||
<div class="hide" data-section="{{raw_component}}" aria-expanded="false">
|
||||
{{#metadata}}
|
||||
<hr />
|
||||
<div class="row-fluid">
|
||||
<div class="span2 col-xs-3">
|
||||
{{#link}}
|
||||
<a href="#{{name}}"><h5>{{name}}</h5></a>
|
||||
{{/link}}
|
||||
{{^link}}
|
||||
<h5>{{name}}</h5>
|
||||
{{/link}}
|
||||
<div class="p-b-1 small text-muted">{{type}}</div>
|
||||
</div>
|
||||
<div class="span10 col-xs-9">{{summary}}</div>
|
||||
</div>
|
||||
<table class="table table-sm">
|
||||
<tbody>
|
||||
{{#fields}}
|
||||
<tr class="row">
|
||||
<td class="col-xs-3">{{field_name}}</td>
|
||||
<td class="col-xs-9">{{field_summary}}</td>
|
||||
</tr>
|
||||
{{/fields}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{/metadata}}
|
||||
{{#nullprovider}}
|
||||
<hr />
|
||||
<div>{{nullprovider}}</div>
|
||||
{{/nullprovider}}
|
||||
</div>
|
||||
{{/compliant}}
|
||||
<hr />
|
||||
|
||||
|
||||
{{#js}}
|
||||
require(['jquery', 'core/url'], function($, url) {
|
||||
|
||||
var expandedImage = $('<img alt="" src="' + url.imageUrl('t/expanded') + '"/>');
|
||||
var collapsedImage = $('<img alt="" src="' + url.imageUrl('t/collapsed') + '"/>');
|
||||
|
||||
$('.expand').click(function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
e.stopImmediatePropagation();
|
||||
var component = $(this).data('component');
|
||||
var metadata = $('[data-section=\'' + component + '\']');
|
||||
var metainfo = metadata.attr('class');
|
||||
if (metadata.attr('class') === 'hide') {
|
||||
metadata.attr('class', 'visible');
|
||||
$(this).children('img').attr('src', expandedImage.attr('src'));
|
||||
metadata.attr('aria-expanded', true);
|
||||
} else {
|
||||
metadata.attr('class', 'hide');
|
||||
$(this).children('img').attr('src', collapsedImage.attr('src'));
|
||||
metadata.attr('aria-expanded', false);
|
||||
}
|
||||
});
|
||||
});
|
||||
{{/js}}
|
@ -0,0 +1,110 @@
|
||||
{{!
|
||||
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 comments.
|
||||
|
||||
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/data_registry_compliance
|
||||
|
||||
Data registry main page.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
* none
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"types" : {
|
||||
"plugin_type_raw" : "mod",
|
||||
"plugin_type" : "Activities and Modules"
|
||||
}
|
||||
}
|
||||
}}
|
||||
<div>
|
||||
<h2>{{#str}}pluginregistrytitle, tool_dataprivacy{{/str}}</h2>
|
||||
<hr />
|
||||
<p><strong>{{#str}}explanationtitle, tool_dataprivacy{{/str}}</strong></p>
|
||||
<dl>
|
||||
<dt>{{#pix}}i/risk_xss, moodle, {{#str}}requiresattention, tool_dataprivacy{{/str}}{{/pix}}</dt>
|
||||
<dd>{{#str}}requiresattentionexplanation, tool_dataprivacy{{/str}}</dd>
|
||||
<dt><span class="badge badge-pill badge-notice">{{#str}}external, tool_dataprivacy{{/str}}</span></dt>
|
||||
<dd>{{#str}}externalexplanation, tool_dataprivacy{{/str}}</dd>
|
||||
</dl>
|
||||
<hr />
|
||||
<div><a class="tool_dataprivacy-expand-all pull-right" href="#" data-visibility-state='visible'>{{#str}}visible, tool_dataprivacy{{/str}}</a></div>
|
||||
{{#types}}
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<a class="other-expand" href='#' data-plugin="{{plugin_type_raw}}">
|
||||
<h3 id="{{plugin_type_raw}}">{{#pix}}t/collapsed, moodle, {{#str}}expandplugintype, tool_dataprivacy{{/str}}{{/pix}}{{plugin_type}}</h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hide" data-plugintarget="{{plugin_type_raw}}" aria-expanded="false">
|
||||
{{#plugins}}
|
||||
{{> tool_dataprivacy/component_status}}
|
||||
{{/plugins}}
|
||||
</div>
|
||||
</div>
|
||||
{{/types}}
|
||||
</div>
|
||||
{{#js}}
|
||||
require(['jquery', 'core/url', 'core/str'], function($, url, str) {
|
||||
|
||||
var expandedImage = $('<img alt="" src="' + url.imageUrl('t/expanded') + '"/>');
|
||||
var collapsedImage = $('<img alt="" src="' + url.imageUrl('t/collapsed') + '"/>');
|
||||
|
||||
$('.other-expand').click(function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
e.stopImmediatePropagation();
|
||||
window.console.log(this);
|
||||
var plugin = $(this).data('plugin');
|
||||
var metadata = $('[data-plugintarget=\'' + plugin + '\']');
|
||||
if (metadata.attr('class') === 'hide') {
|
||||
metadata.attr('class', 'visible');
|
||||
$(this).children('img').attr('src', expandedImage.attr('src'));
|
||||
metadata.attr('aria-expanded', true);
|
||||
} else {
|
||||
metadata.attr('class', 'hide');
|
||||
$(this).children('img').attr('src', collapsedImage.attr('src'));
|
||||
metadata.attr('aria-expanded', false);
|
||||
}
|
||||
});
|
||||
|
||||
$('.tool_dataprivacy-expand-all').click(function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var nextstate = $(this).data('visibilityState');
|
||||
var currentstate = (nextstate == 'visible') ? 'hide' : 'visible';
|
||||
var ariaexpandedstate = (nextstate == 'visible') ? true : false;
|
||||
$('.' + currentstate).each(function() {
|
||||
$(this).attr('class', nextstate);
|
||||
$(this).attr('aria-expanded', ariaexpandedstate);
|
||||
});
|
||||
$(this).data('visibilityState', currentstate);
|
||||
|
||||
str.get_string(currentstate, 'tool_dataprivacy').then(function(langString) {
|
||||
var visibilitynode = $('.tool_dataprivacy-expand-all');
|
||||
visibilitynode.html(langString);
|
||||
}).catch(Notification.exception);
|
||||
});
|
||||
});
|
||||
{{/js}}
|
104
admin/tool/dataprivacy/tests/metadata_registry_test.php
Normal file
104
admin/tool/dataprivacy/tests/metadata_registry_test.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Metadata registry tests.
|
||||
*
|
||||
* @package tool_dataprivacy
|
||||
* @copyright 2018 Adrian Greeve <adriangreeve.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
global $CFG;
|
||||
|
||||
/**
|
||||
* Metadata registry tests.
|
||||
*
|
||||
* @package tool_dataprivacy
|
||||
* @copyright 2018 Adrian Greeve <adriangreeve.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class tool_dataprivacy_metadata_registry_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Fetch the meta data and return it in a form that we can easily unit test.
|
||||
*
|
||||
* @return array the meta data.
|
||||
*/
|
||||
protected function get_meta_data() {
|
||||
$metadataregistry = new \tool_dataprivacy\metadata_registry();
|
||||
$data = $metadataregistry->get_registry_metadata();
|
||||
$newdata = [];
|
||||
foreach ($data as $value) {
|
||||
$additional = [];
|
||||
foreach ($value['plugins'] as $moredata) {
|
||||
$additional[$moredata['raw_component']] = $moredata;
|
||||
}
|
||||
$newdata[$value['plugin_type_raw']] = $additional;
|
||||
}
|
||||
return $newdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can fetch metadata about users for the whole system and that it matches the system count.
|
||||
*/
|
||||
public function test_get_registry_metadata_count() {
|
||||
$data = $this->get_meta_data();
|
||||
|
||||
$plugintypes = \core_component::get_plugin_types();
|
||||
|
||||
// Check that we have the correct number of plugin types.
|
||||
$plugincount = count($plugintypes) + 1; // Plus one for core.
|
||||
$this->assertEquals($plugincount, count($data));
|
||||
|
||||
// Check that each plugin count matches.
|
||||
foreach ($plugintypes as $plugintype => $notused) {
|
||||
$plugins = \core_component::get_plugin_list($plugintype);
|
||||
$this->assertEquals(count($plugins), count($data[$plugintype]));
|
||||
}
|
||||
|
||||
// Let's check core subsystems.
|
||||
$coresubsystems = \core_component::get_core_subsystems();
|
||||
$this->assertEquals(count($coresubsystems), count($data['core']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the expected null provider information is returned.
|
||||
*/
|
||||
public function test_get_registry_metadata_null_provider_details() {
|
||||
$data = $this->get_meta_data();
|
||||
|
||||
// Check details of core privacy (a null privder) are correct.
|
||||
$coreprivacy = $data['core']['core_privacy'];
|
||||
$this->assertEquals(1, $coreprivacy['compliant']);
|
||||
$this->assertNotEmpty($coreprivacy['nullprovider']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the expected privacy provider information is returned.
|
||||
*/
|
||||
public function test_get_registry_metadata_provider_details() {
|
||||
$data = $this->get_meta_data();
|
||||
|
||||
// Check details of core rating (a normal provider) are correct.
|
||||
$corerating = $data['core']['core_rating'];
|
||||
$this->assertEquals(1, $corerating['compliant']);
|
||||
$this->assertNotEmpty($corerating['metadata']);
|
||||
$this->assertEquals('database_table', $corerating['metadata'][0]['type']);
|
||||
$this->assertNotEmpty('database_table', $corerating['metadata'][0]['fields']);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user