See Release Notes
Long Term Support Release
Differences Between: [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Class containing helper methods for processing data requests. 19 * 20 * @package tool_dataprivacy 21 * @copyright 2018 Adrian Greeve 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 namespace tool_dataprivacy; 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 /** 29 * Class containing helper methods for processing data requests. 30 * 31 * @copyright 2018 Adrian Greeve 32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 33 */ 34 class metadata_registry { 35 36 /** 37 * Returns plugin types / plugins and the user data that it stores in a format that can be sent to a template. 38 * 39 * @return array An array with all of the plugin types / plugins and the user data they store. 40 */ 41 public function get_registry_metadata() { 42 $manager = new \core_privacy\manager(); 43 $manager->set_observer(new \tool_dataprivacy\manager_observer()); 44 45 $pluginman = \core_plugin_manager::instance(); 46 $contributedplugins = $this->get_contrib_list(); 47 $metadata = $manager->get_metadata_for_components(); 48 $fullyrichtree = $this->get_full_component_list(); 49 foreach ($fullyrichtree as $branch => $leaves) { 50 $plugintype = $leaves['plugin_type']; 51 $plugins = array_map(function($component) use ($manager, $metadata, $contributedplugins, $plugintype, $pluginman) { 52 // Use the plugin name for the plugins, ignore for core subsystems. 53 $internaldata = ($plugintype == 'core') ? ['component' => $component] : 54 ['component' => $pluginman->plugin_name($component)]; 55 $internaldata['raw_component'] = $component; 56 if ($manager->component_is_compliant($component)) { 57 $internaldata['compliant'] = true; 58 if (isset($metadata[$component])) { 59 $collection = $metadata[$component]->get_collection(); 60 $internaldata = $this->format_metadata($collection, $component, $internaldata); 61 } else if ($manager->is_empty_subsystem($component)) { 62 // This is an unused subsystem. 63 // Use the generic string. 64 $internaldata['nullprovider'] = get_string('privacy:subsystem:empty', 'core_privacy'); 65 } else { 66 // Call get_reason for null provider. 67 $internaldata['nullprovider'] = get_string($manager->get_null_provider_reason($component), $component); 68 } 69 } else { 70 $internaldata['compliant'] = false; 71 } 72 // Check to see if we are an external plugin. 73 // Plugin names can contain _ characters, limit to 2 to just remove initial plugintype. 74 $componentshortname = explode('_', $component, 2); 75 $shortname = array_pop($componentshortname); 76 if (isset($contributedplugins[$plugintype][$shortname])) { 77 $internaldata['external'] = true; 78 } 79 80 // Additional interface checks. 81 if (!$manager->is_empty_subsystem($component)) { 82 $classname = $manager->get_provider_classname_for_component($component); 83 if (class_exists($classname)) { 84 $componentclass = new $classname(); 85 // Check if the interface is deprecated. 86 if ($componentclass instanceof \core_privacy\local\deprecated) { 87 $internaldata['deprecated'] = true; 88 } 89 90 // Check that the core_userlist_provider is implemented for all user data providers. 91 if ($componentclass instanceof \core_privacy\local\request\core_user_data_provider 92 && !$componentclass instanceof \core_privacy\local\request\core_userlist_provider) { 93 $internaldata['userlistnoncompliance'] = true; 94 } 95 96 // Check that any type of userlist_provider is implemented for all shared data providers. 97 if ($componentclass instanceof \core_privacy\local\request\shared_data_provider 98 && !$componentclass instanceof \core_privacy\local\request\userlist_provider) { 99 $internaldata['userlistnoncompliance'] = true; 100 } 101 } 102 } 103 104 return $internaldata; 105 }, $leaves['plugins']); 106 $fullyrichtree[$branch]['plugin_type_raw'] = $plugintype; 107 // We're done using the plugin type. Convert it to a readable string. 108 $fullyrichtree[$branch]['plugin_type'] = $pluginman->plugintype_name($plugintype); 109 $fullyrichtree[$branch]['plugins'] = $plugins; 110 } 111 return $fullyrichtree; 112 } 113 114 /** 115 * Formats the metadata for use with a template. 116 * 117 * @param array $collection The collection associated with the component that we want to expand and format. 118 * @param string $component The component that we are dealing in 119 * @param array $internaldata The array to add the formatted metadata to. 120 * @return array The internal data array with the formatted metadata. 121 */ 122 protected function format_metadata($collection, $component, $internaldata) { 123 foreach ($collection as $collectioninfo) { 124 $privacyfields = $collectioninfo->get_privacy_fields(); 125 $fields = ''; 126 if (!empty($privacyfields)) { 127 $fields = array_map(function($key, $field) use ($component) { 128 return [ 129 'field_name' => $key, 130 'field_summary' => get_string($field, $component) 131 ]; 132 }, array_keys($privacyfields), $privacyfields); 133 } 134 // Can the metadata types be located somewhere else besides core? 135 $items = explode('\\', get_class($collectioninfo)); 136 $type = array_pop($items); 137 $typedata = [ 138 'name' => $collectioninfo->get_name(), 139 'type' => $type, 140 'fields' => $fields, 141 'summary' => get_string($collectioninfo->get_summary(), $component) 142 ]; 143 if (strpos($type, 'subsystem_link') === 0 || strpos($type, 'plugintype_link') === 0) { 144 $typedata['link'] = true; 145 } 146 $internaldata['metadata'][] = $typedata; 147 } 148 return $internaldata; 149 } 150 151 /** 152 * Return the full list of components. 153 * 154 * @return array An array of plugin types which contain plugin data. 155 */ 156 protected function get_full_component_list() { 157 global $CFG; 158 159 $list = \core_component::get_component_list(); 160 $list['core']['core'] = "{$CFG->dirroot}/lib"; 161 $formattedlist = []; 162 foreach ($list as $plugintype => $plugin) { 163 $formattedlist[] = ['plugin_type' => $plugintype, 'plugins' => array_keys($plugin)]; 164 } 165 166 return $formattedlist; 167 } 168 169 /** 170 * Returns a list of contributed plugins installed on the system. 171 * 172 * @return array A list of contributed plugins installed. 173 */ 174 protected function get_contrib_list() { 175 return array_map(function($plugins) { 176 return array_filter($plugins, function($plugindata) { 177 return !$plugindata->is_standard(); 178 }); 179 }, \core_plugin_manager::instance()->get_plugins()); 180 } 181 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body