Merge branch 'MDL-69065-master' of git://github.com/peterRd/moodle
authorJake Dallimore <jake@moodle.com>
Wed, 24 Jun 2020 01:30:31 +0000 (09:30 +0800)
committerJake Dallimore <jake@moodle.com>
Wed, 24 Jun 2020 02:11:08 +0000 (10:11 +0800)
168 files changed:
admin/settings/plugins.php
admin/tool/behat/cli/util_single_run.php
admin/tool/cohortroles/db/upgrade.php
admin/tool/customlang/db/upgrade.php
admin/tool/dataprivacy/db/upgrade.php
admin/tool/dataprivacy/version.php
admin/tool/log/db/upgrade.php
admin/tool/log/store/database/db/upgrade.php
admin/tool/log/store/standard/db/upgrade.php
admin/tool/mobile/db/upgrade.php
admin/tool/monitor/db/upgrade.php
admin/tool/moodlenet/db/upgrade.php
admin/tool/policy/db/upgrade.php
admin/tool/task/renderer.php
admin/tool/task/tests/behat/manage_tasks.feature
admin/tool/usertours/db/upgrade.php
auth/cas/db/upgrade.php
auth/db/db/upgrade.php
auth/email/db/upgrade.php
auth/ldap/db/upgrade.php
auth/manual/db/upgrade.php
auth/mnet/db/upgrade.php
auth/none/db/upgrade.php
auth/oauth2/db/upgrade.php
auth/shibboleth/db/upgrade.php
backup/backup.class.php
blocks/activity_results/block_activity_results.php
blocks/activity_results/styles.css
blocks/badges/db/upgrade.php
blocks/calendar_month/db/upgrade.php
blocks/calendar_upcoming/db/upgrade.php
blocks/completionstatus/db/upgrade.php
blocks/course_summary/db/upgrade.php
blocks/html/db/upgrade.php
blocks/myoverview/db/upgrade.php
blocks/navigation/db/upgrade.php
blocks/quiz_results/db/upgrade.php
blocks/recent_activity/db/upgrade.php
blocks/recentlyaccesseditems/db/upgrade.php
blocks/rss_client/db/upgrade.php
blocks/section_links/db/upgrade.php
blocks/selfcompletion/db/upgrade.php
blocks/settings/db/upgrade.php
contentbank/amd/build/actions.min.js
contentbank/amd/build/actions.min.js.map
contentbank/amd/src/actions.js
contentbank/classes/content.php
contentbank/index.php
contentbank/upload.php
contentbank/view.php
course/format/topics/db/upgrade.php
course/format/weeks/db/upgrade.php
enrol/database/db/upgrade.php
enrol/flatfile/db/upgrade.php
enrol/guest/db/upgrade.php
enrol/imsenterprise/db/upgrade.php
enrol/lti/db/upgrade.php
enrol/manual/db/upgrade.php
enrol/mnet/db/upgrade.php
enrol/paypal/db/upgrade.php
enrol/self/db/upgrade.php
filter/displayh5p/db/upgrade.php
filter/mathjaxloader/db/upgrade.php
filter/mediaplugin/db/upgrade.php
filter/tex/db/upgrade.php
grade/grading/form/guide/db/upgrade.php
grade/grading/form/rubric/db/upgrade.php
grade/report/history/db/upgrade.php
grade/report/overview/db/upgrade.php
grade/report/user/db/upgrade.php
install/lang/de/install.php
lang/en/moodle.php
lib/antivirus/clamav/db/upgrade.php
lib/behat/classes/util.php
lib/db/upgrade.php
lib/editor/atto/db/upgrade.php
lib/editor/atto/plugins/equation/db/upgrade.php
lib/editor/atto/plugins/recordrtc/yui/build/moodle-atto_recordrtc-button/moodle-atto_recordrtc-button-debug.js
lib/editor/atto/plugins/recordrtc/yui/build/moodle-atto_recordrtc-button/moodle-atto_recordrtc-button-min.js
lib/editor/atto/plugins/recordrtc/yui/build/moodle-atto_recordrtc-button/moodle-atto_recordrtc-button.js
lib/editor/atto/plugins/recordrtc/yui/src/button/js/button.js
lib/editor/tinymce/db/upgrade.php
lib/editor/tinymce/plugins/spellchecker/db/upgrade.php
lib/externallib.php
lib/form/dndupload.js
lib/outputlib.php
lib/questionlib.php
lib/templates/paged_content.mustache
lib/templates/paged_content_paging_bar.mustache
lib/templates/paged_content_paging_bar_item.mustache
lib/tests/behat/behat_hooks.php
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue.js
lib/yui/src/chooserdialogue/js/chooserdialogue.js
message/output/email/db/upgrade.php
message/output/jabber/db/upgrade.php
message/output/popup/db/upgrade.php
mod/assign/db/upgrade.php
mod/assign/feedback/comments/db/upgrade.php
mod/assign/feedback/editpdf/db/upgrade.php
mod/assign/feedback/file/db/upgrade.php
mod/assign/submission/comments/db/upgrade.php
mod/assign/submission/file/db/upgrade.php
mod/assign/submission/file/locallib.php
mod/assign/submission/onlinetext/db/upgrade.php
mod/assignment/db/upgrade.php
mod/book/db/upgrade.php
mod/chat/db/upgrade.php
mod/choice/db/upgrade.php
mod/data/db/upgrade.php
mod/feedback/db/upgrade.php
mod/folder/db/upgrade.php
mod/forum/db/upgrade.php
mod/glossary/db/upgrade.php
mod/h5pactivity/db/upgrade.php
mod/imscp/db/upgrade.php
mod/label/db/upgrade.php
mod/lesson/db/upgrade.php
mod/lti/db/upgrade.php
mod/lti/service/gradebookservices/db/upgrade.php
mod/page/db/upgrade.php
mod/quiz/accessrule/seb/classes/privacy/provider.php
mod/quiz/accessrule/seb/db/upgrade.php
mod/quiz/accessrule/seb/tests/privacy_provider_test.php
mod/quiz/classes/event/attempt_regraded.php [new file with mode: 0644]
mod/quiz/db/upgrade.php
mod/quiz/lang/en/quiz.php
mod/quiz/report/overview/db/upgrade.php
mod/quiz/report/overview/report.php
mod/quiz/report/statistics/db/upgrade.php
mod/quiz/tests/events_test.php
mod/resource/db/upgrade.php
mod/scorm/db/upgrade.php
mod/survey/db/upgrade.php
mod/url/db/upgrade.php
mod/wiki/db/upgrade.php
mod/workshop/db/upgrade.php
mod/workshop/form/accumulative/db/upgrade.php
mod/workshop/form/comments/db/upgrade.php
mod/workshop/form/numerrors/db/upgrade.php
mod/workshop/form/rubric/db/upgrade.php
portfolio/boxnet/db/upgrade.php
portfolio/googledocs/db/upgrade.php
portfolio/picasa/db/upgrade.php
question/behaviour/manualgraded/db/upgrade.php
question/type/calculated/db/upgrade.php
question/type/ddmarker/db/upgrade.php
question/type/essay/db/upgrade.php
question/type/match/db/upgrade.php
question/type/multianswer/db/upgrade.php
question/type/multichoice/db/upgrade.php
question/type/numerical/db/upgrade.php
question/type/random/db/upgrade.php
question/type/randomsamatch/db/upgrade.php
question/type/shortanswer/db/upgrade.php
repository/boxnet/db/upgrade.php
repository/dropbox/db/upgrade.php
repository/flickr/db/upgrade.php
repository/googledocs/db/upgrade.php
repository/onedrive/db/upgrade.php
repository/picasa/db/upgrade.php
theme/boost/scss/moodle/core.scss
theme/boost/style/moodle.css
theme/classic/style/moodle.css
user/classes/table/participants_search.php
user/tests/table/participants_search_test.php
version.php

index 4eb6ec4..1942627 100644 (file)
@@ -645,14 +645,14 @@ if ($hassiteconfig) {
 
 // Content bank content types.
 if ($hassiteconfig) {
-    $ADMIN->add('modules', new admin_category('contenbanksettings', new lang_string('contentbank')));
+    $ADMIN->add('modules', new admin_category('contentbanksettings', new lang_string('contentbank')));
     $temp = new admin_settingpage('managecontentbanktypes', new lang_string('managecontentbanktypes'));
     $temp->add(new admin_setting_managecontentbankcontenttypes());
-    $ADMIN->add('contenbanksettings', $temp);
+    $ADMIN->add('contentbanksettings', $temp);
     $plugins = core_plugin_manager::instance()->get_plugins_of_type('contenttype');
     foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\contentbank $plugin */
-        $plugin->load_settings($ADMIN, 'contenbanksettings', $hassiteconfig);
+        $plugin->load_settings($ADMIN, 'contentbanksettings', $hassiteconfig);
     }
 }
 
index 967fde3..f0a3650 100644 (file)
@@ -164,6 +164,8 @@ if ($options['install']) {
         mtrace("Acceptance tests site installed");
     }
 
