You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
8.2 KiB

<?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();
$manager->set_observer(new \tool_dataprivacy\manager_observer());
$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 if ($manager->is_empty_subsystem($component)) {
// This is an unused subsystem.
// Use the generic string.
$internaldata['nullprovider'] = get_string('privacy:subsystem:empty', 'core_privacy');
} 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.
// Plugin names can contain _ characters, limit to 2 to just remove initial plugintype.
$componentshortname = explode('_', $component, 2);
$shortname = array_pop($componentshortname);
if (isset($contributedplugins[$plugintype][$shortname])) {
$internaldata['external'] = true;
}
// Additional interface checks.
if (!$manager->is_empty_subsystem($component)) {
$classname = $manager->get_provider_classname_for_component($component);
if (class_exists($classname)) {
$componentclass = new $classname();
// Check if the interface is deprecated.
if ($componentclass instanceof \core_privacy\local\deprecated) {
$internaldata['deprecated'] = true;
}
// Check that the core_userlist_provider is implemented for all user data providers.
if ($componentclass instanceof \core_privacy\local\request\core_user_data_provider
&& !$componentclass instanceof \core_privacy\local\request\core_userlist_provider) {
$internaldata['userlistnoncompliance'] = true;
}
// Check that any type of userlist_provider is implemented for all shared data providers.
if ($componentclass instanceof \core_privacy\local\request\shared_data_provider
&& !$componentclass instanceof \core_privacy\local\request\userlist_provider) {
$internaldata['userlistnoncompliance'] = 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() {
global $CFG;
$list = \core_component::get_component_list();
$list['core']['core'] = "{$CFG->dirroot}/lib";
$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());
}
}