Merge branch 'MDL-63375-master' of https://github.com/syxton/moodle into master
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 18 Aug 2020 22:13:02 +0000 (00:13 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 18 Aug 2020 22:13:02 +0000 (00:13 +0200)
540 files changed:
.eslintignore
.stylelintignore
.travis.yml
admin/index.php
admin/renderer.php
admin/settings/courses.php
admin/settings/plugins.php
admin/settings/server.php
admin/tool/analytics/version.php
admin/tool/availabilityconditions/version.php
admin/tool/behat/version.php
admin/tool/capability/version.php
admin/tool/cohortroles/version.php
admin/tool/customlang/version.php
admin/tool/dataprivacy/lib.php
admin/tool/dataprivacy/version.php
admin/tool/dbtransfer/version.php
admin/tool/filetypes/version.php
admin/tool/generator/version.php
admin/tool/health/version.php
admin/tool/httpsreplace/version.php
admin/tool/innodb/version.php
admin/tool/installaddon/version.php
admin/tool/langimport/version.php
admin/tool/licensemanager/version.php
admin/tool/log/store/database/version.php
admin/tool/log/store/legacy/version.php
admin/tool/log/store/standard/version.php
admin/tool/log/version.php
admin/tool/lp/version.php
admin/tool/lpimportcsv/version.php
admin/tool/lpmigrate/version.php
admin/tool/messageinbound/version.php
admin/tool/mobile/version.php
admin/tool/monitor/version.php
admin/tool/moodlenet/version.php
admin/tool/multilangupgrade/version.php
admin/tool/oauth2/version.php
admin/tool/phpunit/version.php
admin/tool/policy/version.php
admin/tool/profiling/version.php
admin/tool/recyclebin/version.php
admin/tool/replace/version.php
admin/tool/spamcleaner/version.php
admin/tool/task/version.php
admin/tool/templatelibrary/version.php
admin/tool/unsuproles/version.php
admin/tool/uploadcourse/version.php
admin/tool/uploaduser/version.php
admin/tool/usertours/pix/t/filler.png [new file with mode: 0644]
admin/tool/usertours/version.php
admin/tool/xmldb/version.php
auth/cas/version.php
auth/db/version.php
auth/email/version.php
auth/ldap/version.php
auth/lti/version.php
auth/manual/version.php
auth/mnet/version.php
auth/nologin/version.php
auth/none/version.php
auth/oauth2/version.php
auth/shibboleth/version.php
auth/webservice/version.php
availability/condition/completion/version.php
availability/condition/date/version.php
availability/condition/grade/version.php
availability/condition/group/version.php
availability/condition/grouping/version.php
availability/condition/profile/version.php
availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-debug.js
availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-min.js
availability/yui/build/moodle-core_availability-form/moodle-core_availability-form.js
availability/yui/src/form/js/form.js
backup/backup.class.php
backup/util/ui/amd/build/async_backup.min.js
backup/util/ui/amd/build/async_backup.min.js.map
backup/util/ui/amd/src/async_backup.js
blocks/activity_modules/version.php
blocks/activity_results/version.php
blocks/admin_bookmarks/version.php
blocks/badges/version.php
blocks/blog_menu/version.php
blocks/blog_recent/version.php
blocks/blog_tags/version.php
blocks/calendar_month/version.php
blocks/calendar_upcoming/version.php
blocks/comments/version.php
blocks/completionstatus/version.php
blocks/course_list/version.php
blocks/course_summary/version.php
blocks/feedback/version.php
blocks/globalsearch/version.php
blocks/glossary_random/version.php
blocks/html/version.php
blocks/login/version.php
blocks/lp/version.php
blocks/mentees/version.php
blocks/mnet_hosts/version.php
blocks/myoverview/version.php
blocks/myprofile/version.php
blocks/navigation/version.php
blocks/news_items/version.php
blocks/online_users/version.php
blocks/private_files/version.php
blocks/quiz_results/version.php
blocks/recent_activity/version.php
blocks/recentlyaccessedcourses/version.php
blocks/recentlyaccesseditems/classes/external/recentlyaccesseditems_item_exporter.php
blocks/recentlyaccesseditems/version.php
blocks/rss_client/version.php
blocks/search_forums/version.php
blocks/section_links/version.php
blocks/selfcompletion/version.php
blocks/settings/version.php
blocks/site_main_menu/version.php
blocks/social_activities/version.php
blocks/starredcourses/version.php
blocks/tag_flickr/version.php
blocks/tag_youtube/version.php
blocks/tags/version.php
blocks/timeline/amd/build/event_list.min.js
blocks/timeline/amd/build/event_list.min.js.map
blocks/timeline/amd/src/event_list.js
blocks/timeline/version.php
cache/locks/file/version.php
cache/stores/apcu/version.php
cache/stores/file/version.php
cache/stores/memcached/version.php
cache/stores/mongodb/version.php
cache/stores/redis/version.php
cache/stores/session/version.php
cache/stores/static/version.php
calendar/classes/external/event_exporter_base.php
calendar/classes/external/week_day_exporter.php
calendar/classes/local/event/factories/event_abstract_factory.php
calendar/classes/local/event/mappers/event_mapper.php
calendar/classes/local/event/value_objects/event_times.php
calendar/classes/local/event/value_objects/times_interface.php
calendar/lib.php
calendar/templates/month_detailed.mustache
calendar/templates/month_mini.mustache
calendar/tests/event_mapper_test.php
calendar/tests/event_test.php
calendar/tests/event_times_test.php
calendar/tests/helpers.php
calendar/tests/repeat_event_collection_test.php
calendar/type/gregorian/version.php
calendar/upgrade.txt
contentbank/classes/content.php
contentbank/classes/contentbank.php
contentbank/classes/contenttype.php
contentbank/contenttype/h5p/version.php
contentbank/tests/content_test.php
contentbank/tests/contentbank_test.php
contentbank/tests/contenttype_test.php
contentbank/tests/fixtures/testable_content.php
contentbank/upload.php
course/externallib.php
course/format/singleactivity/version.php
course/format/social/version.php
course/format/topics/version.php
course/format/weeks/version.php
course/lib.php
course/modedit.php
course/tests/externallib_test.php
customfield/field/checkbox/version.php
customfield/field/date/pix/checked.png [new file with mode: 0644]
customfield/field/date/pix/checked.svg [new file with mode: 0644]
customfield/field/date/pix/notchecked.png [new file with mode: 0644]
customfield/field/date/pix/notchecked.svg [new file with mode: 0644]
customfield/field/date/version.php
customfield/field/select/version.php
customfield/field/text/version.php
customfield/field/textarea/version.php
dataformat/csv/version.php
dataformat/excel/version.php
dataformat/html/version.php
dataformat/json/version.php
dataformat/ods/version.php
dataformat/pdf/version.php
enrol/category/version.php
enrol/cohort/version.php
enrol/database/version.php
enrol/flatfile/version.php
enrol/guest/version.php
enrol/imsenterprise/version.php
enrol/ldap/version.php
enrol/lti/version.php
enrol/manual/version.php
enrol/meta/version.php
enrol/mnet/version.php
enrol/paypal/version.php
enrol/self/version.php
files/converter/googledrive/version.php
files/converter/unoconv/version.php
filter/activitynames/version.php
filter/algebra/version.php
filter/censor/version.php
filter/data/version.php
filter/displayh5p/version.php
filter/emailprotect/version.php
filter/emoticon/version.php
filter/glossary/version.php
filter/mathjaxloader/version.php
filter/mediaplugin/version.php
filter/multilang/version.php
filter/tex/version.php
filter/tidy/version.php
filter/urltolink/version.php
grade/export/ods/version.php
grade/export/txt/version.php
grade/export/xls/version.php
grade/export/xml/version.php
grade/grading/form/guide/version.php
grade/grading/form/rubric/version.php
grade/import/csv/version.php
grade/import/direct/version.php
grade/import/xml/version.php
grade/report/grader/version.php
grade/report/history/version.php
grade/report/outcomes/version.php
grade/report/overview/version.php
grade/report/singleview/version.php
grade/report/user/version.php
h5p/h5plib/v124/version.php
lang/en/admin.php
lang/en/calendar.php
lang/en/contentbank.php
lang/en/course.php
lang/en/error.php
lib/adminlib.php
lib/amd/build/showhidesettings.min.js
lib/amd/build/showhidesettings.min.js.map
lib/amd/src/showhidesettings.js
lib/antivirus/clamav/version.php
lib/classes/date.php
lib/dml/oci_native_moodle_database.php
lib/dml/tests/dml_test.php
lib/editor/atto/plugins/accessibilitychecker/version.php
lib/editor/atto/plugins/accessibilityhelper/version.php
lib/editor/atto/plugins/align/version.php
lib/editor/atto/plugins/backcolor/version.php
lib/editor/atto/plugins/bold/version.php
lib/editor/atto/plugins/charmap/version.php
lib/editor/atto/plugins/clear/version.php
lib/editor/atto/plugins/collapse/version.php
lib/editor/atto/plugins/emojipicker/version.php
lib/editor/atto/plugins/emoticon/version.php
lib/editor/atto/plugins/equation/version.php
lib/editor/atto/plugins/fontcolor/version.php
lib/editor/atto/plugins/h5p/version.php
lib/editor/atto/plugins/html/version.php
lib/editor/atto/plugins/image/version.php
lib/editor/atto/plugins/indent/version.php
lib/editor/atto/plugins/italic/version.php
lib/editor/atto/plugins/link/version.php
lib/editor/atto/plugins/managefiles/version.php
lib/editor/atto/plugins/media/version.php
lib/editor/atto/plugins/noautolink/version.php
lib/editor/atto/plugins/orderedlist/version.php
lib/editor/atto/plugins/recordrtc/version.php
lib/editor/atto/plugins/rtl/version.php
lib/editor/atto/plugins/strike/version.php
lib/editor/atto/plugins/subscript/version.php
lib/editor/atto/plugins/superscript/version.php
lib/editor/atto/plugins/table/version.php
lib/editor/atto/plugins/title/version.php
lib/editor/atto/plugins/underline/version.php
lib/editor/atto/plugins/undo/version.php
lib/editor/atto/plugins/unorderedlist/version.php
lib/editor/atto/version.php
lib/editor/textarea/version.php
lib/editor/tinymce/plugins/ctrlhelp/version.php
lib/editor/tinymce/plugins/managefiles/version.php
lib/editor/tinymce/plugins/moodleemoticon/version.php
lib/editor/tinymce/plugins/moodleimage/version.php
lib/editor/tinymce/plugins/moodlemedia/version.php
lib/editor/tinymce/plugins/moodlenolink/version.php
lib/editor/tinymce/plugins/pdw/version.php
lib/editor/tinymce/plugins/spellchecker/version.php
lib/editor/tinymce/plugins/wrap/version.php
lib/editor/tinymce/version.php
lib/environmentlib.php
lib/mlbackend/php/version.php
lib/mlbackend/python/version.php
lib/moodlelib.php
lib/outputrenderers.php
lib/table/amd/build/dynamic.min.js
lib/table/amd/build/dynamic.min.js.map
lib/table/amd/src/dynamic.js
lib/tests/behat/behat_app.php
lib/tests/moodlelib_test.php
lib/tests/setuplib_test.php
lib/upgrade.txt
lib/upgradelib.php
media/player/html5audio/version.php
media/player/html5video/version.php
media/player/swf/version.php
media/player/videojs/version.php
media/player/vimeo/version.php
media/player/youtube/version.php
message/amd/build/message_drawer_view_conversation.min.js
message/amd/build/message_drawer_view_conversation.min.js.map
message/amd/src/message_drawer_view_conversation.js
message/output/airnotifier/version.php
message/output/email/version.php
message/output/jabber/version.php
message/output/popup/version.php
mnet/service/enrol/version.php
mod/assign/feedback/comments/version.php
mod/assign/feedback/editpdf/version.php
mod/assign/feedback/file/version.php
mod/assign/feedback/offline/version.php
mod/assign/submission/comments/version.php
mod/assign/submission/file/version.php
mod/assign/submission/onlinetext/version.php
mod/assign/templates/grading_navigation.mustache
mod/assign/templates/grading_navigation_user_selector.mustache
mod/assign/version.php
mod/assignment/type/offline/version.php
mod/assignment/type/online/version.php
mod/assignment/type/upload/version.php
mod/assignment/type/uploadsingle/version.php
mod/assignment/version.php
mod/book/tool/exportimscp/version.php
mod/book/tool/importhtml/version.php
mod/book/tool/print/version.php
mod/book/version.php
mod/chat/version.php
mod/choice/version.php
mod/data/field/checkbox/version.php
mod/data/field/date/version.php
mod/data/field/file/version.php
mod/data/field/latlong/version.php
mod/data/field/menu/version.php
mod/data/field/multimenu/version.php
mod/data/field/number/version.php
mod/data/field/picture/version.php
mod/data/field/radiobutton/version.php
mod/data/field/text/version.php
mod/data/field/textarea/version.php
mod/data/field/url/version.php
mod/data/preset/imagegallery/version.php
mod/data/version.php
mod/feedback/version.php
mod/folder/version.php
mod/forum/classes/grades/forum_gradeitem.php
mod/forum/classes/task/send_user_digests.php
mod/forum/lib.php
mod/forum/report/summary/version.php
mod/forum/tests/maildigest_test.php
mod/forum/version.php
mod/glossary/version.php
mod/h5pactivity/version.php
mod/imscp/version.php
mod/label/version.php
mod/lesson/version.php
mod/lti/locallib.php
mod/lti/service/basicoutcomes/version.php
mod/lti/service/gradebookservices/version.php
mod/lti/service/memberships/version.php
mod/lti/service/profile/version.php
mod/lti/service/toolproxy/version.php
mod/lti/service/toolsettings/version.php
mod/lti/version.php
mod/page/version.php
mod/quiz/accessrule/delaybetweenattempts/version.php
mod/quiz/accessrule/ipaddress/version.php
mod/quiz/accessrule/numattempts/version.php
mod/quiz/accessrule/offlineattempts/version.php
mod/quiz/accessrule/openclosedate/version.php
mod/quiz/accessrule/password/version.php
mod/quiz/accessrule/seb/version.php
mod/quiz/accessrule/securewindow/version.php
mod/quiz/accessrule/timelimit/version.php
mod/quiz/lib.php
mod/quiz/report/attemptsreport_table.php
mod/quiz/report/grading/version.php
mod/quiz/report/overview/version.php
mod/quiz/report/responses/last_responses_table.php
mod/quiz/report/responses/version.php
mod/quiz/report/statistics/version.php
mod/quiz/tests/generator_test.php
mod/quiz/version.php
mod/resource/version.php
mod/scorm/report/basic/version.php
mod/scorm/report/graphs/version.php
mod/scorm/report/interactions/version.php
mod/scorm/report/objectives/version.php
mod/scorm/version.php
mod/survey/version.php
mod/url/version.php
mod/wiki/version.php
mod/workshop/allocation/manual/version.php
mod/workshop/allocation/random/version.php
mod/workshop/allocation/scheduled/version.php
mod/workshop/eval/best/version.php
mod/workshop/form/accumulative/version.php
mod/workshop/form/comments/version.php
mod/workshop/form/numerrors/version.php
mod/workshop/form/rubric/version.php
mod/workshop/version.php
pix/e/cancel_solid_circle.png [new file with mode: 0644]
pix/e/cancel_solid_circle.svg [new file with mode: 0644]
pix/i/breadcrumbdivider.png [new file with mode: 0644]
pix/i/breadcrumbdivider.svg [new file with mode: 0644]
pix/i/home.png [new file with mode: 0644]
pix/i/menubars.png [new file with mode: 0644]
pix/i/menubars.svg [new file with mode: 0644]
pix/i/next.png [new file with mode: 0644]
pix/i/next.svg [new file with mode: 0644]
pix/i/otherevent.png [new file with mode: 0644]
pix/i/otherevent.svg [new file with mode: 0644]
pix/i/previous.png [new file with mode: 0644]
pix/i/previous.svg [new file with mode: 0644]
pix/i/privatefiles.png [new file with mode: 0644]
pix/i/section.png [new file with mode: 0644]
pix/i/star-o.png [new file with mode: 0644]
pix/i/star-o.svg [new file with mode: 0644]
pix/t/collapsedcaret.png [new file with mode: 0644]
pix/t/collapsedcaret.svg [new file with mode: 0644]
pix/t/downlong.png [new file with mode: 0644]
pix/t/downlong.svg [new file with mode: 0644]
pix/t/tags.png [new file with mode: 0644]
pix/t/uplong.png [new file with mode: 0644]
pix/t/uplong.svg [new file with mode: 0644]
portfolio/boxnet/version.php
portfolio/download/version.php
portfolio/flickr/version.php
portfolio/googledocs/version.php
portfolio/mahara/version.php
portfolio/picasa/version.php
question/behaviour/adaptive/version.php
question/behaviour/adaptivenopenalty/version.php
question/behaviour/deferredcbm/version.php
question/behaviour/deferredfeedback/version.php
question/behaviour/immediatecbm/version.php
question/behaviour/immediatefeedback/version.php
question/behaviour/informationitem/version.php
question/behaviour/interactive/version.php
question/behaviour/interactivecountback/version.php
question/behaviour/manualgraded/version.php
question/behaviour/missing/version.php
question/format/aiken/version.php
question/format/blackboard_six/version.php
question/format/examview/version.php
question/format/gift/version.php
question/format/missingword/version.php
question/format/multianswer/version.php
question/format/webct/version.php
question/format/xhtml/version.php
question/format/xml/version.php
question/type/calculated/version.php
question/type/calculatedmulti/version.php
question/type/calculatedsimple/version.php
question/type/ddimageortext/styles.css
question/type/ddimageortext/version.php
question/type/ddmarker/version.php
question/type/ddwtos/version.php
question/type/description/version.php
question/type/essay/version.php
question/type/gapselect/version.php
question/type/match/version.php
question/type/missingtype/version.php
question/type/multianswer/version.php
question/type/multichoice/version.php
question/type/numerical/version.php
question/type/random/version.php
question/type/randomsamatch/version.php
question/type/shortanswer/version.php
question/type/truefalse/version.php
report/backups/version.php
report/competency/version.php
report/completion/version.php
report/configlog/version.php
report/courseoverview/version.php
report/eventlist/version.php
report/insights/version.php
report/log/version.php
report/loglive/version.php
report/outline/version.php
report/participation/version.php
report/performance/version.php
report/progress/version.php
report/questioninstances/version.php
report/security/version.php
report/stats/version.php
report/status/version.php
report/usersessions/version.php
repository/areafiles/version.php
repository/boxnet/version.php
repository/contentbank/version.php
repository/coursefiles/version.php
repository/dropbox/version.php
repository/equella/version.php
repository/filesystem/version.php
repository/flickr/version.php
repository/flickr_public/version.php
repository/googledocs/version.php
repository/local/version.php
repository/merlot/version.php
repository/nextcloud/version.php
repository/onedrive/version.php
repository/picasa/version.php
repository/recent/version.php
repository/s3/version.php
repository/skydrive/version.php
repository/upload/version.php
repository/url/version.php
repository/user/version.php
repository/webdav/version.php
repository/wikimedia/version.php
repository/youtube/version.php
search/classes/engine.php
search/classes/manager.php
search/engine/simpledb/version.php
search/engine/solr/classes/engine.php
search/engine/solr/classes/schema.php
search/engine/solr/settings.php
search/engine/solr/tests/engine_test.php
search/engine/solr/version.php
search/index.php
search/tests/behat/search_information.feature [new file with mode: 0644]
search/tests/fixtures/testable_core_search.php
search/upgrade.txt
tag/templates/tagcloud.mustache
theme/boost/thirdpartylibs.xml
theme/boost/version.php
theme/classic/version.php
user/profile/field/checkbox/version.php
user/profile/field/datetime/version.php
user/profile/field/menu/version.php
user/profile/field/text/version.php
user/profile/field/textarea/version.php
user/tests/behat/full_name_display.feature
version.php
webservice/rest/version.php
webservice/soap/version.php
webservice/xmlrpc/version.php

index f9f7c27..e4546c5 100644 (file)
@@ -89,5 +89,4 @@ theme/boost/amd/src/bootstrap/tab.js
 theme/boost/amd/src/bootstrap/toast.js
 theme/boost/amd/src/bootstrap/tooltip.js
 theme/boost/amd/src/bootstrap/util.js
-theme/boost/amd/src/tether.js
 theme/boost/scss/fontawesome/
\ No newline at end of file
index 8b99a05..5fae1d4 100644 (file)
@@ -90,5 +90,4 @@ theme/boost/amd/src/bootstrap/tab.js
 theme/boost/amd/src/bootstrap/toast.js
 theme/boost/amd/src/bootstrap/tooltip.js
 theme/boost/amd/src/bootstrap/util.js
-theme/boost/amd/src/tether.js
 theme/boost/scss/fontawesome/
\ No newline at end of file
index d751251..27ee681 100644 (file)
@@ -174,7 +174,9 @@ before_script:
         # Enable test external resources
         sed -i \
           -e "/require_once/i \\define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://127.0.0.1:8080');" \
+          -e "/require_once/i \\define('TEST_EXTERNAL_FILES_HTTPS_URL', 'http://127.0.0.1:8080');" \
           config.php ;
+
         # Redis cache store tests
         sed -i \
           -e "/require_once/i \\define('TEST_CACHESTORE_REDIS_TESTSERVERS', '127.0.0.1');" \
@@ -254,8 +256,6 @@ script:
       if [ "$TASK" = 'PHPUNIT' ];
       then
         vendor/bin/phpunit --fail-on-risky --disallow-test-output --verbose;
-        EXTTESTS_HITS=$(docker logs exttests 2>&1 | grep -Fv -e 'AH00558' -e '[pid 1]' | wc -l)
-        echo -e "\nTest local resources number of hits: ${EXTTESTS_HITS}.\n"
       fi
 
     - >
@@ -292,3 +292,11 @@ script:
           exit 1 ;
         fi
       fi
+
+after_script:
+    - >
+      if [ "$TASK" = 'PHPUNIT' ];
+      then
+        EXTTESTS_HITS=$(docker logs exttests 2>&1 | grep -Fv -e 'AH00558' -e '[pid 1]' | wc -l)
+        echo -e "\nTest local resources number of hits: ${EXTTESTS_HITS}.\n"
+      fi
index 19b3522..f9643fa 100644 (file)
@@ -509,7 +509,8 @@ if (!$cache and $version > $CFG->version) {  // upgrade
         // Always verify plugin dependencies!
         $failed = array();
         if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed, $CFG->branch)) {
-            echo $output->unsatisfied_dependencies_page($version, $failed, $PAGE->url);
+            echo $output->unsatisfied_dependencies_page($version, $failed, new moodle_url($PAGE->url,
+                array('confirmplugincheck' => 0)));
             die();
         }
         unset($failed);
