#189 Implemented privacy provider for GDPR compliance

This commit is contained in:
Mark Nelson 2018-05-15 16:31:06 +08:00
parent 787e370907
commit 1e977bbf31
33 changed files with 1155 additions and 0 deletions

View file

@ -0,0 +1,237 @@
<?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/>.
/**
* Privacy Subsystem implementation for mod_customcert.
*
* @package mod_customcert
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_customcert\privacy;
use core_privacy\local\metadata\collection;
use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\contextlist;
use core_privacy\local\request\helper;
use core_privacy\local\request\transform;
use core_privacy\local\request\writer;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem implementation for mod_customcert.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\metadata\provider,
\core_privacy\local\request\plugin\provider {
/**
* Return the fields which contain personal data.
*
* @param collection $items a reference to the collection to use to store the metadata.
* @return collection the updated collection of metadata items.
*/
public static function get_metadata(collection $items) : collection {
$items->add_database_table(
'customcert_issues',
[
'userid' => 'privacy:metadata:customcert_issues:userid',
'customcertid' => 'privacy:metadata:customcert_issues:customcertid',
'code' => 'privacy:metadata:customcert_issues:code',
'emailed' => 'privacy:metadata:customcert_issues:emailed',
'timecreated' => 'privacy:metadata:customcert_issues:timecreated',
],
'privacy:metadata:customcert_issues'
);
return $items;
}
/**
* Get the list of contexts that contain user information for the specified user.
*
* @param int $userid the userid.
* @return contextlist the list of contexts containing user info for the user.
*/
public static function get_contexts_for_userid(int $userid) : contextlist {
$sql = "SELECT c.id
FROM {context} c
INNER JOIN {course_modules} cm
ON cm.id = c.instanceid
AND c.contextlevel = :contextlevel
INNER JOIN {modules} m
ON m.id = cm.module
AND m.name = :modulename
INNER JOIN {customcert} customcert
ON customcert.id = cm.instance
INNER JOIN {customcert_issues} customcertissues
ON customcertissues.customcertid = customcert.id
WHERE customcertissues.userid = :userid";
$params = [
'modulename' => 'customcert',
'contextlevel' => CONTEXT_MODULE,
'userid' => $userid,
];
$contextlist = new contextlist();
$contextlist->add_from_sql($sql, $params);
return $contextlist;
}
/**
* Export personal data for the given approved_contextlist. User and context information is contained within the contextlist.
*
* @param approved_contextlist $contextlist a list of contexts approved for export.
*/
public static function export_user_data(approved_contextlist $contextlist) {
global $DB;
// Filter out any contexts that are not related to modules.
$cmids = array_reduce($contextlist->get_contexts(), function($carry, $context) {
if ($context->contextlevel == CONTEXT_MODULE) {
$carry[] = $context->instanceid;
}
return $carry;
}, []);
if (empty($cmids)) {
return;
}
$user = $contextlist->get_user();
// Get all the customcert activities associated with the above course modules.
$customcertidstocmids = self::get_customcert_ids_to_cmids_from_cmids($cmids);
list($insql, $inparams) = $DB->get_in_or_equal(array_keys($customcertidstocmids), SQL_PARAMS_NAMED);
$params = array_merge($inparams, ['userid' => $user->id]);
$recordset = $DB->get_recordset_select('customcert_issues', "customcertid $insql AND userid = :userid",
$params, 'timecreated, id ASC');
self::recordset_loop_and_export($recordset, 'customcertid', [], function($carry, $record) {
$carry[] = [
'code' => $record->code,
'emailed' => transform::yesno($record->emailed),
'timecreated' => transform::datetime($record->timecreated)
];
return $carry;
}, function($customcertid, $data) use ($user, $customcertidstocmids) {
$context = \context_module::instance($customcertidstocmids[$customcertid]);
$contextdata = helper::get_context_data($context, $user);
$finaldata = (object) array_merge((array) $contextdata, ['issues' => $data]);
helper::export_context_files($context, $user);
writer::with_context($context)->export_data([], $finaldata);
});
}
/**
* Delete all data for all users in the specified context.
*
* @param \context $context the context to delete in.
*/
public static function delete_data_for_all_users_in_context(\context $context) {
global $DB;
if (!$context instanceof \context_module) {
return;
}
if (!$cm = get_coursemodule_from_id('customcert', $context->instanceid)) {
return;
}
$DB->delete_records('customcert_issues', ['customcertid' => $cm->instance]);
}
/**
* Delete all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist a list of contexts approved for deletion.
*/
public static function delete_data_for_user(approved_contextlist $contextlist) {
global $DB;
if (empty($contextlist->count())) {
return;
}
$userid = $contextlist->get_user()->id;
foreach ($contextlist->get_contexts() as $context) {
if (!$context instanceof \context_module) {
continue;
}
$instanceid = $DB->get_field('course_modules', 'instance', ['id' => $context->instanceid], MUST_EXIST);
$DB->delete_records('customcert_issues', ['customcertid' => $instanceid, 'userid' => $userid]);
}
}
/**
* Return a list of Customcert IDs mapped to their course module ID.
*
* @param array $cmids The course module IDs.
* @return array In the form of [$customcertid => $cmid].
*/
protected static function get_customcert_ids_to_cmids_from_cmids(array $cmids) {
global $DB;
list($insql, $inparams) = $DB->get_in_or_equal($cmids, SQL_PARAMS_NAMED);
$sql = "SELECT customcert.id, cm.id AS cmid
FROM {customcert} customcert
JOIN {modules} m
ON m.name = :modulename
JOIN {course_modules} cm
ON cm.instance = customcert.id
AND cm.module = m.id
WHERE cm.id $insql";
$params = array_merge($inparams, ['modulename' => 'customcert']);
return $DB->get_records_sql_menu($sql, $params);
}
/**
* Loop and export from a recordset.
*
* @param \moodle_recordset $recordset The recordset.
* @param string $splitkey The record key to determine when to export.
* @param mixed $initial The initial data to reduce from.
* @param callable $reducer The function to return the dataset, receives current dataset, and the current record.
* @param callable $export The function to export the dataset, receives the last value from $splitkey and the dataset.
* @return void
*/
protected static function recordset_loop_and_export(\moodle_recordset $recordset, $splitkey, $initial,
callable $reducer, callable $export) {
$data = $initial;
$lastid = null;
foreach ($recordset as $record) {
if ($lastid && $record->{$splitkey} != $lastid) {
$export($lastid, $data);
$data = $initial;
}
$data = $reducer($data, $record);
$lastid = $record->{$splitkey};
}
$recordset->close();
if (!empty($lastid)) {
$export($lastid, $data);
}
}
}

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_bgimage.
*
* @package customcertelement_bgimage
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_bgimage\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_bgimage implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -23,3 +23,4 @@
*/
$string['pluginname'] = 'Background image';
$string['privacy:metadata'] = 'The Background image plugin does not store any personal data.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_border.
*
* @package customcertelement_border
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_border\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_border implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -23,6 +23,7 @@
*/
$string['pluginname'] = 'Border';
$string['privacy:metadata'] = 'The Border plugin does not store any personal data.';
$string['invalidwidth'] = 'The width has to be a valid number greater than 0.';
$string['width'] = 'Width';
$string['width_help'] = 'Width of the border in mm.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_categoryname.
*
* @package customcertelement_categoryname
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_categoryname\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_categoryname implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -23,3 +23,4 @@
*/
$string['pluginname'] = 'Category name';
$string['privacy:metadata'] = 'The Category name plugin does not store any personal data.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_code.
*
* @package customcertelement_code
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_code\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_code implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -23,3 +23,4 @@
*/
$string['pluginname'] = 'Code';
$string['privacy:metadata'] = 'The Code plugin does not store any personal data.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_coursename.
*
* @package customcertelement_coursename
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_coursename\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_coursename implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -23,3 +23,4 @@
*/
$string['pluginname'] = 'Course name';
$string['privacy:metadata'] = 'The Course name plugin does not store any personal data.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_date.
*
* @package customcertelement_date
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_date\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_date implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -32,6 +32,7 @@ $string['dateitem'] = 'Date item';
$string['dateitem_help'] = 'This will be the date that is printed on the certificate';
$string['issueddate'] = 'Issued date';
$string['pluginname'] = 'Date';
$string['privacy:metadata'] = 'The Date plugin does not store any personal data.';
$string['numbersuffix_nd_as_in_second'] = 'nd';
$string['numbersuffix_rd_as_in_third'] = 'rd';
$string['numbersuffix_st_as_in_first'] = 'st';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_digitalsignature.
*
* @package customcertelement_digitalsignature
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_digitalsignature\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_digitalsignature implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -25,6 +25,7 @@
$string['digitalsignature'] = 'Digital signature';
$string['nosignature'] = 'No signature';
$string['pluginname'] = 'Digital signature';
$string['privacy:metadata'] = 'The Digital signature plugin does not store any personal data.';
$string['signaturename'] = 'Signature name';
$string['signaturepassword'] = 'Signature password';
$string['signaturelocation'] = 'Signature location';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_grade.
*
* @package customcertelement_grade
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_grade\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_grade implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -33,3 +33,4 @@ $string['gradepoints'] = 'Points';
$string['gradeletter'] = 'Letter';
$string['pluginname'] = 'Grade';
$string['previewgrade'] = 'Preview grade';
$string['privacy:metadata'] = 'The Grade plugin does not store any personal data.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_gradeitemname.
*
* @package customcertelement_gradeitemname
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_gradeitemname\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_gradeitemname implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -25,3 +25,4 @@
$string['gradeitem'] = 'Grade item';
$string['gradeitem_help'] = 'The name of the selected item will be displayed on the PDF.';
$string['pluginname'] = 'Grade item name';
$string['privacy:metadata'] = 'The Grade item name plugin does not store any personal data.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_image.
*
* @package customcertelement_image
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_image\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_image implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -28,5 +28,6 @@ $string['image'] = 'Image';
$string['invalidheight'] = 'The height has to be a valid number greater than or equal to 0.';
$string['invalidwidth'] = 'The width has to be a valid number greater than or equal to 0.';
$string['pluginname'] = 'Image';
$string['privacy:metadata'] = 'The Image plugin does not store any personal data.';
$string['width'] = 'Width';
$string['width_help'] = 'Width of the image in mm. If equal to zero, it is automatically calculated.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_studentname.
*
* @package customcertelement_studentname
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_studentname\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_studentname implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -23,3 +23,4 @@
*/
$string['pluginname'] = 'Student name';
$string['privacy:metadata'] = 'The Student name plugin does not store any personal data.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_teachername.
*
* @package customcertelement_teachername
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_teachername\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_teachername implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -23,5 +23,6 @@
*/
$string['pluginname'] = 'Teacher name';
$string['privacy:metadata'] = 'The Teacher name plugin does not store any personal data.';
$string['teacher'] = 'Teacher';
$string['teacher_help'] = 'This is the teacher name that will be displayed.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_text.
*
* @package customcertelement_text
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_text\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_text implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -23,5 +23,6 @@
*/
$string['pluginname'] = 'Text';
$string['privacy:metadata'] = 'The Text plugin does not store any personal data.';
$string['text'] = 'Text';
$string['text_help'] = 'This is the text that will display on the PDF.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_userfield.
*
* @package customcertelement_userfield
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_userfield\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_userfield implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -23,5 +23,6 @@
*/
$string['pluginname'] = 'User field';
$string['privacy:metadata'] = 'The User field plugin does not store any personal data.';
$string['userfield'] = 'User field';
$string['userfield_help'] = 'This is the user field that will be displayed on the PDF.';

