mirror of
https://github.com/moodle/moodle.git
synced 2025-08-11 03:46:42 +02:00
MDL-61899 tool_dataprivacy: Add lawful bases fields
Includes MDL-61935 * New fields when defining purposes that let the Privacy Officer set the lawful bases of personal data collection and reason(s) for the exemption of prohibition from processing sensitive personal data.
This commit is contained in:
parent
e60058ff98
commit
5750d233f9
6 changed files with 183 additions and 13 deletions
|
@ -24,7 +24,14 @@
|
|||
namespace tool_dataprivacy\external;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use coding_exception;
|
||||
use core\external\persistent_exporter;
|
||||
use DateInterval;
|
||||
use Exception;
|
||||
use external_single_structure;
|
||||
use external_value;
|
||||
use renderer_base;
|
||||
use tool_dataprivacy\purpose;
|
||||
|
||||
/**
|
||||
* Class for exporting field data.
|
||||
|
@ -40,7 +47,7 @@ class purpose_exporter extends persistent_exporter {
|
|||
* @return string
|
||||
*/
|
||||
protected static function define_class() {
|
||||
return \tool_dataprivacy\purpose::class;
|
||||
return purpose::class;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,25 +67,74 @@ class purpose_exporter extends persistent_exporter {
|
|||
* @return array
|
||||
*/
|
||||
protected static function define_other_properties() {
|
||||
return array(
|
||||
'formattedretentionperiod' => array(
|
||||
$namedescriptiontype = [
|
||||
'name' => [
|
||||
'type' => PARAM_TEXT,
|
||||
],
|
||||
'description' => [
|
||||
'type' => PARAM_TEXT,
|
||||
],
|
||||
];
|
||||
return [
|
||||
'formattedretentionperiod' => [
|
||||
'type' => PARAM_TEXT
|
||||
),
|
||||
);
|
||||
],
|
||||
'formattedlawfulbases' => [
|
||||
'type' => $namedescriptiontype,
|
||||
'multiple' => true
|
||||
],
|
||||
'formattedsensitivedatareasons' => [
|
||||
'type' => $namedescriptiontype,
|
||||
'multiple' => true,
|
||||
'optional' => true
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return other properties.
|
||||
*
|
||||
* @param \renderer_base $output
|
||||
* @throws coding_exception
|
||||
* @throws dml_exception
|
||||
* @param renderer_base $output
|
||||
* @return array
|
||||
* @throws coding_exception
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function get_other_values(\renderer_base $output) {
|
||||
protected function get_other_values(renderer_base $output) {
|
||||
$values = [];
|
||||
|
||||
$formattedbases = [];
|
||||
$lawfulbases = explode(',', $this->persistent->get('lawfulbases'));
|
||||
if (!empty($lawfulbases)) {
|
||||
foreach ($lawfulbases as $basis) {
|
||||
if (empty(trim($basis))) {
|
||||
continue;
|
||||
}
|
||||
$formattedbases[] = (object)[
|
||||
'name' => get_string($basis . '_name', 'tool_dataprivacy'),
|
||||
'description' => get_string($basis . '_description', 'tool_dataprivacy')
|
||||
];
|
||||
}
|
||||
}
|
||||
$values['formattedlawfulbases'] = $formattedbases;
|
||||
|
||||
$formattedsensitivereasons = [];
|
||||
$sensitivereasons = explode(',', $this->persistent->get('sensitivedatareasons'));
|
||||
if (!empty($sensitivereasons)) {
|
||||
foreach ($sensitivereasons as $reason) {
|
||||
if (empty(trim($reason))) {
|
||||
continue;
|
||||
}
|
||||
$formattedsensitivereasons[] = (object)[
|
||||
'name' => get_string($reason . '_name', 'tool_dataprivacy'),
|
||||
'description' => get_string($reason . '_description', 'tool_dataprivacy')
|
||||
];
|
||||
}
|
||||
}
|
||||
$values['formattedsensitivedatareasons'] = $formattedsensitivereasons;
|
||||
|
||||
$retentionperiod = $this->persistent->get('retentionperiod');
|
||||
if ($retentionperiod) {
|
||||
$interval = new \DateInterval($retentionperiod);
|
||||
$interval = new DateInterval($retentionperiod);
|
||||
|
||||
// It is one or another.
|
||||
if ($interval->y) {
|
||||
|
@ -93,6 +149,8 @@ class purpose_exporter extends persistent_exporter {
|
|||
} else {
|
||||
$formattedtime = get_string('retentionperiodnotdefined', 'tool_dataprivacy');
|
||||
}
|
||||
return ['formattedretentionperiod' => $formattedtime];
|
||||
$values['formattedretentionperiod'] = $formattedtime;
|
||||
|
||||
return $values;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace tool_dataprivacy\form;
|
|||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use core\form\persistent;
|
||||
use tool_dataprivacy\purpose as purpose_persistent;
|
||||
|
||||
/**
|
||||
* Data purpose form.
|
||||
|
@ -37,7 +38,7 @@ use core\form\persistent;
|
|||
class purpose extends persistent {
|
||||
|
||||
/**
|
||||
* @var The persistent class.
|
||||
* @var string The persistent class.
|
||||
*/
|
||||
protected static $persistentclass = 'tool_dataprivacy\\purpose';
|
||||
|
||||
|
@ -45,6 +46,8 @@ class purpose extends persistent {
|
|||
* Define the form - called by parent constructor
|
||||
*/
|
||||
public function definition() {
|
||||
global $DB;
|
||||
|
||||
$mform = $this->_form;
|
||||
|
||||
$mform->addElement('text', 'name', get_string('name'), 'maxlength="100"');
|
||||
|
@ -55,6 +58,29 @@ class purpose extends persistent {
|
|||
$mform->addElement('editor', 'description', get_string('description'), null, ['autosave' => false]);
|
||||
$mform->setType('description', PARAM_CLEANHTML);
|
||||
|
||||
// Field for selecting lawful bases (from GDPR Article 6.1).
|
||||
$lawfulbases = [];
|
||||
foreach (purpose_persistent::GDPR_ART_6_1_ITEMS as $article) {
|
||||
$key = 'gdpr_art_6_1_' . $article;
|
||||
$lawfulbases[$key] = get_string($key . '_name', 'tool_dataprivacy');
|
||||
}
|
||||
$options = array(
|
||||
'multiple' => true,
|
||||
);
|
||||
$mform->addElement('autocomplete', 'lawfulbases', get_string('lawfulbases', 'tool_dataprivacy'), $lawfulbases, $options);
|
||||
$mform->addRule('lawfulbases', get_string('required'), 'required', null, 'server');
|
||||
$mform->addHelpButton('lawfulbases', 'lawfulbases', 'tool_dataprivacy');
|
||||
|
||||
// Optional field for selecting reasons for collecting sensitive personal data (from GDPR Article 9.2).
|
||||
$sensitivereasons = [];
|
||||
foreach (purpose_persistent::GDPR_ART_9_2_ITEMS as $article) {
|
||||
$key = 'gdpr_art_9_2_' . $article;
|
||||
$sensitivereasons[$key] = get_string($key . '_name', 'tool_dataprivacy');
|
||||
}
|
||||
$mform->addElement('autocomplete', 'sensitivedatareasons', get_string('sensitivedatareasons', 'tool_dataprivacy'),
|
||||
$sensitivereasons, $options);
|
||||
$mform->addHelpButton('sensitivedatareasons', 'sensitivedatareasons', 'tool_dataprivacy');
|
||||
|
||||
$number = $mform->createElement('text', 'retentionperiodnumber', null, ['size' => 8]);
|
||||
$unitoptions = [
|
||||
'Y' => get_string('years'),
|
||||
|
@ -88,6 +114,13 @@ class purpose extends persistent {
|
|||
protected static function convert_fields(\stdClass $data) {
|
||||
$data = parent::convert_fields($data);
|
||||
|
||||
if (is_array($data->lawfulbases)) {
|
||||
$data->lawfulbases = implode(',', $data->lawfulbases);
|
||||
}
|
||||
if (is_array($data->sensitivedatareasons)) {
|
||||
$data->sensitivedatareasons = implode(',', $data->sensitivedatareasons);
|
||||
}
|
||||
|
||||
// A single value.
|
||||
$data->retentionperiod = 'P' . $data->retentionperiodnumber . $data->retentionperiodunit;
|
||||
unset($data->retentionperiodnumber);
|
||||
|
@ -103,6 +136,11 @@ class purpose extends persistent {
|
|||
protected function get_default_data() {
|
||||
$data = parent::get_default_data();
|
||||
|
||||
$data->lawfulbases = explode(',', $data->lawfulbases);
|
||||
if (!empty($data->sensitivedatareasons)) {
|
||||
$data->sensitivedatareasons = explode(',', $data->sensitivedatareasons);
|
||||
}
|
||||
|
||||
// Convert the single properties into number and unit.
|
||||
$strlen = strlen($data->retentionperiod);
|
||||
$data->retentionperiodnumber = substr($data->retentionperiod, 1, $strlen - 2);
|
||||
|
|
|
@ -42,6 +42,12 @@ class purpose extends \core\persistent {
|
|||
*/
|
||||
const TABLE = 'tool_dataprivacy_purpose';
|
||||
|
||||
/** Items under GDPR Article 6.1. */
|
||||
const GDPR_ART_6_1_ITEMS = ['a', 'b', 'c', 'd', 'e', 'f'];
|
||||
|
||||
/** Items under GDPR Article 9.2. */
|
||||
const GDPR_ART_9_2_ITEMS = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
|
||||
|
||||
/**
|
||||
* Extended constructor to fetch from the cache if available.
|
||||
*
|
||||
|
@ -96,6 +102,16 @@ class purpose extends \core\persistent {
|
|||
'type' => PARAM_INT,
|
||||
'default' => FORMAT_HTML
|
||||
),
|
||||
'lawfulbases' => array(
|
||||
'type' => PARAM_TEXT,
|
||||
'description' => 'Comma-separated IDs matching records in tool_dataprivacy_lawfulbasis.',
|
||||
),
|
||||
'sensitivedatareasons' => array(
|
||||
'type' => PARAM_TEXT,
|
||||
'description' => 'Comma-separated IDs matching records in tool_dataprivacy_sensitive',
|
||||
'null' => NULL_ALLOWED,
|
||||
'default' => ''
|
||||
),
|
||||
'retentionperiod' => array(
|
||||
'type' => PARAM_ALPHANUM,
|
||||
'description' => 'Retention period. ISO_8601 durations format (as in DateInterval format).',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue