Compare commits
90 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ac9e395ed6 | |||
| 99fc164199 | |||
| 9ec2c12f3d | |||
| 6ec89f6374 | |||
| 834c80849c | |||
| 674198a799 | |||
| 66c32a3687 | |||
| 0118227509 | |||
| 2e1478b094 | |||
| 6961258bc2 | |||
| b4f6816952 | |||
| 16b30d920b | |||
| 61d140e99f | |||
| cc5eb38cea | |||
| 3b7bba9e75 | |||
| 2e020b506a | |||
| 74cdb7c4c8 | |||
| ef8d381a2f | |||
| 39717b72b1 | |||
| e7ff99758e | |||
| 26492d4979 | |||
| 3abbcd9976 | |||
| 1456551ba6 | |||
| c1ebec7cbc | |||
| 812c8b37e5 | |||
| f2ab11aa5b | |||
| 240b402523 | |||
| 34c4b3ce0c | |||
| 8b098b4a4e | |||
| 38a40c5e4b | |||
| 72580a5413 | |||
| 6253ab0170 | |||
| ff89abc311 | |||
| 7878d79359 | |||
| 93319747b2 | |||
| f46c1b4fa9 | |||
| a0297df86e | |||
| da9ab8a2f9 | |||
| 33829b8b68 | |||
| f5f468f6e1 | |||
| 6b4f55c91b | |||
| 63ed56bc7c | |||
| 841214dab2 | |||
| 43cbc05a2d | |||
| 973ea46697 | |||
| 98dbb93589 | |||
| 5fa19e43b3 | |||
| 0d3a2c9181 | |||
| 4f7bd72f72 | |||
| cc182408aa | |||
| 8b3913605a | |||
| 8ff67c91de | |||
| 4cbd6a0c6a | |||
| 203a55f57a | |||
| 5b05a9378c | |||
| 81e5d425c4 | |||
| 6362d7b51c | |||
| 51d3df8d30 | |||
| a60a6d41a3 | |||
| d6ba7724ae | |||
| 4f1be71581 | |||
| 58ddfe84c2 | |||
| dd156a4160 | |||
| 3bc8fa20bf | |||
| 954ae33aa9 | |||
| 24dbcc0008 | |||
| ebb96c2850 | |||
| 870c5ffbde | |||
| 049e27a805 | |||
| 6c7fa91d59 | |||
| 7c84b92be3 | |||
| bb36c3a1bb | |||
| 990bfee024 | |||
| 17584f9c92 | |||
| f551072f9e | |||
| 3447ab640c | |||
| 3dbad11471 | |||
| 43b4b87fbf | |||
| 7d33385a1d | |||
| 657617ac21 | |||
| 205e4152cc | |||
| e36fb751e5 | |||
| a0c1acd7fd | |||
| 2184ea5b64 | |||
| c81b3dc384 | |||
| ca6a4b1953 | |||
| 20cefd70e2 | |||
| bc87d55a1f | |||
| 51c376cfca | |||
| e0034b0566 |
@@ -54,3 +54,4 @@ moodle-plugin-ci.phar
|
||||
/admin/tool/componentlibrary/docs
|
||||
/admin/tool/componentlibrary/hugo/site/data/my-index.json
|
||||
.hugo_build.lock
|
||||
.phpcs.xml
|
||||
|
||||
@@ -21,6 +21,43 @@
|
||||
*/
|
||||
|
||||
module.exports = grunt => {
|
||||
|
||||
/**
|
||||
* Generate the PHPCS configuration.
|
||||
*
|
||||
* @param {Object} thirdPartyPaths
|
||||
*/
|
||||
const phpcsIgnore = (thirdPartyPaths) => {
|
||||
const {toXML} = require('jstoxml');
|
||||
|
||||
const config = {
|
||||
_name: 'ruleset',
|
||||
_attrs: {
|
||||
name: "MoodleCore",
|
||||
},
|
||||
_content: [
|
||||
{
|
||||
rule: {
|
||||
_attrs: {
|
||||
ref: './.phpcs.xml.dist',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
thirdPartyPaths.forEach(library => {
|
||||
config._content.push({
|
||||
'exclude-pattern': library,
|
||||
});
|
||||
});
|
||||
|
||||
grunt.file.write('.phpcs.xml', toXML(config, {
|
||||
header: true,
|
||||
indent: ' ',
|
||||
}) + "\n");
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate ignore files (utilising thirdpartylibs.xml data)
|
||||
*/
|
||||
@@ -53,6 +90,8 @@ module.exports = grunt => {
|
||||
'admin/tool/componentlibrary/hugo/dist/css/docs.css',
|
||||
].concat(thirdPartyPaths);
|
||||
grunt.file.write('.stylelintignore', stylelintIgnores.join('\n') + '\n');
|
||||
|
||||
phpcsIgnore(thirdPartyPaths);
|
||||
};
|
||||
|
||||
grunt.registerTask('ignorefiles', 'Generate ignore files for linters', handler);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ruleset name="MoodleCore">
|
||||
<rule ref="moodle"/>
|
||||
</ruleset>
|
||||
+15
-4
@@ -38,11 +38,22 @@
|
||||
}
|
||||
|
||||
if (!empty($show) and confirm_sesskey()) {
|
||||
$class = \core_plugin_manager::resolve_plugininfo_class('mod');
|
||||
$class::enable_plugin($show, true);
|
||||
$canenablemodule = true;
|
||||
$modulename = $show;
|
||||
|
||||
admin_get_root(true, false); // settings not required - only pages
|
||||
redirect(new moodle_url('/admin/modules.php'));
|
||||
// Invoking a callback function that enables plugins to force additional actions (e.g. displaying notifications,
|
||||
// modals, etc.) and also specify through its returned value (bool) whether the process of enabling the plugin
|
||||
// should continue after these actions or not.
|
||||
if (component_callback_exists("mod_{$modulename}", 'pre_enable_plugin_actions')) {
|
||||
$canenablemodule = component_callback("mod_{$modulename}", 'pre_enable_plugin_actions');
|
||||
}
|
||||
|
||||
if ($canenablemodule) {
|
||||
$class = \core_plugin_manager::resolve_plugininfo_class('mod');
|
||||
$class::enable_plugin($show, true);
|
||||
admin_get_root(true, false); // Settings not required - only pages.
|
||||
redirect(new moodle_url('/admin/modules.php'));
|
||||
}
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
+10
-9
@@ -33,8 +33,16 @@ if (!($settingspage->check_access())) {
|
||||
die;
|
||||
}
|
||||
|
||||
$hassiteconfig = has_capability('moodle/site:config', $PAGE->context);
|
||||
if ($hassiteconfig) {
|
||||
// If the context in the admin_settingpage object is explicitly defined and it is not system, reset the current
|
||||
// page context and use that one instead. This ensures that the proper navigation is displayed and highlighted.
|
||||
if ($settingspage->context && !$settingspage->context instanceof \context_system) {
|
||||
$PAGE->set_context($settingspage->context);
|
||||
}
|
||||
|
||||
$hassiteconfig = has_capability('moodle/site:config', context_system::instance());
|
||||
// Display the admin search input element in the page header if the user has the capability to change the site
|
||||
// configuration and the current page context is system.
|
||||
if ($hassiteconfig && $PAGE->context instanceof \context_system) {
|
||||
$PAGE->add_header_action($OUTPUT->render_from_template('core_admin/header_search_input', [
|
||||
'action' => new moodle_url('/admin/search.php'),
|
||||
]));
|
||||
@@ -125,13 +133,6 @@ if (empty($SITE->fullname)) {
|
||||
|
||||
$PAGE->set_title("$SITE->shortname: " . implode(": ",$visiblepathtosection));
|
||||
$PAGE->set_heading($SITE->fullname);
|
||||
if ($section === 'frontpagesettings') {
|
||||
$frontpagenode = $PAGE->settingsnav->find('frontpage', navigation_node::TYPE_SETTING);
|
||||
$frontpagenode->make_active();
|
||||
$PAGE->navbar->add(get_string('frontpage', 'admin'),
|
||||
new moodle_url('/admin/category.php', ['category' => 'frontpage']));
|
||||
$PAGE->navbar->add(get_string('frontpagesettings', 'admin'), $PAGE->url);
|
||||
}
|
||||
echo $OUTPUT->header();
|
||||
|
||||
if ($errormsg !== '') {
|
||||
|
||||
@@ -88,6 +88,15 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
$downloadcontentsitedefault->add_dependent_on('downloadcoursecontentallowed');
|
||||
$temp->add($downloadcontentsitedefault);
|
||||
|
||||
$temp->add(
|
||||
new admin_setting_configtext(
|
||||
'moodlecourse/participantsperpage',
|
||||
new lang_string('participants:perpage', 'course'),
|
||||
new lang_string('participants:perpage_help', 'course'),
|
||||
20
|
||||
)
|
||||
);
|
||||
|
||||
// Course format.
|
||||
$temp->add(new admin_setting_heading('courseformathdr', new lang_string('type_format', 'plugin'), ''));
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
|
||||
And the following "cohorts" exist:
|
||||
| name | idnumber |
|
||||
| Cohort 1 | CH1 |
|
||||
And the following "cohort members" exist:
|
||||
| user | cohort |
|
||||
| user2 | CH1 |
|
||||
| user3 | CH1 |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
@@ -27,8 +31,6 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
|
||||
| user2 | C1 | student |
|
||||
| user3 | C1 | student |
|
||||
And I log in as "admin"
|
||||
And I add "User Two (two@example.com)" user to "CH1" cohort members
|
||||
And I add "User Three (three@example.com)" user to "CH1" cohort members
|
||||
And I navigate to "Users > Accounts > Browse list of users" in site administration
|
||||
|
||||
Scenario: Filter user accounts by role and cohort
|
||||
|
||||
@@ -248,7 +248,7 @@ $string['printable:toolname'] = 'Summary report';
|
||||
$string['printable:toolshortname'] = 'Summary report';
|
||||
$string['printable:downloadpdf'] = 'Download PDF';
|
||||
$string['printable:printreport'] = 'Printable report';
|
||||
$string['error:nocoursespecified'] = 'This summary report requires a valid course id. Please access the accessibility toolkit from within a course, via the actions menu, which will then supply this required course id.';
|
||||
$string['error:nocoursespecified'] = 'The summary report requires a valid course ID. Please access the accessibility toolkit from within a course.';
|
||||
$string['pdf:filename'] = 'Brickfield_Summaryreport_CourseID-{$a}';
|
||||
|
||||
// Advanced page.
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_tool_cohortroles_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,5 +41,8 @@ function xmldb_tool_customlang_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -78,5 +78,8 @@ function xmldb_tool_dataprivacy_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2020061501, 'tool', 'dataprivacy');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,5 +45,8 @@ function xmldb_tool_log_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -46,5 +46,8 @@ function xmldb_logstore_database_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -46,5 +46,8 @@ function xmldb_logstore_standard_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -51,5 +51,8 @@ function xmldb_tool_mobile_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,5 +45,8 @@ function xmldb_tool_monitor_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -164,5 +164,8 @@ function xmldb_tool_moodlenet_upgrade(int $oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2022021601, 'tool', 'moodlenet');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -58,9 +58,8 @@ $string['mnetprofiledesc'] = '<p>Enter your MoodleNet profile details here to be
|
||||
$string['moodlenetsettings'] = 'MoodleNet settings';
|
||||
$string['moodlenetnotenabled'] = 'The MoodleNet integration must be enabled in Site administration / MoodleNet before resource imports can be processed.';
|
||||
$string['notification'] = 'You are about to import the content "{$a->name} ({$a->type})" into your site. Select the course in which it should be added, or <a href="{$a->cancellink}">cancel</a>.';
|
||||
$string['removedmnetprofilenotification'] = '<p>Due to some recent changes on the MoodleNet platform, users that have previously saved their MoodleNet profile on the site can no longer use this data to authenticate on the MoodleNet platform. The related data has now been removed as it is no longer useful.</p>
|
||||
<p>The users will need to reset this information on the site by linking their MoodleNet profile ID which can be found on their MoodleNet profile.</p>';
|
||||
$string['removedmnetprofilenotification_subject'] = 'Linked MoodleNet profiles removed.';
|
||||
$string['removedmnetprofilenotification'] = 'Due to recent changes on the MoodleNet platform, any users who previously saved their MoodleNet profile ID on the site will need to enter a MoodleNet profile ID in the new format in order to authenticate on the MoodleNet platform.';
|
||||
$string['removedmnetprofilenotification_subject'] = 'MoodleNet profile ID format change';
|
||||
$string['searchcourses'] = "Search courses";
|
||||
$string['selectpagetitle'] = 'Select page';
|
||||
$string['pluginname'] = 'MoodleNet';
|
||||
|
||||
@@ -46,5 +46,8 @@ function xmldb_tool_policy_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,12 @@ class tool_uploadcourse_course {
|
||||
/** Outcome of the process: deleting the course */
|
||||
const DO_DELETE = 3;
|
||||
|
||||
/** @var array assignable roles. */
|
||||
protected $assignableroles = [];
|
||||
|
||||
/** @var array Roles context levels. */
|
||||
protected $contextlevels = [];
|
||||
|
||||
/** @var array final import data. */
|
||||
protected $data = array();
|
||||
|
||||
@@ -794,16 +800,15 @@ class tool_uploadcourse_course {
|
||||
|
||||
// Get enrolment data. Where the course already exists, we can also perform validation.
|
||||
$this->enrolmentdata = tool_uploadcourse_helper::get_enrolment_data($this->rawdata);
|
||||
if ($exists) {
|
||||
$errors = $this->validate_enrolment_data($coursedata['id'], $this->enrolmentdata);
|
||||
$courseid = $coursedata['id'] ?? 0;
|
||||
$errors = $this->validate_enrolment_data($courseid, $this->enrolmentdata);
|
||||
|
||||
if (!empty($errors)) {
|
||||
foreach ($errors as $key => $message) {
|
||||
$this->error($key, $message);
|
||||
}
|
||||
|
||||
return false;
|
||||
if (!empty($errors)) {
|
||||
foreach ($errors as $key => $message) {
|
||||
$this->error($key, $message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($this->rawdata['tags']) && strval($this->rawdata['tags']) !== '') {
|
||||
@@ -913,6 +918,8 @@ class tool_uploadcourse_course {
|
||||
* @return lang_string[] Errors keyed on error code
|
||||
*/
|
||||
protected function validate_enrolment_data(int $courseid, array $enrolmentdata): array {
|
||||
global $DB;
|
||||
|
||||
// Nothing to validate.
|
||||
if (empty($enrolmentdata)) {
|
||||
return [];
|
||||
@@ -924,46 +931,67 @@ class tool_uploadcourse_course {
|
||||
$instances = enrol_get_instances($courseid, false);
|
||||
|
||||
foreach ($enrolmentdata as $method => $options) {
|
||||
$plugin = $enrolmentplugins[$method];
|
||||
|
||||
// Find matching instances by enrolment method.
|
||||
$methodinstances = array_filter($instances, static function(stdClass $instance) use ($method) {
|
||||
return (strcmp($instance->enrol, $method) == 0);
|
||||
});
|
||||
if (isset($options['role'])) {
|
||||
$role = $options['role'];
|
||||
if ($courseid) {
|
||||
if (!$this->validate_role_context($courseid, $role)) {
|
||||
$errors['contextrolenotallowed'] = new lang_string('contextrolenotallowed', 'core_role', $role);
|
||||
|
||||
if (!empty($options['delete'])) {
|
||||
// Ensure user is able to delete the instances.
|
||||
foreach ($methodinstances as $methodinstance) {
|
||||
if (!$plugin->can_delete_instance($methodinstance)) {
|
||||
$errors['errorcannotdeleteenrolment'] = new lang_string('errorcannotdeleteenrolment', 'tool_uploadcourse',
|
||||
$plugin->get_instance_name($methodinstance));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// We can at least check that context level is correct while actual context not exist.
|
||||
$roleid = $DB->get_field('role', 'id', ['shortname' => $role], MUST_EXIST);
|
||||
if (!$this->validate_role_context_level($roleid)) {
|
||||
$errors['contextrolenotallowed'] = new lang_string('contextrolenotallowed', 'core_role', $role);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!empty($options['disable'])) {
|
||||
// Ensure user is able to toggle instance statuses.
|
||||
foreach ($methodinstances as $methodinstance) {
|
||||
if (!$plugin->can_hide_show_instance($methodinstance)) {
|
||||
$errors['errorcannotdisableenrolment'] =
|
||||
new lang_string('errorcannotdisableenrolment', 'tool_uploadcourse',
|
||||
}
|
||||
|
||||
if ($courseid) {
|
||||
$plugin = $enrolmentplugins[$method];
|
||||
|
||||
// Find matching instances by enrolment method.
|
||||
$methodinstances = array_filter($instances, static function (stdClass $instance) use ($method) {
|
||||
return (strcmp($instance->enrol, $method) == 0);
|
||||
});
|
||||
|
||||
if (!empty($options['delete'])) {
|
||||
// Ensure user is able to delete the instances.
|
||||
foreach ($methodinstances as $methodinstance) {
|
||||
if (!$plugin->can_delete_instance($methodinstance)) {
|
||||
$errors['errorcannotdeleteenrolment'] = new lang_string('errorcannotdeleteenrolment',
|
||||
'tool_uploadcourse', $plugin->get_instance_name($methodinstance));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!empty($options['disable'])) {
|
||||
// Ensure user is able to toggle instance statuses.
|
||||
foreach ($methodinstances as $methodinstance) {
|
||||
if (!$plugin->can_hide_show_instance($methodinstance)) {
|
||||
$errors['errorcannotdisableenrolment'] =
|
||||
new lang_string('errorcannotdisableenrolment', 'tool_uploadcourse',
|
||||
$plugin->get_instance_name($methodinstance));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Ensure user is able to create/update instance.
|
||||
$methodinstance = empty($methodinstances) ? null : reset($methodinstances);
|
||||
if ((empty($methodinstance) && !$plugin->can_add_instance($courseid)) ||
|
||||
(!empty($methodinstance) && !$plugin->can_edit_instance($methodinstance))) {
|
||||
|
||||
$errors['errorcannotcreateorupdateenrolment'] =
|
||||
new lang_string('errorcannotcreateorupdateenrolment', 'tool_uploadcourse',
|
||||
$plugin->get_instance_name($methodinstance));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Ensure user is able to create/update instance.
|
||||
$methodinstance = empty($methodinstances) ? null : reset($methodinstances);
|
||||
if ((empty($methodinstance) && !$plugin->can_add_instance($courseid)) ||
|
||||
(!empty($methodinstance) && !$plugin->can_edit_instance($methodinstance))) {
|
||||
|
||||
$errors['errorcannotcreateorupdateenrolment'] =
|
||||
new lang_string('errorcannotcreateorupdateenrolment', 'tool_uploadcourse',
|
||||
$plugin->get_instance_name($methodinstance));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1079,8 +1107,15 @@ class tool_uploadcourse_course {
|
||||
$instance->enrolenddate = $instance->enrolstartdate;
|
||||
}
|
||||
|
||||
// Sort out the given role. This does not filter the roles allowed in the course.
|
||||
// Sort out the given role.
|
||||
if (isset($method['role'])) {
|
||||
$role = $method['role'];
|
||||
if (!$this->validate_role_context($course->id, $role)) {
|
||||
$this->error('contextrolenotallowed',
|
||||
new lang_string('contextrolenotallowed', 'core_role', $role));
|
||||
break;
|
||||
}
|
||||
|
||||
$roleids = tool_uploadcourse_helper::get_role_ids();
|
||||
if (isset($roleids[$method['role']])) {
|
||||
$instance->roleid = $roleids[$method['role']];
|
||||
@@ -1093,6 +1128,41 @@ class tool_uploadcourse_course {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if role is allowed in course context
|
||||
*
|
||||
* @param int $courseid course context.
|
||||
* @param string $role Role.
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_role_context(int $courseid, string $role) : bool {
|
||||
if (empty($this->assignableroles[$courseid])) {
|
||||
$coursecontext = \context_course::instance($courseid);
|
||||
$this->assignableroles[$courseid] = get_assignable_roles($coursecontext, ROLENAME_SHORT);
|
||||
}
|
||||
if (!in_array($role, $this->assignableroles[$courseid])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if role is allowed at this context level.
|
||||
*
|
||||
* @param int $roleid Role ID.
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_role_context_level(int $roleid) : bool {
|
||||
if (empty($this->contextlevels[$roleid])) {
|
||||
$this->contextlevels[$roleid] = get_role_contextlevels($roleid);
|
||||
}
|
||||
|
||||
if (!in_array(CONTEXT_COURSE, $this->contextlevels[$roleid])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the current course.
|
||||
*
|
||||
|
||||
@@ -325,6 +325,11 @@ class tool_uploadcourse_helper {
|
||||
continue;
|
||||
}
|
||||
$rolenames['role_' . $rolesids[$matches[1]]] = $value;
|
||||
} else if (preg_match('/^(.+)?_role$/', $field, $matches)) {
|
||||
if (!isset($rolesids[$value])) {
|
||||
$invalidroles[] = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -219,6 +219,10 @@ class tool_uploadcourse_processor {
|
||||
|
||||
$data = array_merge($data, $course->get_data(), array('id' => $course->get_id()));
|
||||
$tracker->output($this->linenb, true, $status, $data);
|
||||
if ($course->has_errors()) {
|
||||
$errors++;
|
||||
$tracker->output($this->linenb, false, $course->get_errors(), $data);
|
||||
}
|
||||
} else {
|
||||
$errors++;
|
||||
$tracker->output($this->linenb, false, $course->get_errors(), $data);
|
||||
|
||||
@@ -105,3 +105,28 @@ Feature: An admin can create courses using a CSV file
|
||||
And I should see "Field 3: b"
|
||||
And I should see "Field 4: Hello"
|
||||
And I should see "Field 5: Some text"
|
||||
|
||||
@javascript
|
||||
Scenario: Validation of role for uploaded courses
|
||||
Given I navigate to "Users > Permissions > Define roles" in site administration
|
||||
And I click on "Add a new role" "button"
|
||||
And I click on "Continue" "button"
|
||||
And I set the following fields to these values:
|
||||
| Short name | notallowed |
|
||||
| Custom full name | notallowed |
|
||||
| contextlevel80 | 1 |
|
||||
And I click on "Create this role" "button"
|
||||
And I navigate to "Courses > Upload courses" in site administration
|
||||
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_role.csv" file to "File" filemanager
|
||||
And I click on "Preview" "button"
|
||||
And I should see "Invalid role names: notexist"
|
||||
And I should see "Role notallowed not allowed in this context."
|
||||
When I click on "Upload courses" "button"
|
||||
And I should see "Course created"
|
||||
And I should see "Courses total: 3"
|
||||
And I should see "Courses created: 1"
|
||||
And I should see "Courses errors: 2"
|
||||
And I should see "Invalid role names: notexist"
|
||||
And I should see "Role notallowed not allowed in this context."
|
||||
And I am on site homepage
|
||||
And I should see "coursez"
|
||||
|
||||
@@ -1561,6 +1561,94 @@ class course_test extends \advanced_testcase {
|
||||
$this->assertArrayHasKey('cannotrenameshortnamealreadyinuse', $co->get_errors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test when role doesn't exist.
|
||||
*
|
||||
* @covers \tool_uploadcourse_course::prepare
|
||||
*/
|
||||
public function test_role_not_exist() {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$mode = tool_uploadcourse_processor::MODE_CREATE_NEW;
|
||||
$updatemode = tool_uploadcourse_processor::UPDATE_NOTHING;
|
||||
|
||||
$upload = new tool_uploadcourse_course($mode, $updatemode, [
|
||||
'category' => 1,
|
||||
'fullname' => 'Testing',
|
||||
'shortname' => 'T101',
|
||||
'enrolment_1' => 'manual',
|
||||
'enrolment_1_role' => 'notexist'
|
||||
]);
|
||||
|
||||
$this->assertFalse($upload->prepare());
|
||||
$this->assertArrayHasKey('invalidroles', $upload->get_errors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test when role not allowed in course context.
|
||||
*
|
||||
* @covers \tool_uploadcourse_course::proceed
|
||||
*/
|
||||
public function test_role_not_allowed() {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$roleid = create_role('New student role', 'student2', 'New student description', 'student');
|
||||
set_role_contextlevels($roleid, [CONTEXT_BLOCK]);
|
||||
|
||||
$mode = tool_uploadcourse_processor::MODE_CREATE_NEW;
|
||||
$updatemode = tool_uploadcourse_processor::UPDATE_NOTHING;
|
||||
|
||||
$upload = new tool_uploadcourse_course($mode, $updatemode, [
|
||||
'category' => 1,
|
||||
'fullname' => 'Testing',
|
||||
'shortname' => 'T101',
|
||||
'enrolment_1' => 'manual',
|
||||
'enrolment_1_role' => 'student2'
|
||||
]);
|
||||
|
||||
$this->assertFalse($upload->prepare());
|
||||
$this->assertArrayHasKey('contextrolenotallowed', $upload->get_errors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test when role is allowed.
|
||||
*
|
||||
* @covers \tool_uploadcourse_course::proceed
|
||||
*/
|
||||
public function test_role_allowed() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY;
|
||||
$updatemode = tool_uploadcourse_processor::UPDATE_MISSING_WITH_DATA_OR_DEFAUTLS;
|
||||
|
||||
$course = $this->getDataGenerator()->create_course([
|
||||
'shortname' => 'c1',
|
||||
]);
|
||||
|
||||
$instances = enrol_get_instances($course->id, true);
|
||||
$studentrole = $DB->get_record('role', ['shortname' => 'student']);
|
||||
$teacherrole = $DB->get_record('role', ['shortname' => 'teacher']);
|
||||
$instance = reset($instances);
|
||||
$this->assertEquals($studentrole->id, $instance->roleid);
|
||||
|
||||
$upload = new tool_uploadcourse_course($mode, $updatemode, [
|
||||
'shortname' => 'c1',
|
||||
'enrolment_1' => 'manual',
|
||||
'enrolment_1_role' => 'teacher'
|
||||
]);
|
||||
|
||||
$this->assertTrue($upload->prepare());
|
||||
$upload->proceed();
|
||||
$instances = enrol_get_instances($course->id, true);
|
||||
$instance = reset($instances);
|
||||
$this->assertEquals($teacherrole->id, $instance->roleid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom field plugin generator
|
||||
*
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
shortname,fullname,category,enrolment_1,enrolment_1_role
|
||||
CX,coursex,1,manual,notexist
|
||||
CY,coursey,1,manual,notallowed
|
||||
CZ,coursez,1,manual,student
|
||||
|
@@ -129,5 +129,8 @@ function xmldb_tool_usertours_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2022040602, 'tool', 'usertours');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
This files describes API changes in /admin/*.
|
||||
|
||||
=== 4.0.1 ===
|
||||
|
||||
* A new callback xxx_pre_enable_plugin_actions has been added in admin/modules.php. Plugins can use this callback to
|
||||
force additional actions (e.g. displaying notifications, modals, etc.) before enabling the plugin. The expected
|
||||
return value (bool) from the plugin callback method specifies whether the process of enabling the plugin should
|
||||
continue after the added actions or not.
|
||||
|
||||
=== 3.11 ===
|
||||
|
||||
* New admin setting admin_setting_encryptedpassword allows passwords in admin settings to be
|
||||
|
||||
@@ -52,5 +52,8 @@ function xmldb_auth_cas_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2021052501, 'auth', 'cas');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_db_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_email_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -52,5 +52,8 @@ function xmldb_auth_ldap_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2021052501, 'auth', 'ldap');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -85,5 +85,8 @@ function xmldb_auth_lti_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2022030900, 'auth', 'lti');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_manual_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_mnet_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_none_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -81,5 +81,8 @@ function xmldb_auth_oauth2_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -66,5 +66,8 @@ function xmldb_auth_shibboleth_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2021052501, 'auth', 'shibboleth');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ Feature: Test if the login form provides the correct feedback
|
||||
Then I should see "Invalid login, please try again"
|
||||
|
||||
Scenario: Test login language selector
|
||||
Given I log in as "admin"
|
||||
Given remote langimport tests are enabled
|
||||
And I log in as "admin"
|
||||
And I navigate to "Language > Language packs" in site administration
|
||||
And I set the field "Available language packs" to "nl,es"
|
||||
And I press "Install selected language pack(s)"
|
||||
|
||||
@@ -475,6 +475,11 @@ class backup_course_structure_step extends backup_structure_step {
|
||||
'shortname', 'type', 'value', 'valueformat'
|
||||
));
|
||||
|
||||
$courseformatoptions = new backup_nested_element('courseformatoptions');
|
||||
$courseformatoption = new backup_nested_element('courseformatoption', [], [
|
||||
'courseid', 'format', 'sectionid', 'name', 'value'
|
||||
]);
|
||||
|
||||
// attach format plugin structure to $course element, only one allowed
|
||||
$this->add_plugin_structure('format', $course, false);
|
||||
|
||||
@@ -512,17 +517,14 @@ class backup_course_structure_step extends backup_structure_step {
|
||||
$course->add_child($customfields);
|
||||
$customfields->add_child($customfield);
|
||||
|
||||
$course->add_child($courseformatoptions);
|
||||
$courseformatoptions->add_child($courseformatoption);
|
||||
|
||||
// Set the sources
|
||||
|
||||
$courserec = $DB->get_record('course', array('id' => $this->task->get_courseid()));
|
||||
$courserec->contextid = $this->task->get_contextid();
|
||||
|
||||
$formatoptions = course_get_format($courserec)->get_format_options();
|
||||
$course->add_final_elements(array_keys($formatoptions));
|
||||
foreach ($formatoptions as $key => $value) {
|
||||
$courserec->$key = $value;
|
||||
}
|
||||
|
||||
// Add 'numsections' in order to be able to restore in previous versions of Moodle.
|
||||
// Even though Moodle does not officially support restore into older verions of Moodle from the
|
||||
// version where backup was made, without 'numsections' restoring will go very wrong.
|
||||
@@ -544,6 +546,10 @@ class backup_course_structure_step extends backup_structure_step {
|
||||
backup_helper::is_sqlparam('course'),
|
||||
backup::VAR_PARENTID));
|
||||
|
||||
$courseformatoption->set_source_sql('SELECT id, format, sectionid, name, value
|
||||
FROM {course_format_options}
|
||||
WHERE courseid = ?', [ backup::VAR_PARENTID ]);
|
||||
|
||||
$handler = core_course\customfield\course_handler::create();
|
||||
$fieldsforbackup = $handler->get_instance_data_for_backup($this->task->get_courseid());
|
||||
$customfield->set_source_array($fieldsforbackup);
|
||||
|
||||
@@ -1806,7 +1806,8 @@ class restore_course_structure_step extends restore_structure_step {
|
||||
$category = new restore_path_element('category', '/course/category');
|
||||
$tag = new restore_path_element('tag', '/course/tags/tag');
|
||||
$customfield = new restore_path_element('customfield', '/course/customfields/customfield');
|
||||
$allowed_module = new restore_path_element('allowed_module', '/course/allowed_modules/module');
|
||||
$courseformatoptions = new restore_path_element('course_format_option', '/course/courseformatoptions/courseformatoption');
|
||||
$allowedmodule = new restore_path_element('allowed_module', '/course/allowed_modules/module');
|
||||
|
||||
// Apply for 'format' plugins optional paths at course level
|
||||
$this->add_plugin_structure('format', $course);
|
||||
@@ -1829,7 +1830,7 @@ class restore_course_structure_step extends restore_structure_step {
|
||||
// Apply for admin tool plugins optional paths at course level.
|
||||
$this->add_plugin_structure('tool', $course);
|
||||
|
||||
return array($course, $category, $tag, $customfield, $allowed_module);
|
||||
return array($course, $category, $tag, $customfield, $allowedmodule, $courseformatoptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1951,8 +1952,6 @@ class restore_course_structure_step extends restore_structure_step {
|
||||
// Course record ready, update it
|
||||
$DB->update_record('course', $data);
|
||||
|
||||
course_get_format($data)->update_course_format_options($data);
|
||||
|
||||
// Role name aliases
|
||||
restore_dbops::set_course_role_names($this->get_restoreid(), $this->get_courseid());
|
||||
}
|
||||
@@ -1980,6 +1979,26 @@ class restore_course_structure_step extends restore_structure_step {
|
||||
$handler->restore_instance_data_from_backup($this->task, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a course format option.
|
||||
*
|
||||
* @param array $data The record being restored.
|
||||
* @throws base_step_exception
|
||||
* @throws dml_exception
|
||||
*/
|
||||
public function process_course_format_option(array $data) : void {
|
||||
global $DB;
|
||||
|
||||
$courseid = $this->get_courseid();
|
||||
$record = $DB->get_record('course_format_options', [ 'courseid' => $courseid, 'name' => $data['name'] ], 'id');
|
||||
if ($record !== false) {
|
||||
$DB->update_record('course_format_options', (object) [ 'id' => $record->id, 'value' => $data['value'] ]);
|
||||
} else {
|
||||
$data['courseid'] = $courseid;
|
||||
$DB->insert_record('course_format_options', (object) $data);
|
||||
}
|
||||
}
|
||||
|
||||
public function process_allowed_module($data) {
|
||||
$data = (object)$data;
|
||||
|
||||
|
||||
@@ -248,8 +248,11 @@ class award_criteria_activity extends award_criteria {
|
||||
if (!empty($moduledata)) {
|
||||
$extraon = implode(' OR ', $moduledata);
|
||||
$join = " JOIN {course_modules_completion} cmc ON cmc.userid = u.id AND
|
||||
( cmc.completionstate = :completionpass OR cmc.completionstate = :completioncomplete ) AND ({$extraon})";
|
||||
( cmc.completionstate = :completionfail OR
|
||||
cmc.completionstate = :completionpass OR
|
||||
cmc.completionstate = :completioncomplete ) AND ({$extraon})";
|
||||
$params["completionpass"] = COMPLETION_COMPLETE_PASS;
|
||||
$params["completionfail"] = COMPLETION_COMPLETE_FAIL;
|
||||
$params["completioncomplete"] = COMPLETION_COMPLETE;
|
||||
}
|
||||
return array($join, $where, $params);
|
||||
@@ -259,10 +262,12 @@ class award_criteria_activity extends award_criteria {
|
||||
cmc{$param['module']}.userid = u.id AND
|
||||
cmc{$param['module']}.coursemoduleid = :completedmodule{$param['module']} AND
|
||||
( cmc{$param['module']}.completionstate = :completionpass{$param['module']} OR
|
||||
cmc{$param['module']}.completionstate = :completionfail{$param['module']} OR
|
||||
cmc{$param['module']}.completionstate = :completioncomplete{$param['module']} )";
|
||||
$where .= " AND cmc{$param['module']}.coursemoduleid IS NOT NULL ";
|
||||
$params["completedmodule{$param['module']}"] = $param['module'];
|
||||
$params["completionpass{$param['module']}"] = COMPLETION_COMPLETE_PASS;
|
||||
$params["completionfail{$param['module']}"] = COMPLETION_COMPLETE_FAIL;
|
||||
$params["completioncomplete{$param['module']}"] = COMPLETION_COMPLETE;
|
||||
}
|
||||
return array($join, $where, $params);
|
||||
|
||||
@@ -202,8 +202,8 @@ class award_criteria_profile extends award_criteria {
|
||||
$join .= " LEFT JOIN {user_info_data} uid{$idx} ON uid{$idx}.userid = u.id AND uid{$idx}.fieldid = :fieldid{$idx} ";
|
||||
$sqlparams["fieldid{$idx}"] = $param['field'];
|
||||
$whereparts[] = "uid{$idx}.id IS NOT NULL";
|
||||
} else {
|
||||
// This is a field from {user} table.
|
||||
} else if (in_array($param['field'], $this->allowed_default_fields)) {
|
||||
// This is a valid field from {user} table.
|
||||
if ($param['field'] == 'picture') {
|
||||
// The picture field is numeric and requires special handling.
|
||||
$whereparts[] = "u.{$param['field']} != 0";
|
||||
|
||||
@@ -8,6 +8,7 @@ Feature: Award badges based on activity completion
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| student1 | Student | 1 | student1@example.com |
|
||||
| student2 | Student | 1 | student2@example.com |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | enablecompletion |
|
||||
@@ -16,6 +17,7 @@ Feature: Award badges based on activity completion
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
| student2 | C1 | student |
|
||||
And the following config values are set as admin:
|
||||
| grade_item_advanced | hiddenuntil |
|
||||
And the following "question categories" exist:
|
||||
@@ -33,6 +35,9 @@ Feature: Award badges based on activity completion
|
||||
And user "student1" has attempted "Test quiz name" with responses:
|
||||
| slot | response |
|
||||
| 1 | False |
|
||||
And user "student2" has attempted "Test quiz name" with responses:
|
||||
| slot | response |
|
||||
| 1 | False |
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I change window size to "large"
|
||||
@@ -42,6 +47,13 @@ Feature: Award badges based on activity completion
|
||||
| Description | Course badge description |
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filemanager
|
||||
And I press "Create badge"
|
||||
|
||||
Scenario: Student earns a badge using activity completion, but does not get passing grade
|
||||
Given I am on the "Course 1" course page logged in as teacher1
|
||||
And I navigate to "Badges" in current page administration
|
||||
And I press "Manage badges"
|
||||
And I follow "Course Badge"
|
||||
And I select "Criteria" from the "jump" singleselect
|
||||
And I set the field "type" to "Activity completion"
|
||||
And I set the field "Quiz - Test quiz name" to "1"
|
||||
And I press "Save"
|
||||
@@ -49,10 +61,7 @@ Feature: Award badges based on activity completion
|
||||
And I press "Continue"
|
||||
And I should see "Recipients (0)"
|
||||
And I log out
|
||||
|
||||
Scenario: Student earns a badge using activity completion, but does not get passing grade
|
||||
Given I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I am on the "Course 1" course page logged in as student1
|
||||
And the "Receive a grade" completion condition of "Test quiz name" is displayed as "done"
|
||||
And the "Receive a passing grade" completion condition of "Test quiz name" is displayed as "failed"
|
||||
And the "Receive a pass grade or complete all available attempts" completion condition of "Test quiz name" is displayed as "todo"
|
||||
@@ -68,3 +77,48 @@ Feature: Award badges based on activity completion
|
||||
And I navigate to "Badges > Manage badges" in current page administration
|
||||
And I follow "Course Badge"
|
||||
Then I should see "Recipients (1)"
|
||||
|
||||
Scenario Outline: Previously graded pass/fail students should earn a badge after enabling a badge
|
||||
Given I am on the "Course 1" course page logged in as teacher1
|
||||
And I navigate to "Badges" in current page administration
|
||||
And I press "Manage badges"
|
||||
And I follow "Course Badge"
|
||||
And I select "Criteria" from the "jump" singleselect
|
||||
And I set the field "type" to "Activity completion"
|
||||
And I click on "Expand all" "link"
|
||||
And I set the field "Quiz - Test quiz name" to "1"
|
||||
And I set the field "<aggregationcriteria>" to "1"
|
||||
And I press "Save"
|
||||
|
||||
# Fail grade with student2
|
||||
And I am on the "Course 1" course page logged in as student2
|
||||
And I am on the "Test quiz name" "quiz activity" page
|
||||
And I press "Re-attempt quiz"
|
||||
And I set the field "False" to "1"
|
||||
And I press "Finish attempt ..."
|
||||
And I press "Submit all and finish"
|
||||
And I click on "Submit all and finish" "button" in the "Confirmation" "dialogue"
|
||||
And I log out
|
||||
|
||||
# Pass grade with student1
|
||||
And I am on the "Course 1" course page logged in as student1
|
||||
And I am on the "Test quiz name" "quiz activity" page
|
||||
And I press "Re-attempt quiz"
|
||||
And I set the field "False" to "0"
|
||||
And I press "Finish attempt ..."
|
||||
And I press "Submit all and finish"
|
||||
And I click on "Submit all and finish" "button" in the "Confirmation" "dialogue"
|
||||
And I log out
|
||||
|
||||
# Enable badge access once all students have completed an activity.
|
||||
And I am on the "Course 1" course page logged in as teacher1
|
||||
And I navigate to "Badges > Manage badges" in current page administration
|
||||
And I follow "Course Badge"
|
||||
When I press "Enable access"
|
||||
And I press "Continue"
|
||||
Then I should see "Recipients (2)"
|
||||
|
||||
Examples:
|
||||
| aggregationcriteria |
|
||||
| Any of the selected activities is complete |
|
||||
| All of the selected activities are complete |
|
||||
|
||||
@@ -405,6 +405,12 @@ Feature: Award badges based on cohort
|
||||
| user1 | First | User | first@example.com |
|
||||
| user2 | Second | User | second@example.com |
|
||||
| user3 | Third | User | third@example.com |
|
||||
And the following "cohort members" exist:
|
||||
| user | cohort |
|
||||
| user1 | CH1 |
|
||||
| user1 | CH2 |
|
||||
| user2 | CH2 |
|
||||
| user2 | CH3 |
|
||||
And I log in as "admin"
|
||||
And I navigate to "Badges > Add a new badge" in site administration
|
||||
And I set the following fields to these values:
|
||||
@@ -419,7 +425,7 @@ Feature: Award badges based on cohort
|
||||
And I press "Save"
|
||||
And I press "Enable access"
|
||||
When I press "Continue"
|
||||
And I should see "Recipients (0)"
|
||||
And I should see "Recipients (1)"
|
||||
And I navigate to "Badges > Add a new badge" in site administration
|
||||
And I set the following fields to these values:
|
||||
| Name | Site Badge 2 |
|
||||
@@ -433,11 +439,7 @@ Feature: Award badges based on cohort
|
||||
And I press "Save"
|
||||
And I press "Enable access"
|
||||
And I press "Continue"
|
||||
Then I navigate to "Users > Accounts >Cohorts" in site administration
|
||||
And I add "First User (first@example.com)" user to "CH1" cohort members
|
||||
And I add "First User (first@example.com)" user to "CH2" cohort members
|
||||
And I add "Second User (second@example.com)" user to "CH2" cohort members
|
||||
And I add "Second User (second@example.com)" user to "CH3" cohort members
|
||||
And I should see "Recipients (1)"
|
||||
And I log out
|
||||
And I log in as "user1"
|
||||
And I follow "Profile" in the user menu
|
||||
|
||||
@@ -57,5 +57,8 @@ function xmldb_block_badges_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -72,5 +72,8 @@ function xmldb_block_calendar_month_upgrade($oldversion, $block) {
|
||||
upgrade_block_savepoint(true, 2022041901, 'calendar_month', false);
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -57,5 +57,8 @@ function xmldb_block_calendar_upcoming_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -60,5 +60,8 @@ function xmldb_block_completionstatus_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,5 +71,8 @@ function xmldb_block_course_summary_upgrade($oldversion, $block) {
|
||||
upgrade_block_savepoint(true, 2021121600, 'course_summary', false);
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -58,5 +58,8 @@ function xmldb_block_feedback_upgrade($oldversion, $block) {
|
||||
upgrade_block_savepoint(true, 2021121600, 'feedback', false);
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,5 +45,8 @@ function xmldb_block_html_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -597,9 +597,20 @@ class block_base {
|
||||
* @return boolean
|
||||
*/
|
||||
function user_can_addto($page) {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/user/lib.php');
|
||||
|
||||
// List of formats this block supports.
|
||||
$formats = $this->applicable_formats();
|
||||
|
||||
// Check if user is trying to add blocks to their profile page.
|
||||
$userpagetypes = user_page_type_list($page->pagetype, null, null);
|
||||
if (array_key_exists($page->pagetype, $userpagetypes)) {
|
||||
$capability = 'block/' . $this->name() . ':addinstance';
|
||||
return $this->has_add_block_capability($page, $capability)
|
||||
&& has_capability('moodle/user:manageownblocks', $page->context);
|
||||
}
|
||||
|
||||
// The blocks in My Moodle are a special case and use a different capability.
|
||||
$mypagetypes = my_page_type_list($page->pagetype); // Get list of possible my page types.
|
||||
|
||||
|
||||
@@ -120,5 +120,8 @@ function xmldb_block_myoverview_upgrade($oldversion) {
|
||||
upgrade_block_savepoint(true, 2022041901, 'myoverview', false);
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -67,5 +67,8 @@ function xmldb_block_navigation_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -59,5 +59,8 @@ function xmldb_block_recent_activity_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,5 +88,8 @@ function xmldb_block_recentlyaccesseditems_upgrade($oldversion, $block) {
|
||||
upgrade_block_savepoint(true, 2022041901, 'recentlyaccesseditems', false);
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -56,5 +56,8 @@ function xmldb_block_rss_client_upgrade($oldversion) {
|
||||
upgrade_block_savepoint(true, 2021121600, 'rss_client', false);
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -61,5 +61,8 @@ function xmldb_block_section_links_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,5 +71,8 @@ function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
|
||||
upgrade_block_savepoint(true, 2021121600, 'selfcompletion', false);
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -67,5 +67,8 @@ function xmldb_block_settings_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -132,5 +132,8 @@ function xmldb_block_tag_youtube_upgrade($oldversion) {
|
||||
upgrade_block_savepoint(true, 2021052501, 'tag_youtube', false);
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,5 +71,8 @@ function xmldb_block_timeline_upgrade($oldversion, $block) {
|
||||
upgrade_block_savepoint(true, 2022041901, 'timeline', false);
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -140,6 +140,13 @@ class managesubscriptions extends \moodleform {
|
||||
$errors['url'] = get_string('errorrequiredurlorfile', 'calendar');
|
||||
}
|
||||
|
||||
// Validate course/category event types (ensure appropriate field is also filled in).
|
||||
if ($eventtype === 'course' && empty($data['courseid'])) {
|
||||
$errors['courseid'] = get_string('selectacourse');
|
||||
} else if ($eventtype === 'category' && empty($data['categoryid'])) {
|
||||
$errors['categoryid'] = get_string('required');
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
@@ -908,15 +908,12 @@ abstract class base {
|
||||
'format' => $this->format,
|
||||
'sectionid' => $sectionid
|
||||
), '', 'id,name,value');
|
||||
$indexedrecords = [];
|
||||
foreach ($records as $record) {
|
||||
if (array_key_exists($record->name, $this->formatoptions[$sectionid])) {
|
||||
$value = $record->value;
|
||||
if ($value !== null && isset($options[$record->name]['type'])) {
|
||||
// This will convert string value to number if needed.
|
||||
$value = clean_param($value, $options[$record->name]['type']);
|
||||
}
|
||||
$this->formatoptions[$sectionid][$record->name] = $value;
|
||||
}
|
||||
$indexedrecords[$record->name] = $record->value;
|
||||
}
|
||||
foreach ($options as $optionname => $option) {
|
||||
contract_value($this->formatoptions[$sectionid], $indexedrecords, $option, $optionname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1011,7 +1008,7 @@ abstract class base {
|
||||
$data = array_intersect_key($rawdata, $allformatoptions);
|
||||
foreach ($data as $key => $value) {
|
||||
$option = $allformatoptions[$key] + ['type' => PARAM_RAW, 'element_type' => null, 'element_attributes' => [[]]];
|
||||
$data[$key] = clean_param($value, $option['type']);
|
||||
expand_value($data, $data, $option, $key);
|
||||
if ($option['element_type'] === 'select' && !array_key_exists($data[$key], $option['element_attributes'][0])) {
|
||||
// Value invalid for select element, skip.
|
||||
unset($data[$key]);
|
||||
@@ -1060,6 +1057,7 @@ abstract class base {
|
||||
if (array_key_exists('default', $option)) {
|
||||
$defaultoptions[$key] = $option['default'];
|
||||
}
|
||||
expand_value($defaultoptions, $defaultoptions, $option, $key);
|
||||
$cached[$key] = ($sectionid === 0 || !empty($option['cache']));
|
||||
}
|
||||
$records = $DB->get_records('course_format_options',
|
||||
|
||||
@@ -135,3 +135,67 @@ class format_site extends course_format {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 'Converts' a value from what is stored in the database into what is used by edit forms.
|
||||
*
|
||||
* @param array $dest The destination array
|
||||
* @param array $source The source array
|
||||
* @param array $option The definition structure of the option.
|
||||
* @param string $optionname The name of the option, as provided in the definition.
|
||||
*/
|
||||
function contract_value(array &$dest, array $source, array $option, string $optionname) : void {
|
||||
if (substr($optionname, -7) == '_editor') { // Suffix '_editor' indicates that the element is an editor.
|
||||
$name = substr($optionname, 0, -7);
|
||||
if (isset($source[$name])) {
|
||||
$dest[$optionname] = [
|
||||
'text' => clean_param_if_not_null($source[$name], $option['type'] ?? PARAM_RAW),
|
||||
'format' => clean_param_if_not_null($source[$name . 'format'], PARAM_INT),
|
||||
];
|
||||
}
|
||||
} else {
|
||||
if (isset($source[$optionname])) {
|
||||
$dest[$optionname] = clean_param_if_not_null($source[$optionname], $option['type'] ?? PARAM_RAW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans the given param, unless it is null.
|
||||
*
|
||||
* @param mixed $param The variable we are cleaning.
|
||||
* @param string $type Expected format of param after cleaning.
|
||||
* @return mixed Null if $param is null, otherwise the cleaned value.
|
||||
* @throws coding_exception
|
||||
*/
|
||||
function clean_param_if_not_null($param, string $type = PARAM_RAW) {
|
||||
if ($param === null) {
|
||||
return null;
|
||||
} else {
|
||||
return clean_param($param, $type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 'Converts' a value from what is used in edit forms into a value(s) to be stored in the database.
|
||||
*
|
||||
* @param array $dest The destination array
|
||||
* @param array $source The source array
|
||||
* @param array $option The definition structure of the option.
|
||||
* @param string $optionname The name of the option, as provided in the definition.
|
||||
*/
|
||||
function expand_value(array &$dest, array $source, array $option, string $optionname) : void {
|
||||
if (substr($optionname, -7) == '_editor') { // Suffix '_editor' indicates that the element is an editor.
|
||||
$name = substr($optionname, 0, -7);
|
||||
if (is_string($source[$optionname])) {
|
||||
$dest[$name] = clean_param($source[$optionname], $option['type'] ?? PARAM_RAW);
|
||||
$dest[$name . 'format'] = 1;
|
||||
} else {
|
||||
$dest[$name] = clean_param($source[$optionname]['text'], $option['type'] ?? PARAM_RAW);
|
||||
$dest[$name . 'format'] = clean_param($source[$optionname]['format'], PARAM_INT);
|
||||
}
|
||||
unset($dest[$optionname]);
|
||||
} else {
|
||||
$dest[$optionname] = clean_param($source[$optionname], $option['type'] ?? PARAM_RAW);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,35 @@ class base_test extends advanced_testcase {
|
||||
require_once($CFG->dirroot . '/course/format/tests/fixtures/format_theunittest_output_course_format_invalidoutput.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the save and load functionality.
|
||||
*
|
||||
* @author Jason den Dulk
|
||||
* @covers \core_courseformat
|
||||
*/
|
||||
public function test_courseformat_saveandload() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$courseformatoptiondata = (object) [
|
||||
"hideoddsections" => 1,
|
||||
'summary_editor' => [
|
||||
'text' => '<p>Somewhere over the rainbow</p><p>The <b>quick</b> brown fox jumpos over the lazy dog.</p>',
|
||||
'format' => 1
|
||||
]
|
||||
];
|
||||
$generator = $this->getDataGenerator();
|
||||
$course1 = $generator->create_course(array('format' => 'theunittest'));
|
||||
$this->assertEquals('theunittest', $course1->format);
|
||||
course_create_sections_if_missing($course1, array(0, 1));
|
||||
|
||||
$courseformat = course_get_format($course1);
|
||||
$courseformat->update_course_format_options($courseformatoptiondata);
|
||||
|
||||
$savedcourseformatoptiondata = $courseformat->get_format_options();
|
||||
|
||||
$this->assertEqualsCanonicalizing($courseformatoptiondata, (object) $savedcourseformatoptiondata);
|
||||
}
|
||||
|
||||
public function test_available_hook() {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
+9
-1
@@ -37,6 +37,10 @@ class format_theunittest extends core_courseformat\base {
|
||||
'default' => 0,
|
||||
'type' => PARAM_INT,
|
||||
),
|
||||
'summary_editor' => array(
|
||||
'default' => '',
|
||||
'type' => PARAM_RAW,
|
||||
),
|
||||
);
|
||||
}
|
||||
if ($foreditform && !isset($courseformatoptions['hideoddsections']['label'])) {
|
||||
@@ -51,6 +55,10 @@ class format_theunittest extends core_courseformat\base {
|
||||
'element_type' => 'select',
|
||||
'element_attributes' => array($sectionmenu),
|
||||
),
|
||||
'summary_editor' => array(
|
||||
'label' => 'Summary Text',
|
||||
'element_type' => 'editor',
|
||||
),
|
||||
);
|
||||
$courseformatoptions = array_merge_recursive($courseformatoptions, $courseformatoptionsedit);
|
||||
}
|
||||
@@ -74,4 +82,4 @@ class format_theunittest extends core_courseformat\base {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,5 +45,8 @@ function xmldb_format_topics_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,5 +45,8 @@ function xmldb_format_weeks_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+3
-2
@@ -391,12 +391,13 @@ function course_integrity_check($courseid, $rawmods = null, $sections = null, $f
|
||||
* and the value is a lang_string object with a human-readable string.
|
||||
*
|
||||
* @param bool $plural If true, the function returns the plural forms of the names.
|
||||
* @param bool $resetcache If true, the static cache will be reset
|
||||
* @return lang_string[] Localised human-readable names of all used modules.
|
||||
*/
|
||||
function get_module_types_names($plural = false) {
|
||||
function get_module_types_names($plural = false, $resetcache = false) {
|
||||
static $modnames = null;
|
||||
global $DB, $CFG;
|
||||
if ($modnames === null) {
|
||||
if ($modnames === null || $resetcache) {
|
||||
$modnames = array(0 => array(), 1 => array());
|
||||
if ($allmods = $DB->get_records("modules")) {
|
||||
foreach ($allmods as $mod) {
|
||||
|
||||
@@ -630,14 +630,6 @@ abstract class moodleform_mod extends moodleform {
|
||||
$mform->addHelpButton('cmidnumber', 'idnumbermod');
|
||||
}
|
||||
|
||||
if ($this->_features->groups) {
|
||||
$options = array(NOGROUPS => get_string('groupsnone'),
|
||||
SEPARATEGROUPS => get_string('groupsseparate'),
|
||||
VISIBLEGROUPS => get_string('groupsvisible'));
|
||||
$mform->addElement('select', 'groupmode', get_string('groupmode', 'group'), $options, NOGROUPS);
|
||||
$mform->addHelpButton('groupmode', 'groupmode', 'group');
|
||||
}
|
||||
|
||||
if ($CFG->downloadcoursecontentallowed) {
|
||||
$choices = [
|
||||
DOWNLOAD_COURSE_CONTENT_DISABLED => get_string('no'),
|
||||
@@ -654,6 +646,14 @@ abstract class moodleform_mod extends moodleform {
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_features->groups) {
|
||||
$options = array(NOGROUPS => get_string('groupsnone'),
|
||||
SEPARATEGROUPS => get_string('groupsseparate'),
|
||||
VISIBLEGROUPS => get_string('groupsvisible'));
|
||||
$mform->addElement('select', 'groupmode', get_string('groupmode', 'group'), $options, NOGROUPS);
|
||||
$mform->addHelpButton('groupmode', 'groupmode', 'group');
|
||||
}
|
||||
|
||||
if ($this->_features->groupings) {
|
||||
// Groupings selector - used to select grouping for groups in activity.
|
||||
$options = array();
|
||||
|
||||
@@ -26,6 +26,7 @@ global $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
|
||||
require_once($CFG->dirroot . '/course/format/tests/fixtures/format_theunittest.php');
|
||||
|
||||
/**
|
||||
* Course restore testcase.
|
||||
@@ -534,4 +535,49 @@ class restore_test extends \advanced_testcase {
|
||||
$this->assertEquals($chat2->chattime, $restoredchat2->chattime);
|
||||
$this->assertEquals($c2->startdate + 1 * WEEKSECS, $restoredchat2->chattime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests course restore with editor in course format.
|
||||
*
|
||||
* @author Matthew Hilton
|
||||
* @covers \core_courseformat
|
||||
*/
|
||||
public function test_restore_editor_courseformat() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Setup user with restore permissions.
|
||||
$dg = $this->getDataGenerator();
|
||||
$u1 = $dg->create_user();
|
||||
|
||||
$managers = get_archetype_roles('manager');
|
||||
$manager = array_shift($managers);
|
||||
$dg->role_assign($manager->id, $u1->id);
|
||||
|
||||
// Create a course with an editor item in the course format.
|
||||
$courseformatoptiondata = (object) [
|
||||
"hideoddsections" => 1,
|
||||
'summary_editor' => [
|
||||
'text' => '<p>Somewhere over the rainbow</p><p>The <b>quick</b> brown fox jumpos over the lazy dog.</p>',
|
||||
'format' => 1
|
||||
]
|
||||
];
|
||||
$course1 = $dg->create_course(['format' => 'theunittest']);
|
||||
$course2 = $dg->create_course(['format' => 'theunittest']);
|
||||
$this->assertEquals('theunittest', $course1->format);
|
||||
course_create_sections_if_missing($course1, array(0, 1));
|
||||
|
||||
// Set the course format.
|
||||
$courseformat = course_get_format($course1);
|
||||
$courseformat->update_course_format_options($courseformatoptiondata);
|
||||
|
||||
// Backup and restore the course.
|
||||
$backupid = $this->backup_course($course1->id);
|
||||
$this->restore_to_existing_course($backupid, $course2->id, $u1->id);
|
||||
|
||||
// Get the restored course format.
|
||||
$restoredformat = course_get_format($course2);
|
||||
$restoredformatoptions = $restoredformat->get_format_options();
|
||||
|
||||
$this->assertEqualsCanonicalizing($courseformatoptiondata, (object) $restoredformatoptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<?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/>.
|
||||
|
||||
namespace core_course;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/course/lib.php');
|
||||
require_once($CFG->dirroot . '/course/format/tests/fixtures/format_theunittest.php');
|
||||
require_once($CFG->dirroot . '/course/format/lib.php');
|
||||
|
||||
/**
|
||||
* Course format function unit tests
|
||||
*
|
||||
* @package core_course
|
||||
* @copyright 2021 Catalyst IT Pty Ltd
|
||||
* @author Jason den Dulk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class course_format_function_test extends \basic_testcase {
|
||||
|
||||
/**
|
||||
* Tests clean_param_if_not_null function
|
||||
* @covers ::clean_param_if_not_null
|
||||
*/
|
||||
public function test_clean_param_if_not_null() {
|
||||
$this->assertNull(clean_param_if_not_null(null));
|
||||
$n = '3x';
|
||||
$this->assertEquals(clean_param($n, PARAM_INT), clean_param_if_not_null($n, PARAM_INT));
|
||||
$this->assertEquals(clean_param($n, PARAM_RAW), clean_param_if_not_null($n, PARAM_RAW));
|
||||
$this->assertEquals(clean_param($n, PARAM_ALPHANUM), clean_param_if_not_null($n, PARAM_ALPHANUM));
|
||||
$this->assertEquals(clean_param($n, PARAM_ALPHA), clean_param_if_not_null($n, PARAM_ALPHA));
|
||||
$s = '<abc>xyz</abc>';
|
||||
$this->assertEquals(clean_param($s, PARAM_ALPHANUM), clean_param_if_not_null($s, PARAM_ALPHANUM));
|
||||
$this->assertEquals(clean_param($s, PARAM_RAW), clean_param_if_not_null($s, PARAM_RAW));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests contract_value function
|
||||
* @covers ::contract_value
|
||||
*/
|
||||
public function test_contract_value() {
|
||||
$input = [
|
||||
'abc' => '<p>All together Now</p>',
|
||||
'abcformat' => '1',
|
||||
'jolly' => 'Roger'
|
||||
];
|
||||
$expected = [
|
||||
'abc_editor' => [ 'text' => $input['abc'], 'format' => $input['abcformat'] ],
|
||||
'jolly' => $input['jolly'],
|
||||
];
|
||||
$defs = [
|
||||
'abc_editor' => [],
|
||||
'jolly' => [ 'type' => PARAM_ALPHA ],
|
||||
];
|
||||
$dest = [];
|
||||
|
||||
foreach ($defs as $name => $def) {
|
||||
contract_value($dest, $input, $def, $name);
|
||||
}
|
||||
|
||||
$this->assertEquals($expected, $dest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests expand_value function
|
||||
* @covers ::expand_value
|
||||
*/
|
||||
public function test_expand_value() {
|
||||
$input = [
|
||||
'abc_editor' => [ 'text' => '<p>All together Now</p>', 'format' => '1' ],
|
||||
'jolly' => 'Roger',
|
||||
];
|
||||
$expected = [
|
||||
'abc' => $input['abc_editor']['text'],
|
||||
'abcformat' => $input['abc_editor']['format'],
|
||||
'jolly' => $input['jolly'],
|
||||
];
|
||||
$defs = [
|
||||
'abc_editor' => [],
|
||||
'jolly' => [ 'type' => PARAM_ALPHA ],
|
||||
];
|
||||
$dest = [];
|
||||
|
||||
foreach ($defs as $name => $def) {
|
||||
expand_value($dest, $input, $def, $name);
|
||||
}
|
||||
|
||||
$this->assertEquals($expected, $dest);
|
||||
}
|
||||
}
|
||||
+1
-9
@@ -34,14 +34,6 @@ require_login();
|
||||
$context = \context_helper::instance_by_id($contextid);
|
||||
$PAGE->set_context($context);
|
||||
|
||||
if ($context->id === \context_user::instance($USER->id)->id) {
|
||||
$PAGE->set_blocks_editing_capability('moodle/my:manageblocks');
|
||||
}
|
||||
|
||||
if ($PAGE->user_allowed_editing()) {
|
||||
$USER->editing = $setmode;
|
||||
} else {
|
||||
\core\notification::add(get_string('cannotswitcheditmodeon', 'error'), \core\notification::ERROR);
|
||||
}
|
||||
$USER->editing = $setmode;
|
||||
|
||||
redirect($pageurl);
|
||||
|
||||
@@ -39,5 +39,8 @@ function xmldb_enrol_database_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -39,5 +39,8 @@ function xmldb_enrol_flatfile_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -39,5 +39,8 @@ function xmldb_enrol_guest_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,5 +45,8 @@ function xmldb_enrol_imsenterprise_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ class ags_info {
|
||||
* @throws \coding_exception if any of the scopes is invalid.
|
||||
*/
|
||||
private function validate_scopes(array $scopes): void {
|
||||
$validscopes = [
|
||||
$supportedscopes = [
|
||||
self::SCOPES_LINEITEM_READONLY,
|
||||
self::SCOPES_LINEITEM_MANAGE,
|
||||
self::SCOPES_RESULT_READONLY,
|
||||
@@ -96,17 +96,14 @@ class ags_info {
|
||||
if (!is_string($scope)) {
|
||||
throw new \coding_exception('Scope must be a string value');
|
||||
}
|
||||
$key = array_search($scope, $validscopes);
|
||||
if ($key === false) {
|
||||
throw new \coding_exception("Scope '{$scope}' is invalid.");
|
||||
}
|
||||
if ($key == 0) {
|
||||
$key = array_search($scope, $supportedscopes);
|
||||
if ($key === 0) {
|
||||
$this->lineitemscopes[] = self::SCOPES_LINEITEM_READONLY;
|
||||
} else if ($key == 1) {
|
||||
} else if ($key === 1) {
|
||||
$this->lineitemscopes[] = self::SCOPES_LINEITEM_MANAGE;
|
||||
} else if ($key == 2) {
|
||||
} else if ($key === 2) {
|
||||
$this->resultscope = self::SCOPES_RESULT_READONLY;
|
||||
} else if ($key == 3) {
|
||||
} else if ($key === 3) {
|
||||
$this->scorescope = self::SCOPES_SCORES_POST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,5 +456,8 @@ function xmldb_enrol_lti_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2022031402, 'enrol', 'lti');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ $string['deploymentdeleteconfirm'] = 'Warning: Deleting a deployment will result
|
||||
$string['deploymentdeletenotice'] = 'Deployment deleted';
|
||||
$string['deploymentid'] = 'Deployment ID';
|
||||
$string['deployments'] = 'Deployments';
|
||||
$string['deploymentsinfo'] = 'A deployment ID will be generated by the platform when the tool is made available in a context. This may occur at the time of registration, or may occur later, when the tool is made available to a specific course or category. The Deployment ID must be entered here before launches from that tool deployment are permitted.';
|
||||
$string['deploymentsinfo'] = 'A deployment ID is generated by the platform when the tool is made available in a context. This may occur at the time of registration, or later, when the tool is made available to a specific course or category. The deployment ID must be entered here before launches from the tool deployment are permitted.';
|
||||
$string['details'] = 'Details';
|
||||
$string['editplatformdetails'] = 'Edit platform details';
|
||||
$string['endpointltiversionnotice'] = 'The tool endpoints below are for manual LTI 1.3 setup only. For earlier versions (1.1/2.0), details for consumers can be found on the \'Published as LTI tools\' page, accessible via course navigation.';
|
||||
@@ -114,7 +114,7 @@ $string['publishedcontent_help'] = 'A published resource or activity can be used
|
||||
$string['platformdetails'] = 'Platform details';
|
||||
$string['platformdetailsinfo'] = 'Once the tool has been set up in the platform, details from the platform must be recorded here to complete the registration.
|
||||
<ul>
|
||||
<li>For dynamic registrations, this information will have been set automatically and no further changes are required</li>
|
||||
<li>For dynamic registrations, this information will have been set automatically and no further changes are required.</li>
|
||||
<li>For manual registrations, this information must be manually copied from the platform.</li>
|
||||
</ul>';
|
||||
$string['pluginname'] = 'Publish as LTI tool';
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/* enrol_lti styles */
|
||||
|
||||
#registration-tab-content .input-group-append a.btn {
|
||||
#registration-tab-content .input-group-append button.btn {
|
||||
border: solid 1px #8f959e;
|
||||
}
|
||||
form#auto_submit {
|
||||
display: none;
|
||||
}
|
||||
#registration-tab-content .input-group-append a.btn span.pix {
|
||||
#registration-tab-content .input-group-append button.btn span.pix {
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
<table class="admintable generaltable">
|
||||
<thead></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<tr class="d-flex">
|
||||
<th class="col-3" id="lti_tool_endpoint_name_{{id}}">
|
||||
<label for="lti_tool_endpoint_url_{{id}}">{{name}}</label>
|
||||
</th>
|
||||
@@ -70,9 +70,7 @@
|
||||
<div class="input-group col-md-6 ml-0 pl-0">
|
||||
<input class="form-control" type="text" value="{{url}}" aria-label="{{url}}" id="lti_tool_endpoint_url_{{id}}" readonly>
|
||||
<div class="input-group-append">
|
||||
<a class="btn btn-secondary"
|
||||
href="#"
|
||||
role="button"
|
||||
<button class="btn btn-secondary"
|
||||
aria-label="{{#str}} copytoclipboard, enrol_lti {{/str}}"
|
||||
data-action="copytoclipboard"
|
||||
data-clipboard-success-message="{{#str}}copiedtoclipboard, enrol_lti, {{name}}{{/str}}"
|
||||
@@ -80,7 +78,7 @@
|
||||
id="{{id}}"
|
||||
title="{{#str}}copytoclipboard, enrol_lti{{/str}}">
|
||||
<span class="pix">{{#pix}} t/clipboard, core {{/pix}}</span>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@@ -95,14 +93,14 @@
|
||||
<div id="lti_tool_endpoints">
|
||||
<table class="admintable generaltable">
|
||||
<thead>
|
||||
<tr>
|
||||
<tr class="d-flex">
|
||||
<th>{{#str}}name, core{{/str}}</th>
|
||||
<th>{{#str}}url, core{{/str}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#manual_registration_urls}}
|
||||
<tr>
|
||||
<tr class="d-flex">
|
||||
<th class="col-3" id="lti_tool_endpoint_name_{{id}}">
|
||||
<label for="lti_tool_endpoint_url_{{id}}">{{name}}</label>
|
||||
</th>
|
||||
@@ -110,9 +108,7 @@
|
||||
<div class="input-group col-md-6 ml-0 pl-0">
|
||||
<input class="form-control" type="text" value="{{url}}" aria-label="{{url}}" id="lti_tool_endpoint_url_{{id}}" readonly>
|
||||
<div class="input-group-append">
|
||||
<a class="btn btn-secondary"
|
||||
href="#"
|
||||
role="button"
|
||||
<button class="btn btn-secondary"
|
||||
aria-label="{{#str}} copytoclipboard, enrol_lti {{/str}}"
|
||||
data-action="copytoclipboard"
|
||||
data-clipboard-success-message="{{#str}}copiedtoclipboard, enrol_lti, {{name}}{{/str}}"
|
||||
@@ -120,7 +116,7 @@
|
||||
id="{{id}}"
|
||||
title="{{#str}}copytoclipboard, enrol_lti{{/str}}">
|
||||
<span class="pix">{{#pix}} t/clipboard, core {{/pix}}</span>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -198,18 +198,18 @@ Feature: Register a platform with the tool
|
||||
And the "value" attribute of "Initiate login URL" "field" should contain "enrol/lti/login.php"
|
||||
And the "value" attribute of "JWKS URL" "field" should contain "enrol/lti/jwks.php"
|
||||
And the "value" attribute of "Deep linking URL" "field" should contain "enrol/lti/launch_deeplink.php"
|
||||
And "Copy to clipboard" "link" should exist in the "Registration URL" "table_row"
|
||||
And "Copy to clipboard" "link" should exist in the "Tool URL" "table_row"
|
||||
And "Copy to clipboard" "link" should exist in the "Initiate login URL" "table_row"
|
||||
And "Copy to clipboard" "link" should exist in the "JWKS URL" "table_row"
|
||||
And "Copy to clipboard" "link" should exist in the "Deep linking URL" "table_row"
|
||||
When I click on "Copy to clipboard" "link" in the "Registration URL" "table_row"
|
||||
And "Copy to clipboard" "button" should exist in the "Registration URL" "table_row"
|
||||
And "Copy to clipboard" "button" should exist in the "Tool URL" "table_row"
|
||||
And "Copy to clipboard" "button" should exist in the "Initiate login URL" "table_row"
|
||||
And "Copy to clipboard" "button" should exist in the "JWKS URL" "table_row"
|
||||
And "Copy to clipboard" "button" should exist in the "Deep linking URL" "table_row"
|
||||
When I click on "Copy to clipboard" "button" in the "Registration URL" "table_row"
|
||||
Then I should see "Registration URL copied to clipboard"
|
||||
And I click on "Copy to clipboard" "link" in the "Tool URL" "table_row"
|
||||
And I click on "Copy to clipboard" "button" in the "Tool URL" "table_row"
|
||||
And I should see "Tool URL copied to clipboard"
|
||||
And I click on "Copy to clipboard" "link" in the "Initiate login URL" "table_row"
|
||||
And I click on "Copy to clipboard" "button" in the "Initiate login URL" "table_row"
|
||||
And I should see "Initiate login URL copied to clipboard"
|
||||
And I click on "Copy to clipboard" "link" in the "JWKS URL" "table_row"
|
||||
And I click on "Copy to clipboard" "button" in the "JWKS URL" "table_row"
|
||||
And I should see "JWKS URL copied to clipboard"
|
||||
And I click on "Copy to clipboard" "link" in the "Deep linking URL" "table_row"
|
||||
And I click on "Copy to clipboard" "button" in the "Deep linking URL" "table_row"
|
||||
And I should see "Deep linking URL copied to clipboard"
|
||||
|
||||
@@ -42,7 +42,12 @@ class ags_info_test extends \advanced_testcase {
|
||||
$agsinfo = ags_info::create(...array_values($args));
|
||||
$this->assertEquals($args['lineitemsurl'], $agsinfo->get_lineitemsurl());
|
||||
$this->assertEquals($args['lineitemurl'], $agsinfo->get_lineitemurl());
|
||||
$this->assertEquals($args['scopes'], $agsinfo->get_scopes());
|
||||
if (isset($expectations['scopes'])) {
|
||||
$this->assertEquals($expectations['scopes'], $agsinfo->get_scopes());
|
||||
} else {
|
||||
$this->assertEquals($args['scopes'], $agsinfo->get_scopes());
|
||||
}
|
||||
|
||||
$this->assertEquals($expectations['lineitemscope'], $agsinfo->get_lineitemscope());
|
||||
$this->assertEquals($expectations['scorescope'], $agsinfo->get_scorescope());
|
||||
$this->assertEquals($expectations['resultscope'], $agsinfo->get_resultscope());
|
||||
@@ -239,7 +244,7 @@ class ags_info_test extends \advanced_testcase {
|
||||
'exceptionmessage' => 'Scope must be a string value'
|
||||
]
|
||||
],
|
||||
'Both lineitems and lineitem URL provided with invalid scopes' => [
|
||||
'Both lineitems and lineitem URL provided with unsupported scopes' => [
|
||||
'args' => [
|
||||
'lineitemsurl' => new \moodle_url('https://platform.example.org/10/lineitems'),
|
||||
'lineitemurl' => new \moodle_url('https://platform.example.org/10/lineitems/4/lineitem'),
|
||||
@@ -248,13 +253,23 @@ class ags_info_test extends \advanced_testcase {
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/score',
|
||||
'https://example.com/invalid/scope'
|
||||
'https://example.com/unsupported/scope'
|
||||
]
|
||||
],
|
||||
'expectations' => [
|
||||
'valid' => false,
|
||||
'exception' => \coding_exception::class,
|
||||
'exceptionmessage' => "Scope 'https://example.com/invalid/scope' is invalid."
|
||||
'valid' => true,
|
||||
'scopes' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/score',
|
||||
],
|
||||
'lineitemscope' => [
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem',
|
||||
'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly'
|
||||
],
|
||||
'resultscope' => 'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly',
|
||||
'scorescope' => 'https://purl.imsglobal.org/spec/lti-ags/scope/score'
|
||||
]
|
||||
],
|
||||
'Both lineitems and lineitem URL provided with invalid scope types' => [
|
||||
|
||||
@@ -39,5 +39,8 @@ function xmldb_enrol_manual_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -39,5 +39,8 @@ function xmldb_enrol_mnet_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -57,5 +57,8 @@ function xmldb_enrol_paypal_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -39,5 +39,8 @@ function xmldb_enrol_self_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -60,5 +60,8 @@ function xmldb_filter_displayh5p_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -67,5 +67,8 @@ function xmldb_filter_mathjaxloader_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2021052501, 'filter', 'mathjaxloader');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_filter_mediaplugin_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_filter_tex_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -49,5 +49,8 @@ function xmldb_gradingform_guide_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,5 +45,8 @@ function xmldb_gradingform_rubric_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -46,5 +46,8 @@ function xmldb_gradereport_history_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_gradereport_overview_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,5 +41,8 @@ function xmldb_gradereport_user_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.9.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -38,3 +38,5 @@ $string['clitypevaluedefault'] = 'တန်ဖိုး ထည့်သွင်
|
||||
$string['cliunknowoption'] = 'အသိအမှတ် မပြုထားသော ရွေးချယ်မှုများ :
|
||||
{$a}
|
||||
ကျေးဇူးပြု၍ -- အကူအညီရယူရန် ကိုနှိပ်ပါ။';
|
||||
$string['environmentrequireinstall'] = 'ထည့်သွင်းပြီး အသုံးပြုခွင့်ဖွင့်ပါ';
|
||||
$string['environmentrequireversion'] = 'ဗားရှင်း{$a->needed} ကို လိုအပ်ပြီး သင်သည် {$a->current} ကိုအသုံးပြုနေပါသည်';
|
||||
|
||||
@@ -101,6 +101,8 @@ $string['norecentaccessesinfomessage'] = 'Hi {$a->userfirstname},
|
||||
<p>A number of students in {$a->coursename} have not accessed the course recently.</p>';
|
||||
$string['noteachinginfomessage'] = 'Hi {$a->userfirstname},
|
||||
<p>Courses with start dates in the next week have been identified as having no teacher or student enrolments.</p>';
|
||||
$string['participants:perpage'] = 'Number of participants per page';
|
||||
$string['participants:perpage_help'] = 'Specify the number of participants that are shown per page';
|
||||
$string['participantsnavigation'] = 'Participants tertiary navigation.';
|
||||
$string['privacy:perpage'] = 'The number of courses to show per page.';
|
||||
$string['privacy:completionpath'] = 'Course completion';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user