+    // Note: Do not build the themes here. This is done during the 'enable' stage.
+
 } else if ($options['drop']) {
     // Ensure no tests are running.
     test_lock::acquire('behat');
@@ -182,6 +184,10 @@ if ($options['install']) {
     // Enable test mode.
     behat_util::start_test_mode($options['add-core-features-to-theme'], $options['optimize-runs'], $parallel, $run);
 
+    // Themes are only built in the 'enable' command.
+    behat_util::build_themes();
+    mtrace("Testing environment themes built");
+
     // This is only displayed once for parallel install.
     if (empty($run)) {
         // Notify user that 2.5 profile has been converted to 3.5.
index fd228cc..7984d25 100644 (file)
@@ -41,5 +41,8 @@ function xmldb_tool_cohortroles_upgrade($oldversion) {
         upgrade_plugin_savepoint(true, 2020020600, 'tool', 'cohortroles');
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index cf935d8..42d0133 100644 (file)
@@ -41,5 +41,8 @@ function xmldb_tool_customlang_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index e90e82a..30a9881 100644 (file)
@@ -322,10 +322,29 @@ function xmldb_tool_dataprivacy_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
-    if ($oldversion < 2019121700) {
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
 
-        // Define field systemapproved to be added to tool_dataprivacy_request.
+    if ($oldversion < 2020061501) {
+
+        // Define field commentsformat to be added to tool_dataprivacy_request.
         $table = new xmldb_table('tool_dataprivacy_request');
+        $field = new xmldb_field('commentsformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'comments');
+
+        // Conditionally launch add field commentsformat.
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        // Define field dpocommentformat to be added to tool_dataprivacy_request.
+        $field = new xmldb_field('dpocommentformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'dpocomment');
+
+        // Conditionally launch add field dpocommentformat.
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        // Define field systemapproved to be added to tool_dataprivacy_request.
         $field = new xmldb_field('systemapproved', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'dpocommentformat');
 
         // Conditionally launch add field systemapproved.
@@ -334,7 +353,7 @@ function xmldb_tool_dataprivacy_upgrade($oldversion) {
         }
 
         // Dataprivacy savepoint reached.
-        upgrade_plugin_savepoint(true, 2019121700, 'tool', 'dataprivacy');
+        upgrade_plugin_savepoint(true, 2020061501, 'tool', 'dataprivacy');
     }
 
     return true;
index 7925e88..1df48bc 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version   = 2020061500;
+$plugin->version   = 2020061501;
 $plugin->requires  = 2020060900;
 $plugin->component = 'tool_dataprivacy';
index 3a8e797..6fffa79 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_tool_log_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index ec36ccf..1b9aef2 100644 (file)
@@ -46,5 +46,8 @@ function xmldb_logstore_database_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 5a9a7e0..25ec6eb 100644 (file)
@@ -46,5 +46,8 @@ function xmldb_logstore_standard_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index a54e9ef..ace131e 100644 (file)
@@ -48,5 +48,8 @@ function xmldb_tool_mobile_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index b8c93ac..d8c4fd2 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_tool_monitor_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index d366423..0442276 100644 (file)
@@ -102,5 +102,8 @@ function xmldb_tool_moodlenet_upgrade(int $oldversion) {
         upgrade_plugin_savepoint(true, 2020061502, 'tool', 'moodlenet');
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 54833be..4da195d 100644 (file)
@@ -69,5 +69,8 @@ function xmldb_tool_policy_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index a003eab..ec0bb0c 100644 (file)
@@ -48,6 +48,7 @@ class tool_task_renderer extends plugin_renderer_base {
         $showloglink = \core\task\logmanager::has_log_report();
 
         $table = new html_table();
+        $table->caption = get_string('scheduledtasks', 'tool_task');
         $table->head = [
             get_string('name'),
             get_string('component', 'tool_task'),
@@ -180,7 +181,7 @@ class tool_task_renderer extends plugin_renderer_base {
         $plugininfo->init_display_name();
 
         $componentname = $plugininfo->displayname;
-        if (!$plugininfo->is_enabled()) {
+        if ($plugininfo->is_enabled() === false) {
             $componentname .= ' ' . html_writer::span(
                             get_string('disabled', 'tool_task'), 'badge badge-secondary');
         }
index 160451d..dd27d85 100644 (file)
@@ -65,3 +65,9 @@ Feature: Manage scheduled tasks
       | Name               | Component    | Minute | Hour | Day | Day of week | Month |
       | Log table cleanup  | Standard log | */5    | 1    | 2   | 4           | 3     |
     And I should see "Log table cleanup" in the "tr.table-primary" "css_element"
+
+  Scenario: Disabled plugin's tasks are labelled as disabled too
+    When "CAS users sync job \auth_cas\task\sync_task" row "Next run" column of "Scheduled tasks" table should contain "Plugin disabled"
+    Then "CAS users sync job \auth_cas\task\sync_task" row "Component" column of "Scheduled tasks" table should contain "Disabled"
+    And "Background processing for scheduled allocation \workshopallocation_scheduled\task\cron_task" row "Next run" column of "Scheduled tasks" table should not contain "Plugin disabled"
+    And "Background processing for scheduled allocation \workshopallocation_scheduled\task\cron_task" row "Component" column of "Scheduled tasks" table should not contain "Disabled"
index dce812b..6769e01 100644 (file)
@@ -54,5 +54,8 @@ function xmldb_tool_usertours_upgrade($oldversion) {
         upgrade_plugin_savepoint(true, 2020061501, 'tool', 'usertours');
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 8b2d14b..34f5364 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_auth_cas_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 3a0691c..3fdd848 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_auth_db_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 3d2b42d..c641c84 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_auth_email_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index abb56a9..e40963a 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_auth_ldap_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 0795fc2..ced0da1 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_auth_manual_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index fcb489d..f9fabc1 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_auth_mnet_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index ebf92f3..1d17e36 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_auth_none_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 8e8fc1a..d9d50b8 100644 (file)
@@ -81,5 +81,8 @@ function xmldb_auth_oauth2_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 54d240e..b16539d 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_auth_shibboleth_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index a80f303..54fca21 100644 (file)
@@ -160,7 +160,7 @@ abstract class backup implements checksumable {
     /**
      * Usually same than major release zero version, mainly for informative/historic purposes.
      */
-    const RELEASE = '3.9';
+    const RELEASE = '4.0';
 
     /**
      * Cipher to be used in backup and restore operations.
index f62b430..d60e583 100644 (file)
@@ -342,13 +342,13 @@ class block_activity_results extends block_base {
 
                 $rank = 0;
                 if (!empty($best)) {
-                    $this->content->text .= '<table class="grades"><caption>';
+                    $this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
                     if ($numbest == 1) {
                         $this->content->text .= get_string('bestgroupgrade', 'block_activity_results');
                     } else {
                         $this->content->text .= get_string('bestgroupgrades', 'block_activity_results', $numbest);
                     }
-                    $this->content->text .= '</caption><colgroup class="number" />';
+                    $this->content->text .= '</h6></caption><colgroup class="number" />';
                     $this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
                     foreach ($best as $groupid => $averagegrade) {
                         switch ($nameformat) {
@@ -398,13 +398,13 @@ class block_activity_results extends block_base {
                 $rank = 0;
                 if (!empty($worst)) {
                     $worst = array_reverse($worst, true);
-                    $this->content->text .= '<table class="grades"><caption>';
+                    $this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
                     if ($numworst == 1) {
                         $this->content->text .= get_string('worstgroupgrade', 'block_activity_results');
                     } else {
                         $this->content->text .= get_string('worstgroupgrades', 'block_activity_results', $numworst);
                     }
-                    $this->content->text .= '</caption><colgroup class="number" />';
+                    $this->content->text .= '</h6></caption><colgroup class="number" />';
                     $this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
                     foreach ($worst as $groupid => $averagegrade) {
                         switch ($nameformat) {
@@ -529,13 +529,13 @@ class block_activity_results extends block_base {
 
                 $rank = 0;
                 if (!empty($best)) {
-                    $this->content->text .= '<table class="grades"><caption>';
+                    $this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
                     if ($numbest == 1) {
                         $this->content->text .= get_string('bestgrade', 'block_activity_results');
                     } else {
                         $this->content->text .= get_string('bestgrades', 'block_activity_results', $numbest);
                     }
-                    $this->content->text .= '</caption><colgroup class="number" />';
+                    $this->content->text .= '</h6></caption><colgroup class="number" />';
                     $this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
                     foreach ($best as $userid => $gradeid) {
                         switch ($nameformat) {
@@ -592,13 +592,13 @@ class block_activity_results extends block_base {
                 $rank = 0;
                 if (!empty($worst)) {
                     $worst = array_reverse($worst, true);
-                    $this->content->text .= '<table class="grades"><caption>';
+                    $this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
                     if ($numbest == 1) {
                         $this->content->text .= get_string('worstgrade', 'block_activity_results');
                     } else {
                         $this->content->text .= get_string('worstgrades', 'block_activity_results', $numworst);
                     }
-                    $this->content->text .= '</caption><colgroup class="number" />';
+                    $this->content->text .= '</h6></caption><colgroup class="number" />';
                     $this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
                     foreach ($worst as $userid => $gradeid) {
                         switch ($nameformat) {
@@ -678,17 +678,17 @@ class block_activity_results extends block_base {
     }
 
     /**
-     * Generates the Link to the activity module when displaed outside of the module
+     * Generates the Link to the activity module when displayed outside of the module.
      * @param stdclass $activity
      * @param stdclass $cm
      * @return string
      */
     private function activity_link($activity, $cm) {
 
-        $o = html_writer::start_tag('h3');
+        $o = html_writer::start_tag('h5');
         $o .= html_writer::link(new moodle_url('/mod/'.$activity->itemmodule.'/view.php',
         array('id' => $cm->id)), format_string(($activity->itemname), true, ['context' => context_module::instance($cm->id)]));
-        $o .= html_writer::end_tag('h3');
+        $o .= html_writer::end_tag('h5');
         return $o;
     }
 
index 83ffd7d..119ebcd 100644 (file)
@@ -21,8 +21,3 @@
 .block_activity_results table.grades .grade {
     text-align: right;
 }
-
-.block_activity_results table.grades caption {
-    font-weight: bold;
-    font-size: 18px;
-}
index c7ae451..6a1cc4d 100644 (file)
@@ -57,5 +57,8 @@ function xmldb_block_badges_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index b97b4ff..ce70f8b 100644 (file)
@@ -57,5 +57,8 @@ function xmldb_block_calendar_month_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index f99b9ea..3c6cee0 100644 (file)
@@ -57,5 +57,8 @@ function xmldb_block_calendar_upcoming_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index b30d8f2..433fb4f 100644 (file)
@@ -60,5 +60,8 @@ function xmldb_block_completionstatus_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 18a78cf..7fea414 100644 (file)
@@ -60,5 +60,8 @@ function xmldb_block_course_summary_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 52176df..e228620 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_block_html_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index d9bccdd..8239818 100644 (file)
@@ -78,5 +78,8 @@ function xmldb_block_myoverview_upgrade($oldversion) {
         upgrade_block_savepoint(true, 2019111801, 'myoverview', false);
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index c8ca634..c7ffa31 100644 (file)
@@ -67,5 +67,8 @@ function xmldb_block_navigation_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 7b7aab0..0a7e0f9 100644 (file)
@@ -57,5 +57,8 @@ function xmldb_block_quiz_results_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 84dfeab..fe49827 100644 (file)
@@ -59,5 +59,8 @@ function xmldb_block_recent_activity_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 4e15552..0a178d3 100644 (file)
@@ -72,5 +72,8 @@ function xmldb_block_recentlyaccesseditems_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 844c8c6..736a67c 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_block_rss_client_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index d14edc2..9c04b34 100644 (file)
@@ -61,5 +61,8 @@ function xmldb_block_section_links_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index ad3b539..c520cbf 100644 (file)
@@ -60,5 +60,8 @@ function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index afe0e14..38595ab 100644 (file)
@@ -67,5 +67,8 @@ function xmldb_block_settings_upgrade($oldversion, $block) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 4d78f53..237c664 100644 (file)
Binary files a/contentbank/amd/build/actions.min.js and b/contentbank/amd/build/actions.min.js differ
index 6e5344e..79956ea 100644 (file)
Binary files a/contentbank/amd/build/actions.min.js.map and b/contentbank/amd/build/actions.min.js.map differ
index 561cb99..1776292 100644 (file)
@@ -176,10 +176,10 @@ function($, Ajax, Notification, Str, Templates, Url, ModalFactory, ModalEvents)
         var requestType = 'success';
         Ajax.call([request])[0].then(function(data) {
             if (data.result) {
-                return Str.get_string('contentdeleted', 'core_contentbank');
+                return 'contentdeleted';
             }
             requestType = 'error';
-            return Str.get_string('contentnotdeleted', 'core_contentbank');
+            return 'contentnotdeleted';
 
         }).done(function(message) {
             var params = {
@@ -212,10 +212,10 @@ function($, Ajax, Notification, Str, Templates, Url, ModalFactory, ModalEvents)
         var requestType = 'success';
         Ajax.call([request])[0].then(function(data) {
             if (data) {
-                return Str.get_string('contentrenamed', 'core_contentbank');
+                return 'contentrenamed';
             }
             requestType = 'error';
-            return Str.get_string('contentnotrenamed', 'core_contentbank');
+            return 'contentnotrenamed';
 
         }).then(function(message) {
             var params = null;
index 9765bfd..c9dad88 100644 (file)
@@ -59,7 +59,7 @@ abstract class content {
         if (!class_exists($typeclass)) {
             throw new coding_exception(get_string('contenttypenotfound', 'error', $record->contenttype));
         }
-        // A record with the id must exist in 'contenbank_content' table.
+        // A record with the id must exist in 'contentbank_content' table.
         // To improve performance, we are only checking the id is set, but no querying the database.
         if (!isset($record->id)) {
             throw new coding_exception(get_string('invalidcontentid', 'error'));
@@ -103,7 +103,7 @@ abstract class content {
     public function update_content(): bool {
         global $USER, $DB;
 
-        // A record with the id must exist in 'contenbank_content' table.
+        // A record with the id must exist in 'contentbank_content' table.
         // To improve performance, we are only checking the id is set, but no querying the database.
         if (!isset($this->content->id)) {
             throw new coding_exception(get_string('invalidcontentid', 'error'));
index 5608a9a..33eff29 100644 (file)
@@ -32,8 +32,8 @@ $context = context::instance_by_id($contextid, MUST_EXIST);
 
 require_capability('moodle/contentbank:access', $context);
 
-$statusmsg = optional_param('statusmsg', '', PARAM_RAW);
-$errormsg = optional_param('errormsg', '', PARAM_RAW);
+$statusmsg = optional_param('statusmsg', '', PARAM_ALPHANUMEXT);
+$errormsg = optional_param('errormsg', '', PARAM_ALPHANUMEXT);
 
 $title = get_string('contentbank');
 \core_contentbank\helper::get_page_ready($context, $title);
@@ -44,7 +44,7 @@ $PAGE->set_url('/contentbank/index.php');
 $PAGE->set_context($context);
 $PAGE->set_title($title);
 $PAGE->set_heading($title);
-$PAGE->set_pagetype('contenbank');
+$PAGE->set_pagetype('contentbank');
 
 // Get all contents managed by active plugins where the user has permission to render them.
 $cb = new \core_contentbank\contentbank();
@@ -98,9 +98,11 @@ echo $OUTPUT->header();
 echo $OUTPUT->box_start('generalbox');
 
 // If needed, display notifications.
-if ($errormsg !== '') {
+if ($errormsg !== '' && get_string_manager()->string_exists($errormsg, 'core_contentbank')) {
+    $errormsg = get_string($errormsg, 'core_contentbank');
     echo $OUTPUT->notification($errormsg);
-} else if ($statusmsg !== '') {
+} else if ($statusmsg !== '' && get_string_manager()->string_exists($statusmsg, 'core_contentbank')) {
+    $statusmsg = get_string($statusmsg, 'core_contentbank');
     echo $OUTPUT->notification($statusmsg, 'notifysuccess');
 }
 
index 371d27f..c4626f0 100644 (file)
@@ -44,7 +44,7 @@ $PAGE->set_context($context);
 $PAGE->navbar->add(get_string('upload', 'contentbank'));
 $PAGE->set_title($title);
 $PAGE->set_heading($title);
-$PAGE->set_pagetype('contenbank');
+$PAGE->set_pagetype('contentbank');
 
 $maxbytes = $CFG->userquota;
 $maxareabytes = $CFG->userquota;
index 1cf7500..5fd66d1 100644 (file)
@@ -35,8 +35,8 @@ $record = $DB->get_record('contentbank_content', ['id' => $id], '*', MUST_EXIST)
 $context = context::instance_by_id($record->contextid, MUST_EXIST);
 require_capability('moodle/contentbank:access', $context);
 
-$statusmsg = optional_param('statusmsg', '', PARAM_RAW);
-$errormsg = optional_param('errormsg', '', PARAM_RAW);
+$statusmsg = optional_param('statusmsg', '', PARAM_ALPHANUMEXT);
+$errormsg = optional_param('errormsg', '', PARAM_ALPHANUMEXT);
 
 $returnurl = new \moodle_url('/contentbank/index.php', ['contextid' => $context->id]);
 $plugin = core_plugin_manager::instance()->get_plugin_info($record->contenttype);
@@ -56,7 +56,7 @@ $PAGE->navbar->add($record->name);
 $PAGE->set_heading($record->name);
 $title .= ": ".$record->name;
 $PAGE->set_title($title);
-$PAGE->set_pagetype('contenbank');
+$PAGE->set_pagetype('contentbank');
 
 $contenttypeclass = "\\$record->contenttype\\contenttype";
 $contentclass = "\\$record->contenttype\\content";
@@ -111,9 +111,11 @@ $PAGE->add_header_action(html_writer::div(
 echo $OUTPUT->header();
 
 // If needed, display notifications.
-if ($errormsg !== '') {
+if ($errormsg !== '' && get_string_manager()->string_exists($errormsg, 'core_contentbank')) {
+    $errormsg = get_string($errormsg, 'core_contentbank');
     echo $OUTPUT->notification($errormsg);
-} else if ($statusmsg !== '') {
+} else if ($statusmsg !== '' && get_string_manager()->string_exists($statusmsg, 'core_contentbank')) {
+    $statusmsg = get_string($statusmsg, 'core_contentbank');
     echo $OUTPUT->notification($statusmsg, 'notifysuccess');
 }
 if ($contenttype->can_access()) {
index d455f9f..131f927 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_format_topics_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index a7d1c9d..ff33b81 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_format_weeks_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index b492dfa..dcf26fb 100644 (file)
@@ -39,5 +39,8 @@ function xmldb_enrol_database_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 7ba1a90..7ac0520 100644 (file)
@@ -39,5 +39,8 @@ function xmldb_enrol_flatfile_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 0ac5154..230075c 100644 (file)
@@ -39,5 +39,8 @@ function xmldb_enrol_guest_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index b1e9e98..cb22209 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_enrol_imsenterprise_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index d8e0e5d..72ec893 100644 (file)
@@ -51,5 +51,8 @@ function xmldb_enrol_lti_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index d709a5c..7146f26 100644 (file)
@@ -39,5 +39,8 @@ function xmldb_enrol_manual_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 005dab9..59952aa 100644 (file)
@@ -39,5 +39,8 @@ function xmldb_enrol_mnet_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 8cc31b0..0d92c12 100644 (file)
@@ -138,5 +138,8 @@ function xmldb_enrol_paypal_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 20b46dd..04773be 100644 (file)
@@ -39,5 +39,8 @@ function xmldb_enrol_self_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 734f1c1..cc5d039 100644 (file)
@@ -57,5 +57,8 @@ function xmldb_filter_displayh5p_upgrade($oldversion) {
         upgrade_plugin_savepoint(true, 2020031700, 'filter', 'displayh5p');
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 3e83f5a..e61d26a 100644 (file)
@@ -55,5 +55,8 @@ function xmldb_filter_mathjaxloader_upgrade($oldversion) {
         upgrade_plugin_savepoint(true, 2020050401, 'filter', 'mathjaxloader');
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 9f1b26b..83b7e30 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_filter_mediaplugin_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 9e1a27f..dec7d77 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_filter_tex_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 66340e8..2b8c1f1 100644 (file)
@@ -49,5 +49,8 @@ function xmldb_gradingform_guide_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index af2611e..09e1725 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_gradingform_rubric_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index d2c6135..119d7b4 100644 (file)
@@ -43,5 +43,8 @@ function xmldb_gradereport_history_upgrade($oldversion) {
         upgrade_plugin_savepoint(true, 2019111801, 'gradereport', 'history');
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index c94287c..8b40fff 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_gradereport_overview_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 679129f..6e6e42e 100644 (file)
@@ -41,5 +41,8 @@ function xmldb_gradereport_user_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index e7dc1b5..e381777 100644 (file)
@@ -80,8 +80,7 @@ $string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
 $string['welcomep20'] = 'Sie haben das Paket <strong>{$a->packname} {$a->packversion}</strong> erfolgreich auf Ihrem Computer installiert.';
 $string['welcomep30'] = 'Diese Version von <strong>{$a->installername}</strong> enthält folgende Anwendungen, mit denen Sie <strong>Moodle</strong> ausführen können:';
 $string['welcomep40'] = 'Das Paket enthält: <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
-$string['welcomep50'] = 'Die Nutzung dieser Anwendungen ist lizenzrechtlich geprüft. Alle Anwendungen von <strong>{$a->installername}</strong> sind
-<a href="http://www.opensource.org/docs/definition_plain.html"> Open Source </a> und unterliegen der <a href="http://www.gnu.org/copyleft/gpl.html"> GPL</a> Lizenz.';
+$string['welcomep50'] = 'Die Verwendung aller Anwendungen in diesem Paket unterliegt den jeweiligen Lizenzen. Das vollständige Paket <strong>{$a->installername}</strong> ist <a href="https://www.opensource.org/docs/definition_plain.html">Open Source</a> und wird unter mit der Lizenz <a href="https://www.gnu.org/copyleft/gpl.html">GPL</a> angeboten.';
 $string['welcomep60'] = 'Die folgenden Webseiten führen Sie in einfachen Schritten durch die Installation von <strong>Moodle</strong> auf Ihrem Computer. Sie können die vorgeschlagenen Einstellungen übernehmen oder an eigene Bedürfnisse anpassen.';
 $string['welcomep70'] = 'Klicken Sie auf die Taste \'Weiter\', um mit der Installation von Moodle fortzufahren.';
 $string['wwwroot'] = 'Webadresse';
index 7672db6..24d2c03 100644 (file)
@@ -854,6 +854,7 @@ $string['first'] = 'First';
 $string['firstaccess'] = 'First access';
 $string['firstname'] = 'First name';
 $string['firstnamephonetic'] = 'First name - phonetic';
+$string['firstpage'] = 'First page';
 $string['firstsiteaccess'] = 'First access to site';
 $string['firsttime'] = 'Is this your first time here?';
 $string['folder'] = 'Folder';
@@ -1133,6 +1134,7 @@ $string['lastlogin'] = 'Last login';
 $string['lastmodified'] = 'Last modified';
 $string['lastname'] = 'Surname';
 $string['lastnamephonetic'] = 'Surname - phonetic';
+$string['lastpage'] = 'Last page';
 $string['lastsiteaccess'] = 'Last access to site';
 $string['lastyear'] = 'Last year';
 $string['latestlanguagepack'] = 'Check for latest language pack on moodle.org';
@@ -1417,6 +1419,7 @@ Cheers from the \'{$a->sitename}\' administrator,
 $string['newusers'] = 'New users';
 $string['newwindow'] = 'New window';
 $string['next'] = 'Next';
+$string['nextpage'] = 'Next page';
 $string['nextsection'] = 'Next section';
 $string['no'] = 'No';
 $string['noblockstoaddhere'] = 'There are no blocks that you can add to this page.';
@@ -1600,6 +1603,7 @@ $string['preview'] = 'Preview';
 $string['previeworchoose'] = 'Preview or choose a theme';
 $string['previous'] = 'Previous';
 $string['previouslyselectedusers'] = 'Previously selected users not matching \'{$a}\'';
+$string['previouspage'] = 'Previous page';
 $string['previoussection'] = 'Previous section';
 $string['primaryadminsetup'] = 'Setup administrator account';
 $string['privacy:metadata:config_log'] = 'The log of configuration changes.';
index 8477172..ed8ad04 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_antivirus_clamav_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 267406b..b24ea48 100644 (file)
@@ -32,6 +32,7 @@ require_once(__DIR__ . '/behat_config_manager.php');
 
 require_once(__DIR__ . '/../../filelib.php');
 require_once(__DIR__ . '/../../clilib.php');
+require_once(__DIR__ . '/../../csslib.php');
 
 use Behat\Mink\Session;
 use Behat\Mink\Exception\ExpectationException;
@@ -131,6 +132,35 @@ class behat_util extends testing_util {
         self::store_database_state();
     }
 
+    /**
+     * Build theme CSS.
+     */
+    public static function build_themes() {
+        global $CFG;
+        require_once("{$CFG->libdir}/outputlib.php");
+
+        $themenames = array_keys(\core_component::get_plugin_list('theme'));
+
+        // Load the theme configs.
+        $themeconfigs = array_map(function($themename) {
+            return \theme_config::load($themename);
+        }, $themenames);
+
+        // Build the list of themes and cache them in local cache.
+        $themes = theme_build_css_for_themes($themeconfigs, ['ltr'], true);
+
+        $framework = self::get_framework();
+        $storageroot = self::get_dataroot() . "/{$framework}/themedata";
+
+        foreach ($themes as $themename => $themedata) {
+            $dirname = "{$storageroot}/{$themename}";
+            check_dir_exists($dirname);
+            foreach ($themedata as $direction => $css) {
+                file_put_contents("{$dirname}/{$direction}.css", $css);
+            }
+        }
+    }
+
     /**
      * Drops dataroot and remove test database tables
      * @throws coding_exception
@@ -397,6 +427,37 @@ class behat_util extends testing_util {
         initialise_cfg();
     }
 
+    /**
+     * Restore theme CSS stored during behat setup.
+     */
+    public static function restore_saved_themes(): void {
+        global $CFG;
+
+        $themerev = theme_get_revision();
+
+        $framework = self::get_framework();
+        $storageroot = self::get_dataroot() . "/{$framework}/themedata";
+        $themenames = array_keys(\core_component::get_plugin_list('theme'));
+        $directions = ['ltr', 'rtl'];
+
+        $themeconfigs = array_map(function($themename) {
+            return \theme_config::load($themename);
+        }, $themenames);
+
+        foreach ($themeconfigs as $themeconfig) {
+            $themename = $themeconfig->name;
+            $themesubrev = theme_get_sub_revision_for_theme($themename);
+
+            $dirname = "{$storageroot}/{$themename}";
+            foreach ($directions as $direction) {
+                $cssfile = "{$dirname}/{$direction}.css";
+                if (file_exists($cssfile)) {
+                    $themeconfig->set_css_content_cache(file_get_contents($cssfile));
+                }
+            }
+        }
+    }
+
     /**
      * Pause execution immediately.
      *
index b6348d1..53fa76a 100644 (file)
@@ -2441,5 +2441,8 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2020060500.01);
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index c304197..81a3099 100644 (file)
@@ -102,5 +102,8 @@ other = html';
         upgrade_plugin_savepoint(true, 2020052100, 'editor', 'atto');
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 1c8d312..bf910f8 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_atto_equation_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 3f62f9d..e6fd0f4 100644 (file)
Binary files a/lib/editor/atto/plugins/recordrtc/yui/build/moodle-atto_recordrtc-button/moodle-atto_recordrtc-button-debug.js and b/lib/editor/atto/plugins/recordrtc/yui/build/moodle-atto_recordrtc-button/moodle-atto_recordrtc-button-debug.js differ
index 1e16ae0..013087c 100644 (file)
Binary files a/lib/editor/atto/plugins/recordrtc/yui/build/moodle-atto_recordrtc-button/moodle-atto_recordrtc-button-min.js and b/lib/editor/atto/plugins/recordrtc/yui/build/moodle-atto_recordrtc-button/moodle-atto_recordrtc-button-min.js differ
index 3f62f9d..e6fd0f4 100644 (file)
Binary files a/lib/editor/atto/plugins/recordrtc/yui/build/moodle-atto_recordrtc-button/moodle-atto_recordrtc-button.js and b/lib/editor/atto/plugins/recordrtc/yui/build/moodle-atto_recordrtc-button/moodle-atto_recordrtc-button.js differ
index 3ffa677..bba8d70 100644 (file)
@@ -116,12 +116,12 @@ Y.namespace('M.atto_recordrtc').Button = Y.Base.create('button', Y.M.editor_atto
                 focusAfterHide: null
             });
 
-            // If dialogue is closed during recording, do the following.
             dialogue.after('visibleChange', function() {
                 var closed = !dialogue.get('visible'),
                     m = M.atto_recordrtc.commonmodule;
 
                 if (closed) {
+                    // If dialogue is closed during recording, do the following.
                     window.clearInterval(m.countdownTicker);
 
                     if (m.mediaRecorder && m.mediaRecorder.state !== 'inactive') {
@@ -135,9 +135,14 @@ Y.namespace('M.atto_recordrtc').Button = Y.Base.create('button', Y.M.editor_atto
                             }
                         });
                     }
+
+                    // Because the player uses ids to identify things (this should be fixed)
+                    // we must make sure the dialogue contents only exist once in the DOM.
+                    // Therefore, when a dialogue is closed, we must remove its contents.
+                    this.getDialogue().set('bodyContent', '');
                 }
 
-            });
+            }, this);
 
             dialogue.on('click', function() {
                 this.centered();
index 2bebe2e..79c34d5 100644 (file)
@@ -39,5 +39,8 @@ function xmldb_editor_tinymce_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index b001bf8..fb4bb70 100644 (file)
@@ -39,5 +39,8 @@ function xmldb_tinymce_spellchecker_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 002a99d..50cd9da 100644 (file)
@@ -84,11 +84,12 @@ class external_api {
                 $function->classpath = $CFG->dirroot.'/'.$function->classpath;
             }
             if (!file_exists($function->classpath)) {
-                throw new coding_exception('Cannot find file with external function implementation');
+                throw new coding_exception('Cannot find file ' . $function->classpath .
+                        ' with external function implementation');
             }
             require_once($function->classpath);
             if (!class_exists($function->classname)) {
-                throw new coding_exception('Cannot find external class');
+                throw new coding_exception('Cannot find external class ' . $function->classname);
             }
         }
 
@@ -99,13 +100,16 @@ class external_api {
 
         // Make sure the implementaion class is ok.
         if (!method_exists($function->classname, $function->methodname)) {
-            throw new coding_exception('Missing implementation method of '.$function->classname.'::'.$function->methodname);
+            throw new coding_exception('Missing implementation method ' .
+                    $function->classname . '::' . $function->methodname);
         }
         if (!method_exists($function->classname, $function->parameters_method)) {
-            throw new coding_exception('Missing parameters description');
+            throw new coding_exception('Missing parameters description method ' .
+                    $function->classname . '::' . $function->parameters_method);
         }
         if (!method_exists($function->classname, $function->returns_method)) {
-            throw new coding_exception('Missing returned values description');
+            throw new coding_exception('Missing returned values description method ' .
+                    $function->classname . '::' . $function->returns_method);
         }
         if (method_exists($function->classname, $function->deprecated_method)) {
             if (call_user_func(array($function->classname, $function->deprecated_method)) === true) {
@@ -117,14 +121,16 @@ class external_api {
         // Fetch the parameters description.
         $function->parameters_desc = call_user_func(array($function->classname, $function->parameters_method));
         if (!($function->parameters_desc instanceof external_function_parameters)) {
-            throw new coding_exception('Invalid parameters description');
+            throw new coding_exception($function->classname . '::' . $function->parameters_method .
+                    ' did not return a valid external_function_parameters object.');
         }
 
         // Fetch the return values description.
         $function->returns_desc = call_user_func(array($function->classname, $function->returns_method));
         // Null means void result or result is ignored.
         if (!is_null($function->returns_desc) and !($function->returns_desc instanceof external_description)) {
-            throw new coding_exception('Invalid return description');
+            throw new coding_exception($function->classname . '::' . $function->returns_method .
+                    ' did not return a valid external_description object');
         }
 
         // Now get the function description.
index 2d460c4..fc073fe 100644 (file)
@@ -445,12 +445,12 @@ M.form_dndupload.init = function(Y, options) {
                 if (dispfilename.length > 50) {
                     dispfilename = dispfilename.substr(0, 49)+'&hellip;';
                 }
-                var progressouter = this.container.create(dispfilename +
+                var progressouter = this.container.create('<div>' + dispfilename +
                     '<div class="progress">' +
                     '   <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">' +
                     '       <span class="sr-only"></span>' +
                     '   </div>' +
-                    '</div>');
+                    '</div></div>');
                 var progressinner = progressouter.one('.progress-bar');
                 var progressinnertext = progressinner.one('.sr-only');
                 var progresscontainer = this.container.one('.dndupload-progressbars');
index e7cb41e..fb4a29c 100644 (file)
@@ -179,12 +179,13 @@ function theme_get_css_filename($themename, $globalrevision, $themerevision, $di
  * @param theme_config[] $themeconfigs An array of theme_config instances.
  * @param array          $directions   Must be a subset of ['rtl', 'ltr'].
  * @param bool           $cache        Should the generated files be stored in local cache.
+ * @return array         The built theme content in a multi-dimensional array of name => direction => content
  */
-function theme_build_css_for_themes($themeconfigs = [], $directions = ['rtl', 'ltr'], $cache = true) {
+function theme_build_css_for_themes($themeconfigs = [], $directions = ['rtl', 'ltr'], $cache = true): array {
     global $CFG;
 
     if (empty($themeconfigs)) {
-        return;
+        return [];
     }
 
     require_once("{$CFG->libdir}/csslib.php");
@@ -212,7 +213,7 @@ function theme_build_css_for_themes($themeconfigs = [], $directions = ['rtl', 'l
                 css_store_css($themeconfig, $filename, $themecss[$direction]);
             }
         }
-        $themescss[] = $themecss;
+        $themescss[$themeconfig->name] = $themecss;
 
         if ($cache) {
             // Only update the theme revision after we've successfully created the
index 470b3be..8c89e04 100644 (file)
@@ -1813,6 +1813,8 @@ function question_get_question_capabilities() {
         'moodle/question:useall',
         'moodle/question:movemine',
         'moodle/question:moveall',
+        'moodle/question:tagmine',
+        'moodle/question:tagall',
     );
 }
 
index c1b7202..4111ea8 100644 (file)
     Example context (json):
     {
         "pagingbar": {
-            "itemsperpage": 1,
+            "showitemsperpageselector": true,
+            "itemsperpage": [
+                { "value": 5, "active": false },
+                { "value": 10, "active": true },
+                { "value": 15, "active": false }
+            ],
             "previous": true,
             "next": true,
             "first": true,
             "last": true,
+            "barsize": 5,
             "pages": [
                 {
                     "page": "1",
                 {
                     "url": "#",
                     "page": "2"
+                },
+                {
+                    "url": "#",
+                    "page": "3"
+                },
+                {
+                    "url": "#",
+                    "page": "4"
+                },
+                {
+                    "url": "#",
+                    "page": "5"
+                },
+                {
+                    "url": "#",
+                    "page": "6"
+                },
+                {
+                    "url": "#",
+                    "page": "7"
                 }
             ]
         },
             {
                 "page": 2,
                 "content": "<p>Some page 2 content</p>"
+            },
+            {
+                "page": 3,
+                "content": "<p>Some page 3 content</p>"
+            },
+            {
+                "page": 4,
+                "content": "<p>Some page 4 content</p>"
+            },
+            {
+                "page": 5,
+                "content": "<p>Some page 5 content</p>"
+            },
+            {
+                "page": 6,
+                "content": "<p>Some page 6 content</p>"
+            },
+            {
+                "page": 7,
+                "content": "<p>Some page 7 content</p>"
             }
         ]
     }
index b0b84f1..f8af357 100644 (file)
 
     Example context (json):
     {
-        "itemsperpage": 2,
+        "showitemsperpageselector": true,
+        "itemsperpage": [
+            { "value": 5, "active": false },
+            { "value": 10, "active": true },
+            { "value": 15, "active": false }
+        ],
         "previous": true,
         "next": true,
         "first": true,
@@ -89,7 +94,8 @@
                         <a
                             class="dropdown-item {{#active}}active{{/active}}"
                             href="#"
-                            data-limit={{value}}
+                            data-limit="{{value}}"
+                            role="menuitem"
                             {{#active}}aria-current="true"{{/active}}
                         >
                             {{#value}}{{.}}{{/value}}
         <ul class="pagination mb-0">
             {{#previous}}
                 {{< core/paged_content_paging_bar_item }}
+                    {{$linkattributes}}aria-label="{{#str}}previouspage{{/str}}"{{/linkattributes}}
                     {{$item-content}}
                         <span class="icon-no-margin dir-rtl-hide" aria-hidden="true">{{#pix}} i/previous, core {{/pix}}</span>
                         <span class="icon-no-margin dir-ltr-hide" aria-hidden="true">{{#pix}} i/next, core {{/pix}}</span>
             {{/previous}}
             {{#first}}
                 {{< core/paged_content_paging_bar_item }}
+                    {{$linkattributes}}aria-label="{{#str}}firstpage{{/str}}"{{/linkattributes}}
                     {{$item-content}}
-                        <span aria-hidden="true">{{#str}}first{{/str}}</span>
+                        {{#str}}first{{/str}}
                     {{/item-content}}
                     {{$attributes}}data-control="first"{{/attributes}}
                 {{/ core/paged_content_paging_bar_item }}
             {{/first}}
             {{#barsize}}
                 {{< core/paged_content_paging_bar_item }}
+                    {{$linkattributes}}aria-hidden="true"{{/linkattributes}}
                     {{$item-content}}
-                        <span aria-hidden="true">&hellip;</span>
+                        &hellip;
                     {{/item-content}}
                     {{$attributes}}data-dots="beginning"{{/attributes}}
                 {{/ core/paged_content_paging_bar_item }}
             {{/pages}}
             {{#barsize}}
                 {{< core/paged_content_paging_bar_item }}
+                    {{$linkattributes}}aria-hidden="true"{{/linkattributes}}
                     {{$item-content}}
-                        <span aria-hidden="true">&hellip;</span>
+                        &hellip;
                     {{/item-content}}
                     {{$attributes}}data-dots="ending"{{/attributes}}
                 {{/ core/paged_content_paging_bar_item }}
             {{/barsize}}
             {{#last}}
                 {{< core/paged_content_paging_bar_item }}
+                    {{$linkattributes}}aria-label="{{#str}}lastpage{{/str}}"{{/linkattributes}}
                     {{$item-content}}
-                        <span aria-hidden="true">{{#str}}last{{/str}}</span>
+                        {{#str}}last{{/str}}
                     {{/item-content}}
                     {{$attributes}}data-control="last"{{/attributes}}
                 {{/ core/paged_content_paging_bar_item }}
             {{/last}}
             {{#next}}
                 {{< core/paged_content_paging_bar_item }}
+                    {{$linkattributes}}aria-label="{{#str}}nextpage{{/str}}"{{/linkattributes}}
                     {{$item-content}}
                         <span class="icon-no-margin dir-rtl-hide" aria-hidden="true">{{#pix}} i/next, core {{/pix}}</span>
                         <span class="icon-no-margin dir-ltr-hide" aria-hidden="true">{{#pix}} i/previous, core {{/pix}}</span>
index e3ef1a2..ed50b10 100644 (file)
@@ -33,7 +33,7 @@
 
     <a href="{{#url}}{{.}}{{/url}}{{^url}}#{{/url}}"
        class="page-link"
-       data-region="page-link">
+       data-region="page-link" {{$linkattributes}}aria-label="{{#str}}pagea, moodle, {{page}}{{/str}}"{{/linkattributes}}>
         {{$item-content}}
             {{{page}}}
         {{/item-content}}
index c7b53df..115765a 100644 (file)
@@ -367,6 +367,16 @@ class behat_hooks extends behat_base {
         behat_util::reset_all_data();
         error_reporting($errorlevel);
 
+        if ($this->running_javascript()) {
+            // Fetch the user agent.
+            // This isused to choose between the SVG/Non-SVG versions of themes.
+            $useragent = $this->getSession()->evaluateScript('return navigator.userAgent;');
+            \core_useragent::instance(true, $useragent);
+
+            // Restore the saved themes.
+            behat_util::restore_saved_themes();
+        }
+
         // Assign valid data to admin user (some generator-related code needs a valid user).
         $user = $DB->get_record('user', array('username' => 'admin'));
         \core\session\manager::set_user($user);
index 4ccb899..9d72b87 100644 (file)
Binary files a/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js and b/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js differ
index 90a6b75..9af91ef 100644 (file)
Binary files a/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js and b/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js differ
index 4ccb899..9d72b87 100644 (file)
Binary files a/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue.js and b/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue.js differ
index a2df1f7..ddefaa5 100644 (file)
@@ -214,7 +214,9 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
             newheight, totalheight;
 
         if (this.panel.shouldResizeFullscreen()) {
-            // No custom sizing required for a fullscreen dialog.
+            dialogue.setStyle('maxHeight', '100%');
+            dialogue.setStyle('height', 'auto');
+            this.panel.makeResponsive();
             return;
         }
 
index e7a1162..9e548d5 100644 (file)
@@ -71,5 +71,8 @@ function xmldb_message_email_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 8debc87..ca1596a 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_message_jabber_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index d1dbfa8..9152c48 100644 (file)
@@ -52,5 +52,8 @@ function xmldb_message_popup_upgrade($oldversion) {
         upgrade_plugin_savepoint(true, 2020020600, 'message', 'popup');
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 5085479..4de09c6 100644 (file)
@@ -59,5 +59,8 @@ function xmldb_assign_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 34648dd..25fff86 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_assignfeedback_comments_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 0b1831c..3fe8439 100644 (file)
@@ -107,5 +107,8 @@ function xmldb_assignfeedback_editpdf_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 8730f5e..6d79d03 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_assignfeedback_file_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index b5b875c..50860c0 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_assignsubmission_comments_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 20b27c9..863b154 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_assignsubmission_file_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index e0e0539..382c3b3 100644 (file)
@@ -323,8 +323,10 @@ class assign_submission_file extends assign_submission_plugin {
                                $submission->id);
 
         $currentsubmission = $this->get_file_submission($submission->id);
-        $currentsubmission->numfiles = 0;
-        $DB->update_record('assignsubmission_file', $currentsubmission);
+        if ($currentsubmission) {
+            $currentsubmission->numfiles = 0;
+            $DB->update_record('assignsubmission_file', $currentsubmission);
+        }
 
         return true;
     }
index ebd57fd..d09f6bd 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_assignsubmission_onlinetext_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 8dad393..c8fb7d1 100644 (file)
@@ -36,5 +36,8 @@ function xmldb_assignment_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index e41e282..0ec672b 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_book_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index b0ca303..cf1856a 100644 (file)
@@ -39,5 +39,8 @@ function xmldb_chat_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 1da59a9..b3db19a 100644 (file)
@@ -36,5 +36,8 @@ function xmldb_choice_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index a6ef012..b513ac2 100644 (file)
@@ -53,5 +53,8 @@ function xmldb_data_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 5239eec..a041cfb 100644 (file)
@@ -56,5 +56,8 @@ function xmldb_feedback_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 2470939..6bb16b9 100644 (file)
@@ -59,5 +59,8 @@ function xmldb_folder_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 1446801..7d36e04 100644 (file)
@@ -243,5 +243,8 @@ function xmldb_forum_upgrade($oldversion) {
         upgrade_mod_savepoint(true, 2019111801, 'forum');
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index ba2b8b6..e8f6374 100644 (file)
@@ -100,5 +100,8 @@ function xmldb_glossary_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 1f19284..8773c22 100644 (file)
@@ -240,5 +240,8 @@ function xmldb_h5pactivity_upgrade($oldversion) {
         upgrade_mod_savepoint(true, 2020042202, 'h5pactivity');
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 6838444..8690987 100644 (file)
@@ -43,5 +43,8 @@ function xmldb_imscp_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 3de6a43..9da7baa 100644 (file)
@@ -59,5 +59,8 @@ function xmldb_label_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 9ad02c0..e6fce60 100644 (file)
@@ -64,5 +64,8 @@ function xmldb_lesson_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index f5d2b10..5712845 100644 (file)
@@ -166,5 +166,8 @@ function xmldb_lti_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 20d5443..46d5d42 100644 (file)
@@ -107,5 +107,8 @@ function xmldb_ltiservice_gradebookservices_upgrade($oldversion) {
         upgrade_plugin_savepoint(true, 2020042403, 'ltiservice', 'gradebookservices');
     }
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 205f53d..6270d4a 100644 (file)
@@ -59,5 +59,8 @@ function xmldb_page_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index be9b65c..266481d 100644 (file)
@@ -93,12 +93,14 @@ class provider implements
         $sql = "SELECT c.id
                   FROM {quizaccess_seb_quizsettings} qs
                   JOIN {course_modules} cm ON cm.instance = qs.quizid
+                  JOIN {modules} m ON cm.module = m.id AND m.name = :modulename
                   JOIN {context} c ON c.instanceid = cm.id AND c.contextlevel = :context
                  WHERE qs.usermodified = :userid
               GROUP BY c.id";
 
         $params = [
             'context' => CONTEXT_MODULE,
+            'modulename' => 'quiz',
             'userid' => $userid
         ];
 
@@ -108,6 +110,7 @@ class provider implements
                   FROM {quizaccess_seb_template} tem
                   JOIN {quizaccess_seb_quizsettings} qs ON qs.templateid = tem.id
                   JOIN {course_modules} cm ON cm.instance = qs.quizid
+                  JOIN {modules} m ON cm.module = m.id AND m.name = :modulename
                   JOIN {context} c ON c.instanceid = cm.id AND c.contextlevel = :context
                  WHERE qs.usermodified = :userid
               GROUP BY c.id";
@@ -139,6 +142,7 @@ class provider implements
         }
 
         list($insql, $params) = $DB->get_in_or_equal($cmids, SQL_PARAMS_NAMED);
+        $params['modulename'] = 'quiz';
 
         // SEB quiz settings.
         $sql = "SELECT qs.id as id,
@@ -148,6 +152,7 @@ class provider implements
                        qs.timemodified as timemodified
                   FROM {quizaccess_seb_quizsettings} qs
                   JOIN {course_modules} cm ON cm.instance = qs.quizid
+                  JOIN {modules} m ON cm.module = m.id AND m.name = :modulename
                  WHERE cm.id {$insql}";
 
         $quizsettingslist = $DB->get_records_sql($sql, $params);
@@ -180,6 +185,7 @@ class provider implements
                   FROM {quizaccess_seb_template} tem
                   JOIN {quizaccess_seb_quizsettings} qs ON qs.templateid = tem.id
                   JOIN {course_modules} cm ON cm.instance = qs.quizid
+                  JOIN {modules} m ON cm.module = m.id AND m.name = :modulename
                  WHERE cm.id {$insql}";
 
         $templatesettingslist = $DB->get_records_sql($sql, $params);
@@ -262,8 +268,9 @@ class provider implements
         $sql = "SELECT qs.usermodified AS userid
                   FROM {quizaccess_seb_quizsettings} qs
                   JOIN {course_modules} cm ON cm.instance = qs.quizid
+                  JOIN {modules} m ON cm.module = m.id AND m.name = ?
                  WHERE cm.id = ?";
-        $params = [$context->instanceid];
+        $params = ['quiz', $context->instanceid];
         $userlist->add_from_sql('userid', $sql, $params);
     }
 
index 8ff2370..d581b44 100644 (file)
@@ -37,5 +37,8 @@ function xmldb_quizaccess_seb_upgrade($oldversion) {
     global $DB;
     $dbman = $DB->get_manager();
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 4a8aa90..f73a49f 100644 (file)
@@ -99,6 +99,15 @@ class quizaccess_seb_provider_testcase extends advanced_testcase {
 
         $context = context_module::instance($this->quiz->cmid);
 
+        // Add another course_module of a differenty type - doing this lets us
+        // test that the data exporter is correctly limiting its selection to
+        // the quiz and not anything with the same instance id.
+        // (note this is only effective with databases not using fed (+1000) sequences
+        // per table, like postgres and mysql do, rendering this useless. In any
+        // case better to have the situation covered by some DBs,
+        // like sqlsrv or oracle than by none).
+        $this->getDataGenerator()->create_module('label', array('course' => $this->course->id));
+
         $contextlist = provider::get_contexts_for_userid($this->user->id);
         $approvedcontextlist = new approved_contextlist(
             $this->user,
diff --git a/mod/quiz/classes/event/attempt_regraded.php b/mod/quiz/classes/event/attempt_regraded.php
new file mode 100644 (file)
index 0000000..dbbfd5f
--- /dev/null
@@ -0,0 +1,122 @@
+<?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/>.
+
+/**
+ * The mod_quiz attempt regraded event.
+ *
+ * @package    mod_quiz
+ * @copyright  2020 Russell Boyatt <russell.boyatt@warwick.ac.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace mod_quiz\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * The mod_quiz attempt regraded event class.
+ *
+ * @property-read array $other {
+ *      Extra information about event.
+ *
+ *      - int quizid: the id of the quiz.
+ * }
+ *
+ * @package    mod_quiz
+ * @copyright  2020 Russell Boyatt <russell.boyatt@warwick.ac.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class attempt_regraded extends \core\event\base {
+
+    /**
+     * Init method.
+     */
+    protected function init() {
+        $this->data['objecttable'] = 'quiz_attempts';
+        $this->data['crud'] = 'u';
+        $this->data['edulevel'] = self::LEVEL_TEACHING;
+    }
+
+    /**
+     * Returns localised general event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('eventquizattemptregraded', 'mod_quiz');
+    }
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The user with id '$this->userid' regraded quiz attempt with id '$this->objectid' by user " .
+          "with id '$this->relateduserid' for the quiz with course module id '$this->contextinstanceid'.";
+    }
+
+    /**
+     * Returns relevant URL.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/mod/quiz/review.php', array('attempt' => $this->objectid));
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @throws \coding_exception
+     * @return void
+     */
+    protected function validate_data() {
+        parent::validate_data();
+
+        if (!isset($this->relateduserid)) {
+            throw new \coding_exception('The \'relateduserid\' must be set.');
+        }
+
+        if (!isset($this->userid)) {
+            throw new \coding_exception('The \'userid\' must be set.');
+        }
+
+        if (!isset($this->other['quizid'])) {
+            throw new \coding_exception('The \'quizid\' value must be set in other.');
+        }
+    }
+
+    /**
+     * Get mapping to objects
+     *
+     * @return array Array of mappings
+     */
+    public static function get_objectid_mapping() {
+        return array('db' => 'quiz_attempts', 'restore' => 'quiz_attempt');
+    }
+
+    /**
+     * Retrieve other mapping detail for the event.
+     *
+     * @return array Array of array mappings
+     */
+    public static function get_other_mapping() {
+        $othermapped = array();
+        $othermapped['quizid'] = array('db' => 'quiz', 'restore' => 'quiz');
+
+        return $othermapped;
+    }
+}
index 289328f..ecfe6c8 100644 (file)
@@ -43,5 +43,8 @@ function xmldb_quiz_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 187e189..5ac9d24 100644 (file)
@@ -342,6 +342,7 @@ $string['eventoverrideupdated'] = 'Quiz override updated';
 $string['eventquestionmanuallygraded'] = 'Question manually graded';
 $string['eventquizattemptabandoned'] = 'Quiz attempt abandoned';
 $string['eventquizattempttimelimitexceeded'] = 'Quiz attempt time limit exceeded';
+$string['eventquizattemptregraded'] = 'Quiz attempt regraded';
 $string['eventquizattemptstarted'] = 'Quiz attempt started';
 $string['eventquizattemptsubmitted'] = 'Quiz attempt submitted';
 $string['eventreportviewed'] = 'Quiz report viewed';
index 28eed85..a635791 100644 (file)
@@ -79,5 +79,8 @@ function xmldb_quiz_overview_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 50e752b..0c97eca 100644 (file)
@@ -357,6 +357,17 @@ class quiz_overview_report extends quiz_attempts_report {
 
         if (!$dryrun) {
             question_engine::save_questions_usage_by_activity($quba);
+
+            $params = array(
+              'objectid' => $attempt->id,
+              'relateduserid' => $attempt->userid,
+              'context' => $this->context,
+              'other' => array(
+                'quizid' => $attempt->quiz
+              )
+            );
+            $event = \mod_quiz\event\attempt_regraded::create($params);
+            $event->trigger();
         }
 
         $transaction->allow_commit();
index eea4d61..7285805 100644 (file)
@@ -42,5 +42,8 @@ function xmldb_quiz_statistics_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 1771846..7494655 100644 (file)
@@ -749,4 +749,40 @@ class mod_quiz_events_testcase extends advanced_testcase {
         $this->assertEventLegacyLogData($expected, $event);
         $this->assertEventContextNotUsed($event);
     }
+
+    /**
+     * Test the attempt regraded event.
+     *
+     * There is no external API for regrading attempts, so the unit test will simply
+     * create and trigger the event and ensure the event data is returned as expected.
+     */
+    public function test_attempt_regraded() {
+      $this->resetAfterTest();
+
+      $this->setAdminUser();
+      $course = $this->getDataGenerator()->create_course();
+      $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
+
+      $params = array(
+        'objectid' => 1,
+        'relateduserid' => 2,
+        'courseid' => $course->id,
+        'context' => context_module::instance($quiz->cmid),
+        'other' => array(
+          'quizid' => $quiz->id
+        )
+      );
+      $event = \mod_quiz\event\attempt_regraded::create($params);
+
+      // Trigger and capture the event.
+      $sink = $this->redirectEvents();
+      $event->trigger();
+      $events = $sink->get_events();
+      $event = reset($events);
+
+      // Check that the event data is valid.
+      $this->assertInstanceOf('\mod_quiz\event\attempt_regraded', $event);
+      $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context());
+      $this->assertEventContextNotUsed($event);
+    }
 }
index e07f5c0..4bff2a2 100644 (file)
@@ -59,5 +59,8 @@ function xmldb_resource_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 6340b83..77d9e84 100644 (file)
@@ -59,5 +59,8 @@ function xmldb_scorm_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 04fe8e4..41edac7 100644 (file)
@@ -36,5 +36,8 @@ function xmldb_survey_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 7333641..48e084e 100644 (file)
@@ -59,5 +59,8 @@ function xmldb_url_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index b9f2f13..b921fdf 100644 (file)
@@ -52,5 +52,8 @@ function xmldb_wiki_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index aa90b9e..cf73e05 100644 (file)
@@ -92,5 +92,8 @@ function xmldb_workshop_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 14df521..5b55f09 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_workshopform_accumulative_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 7db0a54..c2c9c2d 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_workshopform_comments_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 7789f9b..9bcd3cf 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_workshopform_numerrors_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index beacab4..6bca99d 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_workshopform_rubric_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 10efcfa..0c188fe 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_portfolio_boxnet_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index a97753b..25b7e28 100644 (file)
@@ -35,5 +35,8 @@ function xmldb_portfolio_googledocs_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 1c1068a..9d34c13 100644 (file)
@@ -35,5 +35,8 @@ function xmldb_portfolio_picasa_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 2099891..913f5a1 100644 (file)
@@ -42,5 +42,8 @@ function xmldb_qbehaviour_manualgraded_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index a90295b..778ba9e 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_qtype_calculated_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 357a59e..e70a625 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_qtype_ddmarker_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 21595b6..2022579 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_qtype_essay_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 3f23799..4e13e59 100644 (file)
@@ -43,5 +43,8 @@ function xmldb_qtype_match_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index c99e735..11f5fe8 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_qtype_multianswer_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 484d796..6546de4 100644 (file)
@@ -63,5 +63,8 @@ function xmldb_qtype_multichoice_upgrade($oldversion) {
         // Multichoice savepoint reached.
         upgrade_plugin_savepoint(true, $newversion, 'qtype', 'multichoice');
     }
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index e13063c..fdb4de5 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_qtype_numerical_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index c6c16f9..1ba40d4 100644 (file)
@@ -43,5 +43,8 @@ function xmldb_qtype_random_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 7f487a8..de00fcc 100644 (file)
@@ -43,5 +43,8 @@ function xmldb_qtype_randomsamatch_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 7d0cb36..b4787f7 100644 (file)
@@ -44,5 +44,8 @@ function xmldb_qtype_shortanswer_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 61dd59a..94da3f4 100644 (file)
@@ -45,5 +45,8 @@ function xmldb_repository_boxnet_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 8522bb6..48942a5 100644 (file)
@@ -35,5 +35,8 @@ function xmldb_repository_dropbox_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 278a90e..d60015d 100644 (file)
@@ -46,5 +46,8 @@ function xmldb_repository_flickr_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 65d14bb..2f077fa 100644 (file)
@@ -35,5 +35,8 @@ function xmldb_repository_googledocs_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index ef9ed7e..40393af 100644 (file)
@@ -38,5 +38,8 @@ function xmldb_repository_onedrive_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 60d0f65..b701850 100644 (file)
@@ -35,5 +35,8 @@ function xmldb_repository_picasa_upgrade($oldversion) {
     // Automatically generated Moodle v3.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Automatically generated Moodle v3.9.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index ac58e81..4f10a37 100644 (file)
@@ -2603,6 +2603,9 @@ $picker-emojis-per-row: 7 !default;
         color: darken(theme-color-level($color, $alert-color-level), 10%);
     }
 }
+.alert a {
+    font-weight: $font-weight-bold;
+}
 
 @include media-breakpoint-down(sm) {
     #page-navbar {
index c9fc671..588a0de 100644 (file)
@@ -11746,6 +11746,9 @@ body.h5p-embed .h5pmessages {
 .alert-dark a {
   color: #040505; }
 
+.alert a {
+  font-weight: 700; }
+
 @media (max-width: 767.98px) {
   #page-navbar {
     width: 100%; }
index 7be6184..e9b5b03 100644 (file)
@@ -11960,6 +11960,9 @@ body.h5p-embed .h5pmessages {
 .alert-dark a {
   color: #040505; }
 
+.alert a {
+  font-weight: 700; }
+
 @media (max-width: 767.98px) {
   #page-navbar {
     width: 100%; }
index 33122cc..7946247 100644 (file)
@@ -283,6 +283,14 @@ class participants_search {
                 case $this->filterset::JOINTYPE_NONE:
                     $wherenot = ' NOT ';
                     $wheresjoin = ' AND NOT ';
+
+                    // Some of the $where conditions may begin with `NOT` which results in `AND NOT NOT ...`.
+                    // To prevent this from breaking on Oracle the inner WHERE clause is wrapped in brackets, making it
+                    // `AND NOT (NOT ...)` which is valid in all DBs.
+                    $wheres = array_map(function($where) {
+                        return "({$where})";
+                    }, $wheres);
+
                     break;
                 default:
                     // Default to 'Any' jointype.
index 66ce32c..89f720e 100644 (file)
@@ -1253,8 +1253,8 @@ class participants_search_test extends advanced_testcase {
         foreach ($usersdata as $username => $userdata) {
             $user = $this->getDataGenerator()->create_user(['username' => $username]);
 
-            if (array_key_exists('statuses', $userdata)) {
-                foreach ($userdata['statuses'] as $enrolmethod => $status) {
+            if (array_key_exists('status', $userdata)) {
+                foreach ($userdata['status'] as $enrolmethod => $status) {
                     $this->getDataGenerator()->enrol_user($user->id, $course->id, 'student', $enrolmethod, 0, 0, $status);
                 }
             }
@@ -1304,27 +1304,27 @@ class participants_search_test extends advanced_testcase {
             'Users with different enrolment statuses' => (object) [
                 'users' => [
                     'a' => [
-                        'statuses' => [
+                        'status' => [
                             'manual' => ENROL_USER_ACTIVE,
                         ]
                     ],
                     'b' => [
-                        'statuses' => [
+                        'status' => [
                             'self' => ENROL_USER_ACTIVE,
                         ]
                     ],
                     'c' => [
-                        'statuses' => [
+                        'status' => [
                             'manual' => ENROL_USER_SUSPENDED,
                         ]
                     ],
                     'd' => [
-                        'statuses' => [
+                        'status' => [
                             'self' => ENROL_USER_SUSPENDED,
                         ]
                     ],
                     'e' => [
-                        'statuses' => [
+                        'status' => [
                             'manual' => ENROL_USER_ACTIVE,
                             'self' => ENROL_USER_SUSPENDED,
                         ]
@@ -1333,7 +1333,7 @@ class participants_search_test extends advanced_testcase {
                 'expect' => [
                     // Tests for jointype: ANY.
                     'ANY: No filter' => (object) [
-                        'statuses' => [],
+                        'status' => [],
                         'jointype' => filter::JOINTYPE_ANY,
                         'count' => 5,
                         'expectedusers' => [
@@ -1345,7 +1345,7 @@ class participants_search_test extends advanced_testcase {
                         ],
                     ],
                     'ANY: Filter on active only' => (object) [
-                        'statuses' => [ENROL_USER_ACTIVE],
+                        'status' => [ENROL_USER_ACTIVE],
                         'jointype' => filter::JOINTYPE_ANY,
                         'count' => 3,
                         'expectedusers' => [
@@ -1355,7 +1355,7 @@ class participants_search_test extends advanced_testcase {
                         ],
                     ],
                     'ANY: Filter on suspended only' => (object) [
-                        'statuses' => [ENROL_USER_SUSPENDED],
+                        'status' => [ENROL_USER_SUSPENDED],
                         'jointype' => filter::JOINTYPE_ANY,
                         'count' => 3,
                         'expectedusers' => [
@@ -1365,7 +1365,7 @@ class participants_search_test extends advanced_testcase {
                         ],
                     ],
                     'ANY: Filter on multiple statuses' => (object) [
-                        'statuses' => [ENROL_USER_ACTIVE, ENROL_USER_SUSPENDED],
+                        'status' => [ENROL_USER_ACTIVE, ENROL_USER_SUSPENDED],
                         'jointype' => filter::JOINTYPE_ANY,
                         'count' => 5,
                         'expectedusers' => [
@@ -1379,7 +1379,7 @@ class participants_search_test extends advanced_testcase {
 
                     // Tests for jointype: ALL.
                     'ALL: No filter' => (object) [
-                       'statuses' => [],
+                       'status' => [],
                         'jointype' => filter::JOINTYPE_ALL,
                         'count' => 5,
                         'expectedusers' => [
@@ -1391,7 +1391,7 @@ class participants_search_test extends advanced_testcase {
                         ],
                     ],
                     'ALL: Filter on active only' => (object) [
-                        'statuses' => [ENROL_USER_ACTIVE],
+                        'status' => [ENROL_USER_ACTIVE],
                         'jointype' => filter::JOINTYPE_ALL,
                         'count' => 3,
                         'expectedusers' => [
@@ -1401,7 +1401,7 @@ class participants_search_test extends advanced_testcase {
                         ],
                     ],
                     'ALL: Filter on suspended only' => (object) [
-                        'statuses' => [ENROL_USER_SUSPENDED],
+                        'status' => [ENROL_USER_SUSPENDED],
                         'jointype' => filter::JOINTYPE_ALL,
                         'count' => 3,
                         'expectedusers' => [
@@ -1411,7 +1411,7 @@ class participants_search_test extends advanced_testcase {
                         ],
                     ],
                     'ALL: Filter on multiple statuses' => (object) [
-                        'statuses' => [ENROL_USER_ACTIVE, ENROL_USER_SUSPENDED],
+                        'status' => [ENROL_USER_ACTIVE, ENROL_USER_SUSPENDED],
                         'jointype' => filter::JOINTYPE_ALL,
                         'count' => 1,
                         'expectedusers' => [
@@ -1421,7 +1421,7 @@ class participants_search_test extends advanced_testcase {
 
                     // Tests for jointype: NONE.
                     'NONE: No filter' => (object) [
-                       'statuses' => [],
+                       'status' => [],
                         'jointype' => filter::JOINTYPE_NONE,
                         'count' => 5,
                         'expectedusers' => [
@@ -1433,7 +1433,7 @@ class participants_search_test extends advanced_testcase {
                         ],
                     ],
                     'NONE: Filter on active only' => (object) [
-                        'statuses' => [ENROL_USER_ACTIVE],
+                        'status' => [ENROL_USER_ACTIVE],
                         'jointype' => filter::JOINTYPE_NONE,
                         'count' => 3,
                         'expectedusers' => [
@@ -1443,7 +1443,7 @@ class participants_search_test extends advanced_testcase {
                         ],
                     ],
                     'NONE: Filter on suspended only' => (object) [
-                        'statuses' => [ENROL_USER_SUSPENDED],
+                        'status' => [ENROL_USER_SUSPENDED],
                         'jointype' => filter::JOINTYPE_NONE,
                         'count' => 3,
                         'expectedusers' => [
@@ -1453,7 +1453,7 @@ class participants_search_test extends advanced_testcase {
                         ],
                     ],
                     'NONE: Filter on multiple statuses' => (object) [
-                        'statuses' => [ENROL_USER_ACTIVE, ENROL_USER_SUSPENDED],
+                        'status' => [ENROL_USER_ACTIVE, ENROL_USER_SUSPENDED],
                         'jointype' => filter::JOINTYPE_NONE,
                         'count' => 0,
                         'expectedusers' => [],
@@ -1467,7 +1467,7 @@ class participants_search_test extends advanced_testcase {
             foreach ($testdata->expect as $expectname => $expectdata) {
                 $finaltests["{$testname} => {$expectname}"] = [
                     'users' => $testdata->users,
-                    'statuses' => $expectdata->statuses,
+                    'status' => $expectdata->status,
                     'jointype' => $expectdata->jointype,
                     'count' => $expectdata->count,
                     'expectedusers' => $expectdata->expectedusers,
@@ -3044,8 +3044,8 @@ class participants_search_test extends advanced_testcase {
                                 'jointype' => filter::JOINTYPE_ALL,
                             ],
                             // Match Sarah only.
-                            'statuses' => [
-                                'values' => ['active', 'suspended'],
+                            'status' => [
+                                'values' => [ENROL_USER_ACTIVE, ENROL_USER_SUSPENDED],
                                 'jointype' => filter::JOINTYPE_ALL,
                             ],
                             // Match Colin only.
@@ -3119,8 +3119,8 @@ class participants_search_test extends advanced_testcase {
                                 'jointype' => filter::JOINTYPE_NONE,
                             ],
                             // Exclude Colin and Tony.
-                            'statuses' => [
-                                'values' => ['active'],
+                            'status' => [
+                                'values' => [ENROL_USER_ACTIVE],
                                 'jointype' => filter::JOINTYPE_ALL,
                             ],
                             // Exclude Barbara.
@@ -3190,8 +3190,8 @@ class participants_search_test extends advanced_testcase {
                                 'jointype' => filter::JOINTYPE_NONE,
                             ],
                             // Excludes Colin, Tony and Sarah.
-                            'statuses' => [
-                                'values' => ['suspended'],
+                            'status' => [
+                                'values' => [ENROL_USER_SUSPENDED],
                                 'jointype' => filter::JOINTYPE_ALL,
                             ],
                             // Excludes Adam, Colin, Tony, Sarah, Morgan and Jonathan.
@@ -3203,7 +3203,7 @@ class participants_search_test extends advanced_testcase {
                             'accesssince' => [
                                 'values' => ['-6 months'],
                                 'jointype' => filter::JOINTYPE_ALL,
-                                ],
+                            ],
                         ],
                         'jointype' => filter::JOINTYPE_NONE,
                         'count' => 1,
@@ -3211,6 +3211,27 @@ class participants_search_test extends advanced_testcase {
                             'barbara.bennett',
                         ],
                     ],
+                    'NONE: Filterset combining several filter types and a double-negative on keyword' => (object) [
+                        'jointype' => filter::JOINTYPE_NONE,
+                        'filterdata' => [
+                            // Note: This is a jointype NONE on the parent jointype NONE.
+                            // The result therefore negated in this instance.
+                            // Include Adam and Anthony.
+                            'keywords' => [
+                                'values' => ['ant'],
+                                'jointype' => filter::JOINTYPE_NONE,
+                            ],
+                            // Excludes Tony.
+                            'status' => [
+                                'values' => [ENROL_USER_SUSPENDED],
+                                'jointype' => filter::JOINTYPE_ALL,
+                            ],
+                        ],
+                        'count' => 1,
+                        'expectedusers' => [
+                            'adam.ant',
+                        ],
+                    ],
                 ],
             ],
         ];
index 2f1d5f0..54a463e 100644 (file)
@@ -29,9 +29,9 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2020061200.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2020061500.01;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.
-$release  = '3.9rc2 (Build: 20200612)'; // Human-friendly version name
-$branch   = '39';                       // This version's branch.
-$maturity = MATURITY_RC;             // This version's maturity level.
+$release  = '4.0dev (Build: 20200618)'; // Human-friendly version name
+$branch   = '40';                       // This version's branch.
+$maturity = MATURITY_ALPHA;             // This version's maturity level.