Compare commits
266 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e786a591d5 | |||
| d9321f3342 | |||
| b2865ca1e4 | |||
| 9973df93f4 | |||
| 9e21adb5f7 | |||
| 65c23f097c | |||
| 92be49df49 | |||
| 7eab2af613 | |||
| 5fb193152e | |||
| 44080d810b | |||
| c525fe3095 | |||
| 86fe3ca41b | |||
| 20884e18e5 | |||
| b0b49c938b | |||
| 2e6acd5f60 | |||
| b0e4353ddd | |||
| 16edec0104 | |||
| 07c9c193b3 | |||
| 0817548194 | |||
| 3585740ced | |||
| 1cf00cde92 | |||
| 4ee7ad2377 | |||
| 9cdf3e4316 | |||
| 60bf7bf6c2 | |||
| d378b3a50e | |||
| 82c9aa61a8 | |||
| cb8197f594 | |||
| 9873a175a5 | |||
| 89033d2d07 | |||
| 110e818da7 | |||
| 5d06da4e41 | |||
| 78ebc5d9e7 | |||
| d8952802e7 | |||
| 7a49ac3d79 | |||
| 1983c83957 | |||
| 1b1b6313c0 | |||
| d2bc47577b | |||
| 674a9c859d | |||
| 56335cc001 | |||
| 2e86cca9ca | |||
| 0913f3314f | |||
| cf7979c622 | |||
| cda6d082de | |||
| eb12fec156 | |||
| d2c04300f3 | |||
| ceb21de5e3 | |||
| 6aef716ec4 | |||
| fc16e61230 | |||
| 0534fbc2aa | |||
| 5b9f872429 | |||
| dd67898152 | |||
| 2377dbd9d8 | |||
| 3810c3ad36 | |||
| ef9c44ad7e | |||
| 3eac779614 | |||
| 5223ceed6b | |||
| f27cf98517 | |||
| 7fe0a3b051 | |||
| f03765aae7 | |||
| 9fa3922c77 | |||
| 4a9c1685bd | |||
| fbb3918ebe | |||
| d17dc20947 | |||
| a63717d365 | |||
| 0867abed26 | |||
| be94915636 | |||
| 5de4b14160 | |||
| 3e316b8713 | |||
| 267e1af112 | |||
| 37db3b8561 | |||
| 5a146aa633 | |||
| 934220228a | |||
| 3c9a5ae1cc | |||
| 8d7d722fb0 | |||
| 2f0be313b3 | |||
| 68e6299010 | |||
| e3a18e4458 | |||
| 21d27e3f96 | |||
| a74a3f8ab8 | |||
| e95f91c90a | |||
| 7a793db488 | |||
| 645b80ea72 | |||
| 5c07c79657 | |||
| 5cb155ad9d | |||
| a8b5704fb4 | |||
| 707d3a3aa3 | |||
| 9f11f13ad8 | |||
| b091c290bb | |||
| c101a623d8 | |||
| 5815d6f01c | |||
| 2e17137c8b | |||
| 28b6ae97e9 | |||
| d527a497ea | |||
| 64488fd069 | |||
| 76148061d7 | |||
| 9214166d89 | |||
| 253fcd9ce2 | |||
| 218cbbed31 | |||
| b3dfb6eafa | |||
| 8fda9b0267 | |||
| 5fafbd8a3c | |||
| 9a550cac49 | |||
| ffd593db80 | |||
| 14618260c8 | |||
| 7f1fcbda75 | |||
| 5fc058c0b0 | |||
| 2faddcdef5 | |||
| a49458943c | |||
| aaf815541b | |||
| eb618c1c71 | |||
| 4948a43536 | |||
| b4a4b7ce70 | |||
| 4f21e3a33f | |||
| d6e63cb602 | |||
| 504e36da8e | |||
| 9c796e028d | |||
| 3a7f56c779 | |||
| c4f22db315 | |||
| f926f376f8 | |||
| 6972f8403f | |||
| 457fcfe3d0 | |||
| bf085b7fc5 | |||
| 2eb83b7678 | |||
| a3e647dc98 | |||
| a5bac67326 | |||
| 3117287072 | |||
| f6121c0bd6 | |||
| fd1ef60779 | |||
| ff1f239381 | |||
| 6c855610bf | |||
| 8b1eb7742e | |||
| 08e1bbd86b | |||
| b899bab0bc | |||
| 48352701a1 | |||
| f23541f3fb | |||
| ab83a52583 | |||
| 2e8f163f64 | |||
| 41275ea779 | |||
| e129c4733b | |||
| 8904b10b44 | |||
| 5e092e2540 | |||
| 235d4be426 | |||
| 0ce2cf80ee | |||
| 7d5efd643c | |||
| 8566cace36 | |||
| f71d4d4a97 | |||
| ccd495d806 | |||
| 5613a37ab2 | |||
| 8e2eb1f335 | |||
| 89660817f7 | |||
| ea61136232 | |||
| 9a36044425 | |||
| 6dc3fc7508 | |||
| 8ba2f949d0 | |||
| e53bde7de2 | |||
| aee5a8666a | |||
| a163049a64 | |||
| 055010a34a | |||
| abe4724b32 | |||
| 163a9d21e5 | |||
| 234d16cfcb | |||
| e598dc49a7 | |||
| 1702e66574 | |||
| 9d8c7eaaa8 | |||
| a77941b809 | |||
| 7fe0d459d6 | |||
| bfe824dd3d | |||
| ad0f68802a | |||
| e3db31ac67 | |||
| 00ab44ee52 | |||
| bb89fdcf22 | |||
| b813a2778b | |||
| 7e9362481d | |||
| 407a8d675e | |||
| 38055cdb22 | |||
| b3c71b12c7 | |||
| 5ac4c7f2ba | |||
| 0c8d6093dc | |||
| 0ab8ddc56b | |||
| 2cda43b3bd | |||
| efc06d64e7 | |||
| a71eb555c2 | |||
| 7517f9ea50 | |||
| 73f8281a01 | |||
| 158586680d | |||
| c81ead0adb | |||
| 1ac64fbe83 | |||
| 3111b937ef | |||
| 58c586c3c4 | |||
| 9b2b1b5b12 | |||
| e9925ef601 | |||
| d8aba73bb4 | |||
| 4174bcc99c | |||
| f89874634c | |||
| 66a13f93e4 | |||
| 859e9b3394 | |||
| 9aae08cc38 | |||
| 5608acd0d7 | |||
| 0b13c999e2 | |||
| fa62cb4137 | |||
| db75ead6fe | |||
| 5ae345bdeb | |||
| ac8bf02214 | |||
| a1a04839eb | |||
| d8c58a53d3 | |||
| 17384a4a8e | |||
| 0a8e683595 | |||
| 63da6656b9 | |||
| 53556cf240 | |||
| a11dae7625 | |||
| 274d3ca6d5 | |||
| 492ddb2bf8 | |||
| 5bb4d629fc | |||
| 9cb82a1530 | |||
| a5e434b97e | |||
| cf9910912f | |||
| b2961aa526 | |||
| 48a5afe796 | |||
| 83539ba7aa | |||
| 01484f2289 | |||
| a167de121b | |||
| f058e911cd | |||
| 06cded2b76 | |||
| df5debbfc4 | |||
| 1c1c751560 | |||
| e6645efea6 | |||
| eedd1437c8 | |||
| b1c1aa89ed | |||
| 8ede8c859e | |||
| e288c6314f | |||
| 4865f138c7 | |||
| 9db5265f18 | |||
| 5b7ee7d6b3 | |||
| e1a489362c | |||
| 2da5023cd2 | |||
| b025f80743 | |||
| b65a529086 | |||
| 68673fb78d | |||
| 0de71f9432 | |||
| 82815a491e | |||
| 5abcd64852 | |||
| da908a84c3 | |||
| fde9d39538 | |||
| 97cf15c9ad | |||
| 6837f2f698 | |||
| 83b01d7505 | |||
| e9c315ff85 | |||
| fb4da0de30 | |||
| 3cf3e20b77 | |||
| 2d6a9a6ef3 | |||
| 2a208a32cb | |||
| ba6233ae2c | |||
| ad2ed52966 | |||
| 84bc03313b | |||
| 043279b4d9 | |||
| 4a108f79a8 | |||
| 0c496132cf | |||
| d251a46588 | |||
| 20c6e3628c | |||
| 6df9abc397 | |||
| c16fd22bbc | |||
| b8cf9f06dc | |||
| 879c847aed | |||
| 1b091c789c | |||
| 15646264c4 | |||
| d716aa1587 |
+4
-2
@@ -75,7 +75,7 @@ if ($data = data_submitted() and confirm_sesskey()) {
|
||||
if ($PAGE->user_allowed_editing() && $adminediting != -1) {
|
||||
$USER->editing = $adminediting;
|
||||
}
|
||||
|
||||
$buttons = null;
|
||||
if ($PAGE->user_allowed_editing()) {
|
||||
$url = clone($PAGE->url);
|
||||
if ($PAGE->user_is_editing()) {
|
||||
@@ -129,7 +129,9 @@ if ($savebutton) {
|
||||
$visiblepathtosection = array_reverse($settingspage->visiblepath);
|
||||
$PAGE->set_title("$SITE->shortname: " . implode(": ",$visiblepathtosection));
|
||||
$PAGE->set_heading($SITE->fullname);
|
||||
$PAGE->set_button($buttons);
|
||||
if ($buttons) {
|
||||
$PAGE->set_button($buttons);
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ if ($roleid) {
|
||||
$select = new single_select($PAGE->url, 'roleid', $nameswithcounts, $roleid, null);
|
||||
$select->label = get_string('assignanotherrole', 'core_role');
|
||||
echo $OUTPUT->render($select);
|
||||
echo '<p><a href="' . $PAGE->url . '">' . get_string('backtoallroles', 'core_role') . '</a></p>';
|
||||
echo '<p><a href="' . $url . '">' . get_string('backtoallroles', 'core_role') . '</a></p>';
|
||||
echo '</div>';
|
||||
|
||||
} else if (empty($assignableroles)) {
|
||||
|
||||
@@ -100,6 +100,8 @@ class core_role_define_role_table_advanced extends core_role_capability_table_wi
|
||||
$this->role->shortname = core_text::strtolower(clean_param($this->role->shortname, PARAM_ALPHANUMEXT));
|
||||
if (empty($this->role->shortname)) {
|
||||
$this->errors['shortname'] = get_string('errorbadroleshortname', 'core_role');
|
||||
} else if (core_text::strlen($this->role->shortname) > 100) { // Check if it exceeds the max of 100 characters.
|
||||
$this->errors['shortname'] = get_string('errorroleshortnametoolong', 'core_role');
|
||||
}
|
||||
}
|
||||
if ($DB->record_exists_select('role', 'shortname = ? and id <> ?', array($this->role->shortname, $this->roleid))) {
|
||||
@@ -476,7 +478,7 @@ class core_role_define_role_table_advanced extends core_role_capability_table_wi
|
||||
}
|
||||
|
||||
protected function get_shortname_field($id) {
|
||||
return '<input type="text" id="' . $id . '" name="' . $id . '" maxlength="254" value="' . s($this->role->shortname) . '"' .
|
||||
return '<input type="text" id="' . $id . '" name="' . $id . '" maxlength="100" value="' . s($this->role->shortname) . '"' .
|
||||
' class="form-control"/>';
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Adds privacy and policies links to admin tree.
|
||||
*
|
||||
* @package core_privacy
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
if ($hassiteconfig) {
|
||||
// Privacy settings.
|
||||
$temp = new admin_settingpage('privacysettings', new lang_string('privacysettings', 'admin'));
|
||||
|
||||
$options = array(
|
||||
0 => get_string('no'),
|
||||
1 => get_string('yes')
|
||||
);
|
||||
$url = new moodle_url('/admin/settings.php?section=supportcontact');
|
||||
$url = $url->out();
|
||||
$setting = new admin_setting_configselect('agedigitalconsentverification',
|
||||
new lang_string('agedigitalconsentverification', 'admin'),
|
||||
new lang_string('agedigitalconsentverification_desc', 'admin', $url), 0, $options);
|
||||
$setting->set_force_ltr(true);
|
||||
$temp->add($setting);
|
||||
|
||||
$setting = new admin_setting_agedigitalconsentmap('agedigitalconsentmap',
|
||||
new lang_string('ageofdigitalconsentmap', 'admin'),
|
||||
new lang_string('ageofdigitalconsentmap_desc', 'admin'),
|
||||
// See {@link https://gdpr-info.eu/art-8-gdpr/}.
|
||||
implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'AT, 14',
|
||||
'CZ, 13',
|
||||
'DE, 14',
|
||||
'DK, 13',
|
||||
'ES, 13',
|
||||
'FI, 15',
|
||||
'GB, 13',
|
||||
'HU, 14',
|
||||
'IE, 13',
|
||||
'LT, 16',
|
||||
'LU, 16',
|
||||
'NL, 16',
|
||||
'PL, 13',
|
||||
'SE, 13',
|
||||
]),
|
||||
PARAM_RAW
|
||||
);
|
||||
$temp->add($setting);
|
||||
|
||||
$ADMIN->add('privacy', $temp);
|
||||
|
||||
// Policy settings.
|
||||
$temp = new admin_settingpage('policysettings', new lang_string('policysettings', 'admin'));
|
||||
$temp->add(new admin_settings_sitepolicy_handler_select('sitepolicyhandler', new lang_string('sitepolicyhandler', 'core_admin'),
|
||||
new lang_string('sitepolicyhandler_desc', 'core_admin')));
|
||||
$temp->add(new admin_setting_configtext('sitepolicy', new lang_string('sitepolicy', 'core_admin'),
|
||||
new lang_string('sitepolicy_help', 'core_admin'), '', PARAM_RAW));
|
||||
$temp->add(new admin_setting_configtext('sitepolicyguest', new lang_string('sitepolicyguest', 'core_admin'),
|
||||
new lang_string('sitepolicyguest_help', 'core_admin'), (isset($CFG->sitepolicy) ? $CFG->sitepolicy : ''), PARAM_RAW));
|
||||
|
||||
$ADMIN->add('privacy', $temp);
|
||||
}
|
||||
@@ -49,8 +49,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
3600 => new lang_string('numminutes', '', 60))));
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('extendedusernamechars', new lang_string('extendedusernamechars', 'admin'), new lang_string('configextendedusernamechars', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configtext('sitepolicy', new lang_string('sitepolicy', 'admin'), new lang_string('sitepolicy_help', 'admin'), '', PARAM_RAW));
|
||||
$temp->add(new admin_setting_configtext('sitepolicyguest', new lang_string('sitepolicyguest', 'admin'), new lang_string('sitepolicyguest_help', 'admin'), (isset($CFG->sitepolicy) ? $CFG->sitepolicy : ''), PARAM_RAW));
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('extendedusernamechars', new lang_string('extendedusernamechars', 'admin'), new lang_string('configextendedusernamechars', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('keeptagnamecase', new lang_string('keeptagnamecase','admin'),new lang_string('configkeeptagnamecase', 'admin'),'1'));
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ $ADMIN->add('root', new admin_category('badges', new lang_string('badges'), empt
|
||||
$ADMIN->add('root', new admin_category('location', new lang_string('location','admin')));
|
||||
$ADMIN->add('root', new admin_category('language', new lang_string('language')));
|
||||
$ADMIN->add('root', new admin_category('modules', new lang_string('plugins', 'admin')));
|
||||
$ADMIN->add('root', new admin_category('privacy', new lang_string('privacyandpolicies', 'admin')));
|
||||
$ADMIN->add('root', new admin_category('security', new lang_string('security','admin')));
|
||||
$ADMIN->add('root', new admin_category('appearance', new lang_string('appearance','admin')));
|
||||
$ADMIN->add('root', new admin_category('frontpage', new lang_string('frontpage','admin')));
|
||||
|
||||
@@ -167,7 +167,7 @@ class api {
|
||||
$params['roleid'] = $roleid;
|
||||
$params['userid'] = $userid;
|
||||
|
||||
$sql = 'SELECT u.id AS userid, ra.id, ctx.id AS contextid
|
||||
$sql = 'SELECT DISTINCT u.id AS userid, ra.id, ctx.id AS contextid
|
||||
FROM {user} u
|
||||
JOIN {cohort_members} cm ON u.id = cm.userid
|
||||
JOIN {context} ctx ON u.id = ctx.instanceid AND ctx.contextlevel = :usercontext
|
||||
|
||||
@@ -98,7 +98,7 @@ class cohort_role_assignments_table extends table_sql {
|
||||
);
|
||||
$context = context_helper::instance_by_id($data->cohortcontextid);
|
||||
|
||||
$exporter = new \tool_lp\external\cohort_summary_exporter($record, array('context' => $context));
|
||||
$exporter = new \core_cohort\external\cohort_summary_exporter($record, array('context' => $context));
|
||||
$cohort = $exporter->export($OUTPUT);
|
||||
|
||||
$html = $OUTPUT->render_from_template('tool_cohortroles/cohort-in-list', $cohort);
|
||||
|
||||
@@ -159,6 +159,11 @@ class tool_customlang_utils {
|
||||
$needsupdate = true;
|
||||
$current[$stringid]->local = $stringlocal;
|
||||
$current[$stringid]->timecustomized = $now;
|
||||
} else if (isset($currentlocal) && $stringlocal !== $currentlocal) {
|
||||
// If local string has been removed, we need to remove also the old local value from DB.
|
||||
$needsupdate = true;
|
||||
$current[$stringid]->local = null;
|
||||
$current[$stringid]->timecustomized = $now;
|
||||
}
|
||||
|
||||
if ($needsupdate) {
|
||||
|
||||
@@ -211,7 +211,9 @@ class api {
|
||||
}
|
||||
|
||||
if (empty($section) or $section == 'sitepolicies') {
|
||||
$settings->sitepolicy = $CFG->sitepolicy;
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
$settings->sitepolicy = ($sitepolicy = $manager->get_embed_url()) ? $sitepolicy->out(false) : '';
|
||||
$settings->sitepolicyhandler = $CFG->sitepolicyhandler;
|
||||
$settings->disableuserimages = $CFG->disableuserimages;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,4 +74,4 @@ $string['smartappbanners'] = 'App Banners';
|
||||
$string['pluginnotenabledorconfigured'] = 'Plugin not enabled or configured.';
|
||||
$string['remoteaddons'] = 'Remote add-ons';
|
||||
$string['typeoflogin'] = 'Type of login';
|
||||
$string['typeoflogin_desc'] = 'If the site uses a SSO authentication method, then select via a browser window or via an embedded browser. An embedded browser provides a better user experience, though it doesn\'t work with all SSO plugins. If using SSO, autologinguests should be disabled.';
|
||||
$string['typeoflogin_desc'] = 'If the site uses a SSO authentication method, then select via a browser window or via an embedded browser. An embedded browser provides a better user experience, though it doesn\'t work with all SSO plugins.';
|
||||
|
||||
@@ -150,6 +150,7 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
|
||||
array('name' => 'newsitems', 'value' => $SITE->newsitems),
|
||||
array('name' => 'commentsperpage', 'value' => $CFG->commentsperpage),
|
||||
array('name' => 'sitepolicy', 'value' => $mysitepolicy),
|
||||
array('name' => 'sitepolicyhandler', 'value' => ''),
|
||||
array('name' => 'disableuserimages', 'value' => $CFG->disableuserimages),
|
||||
array('name' => 'mygradesurl', 'value' => user_mygrades_url()->out(false)),
|
||||
array('name' => 'tool_mobile_forcelogout', 'value' => 0),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="tool/monitor/db" VERSION="20141103" COMMENT="XMLDB file for Moodle tool/monitor"
|
||||
<XMLDB PATH="admin/tool/monitor/db" VERSION="20141103" COMMENT="XMLDB file for Moodle tool/monitor"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
<TABLES>
|
||||
<TABLE NAME="tool_monitor_rules" COMMENT="Table to store rules">
|
||||
@@ -79,4 +79,4 @@
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
</XMLDB>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="tool/recyclebin/db" VERSION="20160315" COMMENT="XMLDB file for Moodle tool/recyclebin"
|
||||
<XMLDB PATH="admin/tool/recyclebin/db" VERSION="20160315" COMMENT="XMLDB file for Moodle tool/recyclebin"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
<TABLES>
|
||||
<TABLE NAME="tool_recyclebin_course" COMMENT="A list of items in the course recycle bin">
|
||||
@@ -38,4 +38,4 @@
|
||||
</INDEXES>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
</XMLDB>
|
||||
|
||||
@@ -37,7 +37,7 @@ class admin_uploadpicture_form extends moodleform {
|
||||
|
||||
|
||||
$options = array();
|
||||
$options['accepted_types'] = array('archive');
|
||||
$options['accepted_types'] = array('.zip');
|
||||
$mform->addElement('filepicker', 'userpicturesfile', get_string('file'), 'size="40"', $options);
|
||||
$mform->addRule('userpicturesfile', null, 'required');
|
||||
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
define(["core/ajax","tool_usertours/tour","jquery","core/templates","core/str","core/log","core/notification"],function(a,b,c,d,e,f,g){var h={tourId:null,currentTour:null,context:null,init:function(a,b,d){h.tourId=a,h.context=d,"undefined"==typeof b&&(b=!0),b&&h.fetchTour(a),h.addResetLink(),c("body").on("click",'[data-action="tool_usertours/resetpagetour"]',function(a){a.preventDefault(),h.resetTourState(h.tourId)})},fetchTour:function(b){c.when(a.call([{methodname:"tool_usertours_fetch_and_start_tour",args:{tourid:b,context:h.context,pageurl:window.location.href}}])[0],d.render("tool_usertours/tourstep",{})).then(function(a,c){h.startBootstrapTour(b,c[0],a.tourconfig)}).fail(g.exception)},addResetLink:function(){e.get_string("resettouronpage","tool_usertours").done(function(a){c("footer, .logininfo").last().append('<div class="usertour"><a href="#" data-action="tool_usertours/resetpagetour">'+a+"</a></div>")})},startBootstrapTour:function(a,c,d){h.currentTour&&(d.onEnd=null,h.currentTour.endTour(),delete h.currentTour),d.eventHandlers={afterEnd:[h.markTourComplete],afterRender:[h.markStepShown]},d.tourName=d.name,delete d.name,d.template=c,d.steps=d.steps.map(function(a){return"undefined"!=typeof a.element&&(a.target=a.element,delete a.element),"undefined"!=typeof a.reflex&&(a.moveOnClick=!!a.reflex,delete a.reflex),"undefined"!=typeof a.content&&(a.body=a.content,delete a.content),a}),h.currentTour=new b(d),h.currentTour.startTour()},markStepShown:function(){var b=this.getStepConfig(this.getCurrentStepNumber());c.when(a.call([{methodname:"tool_usertours_step_shown",args:{tourid:h.tourId,context:h.context,pageurl:window.location.href,stepid:b.stepid,stepindex:this.getCurrentStepNumber()}}])[0]).fail(f.error)},markTourComplete:function(){var b=this.getStepConfig(this.getCurrentStepNumber());c.when(a.call([{methodname:"tool_usertours_complete_tour",args:{tourid:h.tourId,context:h.context,pageurl:window.location.href,stepid:b.stepid,stepindex:this.getCurrentStepNumber()}}])[0]).fail(f.error)},resetTourState:function(b){c.when(a.call([{methodname:"tool_usertours_reset_tour",args:{tourid:b,context:h.context,pageurl:window.location.href}}])[0]).then(function(a){a.startTour&&h.fetchTour(a.startTour)}).fail(g.exception)}};return{init:h.init,resetTourState:h.resetTourState}});
|
||||
define(["core/ajax","tool_usertours/tour","jquery","core/templates","core/str","core/log","core/notification"],function(a,b,c,d,e,f,g){var h={tourId:null,currentTour:null,context:null,init:function(a,b,d){h.tourId=a,h.context=d,"undefined"==typeof b&&(b=!0),b&&h.fetchTour(a),h.addResetLink(),c("body").on("click",'[data-action="tool_usertours/resetpagetour"]',function(a){a.preventDefault(),h.resetTourState(h.tourId)})},fetchTour:function(b){M.util.js_pending("admin_usertour_fetchTour"+b),c.when(a.call([{methodname:"tool_usertours_fetch_and_start_tour",args:{tourid:b,context:h.context,pageurl:window.location.href}}])[0],d.render("tool_usertours/tourstep",{})).then(function(a,c){return h.startBootstrapTour(b,c[0],a.tourconfig)}).always(function(){M.util.js_complete("admin_usertour_fetchTour"+b)}).fail(g.exception)},addResetLink:function(){M.util.js_pending("admin_usertour_addResetLink"),e.get_string("resettouronpage","tool_usertours").done(function(a){c("footer, .logininfo").last().append('<div class="usertour"><a href="#" data-action="tool_usertours/resetpagetour">'+a+"</a></div>")}).always(function(){M.util.js_complete("admin_usertour_addResetLink")}).fail()},startBootstrapTour:function(a,c,d){return h.currentTour&&(d.onEnd=null,h.currentTour.endTour(),delete h.currentTour),d.eventHandlers={afterEnd:[h.markTourComplete],afterRender:[h.markStepShown]},d.tourName=d.name,delete d.name,d.template=c,d.steps=d.steps.map(function(a){return"undefined"!=typeof a.element&&(a.target=a.element,delete a.element),"undefined"!=typeof a.reflex&&(a.moveOnClick=!!a.reflex,delete a.reflex),"undefined"!=typeof a.content&&(a.body=a.content,delete a.content),a}),h.currentTour=new b(d),h.currentTour.startTour()},markStepShown:function(){var b=this.getStepConfig(this.getCurrentStepNumber());c.when(a.call([{methodname:"tool_usertours_step_shown",args:{tourid:h.tourId,context:h.context,pageurl:window.location.href,stepid:b.stepid,stepindex:this.getCurrentStepNumber()}}])[0]).fail(f.error)},markTourComplete:function(){var b=this.getStepConfig(this.getCurrentStepNumber());c.when(a.call([{methodname:"tool_usertours_complete_tour",args:{tourid:h.tourId,context:h.context,pageurl:window.location.href,stepid:b.stepid,stepindex:this.getCurrentStepNumber()}}])[0]).fail(f.error)},resetTourState:function(b){c.when(a.call([{methodname:"tool_usertours_reset_tour",args:{tourid:b,context:h.context,pageurl:window.location.href}}])[0]).then(function(a){a.startTour&&h.fetchTour(a.startTour)}).fail(g.exception)}};return{init:h.init,resetTourState:h.resetTourState}});
|
||||
@@ -619,43 +619,44 @@ Tour.prototype.addEventHandler = function (eventName, handler) {
|
||||
*/
|
||||
Tour.prototype.processStepListeners = function (stepConfig) {
|
||||
this.listeners.push(
|
||||
// Next/Previous buttons.
|
||||
{
|
||||
node: this.currentStepNode,
|
||||
args: ['click', '[data-role="next"]', $.proxy(this.next, this)]
|
||||
}, {
|
||||
node: this.currentStepNode,
|
||||
args: ['click', '[data-role="previous"]', $.proxy(this.previous, this)]
|
||||
},
|
||||
// Next/Previous buttons.
|
||||
{
|
||||
node: this.currentStepNode,
|
||||
args: ['click', '[data-role="next"]', $.proxy(this.next, this)]
|
||||
}, {
|
||||
node: this.currentStepNode,
|
||||
args: ['click', '[data-role="previous"]', $.proxy(this.previous, this)]
|
||||
},
|
||||
|
||||
// Close and end tour buttons.
|
||||
{
|
||||
node: this.currentStepNode,
|
||||
args: ['click', '[data-role="end"]', $.proxy(this.endTour, this)]
|
||||
},
|
||||
// Close and end tour buttons.
|
||||
{
|
||||
node: this.currentStepNode,
|
||||
args: ['click', '[data-role="end"]', $.proxy(this.endTour, this)]
|
||||
},
|
||||
|
||||
// Click backdrop and hide tour.
|
||||
{
|
||||
node: $('[data-flexitour="backdrop"]'),
|
||||
args: ['click', $.proxy(this.hide, this)]
|
||||
},
|
||||
// Click backdrop and hide tour.
|
||||
{
|
||||
node: $('[data-flexitour="backdrop"]'),
|
||||
args: ['click', $.proxy(this.hide, this)]
|
||||
},
|
||||
|
||||
// Click out and hide tour without backdrop.
|
||||
{
|
||||
node: $('body'),
|
||||
args: ['click', $.proxy(function (e) {
|
||||
// Handle click in or click out tour content,
|
||||
// if click out, hide tour.
|
||||
if (!this.currentStepNode.is(e.target) && $(e.target).closest('[data-role="flexitour-step"]').length === 0) {
|
||||
this.hide();
|
||||
}}, this)]
|
||||
},
|
||||
// Click out and hide tour without backdrop.
|
||||
{
|
||||
node: $('body'),
|
||||
args: ['click', $.proxy(function (e) {
|
||||
// Handle click in or click out tour content,
|
||||
// if click out, hide tour.
|
||||
if (!this.currentStepNode.is(e.target) && $(e.target).closest('[data-role="flexitour-step"]').length === 0) {
|
||||
this.hide();
|
||||
}
|
||||
}, this)]
|
||||
},
|
||||
|
||||
// Keypresses.
|
||||
{
|
||||
node: $('body'),
|
||||
args: ['keydown', $.proxy(this.handleKeyDown, this)]
|
||||
});
|
||||
// Keypresses.
|
||||
{
|
||||
node: $('body'),
|
||||
args: ['keydown', $.proxy(this.handleKeyDown, this)]
|
||||
});
|
||||
|
||||
if (stepConfig.moveOnClick) {
|
||||
var targetNode = this.getStepTarget(stepConfig);
|
||||
@@ -1260,6 +1261,58 @@ Tour.prototype.positionStep = function (stepConfig) {
|
||||
arrow: {
|
||||
element: '[data-role="arrow"]'
|
||||
}
|
||||
},
|
||||
onCreate: function onCreate(data) {
|
||||
recalculateArrowPosition(data);
|
||||
},
|
||||
onUpdate: function onUpdate(data) {
|
||||
recalculateArrowPosition(data);
|
||||
}
|
||||
};
|
||||
|
||||
var recalculateArrowPosition = function recalculateArrowPosition(data) {
|
||||
var placement = data.placement.split('-')[0];
|
||||
var isVertical = ['left', 'right'].indexOf(placement) !== -1;
|
||||
var arrowElement = data.instance.popper.querySelector('[data-role="arrow"]');
|
||||
var stepElement = $(data.instance.popper.querySelector('[data-role="flexitour-step"]'));
|
||||
if (isVertical) {
|
||||
var arrowHeight = parseFloat(window.getComputedStyle(arrowElement).height);
|
||||
var arrowOffset = parseFloat(window.getComputedStyle(arrowElement).top);
|
||||
var popperHeight = parseFloat(window.getComputedStyle(data.instance.popper).height);
|
||||
var popperOffset = parseFloat(window.getComputedStyle(data.instance.popper).top);
|
||||
var popperBorderWidth = parseFloat(stepElement.css('borderTopWidth'));
|
||||
var popperBorderRadiusWidth = parseFloat(stepElement.css('borderTopLeftRadius')) * 2;
|
||||
var arrowPos = arrowOffset + arrowHeight / 2;
|
||||
var maxPos = popperHeight + popperOffset - popperBorderWidth - popperBorderRadiusWidth;
|
||||
var minPos = popperOffset + popperBorderWidth + popperBorderRadiusWidth;
|
||||
if (arrowPos >= maxPos || arrowPos <= minPos) {
|
||||
var newArrowPos = 0;
|
||||
if (arrowPos > popperHeight / 2) {
|
||||
newArrowPos = maxPos - arrowHeight;
|
||||
} else {
|
||||
newArrowPos = minPos + arrowHeight;
|
||||
}
|
||||
$(arrowElement).css('top', newArrowPos);
|
||||
}
|
||||
} else {
|
||||
var arrowWidth = parseFloat(window.getComputedStyle(arrowElement).width);
|
||||
var _arrowOffset = parseFloat(window.getComputedStyle(arrowElement).left);
|
||||
var popperWidth = parseFloat(window.getComputedStyle(data.instance.popper).width);
|
||||
var _popperOffset = parseFloat(window.getComputedStyle(data.instance.popper).left);
|
||||
var _popperBorderWidth = parseFloat(stepElement.css('borderTopWidth'));
|
||||
var _popperBorderRadiusWidth = parseFloat(stepElement.css('borderTopLeftRadius')) * 2;
|
||||
var _arrowPos = _arrowOffset + arrowWidth / 2;
|
||||
var _maxPos = popperWidth + _popperOffset - _popperBorderWidth - _popperBorderRadiusWidth;
|
||||
var _minPos = _popperOffset + _popperBorderWidth + _popperBorderRadiusWidth;
|
||||
if (_arrowPos >= _maxPos || _arrowPos <= _minPos) {
|
||||
var _newArrowPos = 0;
|
||||
if (_arrowPos > popperWidth / 2) {
|
||||
_newArrowPos = _maxPos - arrowWidth;
|
||||
} else {
|
||||
_newArrowPos = _minPos + arrowWidth;
|
||||
}
|
||||
$(arrowElement).css('left', _newArrowPos);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ function(ajax, BootstrapTour, $, templates, str, log, notification) {
|
||||
* @param {Number} tourId The ID of the tour to start.
|
||||
*/
|
||||
fetchTour: function(tourId) {
|
||||
M.util.js_pending('admin_usertour_fetchTour' + tourId);
|
||||
$.when(
|
||||
ajax.call([
|
||||
{
|
||||
@@ -67,7 +68,11 @@ function(ajax, BootstrapTour, $, templates, str, log, notification) {
|
||||
])[0],
|
||||
templates.render('tool_usertours/tourstep', {})
|
||||
).then(function(response, template) {
|
||||
usertours.startBootstrapTour(tourId, template[0], response.tourconfig);
|
||||
return usertours.startBootstrapTour(tourId, template[0], response.tourconfig);
|
||||
}).always(function() {
|
||||
M.util.js_complete('admin_usertour_fetchTour' + tourId);
|
||||
|
||||
return;
|
||||
}).fail(notification.exception);
|
||||
},
|
||||
|
||||
@@ -77,6 +82,7 @@ function(ajax, BootstrapTour, $, templates, str, log, notification) {
|
||||
* @method addResetLink
|
||||
*/
|
||||
addResetLink: function() {
|
||||
M.util.js_pending('admin_usertour_addResetLink');
|
||||
str.get_string('resettouronpage', 'tool_usertours')
|
||||
.done(function(s) {
|
||||
// Grab the last item in the page of these.
|
||||
@@ -89,7 +95,13 @@ function(ajax, BootstrapTour, $, templates, str, log, notification) {
|
||||
'</a>' +
|
||||
'</div>'
|
||||
);
|
||||
});
|
||||
})
|
||||
.always(function() {
|
||||
M.util.js_complete('admin_usertour_addResetLink');
|
||||
|
||||
return;
|
||||
})
|
||||
.fail();
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -99,6 +111,7 @@ function(ajax, BootstrapTour, $, templates, str, log, notification) {
|
||||
* @param {Number} tourId The ID of the tour to start.
|
||||
* @param {String} template The template to use.
|
||||
* @param {Object} tourConfig The tour configuration.
|
||||
* @return {Object}
|
||||
*/
|
||||
startBootstrapTour: function(tourId, template, tourConfig) {
|
||||
if (usertours.currentTour) {
|
||||
@@ -142,7 +155,7 @@ function(ajax, BootstrapTour, $, templates, str, log, notification) {
|
||||
});
|
||||
|
||||
usertours.currentTour = new BootstrapTour(tourConfig);
|
||||
usertours.currentTour.startTour();
|
||||
return usertours.currentTour.startTour();
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<?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 tool_usertours.
|
||||
*
|
||||
* @package tool_usertours
|
||||
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_usertours\privacy;
|
||||
|
||||
use \core_privacy\local\request\writer;
|
||||
use \core_privacy\local\metadata\collection;
|
||||
use \core_privacy\local\request\transform;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Implementation of the privacy subsystem plugin provider for the user tours feature.
|
||||
*
|
||||
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements
|
||||
// This plugin has data.
|
||||
\core_privacy\local\metadata\provider,
|
||||
|
||||
// This plugin has some sitewide user preferences to export.
|
||||
\core_privacy\local\request\user_preference_provider
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns meta data about this system.
|
||||
*
|
||||
* @param collection $itemcollection The initialised item collection to add items to.
|
||||
* @return collection A listing of user data stored through this system.
|
||||
*/
|
||||
public static function get_metadata(collection $items) {
|
||||
// There are several user preferences.
|
||||
$items->add_user_preference(\tool_usertours\tour::TOUR_REQUESTED_BY_USER, 'privacy:metadata:preference:requested');
|
||||
$items->add_user_preference(\tool_usertours\tour::TOUR_LAST_COMPLETED_BY_USER, 'privacy:metadata:preference:completed');
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store all user preferences for the plugin.
|
||||
*
|
||||
* @param int $userid The userid of the user whose data is to be exported.
|
||||
*/
|
||||
public static function export_user_preferences($userid) {
|
||||
$preferences = get_user_preferences();
|
||||
foreach ($preferences as $name => $value) {
|
||||
$descriptionidentifier = null;
|
||||
$tourid = null;
|
||||
if (strpos($name, \tool_usertours\tour::TOUR_REQUESTED_BY_USER) === 0) {
|
||||
$descriptionidentifier = 'privacy:request:preference:requested';
|
||||
$tourid = substr($name, strlen(\tool_usertours\tour::TOUR_REQUESTED_BY_USER));
|
||||
} else if (strpos($name, \tool_usertours\tour::TOUR_LAST_COMPLETED_BY_USER) === 0) {
|
||||
$descriptionidentifier = 'privacy:request:preference:completed';
|
||||
$tourid = substr($name, strlen(\tool_usertours\tour::TOUR_LAST_COMPLETED_BY_USER));
|
||||
}
|
||||
|
||||
if ($descriptionidentifier !== null) {
|
||||
$time = transform::datetime($value);
|
||||
$tour = \tool_usertours\tour::instance($tourid);
|
||||
|
||||
writer::export_user_preference(
|
||||
'tool_usertours',
|
||||
$name,
|
||||
$time,
|
||||
get_string($descriptionidentifier, 'tool_usertours', (object) [
|
||||
'name' => $tour->get_name(),
|
||||
'time' => $time,
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="tool/usertours/db" VERSION="20160830" COMMENT="XMLDB file for Moodle tool/usertours"
|
||||
<XMLDB PATH="admin/tool/usertours/db" VERSION="20160830" COMMENT="XMLDB file for Moodle tool/usertours"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
<TABLES>
|
||||
<TABLE NAME="tool_usertours_tours" COMMENT="List of tours">
|
||||
|
||||
@@ -169,3 +169,7 @@ $string['tour2_title_addingblocks'] = 'Adding blocks';
|
||||
$string['tour2_content_addingblocks'] = 'You can add blocks to this page using this button. However, think carefully about including any blocks on your pages. Blocks are not shown on the Moodle Mobile app, so for the best user experience it is better to make sure your course works well without any blocks.';
|
||||
$string['tour2_title_end'] = 'End of tour';
|
||||
$string['tour2_content_end'] = 'This is the end of your user tour. It won\'t show again unless you reset it using the link in the footer. The site admin can also create further tours for this site if required.';
|
||||
$string['privacy:metadata:preference:requested'] = 'The time that a user last manually requested a user tour.';
|
||||
$string['privacy:metadata:preference:completed'] = 'The time that a user last completed a user tour.';
|
||||
$string['privacy:request:preference:requested'] = 'You last requested the "{$a->name}" user tour on {$a->time}';
|
||||
$string['privacy:request:preference:completed'] = 'You last marked the "{$a->name}" user tour as completed on {$a->time}';
|
||||
|
||||
@@ -62,7 +62,16 @@ class behat_tool_usertours extends behat_base {
|
||||
public function i_add_steps_to_the_named_tour($tourname, TableNode $table) {
|
||||
$this->execute('behat_tool_usertours::i_open_the_user_tour_settings_page');
|
||||
$this->execute('behat_general::click_link', $this->escape($tourname));
|
||||
$this->execute('behat_tool_usertours::i_add_steps_to_the_tour', $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new steps to the current user tour.
|
||||
*
|
||||
* @Given /^I add steps to the tour:$/
|
||||
* @param TableNode $table
|
||||
*/
|
||||
public function i_add_steps_to_the_tour(TableNode $table) {
|
||||
foreach ($table->getHash() as $step) {
|
||||
$this->execute('behat_general::click_link', get_string('newstep', 'tool_usertours'));
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
@tool @tool_usertours
|
||||
Feature: Apply accessibility to a tour
|
||||
Background:
|
||||
Given I log in as "admin"
|
||||
And I add a new user tour with:
|
||||
| Name | First tour |
|
||||
| Description | My first tour |
|
||||
| Apply to URL match | FRONTPAGE |
|
||||
| Tour is enabled | 1 |
|
||||
| Show with backdrop | 1 |
|
||||
And I add steps to the "First tour" tour:
|
||||
| targettype | Title | Content |
|
||||
| Display in middle of page | Welcome | Welcome tour. |
|
||||
And I add steps to the tour:
|
||||
| targettype | targetvalue_selector | Title | Content |
|
||||
| Selector | .usermenu | User menu | Next page |
|
||||
| Selector | input,button | Page 2 | Next page |
|
||||
And I add steps to the tour:
|
||||
| targettype | Title | Content |
|
||||
| Display in middle of page | Page 3 | Final page. |
|
||||
|
||||
@javascript
|
||||
Scenario: Check tabbing working correctly.
|
||||
Given I am on site homepage
|
||||
And I wait "1" seconds
|
||||
And I should see "Welcome"
|
||||
# First dialogue of the tour, "Welcome". It has Close, Next and End buttons.
|
||||
# Nothing highlighted on the page. Initially whole dialogue focused.
|
||||
When I press tab
|
||||
Then the focused element is ".close" "css_element" in the "Welcome" "dialogue"
|
||||
When I press tab
|
||||
Then the focused element is "Next" "button" in the "Welcome" "dialogue"
|
||||
When I press tab
|
||||
Then the focused element is "End tour" "button" in the "Welcome" "dialogue"
|
||||
When I press tab
|
||||
# Here the focus loops round to the whole dialogue again.
|
||||
And I press tab
|
||||
Then the focused element is ".close" "css_element" in the "Welcome" "dialogue"
|
||||
# Check looping works properly going backwards too.
|
||||
When I press shift tab
|
||||
And I press shift tab
|
||||
Then the focused element is "End tour" "button" in the "Welcome" "dialogue"
|
||||
|
||||
When I press "Next"
|
||||
# Now we are on the "User menu" step, so Previous is also enabled.
|
||||
# Also, the user menu section in the page is highlighted, and this
|
||||
# section contain a hyperlink so the focus have to go though and back to the dialogue.
|
||||
And I wait "1" seconds
|
||||
And I press tab
|
||||
Then the focused element is ".close" "css_element" in the "User menu" "dialogue"
|
||||
When I press tab
|
||||
Then the focused element is "Previous" "button" in the "User menu" "dialogue"
|
||||
When I press tab
|
||||
Then the focused element is "Next" "button" in the "User menu" "dialogue"
|
||||
When I press tab
|
||||
Then the focused element is "End tour" "button" in the "User menu" "dialogue"
|
||||
# We tab 3 times from "End Tour" button to header container, drop down then go to "Dashboard" link.
|
||||
When I press tab
|
||||
Then the focused element is ".usermenu" "css_element"
|
||||
When I press tab
|
||||
Then the focused element is "Admin User" "link" in the ".usermenu" "css_element"
|
||||
When I press tab
|
||||
And I press tab
|
||||
Then the focused element is ".close" "css_element" in the "User menu" "dialogue"
|
||||
# Press shift-tab twice should lead us back to "Admin user" link.
|
||||
When I press shift tab
|
||||
And I press shift tab
|
||||
Then the focused element is "Admin User" "link" in the ".usermenu" "css_element"
|
||||
|
||||
@javascript
|
||||
Scenario: Aria tags should not exist
|
||||
And I am on site homepage
|
||||
When I click on "Next" "button"
|
||||
And I click on "Next" "button"
|
||||
Then "input[aria-describedby^='tour-step-tool_usertours'],button[aria-describedby^='tour-step-tool_usertours']" "css_element" should exist
|
||||
And "input[tabindex],button[tabindex]" "css_element" should exist
|
||||
When I click on "Next" "button"
|
||||
Then "input[aria-describedby^='tour-step-tool_usertours'],button[aria-describedby^='tour-step-tool_usertours']" "css_element" should not exist
|
||||
And "input[tabindex],button[tabindex]" "css_element" should not exist
|
||||
When I click on "Previous" "button"
|
||||
Then "input[aria-describedby^='tour-step-tool_usertours'],button[aria-describedby^='tour-step-tool_usertours']" "css_element" should exist
|
||||
And "input[tabindex],button[tabindex]" "css_element" should exist
|
||||
When I click on "End tour" "button"
|
||||
Then "input[aria-describedby^='tour-step-tool_usertours'],button[aria-describedby^='tour-step-tool_usertours']" "css_element" should not exist
|
||||
And "input[tabindex],button[tabindex]" "css_element" should not exist
|
||||
@@ -57,23 +57,3 @@ Feature: Apply tour filters to a tour
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I should see "Welcome to your course tour."
|
||||
|
||||
@javascript
|
||||
Scenario: Aria tags should not exist
|
||||
Given I log in as "admin"
|
||||
And I open the User tour settings page
|
||||
# Turn on default tour for boost theme.
|
||||
And I click on "Enable" "link" in the "Boost - administrator" "table_row"
|
||||
And I am on site homepage
|
||||
When I click on "Next" "button"
|
||||
Then "button[aria-describedby^='tour-step-tool_usertours']" "css_element" should exist
|
||||
And "button[tabindex]" "css_element" should exist
|
||||
When I click on "Next" "button"
|
||||
Then "button[aria-describedby^='tour-step-tool_usertours']" "css_element" should not exist
|
||||
And "button[tabindex]" "css_element" should not exist
|
||||
When I click on "Previous" "button"
|
||||
Then "button[aria-describedby^='tour-step-tool_usertours']" "css_element" should exist
|
||||
And "button[tabindex]" "css_element" should exist
|
||||
When I click on "End tour" "button"
|
||||
Then "button[aria-describedby^='tour-step-tool_usertours']" "css_element" should not exist
|
||||
And "button[tabindex]" "css_element" should not exist
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for the block_html implementation of the privacy API.
|
||||
*
|
||||
* @package block_html
|
||||
* @category test
|
||||
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use \core_privacy\local\metadata\collection;
|
||||
use \core_privacy\local\request\writer;
|
||||
use \core_privacy\local\request\approved_contextlist;
|
||||
use \core_privacy\local\request\deletion_criteria;
|
||||
use \tool_usertours\tour;
|
||||
use \tool_usertours\privacy\provider;
|
||||
|
||||
/**
|
||||
* Unit tests for the block_html implementation of the privacy API.
|
||||
*
|
||||
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class tool_usertours_privacy_testcase extends \core_privacy\tests\provider_testcase {
|
||||
|
||||
/**
|
||||
* Ensure that get_metadata exports valid content.
|
||||
*/
|
||||
public function test_get_metadata() {
|
||||
$items = new collection('tool_usertours');
|
||||
$result = provider::get_metadata($items);
|
||||
$this->assertSame($items, $result);
|
||||
$this->assertInstanceOf(collection::class, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that export_user_preferences returns no data if the user has completed no tours.
|
||||
*/
|
||||
public function test_export_user_preferences_no_pref() {
|
||||
$user = \core_user::get_user_by_username('admin');
|
||||
provider::export_user_preferences($user->id);
|
||||
|
||||
$writer = writer::with_context(\context_system::instance());
|
||||
|
||||
$this->assertFalse($writer->has_any_data());
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that export_user_preferences returns request completion data.
|
||||
*/
|
||||
public function test_export_user_preferences_completed() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$alltours = $DB->get_records('tool_usertours_tours');
|
||||
$tourdata = reset($alltours);
|
||||
|
||||
$user = \core_user::get_user_by_username('admin');
|
||||
$tour = tour::instance($tourdata->id);
|
||||
$tour->mark_user_completed();
|
||||
provider::export_user_preferences($user->id);
|
||||
|
||||
$writer = writer::with_context(\context_system::instance());
|
||||
|
||||
$this->assertTrue($writer->has_any_data());
|
||||
$prefs = $writer->get_user_preferences('tool_usertours');
|
||||
|
||||
$this->assertCount(1, (array) $prefs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that export_user_preferences returns request completion data.
|
||||
*/
|
||||
public function test_export_user_preferences_requested() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$alltours = $DB->get_records('tool_usertours_tours');
|
||||
$tourdata = reset($alltours);
|
||||
|
||||
$user = \core_user::get_user_by_username('admin');
|
||||
$tour = tour::instance($tourdata->id);
|
||||
$tour->mark_user_completed();
|
||||
$tour->request_user_reset();
|
||||
provider::export_user_preferences($user->id);
|
||||
|
||||
$writer = writer::with_context(\context_system::instance());
|
||||
|
||||
$this->assertTrue($writer->has_any_data());
|
||||
$prefs = $writer->get_user_preferences('tool_usertours');
|
||||
|
||||
$this->assertCount(2, (array) $prefs);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<location>amd/src/tour.js</location>
|
||||
<name>Flexitour</name>
|
||||
<license>GPLv3</license>
|
||||
<version>0.12.0</version>
|
||||
<version>0.12.2</version>
|
||||
<licenseversion>3</licenseversion>
|
||||
</library>
|
||||
<library>
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Contains helper class for digital consent.
|
||||
*
|
||||
* @package core_auth
|
||||
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_auth;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Helper class for digital consent.
|
||||
*
|
||||
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class digital_consent {
|
||||
|
||||
/**
|
||||
* Returns true if age and location verification is enabled in the site.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_age_digital_consent_verification_enabled() {
|
||||
global $CFG;
|
||||
|
||||
return !empty($CFG->agedigitalconsentverification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a user is a digital minor.
|
||||
*
|
||||
* @param int $age
|
||||
* @param string $country The country code (ISO 3166-2)
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_minor($age, $country) {
|
||||
global $CFG;
|
||||
|
||||
$ageconsentmap = $CFG->agedigitalconsentmap;
|
||||
$agedigitalconsentmap = self::parse_age_digital_consent_map($ageconsentmap);
|
||||
|
||||
return array_key_exists($country, $agedigitalconsentmap) ?
|
||||
$age < $agedigitalconsentmap[$country] : $age < $agedigitalconsentmap['*'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the agedigitalconsentmap setting into an array.
|
||||
*
|
||||
* @param string $ageconsentmap The value of the agedigitalconsentmap setting
|
||||
* @return array $ageconsentmapparsed
|
||||
*/
|
||||
public static function parse_age_digital_consent_map($ageconsentmap) {
|
||||
|
||||
$ageconsentmapparsed = array();
|
||||
$countries = get_string_manager()->get_list_of_countries();
|
||||
$isdefaultvaluepresent = false;
|
||||
$lines = preg_split('/\r|\n/', $ageconsentmap, -1, PREG_SPLIT_NO_EMPTY);
|
||||
foreach ($lines as $line) {
|
||||
$arr = explode(",", $line);
|
||||
// Handle if there is more or less than one comma separator.
|
||||
if (count($arr) != 2) {
|
||||
throw new \moodle_exception('agedigitalconsentmapinvalidcomma', 'error', '', $line);
|
||||
}
|
||||
$country = trim($arr[0]);
|
||||
$age = trim($arr[1]);
|
||||
// Check if default.
|
||||
if ($country == "*") {
|
||||
$isdefaultvaluepresent = true;
|
||||
}
|
||||
// Handle if the presented value for country is not valid.
|
||||
if ($country !== "*" && !array_key_exists($country, $countries)) {
|
||||
throw new \moodle_exception('agedigitalconsentmapinvalidcountry', 'error', '', $country);
|
||||
}
|
||||
// Handle if the presented value for age is not valid.
|
||||
if (!is_numeric($age)) {
|
||||
throw new \moodle_exception('agedigitalconsentmapinvalidage', 'error', '', $age);
|
||||
}
|
||||
$ageconsentmapparsed[$country] = $age;
|
||||
}
|
||||
// Handle if a default value does not exist.
|
||||
if (!$isdefaultvaluepresent) {
|
||||
throw new \moodle_exception('agedigitalconsentmapinvaliddefault');
|
||||
}
|
||||
|
||||
return $ageconsentmapparsed;
|
||||
}
|
||||
}
|
||||
@@ -121,4 +121,125 @@ class core_auth_external extends external_api {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for the digital minor check.
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.4
|
||||
*/
|
||||
public static function is_minor_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'age' => new external_value(PARAM_INT, 'Age'),
|
||||
'country' => new external_value(PARAM_ALPHA, 'Country of residence'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests a check if a user is digital minor.
|
||||
*
|
||||
* @param int $age User age
|
||||
* @param string $country Country of residence
|
||||
* @return array status (true if the user is a minor, false otherwise)
|
||||
* @since Moodle 3.4
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function is_minor($age, $country) {
|
||||
global $CFG, $PAGE;
|
||||
require_once($CFG->dirroot . '/login/lib.php');
|
||||
|
||||
$params = self::validate_parameters(
|
||||
self::is_minor_parameters(),
|
||||
array(
|
||||
'age' => $age,
|
||||
'country' => $country,
|
||||
)
|
||||
);
|
||||
|
||||
if (!array_key_exists($params['country'], get_string_manager()->get_list_of_countries())) {
|
||||
throw new invalid_parameter_exception('Invalid value for country parameter (value: '.
|
||||
$params['country'] .')');
|
||||
}
|
||||
|
||||
$context = context_system::instance();
|
||||
$PAGE->set_context($context);
|
||||
|
||||
// Check if verification of age and location (minor check) is enabled.
|
||||
if (!\core_auth\digital_consent::is_age_digital_consent_verification_enabled()) {
|
||||
throw new moodle_exception('nopermissions', 'error', '',
|
||||
get_string('agelocationverificationdisabled', 'error'));
|
||||
}
|
||||
|
||||
$status = \core_auth\digital_consent::is_minor($params['age'], $params['country']);
|
||||
|
||||
return array(
|
||||
'status' => $status
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the is_minor return value.
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 3.4
|
||||
*/
|
||||
public static function is_minor_returns() {
|
||||
return new external_single_structure(
|
||||
array(
|
||||
'status' => new external_value(PARAM_BOOL, 'True if the user is considered to be a digital minor,
|
||||
false if not')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for is_age_digital_consent_verification_enabled.
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.3
|
||||
*/
|
||||
public static function is_age_digital_consent_verification_enabled_parameters() {
|
||||
return new external_function_parameters(array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if age digital consent verification is enabled.
|
||||
*
|
||||
* @return array status (true if digital consent verification is enabled, false otherwise.)
|
||||
* @since Moodle 3.3
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function is_age_digital_consent_verification_enabled() {
|
||||
global $PAGE;
|
||||
|
||||
$context = context_system::instance();
|
||||
$PAGE->set_context($context);
|
||||
|
||||
$status = false;
|
||||
// Check if verification is enabled.
|
||||
if (\core_auth\digital_consent::is_age_digital_consent_verification_enabled()) {
|
||||
$status = true;
|
||||
}
|
||||
|
||||
return array(
|
||||
'status' => $status
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the is_age_digital_consent_verification_enabled return value.
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 3.3
|
||||
*/
|
||||
public static function is_age_digital_consent_verification_enabled_returns() {
|
||||
return new external_single_structure(
|
||||
array(
|
||||
'status' => new external_value(PARAM_BOOL, 'True if digital consent verification is enabled,
|
||||
false otherwise.')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Age and location verification mform.
|
||||
*
|
||||
* @package core_auth
|
||||
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_auth\form;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir.'/formslib.php');
|
||||
|
||||
use moodleform;
|
||||
|
||||
/**
|
||||
* Age and location verification mform class.
|
||||
*
|
||||
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class verify_age_location_form extends moodleform {
|
||||
/**
|
||||
* Defines the form fields.
|
||||
*/
|
||||
public function definition() {
|
||||
global $CFG;
|
||||
|
||||
$mform = $this->_form;
|
||||
|
||||
$mform->addElement('text', 'age', get_string('whatisyourage'), array('optional' => false));
|
||||
$mform->setType('age', PARAM_RAW);
|
||||
$mform->addRule('age', null, 'required', null, 'client');
|
||||
$mform->addRule('age', null, 'numeric', null, 'client');
|
||||
|
||||
$countries = get_string_manager()->get_list_of_countries();
|
||||
$defaultcountry[''] = get_string('selectacountry');
|
||||
$countries = array_merge($defaultcountry, $countries);
|
||||
$mform->addElement('select', 'country', get_string('wheredoyoulive'), $countries);
|
||||
$mform->addRule('country', null, 'required', null, 'client');
|
||||
$mform->setDefault('country', $CFG->country);
|
||||
|
||||
$this->add_action_buttons(true, get_string('proceed'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Digital minor renderable.
|
||||
*
|
||||
* @package core_auth
|
||||
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_auth\output;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use renderable;
|
||||
use renderer_base;
|
||||
use templatable;
|
||||
|
||||
/**
|
||||
* Digital minor renderable class.
|
||||
*
|
||||
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class digital_minor_page implements renderable, templatable {
|
||||
|
||||
/**
|
||||
* Export the page data for the mustache template.
|
||||
*
|
||||
* @param renderer_base $output renderer to be used to render the page elements.
|
||||
* @return stdClass
|
||||
*/
|
||||
public function export_for_template(renderer_base $output) {
|
||||
global $SITE, $CFG;
|
||||
|
||||
$sitename = format_string($SITE->fullname);
|
||||
$supportname = $CFG->supportname;
|
||||
$supportemail = $CFG->supportemail;
|
||||
|
||||
$context = [
|
||||
'sitename' => $sitename,
|
||||
'supportname' => $supportname,
|
||||
'supportemail' => $supportemail,
|
||||
'homelink' => new \moodle_url('/')
|
||||
];
|
||||
|
||||
return $context;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Age and location verification renderable.
|
||||
*
|
||||
* @package core_auth
|
||||
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_auth\output;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use renderable;
|
||||
use renderer_base;
|
||||
use templatable;
|
||||
|
||||
require_once($CFG->libdir.'/formslib.php');
|
||||
|
||||
/**
|
||||
* Age and location verification renderable class.
|
||||
*
|
||||
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class verify_age_location_page implements renderable, templatable {
|
||||
|
||||
/** @var mform The form object */
|
||||
protected $form;
|
||||
|
||||
/** @var string Error message */
|
||||
protected $errormessage;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param mform $form The form object
|
||||
* @param string $errormessage The error message.
|
||||
*/
|
||||
public function __construct($form, $errormessage = null) {
|
||||
$this->form = $form;
|
||||
$this->errormessage = $errormessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the page data for the mustache template.
|
||||
*
|
||||
* @param renderer_base $output renderer to be used to render the page elements.
|
||||
* @return stdClass
|
||||
*/
|
||||
public function export_for_template(renderer_base $output) {
|
||||
global $SITE;
|
||||
|
||||
$sitename = format_string($SITE->fullname);
|
||||
$formhtml = $this->form->render();
|
||||
$error = $this->errormessage;
|
||||
|
||||
$context = [
|
||||
'sitename' => $sitename,
|
||||
'formhtml' => $formhtml,
|
||||
'error' => $error
|
||||
];
|
||||
|
||||
return $context;
|
||||
}
|
||||
}
|
||||
@@ -88,8 +88,9 @@ class auth_email_external extends external_api {
|
||||
if (!empty($CFG->passwordpolicy)) {
|
||||
$result['passwordpolicy'] = print_password_policy();
|
||||
}
|
||||
if (!empty($CFG->sitepolicy)) {
|
||||
$result['sitepolicy'] = $CFG->sitepolicy;
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
if ($sitepolicy = $manager->get_embed_url()) {
|
||||
$result['sitepolicy'] = $sitepolicy->out(false);
|
||||
}
|
||||
if (!empty($CFG->defaultcity)) {
|
||||
$result['defaultcity'] = $CFG->defaultcity;
|
||||
@@ -112,11 +113,11 @@ class auth_email_external extends external_api {
|
||||
}
|
||||
|
||||
if (signup_captcha_enabled()) {
|
||||
require_once($CFG->libdir . '/recaptchalib.php');
|
||||
// We return the public key, maybe we want to use the javascript api to get the image.
|
||||
// With reCAPTCHA v2 the captcha will be rendered by the mobile client using just the publickey.
|
||||
// For now include placeholders for the v1 paramaters to support older mobile app versions.
|
||||
$result['recaptchapublickey'] = $CFG->recaptchapublickey;
|
||||
list($result['recaptchachallengehash'], $result['recaptchachallengeimage'], $result['recaptchachallengejs']) =
|
||||
recaptcha_get_challenge_hash_and_urls(RECAPTCHA_API_SECURE_SERVER, $CFG->recaptchapublickey);
|
||||
array('', '', '');
|
||||
}
|
||||
|
||||
$result['warnings'] = array();
|
||||
@@ -287,7 +288,8 @@ class auth_email_external extends external_api {
|
||||
$data = $params;
|
||||
$data['email2'] = $data['email'];
|
||||
// Force policy agreed if a site policy is set. The client is responsible of implementing the interface check.
|
||||
if (!empty($CFG->sitepolicy)) {
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
if (!$manager->is_defined()) {
|
||||
$data['policyagreed'] = 1;
|
||||
}
|
||||
unset($data['recaptcharesponse']);
|
||||
@@ -307,11 +309,11 @@ class auth_email_external extends external_api {
|
||||
|
||||
// Validate recaptcha.
|
||||
if (signup_captcha_enabled()) {
|
||||
require_once($CFG->libdir . '/recaptchalib.php');
|
||||
$response = recaptcha_check_answer($CFG->recaptchaprivatekey, getremoteaddr(), $params['recaptchachallengehash'],
|
||||
$params['recaptcharesponse'], true);
|
||||
if (!$response->is_valid) {
|
||||
$errors['recaptcharesponse'] = $response->error;
|
||||
require_once($CFG->libdir . '/recaptchalib_v2.php');
|
||||
$response = recaptcha_check_response(RECAPTCHA_VERIFY_URL, $CFG->recaptchaprivatekey,
|
||||
getremoteaddr(), $params['recaptcharesponse']);
|
||||
if (!$response['isvalid']) {
|
||||
$errors['recaptcharesponse'] = $response['error'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Step definition for auth_email
|
||||
*
|
||||
* @package auth_email
|
||||
* @category test
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(__DIR__ . '/../../../../lib/behat/behat_base.php');
|
||||
|
||||
/**
|
||||
* Step definition for auth_email.
|
||||
*
|
||||
* @package auth_email
|
||||
* @category test
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_auth_email extends behat_base {
|
||||
|
||||
/**
|
||||
* Emulate clicking on confirmation link from the email
|
||||
*
|
||||
* @When /^I confirm email for "(?P<username>(?:[^"]|\\")*)"$/
|
||||
*
|
||||
* @param string $username
|
||||
*/
|
||||
public function i_confirm_email_for($username) {
|
||||
global $DB;
|
||||
$secret = $DB->get_field('user', 'secret', ['username' => $username], MUST_EXIST);
|
||||
$confirmationurl = new moodle_url('/login/confirm.php');
|
||||
$confirmationpath = $confirmationurl->out_as_local_url(false);
|
||||
$url = $confirmationpath . '?' . 'data='. $secret .'/'. $username;
|
||||
|
||||
$this->getSession()->visit($this->locate_path($url));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
@auth @auth_email
|
||||
Feature: User must accept policy when logging in and signing up
|
||||
In order to record user agreement to use the site
|
||||
As a user
|
||||
I need to be able to accept site policy during sign up
|
||||
|
||||
Scenario: Accept policy on sign up, no site policy
|
||||
Given the following config values are set as admin:
|
||||
| registerauth | email |
|
||||
| passwordpolicy | 0 |
|
||||
And I am on site homepage
|
||||
And I follow "Log in"
|
||||
When I press "Create new account"
|
||||
Then I should not see "I understand and agree"
|
||||
And I set the following fields to these values:
|
||||
| Username | user1 |
|
||||
| Password | user1 |
|
||||
| Email address | user1@address.invalid |
|
||||
| Email (again) | user1@address.invalid |
|
||||
| First name | User1 |
|
||||
| Surname | L1 |
|
||||
And I press "Create my new account"
|
||||
And I should see "Confirm your account"
|
||||
And I should see "An email should have been sent to your address at user1@address.invalid"
|
||||
And I confirm email for "user1"
|
||||
And I should see "Thanks, User1 L1"
|
||||
And I should see "Your registration has been confirmed"
|
||||
And I open my profile in edit mode
|
||||
And the field "First name" matches value "User1"
|
||||
And I log out
|
||||
# Confirm that user can login and browse the site (edit their profile).
|
||||
And I log in as "user1"
|
||||
And I open my profile in edit mode
|
||||
And the field "First name" matches value "User1"
|
||||
|
||||
Scenario: Accept policy on sign up, with site policy
|
||||
Given the following config values are set as admin:
|
||||
| registerauth | email |
|
||||
| passwordpolicy | 0 |
|
||||
| sitepolicy | https://moodle.org |
|
||||
And I am on site homepage
|
||||
And I follow "Log in"
|
||||
When I press "Create new account"
|
||||
Then the field "I understand and agree" matches value "0"
|
||||
And I set the following fields to these values:
|
||||
| Username | user1 |
|
||||
| Password | user1 |
|
||||
| Email address | user1@address.invalid |
|
||||
| Email (again) | user1@address.invalid |
|
||||
| First name | User1 |
|
||||
| Surname | L1 |
|
||||
| I understand and agree | 1 |
|
||||
And I press "Create my new account"
|
||||
And I should see "Confirm your account"
|
||||
And I should see "An email should have been sent to your address at user1@address.invalid"
|
||||
And I confirm email for "user1"
|
||||
And I should see "Thanks, User1 L1"
|
||||
And I should see "Your registration has been confirmed"
|
||||
And I open my profile in edit mode
|
||||
And the field "First name" matches value "User1"
|
||||
And I log out
|
||||
# Confirm that user is not asked to agree to site policy again after the next login.
|
||||
And I log in as "user1"
|
||||
And I open my profile in edit mode
|
||||
And the field "First name" matches value "User1"
|
||||
+3
-1
@@ -1167,7 +1167,9 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
*
|
||||
*/
|
||||
function user_update($olduser, $newuser) {
|
||||
global $USER;
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/user/profile/lib.php');
|
||||
|
||||
if (isset($olduser->username) and isset($newuser->username) and $olduser->username != $newuser->username) {
|
||||
error_log($this->errorlogtag.get_string('renamingnotallowed', 'auth_ldap'));
|
||||
|
||||
@@ -403,7 +403,20 @@ class auth extends \auth_plugin_base {
|
||||
if (!empty($linkedlogin) && empty($linkedlogin->get('confirmtoken'))) {
|
||||
$mappeduser = get_complete_user_data('id', $linkedlogin->get('userid'));
|
||||
|
||||
if ($mappeduser && $mappeduser->confirmed) {
|
||||
if ($mappeduser && $mappeduser->suspended) {
|
||||
$failurereason = AUTH_LOGIN_SUSPENDED;
|
||||
$event = \core\event\user_login_failed::create([
|
||||
'userid' => $mappeduser->id,
|
||||
'other' => [
|
||||
'username' => $userinfo['username'],
|
||||
'reason' => $failurereason
|
||||
]
|
||||
]);
|
||||
$event->trigger();
|
||||
$SESSION->loginerrormsg = get_string('invalidlogin');
|
||||
$client->log_out();
|
||||
redirect(new moodle_url('/login/index.php'));
|
||||
} else if ($mappeduser && $mappeduser->confirmed) {
|
||||
$userinfo = (array) $mappeduser;
|
||||
$userwasmapped = true;
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
@core @verify_age_location
|
||||
Feature: Test validation of 'Age of digital consent' setting.
|
||||
In order to set the 'Age of digital consent' setting
|
||||
As an admin
|
||||
I need to provide valid data and valid format
|
||||
|
||||
Background:
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Privacy settings" node in "Site administration > Privacy and policies"
|
||||
|
||||
Scenario: Admin provides valid value for 'Age of digital consent'.
|
||||
Given I set the field "s__agedigitalconsentmap" to multiline:
|
||||
"""
|
||||
*, 16
|
||||
AT, 14
|
||||
BE, 14
|
||||
"""
|
||||
When I press "Save changes"
|
||||
Then I should see "Changes saved"
|
||||
And I should not see "Some settings were not changed due to an error."
|
||||
And I should not see "The digital age of consent is not valid:"
|
||||
|
||||
Scenario: Admin provides invalid format for 'Age of digital consent'.
|
||||
# Try to set a value with missing space separator
|
||||
Given I set the field "s__agedigitalconsentmap" to multiline:
|
||||
"""
|
||||
*16
|
||||
AT, 14
|
||||
BE, 14
|
||||
"""
|
||||
When I press "Save changes"
|
||||
Then I should not see "Changes saved"
|
||||
And I should see "Some settings were not changed due to an error."
|
||||
And I should see "The digital age of consent is not valid: \"*16\" has more or less than one comma separator."
|
||||
# Try to set a value with missing default age of consent
|
||||
When I set the field "s__agedigitalconsentmap" to multiline:
|
||||
"""
|
||||
AT, 14
|
||||
BE, 14
|
||||
"""
|
||||
And I press "Save changes"
|
||||
Then I should not see "Changes saved"
|
||||
And I should see "Some settings were not changed due to an error."
|
||||
And I should see "The digital age of consent is not valid: Default (*) value is missing."
|
||||
|
||||
Scenario: Admin provides invalid age of consent or country for 'Age of digital consent'.
|
||||
# Try to set a value containing invalid age of consent
|
||||
Given I set the field "s__agedigitalconsentmap" to multiline:
|
||||
"""
|
||||
*, 16
|
||||
AT, age
|
||||
BE, 14
|
||||
"""
|
||||
When I press "Save changes"
|
||||
Then I should not see "Changes saved"
|
||||
And I should see "Some settings were not changed due to an error."
|
||||
And I should see "The digital age of consent is not valid: \"age\" is not a valid value for age."
|
||||
# Try to set a value containing invalid country
|
||||
When I set the field "s__agedigitalconsentmap" to multiline:
|
||||
"""
|
||||
*, 16
|
||||
COUNTRY, 14
|
||||
BE, 14
|
||||
"""
|
||||
And I press "Save changes"
|
||||
Then I should not see "Changes saved"
|
||||
And I should see "Some settings were not changed due to an error."
|
||||
And I should see "The digital age of consent is not valid: \"COUNTRY\" is not a valid value for country."
|
||||
@@ -0,0 +1,45 @@
|
||||
@core @verify_age_location
|
||||
Feature: Test the 'Digital age of consent verification' feature works.
|
||||
In order to self-register on the site
|
||||
As an user
|
||||
I need be to be over the age of digital consent
|
||||
|
||||
Background:
|
||||
Given the following config values are set as admin:
|
||||
| registerauth | email |
|
||||
| agedigitalconsentverification | 1 |
|
||||
|
||||
Scenario: User that is not considered a digital minor attempts to self-register on the site.
|
||||
# Try to access the sign up page.
|
||||
Given I am on homepage
|
||||
When I click on "Log in" "link" in the ".logininfo" "css_element"
|
||||
And I press "Create new account"
|
||||
Then I should see "Age and location verification"
|
||||
When I set the field "What is your age?" to "16"
|
||||
And I set the field "In which country do you live?" to "DZ"
|
||||
And I press "Proceed"
|
||||
Then I should see "New account"
|
||||
And I should see "Choose your username and password"
|
||||
# Try to access the sign up page again.
|
||||
When I press "Cancel"
|
||||
And I press "Create new account"
|
||||
Then I should see "New account"
|
||||
And I should see "Choose your username and password"
|
||||
|
||||
Scenario: User that is considered a digital minor attempts to self-register on the site.
|
||||
# Try to access the sign up page.
|
||||
Given I am on homepage
|
||||
When I click on "Log in" "link" in the ".logininfo" "css_element"
|
||||
And I press "Create new account"
|
||||
Then I should see "Age and location verification"
|
||||
When I set the field "What is your age?" to "12"
|
||||
And I set the field "In which country do you live?" to "AT"
|
||||
And I press "Proceed"
|
||||
Then I should see "You are considered to be a digital minor."
|
||||
And I should see "To create an account on this site please have your parent/guardian contact the following person."
|
||||
# Try to access the sign up page again.
|
||||
When I click on "Back to the site home" "link"
|
||||
And I click on "Log in" "link" in the ".logininfo" "css_element"
|
||||
And I press "Create new account"
|
||||
Then I should see "You are considered to be a digital minor."
|
||||
And I should see "To create an account on this site please have your parent/guardian contact the following person."
|
||||
@@ -0,0 +1,182 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for core_auth\digital_consent.
|
||||
*
|
||||
* @package core_auth
|
||||
* @copyright 2018 Mihail Geshoski
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Digital consent helper testcase.
|
||||
*
|
||||
* @package core_auth
|
||||
* @copyright 2018 Mihail Geshoski
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class core_auth_digital_consent_testcase extends advanced_testcase {
|
||||
|
||||
public function test_is_age_digital_consent_verification_enabled() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Age of digital consent verification is enabled.
|
||||
$CFG->agedigitalconsentverification = 0;
|
||||
|
||||
$isenabled = \core_auth\digital_consent::is_age_digital_consent_verification_enabled();
|
||||
$this->assertFalse($isenabled);
|
||||
}
|
||||
|
||||
public function test_is_minor() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest();
|
||||
|
||||
$agedigitalconsentmap = implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'AT, 14',
|
||||
'CZ, 13',
|
||||
'DE, 14',
|
||||
'DK, 13',
|
||||
]);
|
||||
$CFG->agedigitalconsentmap = $agedigitalconsentmap;
|
||||
|
||||
$usercountry1 = 'DK';
|
||||
$usercountry2 = 'AU';
|
||||
$userage1 = 12;
|
||||
$userage2 = 14;
|
||||
$userage3 = 16;
|
||||
|
||||
// Test country exists in agedigitalconsentmap and user age is below the particular digital minor age.
|
||||
$isminor = \core_auth\digital_consent::is_minor($userage1, $usercountry1);
|
||||
$this->assertTrue($isminor);
|
||||
// Test country exists in agedigitalconsentmap and user age is above the particular digital minor age.
|
||||
$isminor = \core_auth\digital_consent::is_minor($userage2, $usercountry1);
|
||||
$this->assertFalse($isminor);
|
||||
// Test country does not exists in agedigitalconsentmap and user age is below the particular digital minor age.
|
||||
$isminor = \core_auth\digital_consent::is_minor($userage2, $usercountry2);
|
||||
$this->assertTrue($isminor);
|
||||
// Test country does not exists in agedigitalconsentmap and user age is above the particular digital minor age.
|
||||
$isminor = \core_auth\digital_consent::is_minor($userage3, $usercountry2);
|
||||
$this->assertFalse($isminor);
|
||||
}
|
||||
|
||||
public function test_parse_age_digital_consent_map_valid_format() {
|
||||
|
||||
// Value of agedigitalconsentmap has a valid format.
|
||||
$agedigitalconsentmap = implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'AT, 14',
|
||||
'BE, 13'
|
||||
]);
|
||||
|
||||
$ageconsentmapparsed = \core_auth\digital_consent::parse_age_digital_consent_map($agedigitalconsentmap);
|
||||
|
||||
$this->assertEquals([
|
||||
'*' => 16,
|
||||
'AT' => 14,
|
||||
'BE' => 13
|
||||
], $ageconsentmapparsed
|
||||
);
|
||||
}
|
||||
|
||||
public function test_parse_age_digital_consent_map_invalid_format_missing_spaces() {
|
||||
|
||||
// Value of agedigitalconsentmap has an invalid format (missing space separator between values).
|
||||
$agedigitalconsentmap = implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'AT14',
|
||||
]);
|
||||
|
||||
$this->expectException('moodle_exception');
|
||||
$this->expectExceptionMessage(get_string('agedigitalconsentmapinvalidcomma', 'error', 'AT14'));
|
||||
|
||||
\core_auth\digital_consent::parse_age_digital_consent_map($agedigitalconsentmap);
|
||||
}
|
||||
|
||||
public function test_parse_age_digital_consent_map_invalid_format_missing_default_value() {
|
||||
|
||||
// Value of agedigitalconsentmap has an invalid format (missing default value).
|
||||
$agedigitalconsentmap = implode(PHP_EOL, [
|
||||
'BE, 16',
|
||||
'AT, 14'
|
||||
]);
|
||||
|
||||
$this->expectException('moodle_exception');
|
||||
$this->expectExceptionMessage(get_string('agedigitalconsentmapinvaliddefault', 'error'));
|
||||
|
||||
\core_auth\digital_consent::parse_age_digital_consent_map($agedigitalconsentmap);
|
||||
}
|
||||
|
||||
public function test_parse_age_digital_consent_map_invalid_format_invalid_country() {
|
||||
|
||||
// Value of agedigitalconsentmap has an invalid format (invalid value for country).
|
||||
$agedigitalconsentmap = implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'TEST, 14'
|
||||
]);
|
||||
|
||||
$this->expectException('moodle_exception');
|
||||
$this->expectExceptionMessage(get_string('agedigitalconsentmapinvalidcountry', 'error', 'TEST'));
|
||||
|
||||
\core_auth\digital_consent::parse_age_digital_consent_map($agedigitalconsentmap);
|
||||
}
|
||||
|
||||
public function test_parse_age_digital_consent_map_invalid_format_invalid_age_string() {
|
||||
|
||||
// Value of agedigitalconsentmap has an invalid format (string value for age).
|
||||
$agedigitalconsentmap = implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'AT, ten'
|
||||
]);
|
||||
|
||||
$this->expectException('moodle_exception');
|
||||
$this->expectExceptionMessage(get_string('agedigitalconsentmapinvalidage', 'error', 'ten'));
|
||||
|
||||
\core_auth\digital_consent::parse_age_digital_consent_map($agedigitalconsentmap);
|
||||
}
|
||||
|
||||
public function test_parse_age_digital_consent_map_invalid_format_missing_age() {
|
||||
|
||||
// Value of agedigitalconsentmap has an invalid format (missing value for age).
|
||||
$agedigitalconsentmap = implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'AT, '
|
||||
]);
|
||||
|
||||
$this->expectException('moodle_exception');
|
||||
$this->expectExceptionMessage(get_string('agedigitalconsentmapinvalidage', 'error', ''));
|
||||
|
||||
\core_auth\digital_consent::parse_age_digital_consent_map($agedigitalconsentmap);
|
||||
}
|
||||
|
||||
public function test_parse_age_digital_consent_map_invalid_format_missing_country() {
|
||||
|
||||
// Value of agedigitalconsentmap has an invalid format (missing value for country).
|
||||
$agedigitalconsentmap = implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
', 12'
|
||||
]);
|
||||
|
||||
$this->expectException('moodle_exception');
|
||||
$this->expectExceptionMessage(get_string('agedigitalconsentmapinvalidcountry', 'error', ''));
|
||||
|
||||
\core_auth\digital_consent::parse_age_digital_consent_map($agedigitalconsentmap);
|
||||
}
|
||||
}
|
||||
@@ -89,4 +89,30 @@ class core_auth_external_testcase extends externallib_advanced_testcase {
|
||||
$this->expectExceptionMessage(get_string('invalidconfirmdata', 'error'));
|
||||
$result = core_auth_external::confirm_user($username, 'zzZZzz');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test age digital consent not enabled.
|
||||
*/
|
||||
public function test_age_digital_consent_verification_is_not_enabled() {
|
||||
global $CFG;
|
||||
|
||||
$CFG->agedigitalconsentverification = 0;
|
||||
$result = core_auth_external::is_age_digital_consent_verification_enabled();
|
||||
$result = external_api::clean_returnvalue(
|
||||
core_auth_external::is_age_digital_consent_verification_enabled_returns(), $result);
|
||||
$this->assertFalse($result['status']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test age digital consent is enabled.
|
||||
*/
|
||||
public function test_age_digital_consent_verification_is_enabled() {
|
||||
global $CFG;
|
||||
|
||||
$CFG->agedigitalconsentverification = 1;
|
||||
$result = core_auth_external::is_age_digital_consent_verification_enabled();
|
||||
$result = external_api::clean_returnvalue(
|
||||
core_auth_external::is_age_digital_consent_verification_enabled_returns(), $result);
|
||||
$this->assertTrue($result['status']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
This files describes API changes in /auth/* - plugins,
|
||||
information provided here is intended especially for developers.
|
||||
|
||||
=== 3.3.5 ===
|
||||
|
||||
* Self registration plugins should use core_privacy\local\sitepolicy\manager instead of directly checking
|
||||
$CFG->sitepolicy , especially in custom signup forms. See https://docs.moodle.org/dev/Site_policy_handler
|
||||
|
||||
=== 3.3 ===
|
||||
|
||||
* Authentication plugins have been migrated to use the admin settings API. Plugins should use a settings.php file to
|
||||
|
||||
@@ -61,10 +61,10 @@ class edit_backpack_form extends moodleform {
|
||||
array('class' => 'notconnected', 'id' => 'connection-status'));
|
||||
$mform->addElement('static', 'status', get_string('status'), $status);
|
||||
$mform->addElement('hidden', 'email', $this->_customdata['email']);
|
||||
$mform->setType('email', PARAM_RAW_TRIMMED);
|
||||
$mform->setType('email', PARAM_EMAIL);
|
||||
$mform->hardFreeze(['email']);
|
||||
$status = html_writer::tag('span', $this->_customdata['email'], []);
|
||||
$mform->addElement('static', 'emailverify', get_string('email'), $status);
|
||||
$emailverify = html_writer::tag('span', s($this->_customdata['email']), []);
|
||||
$mform->addElement('static', 'emailverify', get_string('email'), $emailverify);
|
||||
$buttonarray = [];
|
||||
$buttonarray[] = &$mform->createElement('submit', 'submitbutton',
|
||||
get_string('backpackconnectionresendemail', 'badges'));
|
||||
@@ -80,7 +80,7 @@ class edit_backpack_form extends moodleform {
|
||||
$mform->addElement('text', 'email', get_string('email'), 'maxlength="100" size="30"');
|
||||
$mform->addHelpButton('email', 'backpackemail', 'badges');
|
||||
$mform->addRule('email', get_string('required'), 'required', null, 'client');
|
||||
$mform->setType('email', PARAM_RAW_TRIMMED);
|
||||
$mform->setType('email', PARAM_EMAIL);
|
||||
$this->add_action_buttons(false, get_string('backpackconnectionconnect', 'badges'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 block_activity_modules.
|
||||
*
|
||||
* @package block_activity_modules
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_activity_modules\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_activity_modules implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -24,3 +24,4 @@
|
||||
|
||||
$string['activity_modules:addinstance'] = 'Add a new activities block';
|
||||
$string['pluginname'] = 'Activities';
|
||||
$string['privacy:metadata'] = 'The Activites block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_activity_results.
|
||||
*
|
||||
* @package block_activity_results
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_activity_results\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_activity_results implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -65,3 +65,4 @@ $string['worstgrade'] = 'The lowest grade:';
|
||||
$string['worstgrades'] = 'The {$a} lowest grades:';
|
||||
$string['worstgroupgrade'] = 'The group with the lowest average:';
|
||||
$string['worstgroupgrades'] = 'The {$a} groups with the lowest average:';
|
||||
$string['privacy:metadata'] = 'The Activites results block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_admin_bookmarks.
|
||||
*
|
||||
* @package block_admin_bookmarks
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_admin_bookmarks\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_admin_bookmarks implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -25,3 +25,4 @@
|
||||
$string['admin_bookmarks:addinstance'] = 'Add a new admin bookmarks block';
|
||||
$string['admin_bookmarks:myaddinstance'] = 'Add a new admin bookmarks block to Dashboard';
|
||||
$string['pluginname'] = 'Admin bookmarks';
|
||||
$string['privacy:metadata'] = 'The Admin bookmarks block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_badges.
|
||||
*
|
||||
* @package block_badges
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_badges\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_badges implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -28,3 +28,4 @@ $string['numbadgestodisplay'] = 'Number of latest badges to display';
|
||||
$string['nothingtodisplay'] = 'You have no badges to display';
|
||||
$string['badges:addinstance'] = 'Add a new My latest badges block';
|
||||
$string['badges:myaddinstance'] = 'Add a new My latest badges block to Dashboard';
|
||||
$string['privacy:metadata'] = 'The Badges block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_blog_menu.
|
||||
*
|
||||
* @package block_blog_menu
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_blog_menu\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_blog_menu implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -25,3 +25,4 @@
|
||||
|
||||
$string['blog_menu:addinstance'] = 'Add a new blog menu block';
|
||||
$string['pluginname'] = 'Blog menu';
|
||||
$string['privacy:metadata'] = 'The Blog menu block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_blog_recent.
|
||||
*
|
||||
* @package block_blog_recent
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_blog_recent\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_blog_recent implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -28,3 +28,4 @@ $string['norecentblogentries'] = 'No recent entries';
|
||||
$string['numentriestodisplay'] = 'Number of recent entries to display';
|
||||
$string['pluginname'] = 'Recent blog entries';
|
||||
$string['recentinterval'] = 'Interval of time considered "recent"';
|
||||
$string['privacy:metadata'] = 'The Recent blog entries block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_blog_tags.
|
||||
*
|
||||
* @package block_blog_tags
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_blog_tags\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_blog_tags implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -24,3 +24,4 @@
|
||||
|
||||
$string['blog_tags:addinstance'] = 'Add a new blog tags block';
|
||||
$string['pluginname'] = 'Blog tags';
|
||||
$string['privacy:metadata'] = 'The Blog tags block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_calendar_month.
|
||||
*
|
||||
* @package block_calendar_month
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_calendar_month\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_calendar_month implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -25,3 +25,4 @@
|
||||
$string['calendar_month:addinstance'] = 'Add a new calendar block';
|
||||
$string['calendar_month:myaddinstance'] = 'Add a new calendar block to Dashboard';
|
||||
$string['pluginname'] = 'Calendar';
|
||||
$string['privacy:metadata'] = 'The Calendar block only displays existing calendar data.';
|
||||
|
||||
@@ -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 block_calendar_upcoming.
|
||||
*
|
||||
* @package block_calendar_upcoming
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_calendar_upcoming\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_calendar_upcoming implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -25,3 +25,4 @@
|
||||
$string['calendar_upcoming:addinstance'] = 'Add a new upcoming events block';
|
||||
$string['calendar_upcoming:myaddinstance'] = 'Add a new upcoming events block to Dashboard';
|
||||
$string['pluginname'] = 'Upcoming events';
|
||||
$string['privacy:metadata'] = 'The Upcoming calendar events block only displays existing calendar data.';
|
||||
|
||||
@@ -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 block_completionstatus.
|
||||
*
|
||||
* @package block_completionstatus
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_completionstatus\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_completionstatus implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -29,3 +29,4 @@ $string['firstofsecond'] = '{$a->first} of {$a->second}';
|
||||
$string['pluginname'] = 'Course completion status';
|
||||
$string['requirement'] = 'Requirement';
|
||||
$string['returntocourse'] = 'Return to course';
|
||||
$string['privacy:metadata'] = 'The Course completion status block only shows information about course completion and does not store any data of its own.';
|
||||
|
||||
@@ -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 block_course_list.
|
||||
*
|
||||
* @package block_course_list
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_course_list\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_course_list implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -31,3 +31,4 @@ $string['course_list:myaddinstance'] = 'Add a new courses block to Dashboard';
|
||||
$string['hideallcourseslink'] = 'Hide \'All courses\' link';
|
||||
$string['owncourses'] = 'Admin user sees own courses';
|
||||
$string['pluginname'] = 'Courses';
|
||||
$string['privacy:metadata'] = 'The Courses block only shows data about courses and does not store any data itself.';
|
||||
|
||||
@@ -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 block_course_summary.
|
||||
*
|
||||
* @package block_course_summary
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_course_summary\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_course_summary implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -26,3 +26,4 @@
|
||||
$string['coursesummary'] = 'Course summary';
|
||||
$string['course_summary:addinstance'] = 'Add a new course/site summary block';
|
||||
$string['pluginname'] = 'Course/site summary';
|
||||
$string['privacy:metadata'] = 'The Course and site summaryblock only shows information about courses and does not store data itself.';
|
||||
|
||||
@@ -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 block_feedback.
|
||||
*
|
||||
* @package block_feedback
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_feedback\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_feedback implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -25,3 +25,4 @@
|
||||
$string['feedback'] = 'Feedback';
|
||||
$string['feedback:addinstance'] = 'Add a new feedback block';
|
||||
$string['pluginname'] = 'Feedback';
|
||||
$string['privacy:metadata'] = 'The Feedback block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_globalsearch.
|
||||
*
|
||||
* @package block_globalsearch
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_globalsearch\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_globalsearch implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -25,3 +25,4 @@
|
||||
$string['globalsearch:addinstance'] = 'Add a new global search block';
|
||||
$string['globalsearch:myaddinstance'] = 'Add a new global search block to Dashboard';
|
||||
$string['pluginname'] = 'Global search';
|
||||
$string['privacy:metadata'] = 'The Global search block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_glossary_random.
|
||||
*
|
||||
* @package block_glossary_random
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_glossary_random\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_glossary_random implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -45,3 +45,4 @@ $string['title'] = 'Title';
|
||||
$string['type'] = 'How a new entry is chosen';
|
||||
$string['viewglossary'] = 'View all entries';
|
||||
$string['whichfooter'] = 'You can display links to actions of the glossary this block is associated with. The block will only display links to actions which are enabled for that glossary.';
|
||||
$string['privacy:metadata'] = 'The Random glossary entry block only shows data stored in other locations.';
|
||||
|
||||
@@ -30,9 +30,13 @@ defined('MOODLE_INTERNAL') || die();
|
||||
class moodle1_block_html_handler extends moodle1_block_handler {
|
||||
private $fileman = null;
|
||||
protected function convert_configdata(array $olddata) {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/db/upgradelib.php');
|
||||
$instanceid = $olddata['id'];
|
||||
$contextid = $this->converter->get_contextid(CONTEXT_BLOCK, $olddata['id']);
|
||||
$configdata = unserialize(base64_decode($olddata['configdata']));
|
||||
$decodeddata = base64_decode($olddata['configdata']);
|
||||
list($updated, $configdata) = upgrade_fix_serialized_objects($decodeddata);
|
||||
$configdata = unserialize($configdata);
|
||||
|
||||
// get a fresh new file manager for this instance
|
||||
$this->fileman = $this->converter->get_file_manager($contextid, 'block_html');
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
<?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 block_html.
|
||||
*
|
||||
* @package block_html
|
||||
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_html\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use \core_privacy\local\request\approved_contextlist;
|
||||
use \core_privacy\local\request\writer;
|
||||
use \core_privacy\local\request\helper;
|
||||
use \core_privacy\local\request\deletion_criteria;
|
||||
use \core_privacy\local\metadata\collection;
|
||||
|
||||
/**
|
||||
* Privacy Subsystem implementation for block_html.
|
||||
*
|
||||
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements
|
||||
// The block_html block stores user provided data.
|
||||
\core_privacy\local\metadata\provider,
|
||||
|
||||
// The block_html block provides data directly to core.
|
||||
\core_privacy\local\request\plugin\provider {
|
||||
|
||||
/**
|
||||
* Returns information about how block_html stores its data.
|
||||
*
|
||||
* @param collection $collection The initialised collection to add items to.
|
||||
* @return collection A listing of user data stored through this system.
|
||||
*/
|
||||
public static function get_metadata(collection $collection) {
|
||||
$collection->link_subsystem('block', 'privacy:metadata:block');
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of contexts that contain user information for the specified user.
|
||||
*
|
||||
* @param int $userid The user to search.
|
||||
* @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
|
||||
*/
|
||||
public static function get_contexts_for_userid($userid) {
|
||||
// This block doesn't know who information is stored against unless it
|
||||
// is at the user context.
|
||||
$contextlist = new \core_privacy\local\request\contextlist();
|
||||
|
||||
$sql = "SELECT c.id
|
||||
FROM {block_instances} b
|
||||
INNER JOIN {context} c ON c.instanceid = b.id AND c.contextlevel = :contextblock
|
||||
INNER JOIN {context} bpc ON bpc.id = b.parentcontextid
|
||||
WHERE b.blockname = 'html'
|
||||
AND bpc.contextlevel = :contextuser
|
||||
AND bpc.instanceid = :userid";
|
||||
|
||||
$params = [
|
||||
'contextblock' => CONTEXT_BLOCK,
|
||||
'contextuser' => CONTEXT_USER,
|
||||
'userid' => $userid,
|
||||
];
|
||||
|
||||
$contextlist->add_from_sql($sql, $params);
|
||||
|
||||
return $contextlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all user data for the specified user, in the specified contexts.
|
||||
*
|
||||
* @param approved_contextlist $contextlist The approved contexts to export information for.
|
||||
*/
|
||||
public static function export_user_data(approved_contextlist $contextlist) {
|
||||
global $DB;
|
||||
|
||||
$user = $contextlist->get_user();
|
||||
|
||||
list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
|
||||
|
||||
$sql = "SELECT
|
||||
c.id AS contextid,
|
||||
bi.*
|
||||
FROM {context} c
|
||||
INNER JOIN {block_instances} bi ON bi.id = c.instanceid AND c.contextlevel = :contextlevel
|
||||
WHERE bi.blockname = 'html'
|
||||
AND(
|
||||
c.id {$contextsql}
|
||||
)
|
||||
";
|
||||
|
||||
$params = [
|
||||
'contextlevel' => CONTEXT_BLOCK,
|
||||
];
|
||||
$params += $contextparams;
|
||||
|
||||
$instances = $DB->get_recordset_sql($sql, $params);
|
||||
foreach ($instances as $instance) {
|
||||
$context = \context_block::instance($instance->id);
|
||||
$block = block_instance('html', $instance);
|
||||
if (empty($block->config)) {
|
||||
// Skip this block. It has not been configured.
|
||||
continue;
|
||||
}
|
||||
|
||||
$html = writer::with_context($context)
|
||||
->rewrite_pluginfile_urls([], 'block_html', 'content', null, $block->config->text);
|
||||
|
||||
// Default to FORMAT_HTML which is what will have been used before the
|
||||
// editor was properly implemented for the block.
|
||||
$format = isset($block->config->format) ? $block->config->format : FORMAT_HTML;
|
||||
|
||||
$filteropt = (object) [
|
||||
'overflowdiv' => true,
|
||||
'noclean' => true,
|
||||
];
|
||||
$html = format_text($html, $format, $filteropt);
|
||||
|
||||
$data = helper::get_context_data($context, $user);
|
||||
helper::export_context_files($context, $user);
|
||||
$data->title = $block->config->title;
|
||||
$data->content = $html;
|
||||
|
||||
writer::with_context($context)->export_data([], $data);
|
||||
}
|
||||
$instances->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all data for all users in the specified context.
|
||||
*
|
||||
* @param context $context The specific context to delete data for.
|
||||
*/
|
||||
public static function delete_data_for_all_users_in_context(\context $context) {
|
||||
// The only way to delete data for the html block is to delete the block instance itself.
|
||||
blocks_delete_instance(static::get_instance_from_context($context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all user data for the specified user, in the specified contexts.
|
||||
*
|
||||
* @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
|
||||
*/
|
||||
public static function delete_data_for_user(approved_contextlist $contextlist) {
|
||||
// The only way to delete data for the html block is to delete the block instance itself.
|
||||
foreach ($contextlist as $context) {
|
||||
blocks_delete_instance(static::get_instance_from_context($context));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block instance record for the specified context.
|
||||
*
|
||||
* @param \context_block $context The context to fetch
|
||||
* @return \stdClass
|
||||
*/
|
||||
protected static function get_instance_from_context(\context_block $context) {
|
||||
global $DB;
|
||||
|
||||
return $DB->get_record('block_instances', ['id' => $context->instanceid]);
|
||||
}
|
||||
}
|
||||
@@ -33,3 +33,4 @@ $string['html:myaddinstance'] = 'Add a new HTML block to Dashboard';
|
||||
$string['leaveblanktohide'] = 'leave blank to hide the title';
|
||||
$string['newhtmlblock'] = '(new HTML block)';
|
||||
$string['pluginname'] = 'HTML';
|
||||
$string['privacy:metadata:block'] = 'The HTML block stores all of its data within the block subsystem.';
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for the block_html implementation of the privacy API.
|
||||
*
|
||||
* @package block_html
|
||||
* @category test
|
||||
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use \core_privacy\local\request\writer;
|
||||
use \core_privacy\local\request\approved_contextlist;
|
||||
use \block_html\privacy\provider;
|
||||
|
||||
/**
|
||||
* Unit tests for the block_html implementation of the privacy API.
|
||||
*
|
||||
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class block_html_privacy_testcase extends \core_privacy\tests\provider_testcase {
|
||||
/**
|
||||
* Get the list of standard format options for comparison.
|
||||
*
|
||||
* @return \stdClass
|
||||
*/
|
||||
protected function get_format_options() {
|
||||
return (object) [
|
||||
'overflowdiv' => true,
|
||||
'noclean' => true,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML block on a user.
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $body
|
||||
* @param string $format
|
||||
* @return \block_instance
|
||||
*/
|
||||
protected function create_user_block($title, $body, $format) {
|
||||
global $USER;
|
||||
|
||||
$configdata = (object) [
|
||||
'title' => $title,
|
||||
'text' => [
|
||||
'itemid' => 19,
|
||||
'text' => $body,
|
||||
'format' => $format,
|
||||
],
|
||||
];
|
||||
|
||||
$this->create_block($this->construct_user_page($USER));
|
||||
$block = $this->get_last_block_on_page($this->construct_user_page($USER));
|
||||
$block = block_instance('html', $block->instance);
|
||||
$block->instance_config_save((object) $configdata);
|
||||
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML block on a course.
|
||||
*
|
||||
* @param \stdClass $course
|
||||
* @param string $title
|
||||
* @param string $body
|
||||
* @param string $format
|
||||
* @return \block_instance
|
||||
*/
|
||||
protected function create_course_block($course, $title, $body, $format) {
|
||||
global $USER;
|
||||
|
||||
$configdata = (object) [
|
||||
'title' => $title,
|
||||
'text' => [
|
||||
'itemid' => 19,
|
||||
'text' => $body,
|
||||
'format' => $format,
|
||||
],
|
||||
];
|
||||
|
||||
$this->create_block($this->construct_course_page($course));
|
||||
$block = $this->get_last_block_on_page($this->construct_course_page($course));
|
||||
$block = block_instance('html', $block->instance);
|
||||
$block->instance_config_save((object) $configdata);
|
||||
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML block on a page.
|
||||
*
|
||||
* @param \page $page Page
|
||||
*/
|
||||
protected function create_block($page) {
|
||||
$page->blocks->add_block_at_end_of_default_region('html');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last block on the page.
|
||||
*
|
||||
* @param \page $page Page
|
||||
* @return \block_html Block instance object
|
||||
*/
|
||||
protected function get_last_block_on_page($page) {
|
||||
$blocks = $page->blocks->get_blocks_for_region($page->blocks->get_default_region());
|
||||
$block = end($blocks);
|
||||
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Page object for the User Dashboard.
|
||||
*
|
||||
* @param \stdClass $user User to create Dashboard for.
|
||||
* @return \moodle_page
|
||||
*/
|
||||
protected function construct_user_page(\stdClass $user) {
|
||||
$page = new \moodle_page();
|
||||
$page->set_context(\context_user::instance($user->id));
|
||||
$page->set_pagelayout('mydashboard');
|
||||
$page->set_pagetype('my-index');
|
||||
$page->blocks->load_blocks();
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Page object for the User Dashboard.
|
||||
*
|
||||
* @param \stdClass $course Course to create Dashboard for.
|
||||
* @return \moodle_page
|
||||
*/
|
||||
protected function construct_course_page(\stdClass $course) {
|
||||
$page = new \moodle_page();
|
||||
$page->set_context(\context_course::instance($course->id));
|
||||
$page->set_pagelayout('standard');
|
||||
$page->set_pagetype('course-view');
|
||||
$page->set_course($course);
|
||||
$page->blocks->load_blocks();
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a block on the dashboard is exported.
|
||||
*/
|
||||
public function test_user_block() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$title = 'Example title';
|
||||
$content = 'Example content';
|
||||
$format = FORMAT_PLAIN;
|
||||
|
||||
// Test setup.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
$block = $this->create_user_block($title, $content, $format);
|
||||
$context = \context_block::instance($block->instance->id);
|
||||
|
||||
// Get the contexts.
|
||||
$contextlist = provider::get_contexts_for_userid($user->id);
|
||||
|
||||
// Only the user context should be returned.
|
||||
$this->assertCount(1, $contextlist);
|
||||
$this->assertEquals($context, $contextlist->current());
|
||||
|
||||
// Export the data.
|
||||
$this->export_context_data_for_user($user->id, $context, 'block_html');
|
||||
$writer = \core_privacy\local\request\writer::with_context($context);
|
||||
$this->assertTrue($writer->has_any_data());
|
||||
|
||||
// Check the data.
|
||||
$data = $writer->get_data([]);
|
||||
$this->assertInstanceOf('stdClass', $data);
|
||||
$this->assertEquals($title, $data->title);
|
||||
$this->assertEquals(format_text($content, $format, $this->get_format_options()), $data->content);
|
||||
|
||||
// Delete the context.
|
||||
provider::delete_data_for_all_users_in_context($context);
|
||||
|
||||
// Re-fetch the contexts - it should no longer be returned.
|
||||
$contextlist = provider::get_contexts_for_userid($user->id);
|
||||
$this->assertCount(0, $contextlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a block on the dashboard which is not configured is _not_ exported.
|
||||
*/
|
||||
public function test_user_block_unconfigured() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$title = 'Example title';
|
||||
$content = 'Example content';
|
||||
$format = FORMAT_PLAIN;
|
||||
|
||||
// Test setup.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
$block = $this->create_user_block($title, $content, $format);
|
||||
$block->instance->configdata = '';
|
||||
$DB->update_record('block_instances', $block->instance);
|
||||
$block = block_instance('html', $block->instance);
|
||||
|
||||
$context = \context_block::instance($block->instance->id);
|
||||
|
||||
// Get the contexts.
|
||||
$contextlist = provider::get_contexts_for_userid($user->id);
|
||||
|
||||
// Only the user context should be returned.
|
||||
$this->assertCount(1, $contextlist);
|
||||
$this->assertEquals($context, $contextlist->current());
|
||||
|
||||
// Export the data.
|
||||
$this->export_context_data_for_user($user->id, $context, 'block_html');
|
||||
$writer = \core_privacy\local\request\writer::with_context($context);
|
||||
$this->assertFalse($writer->has_any_data());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a block on the dashboard is exported.
|
||||
*/
|
||||
public function test_user_multiple_blocks_exported() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$title = 'Example title';
|
||||
$content = 'Example content';
|
||||
$format = FORMAT_PLAIN;
|
||||
|
||||
// Test setup.
|
||||
$blocks = [];
|
||||
$contexts = [];
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
$block = $this->create_user_block($title, $content, $format);
|
||||
$context = \context_block::instance($block->instance->id);
|
||||
$contexts[$context->id] = $context;
|
||||
|
||||
$block = $this->create_user_block($title, $content, $format);
|
||||
$context = \context_block::instance($block->instance->id);
|
||||
$contexts[$context->id] = $context;
|
||||
|
||||
// Get the contexts.
|
||||
$contextlist = provider::get_contexts_for_userid($user->id);
|
||||
|
||||
// There are now two blocks on the user context.
|
||||
$this->assertCount(2, $contextlist);
|
||||
foreach ($contextlist as $context) {
|
||||
$this->assertTrue(isset($contexts[$context->id]));
|
||||
}
|
||||
|
||||
// Turn them into an approved_contextlist.
|
||||
$approvedlist = new approved_contextlist($user, 'block_html', $contextlist->get_contextids());
|
||||
|
||||
// Delete using delete_data_for_user.
|
||||
provider::delete_data_for_user($approvedlist);
|
||||
|
||||
// Re-fetch the contexts - it should no longer be returned.
|
||||
$contextlist = provider::get_contexts_for_userid($user->id);
|
||||
$this->assertCount(0, $contextlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a block on the dashboard is not exported.
|
||||
*/
|
||||
public function test_course_blocks_not_exported() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$title = 'Example title';
|
||||
$content = 'Example content';
|
||||
$format = FORMAT_PLAIN;
|
||||
|
||||
// Test setup.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$this->setUser($user);
|
||||
|
||||
$block = $this->create_course_block($course, $title, $content, $format);
|
||||
$context = \context_block::instance($block->instance->id);
|
||||
|
||||
// Get the contexts.
|
||||
$contextlist = provider::get_contexts_for_userid($user->id);
|
||||
|
||||
// No blocks should be returned.
|
||||
$this->assertCount(0, $contextlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a block on the dashboard is exported.
|
||||
*/
|
||||
public function test_mixed_multiple_blocks_exported() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$title = 'Example title';
|
||||
$content = 'Example content';
|
||||
$format = FORMAT_PLAIN;
|
||||
|
||||
// Test setup.
|
||||
$contexts = [];
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$this->setUser($user);
|
||||
|
||||
$block = $this->create_course_block($course, $title, $content, $format);
|
||||
$context = \context_block::instance($block->instance->id);
|
||||
|
||||
$block = $this->create_user_block($title, $content, $format);
|
||||
$context = \context_block::instance($block->instance->id);
|
||||
$contexts[$context->id] = $context;
|
||||
|
||||
$block = $this->create_user_block($title, $content, $format);
|
||||
$context = \context_block::instance($block->instance->id);
|
||||
$contexts[$context->id] = $context;
|
||||
|
||||
// Get the contexts.
|
||||
$contextlist = provider::get_contexts_for_userid($user->id);
|
||||
|
||||
// There are now two blocks on the user context.
|
||||
$this->assertCount(2, $contextlist);
|
||||
foreach ($contextlist as $context) {
|
||||
$this->assertTrue(isset($contexts[$context->id]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 block_login.
|
||||
*
|
||||
* @package block_login
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_login\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_login implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -24,3 +24,4 @@
|
||||
|
||||
$string['login:addinstance'] = 'Add a new login block';
|
||||
$string['pluginname'] = 'Login';
|
||||
$string['privacy:metadata'] = 'The Login block only provides a way to login and does not store any data itself.';
|
||||
|
||||
@@ -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 block_lp.
|
||||
*
|
||||
* @package block_lp
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_lp\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_lp implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -34,3 +34,4 @@ $string['planstoreview'] = 'Plans to review';
|
||||
$string['pluginname'] = 'Learning plans';
|
||||
$string['viewmore'] = 'View more...';
|
||||
$string['viewotherplans'] = 'View other plans...';
|
||||
$string['privacy:metadata'] = 'The Learning plans block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_mentees.
|
||||
*
|
||||
* @package block_mentees
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_mentees\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_mentees implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -30,3 +30,4 @@ $string['mentees:addinstance'] = 'Add a new mentees block';
|
||||
$string['mentees:myaddinstance'] = 'Add a new mentees block to Dashboard';
|
||||
$string['newmenteesblock'] = '(new Mentees block)';
|
||||
$string['pluginname'] = 'Mentees';
|
||||
$string['privacy:metadata'] = 'The Mentees block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_messages.
|
||||
*
|
||||
* @package block_messages
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_messages\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_messages implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -25,3 +25,4 @@
|
||||
$string['messages:addinstance'] = 'Add a new messages block';
|
||||
$string['messages:myaddinstance'] = 'Add a new messages block to Dashboard';
|
||||
$string['pluginname'] = 'Messages';
|
||||
$string['privacy:metadata'] = 'The Messages block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_mnet_hosts.
|
||||
*
|
||||
* @package block_mnet_hosts
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_mnet_hosts\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_mnet_hosts implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -29,3 +29,4 @@ $string['mnet_hosts:addinstance'] = 'Add a new network servers block';
|
||||
$string['mnet_hosts:myaddinstance'] = 'Add a new network servers block to Dashboard';
|
||||
$string['pluginname'] = 'Network servers';
|
||||
$string['server'] = 'Server';
|
||||
$string['privacy:metadata'] = 'The Network servers block only allows interaction with Network servers and neither stores or exports data itself.';
|
||||
|
||||
@@ -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 block_myoverview.
|
||||
*
|
||||
* @package block_myoverview
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_myoverview\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_myoverview implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -44,3 +44,4 @@ $string['sortbydates'] = 'Sort by dates';
|
||||
$string['timeline'] = 'Timeline';
|
||||
$string['viewcourse'] = 'View course';
|
||||
$string['viewcoursename'] = 'View course {$a}';
|
||||
$string['privacy:metadata'] = 'The Course overview block only shows data stored in other locations.';
|
||||
|
||||
@@ -18,9 +18,9 @@ Feature: The my overview block allows users to easily access their courses and s
|
||||
| activity | course | idnumber | name | intro | timeopen | timeclose |
|
||||
| choice | C2 | choice1 | Test choice 1 | Test choice description | ##yesterday## | ##tomorrow## |
|
||||
| choice | C1 | choice2 | Test choice 2 | Test choice description | ##1 month ago## | ##15 days ago## |
|
||||
| choice | C3 | choice3 | Test choice 3 | Test choice description | ##first day of next month## | ##last day of next month## |
|
||||
| choice | C3 | choice3 | Test choice 3 | Test choice description | ##first day of +5 months## | ##last day of +5 months## |
|
||||
| feedback | C2 | feedback1 | Test feedback 1 | Test feedback description | ##yesterday## | ##tomorrow## |
|
||||
| feedback | C3 | feedback3 | Test feedback 3 | Test feedback description | ##first day of next month## | ##last day of next month## |
|
||||
| feedback | C3 | feedback3 | Test feedback 3 | Test feedback description | ##first day of +5 months## | ##last day of +5 months## |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | C1 | student |
|
||||
|
||||
@@ -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 block_myprofile.
|
||||
*
|
||||
* @package block_myprofile
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_myprofile\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_myprofile implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,7 @@ $string['myprofile:addinstance'] = 'Add a new logged in user block';
|
||||
$string['myprofile:myaddinstance'] = 'Add a new logged in user block to Dashboard';
|
||||
$string['myprofile_settings'] = 'Visible user information';
|
||||
$string['pluginname'] = 'Logged in user';
|
||||
$string['privacy:metadata'] = 'The Logged in users block only shows information about logged in users and does not store data itself.';
|
||||
|
||||
// Deprecated since Moodle 3.2.
|
||||
$string['display_un'] = 'Display name';
|
||||
|
||||
@@ -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 block_navigation.
|
||||
*
|
||||
* @package block_navigation
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_navigation\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_navigation implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -39,3 +39,4 @@ $string['trimmoderight'] = 'Trim characters from the right';
|
||||
$string['trimmodeleft'] = 'Trim characters from the left';
|
||||
$string['trimmodecenter'] = 'Trim characters from the center';
|
||||
$string['trimlength'] = 'How many characters to trim to';
|
||||
$string['privacy:metadata'] = 'The Navigation block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_news_items.
|
||||
*
|
||||
* @package block_news_items
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_news_items\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_news_items implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -25,3 +25,4 @@
|
||||
$string['news_items:addinstance'] = 'Add a new latest announcements block';
|
||||
$string['news_items:myaddinstance'] = 'Add a new latest announcements block to Dashboard';
|
||||
$string['pluginname'] = 'Latest announcements';
|
||||
$string['privacy:metadata'] = 'The Latest announcements block only shows data stored in the forum and does not store data itself.';
|
||||
|
||||
@@ -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 block_online_users.
|
||||
*
|
||||
* @package block_online_users
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_online_users\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_online_users implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -30,3 +30,4 @@ $string['online_users:viewlist'] = 'View list of online users';
|
||||
$string['periodnminutes'] = 'last {$a} minutes';
|
||||
$string['pluginname'] = 'Online users';
|
||||
$string['timetosee'] = 'Remove after inactivity (minutes)';
|
||||
$string['privacy:metadata'] = 'The Online users block only shows data stored in other locations.';
|
||||
|
||||
@@ -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 block_participants.
|
||||
*
|
||||
* @package block_participants
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace block_participants\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_participants implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@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() {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -24,3 +24,4 @@
|
||||
|
||||
$string['participants:addinstance'] = 'Add a new people block';
|
||||
$string['pluginname'] = 'People';
|
||||
$string['privacy:metadata'] = 'The People block only shows data stored in other locations.';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user