Merge branch 'MDL-74643-master' of https://github.com/mickhawkins/moodle

This commit is contained in:
Ilya Tregubov 2022-10-31 14:52:47 +03:00
commit 9a723c0e15
13 changed files with 221 additions and 8 deletions

View file

@ -61,6 +61,16 @@ if ($hassiteconfig) {
$temp->add($setting); $temp->add($setting);
$temp->add(new admin_setting_configtext('supportpage', new lang_string('supportpage', 'admin'), $temp->add(new admin_setting_configtext('supportpage', new lang_string('supportpage', 'admin'),
new lang_string('configsupportpage', 'admin'), '', PARAM_URL)); new lang_string('configsupportpage', 'admin'), '', PARAM_URL));
$temp->add(new admin_setting_configselect('supportavailability', new lang_string('supportavailability', 'admin'),
new lang_string('configsupportavailability', 'admin'), CONTACT_SUPPORT_AUTHENTICATED,
[
CONTACT_SUPPORT_ANYONE => new lang_string('availabletoanyone', 'admin'),
CONTACT_SUPPORT_AUTHENTICATED => new lang_string('availabletoauthenticated', 'admin'),
CONTACT_SUPPORT_DISABLED => new lang_string('disabled', 'admin'),
]
));
$ADMIN->add('server', $temp); $ADMIN->add('server', $temp);
// Session handling. // Session handling.

View file

@ -167,6 +167,9 @@ class api {
// We need this to make work the format text functions. // We need this to make work the format text functions.
$PAGE->set_context($context); $PAGE->set_context($context);
// Check if contacting site support is available to all visitors.
$sitesupportavailable = (isset($CFG->supportavailability) && $CFG->supportavailability == CONTACT_SUPPORT_ANYONE);
list($authinstructions, $notusedformat) = external_format_text($CFG->auth_instructions, FORMAT_MOODLE, $context->id); list($authinstructions, $notusedformat) = external_format_text($CFG->auth_instructions, FORMAT_MOODLE, $context->id);
list($maintenancemessage, $notusedformat) = external_format_text($CFG->maintenance_message, FORMAT_MOODLE, $context->id); list($maintenancemessage, $notusedformat) = external_format_text($CFG->maintenance_message, FORMAT_MOODLE, $context->id);
$settings = array( $settings = array(
@ -198,7 +201,8 @@ class api {
'tool_mobile_androidappid' => get_config('tool_mobile', 'androidappid'), 'tool_mobile_androidappid' => get_config('tool_mobile', 'androidappid'),
'tool_mobile_setuplink' => clean_param(get_config('tool_mobile', 'setuplink'), PARAM_URL), 'tool_mobile_setuplink' => clean_param(get_config('tool_mobile', 'setuplink'), PARAM_URL),
'tool_mobile_qrcodetype' => clean_param(get_config('tool_mobile', 'qrcodetype'), PARAM_INT), 'tool_mobile_qrcodetype' => clean_param(get_config('tool_mobile', 'qrcodetype'), PARAM_INT),
'supportpage' => clean_param($CFG->supportpage, PARAM_URL), 'supportpage' => $sitesupportavailable ? clean_param($CFG->supportpage, PARAM_URL) : '',
'supportavailability' => clean_param($CFG->supportavailability, PARAM_INT),
); );
$typeoflogin = get_config('tool_mobile', 'typeoflogin'); $typeoflogin = get_config('tool_mobile', 'typeoflogin');
@ -236,8 +240,8 @@ class api {
} }
} }
// If age is verified, return also the admin contact details. // If age is verified or support is available to all visitors, also return the admin contact details.
if ($settings['agedigitalconsentverification']) { if ($settings['agedigitalconsentverification'] || $sitesupportavailable) {
$settings['supportname'] = clean_param($CFG->supportname, PARAM_NOTAGS); $settings['supportname'] = clean_param($CFG->supportname, PARAM_NOTAGS);
$settings['supportemail'] = clean_param($CFG->supportemail, PARAM_EMAIL); $settings['supportemail'] = clean_param($CFG->supportemail, PARAM_EMAIL);
} }
@ -330,10 +334,18 @@ class api {
} }
if (empty($section) or $section == 'supportcontact') { if (empty($section) or $section == 'supportcontact') {
$settings->supportavailability = $CFG->supportavailability;
if ($CFG->supportavailability == CONTACT_SUPPORT_DISABLED) {
$settings->supportname = null;
$settings->supportemail = null;
$settings->supportpage = null;
} else {
$settings->supportname = $CFG->supportname; $settings->supportname = $CFG->supportname;
$settings->supportemail = $CFG->supportemail ?? null; $settings->supportemail = $CFG->supportemail ?? null;
$settings->supportpage = $CFG->supportpage; $settings->supportpage = $CFG->supportpage;
} }
}
if (empty($section) || $section === 'graceperiodsettings') { if (empty($section) || $section === 'graceperiodsettings') {
$settings->coursegraceperiodafter = $CFG->coursegraceperiodafter; $settings->coursegraceperiodafter = $CFG->coursegraceperiodafter;

View file

@ -175,6 +175,8 @@ class external extends external_api {
'supportemail' => new external_value(PARAM_EMAIL, 'Site support contact email 'supportemail' => new external_value(PARAM_EMAIL, 'Site support contact email
(only if age verification is enabled).', VALUE_OPTIONAL), (only if age verification is enabled).', VALUE_OPTIONAL),
'supportpage' => new external_value(PARAM_URL, 'Site support page link.', VALUE_OPTIONAL), 'supportpage' => new external_value(PARAM_URL, 'Site support page link.', VALUE_OPTIONAL),
'supportavailability' => new external_value(PARAM_INT, 'Determines who has access to contact site support.',
VALUE_OPTIONAL),
'autolang' => new external_value(PARAM_INT, 'Whether to detect default language 'autolang' => new external_value(PARAM_INT, 'Whether to detect default language
from browser setting.', VALUE_OPTIONAL), from browser setting.', VALUE_OPTIONAL),
'lang' => new external_value(PARAM_LANG, 'Default language for the site.', VALUE_OPTIONAL), 'lang' => new external_value(PARAM_LANG, 'Default language for the site.', VALUE_OPTIONAL),

View file

@ -92,6 +92,7 @@ class externallib_test extends externallib_advanced_testcase {
'tool_mobile_setuplink' => get_config('tool_mobile', 'setuplink'), 'tool_mobile_setuplink' => get_config('tool_mobile', 'setuplink'),
'tool_mobile_qrcodetype' => get_config('tool_mobile', 'qrcodetype'), 'tool_mobile_qrcodetype' => get_config('tool_mobile', 'qrcodetype'),
'supportpage' => $CFG->supportpage, 'supportpage' => $CFG->supportpage,
'supportavailability' => $CFG->supportavailability,
'warnings' => array() 'warnings' => array()
); );
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
@ -111,6 +112,7 @@ class externallib_test extends externallib_advanced_testcase {
set_config('disabledfeatures', 'myoverview', 'tool_mobile'); set_config('disabledfeatures', 'myoverview', 'tool_mobile');
set_config('minimumversion', '3.8.0', 'tool_mobile'); set_config('minimumversion', '3.8.0', 'tool_mobile');
set_config('supportemail', 'test@test.com'); set_config('supportemail', 'test@test.com');
set_config('supportavailability', CONTACT_SUPPORT_ANYONE);
// Enable couple of issuers. // Enable couple of issuers.
$issuer = \core\oauth2\api::create_standard_issuer('google'); $issuer = \core\oauth2\api::create_standard_issuer('google');
@ -132,6 +134,7 @@ class externallib_test extends externallib_advanced_testcase {
$expected['agedigitalconsentverification'] = true; $expected['agedigitalconsentverification'] = true;
$expected['supportname'] = $CFG->supportname; $expected['supportname'] = $CFG->supportname;
$expected['supportemail'] = $CFG->supportemail; $expected['supportemail'] = $CFG->supportemail;
$expected['supportavailability'] = $CFG->supportavailability;
$expected['autolang'] = '1'; $expected['autolang'] = '1';
$expected['lang'] = ''; // Expect empty because it was set to an invalid lang. $expected['lang'] = ''; // Expect empty because it was set to an invalid lang.
$expected['tool_mobile_disabledfeatures'] = 'myoverview'; $expected['tool_mobile_disabledfeatures'] = 'myoverview';
@ -226,6 +229,7 @@ class externallib_test extends externallib_advanced_testcase {
'value' => get_config('core_admin', 'coursecolor' . $number) 'value' => get_config('core_admin', 'coursecolor' . $number)
]; ];
} }
$expected[] = ['name' => 'supportavailability', 'value' => $CFG->supportavailability];
$expected[] = ['name' => 'supportname', 'value' => $CFG->supportname]; $expected[] = ['name' => 'supportname', 'value' => $CFG->supportname];
$expected[] = ['name' => 'supportemail', 'value' => $CFG->supportemail]; $expected[] = ['name' => 'supportemail', 'value' => $CFG->supportemail];
$expected[] = ['name' => 'supportpage', 'value' => $CFG->supportpage]; $expected[] = ['name' => 'supportpage', 'value' => $CFG->supportpage];

View file

@ -1,5 +1,12 @@
This files describes API changes in /admin/*. This files describes API changes in /admin/*.
=== 4.1 ===
* A new admin setting supportavailability allows admins to configure who the "contact site support" feature is available to
(everyone, authenticated users, or nobody).
-For new sites and those upgrading from 3.11.x or older, the default will be "Limited to authenticated users".
-For sites upgrading from 4.0.x, the default will be "available to anyone visiting the site", to main consistent behaviour through the upgrade.
=== 4.0.1 === === 4.0.1 ===
* A new callback xxx_pre_enable_plugin_actions has been added in admin/modules.php. Plugins can use this callback to * A new callback xxx_pre_enable_plugin_actions has been added in admin/modules.php. Plugins can use this callback to

View file

@ -82,6 +82,8 @@ $string['autolangusercreation'] = 'On account creation set user\'s browser langu
$string['autologinguests'] = 'Auto-login guests'; $string['autologinguests'] = 'Auto-login guests';
$string['searchareas'] = 'Search areas'; $string['searchareas'] = 'Search areas';
$string['availableto'] = 'Available to'; $string['availableto'] = 'Available to';
$string['availabletoanyone'] = 'Available to anyone visiting the site';
$string['availabletoauthenticated'] = 'Limited to authenticated users';
$string['backgroundcolour'] = 'Transparent colour'; $string['backgroundcolour'] = 'Transparent colour';
$string['backups'] = 'Backups'; $string['backups'] = 'Backups';
$string['backup_shortname'] = 'Use course name in backup filename'; $string['backup_shortname'] = 'Use course name in backup filename';
@ -378,6 +380,7 @@ $string['configstatsruntimestart'] = 'What time should the cronjob that does the
$string['configstatsuserthreshold'] = 'This setting specifies the minimum number of enrolled users for a course to be included in statistics calculations.'; $string['configstatsuserthreshold'] = 'This setting specifies the minimum number of enrolled users for a course to be included in statistics calculations.';
$string['configstrictformsrequired'] = 'If enabled, users are prevented from entering a space or line break only in required fields in forms.'; $string['configstrictformsrequired'] = 'If enabled, users are prevented from entering a space or line break only in required fields in forms.';
$string['configstripalltitletags'] = 'Uncheck this setting to allow HTML tags in activity and resource names.'; $string['configstripalltitletags'] = 'Uncheck this setting to allow HTML tags in activity and resource names.';
$string['configsupportavailability'] = 'Determines who has access to contact site support from the footer.';
$string['configsupportemail'] = 'If SMTP is configured on this site and a support page is not set, this email address will receive messages submitted through the support form. If sending fails, the email address will be displayed to logged-in users.'; $string['configsupportemail'] = 'If SMTP is configured on this site and a support page is not set, this email address will receive messages submitted through the support form. If sending fails, the email address will be displayed to logged-in users.';
$string['configsupportname'] = 'The name of the person or other entity providing support via the support form or support page.'; $string['configsupportname'] = 'The name of the person or other entity providing support via the support form or support page.';
$string['configsupportpage'] = 'A link to this page will be provided for users to contact the site support. If the field is left blank then a link to a support form will be provided instead.'; $string['configsupportpage'] = 'A link to this page will be provided for users to contact the site support. If the field is left blank then a link to a support form will be provided instead.';
@ -1291,6 +1294,7 @@ $string['stripalltitletags'] = 'Remove HTML tags from all activity names';
$string['supportcontact'] = 'Support contact'; $string['supportcontact'] = 'Support contact';
$string['supportemail'] = 'Support email'; $string['supportemail'] = 'Support email';
$string['supportemailsubject'] = 'Site support request - {$a}'; $string['supportemailsubject'] = 'Site support request - {$a}';
$string['supportavailability'] = 'Support availability';
$string['supportname'] = 'Support name'; $string['supportname'] = 'Support name';
$string['supportpage'] = 'Support page'; $string['supportpage'] = 'Support page';
$string['suspenduser'] = 'Suspend user account'; $string['suspenduser'] = 'Suspend user account';

View file

@ -2992,5 +2992,18 @@ privatefiles,moodle|/user/files.php';
upgrade_main_savepoint(true, 2022101400.05); upgrade_main_savepoint(true, 2022101400.05);
} }
if ($oldversion < 2022102800.01) {
// For sites with "contact site support" already available (4.0.x), maintain existing functionality.
if ($oldversion >= 2022041900.00) {
set_config('supportavailability', CONTACT_SUPPORT_ANYONE);
} else {
// Sites which did not previously have the "contact site support" feature default to it requiring authentication.
set_config('supportavailability', CONTACT_SUPPORT_AUTHENTICATED);
}
// Main savepoint reached.
upgrade_main_savepoint(true, 2022102800.01);
}
return true; return true;
} }

View file

@ -563,6 +563,21 @@ define('EMAIL_VIA_ALWAYS', 1);
*/ */
define('EMAIL_VIA_NO_REPLY_ONLY', 2); define('EMAIL_VIA_NO_REPLY_ONLY', 2);
/**
* Contact site support form/link disabled.
*/
define('CONTACT_SUPPORT_DISABLED', 0);
/**
* Contact site support form/link only available to authenticated users.
*/
define('CONTACT_SUPPORT_AUTHENTICATED', 1);
/**
* Contact site support form/link available to anyone visiting the site.
*/
define('CONTACT_SUPPORT_ANYONE', 2);
// PARAMETER HANDLING. // PARAMETER HANDLING.
/** /**

View file

@ -4195,6 +4195,14 @@ EOD;
public function supportemail(array $customattribs = []): string { public function supportemail(array $customattribs = []): string {
global $CFG; global $CFG;
// Do not provide a link to contact site support if it is unavailable to this user. This would be where the site has
// disabled support, or limited it to authenticated users and the current user is a guest or not logged in.
if (!isset($CFG->supportavailability) ||
$CFG->supportavailability == CONTACT_SUPPORT_DISABLED ||
($CFG->supportavailability == CONTACT_SUPPORT_AUTHENTICATED && (!isloggedin() || isguestuser()))) {
return '';
}
$label = get_string('contactsitesupport', 'admin'); $label = get_string('contactsitesupport', 'admin');
$icon = $this->pix_icon('t/email', ''); $icon = $this->pix_icon('t/email', '');
$content = $icon . $label; $content = $icon . $label;

View file

@ -24,6 +24,16 @@
require_once('../config.php'); require_once('../config.php');
require_once($CFG->dirroot . '/user/lib.php'); require_once($CFG->dirroot . '/user/lib.php');
$user = isloggedin() && !isguestuser() ? $USER : null;
// If not allowed to view this page, redirect to the homepage. This would be where the site has
// disabled support, or limited it to authenticated users and the current user is a guest or not logged in.
if (!isset($CFG->supportavailability) ||
$CFG->supportavailability == CONTACT_SUPPORT_DISABLED ||
($CFG->supportavailability == CONTACT_SUPPORT_AUTHENTICATED && is_null($user))) {
redirect($CFG->wwwroot);
}
if (!empty($CFG->supportpage)) { if (!empty($CFG->supportpage)) {
redirect($CFG->supportpage); redirect($CFG->supportpage);
} }
@ -34,7 +44,6 @@ $PAGE->set_title(get_string('contactsitesupport', 'admin'));
$PAGE->set_heading(get_string('contactsitesupport', 'admin')); $PAGE->set_heading(get_string('contactsitesupport', 'admin'));
$PAGE->set_pagelayout('standard'); $PAGE->set_pagelayout('standard');
$user = isloggedin() && !isguestuser() ? $USER : null;
$renderer = $PAGE->get_renderer('user'); $renderer = $PAGE->get_renderer('user');
$form = new \core_user\form\contactsitesupport_form(null, $user); $form = new \core_user\form\contactsitesupport_form(null, $user);

View file

@ -84,4 +84,26 @@ class behat_user extends behat_base {
throw new ExpectationException('The "' . $field . '" field does have purpose "' . $purpose . '"', $this->getSession()); throw new ExpectationException('The "' . $field . '" field does have purpose "' . $purpose . '"', $this->getSession());
} }
} }
/**
* Convert page names to URLs for steps like 'When I am on the "[page name]" page'.
*
* Recognised page names are:
* | Page name | Description |
* | Contact Site Support | The Contact Site Support page (user/contactsitesupport.php) |
*
* @param string $page name of the page, with the component name removed e.g. 'Admin notification'.
* @return moodle_url the corresponding URL.
* @throws Exception with a meaningful error message if the specified page cannot be found.
*/
protected function resolve_page_url(string $page): moodle_url {
switch (strtolower($page)) {
case 'contact site support':
return new moodle_url('/user/contactsitesupport.php');
default:
throw new Exception("Unrecognised core_user page type '{$page}'.");
}
}
} }

