Merge branch 'MDL-24951-master' of git://github.com/Chocolate-lightning/moodle
authorAndrew Nicols <andrew@nicols.co.uk>
Tue, 8 Jan 2019 05:46:11 +0000 (13:46 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Tue, 8 Jan 2019 05:46:11 +0000 (13:46 +0800)
140 files changed:
.travis.yml
admin/environment.xml
admin/settings/subsystems.php
admin/tool/customlang/db/upgrade.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/monitor/db/upgrade.php
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
blocks/badges/db/upgrade.php
blocks/calendar_month/db/upgrade.php
blocks/calendar_upcoming/db/upgrade.php
blocks/community/db/upgrade.php
blocks/completionstatus/db/upgrade.php
blocks/course_summary/db/upgrade.php
blocks/html/db/upgrade.php
blocks/navigation/db/upgrade.php
blocks/quiz_results/db/upgrade.php
blocks/recent_activity/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
course/renderer.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/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/user/db/upgrade.php
lang/en/admin.php
lib/amd/build/modal.min.js
lib/amd/build/str.min.js
lib/amd/build/templates.min.js
lib/amd/src/modal.js
lib/amd/src/str.js
lib/amd/src/templates.js
lib/antivirus/clamav/db/upgrade.php
lib/classes/output/external.php
lib/classes/output/mustache_template_source_loader.php [new file with mode: 0644]
lib/classes/task/messaging_cleanup_task.php
lib/db/services.php
lib/db/upgrade.php
lib/editor/atto/db/upgrade.php
lib/editor/atto/plugins/equation/db/upgrade.php
lib/editor/tinymce/db/upgrade.php
lib/editor/tinymce/plugins/spellchecker/db/upgrade.php
lib/phpminimumversionlib.php
lib/questionlib.php
lib/tests/mustache_template_source_loader_test.php [new file with mode: 0644]
lib/tests/output_external_test.php [deleted file]
lib/tests/questionlib_test.php
message/output/email/db/upgrade.php
message/output/email/message_output_email.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/onlinetext/db/upgrade.php
mod/assign/tests/locallib_test.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/forum/lib.php
mod/forum/tests/mail_test.php
mod/glossary/db/upgrade.php
mod/imscp/db/upgrade.php
mod/label/db/upgrade.php
mod/lesson/db/upgrade.php
mod/lti/db/upgrade.php
mod/page/db/upgrade.php
mod/quiz/classes/question/bank/add_action_column.php
mod/quiz/db/upgrade.php
mod/quiz/report/overview/db/upgrade.php
mod/quiz/report/statistics/db/upgrade.php
mod/quiz/tests/behat/editing_add_from_question_bank.feature
mod/quiz/tests/quiz_question_bank_view_test.php [new file with mode: 0644]
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
privacy/classes/local/request/moodle_content_writer.php
question/behaviour/manualgraded/db/upgrade.php
question/classes/bank/delete_action_column.php
question/classes/bank/preview_action_column.php
question/engine/bank.php
question/tests/bank_view_test.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/googledocs/db/upgrade.php
repository/picasa/db/upgrade.php
theme/bootstrapbase/templates/core_message/message_drawer_view_conversation_header_content_type_private.mustache
theme/more/db/upgrade.php
version.php

index aa0db16..ec1b68c 100644 (file)
@@ -14,7 +14,7 @@ language: php
 php:
     # We only run the highest and lowest supported versions to reduce the load on travis-ci.org.
     - 7.2
-    - 7.0
+    - 7.1
 
 addons:
   postgresql: "9.6"
@@ -63,7 +63,7 @@ matrix:
         # Exclude it on all versions except for 7.2
 
         - env: DB=mysqli   TASK=PHPUNIT
-          php: 7.0
+          php: 7.1
 
 cache:
     directories:
index 40e66be..ca20d0c 100644 (file)
       </CUSTOM_CHECK>
     </CUSTOM_CHECKS>
   </MOODLE>
+  <MOODLE version="3.7" requires="3.2">
+    <UNICODE level="required">
+      <FEEDBACK>
+        <ON_ERROR message="unicoderequired" />
+      </FEEDBACK>
+    </UNICODE>
+    <DATABASE level="required">
+      <VENDOR name="mariadb" version="5.5.31" />
+      <VENDOR name="mysql" version="5.6" />
+      <VENDOR name="postgres" version="9.4" />
+      <VENDOR name="mssql" version="10.0" />
+      <VENDOR name="oracle" version="11.2" />
+    </DATABASE>
+    <PHP version="7.1.0" level="required">
+    </PHP>
+    <PCREUNICODE level="optional">
+      <FEEDBACK>
+        <ON_CHECK message="pcreunicodewarning" />
+      </FEEDBACK>
+    </PCREUNICODE>
+    <PHP_EXTENSIONS>
+      <PHP_EXTENSION name="iconv" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="iconvrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="mbstring" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="mbstringrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="curl" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="curlrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="openssl" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="opensslrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="tokenizer" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="tokenizerrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="xmlrpc" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="xmlrpcrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="soap" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="soaprecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="ctype" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="ctyperequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="zip" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="ziprequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="zlib" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="gd" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="gdrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="simplexml" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="simplexmlrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="spl" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="splrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="pcre" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="dom" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="xml" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="xmlreader" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="intl" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="intlrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="json" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="hash" level="required"/>
+      <PHP_EXTENSION name="fileinfo" level="required"/>
+    </PHP_EXTENSIONS>
+    <PHP_SETTINGS>
+      <PHP_SETTING name="memory_limit" value="96M" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="settingmemorylimit" />
+        </FEEDBACK>
+      </PHP_SETTING>
+      <PHP_SETTING name="file_uploads" value="1" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="settingfileuploads" />
+        </FEEDBACK>
+      </PHP_SETTING>
+      <PHP_SETTING name="opcache.enable" value="1" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="opcacherecommended" />
+        </FEEDBACK>
+      </PHP_SETTING>
+    </PHP_SETTINGS>
+    <CUSTOM_CHECKS>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="unsupporteddbstorageengine" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="quizattemptsupgradedmessage" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="slashargumentswarning" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="unsupporteddbtablerowformat" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_unoconv_version" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="unoconvwarning" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="libcurlwarning" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="unsupporteddbfileformat" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="unsupporteddbfilepertable" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="unsupporteddblargeprefix" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_is_https" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="ishttpswarning" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_incomplete_unicode_support" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="incompleteunicodesupport" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_sixtyfour_bits" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="sixtyfourbitswarning" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+    </CUSTOM_CHECKS>
+  </MOODLE>
 </COMPATIBILITY_MATRIX>
index db26385..a108b42 100644 (file)
@@ -21,8 +21,28 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
         0)
     );
 
-    $options = array(DAYSECS=>new lang_string('secondstotime86400'), WEEKSECS=>new lang_string('secondstotime604800'), 2620800=>new lang_string('nummonths', 'moodle', 1), 15724800=>new lang_string('nummonths', 'moodle', 6),0=>new lang_string('never'));
-    $optionalsubsystems->add(new admin_setting_configselect('messagingdeletereadnotificationsdelay', new lang_string('messagingdeletereadnotificationsdelay', 'admin'), new lang_string('configmessagingdeletereadnotificationsdelay', 'admin'), 604800, $options));
+    $options = array(
+        DAYSECS => new lang_string('secondstotime86400'),
+        WEEKSECS => new lang_string('secondstotime604800'),
+        2620800 => new lang_string('nummonths', 'moodle', 1),
+        7862400 => new lang_string('nummonths', 'moodle', 3),
+        15724800 => new lang_string('nummonths', 'moodle', 6),
+        0 => new lang_string('never')
+    );
+    $optionalsubsystems->add(new admin_setting_configselect(
+        'messagingdeletereadnotificationsdelay',
+        new lang_string('messagingdeletereadnotificationsdelay', 'admin'),
+        new lang_string('configmessagingdeletereadnotificationsdelay', 'admin'),
+        604800,
+        $options)
+    );
+    $optionalsubsystems->add(new admin_setting_configselect(
+        'messagingdeleteallnotificationsdelay',
+        new lang_string('messagingdeleteallnotificationsdelay', 'admin'),
+        new lang_string('configmessagingdeleteallnotificationsdelay', 'admin'),
+        2620800,
+        $options)
+    );
 
     $optionalsubsystems->add(new admin_setting_configcheckbox('messagingallowemailoverride', new lang_string('messagingallowemailoverride', 'admin'), new lang_string('configmessagingallowemailoverride','admin'), 0));
 