View 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/>.
/**
* Privacy Subsystem implementation for customcertelement_userpicture.
*
* @package customcertelement_userpicture
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace customcertelement_userpicture\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for customcertelement_userpicture implementing null_provider.
*
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}

View file

@ -27,5 +27,6 @@ $string['height_help'] = 'Height of the image in mm. If equal to zero, it is aut
$string['invalidheight'] = 'The height has to be a valid number greater than or equal to 0.';
$string['invalidwidth'] = 'The width has to be a valid number greater than or equal to 0.';
$string['pluginname'] = 'User picture';
$string['privacy:metadata'] = 'The User picture plugin does not store any personal data.';
$string['width'] = 'Width';
$string['width_help'] = 'Width of the image in mm. If equal to zero, it is automatically calculated.';

View file

@ -127,6 +127,12 @@ $string['posx_help'] = 'This is the position in mm from the top left corner you
$string['posy'] = 'Position Y';
$string['posy_help'] = 'This is the position in mm from the top left corner you wish the element\'s reference point to locate in the y direction.';
$string['print'] = 'Print';
$string['privacy:metadata:customcert_issues'] = 'The list of issued certificates';
$string['privacy:metadata:customcert_issues:code'] = 'The code that belongs to the certificate';
$string['privacy:metadata:customcert_issues:customcertid'] = 'The ID of the certificate';
$string['privacy:metadata:customcert_issues:emailed'] = 'Whether or not the certificate was emailed';
$string['privacy:metadata:customcert_issues:timecreated'] = 'The time the certificate was issued';
$string['privacy:metadata:customcert_issues:userid'] = 'The ID of the user who was issued the certificate';
$string['rearrangeelements'] = 'Reposition elements';
$string['rearrangeelementsheading'] = 'Drag and drop elements to change where they are positioned on the certificate.';
$string['receiveddate'] = 'Received date';

View file

@ -0,0 +1,207 @@
<?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/>.
/**
* Privacy provider tests.
*
* @package mod_customcert
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use mod_customcert\privacy\provider;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy provider tests class.
*
* @package mod_customcert
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_customcert_privacy_provider_testcase extends \core_privacy\tests\provider_testcase {
/**
* Test for provider::get_contexts_for_userid().
*/
public function test_get_contexts_for_userid() {
$this->resetAfterTest();
$course = $this->getDataGenerator()->create_course();
// The customcert activity the user will have an issue from.
$customcert = $this->getDataGenerator()->create_module('customcert', ['course' => $course->id]);
// Another customcert activity that has no issued certificates.
$this->getDataGenerator()->create_module('customcert', ['course' => $course->id]);
// Create a user who will be issued a certificate.
$user = $this->getDataGenerator()->create_user();
// Issue the certificate.
$this->create_certificate_issue($customcert->id, $user->id);
// Check the context supplied is correct.
$contextlist = provider::get_contexts_for_userid($user->id);
$this->assertCount(1, $contextlist);
$contextformodule = $contextlist->current();
$cmcontext = context_module::instance($customcert->cmid);
$this->assertEquals($cmcontext->id, $contextformodule->id);
}
/**
* Test for provider::export_user_data().
*/
public function test_export_for_context() {
$this->resetAfterTest();
$course = $this->getDataGenerator()->create_course();
$customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id));
// Create users who will be issued a certificate.
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$this->create_certificate_issue($customcert->id, $user1->id);
$this->create_certificate_issue($customcert->id, $user1->id);
$this->create_certificate_issue($customcert->id, $user2->id);
// Export all of the data for the context for user 1.
$cmcontext = context_module::instance($customcert->cmid);
$this->export_context_data_for_user($user1->id, $cmcontext, 'mod_customcert');
$writer = \core_privacy\local\request\writer::with_context($cmcontext);
$this->assertTrue($writer->has_any_data());
$data = $writer->get_data();
$this->assertCount(2, $data->issues);
$issues = $data->issues;
foreach ($issues as $issue) {
$this->assertArrayHasKey('code', $issue);
$this->assertArrayHasKey('emailed', $issue);
$this->assertArrayHasKey('timecreated', $issue);
}
}
/**
* Test for provider::delete_data_for_all_users_in_context().
*/
public function test_delete_data_for_all_users_in_context() {
global $DB;
$this->resetAfterTest();
$course = $this->getDataGenerator()->create_course();
$customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id));
$customcert2 = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id));
// Create users who will be issued a certificate.
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$this->create_certificate_issue($customcert->id, $user1->id);
$this->create_certificate_issue($customcert->id, $user2->id);
$this->create_certificate_issue($customcert2->id, $user1->id);
$this->create_certificate_issue($customcert2->id, $user2->id);
// Before deletion, we should have 2 issued certificates for the first certificate.
$count = $DB->count_records('customcert_issues', ['customcertid' => $customcert->id]);
$this->assertEquals(2, $count);
// Delete data based on context.
$cmcontext = context_module::instance($customcert->cmid);
provider::delete_data_for_all_users_in_context($cmcontext);
// After deletion, the issued certificates for the activity should have been deleted.
$count = $DB->count_records('customcert_issues', ['customcertid' => $customcert->id]);
$this->assertEquals(0, $count);
// We should still have the issues for the second certificate.
$count = $DB->count_records('customcert_issues', ['customcertid' => $customcert2->id]);
$this->assertEquals(2, $count);
}
/**
* Test for provider::delete_data_for_user().
*/
public function test_delete_data_for_user() {
global $DB;
$this->resetAfterTest();
$course = $this->getDataGenerator()->create_course();
$customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id));
// Create users who will be issued a certificate.
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$this->create_certificate_issue($customcert->id, $user1->id);
$this->create_certificate_issue($customcert->id, $user2->id);
// Before deletion we should have 2 issued certificates.
$count = $DB->count_records('customcert_issues', ['customcertid' => $customcert->id]);
$this->assertEquals(2, $count);
$context = \context_module::instance($customcert->cmid);
$contextlist = new \core_privacy\local\request\approved_contextlist($user1, 'customcert',
[$context->id]);
provider::delete_data_for_user($contextlist);
// After deletion, the issued certificates for the first user should have been deleted.
$count = $DB->count_records('customcert_issues', ['customcertid' => $customcert->id, 'userid' => $user1->id]);
$this->assertEquals(0, $count);
// Check the issue for the other user is still there.
$customcertissue = $DB->get_records('customcert_issues');
$this->assertCount(1, $customcertissue);
$lastissue = reset($customcertissue);
$this->assertEquals($user2->id, $lastissue->userid);
}
/**
* Mimicks the creation of a customcert issue.
*
* There is no API we can use to insert an customcert issue, so we
* will simply insert directly into the database.
*
* @param int $customcertid
* @param int $userid
*/
protected function create_certificate_issue(int $customcertid, int $userid) {
global $DB;
static $i = 1;
$customcertissue = new stdClass();
$customcertissue->customcertid = $customcertid;
$customcertissue->userid = $userid;
$customcertissue->code = \mod_customcert\certificate::generate_code();
$customcertissue->timecreated = time() + $i;
// Insert the record into the database.
$DB->insert_record('customcert_issues', $customcertissue);
$i++;
}
}