View file

@ -0,0 +1,107 @@
@core @core_user
Feature: Contact site support method and availability can be customised
In order to effectively support people using my Moodle site
As an admin
I need to be able to configure the site support method and who has access to it
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| user1 | User | One | user1@example.com |
Scenario: Contact site support can be made available to all site visitors
Given the following config values are set as admin:
| supportavailability | 2 |
# Confirm unauthenticated visitor has access to the contact form.
When I am on site homepage
Then I should see "Contact site support" in the "page-footer" "region"
And I click on "Contact site support" "link" in the "page-footer" "region"
And I should see "Contact site support" in the "page-header" "region"
# Confirm someone logged in as guest has access to the contact form.
And I log in as "guest"
And I should see "Contact site support" in the "page-footer" "region"
And I click on "Contact site support" "link" in the "page-footer" "region"
And I should see "Contact site support" in the "page-header" "region"
And I log out
# Confirm logged in user has access to the contact form.
And I log in as "user1"
And I should see "Contact site support" in the "page-footer" "region"
And I click on "Contact site support" "link" in the "page-footer" "region"
And I should see "Contact site support" in the "page-header" "region"
Scenario: Contact site support can be limited to authenticated users
Given the following config values are set as admin:
| supportavailability | 1 |
# Confirm unauthenticated visitor cannot see the option or directly access the page.
When I am on site homepage
Then I should not see "Contact site support" in the "page-footer" "region"
And I am on the "user > Contact Site Support" page
And I should see "Acceptance test site" in the "page-header" "region"
And I should not see "Contact site support" in the "page-header" "region"
# Confirm someone logged in as guest cannot see the option or directly access the page.
And I log in as "guest"
And I should not see "Contact site support" in the "page-footer" "region"
And I am on the "user > Contact Site Support" page
And I should see "Acceptance test site" in the "page-header" "region"
And I should not see "Contact site support" in the "page-header" "region"
And I log out
# Confirm logged in user has access to the contact form.
And I log in as "user1"
And I should see "Contact site support" in the "page-footer" "region"
And I click on "Contact site support" "link" in the "page-footer" "region"
And I should see "Contact site support" in the "page-header" "region"
Scenario: Contact site support can be disabled
Given the following config values are set as admin:
| supportavailability | 0 |
| defaulthomepage | home |
# Confirm unauthenticated visitor cannot see the option.
When I am on site homepage
Then I should not see "Contact site support" in the "page-footer" "region"
# Confirm someone logged in as guest cannot see the option.
And I log in as "guest"
And I should not see "Contact site support" in the "page-footer" "region"
And I log out
# Confirm logged in user cannot see the option.
And I log in as "user1"
And I should not see "Contact site support" in the "page-footer" "region"
And I log out
# Confirm admin cannot see the option.
And I log in as "admin"
And I should not see "Contact site support" in the "page-footer" "region"
# Confirm visiting the contact form directly without permission redirects to the homepage.
And I am on the "user > Contact Site Support" page
And I should see "Acceptance test site" in the "page-header" "region"
And I should not see "Contact site support" in the "page-header" "region"
@javascript
Scenario: Contact site support link opens a custom support page URL if set
Given the following config values are set as admin:
| supportavailability | 1 |
| supportpage | user/profile.php |
When I log in as "user1"
And I am on site homepage
And I click on "Contact site support" "link" in the "page-footer" "region"
And I switch to the browser tab opened by the app
Then I should see "User One" in the "page-header" "region"
And I should not see "Contact site support" in the "page-header" "region"
And I close the browser tab opened by the app
Scenario: Visiting the contact site support page directly will redirect to the custom support page if set
Given the following config values are set as admin:
| supportavailability | 2 |
| supportpage | profile.php |
When I log in as "user1"
And I am on the "user > Contact Site Support" page
Then I should see "User One" in the "page-header" "region"
And I should not see "Contact site support" in the "page-header" "region"
Scenario: Visiting the contact site support page still redirects to homepage if access to support is disabled
Given the following config values are set as admin:
| supportavailability | 0 |
| supportpage | profile.php |
| defaulthomepage | home |
When I log in as "user1"
And I am on the "user > Contact Site Support" page
Then I should see "Acceptance test site" in the "page-header" "region"
And I should not see "Contact site support" in the "page-header" "region"

View file

@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
$version = 2022102800.00; // YYYYMMDD = weekly release date of this DEV branch. $version = 2022102800.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches. // RR = release increments - 00 in DEV branches.
// .XX = incremental changes. // .XX = incremental changes.
$release = '4.1dev+ (Build: 20221028)'; // Human-friendly version name $release = '4.1dev+ (Build: 20221028)'; // Human-friendly version name