index 5849311..53fa80a 100644 (file)
@@ -29,9 +29,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_tool_customlang_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 70a76cc..bbf1961 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_tool_log_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 0804ce8..04137ab 100644 (file)
@@ -27,9 +27,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_logstore_database_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 14946e8..d6cd26d 100644 (file)
@@ -27,9 +27,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_logstore_standard_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index ee22b83..f8579c9 100644 (file)
@@ -33,26 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_tool_monitor_upgrade($oldversion) {
     global $CFG, $DB;
 
-    $dbman = $DB->get_manager();
-
-    if ($oldversion < 2016052305) {
-
-        // Define field inactivedate to be added to tool_monitor_subscriptions.
-        $table = new xmldb_table('tool_monitor_subscriptions');
-        $field = new xmldb_field('inactivedate', XMLDB_TYPE_INTEGER, '10', null, true, null, 0, 'lastnotificationsent');
-
-        // Conditionally launch add field inactivedate.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Monitor savepoint reached.
-        upgrade_plugin_savepoint(true, 2016052305, 'tool', 'monitor');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017021300) {
 
         // Delete "orphaned" subscriptions.
index 9bdf9ee..a8582de 100644 (file)
@@ -35,9 +35,6 @@ use tool_usertours\manager;
 function xmldb_tool_usertours_upgrade($oldversion) {
     global $CFG, $DB;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 469661c..4df297c 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_auth_cas_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017020700) {
         // Convert info in config plugins from auth/cas to auth_cas.
         upgrade_fix_config_auth_plugin_names('cas');
index 7955ffe..f860220 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_auth_db_upgrade($oldversion) {
     global $CFG, $DB;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017032800) {
         // Convert info in config plugins from auth/db to auth_db
         upgrade_fix_config_auth_plugin_names('db');
index f00705b..f636d6f 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_auth_email_upgrade($oldversion) {
     global $CFG, $DB;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017020700) {
         // Convert info in config plugins from auth/email to auth_email.
         upgrade_fix_config_auth_plugin_names('email');
index 0a4c344..6c57255 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_auth_ldap_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017020700) {
         // Convert info in config plugins from auth/ldap to auth_ldap.
         upgrade_fix_config_auth_plugin_names('ldap');
index d691552..9209e9d 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_auth_manual_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017020700) {
         // Convert info in config plugins from auth/manual to auth_manual.
         upgrade_fix_config_auth_plugin_names('manual');
index 7d4d88d..be29bcd 100644 (file)
@@ -32,8 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_auth_mnet_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
     if ($oldversion < 2017020700) {
         // Convert info in config plugins from auth/mnet to auth_mnet.
         upgrade_fix_config_auth_plugin_names('mnet');
index 596740b..2d5fc97 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_auth_none_upgrade($oldversion) {
     global $CFG, $DB;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017020700) {
         // Convert info in config plugins from auth/none to auth_none.
         upgrade_fix_config_auth_plugin_names('none');
index 8d0a6a6..7582cc9 100644 (file)
@@ -35,9 +35,6 @@ function xmldb_auth_oauth2_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 416ac20..640a023 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_auth_shibboleth_upgrade($oldversion) {
     global $CFG, $DB;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017020700) {
         // Convert info in config plugins from auth/shibboleth to auth_shibboleth.
         upgrade_fix_config_auth_plugin_names('shibboleth');
index 433e0c7..6948646 100644 (file)
@@ -45,9 +45,6 @@
 function xmldb_block_badges_upgrade($oldversion, $block) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 913ccca..3205127 100644 (file)
@@ -45,9 +45,6 @@
 function xmldb_block_calendar_month_upgrade($oldversion, $block) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index b1e95d6..14100c8 100644 (file)
@@ -45,9 +45,6 @@
 function xmldb_block_calendar_upcoming_upgrade($oldversion, $block) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index ecfdca9..0bdc51e 100644 (file)
@@ -46,9 +46,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_block_community_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 770a27b..8a9ec89 100644 (file)
@@ -48,9 +48,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_block_completionstatus_upgrade($oldversion, $block) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index f3d591b..fb0cbae 100644 (file)
@@ -48,9 +48,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_block_course_summary_upgrade($oldversion, $block) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 221dd38..4949b3f 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_block_html_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index fcd820a..97b1063 100644 (file)
@@ -55,9 +55,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_block_navigation_upgrade($oldversion, $block) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index a9ef40e..60b035e 100644 (file)
@@ -45,9 +45,6 @@
 function xmldb_block_quiz_results_upgrade($oldversion, $block) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 148cd37..77e6f61 100644 (file)
@@ -47,9 +47,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_block_recent_activity_upgrade($oldversion, $block) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index ee46406..878f198 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_block_rss_client_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index a8e7bfd..0a8e2b0 100644 (file)
@@ -49,9 +49,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_block_section_links_upgrade($oldversion, $block) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 34a9814..9b8d87b 100644 (file)
@@ -48,9 +48,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 3e93f8b..7b8618d 100644 (file)
@@ -55,9 +55,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_block_settings_upgrade($oldversion, $block) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index ad00ffb..4321d51 100644 (file)
@@ -2425,9 +2425,8 @@ class core_course_renderer extends plugin_renderer_base {
                     if (!empty($mycourseshtml)) {
                         $output .= $this->frontpage_part('skipmycourses', 'frontpage-course-list',
                             get_string('mycourses'), $mycourseshtml);
-                        break;
                     }
-                    // No "break" here. If there are no enrolled courses - continue to 'Available courses'.
+                    break;
 
                 case FRONTPAGEALLCOURSELIST:
                     $availablecourseshtml = $this->frontpage_available_courses();
index 9ba3261..ca2733c 100644 (file)
@@ -27,9 +27,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_enrol_database_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index adc61cb..c286910 100644 (file)
@@ -27,9 +27,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_enrol_flatfile_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index e86cfff..a4f9d25 100644 (file)
@@ -27,9 +27,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_enrol_guest_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 857eb62..d89f296 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_enrol_imsenterprise_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index cccd6ae..7b5736b 100644 (file)
@@ -41,210 +41,6 @@ function xmldb_enrol_lti_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    if ($oldversion < 2016052303) {
-
-        // Define table enrol_lti_lti2_consumer to be created.
-        $table = new xmldb_table('enrol_lti_lti2_consumer');
-
-        // Adding fields to table enrol_lti_lti2_consumer.
-        $table->add_field('id', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('name', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('consumerkey256', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('consumerkey', XMLDB_TYPE_TEXT, null, null, null, null, null);
-        $table->add_field('secret', XMLDB_TYPE_CHAR, '1024', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('ltiversion', XMLDB_TYPE_CHAR, '10', null, null, null, null);
-        $table->add_field('consumername', XMLDB_TYPE_CHAR, '255', null, null, null, null);
-        $table->add_field('consumerversion', XMLDB_TYPE_CHAR, '255', null, null, null, null);
-        $table->add_field('consumerguid', XMLDB_TYPE_CHAR, '1024', null, null, null, null);
-        $table->add_field('profile', XMLDB_TYPE_TEXT, null, null, null, null, null);
-        $table->add_field('toolproxy', XMLDB_TYPE_TEXT, null, null, null, null, null);
-        $table->add_field('settings', XMLDB_TYPE_TEXT, null, null, null, null, null);
-        $table->add_field('protected', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('enablefrom', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
-        $table->add_field('enableuntil', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
-        $table->add_field('lastaccess', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
-        $table->add_field('created', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('updated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-
-        // Adding keys to table enrol_lti_lti2_consumer.
-        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
-
-        // Adding indexes to table enrol_lti_lti2_consumer.
-        $table->add_index('consumerkey256_uniq', XMLDB_INDEX_UNIQUE, array('consumerkey256'));
-
-        // Conditionally launch create table for enrol_lti_lti2_consumer.
-        if (!$dbman->table_exists($table)) {
-            $dbman->create_table($table);
-        }
-
-        // Define table enrol_lti_lti2_tool_proxy to be created.
-        $table = new xmldb_table('enrol_lti_lti2_tool_proxy');
-
-        // Adding fields to table enrol_lti_lti2_tool_proxy.
-        $table->add_field('id', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('toolproxykey', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('consumerid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('toolproxy', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
-        $table->add_field('created', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('updated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-
-        // Adding keys to table enrol_lti_lti2_tool_proxy.
-        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
-        $table->add_key('toolproxykey_uniq', XMLDB_KEY_UNIQUE, array('toolproxykey'));
-        $table->add_key('consumerid', XMLDB_KEY_FOREIGN, array('consumerid'), 'enrol_lti_lti2_consumer', array('id'));
-
-        // Conditionally launch create table for enrol_lti_lti2_tool_proxy.
-        if (!$dbman->table_exists($table)) {
-            $dbman->create_table($table);
-        }
-
-        // Define table enrol_lti_lti2_context to be created.
-        $table = new xmldb_table('enrol_lti_lti2_context');
-
-        // Adding fields to table enrol_lti_lti2_context.
-        $table->add_field('id', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('consumerid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('lticontextkey', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('settings', XMLDB_TYPE_TEXT, null, null, null, null, null);
-        $table->add_field('created', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('updated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-
-        // Adding keys to table enrol_lti_lti2_context.
-        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
-        $table->add_key('consumerid', XMLDB_KEY_FOREIGN, array('consumerid'), 'enrol_lti_lti2_consumer', array('id'));
-
-        // Conditionally launch create table for enrol_lti_lti2_context.
-        if (!$dbman->table_exists($table)) {
-            $dbman->create_table($table);
-        }
-
-        // Define table enrol_lti_lti2_nonce to be created.
-        $table = new xmldb_table('enrol_lti_lti2_nonce');
-
-        // Adding fields to table enrol_lti_lti2_nonce.
-        $table->add_field('id', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('consumerid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('value', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('expires', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-
-        // Adding keys to table enrol_lti_lti2_nonce.
-        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
-        $table->add_key('consumerid', XMLDB_KEY_FOREIGN, array('consumerid'), 'enrol_lti_lti2_consumer', array('id'));
-
-        // Conditionally launch create table for enrol_lti_lti2_nonce.
-        if (!$dbman->table_exists($table)) {
-            $dbman->create_table($table);
-        }
-
-        // Define table enrol_lti_lti2_resource_link to be created.
-        $table = new xmldb_table('enrol_lti_lti2_resource_link');
-
-        // Adding fields to table enrol_lti_lti2_resource_link.
-        $table->add_field('id', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('contextid', XMLDB_TYPE_INTEGER, '11', null, null, null, null);
-        $table->add_field('consumerid', XMLDB_TYPE_INTEGER, '11', null, null, null, null);
-        $table->add_field('ltiresourcelinkkey', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('settings', XMLDB_TYPE_TEXT, null, null, null, null, null);
-        $table->add_field('primaryresourcelinkid', XMLDB_TYPE_INTEGER, '11', null, null, null, null);
-        $table->add_field('shareapproved', XMLDB_TYPE_INTEGER, '1', null, null, null, null);
-        $table->add_field('created', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('updated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-
-        // Adding keys to table enrol_lti_lti2_resource_link.
-        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
-        $table->add_key('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'enrol_lti_lti2_context', array('id'));
-        $table->add_key('primaryresourcelinkid', XMLDB_KEY_FOREIGN, array('primaryresourcelinkid'),
-            'enrol_lti_lti2_resource_link', array('id'));
-        $table->add_key('consumerid', XMLDB_KEY_FOREIGN, array('consumerid'), 'enrol_lti_lti2_consumer', array('id'));
-
-        // Conditionally launch create table for enrol_lti_lti2_resource_link.
-        if (!$dbman->table_exists($table)) {
-            $dbman->create_table($table);
-        }
-
-        // Define table enrol_lti_lti2_share_key to be created.
-        $table = new xmldb_table('enrol_lti_lti2_share_key');
-
-        // Adding fields to table enrol_lti_lti2_share_key.
-        $table->add_field('id', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('sharekey', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('resourcelinkid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('autoapprove', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('expires', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-
-        // Adding keys to table enrol_lti_lti2_share_key.
-        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
-        $table->add_key('sharekey', XMLDB_KEY_UNIQUE, array('sharekey'));
-        $table->add_key('resourcelinkid', XMLDB_KEY_FOREIGN_UNIQUE, array('resourcelinkid'),
-            'enrol_lti_lti2_resource_link', array('id'));
-
-        // Conditionally launch create table for enrol_lti_lti2_share_key.
-        if (!$dbman->table_exists($table)) {
-            $dbman->create_table($table);
-        }
-
-        // Define table enrol_lti_lti2_user_result to be created.
-        $table = new xmldb_table('enrol_lti_lti2_user_result');
-
-        // Adding fields to table enrol_lti_lti2_user_result.
-        $table->add_field('id', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('resourcelinkid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('ltiuserkey', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('ltiresultsourcedid', XMLDB_TYPE_CHAR, '1024', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('created', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('updated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-
-        // Adding keys to table enrol_lti_lti2_user_result.
-        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
-        $table->add_key('resourcelinkid', XMLDB_KEY_FOREIGN, array('resourcelinkid'),
-            'enrol_lti_lti2_resource_link', array('id'));
-
-        // Conditionally launch create table for enrol_lti_lti2_user_result.
-        if (!$dbman->table_exists($table)) {
-            $dbman->create_table($table);
-        }
-
-        // Define table enrol_lti_tool_consumer_map to be created.
-        $table = new xmldb_table('enrol_lti_tool_consumer_map');
-
-        // Adding fields to table enrol_lti_tool_consumer_map.
-        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('toolid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('consumerid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null);
-
-        // Adding keys to table enrol_lti_tool_consumer_map.
-        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
-        $table->add_key('toolid', XMLDB_KEY_FOREIGN, array('toolid'), 'enrol_lti_tools', array('id'));
-        $table->add_key('consumerid', XMLDB_KEY_FOREIGN, array('consumerid'), 'enrol_lti_lti2_consumer', array('id'));
-
-        // Conditionally launch create table for enrol_lti_tool_consumer_map.
-        if (!$dbman->table_exists($table)) {
-            $dbman->create_table($table);
-        }
-
-        // Lti savepoint reached.
-        upgrade_plugin_savepoint(true, 2016052303, 'enrol', 'lti');
-    }
-
-    if ($oldversion < 2016052304) {
-
-        // Define field type to be added to enrol_lti_lti2_context.
-        $table = new xmldb_table('enrol_lti_lti2_context');
-        $field = new xmldb_field('type', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'lticontextkey');
-
-        // Conditionally launch add field type.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Lti savepoint reached.
-        upgrade_plugin_savepoint(true, 2016052304, 'enrol', 'lti');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017011300) {
 
         // Changing precision of field value on table enrol_lti_lti2_nonce to (64).
index 9d3b967..48dfc69 100644 (file)
@@ -27,9 +27,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_enrol_manual_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index e42f78f..f6d9efb 100644 (file)
@@ -27,9 +27,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_enrol_mnet_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 5732fe2..93ebd50 100644 (file)
@@ -47,9 +47,6 @@ function xmldb_enrol_paypal_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 6436e7c..cb255e8 100644 (file)
 defined('MOODLE_INTERNAL') || die();
 
 function xmldb_enrol_self_upgrade($oldversion) {
-    global $CFG, $DB;
-
-    if ($oldversion < 2016052301) {
-        // Get roles with manager archetype.
-        $managerroles = get_archetype_roles('manager');
-        if (!empty($managerroles)) {
-            // Remove wrong CAP_PROHIBIT from self:holdkey.
-            foreach ($managerroles as $role) {
-                $DB->execute("DELETE
-                                FROM {role_capabilities}
-                               WHERE roleid = ? AND capability = ? AND permission = ?",
-                        array($role->id, 'enrol/self:holdkey', CAP_PROHIBIT));
-            }
-        }
-        upgrade_plugin_savepoint(true, 2016052301, 'enrol', 'self');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
index 754152c..e4bb953 100644 (file)
@@ -33,35 +33,6 @@ function xmldb_filter_mathjaxloader_upgrade($oldversion) {
 
     require_once($CFG->dirroot . '/filter/mathjaxloader/db/upgradelib.php');
 
-    if ($oldversion < 2016080200) {
-        // We are consolodating the two settings for http and https url into only the https
-        // setting. Since it is preferably to always load the secure resource.
-
-        $httpurl = get_config('filter_mathjaxloader', 'httpurl');
-        if ($httpurl !== 'http://cdn.mathjax.org/mathjax/2.6-latest/MathJax.js' &&
-            $httpurl !== 'http://cdn.mathjax.org/mathjax/2.6.1/MathJax.js') {
-            // If the http setting has been changed, we make the admin choose the https setting because
-            // it indicates some sort of custom setup. This will be supported by the release notes.
-            unset_config('httpsurl', 'filter_mathjaxloader');
-        }
-
-        // The seperate http setting has been removed. We always use the secure resource.
-        unset_config('httpurl', 'filter_mathjaxloader');
-
-        upgrade_plugin_savepoint(true, 2016080200, 'filter', 'mathjaxloader');
-    }
-
-    if ($oldversion < 2016102500) {
-        $httpsurl = get_config('filter_mathjaxloader', 'httpsurl');
-        if ($httpsurl === "https://cdn.mathjax.org/mathjax/2.6-latest/MathJax.js") {
-            set_config('httpsurl', 'https://cdn.mathjax.org/mathjax/2.7-latest/MathJax.js', 'filter_mathjaxloader');
-        }
-        upgrade_plugin_savepoint(true, 2016102500, 'filter', 'mathjaxloader');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-    //
     if ($oldversion < 2017040300) {
 
         $httpsurl = get_config('filter_mathjaxloader', 'httpsurl');
index 09391c3..a8a43ac 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_filter_mediaplugin_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index da0d43a..ec40486 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_filter_tex_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index e781e99..290350d 100644 (file)
@@ -37,9 +37,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_gradingform_guide_upgrade($oldversion) {
     global $DB;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index a48635c..e7e0bdf 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_gradingform_rubric_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index a2d2496..bc436ed 100644 (file)
@@ -29,9 +29,6 @@
 function xmldb_gradereport_user_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 243344f..c2aad42 100644 (file)
@@ -280,6 +280,7 @@ $string['configmaxevents'] = 'Events to Lookahead';
 $string['configmessaging'] = 'If enabled, users can send messages to other users on the site.';
 $string['configmessagingallowemailoverride'] = 'Allow users to have email message notifications sent to an email address other than the email address in their profile';
 $string['configmessagingdeletereadnotificationsdelay'] = 'Read notifications can be deleted to save space. How long after a notification is read can it be deleted?';
+$string['configmessagingdeleteallnotificationsdelay'] = 'Read and unread notifications can be deleted to save space. How long after a notification is created can it be deleted?';
 $string['configmessagingallusers'] = 'If enabled, users can view the list of all users on the site when selecting someone to message, and their message preferences include the option to accept messages from anyone on the site. If disabled, users can only view the list of users in their courses, and they have just two options in message preferences - to accept messages from their contacts only, or their contacts and anyone in their courses.';
 $string['configminpassworddigits'] = 'Passwords must have at least these many digits.';
 $string['configminpasswordlength'] = 'Passwords must be at least these many characters long.';
@@ -769,6 +770,7 @@ $string['messaging'] = 'Enable messaging system';
 $string['messagingallowemailoverride'] = 'Notification email override';
 $string['messagingallusers'] = 'Allow site-wide messaging';
 $string['messagingdeletereadnotificationsdelay'] = 'Delete read notifications';
+$string['messagingdeleteallnotificationsdelay'] = 'Delete all notifications';
 $string['minpassworddigits'] = 'Digits';
 $string['minpasswordlength'] = 'Password length';
 $string['minpasswordlower'] = 'Lowercase letters';
index 661071e..096b837 100644 (file)
Binary files a/lib/amd/build/modal.min.js and b/lib/amd/build/modal.min.js differ
index d357c17..9e03a10 100644 (file)
Binary files a/lib/amd/build/str.min.js and b/lib/amd/build/str.min.js differ
index 3357ba4..b5be0b1 100644 (file)
Binary files a/lib/amd/build/templates.min.js and b/lib/amd/build/templates.min.js differ
index be98211..799b3dc 100644 (file)
@@ -723,7 +723,12 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes',
             // If the click wasn't inside the modal element then we should
             // hide the modal.
             if (!$(e.target).closest(SELECTORS.MODAL).length) {
-                this.hide();
+                // The check above fails to detect the click was inside the modal when the DOM tree is already changed.
+                // So, we check if we can still find the container element or not. If not, then the DOM tree is changed.
+                // It's best not to hide the modal in that case.
+                if ($(e.target).closest(SELECTORS.CONTAINER).length) {
+                    this.hide();
+                }
             }
         }.bind(this));
 
index eac5c54..286fb48 100644 (file)
@@ -176,6 +176,42 @@ define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage)
             }
 
             return deferred.promise();
+        },
+        /**
+         * Add a list of strings to the caches.
+         *
+         * @method cache_strings
+         * @param {Object[]} strings Array of { key: key, component: component, lang: lang, value: value }
+         */
+         // eslint-disable-next-line camelcase
+        cache_strings: function(strings) {
+            var defaultLang = $('html').attr('lang').replace(/-/g, '_');
+            strings.forEach(function(string) {
+                var lang = !(lang in string) ? defaultLang : string.lang;
+                var key = string.key;
+                var component = string.component;
+                var value = string.value;
+                var cacheKey = ['core_str', key, component, lang].join('/');
+
+                // Check M.str caching.
+                if (!(component in M.str) || !(key in M.str[component])) {
+                    if (!(component in M.str)) {
+                        M.str[component] = {};
+                    }
+
+                    M.str[component][key] = value;
+                }
+
+                // Check local storage.
+                if (!storage.get(cacheKey)) {
+                    storage.set(cacheKey, value);
+                }
+
+                // Check the promises cache.
+                if (!(cacheKey in promiseCache)) {
+                    promiseCache[cacheKey] = $.Deferred().resolve(value).promise();
+                }
+            });
         }
     };
 });
index 514f210..748cea5 100644 (file)
@@ -59,6 +59,191 @@ define([
     /** @var {Object} iconSystem - Object extending core/iconsystem */
     var iconSystem = {};
 
+    /** @var {Object[]} loadTemplateBuffer - List of templates to be loaded */
+    var loadTemplateBuffer = [];
+
+    /** @var {Bool} isLoadingTemplates - Whether templates are currently being loaded */
+    var isLoadingTemplates = false;
+
+    /**
+     * Search the various caches for a template promise for the given search key.
+     * The search key should be in the format <theme>/<component>/<template> e.g. boost/core/modal.
+     *
+     * If the template is found in any of the caches it will populate the other caches with
+     * the same data as well.
+     *
+     * @param {String} searchKey The template search key in the format <theme>/<component>/<template> e.g. boost/core/modal
+     * @return {Object} jQuery promise resolved with the template source
+     */
+    var getTemplatePromiseFromCache = function(searchKey) {
+        // First try the cache of promises.
+        if (searchKey in templatePromises) {
+            return templatePromises[searchKey];
+        }
+
+        // Check the module cache.
+        if (searchKey in templateCache) {
+            // Add this to the promises cache for future.
+            templatePromises[searchKey] = $.Deferred().resolve(templateCache[searchKey]).promise();
+            return templatePromises[searchKey];
+        }
+
+        // Now try local storage.
+        var cached = storage.get('core_template/' + searchKey);
+        if (cached) {
+            // Add this to the module cache for future.
+            templateCache[searchKey] = cached;
+            // Add this to the promises cache for future.
+            templatePromises[searchKey] = $.Deferred().resolve(cached).promise();
+            return templatePromises[searchKey];
+        }
+
+        return null;
+    };
+
+    /**
+     * Take all of the templates waiting in the buffer and load them from the server
+     * or from the cache.
+     *
+     * All of the templates that need to be loaded from the server will be batched up
+     * and sent in a single network request.
+     */
+    var processLoadTemplateBuffer = function() {
+        if (!loadTemplateBuffer.length) {
+            return;
+        }
+
+        if (isLoadingTemplates) {
+            return;
+        }
+
+        isLoadingTemplates = true;
+        // Grab any templates waiting in the buffer.
+        var templatesToLoad = loadTemplateBuffer.slice();
+        // This will be resolved with the list of promises for the server request.
+        var serverRequestsDeferred = $.Deferred();
+        var requests = [];
+        // Get a list of promises for each of the templates we need to load.
+        var templatePromises = templatesToLoad.map(function(templateData) {
+            var component = templateData.component;
+            var name = templateData.name;
+            var searchKey = templateData.searchKey;
+            var theme = templateData.theme;
+            var templateDeferred = templateData.deferred;
+            var promise = null;
+
+            // Double check to see if this template happened to have landed in the
+            // cache as a dependency of an earlier template.
+            var cachedPromise = getTemplatePromiseFromCache(searchKey);
+            if (cachedPromise) {
+                // We've seen this template so immediately resolve the existing promise.
+                promise = cachedPromise;
+            } else {
+                // We haven't seen this template yet so we need to request it from
+                // the server.
+                requests.push({
+                    methodname: 'core_output_load_template_with_dependencies',
+                    args: {
+                        component: component,
+                        template: name,
+                        themename: theme
+                    }
+                });
+                // Remember the index in the requests list for this template so that
+                // we can get the appropriate promise back.
+                var index = requests.length - 1;
+
+                // The server deferred will be resolved with a list of all of the promises
+                // that were sent in the order that they were added to the requests array.
+                promise = serverRequestsDeferred.promise()
+                    .then(function(promises) {
+                        // The promise for this template will be the one that matches the index
+                        // for it's entry in the requests array.
+                        //
+                        // Make sure the promise is added to the promises cache for this template
+                        // search key so that we don't request it again.
+                        templatePromises[searchKey] = promises[index].then(function(response) {
+                            var templateSource = null;
+
+                            // Process all of the template dependencies for this template and add
+                            // them to the caches so that we don't request them again later.
+                            response.templates.forEach(function(data) {
+                                // Generate the search key for this template in the response so that we
+                                // can add it to the caches.
+                                var tempSearchKey = [theme, data.component, data.name].join('/');
+                                // Cache all of the dependent templates because we'll need them to render
+                                // the requested template.
+                                templateCache[tempSearchKey] = data.value;
+                                storage.set('core_template/' + tempSearchKey, data.value);
+
+                                if (data.component == component && data.name == name) {
+                                    // This is the original template that was requested so remember it to return.
+                                    templateSource = data.value;
+                                }
+                            });
+
+                            if (response.strings.length) {
+                                // If we have strings that the template needs then warm the string cache
+                                // with them now so that we don't need to re-fetch them.
+                                str.cache_strings(response.strings.map(function(data) {
+                                    return {
+                                        component: data.component,
+                                        key: data.name,
+                                        value: data.value
+                                    };
+                                }));
+                            }
+
+                            // Return the original template source that the user requested.
+                            return templateSource;
+                        });
+
+                        return templatePromises[searchKey];
+                    });
+            }
+
+            return promise
+                .then(function(source) {
+                    // When we've successfully loaded the template then resolve the deferred
+                    // in the buffer so that all of the calling code can proceed.
+                    return templateDeferred.resolve(source);
+                })
+                .catch(function(error) {
+                    // If there was an error loading the template then reject the deferred
+                    // in the buffer so that all of the calling code can proceed.
+                    templateDeferred.reject(error);
+                    // Rethrow for anyone else listening.
+                    throw error;
+                });
+        });
+
+        if (requests.length) {
+            // We have requests to send so resolve the deferred with the promises.
+            serverRequestsDeferred.resolve(ajax.call(requests, true, false));
+        } else {
+            // Nothing to load so we can resolve our deferred.
+            serverRequestsDeferred.resolve();
+        }
+
+        // Once we've finished loading all of the templates then recurse to process
+        // any templates that may have been added to the buffer in the time that we
+        // were fetching.
+        $.when.apply(null, templatePromises)
+            .then(function() {
+                // Remove the templates we've loaded from the buffer.
+                loadTemplateBuffer.splice(0, templatesToLoad.length);
+                isLoadingTemplates = false;
+                processLoadTemplateBuffer();
+                return;
+            })
+            .catch(function() {
+                // Remove the templates we've loaded from the buffer.
+                loadTemplateBuffer.splice(0, templatesToLoad.length);
+                isLoadingTemplates = false;
+                processLoadTemplateBuffer();
+            });
+    };
+
     /**
      * Constructor
      *
@@ -85,7 +270,7 @@ define([
     Renderer.prototype.currentThemeName = '';
 
     /**
-     * Load a template from the cache or local storage or ajax request.
+     * Load a template.
      *
      * @method getTemplate
      * @private
@@ -95,44 +280,44 @@ define([
      * @return {Promise} JQuery promise object resolved when the template has been fetched.
      */
     Renderer.prototype.getTemplate = function(templateName) {
-        var parts = templateName.split('/');
-        var component = parts.shift();
-        var name = parts.shift();
-
-        var searchKey = this.currentThemeName + '/' + templateName;
+        var currentTheme = this.currentThemeName;
+        var searchKey = currentTheme + '/' + templateName;
 
-        // First try request variables.
-        if (searchKey in templatePromises) {
-            return templatePromises[searchKey];
+        // If we haven't already seen this template then buffer it.
+        var cachedPromise = getTemplatePromiseFromCache(searchKey);
+        if (cachedPromise) {
+            return cachedPromise;
         }
 
-        // Now try local storage.
-        var cached = storage.get('core_template/' + searchKey);
-
-        if (cached) {
-            templateCache[searchKey] = cached;
-            templatePromises[searchKey] = $.Deferred().resolve(cached).promise();
-            return templatePromises[searchKey];
+        // Check the buffer to seee if this template has already been added.
+        var existingBufferRecords = loadTemplateBuffer.filter(function(record) {
+            return record.searchKey == searchKey;
+        });
+        if (existingBufferRecords.length) {
+            // This template is already in the buffer so just return the existing
+            // promise. No need to add it to the buffer again.
+            return existingBufferRecords[0].deferred.promise();
         }
 
-        // Oh well - load via ajax.
-        var promises = ajax.call([{
-            methodname: 'core_output_load_template',
-            args: {
-                component: component,
-                template: name,
-                themename: this.currentThemeName
-            }
-        }], true, false);
+        // This is the first time this has been requested so let's add it to the buffer
+        // to be loaded.
+        var parts = templateName.split('/');
+        var component = parts.shift();
+        var name = parts.shift();
+        var deferred = $.Deferred();
+
+        // Add this template to the buffer to be loaded.
+        loadTemplateBuffer.push({
+            component: component,
+            name: name,
+            theme: currentTheme,
+            searchKey: searchKey,
+            deferred: deferred
+        });
 
-        templatePromises[searchKey] = promises[0].then(
-            function(templateSource) {
-                templateCache[searchKey] = templateSource;
-                storage.set('core_template/' + searchKey, templateSource);
-                return templateSource;
-            }
-        );
-        return templatePromises[searchKey];
+        // We know there is at least one thing in the buffer so kick off a processing run.
+        processLoadTemplateBuffer();
+        return deferred.promise();
     };
 
     /**
index 2ff3f9f..493f0fd 100644 (file)
@@ -32,25 +32,6 @@ defined('MOODLE_INTERNAL') || die();
  */
 function xmldb_antivirus_clamav_upgrade($oldversion) {
 
-    if ($oldversion < 2016101700) {
-        // Remove setting that has been deprecated long time ago at MDL-44260.
-        unset_config('quarantinedir', 'antivirus_clamav');
-        upgrade_plugin_savepoint(true, 2016101700, 'antivirus', 'clamav');
-    }
-
-    if ($oldversion < 2016102600) {
-        // Make command line a default running method for now. We depend on this
-        // config variable in antivirus scan running, it should be defined.
-        if (!get_config('antivirus_clamav', 'runningmethod')) {
-            set_config('runningmethod', 'commandline', 'antivirus_clamav');
-        }
-
-        upgrade_plugin_savepoint(true, 2016102600, 'antivirus', 'clamav');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 509ec44..cdca30c 100644 (file)
@@ -58,15 +58,6 @@ class external extends external_api {
             );
     }
 
-    /**
-     * Remove comments from mustache template.
-     * @param string $templatestr
-     * @return mixed
-     */
-    protected static function strip_template_comments($templatestr) {
-        return preg_replace('/(?={{!)(.*)(}})/sU', '', $templatestr);
-    }
-
     /**
      * Return a mustache template, and all the strings it requires.
      *
@@ -84,23 +75,14 @@ class external extends external_api {
                                                   'themename' => $themename,
                                                   'includecomments' => $includecomments));
 
-        $component = $params['component'];
-        $template = $params['template'];
-        $themename = $params['themename'];
-        $includecomments = $params['includecomments'];
-
-        $templatename = $component . '/' . $template;
-
+        $loader = new mustache_template_source_loader();
         // Will throw exceptions if the template does not exist.
-        $filename = mustache_template_finder::get_template_filepath($templatename, $themename);
-        $templatestr = file_get_contents($filename);
-
-        // Remove comments from template.
-        if (!$includecomments) {
-            $templatestr = self::strip_template_comments($templatestr);
-        }
-
-        return $templatestr;
+        return $loader->load(
+            $params['component'],
+            $params['template'],
+            $params['themename'],
+            $params['includecomments']
+        );
     }
 
     /**
@@ -112,6 +94,95 @@ class external extends external_api {
         return new external_value(PARAM_RAW, 'template');
     }
 
+    /**
+     * Returns description of load_template_with_dependencies() parameters.
+     *
+     * @return external_function_parameters
+     */
+    public static function load_template_with_dependencies_parameters() {
+        return new external_function_parameters([
+            'component' => new external_value(PARAM_COMPONENT, 'component containing the template'),
+            'template' => new external_value(PARAM_ALPHANUMEXT, 'name of the template'),
+            'themename' => new external_value(PARAM_ALPHANUMEXT, 'The current theme.'),
+            'includecomments' => new external_value(PARAM_BOOL, 'Include comments or not', VALUE_DEFAULT, false)
+        ]);
+    }
+
+    /**
+     * Return a mustache template, and all the child templates and strings it requires.
+     *
+     * @param string $component The component that holds the template.
+     * @param string $template The name of the template.
+     * @param string $themename The name of the current theme.
+     * @param bool $includecomments Whether to strip comments from the template source.
+     * @return string the template
+     */
+    public static function load_template_with_dependencies(
+        string $component,
+        string $template,
+        string $themename,
+        bool $includecomments = false
+    ) {
+        global $DB, $CFG, $PAGE;
+
+        $params = self::validate_parameters(
+            self::load_template_with_dependencies_parameters(),
+            [
+                'component' => $component,
+                'template' => $template,
+                'themename' => $themename,
+                'includecomments' => $includecomments
+            ]
+        );
+
+        $loader = new mustache_template_source_loader();
+        // Will throw exceptions if the template does not exist.
+        $dependencies = $loader->load_with_dependencies(
+            $params['component'],
+            $params['template'],
+            $params['themename'],
+            $params['includecomments']
+        );
+        $formatdependencies = function($dependency) {
+            $results = [];
+            foreach ($dependency as $dependencycomponent => $dependencyvalues) {
+                foreach ($dependencyvalues as $dependencyname => $dependencyvalue) {
+                    array_push($results, [
+                        'component' => $dependencycomponent,
+                        'name' => $dependencyname,
+                        'value' => $dependencyvalue
+                    ]);
+                }
+            }
+            return $results;
+        };
+
+        // Now we have to unpack the dependencies into a format that can be returned
+        // by external functions (because they don't support dynamic keys).
+        return [
+            'templates' => $formatdependencies($dependencies['templates']),
+            'strings' => $formatdependencies($dependencies['strings'])
+        ];
+    }
+
+    /**
+     * Returns description of load_template_with_dependencies() result value.
+     *
+     * @return external_description
+     */
+    public static function load_template_with_dependencies_returns() {
+        $resourcestructure = new external_single_structure([
+            'component' => new external_value(PARAM_COMPONENT, 'component containing the resource'),
+            'name' => new external_value(PARAM_TEXT, 'name of the resource'),
+            'value' => new external_value(PARAM_RAW, 'resource value')
+        ]);
+
+        return new external_single_structure([
+            'templates' => new external_multiple_structure($resourcestructure),
+            'strings' => new external_multiple_structure($resourcestructure)
+        ]);
+    }
+
     /**
      * Returns description of load_icon_map() parameters.
      *
diff --git a/lib/classes/output/mustache_template_source_loader.php b/lib/classes/output/mustache_template_source_loader.php
new file mode 100644 (file)
index 0000000..6be1275
--- /dev/null
@@ -0,0 +1,342 @@
+<?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/>.
+
+/**
+ * Load template source strings.
+ *
+ * @package    core
+ * @category   output
+ * @copyright  2018 Ryan Wyllie <ryan@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\output;
+
+defined('MOODLE_INTERNAL') || die();
+
+use \Mustache_Tokenizer;
+
+/**
+ * Load template source strings.
+ *
+ * @copyright  2018 Ryan Wyllie <ryan@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class mustache_template_source_loader {
+
+    /** @var $gettemplatesource Callback function to load the template source from full name */
+    private $gettemplatesource = null;
+
+    /**
+     * Constructor that takes a callback to allow the calling code to specify how to retrieve
+     * the source for a template name.
+     *
+     * If no callback is provided then default to the load from disk implementation.
+     *
+     * @param callable|null $gettemplatesource Callback to load template source by template name
+     */
+    public function __construct(callable $gettemplatesource = null) {
+        if ($gettemplatesource) {
+            // The calling code has specified a function for retrieving the template source
+            // code by name and theme.
+            $this->gettemplatesource = $gettemplatesource;
+        } else {
+            // By default we will pull the template from disk.
+            $this->gettemplatesource = function($component, $name, $themename) {
+                $fulltemplatename = $component . '/' . $name;
+                $filename = mustache_template_finder::get_template_filepath($fulltemplatename, $themename);
+                return file_get_contents($filename);
+            };
+        }
+    }
+
+    /**
+     * Remove comments from mustache template.
+     *
+     * @param string $templatestr
+     * @return string
+     */
+    protected function strip_template_comments($templatestr) : string {
+        return preg_replace('/(?={{!)(.*)(}})/sU', '', $templatestr);
+    }
+
+    /**
+     * Load the template source from the component and template name.
+     *
+     * @param string $component The moodle component (e.g. core_message)
+     * @param string $name The template name (e.g. message_drawer)
+     * @param string $themename The theme to load the template for (e.g. boost)
+     * @param bool $includecomments If the comments should be stripped from the source before returning
+     * @return string The template source
+     */
+    public function load(
+        string $component,
+        string $name,
+        string $themename,
+        bool $includecomments = false
+    ) : string {
+        // Get the template source from the callback.
+        $source = ($this->gettemplatesource)($component, $name, $themename);
+
+        // Remove comments from template.
+        if (!$includecomments) {
+            $source = $this->strip_template_comments($source);
+        }
+
+        return $source;
+    }
+
+    /**
+     * Load a template and some of the dependencies that will be needed in order to render
+     * the template.
+     *
+     * The current implementation will return all of the templates and all of the strings in
+     * each of those templates (excluding string substitutions).
+     *
+     * The return format is an array indexed with the dependency type (e.g. templates / strings) then
+     * the component (e.g. core_message), and then the id (e.g. message_drawer).
+     *
+     * For example:
+     * * We have 3 templates in core named foo, bar, and baz.
+     * * foo includes bar and bar includes baz.
+     * * foo uses the string 'home' from core
+     * * baz uses the string 'help' from core
+     *
+     * If we load the template foo this function would return:
+     * [
+     *      'templates' => [
+     *          'core' => [
+     *              'foo' => '... template source ...',
+     *              'bar' => '... template source ...',
+     *              'baz' => '... template source ...',
+     *          ]
+     *      ],
+     *      'strings' => [
+     *          'core' => [
+     *              'home' => 'Home',
+     *              'help' => 'Help'
+     *          ]
+     *      ]
+     * ]
+     *
+     * @param string $templatecomponent The moodle component (e.g. core_message)
+     * @param string $templatename The template name (e.g. message_drawer)
+     * @param string $themename The theme to load the template for (e.g. boost)
+     * @param bool $includecomments If the comments should be stripped from the source before returning
+     * @param array $seentemplates List of templates already processed / to be skipped.
+     * @param array $seenstrings List of strings already processed / to be skipped.
+     * @return array
+     */
+    public function load_with_dependencies(
+        string $templatecomponent,
+        string $templatename,
+        string $themename,
+        bool $includecomments = false,
+        array $seentemplates = [],
+        array $seenstrings = []
+    ) : array {
+        // Initialise the return values.
+        $templates = [];
+        $strings = [];
+        $templatecomponent = trim($templatecomponent);
+        $templatename = trim($templatename);
+        // Get the requested template source.
+        $templatesource = $this->load($templatecomponent, $templatename, $themename, $includecomments);
+        // This is a helper function to save a value in one of the result arrays (either $templates or $strings).
+        $save = function(array $results, array $seenlist, string $component, string $id, $value) {
+            if (!isset($results[$component])) {
+                // If the results list doesn't already contain this component then initialise it.
+                $results[$component] = [];
+            }
+
+            // Save the value.
+            $results[$component][$id] = $value;
+            // Record that this item has been processed.
+            array_push($seenlist, "$component/$id");
+            // Return the updated results and seen list.
+            return [$results, $seenlist];
+        };
+        // This is a helper function for processing a dependency. Does stuff like ignore duplicate processing,
+        // common result formatting etc.
+        $handler = function(array $dependency, array $ignorelist, callable $processcallback) {
+            foreach ($dependency as $component => $ids) {
+                foreach ($ids as $id) {
+                    $dependencyid = "$component/$id";
+                    if (array_search($dependencyid, $ignorelist) === false) {
+                        $processcallback($component, $id);
+                        // Add this to our ignore list now that we've processed it so that we don't
+                        // process it again.
+                        array_push($ignorelist, $dependencyid);
+                    }
+                }
+            }
+
+            return $ignorelist;
+        };
+
+        // Save this template as the first result in the $templates result array.
+        list($templates, $seentemplates) = $save($templates, $seentemplates, $templatecomponent, $templatename, $templatesource);
+
+        // Check the template for any dependencies that need to be loaded.
+        $dependencies = $this->scan_template_source_for_dependencies($templatesource);
+
+        // Load all of the lang strings that this template requires and add them to the
+        // returned values.
+        $seenstrings = $handler(
+            $dependencies['strings'],
+            $seenstrings,
+            // Include $strings and $seenstrings by reference so that their values can be updated
+            // outside of this anonymous function.
+            function($component, $id) use ($save, &$strings, &$seenstrings) {
+                $string = get_string($id, $component);
+                // Save the string in the $strings results array.
+                list($strings, $seenstrings) = $save($strings, $seenstrings, $component, $id, $string);
+            }
+        );
+
+        // Load any child templates that we've found in this template and add them to
+        // the return list of dependencies.
+        $seentemplates = $handler(
+            $dependencies['templates'],
+            $seentemplates,
+            // Include $strings, $seenstrings, $templates, and $seentemplates by reference so that their values can be updated
+            // outside of this anonymous function.
+            function($component, $id) use (
+                $themename,
+                $includecomments,
+                &$seentemplates,
+                &$seenstrings,
+                &$templates,
+                &$strings,
+                $save
+            ) {
+                // We haven't seen this template yet so load it and it's dependencies.
+                $subdependencies = $this->load_with_dependencies(
+                    $component,
+                    $id,
+                    $themename,
+                    $includecomments,
+                    $seentemplates,
+                    $seenstrings
+                );
+
+                foreach ($subdependencies['templates'] as $component => $ids) {
+                    foreach ($ids as $id => $value) {
+                        // Include the child themes in our results.
+                        list($templates, $seentemplates) = $save($templates, $seentemplates, $component, $id, $value);
+                    }
+                };
+
+                foreach ($subdependencies['strings'] as $component => $ids) {
+                    foreach ($ids as $id => $value) {
+                        // Include any strings that the child templates need in our results.
+                        list($strings, $seenstrings) = $save($strings, $seenstrings, $component, $id, $value);
+                    }
+                }
+            }
+        );
+
+        return [
+            'templates' => $templates,
+            'strings' => $strings
+        ];
+    }
+
+    /**
+     * Scan over a template source string and return a list of dependencies it requires.
+     * At the moment the list will only include other templates and strings.
+     *
+     * The return format is an array indexed with the dependency type (e.g. templates / strings) then
+     * the component (e.g. core_message) with it's value being an array of the items required
+     * in that component.
+     *
+     * For example:
+     * If we have a template foo that includes 2 templates, bar and baz, and also 2 strings
+     * 'home' and 'help' from the core component then the return value would look like:
+     *
+     * [
+     *      'templates' => [
+     *          'core' => ['foo', 'bar', 'baz']
+     *      ],
+     *      'strings' => [
+     *          'core' => ['home', 'help']
+     *      ]
+     * ]
+     *
+     * @param string $source The template source
+     * @return array
+     */
+    protected function scan_template_source_for_dependencies(string $source) : array {
+        $tokenizer = new Mustache_Tokenizer();
+        $tokens = $tokenizer->scan($source);
+        $templates = [];
+        $strings = [];
+        $addtodependencies = function($dependencies, $component, $id) {
+            $id = trim($id);
+            $component = trim($component);
+
+            if (!isset($dependencies[$component])) {
+                // Initialise the component if we haven't seen it before.
+                $dependencies[$component] = [];
+            }
+
+            // Add this id to the list of dependencies.
+            array_push($dependencies[$component], $id);
+
+            return $dependencies;
+        };
+
+        foreach ($tokens as $index => $token) {
+            $type = $token['type'];
+            $name = isset($token['name']) ? $token['name'] : null;
+
+            if ($name) {
+                switch ($type) {
+                    case Mustache_Tokenizer::T_PARTIAL:
+                        list($component, $id) = explode('/', $name);
+                        $templates = $addtodependencies($templates, $component, $id);
+                        break;
+                    case Mustache_Tokenizer::T_PARENT:
+                        list($component, $id) = explode('/', $name);
+                        $templates = $addtodependencies($templates, $component, $id);
+                        break;
+                    case Mustache_Tokenizer::T_SECTION:
+                        if ($name == 'str') {
+                            // The token that containts the string identifiers (key and component) should
+                            // immediately follow the #str token.
+                            $identifiertoken = isset($tokens[$index + 1]) ? $tokens[$index + 1] : null;
+
+                            if ($identifiertoken) {
+                                // The string identifier is the key and component comma separated.
+                                $identifierstring = $identifiertoken['value'];
+                                $parts = explode(',', $identifierstring);
+                                $id = $parts[0];
+                                // Default to 'core' for the component, if not specified.
+                                $component = isset($parts[1]) ? $parts[1] : 'core';
+                                $strings = $addtodependencies($strings, $component, $id);
+                            }
+                        }
+                        break;
+                }
+            }
+        }
+
+        return [
+            'templates' => $templates,
+            'strings' => $strings
+        ];
+    }
+}
index 6d1a2c4..15b781f 100644 (file)
@@ -46,13 +46,18 @@ class messaging_cleanup_task extends scheduled_task {
 
         $timenow = time();
 
-        // Cleanup messaging.
+        // Cleanup read and unread notifications.
+        if (!empty($CFG->messagingdeleteallnotificationsdelay)) {
+            $notificationdeletetime = $timenow - $CFG->messagingdeleteallnotificationsdelay;
+            $params = array('notificationdeletetime' => $notificationdeletetime);
+            $DB->delete_records_select('notifications', 'timecreated < :notificationdeletetime', $params);
+        }
+
+        // Cleanup read notifications.
         if (!empty($CFG->messagingdeletereadnotificationsdelay)) {
             $notificationdeletetime = $timenow - $CFG->messagingdeletereadnotificationsdelay;
             $params = array('notificationdeletetime' => $notificationdeletetime);
             $DB->delete_records_select('notifications', 'timeread < :notificationdeletetime', $params);
         }
-
     }
-
 }
index 6d930b8..066f226 100644 (file)
@@ -1396,6 +1396,14 @@ $functions = array(
         'loginrequired' => false,
         'ajax' => true,
     ),
+    'core_output_load_template_with_dependencies' => array(
+        'classname' => 'core\output\external',
+        'methodname' => 'load_template_with_dependencies',
+        'description' => 'Load a template and its dependencies for a renderable',
+        'type' => 'read',
+        'loginrequired' => false,
+        'ajax' => true,
+    ),
     'core_output_load_fontawesome_icon_map' => array(
         'classname' => 'core\output\external',
         'methodname' => 'load_fontawesome_icon_map',
index 35cf1da..eb00748 100644 (file)
@@ -92,388 +92,15 @@ function xmldb_main_upgrade($oldversion) {
     $dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes.
 
     // Always keep this upgrade step with version being the minimum
-    // allowed version to upgrade from (v3.1.0 right now).
-    if ($oldversion < 2016052300) {
+    // allowed version to upgrade from (v3.2.0 right now).
+    if ($oldversion < 2016120500) {
         // Just in case somebody hacks upgrade scripts or env, we really can not continue.
-        echo("You need to upgrade to 3.1.x or higher first!\n");
+        echo("You need to upgrade to 3.2.x or higher first!\n");
         exit(1);
         // Note this savepoint is 100% unreachable, but needed to pass the upgrade checks.
-        upgrade_main_savepoint(true, 2016052300);
+        upgrade_main_savepoint(true, 2016120500);
     }
 
-    if ($oldversion < 2016081700.00) {
-
-        // If someone is emotionally attached to it let's leave the config (basically the version) there.
-        if (!file_exists($CFG->dirroot . '/report/search/classes/output/form.php')) {
-            unset_all_config_for_plugin('report_search');
-        }
-
-        // Savepoint reached.
-        upgrade_main_savepoint(true, 2016081700.00);
-    }
-
-    if ($oldversion < 2016081700.02) {
-        // Default schedule values.
-        $hour = 0;
-        $minute = 0;
-
-        // Get the old settings.
-        if (isset($CFG->statsruntimestarthour)) {
-            $hour = $CFG->statsruntimestarthour;
-        }
-        if (isset($CFG->statsruntimestartminute)) {
-            $minute = $CFG->statsruntimestartminute;
-        }
-
-        // Retrieve the scheduled task record first.
-        $stattask = $DB->get_record('task_scheduled', array('component' => 'moodle', 'classname' => '\core\task\stats_cron_task'));
-
-        // Don't touch customised scheduling.
-        if ($stattask && !$stattask->customised) {
-
-            $nextruntime = mktime($hour, $minute, 0, date('m'), date('d'), date('Y'));
-            if ($nextruntime < $stattask->lastruntime) {
-                // Add 24 hours to the next run time.
-                $newtime = new DateTime();
-                $newtime->setTimestamp($nextruntime);
-                $newtime->add(new DateInterval('P1D'));
-                $nextruntime = $newtime->getTimestamp();
-            }
-            $stattask->nextruntime = $nextruntime;
-            $stattask->minute = $minute;
-            $stattask->hour = $hour;
-            $stattask->customised = 1;
-            $DB->update_record('task_scheduled', $stattask);
-        }
-        // These settings are no longer used.
-        unset_config('statsruntimestarthour');
-        unset_config('statsruntimestartminute');
-        unset_config('statslastexecution');
-
-        upgrade_main_savepoint(true, 2016081700.02);
-    }
-
-    if ($oldversion < 2016082200.00) {
-        // An upgrade step to remove any duplicate stamps, within the same context, in the question_categories table, and to
-        // add a unique index to (contextid, stamp) to avoid future stamp duplication. See MDL-54864.
-
-        // Extend the execution time limit of the script to 2 hours.
-        upgrade_set_timeout(7200);
-
-        // This SQL fetches the id of those records which have duplicate stamps within the same context.
-        // This doesn't return the original record within the context, from which the duplicate stamps were likely created.
-        $fromclause = "FROM (
-                        SELECT min(id) AS minid, contextid, stamp
-                            FROM {question_categories}
-                            GROUP BY contextid, stamp
-                        ) minid
-                        JOIN {question_categories} qc
-                            ON qc.contextid = minid.contextid AND qc.stamp = minid.stamp AND qc.id > minid.minid";
-
-        // Get the total record count - used for the progress bar.
-        $countduplicatessql = "SELECT count(qc.id) $fromclause";
-        $total = $DB->count_records_sql($countduplicatessql);
-
-        // Get the records themselves.
-        $getduplicatessql = "SELECT qc.id $fromclause ORDER BY minid";
-        $rs = $DB->get_recordset_sql($getduplicatessql);
-
-        // For each duplicate, update the stamp to a new random value.
-        $i = 0;
-        $pbar = new progress_bar('updatequestioncategorystamp', 500, true);
-        foreach ($rs as $record) {
-            // Generate a new, unique stamp and update the record.
-            do {
-                $newstamp = make_unique_id_code();
-            } while (isset($usedstamps[$newstamp]));
-            $usedstamps[$newstamp] = 1;
-            $DB->set_field('question_categories', 'stamp', $newstamp, array('id' => $record->id));
-
-            // Update progress.
-            $i++;
-            $pbar->update($i, $total, "Updating duplicate question category stamp - $i/$total.");
-        }
-        $rs->close();
-        unset($usedstamps);
-
-        // The uniqueness of each (contextid, stamp) pair is now guaranteed, so add the unique index to stop future duplicates.
-        $table = new xmldb_table('question_categories');
-        $index = new xmldb_index('contextidstamp', XMLDB_INDEX_UNIQUE, array('contextid', 'stamp'));
-        if (!$dbman->index_exists($table, $index)) {
-            $dbman->add_index($table, $index);
-        }
-
-        // Savepoint reached.
-        upgrade_main_savepoint(true, 2016082200.00);
-    }
-
-    if ($oldversion < 2016091900.00) {
-
-        // Removing the themes from core.
-        $themes = array('base', 'canvas');
-
-        foreach ($themes as $key => $theme) {
-            if (check_dir_exists($CFG->dirroot . '/theme/' . $theme, false)) {
-                // Ignore the themes that have been re-downloaded.
-                unset($themes[$key]);
-            }
-        }
-
-        if (!empty($themes)) {
-            // Hacky emulation of plugin uninstallation.
-            foreach ($themes as $theme) {
-                unset_all_config_for_plugin('theme_' . $theme);
-            }
-        }
-
-        // Main savepoint reached.
-        upgrade_main_savepoint(true, 2016091900.00);
-    }
-
-    if ($oldversion < 2016091900.02) {
-
-        // Define index attemptstepid-name (unique) to be dropped from question_attempt_step_data.
-        $table = new xmldb_table('question_attempt_step_data');
-        $index = new xmldb_index('attemptstepid-name', XMLDB_INDEX_UNIQUE, array('attemptstepid', 'name'));
-
-        // Conditionally launch drop index attemptstepid-name.
-        if ($dbman->index_exists($table, $index)) {
-            $dbman->drop_index($table, $index);
-        }
-
-        // Main savepoint reached.
-        upgrade_main_savepoint(true, 2016091900.02);
-    }
-
-    if ($oldversion < 2016100300.00) {
-        unset_config('enablecssoptimiser');
-
-        upgrade_main_savepoint(true, 2016100300.00);
-    }
-
-    if ($oldversion < 2016100501.00) {
-
-        // Define field enddate to be added to course.
-        $table = new xmldb_table('course');
-        $field = new xmldb_field('enddate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'startdate');
-
-        // Conditionally launch add field enddate.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Main savepoint reached.
-        upgrade_main_savepoint(true, 2016100501.00);
-    }
-
-    if ($oldversion < 2016101100.00) {
-        // Define field component to be added to message.
-        $table = new xmldb_table('message');
-        $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'timeusertodeleted');
-
-        // Conditionally launch add field component.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Define field eventtype to be added to message.
-        $field = new xmldb_field('eventtype', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'component');
-
-        // Conditionally launch add field eventtype.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Main savepoint reached.
-        upgrade_main_savepoint(true, 2016101100.00);
-    }
-
-
-    if ($oldversion < 2016101101.00) {
-        // Define field component to be added to message_read.
-        $table = new xmldb_table('message_read');
-        $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'timeusertodeleted');
-
-        // Conditionally launch add field component.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Define field eventtype to be added to message_read.
-        $field = new xmldb_field('eventtype', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'component');
-
-        // Conditionally launch add field eventtype.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Main savepoint reached.
-        upgrade_main_savepoint(true, 2016101101.00);
-    }
-
-    if ($oldversion < 2016101401.00) {
-        // Clean up repository_alfresco config unless plugin has been manually installed.
-        if (!file_exists($CFG->dirroot . '/repository/alfresco/lib.php')) {
-            // Remove capabilities.
-            capabilities_cleanup('repository_alfresco');
-            // Clean config.
-            unset_all_config_for_plugin('repository_alfresco');
-        }
-
-        // Savepoint reached.
-        upgrade_main_savepoint(true, 2016101401.00);
-    }
-
-    if ($oldversion < 2016101401.02) {
-        $table = new xmldb_table('external_tokens');
-        $field = new xmldb_field('privatetoken', XMLDB_TYPE_CHAR, '64', null, null, null, null);
-
-        // Conditionally add privatetoken field to the external_tokens table.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Main savepoint reached.
-        upgrade_main_savepoint(true, 2016101401.02);
-    }
-
-    if ($oldversion < 2016110202.00) {
-
-        // Force uninstall of deleted authentication plugin.
-        if (!file_exists("$CFG->dirroot/auth/radius")) {
-            // Leave settings inplace if there are radius users.
-            if (!$DB->record_exists('user', array('auth' => 'radius', 'deleted' => 0))) {
-                // Remove all other associated config.
-                unset_all_config_for_plugin('auth/radius');
-                // The version number for radius is in this format.
-                unset_all_config_for_plugin('auth_radius');
-            }
-        }
-        upgrade_main_savepoint(true, 2016110202.00);
-    }
-
-    if ($oldversion < 2016110300.00) {
-        // Remove unused admin email setting.
-        unset_config('emailonlyfromreplyaddress');
-
-        // Main savepoint reached.
-        upgrade_main_savepoint(true, 2016110300.00);
-    }
-
-    if ($oldversion < 2016110500.00) {
-
-        $oldplayers = [
-            'vimeo' => null,
-            'mp3' => ['.mp3'],
-            'html5video' => ['.mov', '.mp4', '.m4v', '.mpeg', '.mpe', '.mpg', '.ogv', '.webm'],
-            'flv' => ['.flv', '.f4v'],
-            'html5audio' => ['.aac', '.flac', '.mp3', '.m4a', '.oga', '.ogg', '.wav'],
-            'youtube' => null,
-            'swf' => null,
-        ];
-
-        // Convert hardcoded media players to the settings of the new media player plugin type.
-        if (get_config('core', 'media_plugins_sortorder') === false) {
-            $enabledplugins = [];
-            $videoextensions = [];
-            $audioextensions = [];
-            foreach ($oldplayers as $oldplayer => $extensions) {
-                $settingname = 'core_media_enable_'.$oldplayer;
-                if (!empty($CFG->$settingname)) {
-                    if ($extensions) {
-                        // VideoJS will be used for all media files players that were used previously.
-                        $enabledplugins['videojs'] = 'videojs';
-                        if ($oldplayer === 'mp3' || $oldplayer === 'html5audio') {
-                            $audioextensions += array_combine($extensions, $extensions);
-                        } else {
-                            $videoextensions += array_combine($extensions, $extensions);
-                        }
-                    } else {
-                        // Enable youtube, vimeo and swf.
-                        $enabledplugins[$oldplayer] = $oldplayer;
-                    }
-                }
-            }
-
-            set_config('media_plugins_sortorder', join(',', $enabledplugins));
-
-            // Configure VideoJS to match the existing players set up.
-            if ($enabledplugins['videojs']) {
-                $enabledplugins[] = 'videojs';
-                set_config('audioextensions', join(',', $audioextensions), 'media_videojs');
-                set_config('videoextensions', join(',', $videoextensions), 'media_videojs');
-                $useflash = !empty($CFG->core_media_enable_flv) || !empty($CFG->core_media_enable_mp3);
-                set_config('useflash', $useflash, 'media_videojs');
-                if (empty($CFG->core_media_enable_youtube)) {
-                    // Normally YouTube is enabled in videojs, but if youtube converter was disabled before upgrade
-                    // disable it in videojs as well.
-                    set_config('youtube', false, 'media_videojs');
-                }
-            }
-        }
-
-        // Unset old settings.
-        foreach ($oldplayers as $oldplayer => $extensions) {
-            unset_config('core_media_enable_' . $oldplayer);
-        }
-
-        // Preset defaults if CORE_MEDIA_VIDEO_WIDTH and CORE_MEDIA_VIDEO_HEIGHT are specified in config.php .
-        // After this upgrade step these constants will not be used any more.
-        if (defined('CORE_MEDIA_VIDEO_WIDTH')) {
-            set_config('media_default_width', CORE_MEDIA_VIDEO_WIDTH);
-        }
-        if (defined('CORE_MEDIA_VIDEO_HEIGHT')) {
-            set_config('media_default_height', CORE_MEDIA_VIDEO_HEIGHT);
-        }
-
-        // Savepoint reached.
-        upgrade_main_savepoint(true, 2016110500.00);
-    }
-
-    if ($oldversion < 2016110600.00) {
-        // Define a field 'deletioninprogress' in the 'course_modules' table, to background deletion tasks.
-        $table = new xmldb_table('course_modules');
-        $field = new xmldb_field('deletioninprogress', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'availability');
-
-        // Conditionally launch add field 'deletioninprogress'.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Main savepoint reached.
-        upgrade_main_savepoint(true, 2016110600.00);
-    }
-
-    if ($oldversion < 2016112200.01) {
-
-        // Define field requiredbytheme to be added to block_instances.
-        $table = new xmldb_table('block_instances');
-        $field = new xmldb_field('requiredbytheme', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'showinsubcontexts');
-
-        // Conditionally launch add field requiredbytheme.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Main savepoint reached.
-        upgrade_main_savepoint(true, 2016112200.01);
-    }
-    if ($oldversion < 2016112200.02) {
-
-        // Change the existing site level admin and settings blocks to be requiredbytheme which means they won't show in boost.
-        $context = context_system::instance();
-        $params = array('blockname' => 'settings', 'parentcontextid' => $context->id);
-        $DB->set_field('block_instances', 'requiredbytheme', 1, $params);
-
-        $params = array('blockname' => 'navigation', 'parentcontextid' => $context->id);
-        $DB->set_field('block_instances', 'requiredbytheme', 1, $params);
-        // Main savepoint reached.
-        upgrade_main_savepoint(true, 2016112200.02);
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2016122800.00) {
         // Find all roles with the coursecreator archetype.
         $coursecreatorroleids = $DB->get_records('role', array('archetype' => 'coursecreator'), '', 'id');
index c668c23..2d91167 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_editor_atto_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 0443ae8..e10c52f 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_atto_equation_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index a6a09f3..76c25ef 100644 (file)
@@ -27,9 +27,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_editor_tinymce_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index b387c7f..5408bf6 100644 (file)
@@ -27,9 +27,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_tinymce_spellchecker_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 7beeac0..0c3e0d1 100644 (file)
@@ -48,8 +48,8 @@ function moodle_minimum_php_version_is_met($haltexecution = false) {
     // PLEASE NOTE THIS FUNCTION MUST BE COMPATIBLE WITH OLD UNSUPPORTED VERSIONS OF PHP.
     // Do not use modern php features or Moodle convenience functions (e.g. localised strings).
 
-    $minimumversion = '7.0.0';
-    $moodlerequirementchanged = '3.4';
+    $minimumversion = '7.1.0';
+    $moodlerequirementchanged = '3.7';
 
     if (version_compare(PHP_VERSION, $minimumversion) < 0) {
         if ($haltexecution) {
index 61764ed..22fa4f7 100644 (file)
@@ -921,8 +921,6 @@ function question_load_questions($questionids, $extrafields = '', $join = '') {
  * @param stdClass[]|null $filtercourses The courses to filter the course tags by.
  */
 function _tidy_question($question, $category, array $tagobjects = null, array $filtercourses = null) {
-    global $CFG;
-
     // Load question-type specific fields.
     if (!question_bank::is_qtype_installed($question->qtype)) {
         $question->questiontext = html_writer::tag('p', get_string('warningmissingtype',
@@ -1651,25 +1649,44 @@ class context_to_string_translator{
 /**
  * Check capability on category
  *
- * @param mixed $questionorid object or id. If an object is passed, it should include ->contextid and ->createdby.
+ * @param int|stdClass $questionorid object or id. If an object is passed, it should include ->contextid and ->createdby.
  * @param string $cap 'add', 'edit', 'view', 'use', 'move' or 'tag'.
- * @param integer $notused no longer used.
- * @return boolean this user has the capability $cap for this question $question?
+ * @param int $notused no longer used.
+ * @return bool this user has the capability $cap for this question $question?
+ * @throws coding_exception
  */
 function question_has_capability_on($questionorid, $cap, $notused = -1) {
-    global $USER;
+    global $USER, $DB;
 
     if (is_numeric($questionorid)) {
-        $question = question_bank::load_question_data((int)$questionorid);
+        $questionid = (int)$questionorid;
     } else if (is_object($questionorid)) {
+        // All we really need in this function is the contextid and author of the question.
+        // We won't bother fetching other details of the question if these 2 fields are provided.
         if (isset($questionorid->contextid) && isset($questionorid->createdby)) {
             $question = $questionorid;
+        } else if (!empty($questionorid->id)) {
+            $questionid = $questionorid->id;
         }
+    }
+
+    // At this point, either $question or $questionid is expected to be set.
+    if (isset($questionid)) {
+        try {
+            $question = question_bank::load_question_data($questionid);
+        } catch (Exception $e) {
+            // Let's log the exception for future debugging.
+            debugging($e->getMessage(), DEBUG_NORMAL, $e->getTrace());
 
-        if (!isset($question) && isset($questionorid->id) && $questionorid->id != 0) {
-            $question = question_bank::load_question_data($questionorid->id);
+            // Well, at least we tried. Seems that we really have to read from DB.
+            $question = $DB->get_record_sql('SELECT q.id, q.createdby, qc.contextid
+                                               FROM {question} q
+                                               JOIN {question_categories} qc ON q.category = qc.id
+                                              WHERE q.id = :id', ['id' => $questionid]);
         }
-    } else {
+    }
+
+    if (!isset($question)) {
         throw new coding_exception('$questionorid parameter needs to be an integer or an object.');
     }
 
diff --git a/lib/tests/mustache_template_source_loader_test.php b/lib/tests/mustache_template_source_loader_test.php
new file mode 100644 (file)
index 0000000..1ccac41
--- /dev/null
@@ -0,0 +1,445 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Unit tests for lib/classes/output/mustache_template_source_loader.php
+ *
+ * @package   core
+ * @copyright 2018 Ryan Wyllie <ryan@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+use core\output\mustache_template_source_loader;
+
+/**
+ * Unit tests for the Mustache source loader class.
+ *
+ * @package   core
+ * @copyright 2018 Ryan Wyllie <ryan@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class core_output_mustache_template_source_loader_testcase extends advanced_testcase {
+    /**
+     * Ensure that stripping comments from templates does not mutilate the template body.
+     */
+    public function test_strip_template_comments() {
+
+        $templatebody = <<<'TBD'
+        <h1>{{# str }} pluginname, mod_lemmings {{/ str }}</h1>
+        <div>{{test}}</div>
+        <div>{{{unescapedtest}}}</div>
+        {{#lemmings}}
+            <div>
+                <h2>{{name}}</h2>
+                {{> mod_lemmings/lemmingprofile }}
+                {{# pix }} t/edit, core, Edit Lemming {{/ pix }}
+            </div>
+        {{/lemmings}}
+        {{^lemmings}}Sorry, no lemmings today{{/lemmings}}
+        <div id="{{ uniqid }}-tab-container">
+            {{# tabheader }}
+                <ul role="tablist" class="nav nav-tabs">
+                    {{# iconlist }}
+                        {{# icons }}
+                            {{> core/pix_icon }}
+                        {{/ icons }}
+                    {{/ iconlist }}
+                </ul>
+            {{/ tabheader }}
+            {{# tabbody }}
+                <div class="tab-content">
+                    {{# tabcontent }}
+                        {{# tabs }}
+                            {{> core/notification_info}}
+                        {{/ tabs }}
+                    {{/ tabcontent }}
+                </div>
+            {{/ tabbody }}
+        </div>
+        {{#js}}
+            require(['jquery','core/tabs'], function($, tabs) {
+
+                var container = $("#{{ uniqid }}-tab-container");
+                tabs.create(container);
+            });
+        {{/js}}
+TBD;
+        $templatewithcomment = <<<TBC
+        {{!
+            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/>.
+        }}
+        {{!
+            @template mod_lemmings/lemmings
+
+            Lemmings template.
+
+            The purpose of this template is to render a lot of lemmings.
+
+            Classes required for JS:
+            * none
+
+            Data attributes required for JS:
+            * none
+
+            Context variables required for this template:
+            * attributes Array of name / value pairs.
+
+            Example context (json):
+            {
+                "lemmings": [
+                    { "name": "Lemmy Winks", "age" : 1, "size" : "big" },
+                    { "name": "Rocky", "age" : 2, "size" : "small" }
+                ]
+            }
+
+        }}
+        $templatebody
+        {{!
+            Here's some more comment text
+            Note, there is no need to test bracketed variables inside comments as gherkin does not support that!
+            See this issue: https://github.com/mustache/spec/issues/8
+        }}
+TBC;
+
+        $loader = new mustache_template_source_loader();
+        $actual = phpunit_util::call_internal_method(
+            $loader,
+            'strip_template_comments',
+            [$templatewithcomment],
+            \core\output\mustache_template_source_loader::class
+        );
+        $this->assertEquals(trim($templatebody), trim($actual));
+    }
+
+    /**
+     * Data provider for the test_load function.
+     */
+    public function test_load_test_cases() {
+        $cache = [
+            'core' => [
+                'test' => '{{! a comment }}The rest of the template'
+            ]
+        ];
+        $loader = $this->build_loader_from_static_cache($cache);
+
+        return [
+            'with comments' => [
+                'loader' => $loader,
+                'component' => 'core',
+                'name' => 'test',
+                'includecomments' => true,
+                'expected' => '{{! a comment }}The rest of the template'
+            ],
+            'without comments' => [
+                'loader' => $loader,
+                'component' => 'core',
+                'name' => 'test',
+                'includecomments' => false,
+                'expected' => 'The rest of the template'
+            ],
+        ];
+    }
+
+    /**
+     * Test the load function.
+     *
+     * @dataProvider test_load_test_cases()
+     * @param mustache_template_source_loader $loader The loader
+     * @param string $component The moodle component
+     * @param string $name The template name
+     * @param bool $includecomments Whether to strip comments
+     * @param string $expected The expected output
+     */
+    public function test_load($loader, $component, $name, $includecomments, $expected) {
+        $this->assertEquals($expected, $loader->load($component, $name, 'boost', $includecomments));
+    }
+
+    /**
+     * Data provider for the load_with_dependencies function.
+     */
+    public function test_load_with_dependencies_test_cases() {
+        // Create a bunch of templates that include one another in various ways. There is
+        // multiple instances of recursive inclusions to test that the code doensn't get
+        // stuck in an infinite loop.
+        $foo = '{{! a comment }}{{> core/bar }}{{< test/bop }}{{/ test/bop}}{{#str}} help, core {{/str}}';
+        $foo2 = '{{! a comment }}hello';
+        $bar = '{{! a comment }}{{> core/baz }}';
+        $baz = '{{! a comment }}{{#str}} hide, core {{/str}}';
+        $bop = '{{! a comment }}{{< test/bim }}{{/ test/bim }}{{> core/foo }}';
+        $bim = '{{! a comment }}{{< core/foo }}{{/ core/foo}}{{> test/foo }}';
+        $foonocomment = '{{> core/bar }}{{< test/bop }}{{/ test/bop}}{{#str}} help, core {{/str}}';
+        $foo2nocomment = 'hello';
+        $barnocomment = '{{> core/baz }}';
+        $baznocomment = '{{#str}} hide, core {{/str}}';
+        $bopnocomment = '{{< test/bim }}{{/ test/bim }}{{> core/foo }}';
+        $bimnocomment = '{{< core/foo }}{{/ core/foo}}{{> test/foo }}';
+        $cache = [
+            'core' => [
+                'foo' => $foo,
+                'bar' => $bar,
+                'baz' => $baz,
+            ],
+            'test' => [
+                'foo' => $foo2,
+                'bop' => $bop,
+                'bim' => $bim
+            ]
+        ];
+        $loader = $this->build_loader_from_static_cache($cache);
+
+        return [
+            'no template includes w comments' => [
+                'loader' => $loader,
+                'component' => 'test',
+                'name' => 'foo',
+                'includecomments' => true,
+                'expected' => [
+                    'templates' => [
+                        'test' => [
+                            'foo' => $foo2
+                        ]
+                    ],
+                    'strings' => []
+                ]
+            ],
+            'no template includes w/o comments' => [
+                'loader' => $loader,
+                'component' => 'test',
+                'name' => 'foo',
+                'includecomments' => false,
+                'expected' => [
+                    'templates' => [
+                        'test' => [
+                            'foo' => $foo2nocomment
+                        ]
+                    ],
+                    'strings' => []
+                ]
+            ],
+            'no template includes with string w comments' => [
+                'loader' => $loader,
+                'component' => 'core',
+                'name' => 'baz',
+                'includecomments' => true,
+                'expected' => [
+                    'templates' => [
+                        'core' => [
+                            'baz' => $baz
+                        ]
+                    ],
+                    'strings' => [
+                        'core' => [
+                            'hide' => 'Hide'
+                        ]
+                    ]
+                ]
+            ],
+            'no template includes with string w/o comments' => [
+                'loader' => $loader,
+                'component' => 'core',
+                'name' => 'baz',
+                'includecomments' => false,
+                'expected' => [
+                    'templates' => [
+                        'core' => [
+                            'baz' => $baznocomment
+                        ]
+                    ],
+                    'strings' => [
+                        'core' => [
+                            'hide' => 'Hide'
+                        ]
+                    ]
+                ]
+            ],
+            'full with comments' => [
+                'loader' => $loader,
+                'component' => 'core',
+                'name' => 'foo',
+                'includecomments' => true,
+                'expected' => [
+                    'templates' => [
+                        'core' => [
+                            'foo' => $foo,
+                            'bar' => $bar,
+                            'baz' => $baz
+                        ],
+                        'test' => [
+                            'foo' => $foo2,
+                            'bop' => $bop,
+                            'bim' => $bim
+                        ]
+                    ],
+                    'strings' => [
+                        'core' => [
+                            'help' => 'Help',
+                            'hide' => 'Hide'
+                        ]
+                    ]
+                ]
+            ],
+            'full without comments' => [
+                'loader' => $loader,
+                'component' => 'core',
+                'name' => 'foo',
+                'includecomments' => false,
+                'expected' => [
+                    'templates' => [
+                        'core' => [
+                            'foo' => $foonocomment,
+                            'bar' => $barnocomment,
+                            'baz' => $baznocomment
+                        ],
+                        'test' => [
+                            'foo' => $foo2nocomment,
+                            'bop' => $bopnocomment,
+                            'bim' => $bimnocomment
+                        ]
+                    ],
+                    'strings' => [
+                        'core' => [
+                            'help' => 'Help',
+                            'hide' => 'Hide'
+                        ]
+                    ]
+                ]
+            ]
+        ];
+    }
+
+    /**
+     * Test the load_with_dependencies function.
+     *
+     * @dataProvider test_load_with_dependencies_test_cases()
+     * @param mustache_template_source_loader $loader The loader
+     * @param string $component The moodle component
+     * @param string $name The template name
+     * @param bool $includecomments Whether to strip comments
+     * @param string $expected The expected output
+     */
+    public function test_load_with_dependencies($loader, $component, $name, $includecomments, $expected) {
+        $actual = $loader->load_with_dependencies($component, $name, 'boost', $includecomments);
+        $this->assertEquals($expected, $actual);
+    }
+    /**
+     * Data provider for the test_load function.
+     */
+    public function test_scan_template_source_for_dependencies_test_cases() {
+        $foo = '{{! a comment }}{{> core/bar }}{{< test/bop }}{{/ test/bop}}{{#str}} help, core {{/str}}';
+        $bar = '{{! a comment }}{{> core/baz }}';
+        $baz = '{{! a comment }}{{#str}} hide, core {{/str}}';
+        $bop = '{{! a comment }}hello';
+        $cache = [
+            'core' => [
+                'foo' => $foo,
+                'bar' => $bar,
+                'baz' => $baz,
+                'bop' => $bop
+            ]
+        ];
+        $loader = $this->build_loader_from_static_cache($cache);
+
+        return [
+            'single template include' => [
+                'loader' => $loader,
+                'source' => $bar,
+                'expected' => [
+                    'templates' => [
+                        'core' => ['baz']
+                    ],
+                    'strings' => []
+                ]
+            ],
+            'single string include' => [
+                'loader' => $loader,
+                'source' => $baz,
+                'expected' => [
+                    'templates' => [],
+                    'strings' => [
+                        'core' => ['hide']
+                    ]
+                ]
+            ],
+            'no include' => [
+                'loader' => $loader,
+                'source' => $bop,
+                'expected' => [
+                    'templates' => [],
+                    'strings' => []
+                ]
+            ],
+            'all include' => [
+                'loader' => $loader,
+                'source' => $foo,
+                'expected' => [
+                    'templates' => [
+                        'core' => ['bar'],
+                        'test' => ['bop']
+                    ],
+                    'strings' => [
+                        'core' => ['help']
+                    ]
+                ]
+            ],
+        ];
+    }
+
+    /**
+     * Test the scan_template_source_for_dependencies function.
+     *
+     * @dataProvider test_scan_template_source_for_dependencies_test_cases()
+     * @param mustache_template_source_loader $loader The loader
+     * @param string $source The template to test
+     * @param string $expected The expected output
+     */
+    public function test_scan_template_source_for_dependencies($loader, $source, $expected) {
+        $actual = phpunit_util::call_internal_method(
+            $loader,
+            'scan_template_source_for_dependencies',
+            [$source],
+            \core\output\mustache_template_source_loader::class
+        );
+        $this->assertEquals($expected, $actual);
+    }
+
+    /**
+     * Create an instance of mustache_template_source_loader which loads its templates
+     * from the given cache rather than disk.
+     *
+     * @param array $cache A cache of templates
+     * @return mustache_template_source_loader
+     */
+    private function build_loader_from_static_cache(array $cache) : mustache_template_source_loader {
+        return new mustache_template_source_loader(function($component, $name, $themename) use ($cache) {
+            return $cache[$component][$name];
+        });
+    }
+}
diff --git a/lib/tests/output_external_test.php b/lib/tests/output_external_test.php
deleted file mode 100644 (file)
index 35acb97..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Unit tests for lib/classes/output/external.php
- * @author    Guy Thomas <gthomas@moodlerooms.com>
- * @copyright Copyright (c) 2017 Blackboard Inc.
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-use core\output\external;
-
-require_once(__DIR__.'/../../lib/externallib.php');
-require_once(__DIR__.'/../../lib/mustache/src/Mustache/Tokenizer.php');
-require_once(__DIR__.'/../../lib/mustache/src/Mustache/Parser.php');
-
-/**
- * Class core_output_external_testcase - test \core\output\external class.
- * @package   core
- * @author    Guy Thomas <gthomas@moodlerooms.com>
- * @copyright Copyright (c) 2017 Blackboard Inc.
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class core_output_external_testcase extends base_testcase {
-
-    /**
-     * Ensure that stripping comments from templates does not mutilate the template body.
-     */
-    public function test_strip_template_comments() {
-
-        $templatebody = <<<'TBD'
-        <h1>{{# str }} pluginname, mod_lemmings {{/ str }}</h1>
-        <div>{{test}}</div>
-        <div>{{{unescapedtest}}}</div>
-        {{#lemmings}}
-            <div>
-                <h2>{{name}}</h2>
-                {{> mod_lemmings/lemmingprofile }}
-                {{# pix }} t/edit, core, Edit Lemming {{/ pix }}
-            </div>
-        {{/lemmings}}
-        {{^lemmings}}Sorry, no lemmings today{{/lemmings}}
-        <div id="{{ uniqid }}-tab-container">
-            {{# tabheader }}
-                <ul role="tablist" class="nav nav-tabs">
-                    {{# iconlist }}
-                        {{# icons }}
-                            {{> core/pix_icon }}
-                        {{/ icons }}
-                    {{/ iconlist }}
-                </ul>
-            {{/ tabheader }}
-            {{# tabbody }}
-                <div class="tab-content">
-                    {{# tabcontent }}
-                        {{# tabs }}
-                            {{> core/notification_info}}
-                        {{/ tabs }}
-                    {{/ tabcontent }}
-                </div>
-            {{/ tabbody }}
-        </div>
-        {{#js}}
-            require(['jquery','core/tabs'], function($, tabs) {
-
-                var container = $("#{{ uniqid }}-tab-container");
-                tabs.create(container);
-            });
-        {{/js}}
-TBD;
-        $templatewithcomment = <<<TBC
-        {{!
-            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/>.
-        }}
-        {{!
-            @template mod_lemmings/lemmings
-
-            Lemmings template.
-
-            The purpose of this template is to render a lot of lemmings.
-
-            Classes required for JS:
-            * none
-
-            Data attributes required for JS:
-            * none
-
-            Context variables required for this template:
-            * attributes Array of name / value pairs.
-
-            Example context (json):
-            {
-                "lemmings": [
-                    { "name": "Lemmy Winks", "age" : 1, "size" : "big" },
-                    { "name": "Rocky", "age" : 2, "size" : "small" }
-                ]
-            }
-
-        }}
-        $templatebody
-        {{!
-            Here's some more comment text
-            Note, there is no need to test bracketed variables inside comments as gherkin does not support that!
-            See this issue: https://github.com/mustache/spec/issues/8
-        }}
-TBC;
-
-        // Ensure that the template when stripped of comments just includes the body.
-        $stripped = phpunit_util::call_internal_method(null, 'strip_template_comments',
-                [$templatewithcomment], 'core\output\external');
-        $this->assertEquals(trim($templatebody), trim($stripped));
-
-        $tokenizer = new Mustache_Tokenizer();
-        $tokens = $tokenizer->scan($templatebody);
-        $parser = new Mustache_Parser();
-        $tree = $parser->parse($tokens);
-        $this->assertNotEmpty($tree);
-    }
-}
index ced468b..ae1cd80 100644 (file)
@@ -1643,6 +1643,37 @@ class core_questionlib_testcase extends advanced_testcase {
         ];
     }
 
+    /**
+     * Tests that question_has_capability_on does not throw exception on broken questions.
+     */
+    public function test_question_has_capability_on_broken_question() {
+        global $DB;
+
+        // Create the test data.
+        $generator = $this->getDataGenerator();
+        $questiongenerator = $generator->get_plugin_generator('core_question');
+
+        $category = $generator->create_category();
+        $context = context_coursecat::instance($category->id);
+        $questioncat = $questiongenerator->create_question_category([
+            'contextid' => $context->id,
+        ]);
+
+        // Create a cloze question.
+        $question = $questiongenerator->create_question('multianswer', null, [
+            'category' => $questioncat->id,
+        ]);
+        // Now, break the question.
+        $DB->delete_records('question_multianswer', ['question' => $question->id]);
+
+        $this->setAdminUser();
+
+        $result = question_has_capability_on($question->id, 'tag');
+        $this->assertTrue($result);
+
+        $this->assertDebuggingCalled();
+    }
+
     /**
      * Tests for the deprecated question_has_capability_on function when passing a stdClass as parameter.
      *
index 3335d7f..e7bb6de 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_message_email_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 1a7a222..96536ec 100644 (file)
@@ -37,7 +37,7 @@ class message_output_email extends message_output {
      * @param object $eventdata the event data submitted by the message sender plus $eventdata->savedmessageid
      */
     function send_message($eventdata) {
-        global $CFG;
+        global $CFG, $DB;
 
         // skip any messaging suspended and deleted users
         if ($eventdata->userto->auth === 'nologin' or $eventdata->userto->suspended or $eventdata->userto->deleted) {
@@ -93,6 +93,10 @@ class message_output_email extends message_output {
         $result = email_to_user($recipient, $eventdata->userfrom, $eventdata->subject, $eventdata->fullmessage,
                                 $eventdata->fullmessagehtml, $attachment, $attachname, true, $replyto, $replytoname);
 
+        if ($result && $notification = $DB->get_record('notifications', ['id' => $eventdata->savedmessageid])) {
+            \core_message\api::mark_notification_as_read($notification);
+        }
+
         // Remove an attachment file if any.
         if (!empty($attachment) && file_exists($attachment)) {
             unlink($attachment);
index aa1681f..f27426c 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_message_jabber_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 3256057..5c179e5 100644 (file)
@@ -34,34 +34,6 @@ function xmldb_message_popup_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    if ($oldversion < 2016052309) {
-
-        // Define table message_popup to be created.
-        $table = new xmldb_table('message_popup');
-
-        // Adding fields to table message_popup.
-        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('messageid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('isread', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
-
-        // Adding keys to table message_popup.
-        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
-
-        // Adding indexes to table message_popup.
-        $table->add_index('messageid-isread', XMLDB_INDEX_UNIQUE, array('messageid', 'isread'));
-
-        // Conditionally launch create table for message_popup.
-        if (!$dbman->table_exists($table)) {
-            $dbman->create_table($table);
-        }
-
-        // Popup savepoint reached.
-        upgrade_plugin_savepoint(true, 2016052309, 'message', 'popup');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2016122100) {
 
         // Define index isread (not unique) to be added to message_popup.
index 3b7e4df..18a0391 100644 (file)
@@ -34,39 +34,6 @@ function xmldb_assign_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    if ($oldversion < 2016100301) {
-
-        // Define table assign_overrides to be created.
-        $table = new xmldb_table('assign_overrides');
-
-        // Adding fields to table assign_overrides.
-        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('assignid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
-        $table->add_field('groupid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
-        $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
-        $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
-        $table->add_field('allowsubmissionsfromdate', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
-        $table->add_field('duedate', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
-        $table->add_field('cutoffdate', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
-
-        // Adding keys to table assign_overrides.
-        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
-        $table->add_key('assignid', XMLDB_KEY_FOREIGN, array('assignid'), 'assign', array('id'));
-        $table->add_key('groupid', XMLDB_KEY_FOREIGN, array('groupid'), 'groups', array('id'));
-        $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
-
-        // Conditionally launch create table for assign_overrides.
-        if (!$dbman->table_exists($table)) {
-            $dbman->create_table($table);
-        }
-
-        // Assign savepoint reached.
-        upgrade_mod_savepoint(true, 2016100301, 'assign');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017021500) {
         // Fix event types of assign events.
         $params = [
@@ -129,6 +96,7 @@ function xmldb_assign_upgrade($oldversion) {
 
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
+
     if ($oldversion < 2017061200) {
         // Data fix any assign group override event priorities which may have been accidentally nulled due to a bug on the group
         // overrides edit form.
index 1356de0..ae87b98 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_assignfeedback_comments_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 61353d0..2cd3cd9 100644 (file)
@@ -34,9 +34,6 @@ function xmldb_assignfeedback_editpdf_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017022700) {
 
         // Get orphaned, duplicate files and delete them.
index 72b6a3f..898839c 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_assignfeedback_file_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 3955a17..3c41dfe 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_assignsubmission_comments_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index a62453a..2f6c544 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_assignsubmission_file_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index b362fb8..2b04ada 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_assignsubmission_onlinetext_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 602d0d9..c0bce96 100644 (file)
@@ -1678,9 +1678,16 @@ class mod_assign_locallib_testcase extends advanced_testcase {
         assign::cron();
 
         $events = $sink->get_events();
+        // Notification has been marked as read, so now first event should be a 'notification_viewed' one. For student.
         $event = reset($events);
+        $this->assertInstanceOf('\core\event\notification_viewed', $event);
+        $this->assertEquals($student->id, $event->userid);
+
+        // And next event should be the 'notification_sent' one. For teacher.
+        $event = $events[1];
         $this->assertInstanceOf('\core\event\notification_sent', $event);
         $this->assertEquals($assign->get_course()->id, $event->other['courseid']);
+        $this->assertEquals($teacher->id, $event->userid);
         $sink->close();
     }
 
index 16b0bcc..a6187c6 100644 (file)
@@ -24,9 +24,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_assignment_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index ee5c7fd..eeac64f 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die;
 function xmldb_book_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 9f8d3b4..5351271 100644 (file)
@@ -29,9 +29,6 @@ function xmldb_chat_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 9a04cb6..31f2963 100644 (file)
@@ -24,9 +24,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_choice_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 78e056e..96d2f35 100644 (file)
@@ -26,24 +26,6 @@ function xmldb_data_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    if ($oldversion < 2016090600) {
-
-        // Define field config to be added to data.
-        $table = new xmldb_table('data');
-        $field = new xmldb_field('config', XMLDB_TYPE_TEXT, null, null, null, null, null, 'timemodified');
-
-        // Conditionally launch add field config.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Data savepoint reached.
-        upgrade_mod_savepoint(true, 2016090600, 'data');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017032800) {
 
         // Define field completionentries to be added to data. Require a number of entries to be considered complete.
index b21dfe8..603521d 100644 (file)
@@ -41,9 +41,6 @@ function xmldb_feedback_upgrade($oldversion) {
 
     $dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes.
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017032800) {
 
         // Delete duplicated records in feedback_completed. We just keep the last record of completion.
index d3ba81b..d106c21 100644 (file)
@@ -49,9 +49,6 @@ function xmldb_folder_upgrade($oldversion) {
 
     $dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes.
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 37a6b3b..0d4a5d4 100644 (file)
@@ -47,24 +47,6 @@ function xmldb_forum_upgrade($oldversion) {
 
     $dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes.
 
-    if ($oldversion < 2016091200) {
-
-        // Define field lockdiscussionafter to be added to forum.
-        $table = new xmldb_table('forum');
-        $field = new xmldb_field('lockdiscussionafter', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'displaywordcount');
-
-        // Conditionally launch add field lockdiscussionafter.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Forum savepoint reached.
-        upgrade_mod_savepoint(true, 2016091200, 'forum');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index c198dd9..2baa6c8 100644 (file)
@@ -657,6 +657,12 @@ function forum_cron() {
                     }
                 }
 
+                $coursecontext = context_course::instance($course->id);
+                if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext, $userto->id)) {
+                    // The course is hidden and the user does not have access to it.
+                    continue;
+                }
+
                 // Don't send email if the forum is Q&A and the user has not posted.
                 // Initial topics are still mailed.
                 if ($forum->type == 'qanda' && !forum_get_user_posted_time($discussion->id, $userto->id) && $pid != $discussion->firstpost) {
index e96ba94..d233252 100644 (file)
@@ -286,7 +286,13 @@ class mod_forum_mail_testcase extends advanced_testcase {
 
         // Reset the message sink for other tests.
         $this->helper->messagesink = $this->redirectMessages();
+        // Notification has been marked as read, so now first event should be a 'notification_viewed' one.
         $event = reset($events);
+        $this->assertInstanceOf('\core\event\notification_viewed', $event);
+
+        // And next event should be the 'notification_sent' one.
+        $event = $events[1];
+        $this->assertInstanceOf('\core\event\notification_sent', $event);
         $this->assertEquals($course->id, $event->other['courseid']);
     }
 
index 86ea0a1..748a79a 100644 (file)
@@ -22,9 +22,6 @@
 function xmldb_glossary_upgrade($oldversion) {
     global $CFG, $DB;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 671cee4..ac32ec4 100644 (file)
@@ -31,9 +31,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_imscp_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index f16a2d9..7212edc 100644 (file)
@@ -47,9 +47,6 @@ defined('MOODLE_INTERNAL') || die;
 function xmldb_label_upgrade($oldversion) {
     global $CFG, $DB;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 16657f5..a3b5ce3 100644 (file)
@@ -54,9 +54,6 @@ function xmldb_lesson_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2016120515) {
         // Define new fields to be added to lesson.
         $table = new xmldb_table('lesson');
index d8b961a..f77a661 100644 (file)
 function xmldb_lti_upgrade($oldversion) {
     global $CFG, $DB;
 
-    $dbman = $DB->get_manager();
-
-    if ($oldversion < 2016052301) {
-
-        // Changing type of field value on table lti_types_config to text.
-        $table = new xmldb_table('lti_types_config');
-        $field = new xmldb_field('value', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'name');
-
-        // Launch change of type for field value.
-        $dbman->change_field_type($table, $field);
-
-        // Lti savepoint reached.
-        upgrade_mod_savepoint(true, 2016052301, 'lti');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 368f0b8..a284b2e 100644 (file)
@@ -47,9 +47,6 @@ defined('MOODLE_INTERNAL') || die;
 function xmldb_page_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 0e1d17c..cf314b5 100644 (file)
@@ -52,8 +52,4 @@ class add_action_column extends \core_question\bank\action_column_base {
         }
         $this->print_icon('t/add', $this->stradd, $this->qbank->add_to_quiz_url($question->id));
     }
-
-    public function get_required_fields() {
-        return array('q.id');
-    }
 }
index 82e2f0f..fea86fb 100644 (file)
@@ -33,61 +33,6 @@ function xmldb_quiz_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    if ($oldversion < 2016092000) {
-        // Define new fields to be added to quiz.
-        $table = new xmldb_table('quiz');
-
-        $field = new xmldb_field('allowofflineattempts', XMLDB_TYPE_INTEGER, '1', null, null, null, 0, 'completionpass');
-        // Conditionally launch add field allowofflineattempts.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-        // Quiz savepoint reached.
-        upgrade_mod_savepoint(true, 2016092000, 'quiz');
-    }
-
-    if ($oldversion < 2016092001) {
-        // New field for quiz_attemps.
-        $table = new xmldb_table('quiz_attempts');
-
-        $field = new xmldb_field('timemodifiedoffline', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0, 'timemodified');
-        // Conditionally launch add field timemodifiedoffline.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Quiz savepoint reached.
-        upgrade_mod_savepoint(true, 2016092001, 'quiz');
-    }
-
-    if ($oldversion < 2016100300) {
-        // Find quizzes with the combination of require passing grade and grade to pass 0.
-        $gradeitems = $DB->get_records_sql("
-            SELECT gi.id, gi.itemnumber, cm.id AS cmid
-              FROM {quiz} q
-        INNER JOIN {course_modules} cm ON q.id = cm.instance
-        INNER JOIN {grade_items} gi ON q.id = gi.iteminstance
-        INNER JOIN {modules} m ON m.id = cm.module
-             WHERE q.completionpass = 1
-               AND gi.gradepass = 0
-               AND cm.completiongradeitemnumber IS NULL
-               AND gi.itemmodule = m.name
-               AND gi.itemtype = ?
-               AND m.name = ?", array('mod', 'quiz'));
-
-        foreach ($gradeitems as $gradeitem) {
-            $DB->execute("UPDATE {course_modules}
-                             SET completiongradeitemnumber = :itemnumber
-                           WHERE id = :cmid",
-                array('itemnumber' => $gradeitem->itemnumber, 'cmid' => $gradeitem->cmid));
-        }
-        // Quiz savepoint reached.
-        upgrade_mod_savepoint(true, 2016100300, 'quiz');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index e1fbfc3..13ca01a 100644 (file)
@@ -33,9 +33,6 @@ function xmldb_quiz_overview_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 2a5c64e..a4c0d3f 100644 (file)
@@ -30,16 +30,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_quiz_statistics_upgrade($oldversion) {
     global $DB;
 
-    if ($oldversion < 2016100500) {
-        // Clear the quiz_statistics table - it is only a cache table anyway.
-        // This will force re-calculation.
-        $DB->delete_records('quiz_statistics');
-        upgrade_plugin_savepoint(true, 2016100500, 'quiz', 'statistics');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 98d0e90..7cd00fc 100644 (file)
@@ -1,4 +1,4 @@
-@core @core_question
+@mod @mod_quiz @javascript
 Feature: Adding questions to a quiz from the question bank
   In order to re-use questions
   As a teacher
@@ -21,17 +21,19 @@ Feature: Adding questions to a quiz from the question bank
       | contextlevel | reference | name           |
       | Course       | C1        | Test questions |
     And the following "questions" exist:
-      | questioncategory | qtype     | name              | user     | questiontext    |
-      | Test questions   | essay     | question 1 name | admin    | Question 1 text |
-      | Test questions   | essay     | question 2 name | teacher1 | Question 2 text |
-    And I log in as "teacher1"
+      | questioncategory | qtype     | name             | user     | questiontext     |
+      | Test questions   | essay     | question 01 name | admin    | Question 01 text |
+      | Test questions   | essay     | question 02 name | teacher1 | Question 02 text |
+
+  Scenario: The questions can be filtered by tag
+    Given I log in as "teacher1"
     And I am on "Course 1" course homepage
-    And I navigate to "Question bank > Questions" in current page administration
-    And I click on "Edit" "link" in the "question 1 name" "table_row"
+    When I navigate to "Question bank > Questions" in current page administration
+    And I click on "Edit" "link" in the "question 01 name" "table_row"
     And I set the following fields to these values:
       | Tags | foo |
     And I press "id_submitbutton"
-    And I click on "Edit" "link" in the "question 2 name" "table_row"
+    And I click on "Edit" "link" in the "question 02 name" "table_row"
     And I set the following fields to these values:
       | Tags | bar |
     And I press "id_submitbutton"
@@ -40,10 +42,41 @@ Feature: Adding questions to a quiz from the question bank
     And I navigate to "Edit quiz" in current page administration
     And I open the "last" add to quiz menu
     And I follow "from question bank"
-
-  @javascript
-  Scenario: The questions can be filtered by tag
-    When I set the field "Filter by tags..." to "foo"
+    And I set the field "Filter by tags..." to "foo"
     And I press key "13" in the field "Filter by tags..."
-    Then I should see "question 1 name" in the "categoryquestions" "table"
-    And I should not see "question 2 name" in the "categoryquestions" "table"
+    Then I should see "question 01 name" in the "categoryquestions" "table"
+    And I should not see "question 02 name" in the "categoryquestions" "table"
+
+  Scenario: The question modal can be paginated
+    Given the following "questions" exist:
+      | questioncategory | qtype     | name             | user     | questiontext     |
+      | Test questions   | essay     | question 03 name | teacher1 | Question 03 text |
+      | Test questions   | essay     | question 04 name | teacher1 | Question 04 text |
+      | Test questions   | essay     | question 05 name | teacher1 | Question 05 text |
+      | Test questions   | essay     | question 06 name | teacher1 | Question 06 text |
+      | Test questions   | essay     | question 07 name | teacher1 | Question 07 text |
+      | Test questions   | essay     | question 08 name | teacher1 | Question 08 text |
+      | Test questions   | essay     | question 09 name | teacher1 | Question 09 text |
+      | Test questions   | essay     | question 10 name | teacher1 | Question 10 text |
+      | Test questions   | essay     | question 11 name | teacher1 | Question 11 text |
+      | Test questions   | essay     | question 12 name | teacher1 | Question 12 text |
+      | Test questions   | essay     | question 13 name | teacher1 | Question 13 text |
+      | Test questions   | essay     | question 14 name | teacher1 | Question 14 text |
+      | Test questions   | essay     | question 15 name | teacher1 | Question 15 text |
+      | Test questions   | essay     | question 16 name | teacher1 | Question 16 text |
+      | Test questions   | essay     | question 17 name | teacher1 | Question 17 text |
+      | Test questions   | essay     | question 18 name | teacher1 | Question 18 text |
+      | Test questions   | essay     | question 19 name | teacher1 | Question 19 text |
+      | Test questions   | essay     | question 20 name | teacher1 | Question 20 text |
+      | Test questions   | essay     | question 21 name | teacher1 | Question 21 text |
+      | Test questions   | essay     | question 22 name | teacher1 | Question 22 text |
+    And I log in as "teacher1"
+    And I am on "Course 1" course homepage
+    And I follow "Quiz 1"
+    And I navigate to "Edit quiz" in current page administration
+    And I open the "last" add to quiz menu
+    And I follow "from question bank"
+    And I click on "2" "link" in the ".pagination" "css_element"
+    Then I should see "question 21 name" in the "categoryquestions" "table"
+    And I should see "question 22 name" in the "categoryquestions" "table"
+    And I should not see "question 01 name" in the "categoryquestions" "table"
diff --git a/mod/quiz/tests/quiz_question_bank_view_test.php b/mod/quiz/tests/quiz_question_bank_view_test.php
new file mode 100644 (file)
index 0000000..a0c6ef8
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Unit tests for the quiz's own question bank view class.
+ *
+ * @package    mod_quiz
+ * @category   test
+ * @copyright  2018 the Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot . '/question/editlib.php');
+
+
+/**
+ * Unit tests for the quiz's own question bank view class.
+ *
+ * @copyright  2018 the Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class quiz_question_bank_view_testcase extends advanced_testcase {
+
+    public function test_viewing_question_bank_should_not_load_individual_questions() {
+        $this->resetAfterTest();
+        $this->setAdminUser();
+        $generator = $this->getDataGenerator();
+        /** @var core_question_generator $questiongenerator */
+        $questiongenerator = $generator->get_plugin_generator('core_question');
+
+        // Create a course and a quiz.
+        $course = $generator->create_course();
+        $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
+        $context = context_module::instance($quiz->cmid);
+        $cm = get_coursemodule_from_instance('quiz', $quiz->id);
+
+        // Create a question in the default category.
+        $contexts = new question_edit_contexts($context);
+        $cat = question_make_default_categories($contexts->all());
+        $questiondata = $questiongenerator->create_question('numerical', null,
+                ['name' => 'Example question', 'category' => $cat->id]);
+
+        // Ensure the question is not in the cache.
+        $cache = cache::make('core', 'questiondata');
+        $cache->delete($questiondata->id);
+
+        // Generate the view.
+        $view = new mod_quiz\question\bank\custom_view($contexts, new moodle_url('/'), $course, $cm, $quiz);
+        ob_start();
+        $view->display('editq', 0, 20, $cat->id . ',' . $cat->contextid, false, false, false);
+        $html = ob_get_clean();
+
+        // Verify the output includes the expected question.
+        $this->assertContains('Example question', $html);
+
+        // Verify the question has not been loaded into the cache.
+        $this->assertFalse($cache->has($questiondata->id));
+    }
+}
index c2dd1ec..85b16c1 100644 (file)
@@ -47,9 +47,6 @@ defined('MOODLE_INTERNAL') || die;
 function xmldb_resource_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 0ac2aa1..bc47883 100644 (file)
@@ -34,21 +34,6 @@ function xmldb_scorm_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    // MDL-44712 improve multi-sco activity completion.
-    if ($oldversion < 2016080900) {
-        $table = new xmldb_table('scorm');
-
-        $field = new xmldb_field('completionstatusallscos', XMLDB_TYPE_INTEGER, '1', null, null, null, null, 'completionscorerequired');
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        upgrade_mod_savepoint(true, 2016080900, 'scorm');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 5ca506e..4a00899 100644 (file)
 defined('MOODLE_INTERNAL') || die();
 
 function xmldb_survey_upgrade($oldversion) {
-    global $DB;
-
-    $dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes.
-
-    if ($oldversion < 2016061400) {
-
-        // Define field completionsubmit to be added to survey.
-        $table = new xmldb_table('survey');
-        $field = new xmldb_field('completionsubmit', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'questions');
-
-        // Conditionally launch add field completionsubmit.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Survey savepoint reached.
-        upgrade_mod_savepoint(true, 2016061400, 'survey');
-    }
-
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
index 640cead..3065e64 100644 (file)
@@ -47,9 +47,6 @@ defined('MOODLE_INTERNAL') || die;
 function xmldb_url_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index a8b6ab0..5b179a9 100644 (file)
@@ -40,9 +40,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_wiki_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 9793703..9acd30f 100644 (file)
@@ -39,9 +39,6 @@ function xmldb_workshop_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 60f7de5..c5cb7bb 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_workshopform_accumulative_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 652add1..79b166b 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_workshopform_comments_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index f7993c3..9d53ee9 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_workshopform_numerrors_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index cd13441..d40d5e5 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_workshopform_rubric_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 1dc7483..0d8fc59 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_portfolio_boxnet_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 6e1d3db..2f957c1 100644 (file)
@@ -23,9 +23,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_portfolio_googledocs_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index d1ea866..f745e0f 100644 (file)
@@ -23,9 +23,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_portfolio_picasa_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 327cd9e..637c0bb 100644 (file)
@@ -376,11 +376,14 @@ class moodle_content_writer implements content_writer {
      *
      * @param   string          $path       The path to export the data at.
      * @param   string          $data       The data to be exported.
+     * @throws  \moodle_exception           If the file cannot be written for some reason.
      */
     protected function write_data(string $path, string $data) {
         $targetpath = $this->path . DIRECTORY_SEPARATOR . $path;
         check_dir_exists(dirname($targetpath), true, true);
-        file_put_contents($targetpath, $data);
+        if (file_put_contents($targetpath, $data) === false) {
+            throw new \moodle_exception('cannotsavefile', 'error', '', $targetpath);
+        }
         $this->files[$path] = $targetpath;
     }
 
@@ -706,12 +709,12 @@ class moodle_content_writer implements content_writer {
      *
      * @param  string $filepath The file path.
      * @return string contents of the file.
+     * @throws \moodle_exception If the file cannot be opened.
      */
     protected function get_file_content(string $filepath) : String {
-        $filepointer = fopen($filepath, 'r');
-        $content = '';
-        while (!feof($filepointer)) {
-            $content .= fread($filepointer, filesize($filepath));
+        $content = file_get_contents($filepath);
+        if ($content === false) {
+            throw new \moodle_exception('cannotopenfile', 'error', '', $filepath);
         }
         return $content;
     }
index 358138a..45f5cd0 100644 (file)
@@ -30,9 +30,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_qbehaviour_manualgraded_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 7ef065e..ad17bb3 100644 (file)
@@ -51,6 +51,8 @@ class delete_action_column extends action_column_base {
     }
 
     public function get_required_fields() {
-        return array('q.id', 'q.hidden');
+        $required = parent::get_required_fields();
+        $required[] = 'q.hidden';
+        return $required;
     }
 }
index f31d5cc..a81a83c 100644 (file)
@@ -34,8 +34,4 @@ class preview_action_column extends action_column_base {
                     $question->id, $this->qbank->get_most_specific_context(), false);
         }
     }
-
-    public function get_required_fields() {
-        return array('q.id');
-    }
 }
index 6721cbf..68c6aaf 100644 (file)
@@ -267,7 +267,7 @@ abstract class question_bank {
         global $DB;
 
         if (self::$testmode) {
-            // Evil, test code in production, but now way round it.
+            // Evil, test code in production, but no way round it.
             return self::return_test_question_data($questionid);
         }
 
index c9987ff..0f4ea44 100644 (file)
@@ -44,7 +44,7 @@ class core_question_bank_view_testcase extends advanced_testcase {
         /** @var core_question_generator $questiongenerator */
         $questiongenerator = $generator->get_plugin_generator('core_question');
 
-        // Cerate a course.
+        // Create a course.
         $course = $generator->create_course();
         $context = context_course::instance($course->id);
 
@@ -54,7 +54,7 @@ class core_question_bank_view_testcase extends advanced_testcase {
         $questiondata = $questiongenerator->create_question('numerical', null,
                 ['name' => 'Example question', 'category' => $cat->id]);
 
-        // Ensure the qusetion is not in the cache.
+        // Ensure the question is not in the cache.
         $cache = cache::make('core', 'questiondata');
         $cache->delete($questiondata->id);
 
@@ -67,7 +67,7 @@ class core_question_bank_view_testcase extends advanced_testcase {
         // Verify the output includes the expected question.
         $this->assertContains('Example question', $html);
 
-        // Verify the qusetion has not been loaded into the cache.
+        // Verify the question has not been loaded into the cache.
         $this->assertFalse($cache->has($questiondata->id));
     }
 }
index c6d4267..a639b00 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_qtype_calculated_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 010b624..160f0f2 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_qtype_ddmarker_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 873f939..93acbb4 100644 (file)
@@ -34,9 +34,6 @@ function xmldb_qtype_essay_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 0483680..1dd18fc 100644 (file)
@@ -31,9 +31,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_qtype_match_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index caa3b68..e0bd450 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_qtype_multianswer_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index fcf0be9..b2dc15b 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_qtype_multichoice_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index acca38d..e303c1d 100644 (file)
@@ -33,6 +33,12 @@ function xmldb_qtype_numerical_upgrade($oldversion) {
     global $CFG, $DB;
     $dbman = $DB->get_manager();
 
+    // Automatically generated Moodle v3.3.0 release upgrade line.
+    // Put any upgrade step following this.
+
+    // Automatically generated Moodle v3.4.0 release upgrade line.
+    // Put any upgrade step following this.
+
     if ($oldversion < 2017121000) {
 
         // Changing length of field multiplier on table question_numerical_units to 38.
@@ -46,15 +52,6 @@ function xmldb_qtype_numerical_upgrade($oldversion) {
         upgrade_plugin_savepoint(true, 2017121000, 'qtype', 'numerical');
     }
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Automatically generated Moodle v3.3.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Automatically generated Moodle v3.4.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.5.0 release upgrade line.
     // Put any upgrade step following this.
 
index 658cd34..cb50b67 100644 (file)
@@ -31,9 +31,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_qtype_random_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 3acd3e6..c8471b4 100644 (file)
@@ -31,9 +31,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_qtype_randomsamatch_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 413fb48..63031fe 100644 (file)
@@ -32,9 +32,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_qtype_shortanswer_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index fab31f5..41d2126 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_repository_boxnet_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 0177d3a..73aaf94 100644 (file)
@@ -23,13 +23,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_repository_dropbox_upgrade($oldversion) {
     global $CFG;
 
-    if ($oldversion < 2016091300) {
-        unset_config('legacyapi', 'dropbox');
-        upgrade_plugin_savepoint(true, 2016091300, 'repository', 'dropbox');
-    }
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index dfe5f26..3266380 100644 (file)
@@ -23,9 +23,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_repository_googledocs_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2017011100) {
         // Set default import formats from Google.
         set_config('documentformat', 'rtf', 'googledocs');
index 1f37518..3ec6125 100644 (file)
@@ -23,9 +23,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_repository_picasa_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 6b341d8..1b35f9f 100644 (file)
@@ -80,7 +80,7 @@
             {{#pix}} i/moremenu, core {{/pix}}
         </button>
         <ul class="dropdown-menu pull-right">
-            <li data-route="view-contact" data-route-param="{{userid}}">
+            <li data-action="view-contact">
                 <a class="dropdown-item" href="#" >
                     {{#str}} info, core_message {{/str}}
                 </a>
index 8c39b5b..1573e64 100644 (file)
@@ -33,9 +33,6 @@ defined('MOODLE_INTERNAL') || die();
 function xmldb_theme_more_upgrade($oldversion) {
     global $CFG;
 
-    // Automatically generated Moodle v3.2.0 release upgrade line.
-    // Put any upgrade step following this.
-
     // Automatically generated Moodle v3.3.0 release upgrade line.
     // Put any upgrade step following this.
 
index 98db871..498a8cc 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2018122000.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2018122000.01;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.