@@ -701,7 +702,8 @@ if (!$cache and moodle_needs_upgrading()) {
         $failed = array();
         if (!$pluginman->all_plugins_ok($version, $failed, $CFG->branch)) {
             $output = $PAGE->get_renderer('core', 'admin');
-            echo $output->unsatisfied_dependencies_page($version, $failed, $PAGE->url);
+            echo $output->unsatisfied_dependencies_page($version, $failed, new moodle_url($PAGE->url,
+                array('confirmplugincheck' => 0)));
             die();
         }
         unset($failed);
index cc766ce..69af954 100644 (file)
@@ -1110,7 +1110,7 @@ class core_admin_renderer extends plugin_renderer_base {
 
                 if (!empty($installabortable[$plugin->component])) {
                     $status .= $this->output->single_button(
-                        new moodle_url($this->page->url, array('abortinstall' => $plugin->component)),
+                        new moodle_url($this->page->url, array('abortinstall' => $plugin->component, 'confirmplugincheck' => 0)),
                         get_string('cancelinstallone', 'core_plugin'),
                         'post',
                         array('class' => 'actionbutton cancelinstallone d-block mt-1')
@@ -1209,7 +1209,7 @@ class core_admin_renderer extends plugin_renderer_base {
 
         if ($installabortable) {
             $out .= $this->output->single_button(
-                new moodle_url($this->page->url, array('abortinstallx' => 1)),
+                new moodle_url($this->page->url, array('abortinstallx' => 1, 'confirmplugincheck' => 0)),
                 get_string('cancelinstallall', 'core_plugin', count($installabortable)),
                 'post',
                 array('class' => 'singlebutton cancelinstallall mr-1')
index b6ba368..e7d9bf9 100644 (file)
@@ -184,6 +184,7 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
     // Add a category for the Activity Chooser.
     $ADMIN->add('courses', new admin_category('activitychooser', new lang_string('activitychoosercategory', 'course')));
     $temp = new admin_settingpage('activitychoosersettings', new lang_string('activitychoosersettings', 'course'));
+    // Tab mode for the activity chooser.
     $temp->add(
         new admin_setting_configselect(
             'activitychoosertabmode',
@@ -197,6 +198,31 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
             ]
         )
     );
+
+    // Build a list of plugins that use the footer callback.
+    $pluginswithfunction = get_plugins_with_function('custom_chooser_footer', 'lib.php');
+    $pluginsoptions = [];
+    $pluginsoptions[COURSE_CHOOSER_FOOTER_NONE] = get_string('activitychooserhidefooter', 'course');
+    if ($pluginswithfunction) {
+        foreach ($pluginswithfunction as $plugintype => $plugins) {
+            foreach ($plugins as $pluginname => $pluginfunction) {
+                $plugin = $plugintype.'_'.$pluginname;
+                $pluginsoptions[$plugin] = get_string('pluginname', $plugin);
+            }
+        }
+    }
+
+    // Select what plugin to show in the footer.
+    $temp->add(
+        new admin_setting_configselect(
+            'activitychooseractivefooter',
+            new lang_string('activitychooseractivefooter', 'course'),
+            new lang_string('activitychooseractivefooter_desc', 'course'),
+            COURSE_CHOOSER_FOOTER_NONE,
+            $pluginsoptions
+        )
+    );
+
     $ADMIN->add('activitychooser', $temp);
     $ADMIN->add('activitychooser',
         new admin_externalpage('activitychooserrecommended', new lang_string('activitychooserrecommendations', 'course'),
index 1942627..3e7c68c 100644 (file)
@@ -549,8 +549,19 @@ if ($hassiteconfig) {
 
     // Search engine selection.
     $temp->add(new admin_setting_heading('searchengineheading', new lang_string('searchengine', 'admin'), ''));
-    $temp->add(new admin_setting_configselect('searchengine',
-                                new lang_string('selectsearchengine', 'admin'), '', 'simpledb', $engines));
+    $searchengineselect = new admin_setting_configselect('searchengine',
+            new lang_string('selectsearchengine', 'admin'), '', 'simpledb', $engines);
+    $searchengineselect->set_validate_function(function(string $value): string {
+        global $CFG;
+
+        // Check nobody's setting the indexing and query-only server to the same one.
+        if (isset($CFG->searchenginequeryonly) && $CFG->searchenginequeryonly === $value) {
+            return get_string('searchenginequeryonlysame', 'admin');
+        } else {
+            return '';
+        }
+    });
+    $temp->add($searchengineselect);
     $temp->add(new admin_setting_heading('searchoptionsheading', new lang_string('searchoptions', 'admin'), ''));
     $temp->add(new admin_setting_configcheckbox('searchindexwhendisabled',
             new lang_string('searchindexwhendisabled', 'admin'), new lang_string('searchindexwhendisabled_desc', 'admin'),
@@ -590,6 +601,43 @@ if ($hassiteconfig) {
         new lang_string('searchhideallcategory_desc', 'admin'),
         0));
 
+    $temp->add(new admin_setting_heading('searchmanagement', new lang_string('searchmanagement', 'admin'),
+            new lang_string('searchmanagement_desc', 'admin')));
+
+    // Get list of search engines including those with alternate settings.
+    $searchenginequeryonlyselect = new admin_setting_configselect('searchenginequeryonly',
+            new lang_string('searchenginequeryonly', 'admin'),
+            new lang_string('searchenginequeryonly_desc', 'admin'), '', function() use($engines) {
+                $options = ['' => new lang_string('searchenginequeryonly_none', 'admin')];
+                foreach ($engines as $name => $display) {
+                    $options[$name] = $display;
+
+                    $classname = '\search_' . $name . '\engine';
+                    $engine = new $classname;
+                    if ($engine->has_alternate_configuration()) {
+                        $options[$name . '-alternate'] =
+                                new lang_string('searchenginealternatesettings', 'admin', $display);
+                    }
+                }
+                return $options;
+            });
+    $searchenginequeryonlyselect->set_validate_function(function(string $value): string {
+        global $CFG;
+
+        // Check nobody's setting the indexing and query-only server to the same one.
+        if (isset($CFG->searchengine) && $CFG->searchengine === $value) {
+            return get_string('searchenginequeryonlysame', 'admin');
+        } else {
+            return '';
+        }
+    });
+    $temp->add($searchenginequeryonlyselect);
+    $temp->add(new admin_setting_configcheckbox('searchbannerenable',
+            new lang_string('searchbannerenable', 'admin'), new lang_string('searchbannerenable_desc', 'admin'),
+            0));
+    $temp->add(new admin_setting_confightmleditor('searchbanner',
+            new lang_string('searchbanner', 'admin'), '', ''));
+
     $ADMIN->add('searchplugins', $temp);
     $ADMIN->add('searchplugins', new admin_externalpage('searchareas', new lang_string('searchareas', 'admin'),
         new moodle_url('/admin/searchareas.php')));
index c1b2056..e86bbc9 100644 (file)
@@ -363,8 +363,11 @@ $choices = array(new lang_string('never', 'admin'),
                  new lang_string('onlynoreply', 'admin'));
 $temp->add(new admin_setting_configselect('emailfromvia', new lang_string('emailfromvia', 'admin'),
           new lang_string('configemailfromvia', 'admin'), 1, $choices));
-    $temp->add(new admin_setting_configtext('emailsubjectprefix', new lang_string('emailsubjectprefix', 'admin'),
+
+$temp->add(new admin_setting_configtext('emailsubjectprefix', new lang_string('emailsubjectprefix', 'admin'),
         new lang_string('configemailsubjectprefix', 'admin'), '', PARAM_RAW));
+$temp->add(new admin_setting_configtextarea('emailheaders', new lang_string('emailheaders', 'admin'),
+        new lang_string('configemailheaders', 'admin'), '', PARAM_RAW, '50', '3'));
 
 $ADMIN->add('email', $temp);
 
index d4c2fba..c8a3a5b 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_analytics'; // Full name of the plugin (used for diagnostics).
index e1c70f5..f1adbf8 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500;
-$plugin->requires = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires = 2021052500;
 $plugin->component = 'tool_availabilityconditions';
index daee263..7779de3 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;   // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;   // Requires this Moodle version
+$plugin->version   = 2021052500;   // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;   // Requires this Moodle version
 $plugin->component = 'tool_behat'; // Full name of the plugin (used for diagnostics)
index 7babee7..4f1d333 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_capability'; // Full name of the plugin (used for diagnostics).
index 78a1b83..b293373 100644 (file)
@@ -25,8 +25,8 @@
 defined('MOODLE_INTERNAL') || die();
 
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_cohortroles'; // Full name of the plugin (used for diagnostics).
 
 $plugin->dependencies = array(
index ac32029..508df54 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;
-$plugin->requires  = 2020060900;
+$plugin->version   = 2021052500;
+$plugin->requires  = 2021052500;
 $plugin->component = 'tool_customlang'; // Full name of the plugin (used for diagnostics)
index c069301..5b5f28a 100644 (file)
@@ -95,7 +95,7 @@ function tool_dataprivacy_myprofile_navigation(tree $tree, $user, $iscurrentuser
         $showsummary = true;
     }
 
-    if ($showsummary) {
+    if ($showsummary && $iscurrentuser) {
         $summaryurl = new moodle_url('/admin/tool/dataprivacy/summary.php');
         $summarynode = new core_user\output\myprofile\node('privacyandpolicies', 'retentionsummary',
             get_string('dataretentionsummary', 'tool_dataprivacy'), null, $summaryurl);
index 1df48bc..7f590ea 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version   = 2020061501;
-$plugin->requires  = 2020060900;
+$plugin->version   = 2021052500;
+$plugin->requires  = 2021052500;
 $plugin->component = 'tool_dataprivacy';
index d89490a..409a848 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_dbtransfer'; // Full name of the plugin (used for diagnostics).
index 51da479..c618d2c 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500;
-$plugin->requires = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires = 2021052500;
 $plugin->component = 'tool_filetypes';
index 5bd0684..6f58043 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500;
-$plugin->requires = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires = 2021052500;
 $plugin->component = 'tool_generator';
index 841691d..70e8aa8 100644 (file)
@@ -25,8 +25,8 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900; // Requires this Moodle version
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500; // Requires this Moodle version
 $plugin->component = 'tool_health'; // Full name of the plugin (used for diagnostics)
 
 $plugin->maturity  = MATURITY_ALPHA; // this version's maturity level
index 6fc9cf8..0ef8577 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_httpsreplace'; // Full name of the plugin (used for diagnostics).
index 734df35..b3010b1 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900; // Requires this Moodle version
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500; // Requires this Moodle version
 $plugin->component = 'tool_innodb'; // Full name of the plugin (used for diagnostics)
index d2530c0..2c24166 100644 (file)
@@ -24,6 +24,6 @@
 defined('MOODLE_INTERNAL') || die();
 
 $plugin->component  = 'tool_installaddon';
-$plugin->version    = 2020061500;
-$plugin->requires   = 2020060900;
+$plugin->version    = 2021052500;
+$plugin->requires   = 2021052500;
 $plugin->maturity   = MATURITY_STABLE;
index dee1b46..ccd8ed3 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900; // Requires this Moodle version
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500; // Requires this Moodle version
 $plugin->component = 'tool_langimport'; // Full name of the plugin (used for diagnostics)
index a05ba8b..aa30f56 100644 (file)
@@ -24,8 +24,8 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;
-$plugin->requires  = 2020060900;         // Requires this Moodle version.
+$plugin->version   = 2021052500;
+$plugin->requires  = 2021052500;         // Requires this Moodle version.
 $plugin->component = 'tool_licensemanager';
 
 $plugin->maturity = MATURITY_STABLE;
index 70d1a2d..d0f8a6b 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires = 2020060900; // Requires this Moodle version.
+$plugin->version = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2021052500; // Requires this Moodle version.
 $plugin->component = 'logstore_database'; // Full name of the plugin (used for diagnostics).
index dbb4906..ad25e20 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires = 2020060900; // Requires this Moodle version.
+$plugin->version = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2021052500; // Requires this Moodle version.
 $plugin->component = 'logstore_legacy'; // Full name of the plugin (used for diagnostics).
index beb8247..7b7aa29 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires = 2020060900; // Requires this Moodle version.
+$plugin->version = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2021052500; // Requires this Moodle version.
 $plugin->component = 'logstore_standard'; // Full name of the plugin (used for diagnostics).
index 101e890..bb59aff 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires = 2020060900; // Requires this Moodle version.
+$plugin->version = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_log'; // Full name of the plugin (used for diagnostics).
index 855ab25..a426dd3 100644 (file)
@@ -25,6 +25,6 @@
 defined('MOODLE_INTERNAL') || die();
 
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_lp'; // Full name of the plugin (used for diagnostics).
index 032cdb5..0c4e107 100644 (file)
@@ -25,8 +25,8 @@
 defined('MOODLE_INTERNAL') || die();
 
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_lpimportcsv'; // Full name of the plugin (used for diagnostics).
-$plugin->dependencies = array('tool_lp' => 2020060900);
+$plugin->dependencies = array('tool_lp' => 2021052500);
 
index 9e15806..74d3f95 100644 (file)
@@ -24,8 +24,8 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_lpmigrate'; // Full name of the plugin (used for diagnostics).
 $plugin->dependencies = array(
     'tool_lp' => ANY_VERSION
index fa17bc3..4e04ebd 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;
-$plugin->requires  = 2020060900;
+$plugin->version   = 2021052500;
+$plugin->requires  = 2021052500;
 $plugin->component = 'tool_messageinbound';
index 33cdccd..87cd3fb 100644 (file)
@@ -23,9 +23,9 @@
  */
 
 defined('MOODLE_INTERNAL') || die();
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_mobile'; // Full name of the plugin (used for diagnostics).
 $plugin->dependencies = array(
-    'webservice_rest' => 2020060900
+    'webservice_rest' => 2021052500
 );
index c80a809..4549721 100644 (file)
@@ -26,6 +26,6 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version   = 2020061500;     // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900;     // Requires this Moodle version.
+$plugin->version   = 2021052500;     // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500;     // Requires this Moodle version.
 $plugin->component = 'tool_monitor'; // Full name of the plugin (used for diagnostics).
index 415d400..7a3d19f 100644 (file)
@@ -25,6 +25,6 @@
 defined('MOODLE_INTERNAL') || die();
 
 $plugin->component  = 'tool_moodlenet';
-$plugin->version    = 2020061502;
-$plugin->requires   = 2020060900;
+$plugin->version    = 2021052500;
+$plugin->requires   = 2021052500;
 $plugin->maturity   = MATURITY_ALPHA;
index fdc6025..39b2e6f 100644 (file)
@@ -25,7 +25,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900; // Requires this Moodle version
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500; // Requires this Moodle version
 $plugin->component = 'tool_multilangupgrade'; // Full name of the plugin (used for diagnostics)
 
index 8c9f9e8..8fbde7c 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_oauth2'; // Full name of the plugin (used for diagnostics).
 
index 4144fe5..bdb1a38 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900; // Requires this Moodle version
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500; // Requires this Moodle version
 $plugin->component = 'tool_phpunit'; // Full name of the plugin (used for diagnostics)
 
index 51d51fd..814290d 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;         // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900;         // Requires this Moodle version.
+$plugin->version   = 2021052500;         // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500;         // Requires this Moodle version.
 $plugin->component = 'tool_policy';      // Full name of the plugin (used for diagnostics).
index 9c391dc..c70260b 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900; // Requires this Moodle version
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500; // Requires this Moodle version
 $plugin->component = 'tool_profiling'; // Full name of the plugin (used for diagnostics)
index 98370c0..9d9f26a 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_recyclebin'; // Full name of the plugin (used for diagnostics).
index 3621d68..fa1f05d 100644 (file)
@@ -25,8 +25,8 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900; // Requires this Moodle version
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500; // Requires this Moodle version
 $plugin->component = 'tool_replace'; // Full name of the plugin (used for diagnostics)
 
 $plugin->maturity  = MATURITY_ALPHA; // this version's maturity level
index 4f6daba..6cb07ca 100644 (file)
@@ -25,7 +25,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;
-$plugin->requires  = 2020060900;
+$plugin->version   = 2021052500;
+$plugin->requires  = 2021052500;
 $plugin->component = 'tool_spamcleaner'; // Full name of the plugin (used for diagnostics)
 
index 636233a..1823273 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900; // Requires this Moodle version
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500; // Requires this Moodle version
 $plugin->component = 'tool_task'; // Full name of the plugin (used for diagnostics)
 
index aa6dcfb..e530aeb 100644 (file)
@@ -21,6 +21,6 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 defined('MOODLE_INTERNAL') || die();
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'tool_templatelibrary'; // Full name of the plugin (used for diagnostics).
index c4d9964..0a0cb63 100644 (file)
@@ -25,7 +25,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900; // Requires this Moodle version
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500; // Requires this Moodle version
 $plugin->component = 'tool_unsuproles'; // Full name of the plugin (used for diagnostics)
 
index ea66e94..ce4bd6a 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;            // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900;            // Requires this Moodle version.
+$plugin->version   = 2021052500;            // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500;            // Requires this Moodle version.
 $plugin->component = 'tool_uploadcourse';   // Full name of the plugin (used for diagnostics).
index cff2376..33b8c0f 100644 (file)
@@ -25,7 +25,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900; // Requires this Moodle version
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500; // Requires this Moodle version
 $plugin->component = 'tool_uploaduser'; // Full name of the plugin (used for diagnostics)
 
diff --git a/admin/tool/usertours/pix/t/filler.png b/admin/tool/usertours/pix/t/filler.png
new file mode 100644 (file)
index 0000000..055c8fb
Binary files /dev/null and b/admin/tool/usertours/pix/t/filler.png differ
index c477167..2f2cce4 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061501;            // The current module version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900;            // Requires this Moodle version.
+$plugin->version   = 2021052500;            // The current module version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500;            // Requires this Moodle version.
 $plugin->component = 'tool_usertours';      // Full name of the plugin (used for diagnostics).
index c96d978..e9c4e3c 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900; // Requires this Moodle version
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500; // Requires this Moodle version
 $plugin->component = 'tool_xmldb'; // Full name of the plugin (used for diagnostics)
 
index 4699c55..eb0c3b9 100644 (file)
@@ -26,8 +26,8 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'auth_cas';        // Full name of the plugin (used for diagnostics)
 
-$plugin->dependencies = array('auth_ldap' => 2020060900);
+$plugin->dependencies = array('auth_ldap' => 2021052500);
index a6896eb..a58b571 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'auth_db';         // Full name of the plugin (used for diagnostics)
index aa0fb66..3062a9d 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'auth_email';      // Full name of the plugin (used for diagnostics)
index 61e1f53..592dff5 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'auth_ldap';       // Full name of the plugin (used for diagnostics)
index 387670a..3084bb0 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires = 2020060900; // Requires this Moodle version.
+$plugin->version = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2021052500; // Requires this Moodle version.
 $plugin->component = 'auth_lti'; // Full name of the plugin (used for diagnostics).
index 896f866..118f53d 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'auth_manual';     // Full name of the plugin (used for diagnostics)
index c579967..0908e08 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'auth_mnet';       // Full name of the plugin (used for diagnostics)
index 249d99b..3134543 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'auth_nologin';    // Full name of the plugin (used for diagnostics)
index 5520d23..ba0248a 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'auth_none';       // Full name of the plugin (used for diagnostics)
index 22fe0b6..27c2e14 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900;        // Requires this Moodle version.
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500;        // Requires this Moodle version.
 $plugin->component = 'auth_oauth2';       // Full name of the plugin (used for diagnostics).
index 9898bc0..8f361ee 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'auth_shibboleth'; // Full name of the plugin (used for diagnostics)
index b880c4b..fb57762 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'auth_webservice'; // Full name of the plugin (used for diagnostics)
index 6883cc9..6fe5cf5 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500;
-$plugin->requires = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires = 2021052500;
 $plugin->component = 'availability_completion';
index e682886..037cc28 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500;
-$plugin->requires = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires = 2021052500;
 $plugin->component = 'availability_date';
index 9acc029..60d9be2 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500;
-$plugin->requires = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires = 2021052500;
 $plugin->component = 'availability_grade';
index 4701076..c9de221 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500;
-$plugin->requires = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires = 2021052500;
 $plugin->component = 'availability_group';
index 6efb1ad..d7cee96 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500;
-$plugin->requires = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires = 2021052500;
 $plugin->component = 'availability_grouping';
index 1eedfc8..78a91e5 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2020061500;
-$plugin->requires = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires = 2021052500;
 $plugin->component = 'availability_profile';
index ed45e94..a98f863 100644 (file)
Binary files a/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-debug.js and b/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-debug.js differ
index dd09dd5..d2c2b71 100644 (file)
Binary files a/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-min.js and b/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-min.js differ
index ed45e94..a98f863 100644 (file)
Binary files a/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form.js and b/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form.js differ
index 842b07f..9083dae 100644 (file)
@@ -408,7 +408,7 @@ M.core_availability.List = function(json, root, parentRoot) {
         noneNode.appendChild(deleteIcon.span);
 
         // Also if it's not the root, none is actually invalid, so add a label.
-        noneNode.appendChild(Y.Node.create('<span class="mt-1 label label-warning">' +
+        noneNode.appendChild(Y.Node.create('<span class="mt-1 badge badge-warning">' +
                 M.util.get_string('invalid', 'availability') + '</span>'));
     }
 
@@ -922,7 +922,7 @@ M.core_availability.Item = function(json, root) {
 
     // Add the invalid marker (empty).
     this.node.appendChild(document.createTextNode(' '));
-    this.node.appendChild(Y.Node.create('<span class="label label-warning"/>'));
+    this.node.appendChild(Y.Node.create('<span class="badge badge-warning"/>'));
 };
 
 /**
@@ -958,7 +958,7 @@ M.core_availability.Item.prototype.fillErrors = function(errors) {
         errors.push('core_availability:item_unknowntype');
     }
     // If any errors were added, add the marker to this item.
-    var errorLabel = this.node.one('> .label-warning');
+    var errorLabel = this.node.one('> .badge-warning');
     if (errors.length !== before && !errorLabel.get('firstChild')) {
         errorLabel.appendChild(document.createTextNode(M.util.get_string('invalid', 'availability')));
     } else if (errors.length === before && errorLabel.get('firstChild')) {
index 54fca21..79ecb93 100644 (file)
@@ -156,7 +156,7 @@ abstract class backup implements checksumable {
      * point is backup when some behavior/approach channged, in order to allow
      * conditional coding based on it.
      */
-    const VERSION = 2020061500;
+    const VERSION = 2021052500;
     /**
      * Usually same than major release zero version, mainly for informative/historic purposes.
      */
index 15d852a..1511c10 100644 (file)
Binary files a/backup/util/ui/amd/build/async_backup.min.js and b/backup/util/ui/amd/build/async_backup.min.js differ
index 42387a1..bfacf49 100644 (file)
Binary files a/backup/util/ui/amd/build/async_backup.min.js.map and b/backup/util/ui/amd/build/async_backup.min.js.map differ
index 59a4bc9..4854ded 100644 (file)
@@ -524,7 +524,7 @@ define(['jquery', 'core/ajax', 'core/str', 'core/notification', 'core/templates'
      */
     function getAllCopyProgress() {
         var copyids = [];
-        var progressbars = $('.progress').find('.progress-bar').not('.complete');
+        var progressbars = $('.progress').find('.progress-bar[data-operation][data-backupid][data-restoreid]').not('.complete');
 
         progressbars.each(function() {
             let progressvars = {
index 071cfc2..8c3a55a 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_activity_modules'; // Full name of the plugin (used for diagnostics)
index 65ced1e..6d9cac9 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;               // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900;               // Requires this Moodle version.
+$plugin->version   = 2021052500;               // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500;               // Requires this Moodle version.
 $plugin->component = 'block_activity_results'; // Full name of the plugin (used for diagnostics).
\ No newline at end of file
index de90f7b..8c582f8 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_admin_bookmarks'; // Full name of the plugin (used for diagnostics)
index d41ed7a..139e87e 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900;        // Requires this Moodle version.
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500;        // Requires this Moodle version.
 $plugin->component = 'block_badges';
index af5acfd..1d4d32e 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_blog_menu'; // Full name of the plugin (used for diagnostics)
index 4fb1a60..916c20b 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_blog_recent'; // Full name of the plugin (used for diagnostics)
index c6f68da..6f75d25 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_blog_tags'; // Full name of the plugin (used for diagnostics)
index 46885f1..e73b27b 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_calendar_month'; // Full name of the plugin (used for diagnostics)
index 7a91fe7..d4fef8d 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_calendar_upcoming'; // Full name of the plugin (used for diagnostics)
index 180b568..858eeed 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_comments'; // Full name of the plugin (used for diagnostics)
index 29487d8..985afe5 100644 (file)
@@ -25,7 +25,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version      = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires     = 2020060900; // Requires this Moodle version.
+$plugin->version      = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires     = 2021052500; // Requires this Moodle version.
 $plugin->component    = 'block_completionstatus';
-$plugin->dependencies = array('report_completion' => 2020060900);
+$plugin->dependencies = array('report_completion' => 2021052500);
index 81a8ade..9a94758 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_course_list'; // Full name of the plugin (used for diagnostics)
index ddf8b7b..7e4686d 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_course_summary'; // Full name of the plugin (used for diagnostics)
index 3e137af..ddff9a6 100644 (file)
@@ -24,8 +24,8 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_feedback';  // Full name of the plugin (used for diagnostics)
 
-$plugin->dependencies = array('mod_feedback' => 2020060900);
+$plugin->dependencies = array('mod_feedback' => 2021052500);
index 89324c8..80a49c2 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version = 2020061500;
-$plugin->requires  = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires  = 2021052500;
 $plugin->component = 'block_globalsearch';
index cb2cb33..5394c5d 100644 (file)
@@ -24,8 +24,8 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_glossary_random'; // Full name of the plugin (used for diagnostics)
 
-$plugin->dependencies = array('mod_glossary' => 2020060900);
+$plugin->dependencies = array('mod_glossary' => 2021052500);
index 2a5aa61..1b67f71 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_html';      // Full name of the plugin (used for diagnostics)
index 1054144..728740c 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_login';     // Full name of the plugin (used for diagnostics)
index f03ab7c..d07ef3e 100644 (file)
@@ -24,8 +24,8 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;
-$plugin->requires  = 2020060900;
+$plugin->version   = 2021052500;
+$plugin->requires  = 2021052500;
 $plugin->component = 'block_lp';
 $plugin->dependencies = array(
     'tool_lp' => ANY_VERSION
index 7849e00..d3fb9d7 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_mentees';   // Full name of the plugin (used for diagnostics)
index 55c1106..5b144de 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_mnet_hosts'; // Full name of the plugin (used for diagnostics)
index 2769409..81415da 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;         // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900;         // Requires this Moodle version.
+$plugin->version   = 2021052500;         // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500;         // Requires this Moodle version.
 $plugin->component = 'block_myoverview'; // Full name of the plugin (used for diagnostics).
index e7b6704..3402536 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_myprofile'; // Full name of the plugin (used for diagnostics)
index 952772f..8592fbb 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_navigation'; // Full name of the plugin (used for diagnostics)
index 9d60765..88ef771 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;         // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;         // Requires this Moodle version
+$plugin->version   = 2021052500;         // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;         // Requires this Moodle version
 $plugin->component = 'block_news_items'; // Full name of the plugin (used for diagnostics)
-$plugin->dependencies = array('mod_forum' => 2020060900);
+$plugin->dependencies = array('mod_forum' => 2021052500);
index 977c08b..1d951b5 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_online_users'; // Full name of the plugin (used for diagnostics)
index 9becb97..c2b1521 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_private_files'; // Full name of the plugin (used for diagnostics)
index 1c3ab26..cbe6a70 100644 (file)
@@ -24,8 +24,8 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_quiz_results'; // Full name of the plugin (used for diagnostics)
 
-$plugin->dependencies = array('mod_quiz' => 2020060900);
+$plugin->dependencies = array('mod_quiz' => 2021052500);
index 268625a..2ec02bc 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_recent_activity'; // Full name of the plugin (used for diagnostics)
index 64701ba..5a903d9 100644 (file)
@@ -22,6 +22,6 @@
  */
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;            // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900;            // Requires this Moodle version.
+$plugin->version   = 2021052500;            // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500;            // Requires this Moodle version.
 $plugin->component = 'block_recentlyaccessedcourses'; // Full name of the plugin (used for diagnostics).
index f26b43d..934433d 100644 (file)
@@ -49,13 +49,18 @@ class recentlyaccesseditems_item_exporter extends \core\external\exporter {
      * @return array Additional properties with values
      */
     protected function get_other_values(renderer_base $output) {
-        global $OUTPUT;
+        global $CFG;
+        require_once($CFG->libdir.'/modinfolib.php');
 
         return array(
-                'viewurl' => (new moodle_url('/mod/'.$this->data->modname.'/view.php',
-                        array('id' => $this->data->cmid)))->out(false),
-                'courseviewurl' => (new moodle_url('/course/view.php', array('id' => $this->data->courseid)))->out(false),
-                'icon' => $OUTPUT->image_icon('icon', get_string('pluginname', $this->data->modname), $this->data->modname)
+            'viewurl' => (new moodle_url('/mod/'.$this->data->modname.'/view.php',
+                array('id' => $this->data->cmid)))->out(false),
+            'courseviewurl' => (new moodle_url('/course/view.php', array('id' => $this->data->courseid)))->out(false),
+            'icon' => \html_writer::img(
+                get_fast_modinfo($this->data->courseid)->cms[$this->data->cmid]->get_icon_url(),
+                get_string('pluginname', $this->data->modname),
+                ['title' => get_string('pluginname', $this->data->modname), 'class' => 'icon']
+            )
         );
     }
 
@@ -111,4 +116,4 @@ class recentlyaccesseditems_item_exporter extends \core\external\exporter {
             )
         );
     }
-}
\ No newline at end of file
+}
index cceeb66..0760701 100644 (file)
@@ -22,6 +22,6 @@
  */
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;            // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900;            // Requires this Moodle version.
+$plugin->version   = 2021052500;            // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500;            // Requires this Moodle version.
 $plugin->component = 'block_recentlyaccesseditems'; // Full name of the plugin (used for diagnostics).
index bc034a6..135b32e 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_rss_client'; // Full name of the plugin (used for diagnostics)
index 2f9685c..e941df9 100644 (file)
@@ -24,8 +24,8 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_search_forums'; // Full name of the plugin (used for diagnostics)
 
-$plugin->dependencies = array('mod_forum' => 2020060900);
+$plugin->dependencies = array('mod_forum' => 2021052500);
index 084fbd0..96451a2 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_section_links'; // Full name of the plugin (used for diagnostics)
index 17f539a..3b0b4de 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_selfcompletion'; // Full name of the plugin (used for diagnostics)
index 25f1487..3803027 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_settings';  // Full name of the plugin (used for diagnostics)
index fa01048..592e852 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_site_main_menu'; // Full name of the plugin (used for diagnostics)
index 1e4079d..8f4d507 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_social_activities'; // Full name of the plugin (used for diagnostics)
index 70c9230..c205fbe 100644 (file)
@@ -23,6 +23,6 @@
  */
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version = 2020061500;
-$plugin->requires  = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires  = 2021052500;
 $plugin->component = 'block_starredcourses';
\ No newline at end of file
index 7c091ab..0dcf070 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_tag_flickr'; // Full name of the plugin (used for diagnostics)
index ad0c955..eb799bb 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_tag_youtube'; // Full name of the plugin (used for diagnostics)
index f255d84..03696c3 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'block_tags';      // Full name of the plugin (used for diagnostics)
index 3b3f2b2..185c3cd 100644 (file)
Binary files a/blocks/timeline/amd/build/event_list.min.js and b/blocks/timeline/amd/build/event_list.min.js differ
index 4d8f7bd..441b4e2 100644 (file)
Binary files a/blocks/timeline/amd/build/event_list.min.js.map and b/blocks/timeline/amd/build/event_list.min.js.map differ
index c7c504e..f1bd1b4 100644 (file)
@@ -132,7 +132,7 @@ function(
         };
 
         calendarEvents.forEach(function(calendarEvent) {
-            var dayTimestamp = UserDate.getUserMidnightForTimestamp(calendarEvent.timesort, midnight);
+            var dayTimestamp = calendarEvent.timeusermidnight;
             if (eventsByDay[dayTimestamp]) {
                 eventsByDay[dayTimestamp].push(calendarEvent);
             } else {
index dc188ab..b088df0 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;         // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900;         // Requires this Moodle version.
+$plugin->version   = 2021052500;         // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500;         // Requires this Moodle version.
 $plugin->component = 'block_timeline'; // Full name of the plugin (used for diagnostics).
index e4023f9..6581e2b 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;        // Requires this Moodle version
+$plugin->version   = 2021052500;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;        // Requires this Moodle version
 $plugin->component = 'cachelock_file';  // Full name of the plugin (used for diagnostics)
index dff2b21..64d3635 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version = 2020061500;
-$plugin->requires = 2020060900;
+$plugin->version = 2021052500;
+$plugin->requires = 2021052500;
 $plugin->maturity = MATURITY_STABLE;
 $plugin->component = 'cachestore_apcu';
index 0233c76..1b7d49b 100644 (file)
@@ -27,6 +27,6 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version = 2020061500;    // The current module version (Date: YYYYMMDDXX)
-$plugin->requires = 2020060900;    // Requires this Moodle version.
+$plugin->version = 2021052500;    // The current module version (Date: YYYYMMDDXX)
+$plugin->requires = 2021052500;    // Requires this Moodle version.
 $plugin->component = 'cachestore_file';  // Full name of the plugin.
\ No newline at end of file
index 8c8786b..bd9b268 100644 (file)
@@ -26,6 +26,6 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version   = 2020061500;    // The current module version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;    // Requires this Moodle version.
+$plugin->version   = 2021052500;    // The current module version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;    // Requires this Moodle version.
 $plugin->component = 'cachestore_memcached';  // Full name of the plugin.
\ No newline at end of file
index 0849468..4d18f84 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version   = 2020061500;    // The current module version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;    // Requires this Moodle version.
+$plugin->version   = 2021052500;    // The current module version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;    // Requires this Moodle version.
 $plugin->component = 'cachestore_mongodb';  // Full name of the plugin.
\ No newline at end of file
index 5ef450e..0c71a1a 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version    = 2020061500;
-$plugin->requires   = 2020060900; // Requires this Moodle version.
+$plugin->version    = 2021052500;
+$plugin->requires   = 2021052500; // Requires this Moodle version.
 $plugin->maturity   = MATURITY_STABLE;
 $plugin->component  = 'cachestore_redis';
index 7e3eee5..9b4d2d8 100644 (file)
@@ -27,6 +27,6 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version = 2020061500;    // The current module version (Date: YYYYMMDDXX)
-$plugin->requires = 2020060900;    // Requires this Moodle version.
+$plugin->version = 2021052500;    // The current module version (Date: YYYYMMDDXX)
+$plugin->requires = 2021052500;    // Requires this Moodle version.
 $plugin->component = 'cachestore_session';  // Full name of the plugin.
\ No newline at end of file
index 6ee5dcd..ffa23dc 100644 (file)
@@ -27,6 +27,6 @@
 
 defined('MOODLE_INTERNAL') || die;
 
-$plugin->version   = 2020061500;    // The current module version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;    // Requires this Moodle version.
+$plugin->version   = 2021052500;    // The current module version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;    // Requires this Moodle version.
 $plugin->component = 'cachestore_static';  // Full name of the plugin.
\ No newline at end of file
index 5342220..2107414 100644 (file)
@@ -87,6 +87,7 @@ class event_exporter_base extends exporter {
         $data->timestart = $starttimestamp;
         $data->timeduration = $endtimestamp - $starttimestamp;
         $data->timesort = $event->get_times()->get_sort_time()->getTimestamp();
+        $data->timeusermidnight = $event->get_times()->get_usermidnight_time()->getTimestamp();
         $data->visible = $event->is_visible() ? 1 : 0;
         $data->timemodified = $event->get_times()->get_modified_time()->getTimestamp();
         $data->component = $event->get_component();
@@ -183,6 +184,7 @@ class event_exporter_base extends exporter {
             'timestart' => ['type' => PARAM_INT],
             'timeduration' => ['type' => PARAM_INT],
             'timesort' => ['type' => PARAM_INT],
+            'timeusermidnight' => ['type' => PARAM_INT],
             'visible' => ['type' => PARAM_INT],
             'timemodified' => ['type' => PARAM_INT],
         ];
index 98ad278..80ddbf0 100644 (file)
@@ -86,6 +86,9 @@ class week_day_exporter extends day_exporter {
                 'type' => PARAM_RAW,
                 'default' => '',
             ],
+            'daytitle' => [
+                'type' => PARAM_RAW,
+            ]
         ]);
 
         return $return;
@@ -104,6 +107,8 @@ class week_day_exporter extends day_exporter {
             $return['popovertitle'] = $popovertitle;
         }
 
+        $return['daytitle'] = $this->get_day_title();
+
         return $return;
     }
 
@@ -141,4 +146,24 @@ class week_day_exporter extends day_exporter {
 
         return $title;
     }
+
+    /**
+     * Get the title for this day.
+     *
+     * @return string
+     */
+    protected function get_day_title(): string {
+        $userdate = userdate($this->data[0], get_string('strftimedayshort'));
+
+        $numevents = count($this->related['events']);
+        if ($numevents == 1) {
+            $title = get_string('dayeventsone', 'calendar', $userdate);
+        } else if ($numevents) {
+            $title = get_string('dayeventsmany', 'calendar', ['num' => $numevents, 'day' => $userdate]);
+        } else {
+            $title = get_string('dayeventsnone', 'calendar', $userdate);
+        }
+
+        return $title;
+    }
 }
index 1fa43c2..b964673 100644 (file)
@@ -191,7 +191,8 @@ abstract class event_abstract_factory implements event_factory_interface {
                 (new \DateTimeImmutable())->setTimestamp($dbrow->timestart),
                 (new \DateTimeImmutable())->setTimestamp($dbrow->timestart + $dbrow->timeduration),
                 (new \DateTimeImmutable())->setTimestamp($dbrow->timesort ? $dbrow->timesort : $dbrow->timestart),
-                (new \DateTimeImmutable())->setTimestamp($dbrow->timemodified)
+                (new \DateTimeImmutable())->setTimestamp($dbrow->timemodified),
+                (new \DateTimeImmutable())->setTimestamp(usergetmidnight($dbrow->timesort))
             ),
             !empty($dbrow->visible),
             $subscription,
index a6746ea..a0ca5ba 100644 (file)
@@ -136,6 +136,7 @@ class event_mapper implements event_mapper_interface {
             'timestart'        => $event->get_times()->get_start_time()->getTimestamp(),
             'timeduration'     => $timeduration,
             'timesort'         => $event->get_times()->get_sort_time()->getTimestamp(),
+            'timeusermidnight' => $event->get_times()->get_usermidnight_time()->getTimestamp(),
             'visible'          => $event->is_visible() ? 1 : 0,
             'timemodified'     => $event->get_times()->get_modified_time()->getTimestamp(),
             'subscriptionid'   => $event->get_subscription() ? $event->get_subscription()->get('id') : null,
index 511b59c..b146146 100644 (file)
@@ -53,24 +53,32 @@ class event_times implements times_interface {
      */
     protected $modified;
 
+    /**
+     * @var \DateTimeImmutable $usermidnight User midnight for the event.
+     */
+    protected $usermidnight;
+
     /**
      * Constructor.
      *
-     * @param \DateTimeImmutable $start    Event start time.
-     * @param \DateTimeImmutable $end      Event end time.
-     * @param \DateTimeImmutable $sort     Date used to sort events.
-     * @param \DateTimeImmutable $modified Time event was last updated.
+     * @param \DateTimeImmutable $start        Event start time.
+     * @param \DateTimeImmutable $end          Event end time.
+     * @param \DateTimeImmutable $sort         Date used to sort events.
+     * @param \DateTimeImmutable $modified     Time event was last updated.
+     * @param \DateTimeImmutable $usermidnight User midnight for the event.
      */
     public function __construct(
         \DateTimeImmutable $start,
         \DateTimeImmutable $end,
         \DateTimeImmutable $sort,
-        \DateTimeImmutable $modified
+        \DateTimeImmutable $modified,
+        \DateTimeImmutable $usermidnight
     ) {
         $this->start = $start;
         $this->end = $end;
         $this->sort = $sort;
         $this->modified = $modified;
+        $this->usermidnight = $usermidnight;
     }
 
     public function get_start_time() {
@@ -92,4 +100,13 @@ class event_times implements times_interface {
     public function get_sort_time() {
         return $this->sort;
     }
+
+    /**
+     * Getter for usermidnight.
+     *
+     * @return \DateTimeImmutable
+     */
+    public function get_usermidnight_time() {
+        return $this->usermidnight;
+    }
 }
index 22cc821..44fc076 100644 (file)
@@ -67,4 +67,11 @@ interface times_interface {
      * @return \DateTimeImmutable
      */
     public function get_modified_time();
+
+    /**
+     * Get the user midnight time.
+     *
+     * @return \DateTimeImmutable
+     */
+    public function get_usermidnight_time();
 }
index c194636..541f1b2 100644 (file)
@@ -178,6 +178,7 @@ define('CALENDAR_EVENT_TYPE_ACTION', 1);
  * @property string $eventtype The event type
  * @property int $timestart The start time as a timestamp
  * @property int $timeduration The duration of the event in seconds
+ * @property int $timeusermidnight User midnight for the event
  * @property int $visible 1 if the event is visible
  * @property int $uuid ?
  * @property int $sequence ?
index a88f65e..ba01dfe 100644 (file)
@@ -46,8 +46,9 @@
         <thead>
             <tr>
                 {{# daynames }}
-                <th class="header text-xs-center" aria-label="{{fullname}}">
-                    {{shortname}}
+                <th class="header text-xs-center">
+                    <span class="sr-only">{{fullname}}</span>
+                    <span aria-hidden="true">{{shortname}}</span>
                 </th>
                 {{/ daynames }}
             </tr>
@@ -71,6 +72,7 @@
                         data-region="day"
                         data-new-event-timestamp="{{neweventtimestamp}}">
                         <div class="d-none d-md-block hidden-phone text-xs-center">
+                            <span class="sr-only">{{daytitle}}</span>
                             {{#hasevents}}
                                 <a data-action="view-day-link" href="#" class="aalink day" aria-label="{{viewdaylinktitle}}"
                                     data-year="{{date.year}}" data-month="{{date.mon}}" data-day="{{mday}}"
@@ -78,7 +80,7 @@
                                     data-timestamp="{{timestamp}}">{{mday}}</a>
                             {{/hasevents}}
                             {{^hasevents}}
-                                {{mday}}
+                                <span aria-hidden="true">{{mday}}</span>
                             {{/hasevents}}
                             {{#hasevents}}
                                 <div data-region="day-content">
                             {{/hasevents}}
                         </div>
                         <div class="d-md-none hidden-desktop hidden-tablet">
+                            <span class="sr-only">{{daytitle}}</span>
                             {{#hasevents}}
                                 <a data-action="view-day-link" href="#" class="day aalink" aria-label="{{viewdaylinktitle}}"
                                     data-year="{{date.year}}" data-month="{{date.mon}}" data-day="{{mday}}"
                                     data-timestamp="{{timestamp}}">{{mday}}</a>
                             {{/hasevents}}
                             {{^hasevents}}
-                                    {{mday}}
+                                <span aria-hidden="true">{{mday}}</span>
                             {{/hasevents}}
                         </div>
                     </td>
index ff10a74..4ff2656 100644 (file)
@@ -78,8 +78,9 @@
         <thead>
           <tr>
                 {{# daynames }}
-                <th class="header text-xs-center" scope="col" aria-label="{{fullname}}">
-                    {{shortname}}
+                <th class="header text-xs-center">
+                    <span class="sr-only">{{fullname}}</span>
+                    <span aria-hidden="true">{{shortname}}</span>
                 </th>
                 {{/ daynames }}
             </tr>
                         This is the timestamp for this month.
                         }} data-day-timestamp="{{timestamp}}"{{!
                     }}>{{!
-                        }}{{#popovertitle}}
+                        }}<span class="sr-only">{{daytitle}}</span>
+                        {{#popovertitle}}
                             {{< core_calendar/minicalendar_day_link }}
                                 {{$day}}{{mday}}{{/day}}
                                 {{$url}}{{viewdaylink}}{{/url}}
                             {{/ core_calendar/minicalendar_day_link }}
                         {{/popovertitle}}{{!
                         }}{{^popovertitle}}
-                            {{mday}}
+                            <span aria-hidden="true">{{mday}}</span>
                         {{/popovertitle}}{{!
                     }}</td>
                 {{/days}}
index e9cafd7..e694563 100644 (file)
@@ -367,7 +367,8 @@ class event_mapper_test_event implements event_interface {
             (new \DateTimeImmutable())->setTimestamp(-386380800),
             (new \DateTimeImmutable())->setTimestamp(115776000),
             (new \DateTimeImmutable())->setTimestamp(115776000),
-            (new \DateTimeImmutable())->setTimestamp(time())
+            (new \DateTimeImmutable())->setTimestamp(time()),
+            (new \DateTimeImmutable())->setTimestamp(115776000)
         );
     }
 
index 9302a9d..843bce0 100644 (file)
@@ -98,7 +98,8 @@ class core_calendar_event_testcase extends advanced_testcase {
                         (new \DateTimeImmutable())->setTimestamp(-386380800),
                         (new \DateTimeImmutable())->setTimestamp(115776000),
                         (new \DateTimeImmutable())->setTimestamp(115776000),
-                        (new \DateTimeImmutable())->setTimestamp(time())
+                        (new \DateTimeImmutable())->setTimestamp(time()),
+                        (new \DateTimeImmutable())->setTimestamp(115776000)
                     ),
                     'visible' => true,
                     'subscription' => new std_proxy(1, $lamecallable),
index 607c869..ee7e5e1 100644 (file)
@@ -44,7 +44,8 @@ class core_calendar_event_times_testcase extends advanced_testcase {
             $constructorparams['start_time'],
             $constructorparams['end_time'],
             $constructorparams['sort_time'],
-            $constructorparams['modified_time']
+            $constructorparams['modified_time'],
+            $constructorparams['usermidnight_time']
         );
 
         foreach ($constructorparams as $name => $value) {
@@ -64,7 +65,8 @@ class core_calendar_event_times_testcase extends advanced_testcase {
                     'start_time' => (new \DateTimeImmutable())->setTimestamp(-386380800),
                     'end_time' => (new \DateTimeImmutable())->setTimestamp(115776000),
                     'sort_time' => (new \DateTimeImmutable())->setTimestamp(115776000),
-                    'modified_time' => (new \DateTimeImmutable())->setTimestamp(time())
+                    'modified_time' => (new \DateTimeImmutable())->setTimestamp(time()),
+                    'usermidnight_time' => (new \DateTimeImmutable())->setTimestamp(115776000),
                 ]
             ],
             'Dataset 2' => [
@@ -72,7 +74,8 @@ class core_calendar_event_times_testcase extends advanced_testcase {
                     'start_time' => (new \DateTimeImmutable())->setTimestamp(123456),
                     'end_time' => (new \DateTimeImmutable())->setTimestamp(12345678),
                     'sort_time' => (new \DateTimeImmutable())->setTimestamp(1111),
-                    'modified_time' => (new \DateTimeImmutable())->setTimestamp(time())
+                    'modified_time' => (new \DateTimeImmutable())->setTimestamp(time()),
+                    'usermidnight_time' => (new \DateTimeImmutable())->setTimestamp(1111),
                 ]
             ]
         ];
index 67f41ff..a1e2004 100644 (file)
@@ -133,7 +133,8 @@ class action_event_test_factory implements event_factory_interface {
                 (new \DateTimeImmutable())->setTimestamp($record->timestart),
                 (new \DateTimeImmutable())->setTimestamp($record->timestart + $record->timeduration),
                 (new \DateTimeImmutable())->setTimestamp($record->timesort ? $record->timesort : $record->timestart),
-                (new \DateTimeImmutable())->setTimestamp($record->timemodified)
+                (new \DateTimeImmutable())->setTimestamp($record->timemodified),
+                (new \DateTimeImmutable())->setTimestamp(usergetmidnight($record->timesort))
             ),
             !empty($record->visible),
             $subscription,
index f11e271..0b50958 100644 (file)
@@ -201,7 +201,8 @@ class core_calendar_repeat_event_collection_event_test_factory implements event_
                 (new \DateTimeImmutable())->setTimestamp($dbrow->timestart),
                 (new \DateTimeImmutable())->setTimestamp($dbrow->timestart + $dbrow->timeduration),
                 (new \DateTimeImmutable())->setTimestamp($dbrow->timesort ? $dbrow->timesort : $dbrow->timestart),
-                (new \DateTimeImmutable())->setTimestamp($dbrow->timemodified)
+                (new \DateTimeImmutable())->setTimestamp($dbrow->timemodified),
+                (new \DateTimeImmutable())->setTimestamp(usergetmidnight($dbrow->timesort))
             ),
             !empty($dbrow->visible),
             new std_proxy($dbrow->subscriptionid, $identity),
index b5e1e47..df5601a 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires  = 2020060900; // Requires this Moodle version.
+$plugin->version   = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2021052500; // Requires this Moodle version.
 $plugin->component = 'calendartype_gregorian'; // Full name of the plugin (used for diagnostics).
index c458319..5e9f641 100644 (file)
@@ -1,6 +1,10 @@
 This files describes API changes in /calendar/* ,
 information provided here is intended especially for developers.
 
+=== 4.0 ===
+* The core_calendar\local\event\value_objects\times_interface class now has new method get_usermidnight_time() which
+  returns the user midnight time for a given event.
+
 === 3.9 ===
 * Plugins can now create their own calendar events, both standard and action ones. To do it they need to specify
   $event->component when creating an event. Component events can not be edited or deleted manually.
index c9dad88..b8a9d40 100644 (file)
@@ -237,6 +237,42 @@ abstract class content {
         return $this->content->configdata;
     }
 
+    /**
+     * Import a file as a valid content.
+     *
+     * By default, all content has a public file area to interact with the content bank
+     * repository. This method should be overridden by contentypes which does not simply
+     * upload to the public file area.
+     *
+     * If any, the method will return the final stored_file. This way it can be invoked
+     * as parent::import_file in case any plugin want to store the file in the public area
+     * and also parse it.
+     *
+     * @throws file_exception If file operations fail
+     * @param stored_file $file File to store in the content file area.
+     * @return stored_file|null the stored content file or null if the file is discarted.
+     */
+    public function import_file(stored_file $file): ?stored_file {
+        $originalfile = $this->get_file();
+        if ($originalfile) {
+            $originalfile->replace_file_with($file);
+            return $originalfile;
+        } else {
+            $itemid = $this->get_id();
+            $fs = get_file_storage();
+            $filerecord = [
+                'contextid' => $this->get_contextid(),
+                'component' => 'contentbank',
+                'filearea' => 'public',
+                'itemid' => $this->get_id(),
+                'filepath' => '/',
+                'filename' => $file->get_filename(),
+                'timecreated' => time(),
+            ];
+            return $fs->create_file_from_storedfile($filerecord, $file);
+        }
+    }
+
     /**
      * Returns the $file related to this content.
      *
index 326e304..307b949 100644 (file)
@@ -224,6 +224,8 @@ class contentbank {
     /**
      * Create content from a file information.
      *
+     * @throws file_exception If file operations fail
+     * @throws dml_exception if the content creation fails
      * @param \context $context Context where to upload the file and content.
      * @param int $userid Id of the user uploading the file.
      * @param stored_file $file The file to get information from
@@ -243,7 +245,7 @@ class contentbank {
         $record->name = $filename;
         $record->usercreated = $userid;
         $contentype = new $classname($context);
-        $content = $contentype->create_content($record);
+        $content = $contentype->upload_content($file, $record);
         $event = \core\event\contentbank_content_uploaded::create_from_record($content->get_content());
         $event->trigger();
         return $content;
index 6b6a140..699cee0 100644 (file)
@@ -27,6 +27,8 @@ namespace core_contentbank;
 use core\event\contentbank_content_created;
 use core\event\contentbank_content_deleted;
 use core\event\contentbank_content_viewed;
+use stored_file;
+use Exception;
 use moodle_url;
 
 /**
@@ -62,10 +64,11 @@ abstract class contenttype {
     /**
      * Fills content_bank table with appropiate information.
      *
+     * @throws dml_exception A DML specific exception is thrown for any creation error.
      * @param \stdClass $record An optional content record compatible object (default null)
      * @return content  Object with content bank information.
      */
-    public function create_content(\stdClass $record = null): ?content {
+    public function create_content(\stdClass $record = null): content {
         global $USER, $DB;
 
         $entry = new \stdClass();
@@ -79,15 +82,37 @@ abstract class contenttype {
         $entry->configdata = $record->configdata ?? '';
         $entry->instanceid = $record->instanceid ?? 0;
         $entry->id = $DB->insert_record('contentbank_content', $entry);
-        if ($entry->id) {
-            $classname = '\\'.$entry->contenttype.'\\content';
-            $content = new $classname($entry);
-            // Trigger an event for creating the content.
-            $event = contentbank_content_created::create_from_record($content->get_content());
-            $event->trigger();
-            return $content;
+        $classname = '\\'.$entry->contenttype.'\\content';
+        $content = new $classname($entry);
+        // Trigger an event for creating the content.
+        $event = contentbank_content_created::create_from_record($content->get_content());
+        $event->trigger();
+        return $content;
+    }
+
+    /**
+     * Create a new content from an uploaded file.
+     *
+     * @throws file_exception If file operations fail
+     * @throws dml_exception if the content creation fails
+     * @param stored_file $file the uploaded file
+     * @param \stdClass|null $record an optional content record
+     * @return content  Object with content bank information.
+     */
+    public function upload_content(stored_file $file, \stdClass $record = null): content {
+        if (empty($record)) {
+            $record = new \stdClass();
+            $record->name = $file->get_filename();
         }
-        return null;
+        $content = $this->create_content($record);
+        try {
+            $content->import_file($file);
+        } catch (Exception $e) {
+            $this->delete_content($content);
+            throw $e;
+        }
+
+        return $content;
     }
 
     /**
index 0841770..823d089 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;         // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;         // Requires this Moodle version
+$plugin->version   = 2021052500;         // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;         // Requires this Moodle version
 $plugin->component = 'contenttype_h5p'; // Full name of the plugin (used for diagnostics).
index 45c70c8..b0bfede 100644 (file)
@@ -189,4 +189,88 @@ class core_contenttype_content_testcase extends \advanced_testcase {
         $this->assertEquals($newcontext->id, $content->get_contextid());
         $this->assertEquals($newcontext->id, $file->get_contextid());
     }
+
+    /**
+     * Tests for 'import_file' behaviour when replacing a file.
+     *
+     * @covers ::import_file
+     */
+    public function test_import_file_replace(): void {
+        global $USER;
+        $this->resetAfterTest();
+        $this->setAdminUser();
+        $context = context_system::instance();
+
+        // Add some content to the content bank.
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
+        $contents = $generator->generate_contentbank_data('contenttype_testable', 3, 0, $context);
+        $content = reset($contents);
+
+        $originalfile = $content->get_file();
+
+        // Create a dummy file.
+        $filerecord = array(
+            'contextid' => $context->id,
+            'component' => 'contentbank',
+            'filearea' => 'draft',
+            'itemid' => $content->get_id(),
+            'filepath' => '/',
+            'filename' => 'example.txt'
+        );
+        $fs = get_file_storage();
+        $file = $fs->create_file_from_string($filerecord, 'Dummy content ');
+
+        $importedfile = $content->import_file($file);
+
+        $this->assertEquals($originalfile->get_filename(), $importedfile->get_filename());
+        $this->assertEquals($originalfile->get_filearea(), $importedfile->get_filearea());
+        $this->assertEquals($originalfile->get_filepath(), $importedfile->get_filepath());
+        $this->assertEquals($originalfile->get_mimetype(), $importedfile->get_mimetype());
+
+        $this->assertEquals($file->get_userid(), $importedfile->get_userid());
+        $this->assertEquals($file->get_contenthash(), $importedfile->get_contenthash());
+    }
+
+    /**
+     * Tests for 'import_file' behaviour when uploading a new file.
+     *
+     * @covers ::import_file
+     */
+    public function test_import_file_upload(): void {
+        global $USER;
+        $this->resetAfterTest();
+        $this->setAdminUser();
+        $context = context_system::instance();
+
+        $type = new contenttype($context);
+        $record = (object)[
+            'name' => 'content name',
+            'usercreated' => $USER->id,
+        ];
+        $content = $type->create_content($record);
+
+        // Create a dummy file.
+        $filerecord = array(
+            'contextid' => $context->id,
+            'component' => 'contentbank',
+            'filearea' => 'draft',
+            'itemid' => $content->get_id(),
+            'filepath' => '/',
+            'filename' => 'example.txt'
+        );
+        $fs = get_file_storage();
+        $file = $fs->create_file_from_string($filerecord, 'Dummy content ');
+
+        $importedfile = $content->import_file($file);
+
+        $this->assertEquals($file->get_filename(), $importedfile->get_filename());
+        $this->assertEquals($file->get_userid(), $importedfile->get_userid());
+        $this->assertEquals($file->get_mimetype(), $importedfile->get_mimetype());
+        $this->assertEquals($file->get_contenthash(), $importedfile->get_contenthash());
+        $this->assertEquals('public', $importedfile->get_filearea());
+        $this->assertEquals('/', $importedfile->get_filepath());
+
+        $contentfile = $content->get_file($file);
+        $this->assertEquals($importedfile->get_id(), $contentfile->get_id());
+    }
 }
index d347a72..cd22e80 100644 (file)
@@ -112,14 +112,14 @@ class core_contentbank_testcase extends advanced_testcase {
         $this->resetAfterTest();
 
         $cb = new contentbank();
-        $expectedsupporters = [$extension => $expected];
 
         $systemcontext = context_system::instance();
 
         // All contexts allowed for admins.
         $this->setAdminUser();
         $contextsupporters = $cb->load_context_supported_extensions($systemcontext);
-        $this->assertEquals($expectedsupporters, $contextsupporters);
+        $this->assertArrayHasKey($extension, $contextsupporters);
+        $this->assertEquals($expected, $contextsupporters[$extension]);
     }
 
     /**
@@ -161,7 +161,6 @@ class core_contentbank_testcase extends advanced_testcase {
         $this->resetAfterTest();
 
         $cb = new contentbank();
-        $expectedsupporters = [$extension => $expected];
 
         $course = $this->getDataGenerator()->create_course();
         $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
@@ -170,7 +169,8 @@ class core_contentbank_testcase extends advanced_testcase {
 
         // Teachers has permission in their context to upload supported by H5P content type.
         $contextsupporters = $cb->load_context_supported_extensions($coursecontext);
-        $this->assertEquals($expectedsupporters, $contextsupporters);
+        $this->assertArrayHasKey($extension, $contextsupporters);
+        $this->assertEquals($expected, $contextsupporters[$extension]);
     }
 
     /**
index f3bc67b..1fee5be 100644 (file)
@@ -27,6 +27,8 @@ namespace core_contentbank;
 
 use stdClass;
 use context_system;
+use context_user;
+use Exception;
 use contenttype_testable\contenttype as contenttype;
 /**
  * Test for content bank contenttype class.
@@ -183,6 +185,111 @@ class core_contenttype_contenttype_testcase extends \advanced_testcase {
         $this->assertInstanceOf('\\contenttype_testable\\content', $content);
     }
 
+    /**
+     * Tests for behaviour of upload_content() with a file and a record.
+     *
+     * @dataProvider upload_content_provider
+     * @param bool $userecord if a predefined record has to be used.
+     *
+     * @covers ::upload_content
+     */
+    public function test_upload_content(bool $userecord): void {
+        global $USER;
+
+        $this->resetAfterTest();
+        $this->setAdminUser();
+
+        $dummy = [
+            'contextid' => context_user::instance($USER->id)->id,
+            'component' => 'user',
+            'filearea' => 'draft',
+            'itemid' => 1,
+            'filepath' => '/',
+            'filename' => 'file.h5p',
+            'userid' => $USER->id,
+        ];
+        $fs = get_file_storage();
+        $dummyfile = $fs->create_file_from_string($dummy, 'Dummy content');
+
+        // Create content.
+        if ($userecord) {
+            $record = new stdClass();
+            $record->name = 'Test content';
+            $record->configdata = '';
+            $record->contenttype = '';
+            $checkname = $record->name;
+        } else {
+            $record = null;
+            $checkname = $dummyfile->get_filename();
+        }
+
+        $contenttype = new contenttype(context_system::instance());
+        $content = $contenttype->upload_content($dummyfile, $record);
+
+        $this->assertEquals('contenttype_testable', $content->get_content_type());
+        $this->assertEquals($checkname, $content->get_name());
+        $this->assertInstanceOf('\\contenttype_testable\\content', $content);
+
+        $file = $content->get_file();
+        $this->assertEquals($dummyfile->get_filename(), $file->get_filename());
+        $this->assertEquals($dummyfile->get_userid(), $file->get_userid());
+        $this->assertEquals($dummyfile->get_mimetype(), $file->get_mimetype());
+        $this->assertEquals($dummyfile->get_contenthash(), $file->get_contenthash());
+        $this->assertEquals('contentbank', $file->get_component());
+        $this->assertEquals('public', $file->get_filearea());
+        $this->assertEquals('/', $file->get_filepath());
+    }
+
+    /**
+     * Data provider for test_rename_content.
+     *
+     * @return  array
+     */
+    public function upload_content_provider() {
+        return [
+            'With record' => [true],
+            'Without record' => [false],
+        ];
+    }
+
+    /**
+     * Tests for behaviour of upload_content() with a file wrong file.
+     *
+     * @covers ::upload_content
+     */
+    public function test_upload_content_exception(): void {
+        global $USER, $DB;
+
+        $this->resetAfterTest();
+        $this->setAdminUser();
+
+        // The testing contenttype thows exception if filename is "error.*".
+        $dummy = [
+            'contextid' => context_user::instance($USER->id)->id,
+            'component' => 'user',
+            'filearea' => 'draft',
+            'itemid' => 1,
+            'filepath' => '/',
+            'filename' => 'error.txt',
+            'userid' => $USER->id,
+        ];
+        $fs = get_file_storage();
+        $dummyfile = $fs->create_file_from_string($dummy, 'Dummy content');
+
+        $contenttype = new contenttype(context_system::instance());
+        $cbcontents = $DB->count_records('contentbank_content');
+
+        // We need to capture the exception to check no content is created.
+        try {
+            $content = $contenttype->upload_content($dummyfile);
+            $this->assertTrue(false);
+        } catch (Exception $e) {
+            $this->assertTrue(true);
+        }
+        $this->assertEquals($cbcontents, $DB->count_records('contentbank_content'));
+        $this->assertEquals(1, $DB->count_records('files', ['contenthash' => $dummyfile->get_contenthash()]));
+    }
+
     /**
      * Test the behaviour of can_delete().
      */
index d379dea..3d3ed4a 100644 (file)
@@ -25,6 +25,9 @@
 
 namespace contenttype_testable;
 
+use file_exception;
+use stored_file;
+
 /**
  * Testable content plugin class.
  *
@@ -33,4 +36,21 @@ namespace contenttype_testable;
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class content extends \core_contentbank\content {
+
+    /**
+     * Import a file as a valid content.
+     *
+     * This method will thow an error if the filename is "error.*"
+     *
+     * @param stored_file $file File to store in the content file area.
+     * @return stored_file|null the stored content file or null if the file is discarted.
+     * @throws file_exception if the filename contains the word "error"
+     */
+    public function import_file(stored_file $file): ?stored_file {
+        $filename = $file->get_filename();
+        if (strrpos($filename, 'error') !== false) {
+            throw new file_exception('yourerrorthanks', 'contenttype_test');
+        }
+        return parent::import_file($file);
+    }
 }
index c4626f0..00cc40c 100644 (file)
@@ -25,6 +25,8 @@
 require('../config.php');
 require_once("$CFG->dirroot/contentbank/files_form.php");
 
+use core\output\notification;
+
 require_login();
 
 $contextid = optional_param('contextid', \context_system::instance()->id, PARAM_INT);
@@ -68,6 +70,8 @@ file_prepare_standard_filemanager($data, 'files', $options, $context, 'contentba
 
 $mform = new contentbank_files_form(null, ['contextid' => $contextid, 'data' => $data, 'options' => $options]);
 
+$error = '';
+
 if ($mform->is_cancelled()) {
     redirect($returnurl);
 } else if ($formdata = $mform->get_data()) {
@@ -79,16 +83,20 @@ if ($mform->is_cancelled()) {
     if (!empty($files)) {
         $file = reset($files);
         $content = $cb->create_content_from_file($context, $USER->id, $file);
-        file_save_draft_area_files($formdata->file, $contextid, 'contentbank', 'public', $content->get_id());
         $viewurl = new \moodle_url('/contentbank/view.php', ['id' => $content->get_id(), 'contextid' => $contextid]);
         redirect($viewurl);
+    } else {
+        $error = get_string('errornofile', 'contentbank');
     }
-    redirect($returnurl);
 }
 
 echo $OUTPUT->header();
 echo $OUTPUT->box_start('generalbox');
 
+if (!empty($error)) {
+    echo $OUTPUT->notification($error, notification::NOTIFY_ERROR);
+}
+
 $mform->display();
 
 echo $OUTPUT->box_end();
index fe3e80b..5a896e7 100644 (file)
@@ -855,6 +855,13 @@ class core_course_external extends external_api {
             }
             require_capability('moodle/course:create', $context);
 
+            // Fullname and short name are required to be non-empty.
+            if (trim($course['fullname']) === '') {
+                throw new moodle_exception('errorinvalidparam', 'webservice', '', 'fullname');
+            } else if (trim($course['shortname']) === '') {
+                throw new moodle_exception('errorinvalidparam', 'webservice', '', 'shortname');
+            }
+
             // Make sure lang is valid
             if (array_key_exists('lang', $course)) {
                 if (empty($availablelangs[$course['lang']])) {
@@ -1040,14 +1047,20 @@ class core_course_external extends external_api {
                     $course['category'] = $course['categoryid'];
                 }
 
-                // Check if the user can change fullname.
+                // Check if the user can change fullname, and the new value is non-empty.
                 if (array_key_exists('fullname', $course) && ($oldcourse->fullname != $course['fullname'])) {
                     require_capability('moodle/course:changefullname', $context);
+                    if (trim($course['fullname']) === '') {
+                        throw new moodle_exception('errorinvalidparam', 'webservice', '', 'fullname');
+                    }
                 }
 
-                // Check if the user can change shortname.
+                // Check if the user can change shortname, and the new value is non-empty.
                 if (array_key_exists('shortname', $course) && ($oldcourse->shortname != $course['shortname'])) {
                     require_capability('moodle/course:changeshortname', $context);
+                    if (trim($course['shortname']) === '') {
+                        throw new moodle_exception('errorinvalidparam', 'webservice', '', 'shortname');
+                    }
                 }
 
                 // Check if the user can change the idnumber.
@@ -4368,15 +4381,10 @@ class core_course_external extends external_api {
         $coursecontext = context_course::instance($courseid);
         self::validate_context($coursecontext);
 
-        $pluginswithfunction = get_plugins_with_function('custom_chooser_footer', 'lib.php');
-        if ($pluginswithfunction) {
-            foreach ($pluginswithfunction as $plugintype => $plugins) {
-                foreach ($plugins as $pluginfunction) {
-                    $footerdata = $pluginfunction($courseid, $sectionid);
-                    break; // Only a single plugin can modify the footer.
-                }
-                break; // Only a single plugin can modify the footer.
-            }
+        $activeplugin = get_config('core', 'activitychooseractivefooter');
+
+        if ($activeplugin !== COURSE_CHOOSER_FOOTER_NONE) {
+            $footerdata = component_callback($activeplugin, 'custom_chooser_footer', [$courseid, $sectionid]);
             return [
                 'footer' => true,
                 'customfooterjs' => $footerdata->get_footer_js_file(),
index b3c9e95..e0b9eb3 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2020061500;              // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2020060900;              // Requires this Moodle version
+$plugin->version   = 2021052500;              // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2021052500;              // Requires this Moodle version