From cfa7d2653c49dadd3f05ed77191973db8fa78bce Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Mon, 13 May 2019 11:41:43 +0800 Subject: [PATCH 001/786] MDL-65572 messaging: Loginas upgrade check When using login as, we also need to check if there are legacy messages that need updating and set the user preference if required. --- lib/classes/session/manager.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/classes/session/manager.php b/lib/classes/session/manager.php index 6c0e171e50676..36083dd1deea6 100644 --- a/lib/classes/session/manager.php +++ b/lib/classes/session/manager.php @@ -933,6 +933,16 @@ public static function loginas($userid, \context $context, $generateevent = true if ($generateevent) { $event->trigger(); } + + // Queue migrating the messaging data, if we need to. + if (!get_user_preferences('core_message_migrate_data', false, $userid)) { + // Check if there are any legacy messages to migrate. + if (\core_message\helper::legacy_messages_exist($userid)) { + \core_message\task\migrate_message_data::queue_task($userid); + } else { + set_user_preference('core_message_migrate_data', true, $userid); + } + } } /** From a01edef5be3f21f4f3816c01725d20a04e5c4b64 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Wed, 15 May 2019 17:47:50 +1000 Subject: [PATCH 002/786] MDL-65605 mod_lesson: Fix the issue when get_draft_files returns null --- mod/lesson/import_form.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mod/lesson/import_form.php b/mod/lesson/import_form.php index b152c0abe242a..0ca0b1e5d68b5 100644 --- a/mod/lesson/import_form.php +++ b/mod/lesson/import_form.php @@ -59,6 +59,7 @@ public function definition() { * @param array $data the submitted data. * @param array $errors the errors so far. * @return array the updated errors. + * @throws moodle_exception */ protected function validate_uploaded_file($data, $errors) { global $CFG; @@ -69,7 +70,7 @@ protected function validate_uploaded_file($data, $errors) { } $files = $this->get_draft_files('questionfile'); - if (count($files) < 1) { + if (!is_array($files) || count($files) < 1) { $errors['questionfile'] = get_string('required'); return $errors; } From 159f904af579f66f205d2e45ab260d18209a4be4 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Wed, 15 May 2019 17:52:17 +1000 Subject: [PATCH 003/786] MDL-65605 core_question: Fix the issue when get_draft_files returns nul --- question/import_form.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/question/import_form.php b/question/import_form.php index ad2cc18feb6b4..f4693e4018414 100644 --- a/question/import_form.php +++ b/question/import_form.php @@ -112,6 +112,7 @@ protected function definition() { * @param array $data the submitted data. * @param array $errors the errors so far. * @return array the updated errors. + * @throws moodle_exception */ protected function validate_uploaded_file($data, $errors) { if (empty($data['newfile'])) { @@ -120,7 +121,7 @@ protected function validate_uploaded_file($data, $errors) { } $files = $this->get_draft_files('newfile'); - if (count($files) < 1) { + if (!is_array($files) || count($files) < 1) { $errors['newfile'] = get_string('required'); return $errors; } From 400239c7c5197c06ac18f2fac9bff6f502b21123 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Mon, 20 May 2019 15:30:01 +1000 Subject: [PATCH 004/786] MDL-65630 mod_quiz: Move logging in to the start of tests The background is for set up, the scenario is for the test. Logging in to start the test is the start of the test and the end of the background itself. --- mod/quiz/tests/behat/attempt_redo_questions.feature | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mod/quiz/tests/behat/attempt_redo_questions.feature b/mod/quiz/tests/behat/attempt_redo_questions.feature index 218976ad8673a..4499aaad4804c 100644 --- a/mod/quiz/tests/behat/attempt_redo_questions.feature +++ b/mod/quiz/tests/behat/attempt_redo_questions.feature @@ -30,11 +30,11 @@ Feature: Allow students to redo questions in a practice quiz, without starting a | question | page | maxmark | | TF1 | 1 | 2 | | TF2 | 1 | 1 | - And I log in as "student" - And I am on "Course 1" course homepage @javascript Scenario: After completing a question, there is a redo question button that restarts the question + Given I log in as "student" + And I am on "Course 1" course homepage When I follow "Quiz 1" And I press "Attempt quiz now" And I click on "False" "radio" in the "First question" "question" @@ -45,6 +45,8 @@ Feature: Allow students to redo questions in a practice quiz, without starting a @javascript Scenario: The redo question button is visible but disabled for teachers + Given I log in as "student" + And I am on "Course 1" course homepage When I follow "Quiz 1" And I press "Attempt quiz now" And I click on "False" "radio" in the "First question" "question" @@ -59,6 +61,8 @@ Feature: Allow students to redo questions in a practice quiz, without starting a @javascript Scenario: The redo question buttons are no longer visible after the attempt is submitted. + Given I log in as "student" + And I am on "Course 1" course homepage When I follow "Quiz 1" And I press "Attempt quiz now" And I click on "False" "radio" in the "First question" "question" @@ -70,6 +74,8 @@ Feature: Allow students to redo questions in a practice quiz, without starting a @javascript @_switch_window Scenario: Teachers reviewing can see all the qestions attempted in a slot + Given I log in as "student" + And I am on "Course 1" course homepage When I follow "Quiz 1" And I press "Attempt quiz now" And I click on "False" "radio" in the "First question" "question" @@ -100,6 +106,8 @@ Feature: Allow students to redo questions in a practice quiz, without starting a @javascript Scenario: Redoing question 1 should save any changes to question 2 on the same page + Given I log in as "student" + And I am on "Course 1" course homepage When I follow "Quiz 1" And I press "Attempt quiz now" And I click on "False" "radio" in the "First question" "question" From b52ceb29725b696a085a7d2880fbfd4910724a1e Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Mon, 20 May 2019 22:56:57 +1000 Subject: [PATCH 005/786] MDL-65630 mod_quiz: Allow redo within an attempt with random questions --- mod/quiz/attemptlib.php | 2 +- .../behat/attempt_redo_questions.feature | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mod/quiz/attemptlib.php b/mod/quiz/attemptlib.php index 1f6674a9a08a3..87d29437dada1 100644 --- a/mod/quiz/attemptlib.php +++ b/mod/quiz/attemptlib.php @@ -588,7 +588,7 @@ public function __construct($attempt, $quiz, $cm, $course, $loadquestions = true $this->quba = question_engine::load_questions_usage_by_activity($this->attempt->uniqueid); $this->slots = $DB->get_records('quiz_slots', array('quizid' => $this->get_quizid()), 'slot', - 'slot, requireprevious, questionid, includingsubcategories'); + 'slot, id, requireprevious, questionid, includingsubcategories'); $this->sections = array_values($DB->get_records('quiz_sections', array('quizid' => $this->get_quizid()), 'firstslot')); diff --git a/mod/quiz/tests/behat/attempt_redo_questions.feature b/mod/quiz/tests/behat/attempt_redo_questions.feature index 4499aaad4804c..fbadb44b45fb7 100644 --- a/mod/quiz/tests/behat/attempt_redo_questions.feature +++ b/mod/quiz/tests/behat/attempt_redo_questions.feature @@ -116,3 +116,23 @@ Feature: Allow students to redo questions in a practice quiz, without starting a And I press "Try another question like this one" And I click on "Check" "button" in the "Second question" "question" Then the state of "Second question" question is shown as "Correct" + + @javascript + Scenario: Redoing questions should work with random questions as well + Given the following "questions" exist: + | questioncategory | qtype | name | questiontext | + | Test questions | random | Random (Test questions) | 0 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | preferredbehaviour | canredoquestions | + | quiz | Quiz 2 | Quiz 2 description | C1 | quiz2 | immediatefeedback | 1 | + And quiz "Quiz 2" contains the following questions: + | question | page | + | Random (Test questions) | 1 | + And I log in as "student" + And I am on "Course 1" course homepage + When I follow "Quiz 2" + And I press "Attempt quiz now" + And I click on "False" "radio" + And I click on "Check" "button" + And I press "Try another question like this one" + Then "Check" "button" should exist From a137762fec515c9b2320823560fbf43966b07b8c Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Tue, 14 May 2019 17:00:25 +0200 Subject: [PATCH 006/786] MDL-65274 mod_quiz: Do not return a translated string We should be returning proper error codes and the translated string can be part of the debug information. --- mod/quiz/classes/external.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mod/quiz/classes/external.php b/mod/quiz/classes/external.php index 9c38f7e69bcca..cfdc4a89d33ef 100644 --- a/mod/quiz/classes/external.php +++ b/mod/quiz/classes/external.php @@ -1299,7 +1299,8 @@ protected static function validate_attempt_review($params) { if (!$attemptobj->is_finished()) { throw new moodle_quiz_exception($attemptobj->get_quizobj(), 'attemptclosed'); } else if (!$displayoptions->attempt) { - throw new moodle_exception($attemptobj->cannot_review_message()); + throw new moodle_quiz_exception($attemptobj->get_quizobj(), 'noreview', null, '', + $attemptobj->cannot_review_message()); } } else if (!$attemptobj->is_review_allowed()) { throw new moodle_quiz_exception($attemptobj->get_quizobj(), 'noreviewattempt'); From 171a83f79bc5c30cb4cf8274b2a17c7c0fcf1dd3 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Tue, 14 May 2019 14:40:26 +1000 Subject: [PATCH 007/786] MDL-65591 tool_customlang: Re-adding the save buttons at the bottom --- admin/tool/customlang/templates/translator.mustache | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/admin/tool/customlang/templates/translator.mustache b/admin/tool/customlang/templates/translator.mustache index 5092f68bab968..a7d441e6d0910 100644 --- a/admin/tool/customlang/templates/translator.mustache +++ b/admin/tool/customlang/templates/translator.mustache @@ -146,5 +146,14 @@ {{/strings}} + +
+ + +
{{/hasstrings}} From 1f2cde345a991aaa00df14bac021bd5e5be437f0 Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Mon, 20 May 2019 19:35:05 +0200 Subject: [PATCH 008/786] MDL-65644 upgrade: add 3.7.0 separation line to all upgrade scripts --- admin/tool/customlang/db/upgrade.php | 3 +++ admin/tool/dataprivacy/db/upgrade.php | 3 +++ admin/tool/log/db/upgrade.php | 3 +++ admin/tool/log/store/database/db/upgrade.php | 3 +++ admin/tool/log/store/standard/db/upgrade.php | 3 +++ admin/tool/mobile/db/upgrade.php | 3 +++ admin/tool/monitor/db/upgrade.php | 3 +++ admin/tool/policy/db/upgrade.php | 3 +++ admin/tool/usertours/db/upgrade.php | 3 +++ auth/cas/db/upgrade.php | 3 +++ auth/db/db/upgrade.php | 3 +++ auth/email/db/upgrade.php | 3 +++ auth/ldap/db/upgrade.php | 3 +++ auth/manual/db/upgrade.php | 3 +++ auth/mnet/db/upgrade.php | 3 +++ auth/none/db/upgrade.php | 3 +++ auth/oauth2/db/upgrade.php | 3 +++ auth/shibboleth/db/upgrade.php | 3 +++ blocks/badges/db/upgrade.php | 3 +++ blocks/calendar_month/db/upgrade.php | 3 +++ blocks/calendar_upcoming/db/upgrade.php | 3 +++ blocks/community/db/upgrade.php | 3 +++ blocks/completionstatus/db/upgrade.php | 3 +++ blocks/course_summary/db/upgrade.php | 3 +++ blocks/html/db/upgrade.php | 3 +++ blocks/navigation/db/upgrade.php | 3 +++ blocks/quiz_results/db/upgrade.php | 3 +++ blocks/recent_activity/db/upgrade.php | 3 +++ blocks/rss_client/db/upgrade.php | 3 +++ blocks/section_links/db/upgrade.php | 3 +++ blocks/selfcompletion/db/upgrade.php | 3 +++ blocks/settings/db/upgrade.php | 3 +++ course/format/topics/db/upgrade.php | 3 +++ course/format/weeks/db/upgrade.php | 3 +++ enrol/database/db/upgrade.php | 3 +++ enrol/flatfile/db/upgrade.php | 3 +++ enrol/guest/db/upgrade.php | 3 +++ enrol/imsenterprise/db/upgrade.php | 3 +++ enrol/lti/db/upgrade.php | 3 +++ enrol/manual/db/upgrade.php | 3 +++ enrol/mnet/db/upgrade.php | 3 +++ enrol/paypal/db/upgrade.php | 3 +++ enrol/self/db/upgrade.php | 3 +++ filter/mathjaxloader/db/upgrade.php | 3 +++ filter/mediaplugin/db/upgrade.php | 3 +++ filter/tex/db/upgrade.php | 3 +++ grade/grading/form/guide/db/upgrade.php | 3 +++ grade/grading/form/rubric/db/upgrade.php | 3 +++ grade/report/overview/db/upgrade.php | 3 +++ grade/report/user/db/upgrade.php | 3 +++ lib/antivirus/clamav/db/upgrade.php | 3 +++ lib/db/upgrade.php | 3 +++ lib/editor/atto/db/upgrade.php | 3 +++ lib/editor/atto/plugins/equation/db/upgrade.php | 3 +++ lib/editor/tinymce/db/upgrade.php | 3 +++ lib/editor/tinymce/plugins/spellchecker/db/upgrade.php | 3 +++ message/output/email/db/upgrade.php | 3 +++ message/output/jabber/db/upgrade.php | 3 +++ message/output/popup/db/upgrade.php | 3 +++ mod/assign/db/upgrade.php | 3 +++ mod/assign/feedback/comments/db/upgrade.php | 3 +++ mod/assign/feedback/editpdf/db/upgrade.php | 3 +++ mod/assign/feedback/file/db/upgrade.php | 3 +++ mod/assign/submission/comments/db/upgrade.php | 3 +++ mod/assign/submission/file/db/upgrade.php | 3 +++ mod/assign/submission/onlinetext/db/upgrade.php | 3 +++ mod/assignment/db/upgrade.php | 3 +++ mod/book/db/upgrade.php | 3 +++ mod/chat/db/upgrade.php | 3 +++ mod/choice/db/upgrade.php | 3 +++ mod/data/db/upgrade.php | 3 +++ mod/feedback/db/upgrade.php | 3 +++ mod/folder/db/upgrade.php | 3 +++ mod/forum/db/upgrade.php | 3 +++ mod/glossary/db/upgrade.php | 3 +++ mod/imscp/db/upgrade.php | 3 +++ mod/label/db/upgrade.php | 3 +++ mod/lesson/db/upgrade.php | 3 +++ mod/lti/db/upgrade.php | 3 +++ mod/page/db/upgrade.php | 3 +++ mod/quiz/db/upgrade.php | 3 +++ mod/quiz/report/overview/db/upgrade.php | 3 +++ mod/quiz/report/statistics/db/upgrade.php | 3 +++ mod/resource/db/upgrade.php | 3 +++ mod/scorm/db/upgrade.php | 3 +++ mod/survey/db/upgrade.php | 3 +++ mod/url/db/upgrade.php | 3 +++ mod/wiki/db/upgrade.php | 3 +++ mod/workshop/db/upgrade.php | 3 +++ mod/workshop/form/accumulative/db/upgrade.php | 3 +++ mod/workshop/form/comments/db/upgrade.php | 3 +++ mod/workshop/form/numerrors/db/upgrade.php | 3 +++ mod/workshop/form/rubric/db/upgrade.php | 3 +++ portfolio/boxnet/db/upgrade.php | 3 +++ portfolio/googledocs/db/upgrade.php | 3 +++ portfolio/picasa/db/upgrade.php | 3 +++ question/behaviour/manualgraded/db/upgrade.php | 3 +++ question/type/calculated/db/upgrade.php | 3 +++ question/type/ddmarker/db/upgrade.php | 3 +++ question/type/essay/db/upgrade.php | 3 +++ question/type/match/db/upgrade.php | 3 +++ question/type/multianswer/db/upgrade.php | 3 +++ question/type/multichoice/db/upgrade.php | 3 +++ question/type/numerical/db/upgrade.php | 3 +++ question/type/random/db/upgrade.php | 3 +++ question/type/randomsamatch/db/upgrade.php | 3 +++ question/type/shortanswer/db/upgrade.php | 3 +++ repository/boxnet/db/upgrade.php | 3 +++ repository/dropbox/db/upgrade.php | 3 +++ repository/flickr/db/upgrade.php | 3 +++ repository/googledocs/db/upgrade.php | 3 +++ repository/onedrive/db/upgrade.php | 3 +++ repository/picasa/db/upgrade.php | 3 +++ 113 files changed, 339 insertions(+) diff --git a/admin/tool/customlang/db/upgrade.php b/admin/tool/customlang/db/upgrade.php index 53fa80a2039d9..823c1e72a6a77 100644 --- a/admin/tool/customlang/db/upgrade.php +++ b/admin/tool/customlang/db/upgrade.php @@ -41,5 +41,8 @@ function xmldb_tool_customlang_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/admin/tool/dataprivacy/db/upgrade.php b/admin/tool/dataprivacy/db/upgrade.php index 47989cb8b106d..49cedd626f4d3 100644 --- a/admin/tool/dataprivacy/db/upgrade.php +++ b/admin/tool/dataprivacy/db/upgrade.php @@ -316,5 +316,8 @@ function xmldb_tool_dataprivacy_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/admin/tool/log/db/upgrade.php b/admin/tool/log/db/upgrade.php index bbf196143f9a0..b3de05d459bba 100644 --- a/admin/tool/log/db/upgrade.php +++ b/admin/tool/log/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_tool_log_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/admin/tool/log/store/database/db/upgrade.php b/admin/tool/log/store/database/db/upgrade.php index b5536abdda7e6..e17a51e1ea839 100644 --- a/admin/tool/log/store/database/db/upgrade.php +++ b/admin/tool/log/store/database/db/upgrade.php @@ -46,5 +46,8 @@ function xmldb_logstore_database_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2019032800, 'logstore', 'database'); } + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/admin/tool/log/store/standard/db/upgrade.php b/admin/tool/log/store/standard/db/upgrade.php index e1ac5a2ddc102..a341ac8eab900 100644 --- a/admin/tool/log/store/standard/db/upgrade.php +++ b/admin/tool/log/store/standard/db/upgrade.php @@ -46,5 +46,8 @@ function xmldb_logstore_standard_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2019032800, 'logstore', 'standard'); } + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/admin/tool/mobile/db/upgrade.php b/admin/tool/mobile/db/upgrade.php index 73748aa8d9ef4..6d5c5a79c41a7 100644 --- a/admin/tool/mobile/db/upgrade.php +++ b/admin/tool/mobile/db/upgrade.php @@ -42,5 +42,8 @@ function xmldb_tool_mobile_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2019021100, 'tool', 'mobile'); } + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/admin/tool/monitor/db/upgrade.php b/admin/tool/monitor/db/upgrade.php index f8579c9183ae0..139dec78dd186 100644 --- a/admin/tool/monitor/db/upgrade.php +++ b/admin/tool/monitor/db/upgrade.php @@ -62,5 +62,8 @@ function xmldb_tool_monitor_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/admin/tool/policy/db/upgrade.php b/admin/tool/policy/db/upgrade.php index cf1a33b3ed4b4..87e99655470ab 100644 --- a/admin/tool/policy/db/upgrade.php +++ b/admin/tool/policy/db/upgrade.php @@ -63,5 +63,8 @@ function xmldb_tool_policy_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/admin/tool/usertours/db/upgrade.php b/admin/tool/usertours/db/upgrade.php index 47e499422ffe4..523a453ceda0e 100644 --- a/admin/tool/usertours/db/upgrade.php +++ b/admin/tool/usertours/db/upgrade.php @@ -61,5 +61,8 @@ function xmldb_tool_usertours_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2019030600, 'tool', 'usertours'); } + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/auth/cas/db/upgrade.php b/auth/cas/db/upgrade.php index 4df297c456f49..3d05e54e1e9df 100644 --- a/auth/cas/db/upgrade.php +++ b/auth/cas/db/upgrade.php @@ -51,5 +51,8 @@ function xmldb_auth_cas_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/auth/db/db/upgrade.php b/auth/db/db/upgrade.php index f860220094323..ec2c80e2018b6 100644 --- a/auth/db/db/upgrade.php +++ b/auth/db/db/upgrade.php @@ -51,5 +51,8 @@ function xmldb_auth_db_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/auth/email/db/upgrade.php b/auth/email/db/upgrade.php index f636d6ff99fa2..d1b60496c3c4f 100644 --- a/auth/email/db/upgrade.php +++ b/auth/email/db/upgrade.php @@ -51,5 +51,8 @@ function xmldb_auth_email_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/auth/ldap/db/upgrade.php b/auth/ldap/db/upgrade.php index 6c5725574d824..cf73d4c2675a1 100644 --- a/auth/ldap/db/upgrade.php +++ b/auth/ldap/db/upgrade.php @@ -69,5 +69,8 @@ function xmldb_auth_ldap_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/auth/manual/db/upgrade.php b/auth/manual/db/upgrade.php index 9209e9dcffdab..9f18bc79d3b07 100644 --- a/auth/manual/db/upgrade.php +++ b/auth/manual/db/upgrade.php @@ -51,5 +51,8 @@ function xmldb_auth_manual_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/auth/mnet/db/upgrade.php b/auth/mnet/db/upgrade.php index be29bcd6c88dc..e8eb8499fdf02 100644 --- a/auth/mnet/db/upgrade.php +++ b/auth/mnet/db/upgrade.php @@ -51,5 +51,8 @@ function xmldb_auth_mnet_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/auth/none/db/upgrade.php b/auth/none/db/upgrade.php index 2d5fc97003034..a051a323b464c 100644 --- a/auth/none/db/upgrade.php +++ b/auth/none/db/upgrade.php @@ -51,5 +51,8 @@ function xmldb_auth_none_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/auth/oauth2/db/upgrade.php b/auth/oauth2/db/upgrade.php index 7582cc9ce9d83..599faa4abe1c1 100644 --- a/auth/oauth2/db/upgrade.php +++ b/auth/oauth2/db/upgrade.php @@ -47,5 +47,8 @@ function xmldb_auth_oauth2_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/auth/shibboleth/db/upgrade.php b/auth/shibboleth/db/upgrade.php index 640a02350ce06..d47ddad5f322a 100644 --- a/auth/shibboleth/db/upgrade.php +++ b/auth/shibboleth/db/upgrade.php @@ -51,5 +51,8 @@ function xmldb_auth_shibboleth_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/badges/db/upgrade.php b/blocks/badges/db/upgrade.php index 6948646ed2df0..f1f069a661488 100644 --- a/blocks/badges/db/upgrade.php +++ b/blocks/badges/db/upgrade.php @@ -57,5 +57,8 @@ function xmldb_block_badges_upgrade($oldversion, $block) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/calendar_month/db/upgrade.php b/blocks/calendar_month/db/upgrade.php index 32051277b3baf..58d654659b249 100644 --- a/blocks/calendar_month/db/upgrade.php +++ b/blocks/calendar_month/db/upgrade.php @@ -57,5 +57,8 @@ function xmldb_block_calendar_month_upgrade($oldversion, $block) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/calendar_upcoming/db/upgrade.php b/blocks/calendar_upcoming/db/upgrade.php index 14100c83782ef..69a5774fa02cc 100644 --- a/blocks/calendar_upcoming/db/upgrade.php +++ b/blocks/calendar_upcoming/db/upgrade.php @@ -57,5 +57,8 @@ function xmldb_block_calendar_upcoming_upgrade($oldversion, $block) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/community/db/upgrade.php b/blocks/community/db/upgrade.php index 0bdc51e15f01b..1a593de5c9af3 100644 --- a/blocks/community/db/upgrade.php +++ b/blocks/community/db/upgrade.php @@ -58,5 +58,8 @@ function xmldb_block_community_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/completionstatus/db/upgrade.php b/blocks/completionstatus/db/upgrade.php index 8a9ec8966cf84..6d78948074050 100644 --- a/blocks/completionstatus/db/upgrade.php +++ b/blocks/completionstatus/db/upgrade.php @@ -60,5 +60,8 @@ function xmldb_block_completionstatus_upgrade($oldversion, $block) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/course_summary/db/upgrade.php b/blocks/course_summary/db/upgrade.php index fb0cbaefb3138..f5732e5fce33c 100644 --- a/blocks/course_summary/db/upgrade.php +++ b/blocks/course_summary/db/upgrade.php @@ -60,5 +60,8 @@ function xmldb_block_course_summary_upgrade($oldversion, $block) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/html/db/upgrade.php b/blocks/html/db/upgrade.php index 4949b3f3a17b6..62d89a65971f6 100644 --- a/blocks/html/db/upgrade.php +++ b/blocks/html/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_block_html_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/navigation/db/upgrade.php b/blocks/navigation/db/upgrade.php index 97b106317ca71..1022e847e4c18 100644 --- a/blocks/navigation/db/upgrade.php +++ b/blocks/navigation/db/upgrade.php @@ -67,5 +67,8 @@ function xmldb_block_navigation_upgrade($oldversion, $block) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/quiz_results/db/upgrade.php b/blocks/quiz_results/db/upgrade.php index 60b035ecaebaa..055bb61561f52 100644 --- a/blocks/quiz_results/db/upgrade.php +++ b/blocks/quiz_results/db/upgrade.php @@ -57,5 +57,8 @@ function xmldb_block_quiz_results_upgrade($oldversion, $block) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/recent_activity/db/upgrade.php b/blocks/recent_activity/db/upgrade.php index 77e6f61c86165..1ad6e1aa1c982 100644 --- a/blocks/recent_activity/db/upgrade.php +++ b/blocks/recent_activity/db/upgrade.php @@ -59,5 +59,8 @@ function xmldb_block_recent_activity_upgrade($oldversion, $block) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/rss_client/db/upgrade.php b/blocks/rss_client/db/upgrade.php index 878f198c3f947..84dc47033e295 100644 --- a/blocks/rss_client/db/upgrade.php +++ b/blocks/rss_client/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_block_rss_client_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/section_links/db/upgrade.php b/blocks/section_links/db/upgrade.php index 0a8e2b0421b9c..41638f4753ba5 100644 --- a/blocks/section_links/db/upgrade.php +++ b/blocks/section_links/db/upgrade.php @@ -61,5 +61,8 @@ function xmldb_block_section_links_upgrade($oldversion, $block) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/selfcompletion/db/upgrade.php b/blocks/selfcompletion/db/upgrade.php index 9b8d87bddb055..92b3268f797c0 100644 --- a/blocks/selfcompletion/db/upgrade.php +++ b/blocks/selfcompletion/db/upgrade.php @@ -60,5 +60,8 @@ function xmldb_block_selfcompletion_upgrade($oldversion, $block) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/blocks/settings/db/upgrade.php b/blocks/settings/db/upgrade.php index 7b8618d76b6ad..f2b732712f1f6 100644 --- a/blocks/settings/db/upgrade.php +++ b/blocks/settings/db/upgrade.php @@ -67,5 +67,8 @@ function xmldb_block_settings_upgrade($oldversion, $block) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/course/format/topics/db/upgrade.php b/course/format/topics/db/upgrade.php index 055a902bca658..6dc38410cc8aa 100644 --- a/course/format/topics/db/upgrade.php +++ b/course/format/topics/db/upgrade.php @@ -65,5 +65,8 @@ function xmldb_format_topics_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/course/format/weeks/db/upgrade.php b/course/format/weeks/db/upgrade.php index bbb141f28c58d..0309ac8001418 100644 --- a/course/format/weeks/db/upgrade.php +++ b/course/format/weeks/db/upgrade.php @@ -101,5 +101,8 @@ function xmldb_format_weeks_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/enrol/database/db/upgrade.php b/enrol/database/db/upgrade.php index ca2733c53cb7c..9c288eb34e2b8 100644 --- a/enrol/database/db/upgrade.php +++ b/enrol/database/db/upgrade.php @@ -39,5 +39,8 @@ function xmldb_enrol_database_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/enrol/flatfile/db/upgrade.php b/enrol/flatfile/db/upgrade.php index c286910f29c8e..9e216f6fac30f 100644 --- a/enrol/flatfile/db/upgrade.php +++ b/enrol/flatfile/db/upgrade.php @@ -39,5 +39,8 @@ function xmldb_enrol_flatfile_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/enrol/guest/db/upgrade.php b/enrol/guest/db/upgrade.php index a4f9d25eb980b..81fa08cb9bca1 100644 --- a/enrol/guest/db/upgrade.php +++ b/enrol/guest/db/upgrade.php @@ -39,5 +39,8 @@ function xmldb_enrol_guest_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/enrol/imsenterprise/db/upgrade.php b/enrol/imsenterprise/db/upgrade.php index d89f2962cbad4..137602d74f4f5 100644 --- a/enrol/imsenterprise/db/upgrade.php +++ b/enrol/imsenterprise/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_enrol_imsenterprise_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/enrol/lti/db/upgrade.php b/enrol/lti/db/upgrade.php index 7b5736b44a54d..21c0943f74529 100644 --- a/enrol/lti/db/upgrade.php +++ b/enrol/lti/db/upgrade.php @@ -66,5 +66,8 @@ function xmldb_enrol_lti_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/enrol/manual/db/upgrade.php b/enrol/manual/db/upgrade.php index 48dfc6929bf63..0546271b635f0 100644 --- a/enrol/manual/db/upgrade.php +++ b/enrol/manual/db/upgrade.php @@ -39,5 +39,8 @@ function xmldb_enrol_manual_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/enrol/mnet/db/upgrade.php b/enrol/mnet/db/upgrade.php index f6d9efb4af0ac..62dd9bb04d31f 100644 --- a/enrol/mnet/db/upgrade.php +++ b/enrol/mnet/db/upgrade.php @@ -39,5 +39,8 @@ function xmldb_enrol_mnet_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/enrol/paypal/db/upgrade.php b/enrol/paypal/db/upgrade.php index 93ebd504d81f6..40b8abda19e28 100644 --- a/enrol/paypal/db/upgrade.php +++ b/enrol/paypal/db/upgrade.php @@ -138,5 +138,8 @@ function xmldb_enrol_paypal_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/enrol/self/db/upgrade.php b/enrol/self/db/upgrade.php index cb255e8bf6dd5..42046662970d4 100644 --- a/enrol/self/db/upgrade.php +++ b/enrol/self/db/upgrade.php @@ -39,5 +39,8 @@ function xmldb_enrol_self_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/filter/mathjaxloader/db/upgrade.php b/filter/mathjaxloader/db/upgrade.php index e4bb953f13d25..c93d3987a12d8 100644 --- a/filter/mathjaxloader/db/upgrade.php +++ b/filter/mathjaxloader/db/upgrade.php @@ -160,5 +160,8 @@ function xmldb_filter_mathjaxloader_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/filter/mediaplugin/db/upgrade.php b/filter/mediaplugin/db/upgrade.php index a8a43ac6634ef..b201df6afbcfb 100644 --- a/filter/mediaplugin/db/upgrade.php +++ b/filter/mediaplugin/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_filter_mediaplugin_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/filter/tex/db/upgrade.php b/filter/tex/db/upgrade.php index ec40486e27dda..dae22573abd56 100644 --- a/filter/tex/db/upgrade.php +++ b/filter/tex/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_filter_tex_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/grade/grading/form/guide/db/upgrade.php b/grade/grading/form/guide/db/upgrade.php index 290350d3cdd19..e9e73f4c461d5 100644 --- a/grade/grading/form/guide/db/upgrade.php +++ b/grade/grading/form/guide/db/upgrade.php @@ -49,5 +49,8 @@ function xmldb_gradingform_guide_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/grade/grading/form/rubric/db/upgrade.php b/grade/grading/form/rubric/db/upgrade.php index e7e0bdf5c63fe..7b47339e44b7e 100644 --- a/grade/grading/form/rubric/db/upgrade.php +++ b/grade/grading/form/rubric/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_gradingform_rubric_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/grade/report/overview/db/upgrade.php b/grade/report/overview/db/upgrade.php index 72726d8cf82c0..6efe5a2d4fd9b 100644 --- a/grade/report/overview/db/upgrade.php +++ b/grade/report/overview/db/upgrade.php @@ -54,5 +54,8 @@ function xmldb_gradereport_overview_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/grade/report/user/db/upgrade.php b/grade/report/user/db/upgrade.php index bc436ed2c3b9b..bca069486ab18 100644 --- a/grade/report/user/db/upgrade.php +++ b/grade/report/user/db/upgrade.php @@ -41,5 +41,8 @@ function xmldb_gradereport_user_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/lib/antivirus/clamav/db/upgrade.php b/lib/antivirus/clamav/db/upgrade.php index 493f0fd5dcac6..189c81a5d26b4 100644 --- a/lib/antivirus/clamav/db/upgrade.php +++ b/lib/antivirus/clamav/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_antivirus_clamav_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index c32bcfe994f12..f304bab761117 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -3375,5 +3375,8 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2019051300.01); } + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/lib/editor/atto/db/upgrade.php b/lib/editor/atto/db/upgrade.php index 2d91167ca5c63..7b1f233bd92ca 100644 --- a/lib/editor/atto/db/upgrade.php +++ b/lib/editor/atto/db/upgrade.php @@ -100,5 +100,8 @@ function xmldb_editor_atto_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/lib/editor/atto/plugins/equation/db/upgrade.php b/lib/editor/atto/plugins/equation/db/upgrade.php index e10c52f8f670a..732be3ef6d6ae 100644 --- a/lib/editor/atto/plugins/equation/db/upgrade.php +++ b/lib/editor/atto/plugins/equation/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_atto_equation_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/lib/editor/tinymce/db/upgrade.php b/lib/editor/tinymce/db/upgrade.php index 76c25ef4749f9..09e2a487747ce 100644 --- a/lib/editor/tinymce/db/upgrade.php +++ b/lib/editor/tinymce/db/upgrade.php @@ -39,5 +39,8 @@ function xmldb_editor_tinymce_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/lib/editor/tinymce/plugins/spellchecker/db/upgrade.php b/lib/editor/tinymce/plugins/spellchecker/db/upgrade.php index 5408bf68fb20e..25c8cbc4b4b36 100644 --- a/lib/editor/tinymce/plugins/spellchecker/db/upgrade.php +++ b/lib/editor/tinymce/plugins/spellchecker/db/upgrade.php @@ -39,5 +39,8 @@ function xmldb_tinymce_spellchecker_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/message/output/email/db/upgrade.php b/message/output/email/db/upgrade.php index b4fe03373fa23..2be294676f0ef 100644 --- a/message/output/email/db/upgrade.php +++ b/message/output/email/db/upgrade.php @@ -71,5 +71,8 @@ function xmldb_message_email_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2019032500, 'message', 'email'); } + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/message/output/jabber/db/upgrade.php b/message/output/jabber/db/upgrade.php index f27426cf4779d..85f174071b4ec 100644 --- a/message/output/jabber/db/upgrade.php +++ b/message/output/jabber/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_message_jabber_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/message/output/popup/db/upgrade.php b/message/output/popup/db/upgrade.php index 5c179e50bbc52..e659afbb1a22f 100644 --- a/message/output/popup/db/upgrade.php +++ b/message/output/popup/db/upgrade.php @@ -82,5 +82,8 @@ function xmldb_message_popup_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/assign/db/upgrade.php b/mod/assign/db/upgrade.php index 18a0391a7486a..254c12601d440 100644 --- a/mod/assign/db/upgrade.php +++ b/mod/assign/db/upgrade.php @@ -155,5 +155,8 @@ function xmldb_assign_upgrade($oldversion) { upgrade_mod_savepoint(true, 2018120500, 'assign'); } + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/assign/feedback/comments/db/upgrade.php b/mod/assign/feedback/comments/db/upgrade.php index ae87b98ad30f1..2ef8e87b427f9 100644 --- a/mod/assign/feedback/comments/db/upgrade.php +++ b/mod/assign/feedback/comments/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_assignfeedback_comments_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/assign/feedback/editpdf/db/upgrade.php b/mod/assign/feedback/editpdf/db/upgrade.php index ef219b66d8c88..0e0a90bfd3165 100644 --- a/mod/assign/feedback/editpdf/db/upgrade.php +++ b/mod/assign/feedback/editpdf/db/upgrade.php @@ -123,5 +123,8 @@ function xmldb_assignfeedback_editpdf_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2019010800, 'assignfeedback', 'editpdf'); } + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/assign/feedback/file/db/upgrade.php b/mod/assign/feedback/file/db/upgrade.php index 898839c128c8b..ee2291bf41b46 100644 --- a/mod/assign/feedback/file/db/upgrade.php +++ b/mod/assign/feedback/file/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_assignfeedback_file_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/assign/submission/comments/db/upgrade.php b/mod/assign/submission/comments/db/upgrade.php index 3c41dfe59f321..c134833cdc8f9 100644 --- a/mod/assign/submission/comments/db/upgrade.php +++ b/mod/assign/submission/comments/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_assignsubmission_comments_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/assign/submission/file/db/upgrade.php b/mod/assign/submission/file/db/upgrade.php index 2f6c544ab256e..ec51258080467 100644 --- a/mod/assign/submission/file/db/upgrade.php +++ b/mod/assign/submission/file/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_assignsubmission_file_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/assign/submission/onlinetext/db/upgrade.php b/mod/assign/submission/onlinetext/db/upgrade.php index 2b04adaee19bd..8c45377c0c9bb 100644 --- a/mod/assign/submission/onlinetext/db/upgrade.php +++ b/mod/assign/submission/onlinetext/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_assignsubmission_onlinetext_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/assignment/db/upgrade.php b/mod/assignment/db/upgrade.php index a6187c6f52d6f..a95733d9bd365 100644 --- a/mod/assignment/db/upgrade.php +++ b/mod/assignment/db/upgrade.php @@ -36,5 +36,8 @@ function xmldb_assignment_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/book/db/upgrade.php b/mod/book/db/upgrade.php index eeac64fbd9934..5a08ad22e072b 100644 --- a/mod/book/db/upgrade.php +++ b/mod/book/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_book_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/chat/db/upgrade.php b/mod/chat/db/upgrade.php index 5351271133c95..a98d1b789777e 100644 --- a/mod/chat/db/upgrade.php +++ b/mod/chat/db/upgrade.php @@ -68,5 +68,8 @@ function xmldb_chat_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/choice/db/upgrade.php b/mod/choice/db/upgrade.php index 31f2963797031..84abf36993750 100644 --- a/mod/choice/db/upgrade.php +++ b/mod/choice/db/upgrade.php @@ -36,5 +36,8 @@ function xmldb_choice_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/data/db/upgrade.php b/mod/data/db/upgrade.php index 96d2f3592400e..0ecbeff5166a6 100644 --- a/mod/data/db/upgrade.php +++ b/mod/data/db/upgrade.php @@ -53,5 +53,8 @@ function xmldb_data_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/feedback/db/upgrade.php b/mod/feedback/db/upgrade.php index 603521d8d6db3..0ec677a4c7f44 100644 --- a/mod/feedback/db/upgrade.php +++ b/mod/feedback/db/upgrade.php @@ -81,5 +81,8 @@ function xmldb_feedback_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/folder/db/upgrade.php b/mod/folder/db/upgrade.php index d106c21a88826..27c9f55523601 100644 --- a/mod/folder/db/upgrade.php +++ b/mod/folder/db/upgrade.php @@ -61,5 +61,8 @@ function xmldb_folder_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/forum/db/upgrade.php b/mod/forum/db/upgrade.php index 7addc739bc454..918ec72d6fa67 100644 --- a/mod/forum/db/upgrade.php +++ b/mod/forum/db/upgrade.php @@ -154,5 +154,8 @@ function xmldb_forum_upgrade($oldversion) { upgrade_mod_savepoint(true, 2019040402, 'forum'); } + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/glossary/db/upgrade.php b/mod/glossary/db/upgrade.php index 748a79aac22bd..b1a22ede78d42 100644 --- a/mod/glossary/db/upgrade.php +++ b/mod/glossary/db/upgrade.php @@ -100,5 +100,8 @@ function xmldb_glossary_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/imscp/db/upgrade.php b/mod/imscp/db/upgrade.php index ac32ec4dc80c1..c897c086f7ed4 100644 --- a/mod/imscp/db/upgrade.php +++ b/mod/imscp/db/upgrade.php @@ -43,5 +43,8 @@ function xmldb_imscp_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/label/db/upgrade.php b/mod/label/db/upgrade.php index 7212edc246f30..a6f9dc10bbe2d 100644 --- a/mod/label/db/upgrade.php +++ b/mod/label/db/upgrade.php @@ -70,5 +70,8 @@ function xmldb_label_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/lesson/db/upgrade.php b/mod/lesson/db/upgrade.php index a3b5ce356368a..3d24f043189c6 100644 --- a/mod/lesson/db/upgrade.php +++ b/mod/lesson/db/upgrade.php @@ -110,5 +110,8 @@ function xmldb_lesson_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/lti/db/upgrade.php b/mod/lti/db/upgrade.php index 4d313e590d197..e605f01f37f57 100644 --- a/mod/lti/db/upgrade.php +++ b/mod/lti/db/upgrade.php @@ -218,5 +218,8 @@ function xmldb_lti_upgrade($oldversion) { upgrade_mod_savepoint(true, 2019031302, 'lti'); } + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/page/db/upgrade.php b/mod/page/db/upgrade.php index a284b2ed6bcfe..6e12641b2a405 100644 --- a/mod/page/db/upgrade.php +++ b/mod/page/db/upgrade.php @@ -59,5 +59,8 @@ function xmldb_page_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/quiz/db/upgrade.php b/mod/quiz/db/upgrade.php index fea86fb4e916f..7c0a4260e7f60 100644 --- a/mod/quiz/db/upgrade.php +++ b/mod/quiz/db/upgrade.php @@ -147,5 +147,8 @@ function xmldb_quiz_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/quiz/report/overview/db/upgrade.php b/mod/quiz/report/overview/db/upgrade.php index 13ca01a3ad4b1..8979e3ffe32fa 100644 --- a/mod/quiz/report/overview/db/upgrade.php +++ b/mod/quiz/report/overview/db/upgrade.php @@ -79,5 +79,8 @@ function xmldb_quiz_overview_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/quiz/report/statistics/db/upgrade.php b/mod/quiz/report/statistics/db/upgrade.php index a4c0d3fa2e824..264ff74ad1406 100644 --- a/mod/quiz/report/statistics/db/upgrade.php +++ b/mod/quiz/report/statistics/db/upgrade.php @@ -42,5 +42,8 @@ function xmldb_quiz_statistics_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/resource/db/upgrade.php b/mod/resource/db/upgrade.php index 85b16c1ee7423..fc005c7de60c6 100644 --- a/mod/resource/db/upgrade.php +++ b/mod/resource/db/upgrade.php @@ -59,5 +59,8 @@ function xmldb_resource_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/scorm/db/upgrade.php b/mod/scorm/db/upgrade.php index 5d2380ff5c331..f1e661e07bc0b 100644 --- a/mod/scorm/db/upgrade.php +++ b/mod/scorm/db/upgrade.php @@ -79,5 +79,8 @@ function xmldb_scorm_upgrade($oldversion) { upgrade_mod_savepoint(true, 2018123100, 'scorm'); } + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/survey/db/upgrade.php b/mod/survey/db/upgrade.php index 4a008999f4a28..33a81e6f8ad9d 100644 --- a/mod/survey/db/upgrade.php +++ b/mod/survey/db/upgrade.php @@ -36,5 +36,8 @@ function xmldb_survey_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/url/db/upgrade.php b/mod/url/db/upgrade.php index 3065e640010c3..5543f205aba5d 100644 --- a/mod/url/db/upgrade.php +++ b/mod/url/db/upgrade.php @@ -59,5 +59,8 @@ function xmldb_url_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/wiki/db/upgrade.php b/mod/wiki/db/upgrade.php index 5b179a96d3ff0..ad21e702fd847 100644 --- a/mod/wiki/db/upgrade.php +++ b/mod/wiki/db/upgrade.php @@ -52,5 +52,8 @@ function xmldb_wiki_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/workshop/db/upgrade.php b/mod/workshop/db/upgrade.php index 9acd30f4053b2..fe16f0faeb4bb 100644 --- a/mod/workshop/db/upgrade.php +++ b/mod/workshop/db/upgrade.php @@ -109,5 +109,8 @@ function xmldb_workshop_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/workshop/form/accumulative/db/upgrade.php b/mod/workshop/form/accumulative/db/upgrade.php index c5cb7bb941390..c2f52d5c774c5 100644 --- a/mod/workshop/form/accumulative/db/upgrade.php +++ b/mod/workshop/form/accumulative/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_workshopform_accumulative_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/workshop/form/comments/db/upgrade.php b/mod/workshop/form/comments/db/upgrade.php index 79b166b2f09fb..eacb0e9c9a806 100644 --- a/mod/workshop/form/comments/db/upgrade.php +++ b/mod/workshop/form/comments/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_workshopform_comments_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/workshop/form/numerrors/db/upgrade.php b/mod/workshop/form/numerrors/db/upgrade.php index 9d53ee94518e4..5eade3ab416dd 100644 --- a/mod/workshop/form/numerrors/db/upgrade.php +++ b/mod/workshop/form/numerrors/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_workshopform_numerrors_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/mod/workshop/form/rubric/db/upgrade.php b/mod/workshop/form/rubric/db/upgrade.php index d40d5e58e5075..0984cb7caad57 100644 --- a/mod/workshop/form/rubric/db/upgrade.php +++ b/mod/workshop/form/rubric/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_workshopform_rubric_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/portfolio/boxnet/db/upgrade.php b/portfolio/boxnet/db/upgrade.php index 0d8fc59152d5d..1cde289354f7d 100644 --- a/portfolio/boxnet/db/upgrade.php +++ b/portfolio/boxnet/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_portfolio_boxnet_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/portfolio/googledocs/db/upgrade.php b/portfolio/googledocs/db/upgrade.php index 2f957c1f58e9f..0a9e08be3d891 100644 --- a/portfolio/googledocs/db/upgrade.php +++ b/portfolio/googledocs/db/upgrade.php @@ -35,5 +35,8 @@ function xmldb_portfolio_googledocs_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/portfolio/picasa/db/upgrade.php b/portfolio/picasa/db/upgrade.php index f745e0f4bf0d8..f006680cc5e72 100644 --- a/portfolio/picasa/db/upgrade.php +++ b/portfolio/picasa/db/upgrade.php @@ -35,5 +35,8 @@ function xmldb_portfolio_picasa_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/question/behaviour/manualgraded/db/upgrade.php b/question/behaviour/manualgraded/db/upgrade.php index 45f5cd010851f..5b49339e80e4b 100644 --- a/question/behaviour/manualgraded/db/upgrade.php +++ b/question/behaviour/manualgraded/db/upgrade.php @@ -42,5 +42,8 @@ function xmldb_qbehaviour_manualgraded_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/question/type/calculated/db/upgrade.php b/question/type/calculated/db/upgrade.php index a639b0045d93c..6769936f5735d 100644 --- a/question/type/calculated/db/upgrade.php +++ b/question/type/calculated/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_qtype_calculated_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/question/type/ddmarker/db/upgrade.php b/question/type/ddmarker/db/upgrade.php index 160f0f2f7843a..8dbd5180e4c41 100644 --- a/question/type/ddmarker/db/upgrade.php +++ b/question/type/ddmarker/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_qtype_ddmarker_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/question/type/essay/db/upgrade.php b/question/type/essay/db/upgrade.php index 93acbb48e3177..46e30cfe578d4 100644 --- a/question/type/essay/db/upgrade.php +++ b/question/type/essay/db/upgrade.php @@ -61,5 +61,8 @@ function xmldb_qtype_essay_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/question/type/match/db/upgrade.php b/question/type/match/db/upgrade.php index 1dd18fc90bf3c..bf8d92411dc19 100644 --- a/question/type/match/db/upgrade.php +++ b/question/type/match/db/upgrade.php @@ -43,5 +43,8 @@ function xmldb_qtype_match_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/question/type/multianswer/db/upgrade.php b/question/type/multianswer/db/upgrade.php index e0bd450329f7f..f107175f6b1c5 100644 --- a/question/type/multianswer/db/upgrade.php +++ b/question/type/multianswer/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_qtype_multianswer_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/question/type/multichoice/db/upgrade.php b/question/type/multichoice/db/upgrade.php index b2dc15b9e3a7b..e182cae3c1e82 100644 --- a/question/type/multichoice/db/upgrade.php +++ b/question/type/multichoice/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_qtype_multichoice_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/question/type/numerical/db/upgrade.php b/question/type/numerical/db/upgrade.php index e303c1df9682a..8aef850c38c41 100644 --- a/question/type/numerical/db/upgrade.php +++ b/question/type/numerical/db/upgrade.php @@ -58,5 +58,8 @@ function xmldb_qtype_numerical_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/question/type/random/db/upgrade.php b/question/type/random/db/upgrade.php index cb50b671aece4..95ee4c4e43ec4 100644 --- a/question/type/random/db/upgrade.php +++ b/question/type/random/db/upgrade.php @@ -43,5 +43,8 @@ function xmldb_qtype_random_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/question/type/randomsamatch/db/upgrade.php b/question/type/randomsamatch/db/upgrade.php index c8471b4ba3047..d98bf53129c9e 100644 --- a/question/type/randomsamatch/db/upgrade.php +++ b/question/type/randomsamatch/db/upgrade.php @@ -43,5 +43,8 @@ function xmldb_qtype_randomsamatch_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/question/type/shortanswer/db/upgrade.php b/question/type/shortanswer/db/upgrade.php index 63031fe218d6d..8b8c2743f72fa 100644 --- a/question/type/shortanswer/db/upgrade.php +++ b/question/type/shortanswer/db/upgrade.php @@ -44,5 +44,8 @@ function xmldb_qtype_shortanswer_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/repository/boxnet/db/upgrade.php b/repository/boxnet/db/upgrade.php index 41d21266c1b6c..baafa6d9aaa9b 100644 --- a/repository/boxnet/db/upgrade.php +++ b/repository/boxnet/db/upgrade.php @@ -45,5 +45,8 @@ function xmldb_repository_boxnet_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/repository/dropbox/db/upgrade.php b/repository/dropbox/db/upgrade.php index 73aaf9406b63f..6207d499b344a 100644 --- a/repository/dropbox/db/upgrade.php +++ b/repository/dropbox/db/upgrade.php @@ -35,5 +35,8 @@ function xmldb_repository_dropbox_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/repository/flickr/db/upgrade.php b/repository/flickr/db/upgrade.php index 4698713b66a69..ef2d1f4f12e4f 100644 --- a/repository/flickr/db/upgrade.php +++ b/repository/flickr/db/upgrade.php @@ -53,5 +53,8 @@ function xmldb_repository_flickr_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/repository/googledocs/db/upgrade.php b/repository/googledocs/db/upgrade.php index 3266380f01619..1ca4dd0c437d7 100644 --- a/repository/googledocs/db/upgrade.php +++ b/repository/googledocs/db/upgrade.php @@ -67,5 +67,8 @@ function xmldb_repository_googledocs_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/repository/onedrive/db/upgrade.php b/repository/onedrive/db/upgrade.php index c27f339400fc2..b58098c5f1315 100644 --- a/repository/onedrive/db/upgrade.php +++ b/repository/onedrive/db/upgrade.php @@ -40,5 +40,8 @@ function xmldb_repository_onedrive_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } diff --git a/repository/picasa/db/upgrade.php b/repository/picasa/db/upgrade.php index 3ec6125321449..5ac7ef1d70116 100644 --- a/repository/picasa/db/upgrade.php +++ b/repository/picasa/db/upgrade.php @@ -35,5 +35,8 @@ function xmldb_repository_picasa_upgrade($oldversion) { // Automatically generated Moodle v3.6.0 release upgrade line. // Put any upgrade step following this. + // Automatically generated Moodle v3.7.0 release upgrade line. + // Put any upgrade step following this. + return true; } From c48f2c90ccb7bc4e5e8432642a61376cb28ec9bd Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Mon, 20 May 2019 23:12:58 +0200 Subject: [PATCH 009/786] MDL-64530 travis: Enabble PHP 7.3 and redis cache This commit performs a number of changes: - Enables PHP 7.3, replacing PHP 7.2 (max/min approach). - Enables back the redis service - Configures redis cache store tests to be run. - Disables redis session tests for PHP 7.2 and up (MDL-60978) --- .travis.yml | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 229c46cf80d0b..4f4e263977fe5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ language: php php: # We only run the highest and lowest supported versions to reduce the load on travis-ci.org. - - 7.2 + - 7.3 - 7.1 addons: @@ -23,10 +23,6 @@ addons: - mysql-client-core-5.6 - mysql-client-5.6 -# Redis tests are currently failing on php 7.2 due to https://bugs.php.net/bug.php?id=75628 -# services: -# - redis-server - env: # Although we want to run these jobs and see failures as quickly as possible, we also want to get the slowest job to # start first so that the total run time is not too high. @@ -35,9 +31,6 @@ env: # CI Tests should be second-highest in priority as these only take <= 60 seconds to run under normal circumstances. # Postgres is significantly is pretty reasonable in its run-time. - # Run unit tests on MySQL - - DB=mysqli TASK=PHPUNIT - # Run CI Tests without running PHPUnit. - DB=none TASK=CITEST @@ -54,22 +47,22 @@ matrix: fast_finish: true include: + # Run mysql only on 7.3 - it's just too slow + - php: 7.3 + env: DB=mysqli TASK=PHPUNIT # Run grunt/npm install on highest version ('node' is an alias for the latest node.js version.) - php: 7.2 env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon' - exclude: - # MySQL - it's just too slow. - # Exclude it on all versions except for 7.2 - - - env: DB=mysqli TASK=PHPUNIT - php: 7.1 - cache: directories: - $HOME/.composer/cache - $HOME/.npm +before_install: + # Avoid IPv6 default binding as service (causes redis not to start). + sudo service redis-server start --bind 127.0.0.1 + install: - > if [ "$DB" = 'mysqli' ]; @@ -99,10 +92,8 @@ install: echo 'auth.json' >> .git/info/exclude fi - # Enable Redis. - # Redis tests are currently failing on php 7.2 due to https://bugs.php.net/bug.php?id=75628 - # echo 'extension="redis.so"' > /tmp/redis.ini - # phpenv config-add /tmp/redis.ini + echo 'extension="redis.so"' > /tmp/redis.ini + phpenv config-add /tmp/redis.ini # Install composer dependencies. # We need --no-interaction in case we hit API limits for composer. This causes it to fall back to a standard clone. @@ -173,12 +164,19 @@ before_script: mkdir -p "$HOME"/roots/phpunit # The phpunit dataroot and prefix.. - # Redis tests are currently failing on php 7.2 due to https://bugs.php.net/bug.php?id=75628 - # -e "/require_once/i \\define('TEST_SESSION_REDIS_HOST', '127.0.0.1');" \ sed -i \ -e "/require_once/i \\\$CFG->phpunit_dataroot = '\/home\/travis\/roots\/phpunit';" \ -e "/require_once/i \\\$CFG->phpunit_prefix = 'p_';" \ config.php ; + # Redis cache store tests + sed -i \ + -e "/require_once/i \\define('TEST_CACHESTORE_REDIS_TESTSERVERS', '127.0.0.1');" \ + config.php ; + # Redis session tests, but not for PHP 7.2 and up. See MDL-60978 for more info. + redissession="if (version_compare(PHP_VERSION, '7.2.0', '<')) { define('TEST_SESSION_REDIS_HOST', '127.0.0.1'); }" + sed -i \ + -e "/require_once/i \\${redissession}" \ + config.php ; # Initialise PHPUnit for Moodle. php admin/tool/phpunit/cli/init.php From d16540aa8831f30e2a6412c666397029e71a88f7 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Tue, 14 May 2019 16:18:10 +1000 Subject: [PATCH 010/786] MDL-65590 tool_customlang: Escape html on the standard text field --- admin/tool/customlang/templates/translator.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/tool/customlang/templates/translator.mustache b/admin/tool/customlang/templates/translator.mustache index 5092f68bab968..5e2c77e5f8c3f 100644 --- a/admin/tool/customlang/templates/translator.mustache +++ b/admin/tool/customlang/templates/translator.mustache @@ -113,7 +113,7 @@
{{#str}}headingstandard, tool_customlang{{/str}}
- {{{ master }}} + {{ master }}
{{{ placeholderhelp }}} {{{ outdatedhelp}}} From 0864ebc14c5c63bc34125a9aa4e7843ddeba9ba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20D=C3=A9niz=20Falc=C3=B3n?= Date: Tue, 14 May 2019 01:06:00 +0100 Subject: [PATCH 011/786] MDL-60407 report_insights: Fix redirect when action on last prediction When an actions is taken on the last prediction, the predictions list page is reloaded. --- analytics/classes/local/target/base.php | 4 +++- report/insights/amd/build/actions.min.js | 2 +- report/insights/amd/src/actions.js | 18 +++++++++++------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/analytics/classes/local/target/base.php b/analytics/classes/local/target/base.php index 0ea5e8b8e29c5..3a5d9f291a956 100644 --- a/analytics/classes/local/target/base.php +++ b/analytics/classes/local/target/base.php @@ -130,8 +130,10 @@ public function prediction_actions(\core_analytics\prediction $prediction, $incl global $PAGE; $predictionid = $prediction->get_prediction_data()->id; + $contextid = $prediction->get_prediction_data()->contextid; + $modelid = $prediction->get_prediction_data()->modelid; - $PAGE->requires->js_call_amd('report_insights/actions', 'init', array($predictionid)); + $PAGE->requires->js_call_amd('report_insights/actions', 'init', array($predictionid, $contextid, $modelid)); $actions = array(); diff --git a/report/insights/amd/build/actions.min.js b/report/insights/amd/build/actions.min.js index 71cc939b182af..98e554bd4684c 100644 --- a/report/insights/amd/build/actions.min.js +++ b/report/insights/amd/build/actions.min.js @@ -1 +1 @@ -define(["jquery","core/ajax","core/notification"],function(a,b,c){return{init:function(d){a("a[data-prediction-methodname][data-prediction-id="+d+"]").on("click",function(e){e.preventDefault();var f=a(e.currentTarget),g=f.attr("data-prediction-methodname"),h=f.closest("tr");if(h.length>0){var i=b.call([{methodname:g,args:{predictionid:d}}])[0];i.done(function(){h[0].remove(),a(".insights-list tr").length<2&&(document.referrer?window.location.assign(document.referrer):window.location.reload(!0))}).fail(c.exception)}})}}}); \ No newline at end of file +define(["jquery","core/ajax","core/notification","core/url"],function(a,b,c,d){return{init:function(e,f,g){a("a[data-prediction-methodname][data-prediction-id="+e+"]").on("click",function(h){h.preventDefault();var i=a(h.currentTarget),j=i.attr("data-prediction-methodname"),k=i.closest("tr");if(k.length>0){var l=b.call([{methodname:j,args:{predictionid:e}}])[0];l.done(function(){if(k[0].remove(),a(".insights-list tr").length<2){var b={contextid:f,modelid:g},c=a.param(b);window.location.assign(d.relativeUrl("report/insights/insights.php?"+c))}}).fail(c.exception)}})}}}); \ No newline at end of file diff --git a/report/insights/amd/src/actions.js b/report/insights/amd/src/actions.js index 3c98868fc90d3..833d32d0e16ff 100644 --- a/report/insights/amd/src/actions.js +++ b/report/insights/amd/src/actions.js @@ -26,7 +26,7 @@ * * @module report_insights/actions */ -define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notification) { +define(['jquery', 'core/ajax', 'core/notification', 'core/url'], function($, Ajax, Notification, Url) { return { @@ -34,9 +34,11 @@ define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notificat * Attach on click handlers to hide predictions. * * @param {Number} predictionId The prediction id. + * @param {Number} contextId The context in which the prediction was made. + * @param {Number} modelId The model id model with which the prediction was made. * @access public */ - init: function(predictionId) { + init: function(predictionId, contextId, modelId) { // Select the prediction with the provided id ensuring that an external function is set as method name. $('a[data-prediction-methodname][data-prediction-id=' + predictionId + ']').on('click', function(e) { @@ -57,11 +59,13 @@ define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notificat // Move back if no remaining predictions. if ($('.insights-list tr').length < 2) { - if (document.referrer) { - window.location.assign(document.referrer); - } else { - window.location.reload(true); - } + var params = { + contextid: contextId, + modelid: modelId + }; + + var queryparams = $.param(params); + window.location.assign(Url.relativeUrl("report/insights/insights.php?" + queryparams)); } }).fail(Notification.exception); } From 21527bf0968d7aa8722dcf156dc21aa255f2b342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Monlla=C3=B3?= Date: Fri, 17 May 2019 12:23:12 +0200 Subject: [PATCH 012/786] MDL-65634 analytics: Discard late and early student enrolments --- .../analytics/target/course_competencies.php | 5 ++ .../analytics/target/course_completion.php | 4 ++ .../analytics/target/course_dropout.php | 5 ++ .../analytics/target/course_enrolments.php | 44 ++++++++++++++++-- .../analytics/target/course_gradetopass.php | 5 ++ lib/tests/targets_test.php | 46 ++++++++++++++++--- 6 files changed, 99 insertions(+), 10 deletions(-) diff --git a/course/classes/analytics/target/course_competencies.php b/course/classes/analytics/target/course_competencies.php index 0aea6268db6bb..046013b54bf57 100644 --- a/course/classes/analytics/target/course_competencies.php +++ b/course/classes/analytics/target/course_competencies.php @@ -118,6 +118,11 @@ public function is_valid_analysable(\core_analytics\analysable $course, $fortrai */ protected function calculate_sample($sampleid, \core_analytics\analysable $course, $starttime = false, $endtime = false) { + if ($this->enrolment_starts_after_calculation_start($sampleid, $starttime)) { + // Discard user enrolments whose start date is after $starttime. + return null; + } + $userenrol = $this->retrieve('user_enrolments', $sampleid); $key = $course->get_id(); diff --git a/course/classes/analytics/target/course_completion.php b/course/classes/analytics/target/course_completion.php index 9c187ca76b7d7..75f0d82c1c377 100644 --- a/course/classes/analytics/target/course_completion.php +++ b/course/classes/analytics/target/course_completion.php @@ -96,6 +96,10 @@ public function is_valid_analysable(\core_analytics\analysable $course, $fortrai */ protected function calculate_sample($sampleid, \core_analytics\analysable $course, $starttime = false, $endtime = false) { + if ($this->enrolment_starts_after_calculation_start($sampleid, $starttime)) { + // Discard user enrolments whose start date is after $starttime. + return null; + } $userenrol = $this->retrieve('user_enrolments', $sampleid); // We use completion as a success metric. diff --git a/course/classes/analytics/target/course_dropout.php b/course/classes/analytics/target/course_dropout.php index 694b05810793c..4cb43c7a82acb 100644 --- a/course/classes/analytics/target/course_dropout.php +++ b/course/classes/analytics/target/course_dropout.php @@ -118,6 +118,11 @@ public function is_valid_analysable(\core_analytics\analysable $course, $fortrai */ protected function calculate_sample($sampleid, \core_analytics\analysable $course, $starttime = false, $endtime = false) { + if ($this->enrolment_starts_after_calculation_start($sampleid, $starttime)) { + // Discard user enrolments whose start date is after $starttime. + return null; + } + $userenrol = $this->retrieve('user_enrolments', $sampleid); // We use completion as a success metric only when it is enabled. diff --git a/course/classes/analytics/target/course_enrolments.php b/course/classes/analytics/target/course_enrolments.php index e97112a4172bc..e3384132438d3 100644 --- a/course/classes/analytics/target/course_enrolments.php +++ b/course/classes/analytics/target/course_enrolments.php @@ -122,6 +122,8 @@ public function is_valid_analysable(\core_analytics\analysable $course, $fortrai */ public function is_valid_sample($sampleid, \core_analytics\analysable $course, $fortraining = true) { + $now = time(); + $userenrol = $this->retrieve('user_enrolments', $sampleid); if ($userenrol->timeend && $course->get_start() > $userenrol->timeend) { // Discard enrolments which time end is prior to the course start. This should get rid of @@ -139,9 +141,22 @@ public function is_valid_sample($sampleid, \core_analytics\analysable $course, $ return false; } - if (($userenrol->timestart && $userenrol->timestart > $course->get_end()) || - (!$userenrol->timestart && $userenrol->timecreated > $course->get_end())) { - // Discard user enrolments that starts after the analysable official end. + if ($course->get_end()) { + if (($userenrol->timestart && $userenrol->timestart > $course->get_end()) || + (!$userenrol->timestart && $userenrol->timecreated > $course->get_end())) { + // Discard user enrolments that starts after the analysable official end. + return false; + } + + } + + if ($now < $userenrol->timestart && $userenrol->timestart) { + // Discard enrolments whose start date is after now (no need to check timecreated > $now :P). + return false; + } + + if (!$fortraining && $userenrol->timeend && $userenrol->timeend < $now) { + // We don't want to generate predictions for finished enrolments. return false; } @@ -182,4 +197,27 @@ public function prediction_actions(\core_analytics\prediction $prediction, $incl return array_merge($actions, parent::prediction_actions($prediction, $includedetailsaction)); } + + /** + * Does the user enrolment created after this time range start time or starts after it? + * + * We need to identify these enrolments because the indicators can not be calculated properly + * if the student enrolment started half way through this time range. + * + * User enrolments whose end date is before time() have already been discarded in + * course_enrolments::is_valid_sample. + * + * @param int $sampleid + * @param int $starttime + * @return bool + */ + protected function enrolment_starts_after_calculation_start(int $sampleid, int $starttime) { + + $userenrol = $this->retrieve('user_enrolments', $sampleid); + if ($userenrol->timestart && $userenrol->timestart > $starttime) { + return true; + } + + return false; + } } diff --git a/course/classes/analytics/target/course_gradetopass.php b/course/classes/analytics/target/course_gradetopass.php index cb5727c393d81..84152eb2b70e9 100644 --- a/course/classes/analytics/target/course_gradetopass.php +++ b/course/classes/analytics/target/course_gradetopass.php @@ -164,6 +164,11 @@ public function is_valid_analysable(\core_analytics\analysable $course, $fortrai */ protected function calculate_sample($sampleid, \core_analytics\analysable $course, $starttime = false, $endtime = false) { + if ($this->enrolment_starts_after_calculation_start($sampleid, $starttime)) { + // Discard user enrolments whose start date is after $starttime. + return null; + } + $userenrol = $this->retrieve('user_enrolments', $sampleid); // Get course grade to pass. diff --git a/lib/tests/targets_test.php b/lib/tests/targets_test.php index 616ecc99db917..a61cb8365d3e4 100644 --- a/lib/tests/targets_test.php +++ b/lib/tests/targets_test.php @@ -148,21 +148,40 @@ public function sample_provider() { 'courseend' => $now + (WEEKSECS * 8), 'timestart' => $now, 'timeend' => $now - DAYSECS, - 'isvalid' => false + 'isvalidfortraining' => false, + 'isvalidforprediction' => false ], 'enrolmenttoolong' => [ 'coursestart' => $now, 'courseend' => $now + (WEEKSECS * 8), 'timestart' => $now - (YEARSECS + (WEEKSECS * 8)), 'timeend' => $now + (WEEKSECS * 8), - 'isvalid' => false + 'isvalidfortraining' => false, + 'isvalidforprediction' => false ], 'enrolmentstartaftercourse' => [ 'coursestart' => $now, 'courseend' => $now + (WEEKSECS * 8), 'timestart' => $now + (WEEKSECS * 9), 'timeend' => $now + (WEEKSECS * 10), - 'isvalid' => false + 'isvalidfortraining' => false, + 'isvalidforprediction' => false + ], + 'enrolmentstartsafternow' => [ + 'coursestart' => $now, + 'courseend' => $now + (WEEKSECS * 8), + 'timestart' => $now + (WEEKSECS * 2), + 'timeend' => $now + (WEEKSECS * 7), + 'isvalidfortraining' => false, + 'isvalidforprediction' => false + ], + 'enrolmentfinishedbeforenow' => [ + 'coursestart' => $now - (WEEKSECS * 4), + 'courseend' => $now - (WEEKSECS * 1), + 'timestart' => $now - (WEEKSECS * 3), + 'timeend' => $now - (WEEKSECS * 2), + 'isvalidfortraining' => true, + 'isvalidforprediction' => false ], ]; } @@ -228,9 +247,11 @@ public function test_core_target_course_completion_analysable($courseparams, $is * @param int $courseend Course end date * @param int $timestart Enrol start date * @param int $timeend Enrol end date - * @param boolean $isvalid True when sample is valid, false when it is not + * @param boolean $isvalidfortraining True when sample is valid for training, false when it is not + * @param boolean $isvalidforprediction True when sample is valid for prediction, false when it is not */ - public function test_core_target_course_completion_samples($coursestart, $courseend, $timestart, $timeend, $isvalid) { + public function test_core_target_course_completion_samples($coursestart, $courseend, $timestart, $timeend, + $isvalidfortraining, $isvalidforprediction) { $this->resetAfterTest(true); @@ -254,7 +275,8 @@ public function test_core_target_course_completion_samples($coursestart, $course $target->add_sample_data($samplesdata); $sampleid = reset($sampleids); - $this->assertEquals($isvalid, $target->is_valid_sample($sampleid, $analysable)); + $this->assertEquals($isvalidfortraining, $target->is_valid_sample($sampleid, $analysable, true)); + $this->assertEquals($isvalidforprediction, $target->is_valid_sample($sampleid, $analysable, false)); } /** @@ -391,11 +413,15 @@ public function test_core_target_course_gradetopass_calculate() { $student1 = $dg->create_user(); $student2 = $dg->create_user(); $student3 = $dg->create_user(); + $student4 = $dg->create_user(); $studentrole = $DB->get_record('role', array('shortname' => 'student')); $dg->enrol_user($student1->id, $course1->id, $studentrole->id); $dg->enrol_user($student2->id, $course1->id, $studentrole->id); $dg->enrol_user($student3->id, $course1->id, $studentrole->id); + $enrolstart = mktime(0, 0, 0, 10, 25, 2015); + $dg->enrol_user($student4->id, $course1->id, $studentrole->id, 'manual', $enrolstart); + // get_all_samples() does not guarantee any order, so let's // explicitly define the expectations here for later comparing. // Expectations format being array($userid => expectation, ...) @@ -413,6 +439,9 @@ public function test_core_target_course_gradetopass_calculate() { // Student 3 (has no grade) fails, so it's non achieved sample. $expectations[$student3->id] = 1; + // Student 4 should be null as its enrolment timestart is after the this range. + $expectations[$student4->id] = null; + $courseitem->gradepass = 50; $DB->update_record('grade_items', $courseitem); @@ -431,9 +460,12 @@ public function test_core_target_course_gradetopass_calculate() { $method = $class->getMethod('calculate_sample'); $method->setAccessible(true); + $starttime = mktime(0, 0, 0, 10, 24, 2015); + // Verify all the expectations are fulfilled. foreach ($sampleids as $sampleid => $key) { - $this->assertEquals($expectations[$samplesdata[$key]['user']->id], $method->invoke($target, $sampleid, $analysable)); + $this->assertEquals($expectations[$samplesdata[$key]['user']->id], $method->invoke($target, $sampleid, + $analysable, $starttime)); } } } From c3217a6b0d94c2fa8f14318d730b5bce8906225a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Monlla=C3=B3?= Date: Thu, 9 May 2019 15:47:48 +0200 Subject: [PATCH 013/786] MDL-65549 tool_analytics: Reduce the context name length in models_view --- admin/tool/analytics/classes/output/models_list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/tool/analytics/classes/output/models_list.php b/admin/tool/analytics/classes/output/models_list.php index c6831d0e20aa2..9c918ce1ef42a 100644 --- a/admin/tool/analytics/classes/output/models_list.php +++ b/admin/tool/analytics/classes/output/models_list.php @@ -181,7 +181,7 @@ public function export_for_template(\renderer_base $output) { if ($contextid == SYSCONTEXTID) { $contextname = get_string('allpredictions', 'tool_analytics'); } else { - $contextname = shorten_text($context->get_context_name(true, true), 90); + $contextname = shorten_text($context->get_context_name(false, true), 40); } $predictioncontexts[$contextid] = $contextname; } From 695675483f7995b31668f80f08433c45c36b94ef Mon Sep 17 00:00:00 2001 From: Daniel Neis Araujo Date: Mon, 20 May 2019 12:44:05 -0300 Subject: [PATCH 014/786] MDL-65654 tool_uploaduser: Fix undefined variable warning --- admin/tool/uploaduser/locallib.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/admin/tool/uploaduser/locallib.php b/admin/tool/uploaduser/locallib.php index e988e777838ab..e389f8064e4f8 100644 --- a/admin/tool/uploaduser/locallib.php +++ b/admin/tool/uploaduser/locallib.php @@ -360,6 +360,7 @@ function uu_allowed_roles() { */ function uu_allowed_roles_cache() { $allowedroles = get_assignable_roles(context_course::instance(SITEID), ROLENAME_SHORT); + $rolecache = []; foreach ($allowedroles as $rid=>$rname) { $rolecache[$rid] = new stdClass(); $rolecache[$rid]->id = $rid; @@ -379,6 +380,7 @@ function uu_allowed_roles_cache() { */ function uu_allowed_sysroles_cache() { $allowedroles = get_assignable_roles(context_system::instance(), ROLENAME_SHORT); + $rolecache = []; foreach ($allowedroles as $rid => $rname) { $rolecache[$rid] = new stdClass(); $rolecache[$rid]->id = $rid; From 8978731b821ea0a9c0a85c4d605f8048ecd7c703 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Thu, 4 Apr 2019 16:08:26 +0100 Subject: [PATCH 015/786] MDL-64784 core: consistent column sort direction in flexible_table. --- lib/tablelib.php | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/tablelib.php b/lib/tablelib.php index d1213b89b4742..421632cbc0c77 100644 --- a/lib/tablelib.php +++ b/lib/tablelib.php @@ -35,6 +35,7 @@ define('TABLE_VAR_ILAST', 5); define('TABLE_VAR_PAGE', 6); define('TABLE_VAR_RESET', 7); +define('TABLE_VAR_DIR', 8); /**#@-*/ /**#@+ @@ -150,7 +151,8 @@ function __construct($uniqueid) { TABLE_VAR_IFIRST => 'tifirst', TABLE_VAR_ILAST => 'tilast', TABLE_VAR_PAGE => 'page', - TABLE_VAR_RESET => 'treset' + TABLE_VAR_RESET => 'treset', + TABLE_VAR_DIR => 'tdir', ); } @@ -516,14 +518,16 @@ function setup() { (isset($this->columns[$sortcol]) || in_array($sortcol, get_all_user_name_fields()) && isset($this->columns['fullname']))) { + $sortdir = optional_param($this->request[TABLE_VAR_DIR], $this->sort_default_order, PARAM_INT); + if (array_key_exists($sortcol, $this->prefs['sortby'])) { // This key already exists somewhere. Change its sortorder and bring it to the top. - $sortorder = $this->prefs['sortby'][$sortcol] == SORT_ASC ? SORT_DESC : SORT_ASC; + $sortorder = $this->prefs['sortby'][$sortcol] = $sortdir; unset($this->prefs['sortby'][$sortcol]); $this->prefs['sortby'] = array_merge(array($sortcol => $sortorder), $this->prefs['sortby']); } else { // Key doesn't exist, so just add it to the beginning of the array, ascending order - $this->prefs['sortby'] = array_merge(array($sortcol => SORT_ASC), $this->prefs['sortby']); + $this->prefs['sortby'] = array_merge(array($sortcol => $sortdir), $this->prefs['sortby']); } // Finally, make sure that no more than $this->maxsortkeys are present into the array @@ -1362,8 +1366,19 @@ protected function sort_order_name($isprimary, $order) { * @return string HTML fragment. */ protected function sort_link($text, $column, $isprimary, $order) { - return html_writer::link($this->baseurl->out(false, - array($this->request[TABLE_VAR_SORT] => $column)), + // If we are already sorting by this column, switch direction. + if (array_key_exists($column, $this->prefs['sortby'])) { + $sortorder = $this->prefs['sortby'][$column] == SORT_ASC ? SORT_DESC : SORT_ASC; + } else { + $sortorder = $order; + } + + $params = [ + $this->request[TABLE_VAR_SORT] => $column, + $this->request[TABLE_VAR_DIR] => $sortorder, + ]; + + return html_writer::link($this->baseurl->out(false, $params), $text . get_accesshide(get_string('sortby') . ' ' . $text . ' ' . $this->sort_order_name($isprimary, $order))) . ' ' . $this->sort_icon($isprimary, $order); From 2cd4e5f8dc3f1fbfb1f1d3506a98cb7f4e8b9eca Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Fri, 5 Apr 2019 11:53:33 +0100 Subject: [PATCH 016/786] MDL-64784 core: update tablelib tests for explicit sort direction. --- lib/tests/tablelib_test.php | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/tests/tablelib_test.php b/lib/tests/tablelib_test.php index 9346e05c774f7..e43fdb11a3818 100644 --- a/lib/tests/tablelib_test.php +++ b/lib/tests/tablelib_test.php @@ -526,7 +526,6 @@ protected function prepare_table_for_reset_test($tableid) { } public function test_can_be_reset() { - // Table in its default state (as if seen for the first time), nothing to reset. $table = $this->prepare_table_for_reset_test(uniqid('tablelib_test_')); $table->setup(); @@ -538,21 +537,25 @@ public function test_can_be_reset() { $table->setup(); $this->assertFalse($table->can_be_reset()); - // Table explicitly sorted by the default column (reverses the order), can be reset. + // Table explicitly sorted by the default column & direction, nothing to reset. $table = $this->prepare_table_for_reset_test(uniqid('tablelib_test_')); $table->sortable(true, 'column1', SORT_DESC); $_GET['tsort'] = 'column1'; + $_GET['tdir'] = SORT_DESC; $table->setup(); unset($_GET['tsort']); - $this->assertTrue($table->can_be_reset()); + unset($_GET['tdir']); + $this->assertFalse($table->can_be_reset()); - // Table explicitly sorted twice by the default column (puts back to default order), nothing to reset. + // Table explicitly sorted twice by the default column & direction, nothing to reset. $table = $this->prepare_table_for_reset_test(uniqid('tablelib_test_')); $table->sortable(true, 'column1', SORT_DESC); $_GET['tsort'] = 'column1'; + $_GET['tdir'] = SORT_DESC; $table->setup(); $table->setup(); // Set up again to simulate the second page request. unset($_GET['tsort']); + unset($_GET['tdir']); $this->assertFalse($table->can_be_reset()); // Table sorted by other than default column, can be reset. @@ -563,6 +566,16 @@ public function test_can_be_reset() { unset($_GET['tsort']); $this->assertTrue($table->can_be_reset()); + // Table sorted by other than default direction, can be reset. + $table = $this->prepare_table_for_reset_test(uniqid('tablelib_test_')); + $table->sortable(true, 'column1', SORT_DESC); + $_GET['tsort'] = 'column1'; + $_GET['tdir'] = SORT_ASC; + $table->setup(); + unset($_GET['tsort']); + unset($_GET['tdir']); + $this->assertTrue($table->can_be_reset()); + // Table sorted by the default column after another sorting previously selected. // This leads to different ORDER BY than just having a single sort defined, can be reset. $table = $this->prepare_table_for_reset_test(uniqid('tablelib_test_')); From cd9c54c93c2c37ce6986f1274e3a0bf3700fbee0 Mon Sep 17 00:00:00 2001 From: Didier 'OdyX' Raboud Date: Thu, 14 Mar 2019 14:00:27 +0100 Subject: [PATCH 017/786] MDL-65067 analytics: Strengthen format_weeks detection The public function get_section_dates($section, $startdate = false) is only defined in format_weeks, not in format_base. As other formats can (and format_topcoll has) declare a different get_section_dates public method, merely checking that it exists is not sufficient to guarantee that it can be called with just a section object. Check that the format either is, or is a subclass of format_weeks. --- .../classes/local/indicator/community_of_inquiry_activity.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/analytics/classes/local/indicator/community_of_inquiry_activity.php b/analytics/classes/local/indicator/community_of_inquiry_activity.php index 5deaeb6049e3c..555bb420e7c8b 100644 --- a/analytics/classes/local/indicator/community_of_inquiry_activity.php +++ b/analytics/classes/local/indicator/community_of_inquiry_activity.php @@ -836,7 +836,8 @@ protected function activity_completed_by(\cm_info $activity, $starttime, $endtim // When the course is using format weeks we use the week's end date. $format = course_get_format($activity->get_modinfo()->get_course()); // We should change this in MDL-60702. - if (method_exists($format, 'get_section_dates')) { + if (get_class($format) == 'format_weeks' || is_subclass_of($format, 'format_weeks') + && method_exists($format, 'get_section_dates')) { $dates = $format->get_section_dates($section); // We need to consider the +2 hours added by get_section_dates. From e260354fc999b2ea7b2f6316915c1fdcb3c47d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Monlla=C3=B3?= Date: Fri, 17 May 2019 16:57:46 +0200 Subject: [PATCH 018/786] MDL-65067 tool_analytics: Limit update_end_date to format_weeks --- admin/tool/analytics/cli/guess_course_start_and_end.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/admin/tool/analytics/cli/guess_course_start_and_end.php b/admin/tool/analytics/cli/guess_course_start_and_end.php index f8a8aa5d6b5cc..f6e653ba77e93 100644 --- a/admin/tool/analytics/cli/guess_course_start_and_end.php +++ b/admin/tool/analytics/cli/guess_course_start_and_end.php @@ -173,7 +173,8 @@ function tool_analytics_calculate_course_dates($course, $options) { $formatoptions = $format->get_format_options(); // Change this for a course formats API level call in MDL-60702. - if (method_exists($format, 'update_end_date') && $formatoptions['automaticenddate']) { + if ((get_class($format) == 'format_weeks' || is_subclass_of($format, 'format_weeks')) && + method_exists($format, 'update_end_date') && $formatoptions['automaticenddate']) { // Special treatment for weeks-based formats with automatic end date. if ($options['update']) { From 7ee550a943fd97dfe1ed083a6faf13fdfed5d054 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 21 May 2019 17:43:28 +0800 Subject: [PATCH 019/786] MDL-65661 core_course: Truncate long course names --- course/templates/coursecard.mustache | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/course/templates/coursecard.mustache b/course/templates/coursecard.mustache index 1aba15c597fd7..2d45db2741464 100644 --- a/course/templates/coursecard.mustache +++ b/course/templates/coursecard.mustache @@ -43,8 +43,8 @@
-
-
+
+
{{$coursecategory}}{{/coursecategory}} {{#showshortname}} {{$divider}}{{/divider}} @@ -56,7 +56,7 @@
{{/showshortname}}
- + {{> core_course/favouriteicon }} {{#str}}aria:coursename, core_course{{/str}} From d186ba2f81d637f10938bef093807cfefb90ae1e Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 22 May 2019 19:30:48 +0800 Subject: [PATCH 020/786] MDL-65661 block_myoverview: Truncate category name --- blocks/myoverview/templates/view-cards.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blocks/myoverview/templates/view-cards.mustache b/blocks/myoverview/templates/view-cards.mustache index b940a1e414af2..0a995fd993337 100644 --- a/blocks/myoverview/templates/view-cards.mustache +++ b/blocks/myoverview/templates/view-cards.mustache @@ -55,7 +55,7 @@ {{#str}}aria:coursecategory, core_course{{/str}} - + {{{coursecategory}}} {{/coursecategory}} From 09558248e801f998e7a4873e32045b4f90d9d724 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Fri, 17 May 2019 12:22:19 +0100 Subject: [PATCH 021/786] MDL-65636 filter_multilang: add some basic unit tests This commit includes suggestions from Jun Pataleta on how to improve the unit tests. --- filter/multilang/filter.php | 3 +- filter/multilang/tests/filter_test.php | 143 +++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 filter/multilang/tests/filter_test.php diff --git a/filter/multilang/filter.php b/filter/multilang/filter.php index efb618f705b22..4cf90f7a90916 100644 --- a/filter/multilang/filter.php +++ b/filter/multilang/filter.php @@ -16,8 +16,7 @@ // along with Moodle. If not, see . /** - * @package filter - * @subpackage multilang + * @package filter_multilang * @copyright Gaetan Frenoy * @copyright 2004 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later diff --git a/filter/multilang/tests/filter_test.php b/filter/multilang/tests/filter_test.php new file mode 100644 index 0000000000000..116dc50f02ae9 --- /dev/null +++ b/filter/multilang/tests/filter_test.php @@ -0,0 +1,143 @@ +. + +/** + * Unit tests. + * + * @package filter_multilang + * @category test + * @copyright 2019 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + + +/** + * Tests for filter_multilang. + * + * @copyright 2019 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class filter_multilang_filter_testcase extends advanced_testcase { + + public function setUp() { + parent::setUp(); + + $this->resetAfterTest(true); + + // Enable glossary filter at top level. + filter_set_global_state('multilang', TEXTFILTER_ON); + } + + /** + * Setup parent language relationship. + * + * @param string $child the child language, e.g. 'fr_ca'. + * @param string $parent the parent language, e.g. 'fr'. + */ + protected function setup_parent_language(string $child, string $parent) { + global $CFG; + + $langfolder = $CFG->dataroot . '/lang/' . $child; + check_dir_exists($langfolder); + $langconfig = " [ + 'English', + 'EnglishFrançais', + 'en', + ], + 'Basic case FR' => [ + 'Français', + 'EnglishFrançais', + 'fr', + ], + 'Reversed input order EN' => [ + 'English', + 'FrançaisEnglish', + 'en', + ], + 'Reversed input order EN' => [ + 'Français', + 'FrançaisEnglish', + 'fr', + ], + 'Fallback to parent when child not present' => [ + 'Français', + 'EnglishFrançais', + 'fr_ca', ['fr_ca' => 'fr'] + ], + 'Both parent and child language present, using child' => [ + 'Québécois', + 'Québécois + Français + English', + 'fr_ca', ['fr_ca' => 'fr'], + ], + 'Both parent and child language present, using parent' => [ + 'Français', + 'Québécois + Français + English', + 'fr', ['fr_ca' => 'fr'], + ], + 'Both parent and child language present - reverse order, using child' => [ + 'Québécois', + 'English + Français + Québécois', + 'fr_ca', ['fr_ca' => 'fr'], + ], + 'Both parent and child language present - reverse order, using parent' => [ + 'Français', + 'English + Français + Québécois', + 'fr', ['fr_ca' => 'fr'], + ], + ]; + } + + /** + * Tests the filtering of multi-language strings. + * + * @dataProvider multilang_testcases + * + * @param string $expectedoutput The expected filter output. + * @param string $input the input that is filtererd. + * @param string $targetlang the laguage to set as the current languge . + * @param array $parentlangs Array child lang => parent lang. E.g. ['es_co' => 'es', 'es_mx' => 'es']. + */ + public function test_filtering($expectedoutput, $input, $targetlang, $parentlangs = []) { + global $SESSION; + $SESSION->forcelang = $targetlang; + + foreach ($parentlangs as $child => $parent) { + $this->setup_parent_language($child, $parent); + } + + $filtered = format_text($input, FORMAT_HTML, array('context' => context_system::instance())); + $this->assertEquals($expectedoutput, $filtered); + } +} From 67b64f85e95c2fd96fe7674e3c45fe57fb8d011c Mon Sep 17 00:00:00 2001 From: Ryan Wyllie Date: Wed, 28 Nov 2018 12:08:42 +0800 Subject: [PATCH 022/786] MDL-65060 core_message: add render buffer to conversations Change the conversation logic to render using a buffer so that we can immediately save state. The render patches are based on the state so the UI will always reach eventual consistency with the state since the patches are processed in order. --- .../message_drawer_view_conversation.min.js | 2 +- .../src/message_drawer_view_conversation.js | 533 +++++++++--------- 2 files changed, 280 insertions(+), 255 deletions(-) diff --git a/message/amd/build/message_drawer_view_conversation.min.js b/message/amd/build/message_drawer_view_conversation.min.js index 67374e6b6ad3e..63ce8d317f59e 100644 --- a/message/amd/build/message_drawer_view_conversation.min.js +++ b/message/amd/build/message_drawer_view_conversation.min.js @@ -1 +1 @@ -define(["jquery","core/auto_rows","core/backoff_timer","core/custom_interaction_events","core/notification","core/pubsub","core/str","core_message/message_repository","core_message/message_drawer_events","core_message/message_drawer_view_conversation_constants","core_message/message_drawer_view_conversation_patcher","core_message/message_drawer_view_conversation_renderer","core_message/message_drawer_view_conversation_state_manager","core_message/message_drawer_router","core_message/message_drawer_routes"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p={},q=null,r=!1,s=0,t=null,u=!0,v=!1,w=null,x=[],y=j.NEWEST_MESSAGES_FIRST,z=j.LOAD_MESSAGE_LIMIT,A=j.INITIAL_NEW_MESSAGE_POLL_TIMEOUT,B=j.SELECTORS,C=j.CONVERSATION_TYPES,D=function(){if(!q||q.type==C.PUBLIC)return null;var a=q.loggedInUserId;if(q.type==C.SELF)return a;var b=Object.keys(q.members).filter(function(b){return a!=b});return b.length?b[0]:null},E=function(a){return Object.keys(p).reduce(function(b,c){if(!b){var d=p[c].state;d.type!=C.PUBLIC&&a in d.members&&(b=d.id)}return b},null)},F=function(a){return{id:parseInt(a.attr("data-user-id"),10),fullname:null,profileimageurl:null,profileimageurlsmall:null,isonline:null,showonlinestatus:null,isblocked:null,iscontact:null,isdeleted:null,canmessage:null,requirescontact:null,contactrequests:[]}},G=function(){return s},H=function(a){s=a,p[q.id].messagesOffset=a},I=function(){return r},J=function(a){r=a,p[q.id].loadedAllMessages=a},K=function(a){return a.find(B.MESSAGES_CONTAINER)},L=function(b){return{id:b.id,name:b.name,subname:b.subname,imageUrl:b.imageUrl,isFavourite:b.isFavourite,isMuted:b.isMuted,type:b.type,totalMemberCount:b.totalMemberCount,loggedInUserId:b.loggedInUserId,messages:b.messages.map(function(b){return a.extend({},b)}),members:Object.keys(b.members).map(function(c){var d=a.extend({},b.members[c]);return d.contactrequests=b.members[c].contactrequests.map(function(b){return a.extend({},b)}),d})}},M=function(a,b){var c=a.id,d=c==b?C.SELF:C.PRIVATE,f=m.setLoadingMembers(q,!0);return f=m.setLoadingMessages(f,!0),w(f).then(function(){return h.getMemberInfo(c,[b],!0,!0)}).then(function(a){if(a.length)return a[0];throw new Error("Unable to load other user profile")}).then(function(b){var c=d==C.SELF?[b]:[b,a],e=m.addMembers(q,c);return e=m.setLoadingMembers(e,!1),e=m.setLoadingMessages(e,!1),e=m.setName(e,b.fullname),e=m.setType(e,d),e=m.setImageUrl(e,b.profileimageurl),e=m.setTotalMemberCount(e,c.length),w(e).then(function(){return b})})["catch"](function(a){var b=m.setLoadingMembers(q,!1);w(b),e.exception(a)})},N=function(a,b){var c=null;if(a.type==C.PRIVATE){var d=a.members.filter(function(a){return a.id!=b});c=d.length?d[0]:null}else a.type==C.SELF&&(c=a.members[0]);var e=a.name,f=a.imageurl;a.type!=C.PUBLIC&&(e=e||c?c.fullname:"",f=f||c?c.profileimageurl:"");var g=m.addMembers(q,a.members);return g=m.setName(g,e),g=m.setSubname(g,a.subname),g=m.setType(g,a.type),g=m.setImageUrl(g,f),g=m.setTotalMemberCount(g,a.membercount),g=m.setIsFavourite(g,a.isfavourite),g=m.setIsMuted(g,a.ismuted),g=m.addMessages(g,a.messages),g=m.setCanDeleteMessagesForAllUsers(g,a.candeletemessagesforallusers)},O=function(a,b,c,d,f){var g=b.id,i=m.setLoadingMembers(q,!0);return i=m.setLoadingMessages(i,!0),w(i).then(function(){return h.getConversation(g,a,!0,!0,0,0,c+1,d,f)}).then(function(a){return a.messages.length>c?a.messages=a.messages.slice(1):J(!0),H(d+c),a}).then(function(a){var c=a.members.filter(function(a){return a.id==b.id});c.length<1&&(a.members=a.members.concat([b]));var d=N(a,b.id);return d=m.setLoadingMembers(d,!1),d=m.setLoadingMessages(d,!1),w(d).then(function(){return a})}).then(function(){return S(a)})["catch"](function(a){var b=m.setLoadingMembers(q,!1);b=m.setLoadingMessages(b,!1),w(b),e.exception(a)})},P=function(a,b,c,d){var f=a.members.filter(function(a){return a.id==b.id});f.length<1&&(a.members=a.members.concat([b]));var g=N(a,b.id);g=m.setLoadingMembers(g,!1),g=m.setLoadingMessages(g,!0);var h=a.messages.length;return w(g).then(function(){if(hb?a.messages=a.messages.slice(0,-1):J(!0),a):a}).then(function(a){var b=a.members.filter(function(a){return!(a.id in q.members)}),c=m.addMembers(q,b);return c=m.addMessages(c,a.messages),c=m.setLoadingMessages(c,!1),w(c).then(function(){return a})})["catch"](function(a){var b=m.setLoadingMessages(q,!1);throw w(b),a})},R=function(b,c){return function(){var d=q.messages,e=d.length?d[d.length-1]:null;if(e&&!u&&!v){for(var g=[],h=d.length-1;h>=0;h--){var j=d[h];if(j.timeCreated!==e.timeCreated)break;g.push(j.id)}return Q(b,0,0,c,g,e.timeCreated).then(function(a){if(a.messages.length){t.restart();var c=L(q);return f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c),S(b)}return a})}return a.Deferred().resolve().promise()}},S=function(a){var b=q.loggedInUserId;return h.markAllConversationMessagesAsRead(b,a).then(function(){var b=m.markMessagesAsRead(q,q.messages);return f.publish(i.CONVERSATION_READ,a),w(b)})},T=function(a){return ha(a).then(function(){var b=m.addPendingBlockUsersById(q,[a]);return w(b)})},U=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.blockUser(q.loggedInUserId,a)}).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingBlockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_BLOCKED,a),w(c)})},V=function(a){return ha(a).then(function(){var b=m.addPendingUnblockUsersById(q,[a]);return w(b)})},W=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.unblockUser(q.loggedInUserId,a)}).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingUnblockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_UNBLOCKED,a),w(c)})},X=function(a){return ha(a).then(function(){var b=m.addPendingRemoveContactsById(q,[a]);return w(b)})},Y=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.deleteContacts(q.loggedInUserId,[a])}).then(function(b){var c=m.addMembers(q,b);return c=m.removePendingRemoveContactsById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_REMOVED,a),w(c)})},Z=function(a){return ha(a).then(function(){var b=m.addPendingAddContactsById(q,[a]);return w(b)})},$=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.createContactRequest(q.loggedInUserId,a)}).then(function(a){if(!a.request)throw new Error(a.warnings[0].message);return a.request}).then(function(b){var c=m.removePendingAddContactsById(q,[a]);return c=m.addContactRequests(c,[b]),c=m.setLoadingConfirmAction(c,!1),w(c)})},_=function(){var a=q.loggedInUserId,b=q.id;return h.setFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!0);return w(a)}).then(function(){return f.publish(i.CONVERSATION_SET_FAVOURITE,L(q))})},aa=function(){var a=q.loggedInUserId,b=q.id;return h.unsetFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!1);return w(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_FAVOURITE,L(q))})},ba=function(){var a=q.loggedInUserId,b=q.id;return h.setMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!0);return w(a)}).then(function(){return f.publish(i.CONVERSATION_SET_MUTED,L(q))})},ca=function(){var a=q.loggedInUserId,b=q.id;return h.unsetMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!1);return w(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_MUTED,L(q))})},da=function(a){var b=q.selectedMessageIds;return ha(a).then(function(){var a=m.addPendingDeleteMessagesById(q,b);return w(a)})},ea=function(){var a=q.pendingDeleteMessageIds,b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return b.deleteMessagesForAllUsers?h.deleteMessagesForAllUsers(q.loggedInUserId,a):h.deleteMessages(q.loggedInUserId,a)}).then(function(){var b=m.removeMessagesById(q,a);b=m.removePendingDeleteMessagesById(b,a),b=m.removeSelectedMessagesById(b,a),b=m.setLoadingConfirmAction(b,!1),b=m.setDeleteMessagesForAllUsers(b,!1);var c=q.messages[q.messages.length-1],d=b.messages.length?b.messages[b.messages.length-1]:null;if(d&&d.id!=c.id){var e=L(b);f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,e)}else b.messages.length||f.publish(i.CONVERSATION_DELETED,b.id);return w(b)})},fa=function(a){return ha(a).then(function(){var a=m.setPendingDeleteConversation(q,!0);return w(a)})},ga=function(){var a=m.setLoadingConfirmAction(q,!0);return w(a).then(function(){return h.deleteConversation(q.loggedInUserId,q.id)}).then(function(){var a=m.removeMessages(q,q.messages);return a=m.removeSelectedMessagesById(a,q.selectedMessageIds),a=m.setPendingDeleteConversation(a,!1),a=m.setLoadingConfirmAction(a,!1),f.publish(i.CONVERSATION_DELETED,a.id),w(a)})},ha=function(a){var b=q.pendingDeleteMessageIds,c=m.removePendingAddContactsById(q,[a]);return c=m.removePendingRemoveContactsById(c,[a]),c=m.removePendingUnblockUsersById(c,[a]),c=m.removePendingBlockUsersById(c,[a]),c=m.removePendingDeleteMessagesById(c,b),c=m.setPendingDeleteConversation(c,!1),c=m.setDeleteMessagesForAllUsers(c,!1),w(c)},ia=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return w(e).then(function(){return h.acceptContactRequest(a,b)}).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),w(b)}).then(function(){f.publish(i.CONTACT_ADDED,q.members[a]),f.publish(i.CONTACT_REQUEST_ACCEPTED,d)})},ja=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return w(e).then(function(){return h.declineContactRequest(a,b)}).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),w(b)}).then(function(){f.publish(i.CONTACT_REQUEST_DECLINED,d)})},ka=function(a,b){v=!0;var c=m.setSendingMessage(q,!0),d=null,g=!1;return w(c).then(function(){if(a||q.type==C.PUBLIC)return h.sendMessageToConversation(a,b);var c=D();return h.sendMessageToUser(c,b).then(function(a){return d=parseInt(a.conversationid,10),g=a.candeletemessagesforallusers,a})}).then(function(a){var b=m.addMessages(q,[a]);b=m.setSendingMessage(b,!1);var c=L(b);return b.id||(b=m.setId(b,d),c.id=d,Aa(d),f.publish(i.CONVERSATION_CREATED,c),b=m.setCanDeleteMessagesForAllUsers(b,g)),w(b).then(function(){v=!1,f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c)})})["catch"](function(a){v=!1;var b=m.setSendingMessage(q,!1);w(b),e.exception(a)})},la=function(a){var b=q;return b=q.selectedMessageIds.indexOf(a)>-1?m.removeSelectedMessagesById(q,[a]):m.addSelectedMessagesById(q,[a]),w(b)},ma=function(){return ha(D()).then(function(){var a=m.removeSelectedMessagesById(q,q.selectedMessageIds);return w(a)})},na=function(b,c,d,e){var f=function(a){return l.render(b,c,d,a)};if(!e){var g=m.buildInitialState(q.midnight,q.loggedInUserId,q.id),h=k.buildPatch(g,q);f(h)}return x.push(f),function(b){var c=k.buildPatch(q,b),d=x.map(function(a){return a(c)});return a.when.apply(null,d).then(function(){q=b,b.id&&(p[b.id]={state:b,messagesOffset:G(),loadedAllMessages:I()})})}},oa=function(a){return function(b,c){q.loadingConfirmAction||a(D())["catch"](function(a){var b=m.setLoadingConfirmAction(q,!1);w(b),e.exception(a)}),c.originalEvent.preventDefault()}},pa=function(b,c){var d=a(b.target),e=d.closest(B.FOOTER_CONTAINER),f=e.find(B.MESSAGE_TEXT_AREA),g=f.val().trim();""!==g&&ka(q.id,g),c.originalEvent.preventDefault()},qa=function(b,c){var d=window.getSelection(),f=a(b.target);if(""==d.toString()&&!f.is("a")){var g=f.closest(B.MESSAGE),h=parseInt(g.attr("data-message-id"),10);la(h)["catch"](e.exception),c.originalEvent.preventDefault()}},ra=function(a,b){ma()["catch"](e.exception),b.originalEvent.preventDefault()},sa=function(a){return function(b,c){var d=D(),e=q.members[d];n.go(a,o.VIEW_CONTACT,e),c.originalEvent.preventDefault()}},ta=function(a,b){_()["catch"](e.exception),b.originalEvent.preventDefault()},ua=function(a,b){aa()["catch"](e.exception),b.originalEvent.preventDefault()},va=function(a,b){ba()["catch"](e.exception),b.originalEvent.preventDefault()},wa=function(a,b){ca()["catch"](e.exception),b.originalEvent.preventDefault()},xa=function(b){var c=a(b.target).prop("checked"),d=m.setDeleteMessagesForAllUsers(q,c);w(d)},ya=function(a){return function(b,c){n.go(a,o.VIEW_GROUP_INFO,{id:q.id,name:q.name,subname:q.subname,imageUrl:q.imageUrl,totalMemberCount:q.totalMemberCount},q.loggedInUserId),c.originalEvent.preventDefault()}},za=function(a,c,g,h){var j=!1,k=K(g),l=[[B.ACTION_REQUEST_BLOCK,oa(T)],[B.ACTION_REQUEST_UNBLOCK,oa(V)],[B.ACTION_REQUEST_ADD_CONTACT,oa(Z)],[B.ACTION_REQUEST_REMOVE_CONTACT,oa(X)],[B.ACTION_REQUEST_DELETE_CONVERSATION,oa(fa)],[B.ACTION_CANCEL_EDIT_MODE,ra],[B.ACTION_VIEW_CONTACT,sa(a)],[B.ACTION_VIEW_GROUP_INFO,ya(a)],[B.ACTION_CONFIRM_FAVOURITE,ta],[B.ACTION_CONFIRM_MUTE,va],[B.ACTION_CONFIRM_UNFAVOURITE,ua],[B.ACTION_CONFIRM_UNMUTE,wa]],n=[[B.ACTION_CANCEL_CONFIRM,oa(ha)],[B.ACTION_CONFIRM_BLOCK,oa(U)],[B.ACTION_CONFIRM_UNBLOCK,oa(W)],[B.ACTION_CONFIRM_ADD_CONTACT,oa($)],[B.ACTION_CONFIRM_REMOVE_CONTACT,oa(Y)],[B.ACTION_CONFIRM_DELETE_SELECTED_MESSAGES,oa(ea)],[B.ACTION_CONFIRM_DELETE_CONVERSATION,oa(ga)],[B.ACTION_REQUEST_ADD_CONTACT,oa(Z)],[B.ACTION_ACCEPT_CONTACT_REQUEST,oa(ia)],[B.ACTION_DECLINE_CONTACT_REQUEST,oa(ja)],[B.MESSAGE,qa],[B.DELETE_MESSAGES_FOR_ALL_USERS_TOGGLE,xa]],p=[[B.SEND_MESSAGE_BUTTON,pa],[B.ACTION_REQUEST_DELETE_SELECTED_MESSAGES,oa(da)],[B.ACTION_REQUEST_ADD_CONTACT,oa(Z)],[B.ACTION_REQUEST_UNBLOCK,oa(V)]];b.init(h),d.define(c,[d.events.activate]),d.define(g,[d.events.activate]),d.define(h,[d.events.activate,d.events.enter]),d.define(k,[d.events.scrollTop,d.events.scrollLock]),k.on(d.events.scrollTop,function(a,b){var c=Object.keys(q.members).length>1;if(!u&&!j&&!I()&&c){j=!0;var d=m.setLoadingMessages(q,!0);w(d).then(function(){return Q(q.id,z,G(),y,[])}).then(function(){j=!1,H(G()+z)})["catch"](function(a){j=!1,e.exception(a)})}b.originalEvent.preventDefault()}),l.forEach(function(a){var b=a[0],e=a[1];c.on(d.events.activate,b,e)}),n.forEach(function(a){var b=a[0],c=a[1];g.on(d.events.activate,b,c)}),p.forEach(function(a){var b=a[0],c=a[1];h.on(d.events.activate,b,c)}),h.on(d.events.enter,B.MESSAGE_TEXT_AREA,function(a,b){var c=h.attr("data-enter-to-send");c&&"false"!=c&&"0"!=c&&pa(a,b)}),f.subscribe(i.ROUTE_CHANGED,function(a){t&&a.route!=o.VIEW_CONVERSATION&&t.stop()})},Aa=function(a){t&&t.stop(),t=new c(R(a,y),function(a){return a?2*a:A}),t.start()},Ba=function(a,b,c){var d=c.id,e=parseInt(a.attr("data-midnight"),10),f=m.buildInitialState(e,d,b);return q||(q=f),t&&t.stop(),w(f)},Ca=function(a,b,c){return Ba(a,null,b).then(function(){return b.id!=c?h.getConversationBetweenUsers(b.id,c,!0,!0,0,0,z,0,y):h.getSelfConversation(b.id,z,0,y)}).then(function(c){return Ea(a,c,b)})["catch"](function(){return M(b,c)})},Da=function(a,b,c){var d=null;return b in p&&(d=p[b]),Ba(a,b,c).then(function(){if(d){var a=d.state;return a=m.setLoadingMessages(a,!1),a=m.setLoadingMembers(a,!1),H(d.messagesOffset),J(d.loadedAllMessages),w(a)}return O(b,c,z,0,y)}).then(function(){return Aa(b)})},Ea=function(a,b,c){var d=null;return b.id in p&&(d=p[b.id]),Ba(a,b.id,c).then(function(){if(d){var a=d.state;return a=m.setLoadingMessages(a,!1),a=m.setLoadingMembers(a,!1),H(d.messagesOffset),J(d.loadedAllMessages),w(a)}return P(b,c,z,y)}).then(function(){return Aa(b.id)})},Fa=function(b,c,d,f,g,h,i){var k=null,l=null;g&&null!==g&&"object"==typeof g?(k=g,l=parseInt(k.id,10)):(k=null,l=parseInt(g,10),l=isNaN(l)?null:l),!l&&h&&i&&(l=E(i));var m=!q||q.id!=l||i&&i!=D();if(d.attr("data-init")||(w=na(c,d,f,m),za(b,c,d,f),d.attr("data-init",!0)),m){u=!0;var n=null,o=F(d);return n=k?Ea(d,k,o,i):l?Da(d,l,o,i):Ca(d,o,i),n.then(function(){u=!1,c.find(j.SELECTORS.CAN_RECEIVE_FOCUS).first().focus()})["catch"](function(a){u=!1,e.exception(a)})}if(Aa(l),q.type==C.PRIVATE&&h){var p=D();switch(h){case"block":return T(p);case"unblock":return V(p);case"add-contact":return Z(p);case"remove-contact":return X(p)}}return a.Deferred().resolve().promise()},Ga=function(){return g.get_string("messagedrawerviewconversation","core_message",q.name)};return{show:Fa,description:Ga}}); \ No newline at end of file +define(["jquery","core/auto_rows","core/backoff_timer","core/custom_interaction_events","core/notification","core/pubsub","core/str","core_message/message_repository","core_message/message_drawer_events","core_message/message_drawer_view_conversation_constants","core_message/message_drawer_view_conversation_patcher","core_message/message_drawer_view_conversation_renderer","core_message/message_drawer_view_conversation_state_manager","core_message/message_drawer_router","core_message/message_drawer_routes"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p={},q=null,r=!1,s=0,t=null,u=!1,v=[],w=!0,x=!1,y=null,z=[],A=j.NEWEST_MESSAGES_FIRST,B=j.LOAD_MESSAGE_LIMIT,C=j.INITIAL_NEW_MESSAGE_POLL_TIMEOUT,D=j.SELECTORS,E=j.CONVERSATION_TYPES,F=function(){if(!q||q.type==E.PUBLIC)return null;var a=q.loggedInUserId;if(q.type==E.SELF)return a;var b=Object.keys(q.members).filter(function(b){return a!=b});return b.length?b[0]:null},G=function(a){return Object.keys(p).reduce(function(b,c){if(!b){var d=p[c].state;d.type!=E.PUBLIC&&a in d.members&&(b=d.id)}return b},null)},H=function(a){return{id:parseInt(a.attr("data-user-id"),10),fullname:null,profileimageurl:null,profileimageurlsmall:null,isonline:null,showonlinestatus:null,isblocked:null,iscontact:null,isdeleted:null,canmessage:null,requirescontact:null,contactrequests:[]}},I=function(){return s},J=function(a){s=a,p[q.id].messagesOffset=a},K=function(){return r},L=function(a){r=a,p[q.id].loadedAllMessages=a},M=function(a){return a.find(D.MESSAGES_CONTAINER)},N=function(b){return{id:b.id,name:b.name,subname:b.subname,imageUrl:b.imageUrl,isFavourite:b.isFavourite,isMuted:b.isMuted,type:b.type,totalMemberCount:b.totalMemberCount,loggedInUserId:b.loggedInUserId,messages:b.messages.map(function(b){return a.extend({},b)}),members:Object.keys(b.members).map(function(c){var d=a.extend({},b.members[c]);return d.contactrequests=b.members[c].contactrequests.map(function(b){return a.extend({},b)}),d})}},O=function(a,b){var c=a.id,d=c==b?E.SELF:E.PRIVATE,f=m.setLoadingMembers(q,!0);return f=m.setLoadingMessages(f,!0),y(f),h.getMemberInfo(c,[b],!0,!0).then(function(a){if(a.length)return a[0];throw new Error("Unable to load other user profile")}).then(function(b){var c=d==E.SELF?[b]:[b,a],e=m.addMembers(q,c);return e=m.setLoadingMembers(e,!1),e=m.setLoadingMessages(e,!1),e=m.setName(e,b.fullname),e=m.setType(e,d),e=m.setImageUrl(e,b.profileimageurl),e=m.setTotalMemberCount(e,c.length),y(e),b})["catch"](function(a){var b=m.setLoadingMembers(q,!1);y(b),e.exception(a)})},P=function(a,b){var c=null;if(a.type==E.PRIVATE){var d=a.members.filter(function(a){return a.id!=b});c=d.length?d[0]:null}else a.type==E.SELF&&(c=a.members[0]);var e=a.name,f=a.imageurl;a.type!=E.PUBLIC&&(e=e||c?c.fullname:"",f=f||c?c.profileimageurl:"");var g=m.addMembers(q,a.members);return g=m.setName(g,e),g=m.setSubname(g,a.subname),g=m.setType(g,a.type),g=m.setImageUrl(g,f),g=m.setTotalMemberCount(g,a.membercount),g=m.setIsFavourite(g,a.isfavourite),g=m.setIsMuted(g,a.ismuted),g=m.addMessages(g,a.messages),g=m.setCanDeleteMessagesForAllUsers(g,a.candeletemessagesforallusers)},Q=function(a,b,c,d,f){var g=b.id,i=m.setLoadingMembers(q,!0);return i=m.setLoadingMessages(i,!0),y(i),h.getConversation(g,a,!0,!0,0,0,c+1,d,f).then(function(a){return a.messages.length>c?a.messages=a.messages.slice(1):L(!0),J(d+c),a}).then(function(a){var c=a.members.filter(function(a){return a.id==b.id});c.length<1&&(a.members=a.members.concat([b]));var d=P(a,b.id);return d=m.setLoadingMembers(d,!1),d=m.setLoadingMessages(d,!1),y(d).then(function(){return a})}).then(function(){return U(a)})["catch"](function(a){var b=m.setLoadingMembers(q,!1);b=m.setLoadingMessages(b,!1),y(b),e.exception(a)})},R=function(a,b,c,d){var f=a.members.filter(function(a){return a.id==b.id});f.length<1&&(a.members=a.members.concat([b]));var g=a.messages.length,h=g>=c,i=P(a,b.id);i=m.setLoadingMembers(i,!1),i=m.setLoadingMessages(i,!h);var j=y(i);return j.then(function(){return h?{messages:a.messages}:S(a.id,c,g,d,[])}).then(function(){var a=q.messages;return J(a.length),U(q.id),a})["catch"](e.exception)},S=function(a,b,c,d,e,f){return h.getMessages(q.loggedInUserId,a,b?b+1:b,c,d,f).then(function(a){return a.messages.length&&e.length&&(a.messages=a.messages.filter(function(a){return e.indexOf(parseInt(a.id,10))<0})),a}).then(function(a){return b?(a.messages.length>b?a.messages=a.messages.slice(0,-1):L(!0),a):a}).then(function(a){var b=a.members.filter(function(a){return!(a.id in q.members)}),c=m.addMembers(q,b);return c=m.addMessages(c,a.messages),c=m.setLoadingMessages(c,!1),y(c).then(function(){return a})})["catch"](function(a){var b=m.setLoadingMessages(q,!1);throw y(b),a})},T=function(b,c){return function(){var d=q.messages,e=d.length?d[d.length-1]:null;if(e&&!w&&!x){for(var g=[],h=d.length-1;h>=0;h--){var j=d[h];if(j.timeCreated!==e.timeCreated)break;g.push(j.id)}return S(b,0,0,c,g,e.timeCreated).then(function(a){if(a.messages.length){t.restart();var c=N(q);return f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c),U(b)}return a})}return a.Deferred().resolve().promise()}},U=function(a){var b=q.loggedInUserId;return h.markAllConversationMessagesAsRead(b,a).then(function(){var b=m.markMessagesAsRead(q,q.messages);return f.publish(i.CONVERSATION_READ,a),y(b)})},V=function(a){ja(a);var b=m.addPendingBlockUsersById(q,[a]);y(b)},W=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.blockUser(q.loggedInUserId,a).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingBlockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_BLOCKED,a),y(c)})},X=function(a){ja(a);var b=m.addPendingUnblockUsersById(q,[a]);y(b)},Y=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.unblockUser(q.loggedInUserId,a).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingUnblockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_UNBLOCKED,a),y(c)})},Z=function(a){ja(a);var b=m.addPendingRemoveContactsById(q,[a]);y(b)},$=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.deleteContacts(q.loggedInUserId,[a]).then(function(b){var c=m.addMembers(q,b);return c=m.removePendingRemoveContactsById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_REMOVED,a),y(c)})},_=function(a){ja(a);var b=m.addPendingAddContactsById(q,[a]);y(b)},aa=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.createContactRequest(q.loggedInUserId,a).then(function(a){if(!a.request)throw new Error(a.warnings[0].message);return a.request}).then(function(b){var c=m.removePendingAddContactsById(q,[a]);return c=m.addContactRequests(c,[b]),c=m.setLoadingConfirmAction(c,!1),y(c)})},ba=function(){var a=q.loggedInUserId,b=q.id;return h.setFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!0);return y(a)}).then(function(){return f.publish(i.CONVERSATION_SET_FAVOURITE,N(q))})},ca=function(){var a=q.loggedInUserId,b=q.id;return h.unsetFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!1);return y(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_FAVOURITE,N(q))})},da=function(){var a=q.loggedInUserId,b=q.id;return h.setMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!0);return y(a)}).then(function(){return f.publish(i.CONVERSATION_SET_MUTED,N(q))})},ea=function(){var a=q.loggedInUserId,b=q.id;return h.unsetMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!1);return y(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_MUTED,N(q))})},fa=function(a){var b=q.selectedMessageIds;ja(a);var c=m.addPendingDeleteMessagesById(q,b);y(c)},ga=function(){var a=q.pendingDeleteMessageIds,b=m.setLoadingConfirmAction(q,!0);y(b);var c=null;return c=b.deleteMessagesForAllUsers?h.deleteMessagesForAllUsers(q.loggedInUserId,a):h.deleteMessages(q.loggedInUserId,a),c.then(function(){var b=m.removeMessagesById(q,a);b=m.removePendingDeleteMessagesById(b,a),b=m.removeSelectedMessagesById(b,a),b=m.setLoadingConfirmAction(b,!1),b=m.setDeleteMessagesForAllUsers(b,!1);var c=q.messages[q.messages.length-1],d=b.messages.length?b.messages[b.messages.length-1]:null;if(d&&d.id!=c.id){var e=N(b);f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,e)}else b.messages.length||f.publish(i.CONVERSATION_DELETED,b.id);return y(b)})},ha=function(a){ja(a);var b=m.setPendingDeleteConversation(q,!0);y(b)},ia=function(){var a=m.setLoadingConfirmAction(q,!0);return y(a),h.deleteConversation(q.loggedInUserId,q.id).then(function(){var a=m.removeMessages(q,q.messages);return a=m.removeSelectedMessagesById(a,q.selectedMessageIds),a=m.setPendingDeleteConversation(a,!1),a=m.setLoadingConfirmAction(a,!1),f.publish(i.CONVERSATION_DELETED,a.id),y(a)})},ja=function(a){var b=q.pendingDeleteMessageIds,c=m.removePendingAddContactsById(q,[a]);c=m.removePendingRemoveContactsById(c,[a]),c=m.removePendingUnblockUsersById(c,[a]),c=m.removePendingBlockUsersById(c,[a]),c=m.removePendingDeleteMessagesById(c,b),c=m.setPendingDeleteConversation(c,!1),c=m.setDeleteMessagesForAllUsers(c,!1),y(c)},ka=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return y(e),h.acceptContactRequest(a,b).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),y(b)}).then(function(){f.publish(i.CONTACT_ADDED,q.members[a]),f.publish(i.CONTACT_REQUEST_ACCEPTED,d)})},la=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return y(e),h.declineContactRequest(a,b).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),y(b)}).then(function(){f.publish(i.CONTACT_REQUEST_DECLINED,d)})},ma=function(a,b){x=!0;var c=m.setSendingMessage(q,!0),d=null;y(c);var g=null,j=null;if(a||q.type==E.PUBLIC)g=h.sendMessageToConversation(a,b);else{var k=F();g=h.sendMessageToUser(k,b).then(function(a){return d=parseInt(a.conversationid,10),j=a.candeletemessagesforallusers,a})}g.then(function(a){var b=m.addMessages(q,[a]);b=m.setSendingMessage(b,!1);var c=N(b);b.id||(b=m.setId(b,d),c.id=d,Da(d),f.publish(i.CONVERSATION_CREATED,c),b=m.setCanDeleteMessagesForAllUsers(b,j)),y(b),x=!1,f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c)})["catch"](function(a){x=!1;var b=m.setSendingMessage(q,!1);y(b),e.exception(a)})},na=function(a){var b=q;b=q.selectedMessageIds.indexOf(a)>-1?m.removeSelectedMessagesById(q,[a]):m.addSelectedMessagesById(q,[a]),y(b)},oa=function(){ja(F());var a=m.removeSelectedMessagesById(q,q.selectedMessageIds);y(a)},pa=function(b,c,d){if(!u&&v.length){u=!0;var f=v.shift(),g=z.map(function(a){return a(f.patch)});a.when.apply(null,g).then(function(){u=!1,f.deferred.resolve(!0),pa(b,c,d)})["catch"](function(a){u=!1,f.deferred.reject(a),e.exception(a)})}},qa=function(b,c,d,e){var f=function(a){return l.render(b,c,d,a)};if(!e){var g=m.buildInitialState(q.midnight,q.loggedInUserId,q.id),h=k.buildPatch(g,q);f(h)}return z.push(f),function(e){var f=k.buildPatch(q,e),g=a.Deferred();return Object.keys(f).length?v.push({patch:f,deferred:g}):g.resolve(!0),q=e,e.id&&(p[e.id]={state:e,messagesOffset:I(),loadedAllMessages:K()}),pa(b,c,d),g.promise()}},ra=function(a){return function(b,c){if(!q.loadingConfirmAction){a(F());var d=m.setLoadingConfirmAction(q,!1);y(d)}c.originalEvent.preventDefault()}},sa=function(b,c){var d=a(b.target),e=d.closest(D.FOOTER_CONTAINER),f=e.find(D.MESSAGE_TEXT_AREA),g=f.val().trim();""!==g&&ma(q.id,g),c.originalEvent.preventDefault()},ta=function(b,c){var d=window.getSelection(),e=a(b.target);if(""==d.toString()&&!e.is("a")){var f=e.closest(D.MESSAGE),g=parseInt(f.attr("data-message-id"),10);na(g),c.originalEvent.preventDefault()}},ua=function(a,b){oa(),b.originalEvent.preventDefault()},va=function(a){return function(b,c){var d=F(),e=q.members[d];n.go(a,o.VIEW_CONTACT,e),c.originalEvent.preventDefault()}},wa=function(a,b){ba()["catch"](e.exception),b.originalEvent.preventDefault()},xa=function(a,b){ca()["catch"](e.exception),b.originalEvent.preventDefault()},ya=function(a,b){da()["catch"](e.exception),b.originalEvent.preventDefault()},za=function(a,b){ea()["catch"](e.exception),b.originalEvent.preventDefault()},Aa=function(b){var c=a(b.target).prop("checked"),d=m.setDeleteMessagesForAllUsers(q,c);y(d)},Ba=function(a){return function(b,c){n.go(a,o.VIEW_GROUP_INFO,{id:q.id,name:q.name,subname:q.subname,imageUrl:q.imageUrl,totalMemberCount:q.totalMemberCount},q.loggedInUserId),c.originalEvent.preventDefault()}},Ca=function(a,c,g,h){var j=!1,k=M(g),l=[[D.ACTION_REQUEST_BLOCK,ra(V)],[D.ACTION_REQUEST_UNBLOCK,ra(X)],[D.ACTION_REQUEST_ADD_CONTACT,ra(_)],[D.ACTION_REQUEST_REMOVE_CONTACT,ra(Z)],[D.ACTION_REQUEST_DELETE_CONVERSATION,ra(ha)],[D.ACTION_CANCEL_EDIT_MODE,ua],[D.ACTION_VIEW_CONTACT,va(a)],[D.ACTION_VIEW_GROUP_INFO,Ba(a)],[D.ACTION_CONFIRM_FAVOURITE,wa],[D.ACTION_CONFIRM_MUTE,ya],[D.ACTION_CONFIRM_UNFAVOURITE,xa],[D.ACTION_CONFIRM_UNMUTE,za]],n=[[D.ACTION_CANCEL_CONFIRM,ra(ja)],[D.ACTION_CONFIRM_BLOCK,ra(W)],[D.ACTION_CONFIRM_UNBLOCK,ra(Y)],[D.ACTION_CONFIRM_ADD_CONTACT,ra(aa)],[D.ACTION_CONFIRM_REMOVE_CONTACT,ra($)],[D.ACTION_CONFIRM_DELETE_SELECTED_MESSAGES,ra(ga)],[D.ACTION_CONFIRM_DELETE_CONVERSATION,ra(ia)],[D.ACTION_REQUEST_ADD_CONTACT,ra(_)],[D.ACTION_ACCEPT_CONTACT_REQUEST,ra(ka)],[D.ACTION_DECLINE_CONTACT_REQUEST,ra(la)],[D.MESSAGE,ta],[D.DELETE_MESSAGES_FOR_ALL_USERS_TOGGLE,Aa]],p=[[D.SEND_MESSAGE_BUTTON,sa],[D.ACTION_REQUEST_DELETE_SELECTED_MESSAGES,ra(fa)],[D.ACTION_REQUEST_ADD_CONTACT,ra(_)],[D.ACTION_REQUEST_UNBLOCK,ra(X)]];b.init(h),d.define(c,[d.events.activate]),d.define(g,[d.events.activate]),d.define(h,[d.events.activate,d.events.enter]),d.define(k,[d.events.scrollTop,d.events.scrollLock]),k.on(d.events.scrollTop,function(a,b){var c=Object.keys(q.members).length>1;if(!w&&!j&&!K()&&c){j=!0;var d=m.setLoadingMessages(q,!0);y(d),S(q.id,B,I(),A,[]).then(function(){j=!1,J(I()+B)})["catch"](function(a){j=!1,e.exception(a)})}b.originalEvent.preventDefault()}),l.forEach(function(a){var b=a[0],e=a[1];c.on(d.events.activate,b,e)}),n.forEach(function(a){var b=a[0],c=a[1];g.on(d.events.activate,b,c)}),p.forEach(function(a){var b=a[0],c=a[1];h.on(d.events.activate,b,c)}),h.on(d.events.enter,D.MESSAGE_TEXT_AREA,function(a,b){var c=h.attr("data-enter-to-send");c&&"false"!=c&&"0"!=c&&sa(a,b)}),f.subscribe(i.ROUTE_CHANGED,function(a){t&&a.route!=o.VIEW_CONVERSATION&&t.stop()})},Da=function(a){t&&t.stop(),t=new c(T(a,A),function(a){return a?2*a:C}),t.start()},Ea=function(a,b,c){w=!0,u=!1,v=[],x=!1;var d=c.id,e=parseInt(a.attr("data-midnight"),10),f=m.buildInitialState(e,d,b);q||(q=f),t&&t.stop(),y(f)},Fa=function(a,b,c){Ea(a,null,b);var d=null;return d=b.id!=c?h.getConversationBetweenUsers(b.id,c,!0,!0,0,0,B,0,A):h.getSelfConversation(b.id,B,0,A),d.then(function(c){return Ha(a,c,b)})["catch"](function(){return O(b,c)})},Ga=function(b,c,d){var e=null;c in p&&(e=p[c]),Ea(b,c,d);var f=a.Deferred().resolve({}).promise();if(e){var g=e.state;g=m.setLoadingMessages(g,!1),g=m.setLoadingMembers(g,!1),J(e.messagesOffset),L(e.loadedAllMessages),y(g)}else f=Q(c,d,B,0,A);return f.then(function(){return Da(c)})},Ha=function(b,c,d){var e=null;c.id in p&&(e=p[c.id]),Ea(b,c.id,d);var f=a.Deferred().resolve({}).promise();if(e){var g=e.state;g=m.setLoadingMessages(g,!1),g=m.setLoadingMembers(g,!1),J(e.messagesOffset),L(e.loadedAllMessages),y(g)}else f=R(c,d,B,A);return f.then(function(){return Da(c.id)})},Ia=function(b,c,d,f,g,h,i){var k=null,l=null;g&&null!==g&&"object"==typeof g?(k=g,l=parseInt(k.id,10)):(k=null,l=parseInt(g,10),l=isNaN(l)?null:l),!l&&h&&i&&(l=G(i));var m=!q||q.id!=l||i&&i!=F();if(d.attr("data-init")||(y=qa(c,d,f,m),Ca(b,c,d,f),d.attr("data-init",!0)),m){var n=null,o=H(d);return n=k?Ha(d,k,o,i):l?Ga(d,l,o,i):Fa(d,o,i),n.then(function(){w=!1,c.find(j.SELECTORS.CAN_RECEIVE_FOCUS).first().focus()})["catch"](function(a){w=!1,e.exception(a)})}if(Da(l),q.type==E.PRIVATE&&h){var p=F();switch(h){case"block":return V(p);case"unblock":return X(p);case"add-contact":return _(p);case"remove-contact":return Z(p)}}return a.Deferred().resolve().promise()},Ja=function(){return g.get_string("messagedrawerviewconversation","core_message",q.name)};return{show:Ia,description:Ja}}); \ No newline at end of file diff --git a/message/amd/src/message_drawer_view_conversation.js b/message/amd/src/message_drawer_view_conversation.js index e2ca7e58647f8..4c98b0583f7eb 100644 --- a/message/amd/src/message_drawer_view_conversation.js +++ b/message/amd/src/message_drawer_view_conversation.js @@ -97,11 +97,13 @@ function( var loadedAllMessages = false; var messagesOffset = 0; var newMessagesPollTimer = null; + var isRendering = false; + var renderBuffer = []; // If the UI is currently resetting. var isResetting = true; // If the UI is currently sending a message. var isSendingMessage = false; - // This is the render function which will be generated when this module is + // These functions which will be generated when this module is // first called. See generateRenderFunction for details. var render = null; // The list of renderers that have been registered to render @@ -279,10 +281,9 @@ function( var conversationType = loggedInUserId == otherUserId ? CONVERSATION_TYPES.SELF : CONVERSATION_TYPES.PRIVATE; var newState = StateManager.setLoadingMembers(viewState, true); newState = StateManager.setLoadingMessages(newState, true); - return render(newState) - .then(function() { - return Repository.getMemberInfo(loggedInUserId, [otherUserId], true, true); - }) + render(newState); + + return Repository.getMemberInfo(loggedInUserId, [otherUserId], true, true) .then(function(profiles) { if (profiles.length) { return profiles[0]; @@ -301,10 +302,8 @@ function( newState = StateManager.setType(newState, conversationType); newState = StateManager.setImageUrl(newState, profile.profileimageurl); newState = StateManager.setTotalMemberCount(newState, members.length); - return render(newState) - .then(function() { - return profile; - }); + render(newState); + return profile; }) .catch(function(error) { var newState = StateManager.setLoadingMembers(viewState, false); @@ -374,20 +373,19 @@ function( var loggedInUserId = loggedInUserProfile.id; var newState = StateManager.setLoadingMembers(viewState, true); newState = StateManager.setLoadingMessages(newState, true); - return render(newState) - .then(function() { - return Repository.getConversation( - loggedInUserId, - conversationId, - true, - true, - 0, - 0, - messageLimit + 1, - messageOffset, - newestFirst - ); - }) + render(newState); + + return Repository.getConversation( + loggedInUserId, + conversationId, + true, + true, + 0, + 0, + messageLimit + 1, + messageOffset, + newestFirst + ) .then(function(conversation) { if (conversation.messages.length > messageLimit) { conversation.messages = conversation.messages.slice(1); @@ -450,37 +448,30 @@ function( conversation.members = conversation.members.concat([loggedInUserProfile]); } + var messageCount = conversation.messages.length; + var hasLoadedEnoughMessages = messageCount >= messageLimit; var newState = updateStateFromConversation(conversation, loggedInUserProfile.id); newState = StateManager.setLoadingMembers(newState, false); - newState = StateManager.setLoadingMessages(newState, true); - var messageCount = conversation.messages.length; - return render(newState) - .then(function() { - if (messageCount < messageLimit) { + newState = StateManager.setLoadingMessages(newState, !hasLoadedEnoughMessages); + var renderPromise = render(newState); + + return renderPromise.then(function() { + if (!hasLoadedEnoughMessages) { // We haven't got enough messages so let's load some more. - return loadMessages(conversation.id, messageLimit, messageCount, newestFirst, []) - .then(function(result) { - // Give the list of messages to the next handler. - return result.messages; - }); + return loadMessages(conversation.id, messageLimit, messageCount, newestFirst, []); } else { // We've got enough messages. No need to load any more for now. - var newState = StateManager.setLoadingMessages(viewState, false); - return render(newState) - .then(function() { - // Give the list of messages to the next handler. - return conversation.messages; - }); + return {messages: conversation.messages}; } }) - .then(function(messages) { + .then(function() { + var messages = viewState.messages; // Update the offset to reflect the number of messages we've loaded. setMessagesOffset(messages.length); + markConversationAsRead(viewState.id); + return messages; }) - .then(function() { - return markConversationAsRead(conversation.id); - }) .catch(Notification.exception); }; @@ -627,14 +618,12 @@ function( * Tell the statemanager there is request to block a user and run the renderer * to show the block user dialogue. * - * @param {Number} userId User id. - * @return {Promise} Renderer promise. + * @param {Number} userId User id. */ var requestBlockUser = function(userId) { - return cancelRequest(userId).then(function() { - var newState = StateManager.addPendingBlockUsersById(viewState, [userId]); - return render(newState); - }); + cancelRequest(userId); + var newState = StateManager.addPendingBlockUsersById(viewState, [userId]); + render(newState); }; /** @@ -646,10 +635,9 @@ function( */ var blockUser = function(userId) { var newState = StateManager.setLoadingConfirmAction(viewState, true); - return render(newState) - .then(function() { - return Repository.blockUser(viewState.loggedInUserId, userId); - }) + render(newState); + + return Repository.blockUser(viewState.loggedInUserId, userId) .then(function(profile) { var newState = StateManager.addMembers(viewState, [profile]); newState = StateManager.removePendingBlockUsersById(newState, [userId]); @@ -663,14 +651,12 @@ function( * Tell the statemanager there is a request to unblock a user and run the renderer * to show the unblock user dialogue. * - * @param {Number} userId User id of user to unblock. - * @return {Promise} Renderer promise. + * @param {Number} userId User id of user to unblock. */ var requestUnblockUser = function(userId) { - return cancelRequest(userId).then(function() { - var newState = StateManager.addPendingUnblockUsersById(viewState, [userId]); - return render(newState); - }); + cancelRequest(userId); + var newState = StateManager.addPendingUnblockUsersById(viewState, [userId]); + render(newState); }; /** @@ -682,10 +668,9 @@ function( */ var unblockUser = function(userId) { var newState = StateManager.setLoadingConfirmAction(viewState, true); - return render(newState) - .then(function() { - return Repository.unblockUser(viewState.loggedInUserId, userId); - }) + render(newState); + + return Repository.unblockUser(viewState.loggedInUserId, userId) .then(function(profile) { var newState = StateManager.addMembers(viewState, [profile]); newState = StateManager.removePendingUnblockUsersById(newState, [userId]); @@ -699,14 +684,12 @@ function( * Tell the statemanager there is a request to remove a user from the contact list * and run the renderer to show the remove user from contacts dialogue. * - * @param {Number} userId User id of user to remove from contacts. - * @return {Promise} Renderer promise. + * @param {Number} userId User id of user to remove from contacts. */ var requestRemoveContact = function(userId) { - return cancelRequest(userId).then(function() { - var newState = StateManager.addPendingRemoveContactsById(viewState, [userId]); - return render(newState); - }); + cancelRequest(userId); + var newState = StateManager.addPendingRemoveContactsById(viewState, [userId]); + render(newState); }; /** @@ -718,10 +701,9 @@ function( */ var removeContact = function(userId) { var newState = StateManager.setLoadingConfirmAction(viewState, true); - return render(newState) - .then(function() { - return Repository.deleteContacts(viewState.loggedInUserId, [userId]); - }) + render(newState); + + return Repository.deleteContacts(viewState.loggedInUserId, [userId]) .then(function(profiles) { var newState = StateManager.addMembers(viewState, profiles); newState = StateManager.removePendingRemoveContactsById(newState, [userId]); @@ -735,14 +717,12 @@ function( * Tell the statemanager there is a request to add a user to the contact list * and run the renderer to show the add user to contacts dialogue. * - * @param {Number} userId User id of user to add to contacts. - * @return {Promise} Renderer promise. + * @param {Number} userId User id of user to add to contacts. */ var requestAddContact = function(userId) { - return cancelRequest(userId).then(function() { - var newState = StateManager.addPendingAddContactsById(viewState, [userId]); - return render(newState); - }); + cancelRequest(userId); + var newState = StateManager.addPendingAddContactsById(viewState, [userId]); + render(newState); }; /** @@ -754,10 +734,9 @@ function( */ var addContact = function(userId) { var newState = StateManager.setLoadingConfirmAction(viewState, true); - return render(newState) - .then(function() { - return Repository.createContactRequest(viewState.loggedInUserId, userId); - }) + render(newState); + + return Repository.createContactRequest(viewState.loggedInUserId, userId) .then(function(response) { if (!response.request) { throw new Error(response.warnings[0].message); @@ -865,15 +844,13 @@ function( * Tell the statemanager there is a request to delete the selected messages * and run the renderer to show confirm delete messages dialogue. * - * @param {Number} userId User id. - * @return {Promise} Renderer promise. + * @param {Number} userId User id. */ var requestDeleteSelectedMessages = function(userId) { var selectedMessageIds = viewState.selectedMessageIds; - return cancelRequest(userId).then(function() { - var newState = StateManager.addPendingDeleteMessagesById(viewState, selectedMessageIds); - return render(newState); - }); + cancelRequest(userId); + var newState = StateManager.addPendingDeleteMessagesById(viewState, selectedMessageIds); + render(newState); }; /** @@ -885,15 +862,18 @@ function( var deleteSelectedMessages = function() { var messageIds = viewState.pendingDeleteMessageIds; var newState = StateManager.setLoadingConfirmAction(viewState, true); - return render(newState) - .then(function() { - if (newState.deleteMessagesForAllUsers) { - return Repository.deleteMessagesForAllUsers(viewState.loggedInUserId, messageIds); - } - return Repository.deleteMessages(viewState.loggedInUserId, messageIds); - }) - .then(function() { + render(newState); + + var deleteMessagesPromise = null; + + if (newState.deleteMessagesForAllUsers) { + deleteMessagesPromise = Repository.deleteMessagesForAllUsers(viewState.loggedInUserId, messageIds); + } else { + deleteMessagesPromise = Repository.deleteMessages(viewState.loggedInUserId, messageIds); + } + + return deleteMessagesPromise.then(function() { var newState = StateManager.removeMessagesById(viewState, messageIds); newState = StateManager.removePendingDeleteMessagesById(newState, messageIds); newState = StateManager.removeSelectedMessagesById(newState, messageIds); @@ -918,14 +898,12 @@ function( * Tell the statemanager there is a request to delete a conversation * and run the renderer to show confirm delete conversation dialogue. * - * @param {Number} userId User id of other user. - * @return {Promise} Renderer promise. + * @param {Number} userId User id of other user. */ var requestDeleteConversation = function(userId) { - return cancelRequest(userId).then(function() { - var newState = StateManager.setPendingDeleteConversation(viewState, true); - return render(newState); - }); + cancelRequest(userId); + var newState = StateManager.setPendingDeleteConversation(viewState, true); + render(newState); }; /** @@ -936,10 +914,9 @@ function( */ var deleteConversation = function() { var newState = StateManager.setLoadingConfirmAction(viewState, true); - return render(newState) - .then(function() { - return Repository.deleteConversation(viewState.loggedInUserId, viewState.id); - }) + render(newState); + + return Repository.deleteConversation(viewState.loggedInUserId, viewState.id) .then(function() { var newState = StateManager.removeMessages(viewState, viewState.messages); newState = StateManager.removeSelectedMessagesById(newState, viewState.selectedMessageIds); @@ -955,7 +932,6 @@ function( * Tell the statemanager to cancel all pending actions. * * @param {Number} userId User id. - * @return {Promise} Renderer promise. */ var cancelRequest = function(userId) { var pendingDeleteMessageIds = viewState.pendingDeleteMessageIds; @@ -966,7 +942,7 @@ function( newState = StateManager.removePendingDeleteMessagesById(newState, pendingDeleteMessageIds); newState = StateManager.setPendingDeleteConversation(newState, false); newState = StateManager.setDeleteMessagesForAllUsers(newState, false); - return render(newState); + render(newState); }; /** @@ -984,10 +960,9 @@ function( }); var request = requests[0]; var newState = StateManager.setLoadingConfirmAction(viewState, true); - return render(newState) - .then(function() { - return Repository.acceptContactRequest(userId, loggedInUserId); - }) + render(newState); + + return Repository.acceptContactRequest(userId, loggedInUserId) .then(function(profile) { var newState = StateManager.removeContactRequests(viewState, [request]); newState = StateManager.addMembers(viewState, [profile]); @@ -1016,10 +991,9 @@ function( }); var request = requests[0]; var newState = StateManager.setLoadingConfirmAction(viewState, true); - return render(newState) - .then(function() { - return Repository.declineContactRequest(userId, loggedInUserId); - }) + render(newState); + + return Repository.declineContactRequest(userId, loggedInUserId) .then(function(profile) { var newState = StateManager.removeContactRequests(viewState, [request]); newState = StateManager.addMembers(viewState, [profile]); @@ -1044,24 +1018,26 @@ function( isSendingMessage = true; var newState = StateManager.setSendingMessage(viewState, true); var newConversationId = null; - var newCanDeleteMessagesForAllUsers = false; - return render(newState) - .then(function() { - if (!conversationId && (viewState.type != CONVERSATION_TYPES.PUBLIC)) { - // If it's a new private conversation then we need to use the old - // web service function to create the conversation. - var otherUserId = getOtherUserId(); - return Repository.sendMessageToUser(otherUserId, text) - .then(function(message) { - newConversationId = parseInt(message.conversationid, 10); - newCanDeleteMessagesForAllUsers = message.candeletemessagesforallusers; - return message; - }); - } else { - return Repository.sendMessageToConversation(conversationId, text); - } - }) - .then(function(message) { + + render(newState); + + var sendMessagePromise = null; + var newCanDeleteMessagesForAllUsers = null; + if (!conversationId && (viewState.type != CONVERSATION_TYPES.PUBLIC)) { + // If it's a new private conversation then we need to use the old + // web service function to create the conversation. + var otherUserId = getOtherUserId(); + sendMessagePromise = Repository.sendMessageToUser(otherUserId, text) + .then(function(message) { + newConversationId = parseInt(message.conversationid, 10); + newCanDeleteMessagesForAllUsers = message.candeletemessagesforallusers; + return message; + }); + } else { + sendMessagePromise = Repository.sendMessageToConversation(conversationId, text); + } + + sendMessagePromise.then(function(message) { var newState = StateManager.addMessages(viewState, [message]); newState = StateManager.setSendingMessage(newState, false); var conversation = formatConversationForEvent(newState); @@ -1076,12 +1052,10 @@ function( newState = StateManager.setCanDeleteMessagesForAllUsers(newState, newCanDeleteMessagesForAllUsers); } - return render(newState) - .then(function() { - isSendingMessage = false; - PubSub.publish(MessageDrawerEvents.CONVERSATION_NEW_LAST_MESSAGE, conversation); - return; - }); + render(newState); + isSendingMessage = false; + PubSub.publish(MessageDrawerEvents.CONVERSATION_NEW_LAST_MESSAGE, conversation); + return; }) .catch(function(error) { isSendingMessage = false; @@ -1095,7 +1069,6 @@ function( * Toggle the selected messages update the statemanager and render the result. * * @param {Number} messageId The id of the message to be toggled - * @return {Promise} Renderer promise. */ var toggleSelectMessage = function(messageId) { var newState = viewState; @@ -1106,7 +1079,7 @@ function( newState = StateManager.addSelectedMessagesById(viewState, [messageId]); } - return render(newState); + render(newState); }; /** @@ -1115,10 +1088,45 @@ function( * @return {Promise} Renderer promise. */ var cancelEditMode = function() { - return cancelRequest(getOtherUserId()) + cancelRequest(getOtherUserId()); + var newState = StateManager.removeSelectedMessagesById(viewState, viewState.selectedMessageIds); + render(newState); + }; + + /** + * Process the patches in the render buffer one at a time in order until the + * buffer is empty. + * + * @param {Object} header The conversation header container element. + * @param {Object} body The conversation body container element. + * @param {Object} footer The conversation footer container element. + */ + var processRenderBuffer = function(header, body, footer) { + if (isRendering) { + return; + } + + if (!renderBuffer.length) { + return; + } + + isRendering = true; + var renderable = renderBuffer.shift(); + var renderPromises = renderers.map(function(renderFunc) { + return renderFunc(renderable.patch); + }); + + $.when.apply(null, renderPromises) .then(function() { - var newState = StateManager.removeSelectedMessagesById(viewState, viewState.selectedMessageIds); - return render(newState); + isRendering = false; + renderable.deferred.resolve(true); + // Keep processing the buffer until it's empty. + processRenderBuffer(header, body, footer); + }) + .catch(function(error) { + isRendering = false; + renderable.deferred.reject(error); + Notification.exception(error); }); }; @@ -1148,25 +1156,39 @@ function( return function(newState) { var patch = Patcher.buildPatch(viewState, newState); + var deferred = $.Deferred(); + + // Check if the patch has any data. Ignore empty patches. + if (Object.keys(patch).length) { + // Add the patch to the render buffer which gets processed in order. + renderBuffer.push({ + patch: patch, + deferred: deferred + }); + } else { + deferred.resolve(true); + } // This is a great place to add in some console logging if you need // to debug something. You can log the current state, the next state, // and the generated patch and see exactly what will be updated. - var renderPromises = renderers.map(function(renderFunc) { - return renderFunc(patch); - }); - return $.when.apply(null, renderPromises) - .then(function() { - viewState = newState; - if (newState.id) { - // Only cache created conversations. - stateCache[newState.id] = { - state: newState, - messagesOffset: getMessagesOffset(), - loadedAllMessages: hasLoadedAllMessages() - }; - } - return; - }); + + // Optimistically update the state. We're going to assume that the rendering + // will always succeed. The rendering is asynchronous (annoyingly) so it's buffered + // but it'll reach eventual consistency with the current state. + viewState = newState; + if (newState.id) { + // Only cache created conversations. + stateCache[newState.id] = { + state: newState, + messagesOffset: getMessagesOffset(), + loadedAllMessages: hasLoadedAllMessages() + }; + } + + // Start processing the buffer. + processRenderBuffer(header, body, footer); + + return deferred.promise(); }; }; @@ -1179,12 +1201,9 @@ function( var generateConfirmActionHandler = function(actionCallback) { return function(e, data) { if (!viewState.loadingConfirmAction) { - actionCallback(getOtherUserId()) - .catch(function(error) { - var newState = StateManager.setLoadingConfirmAction(viewState, false); - render(newState); - Notification.exception(error); - }); + actionCallback(getOtherUserId()); + var newState = StateManager.setLoadingConfirmAction(viewState, false); + render(newState); } data.originalEvent.preventDefault(); }; @@ -1232,7 +1251,7 @@ function( var element = target.closest(SELECTORS.MESSAGE); var messageId = parseInt(element.attr('data-message-id'), 10); - toggleSelectMessage(messageId).catch(Notification.exception); + toggleSelectMessage(messageId); data.originalEvent.preventDefault(); }; @@ -1244,7 +1263,7 @@ function( * @param {Object} data Data for this event. */ var handleCancelEditMode = function(e, data) { - cancelEditMode().catch(Notification.exception); + cancelEditMode(); data.originalEvent.preventDefault(); }; @@ -1413,10 +1432,9 @@ function( if (!isResetting && !isLoadingMoreMessages && !hasLoadedAllMessages() && hasMembers) { isLoadingMoreMessages = true; var newState = StateManager.setLoadingMessages(viewState, true); - render(newState) - .then(function() { - return loadMessages(viewState.id, LOAD_MESSAGE_LIMIT, getMessagesOffset(), NEWEST_FIRST, []); - }) + render(newState); + + loadMessages(viewState.id, LOAD_MESSAGE_LIMIT, getMessagesOffset(), NEWEST_FIRST, []) .then(function() { isLoadingMoreMessages = false; setMessagesOffset(getMessagesOffset() + LOAD_MESSAGE_LIMIT); @@ -1495,9 +1513,15 @@ function( * @param {Object} body Conversation body container element. * @param {Number|null} conversationId The conversation id. * @param {Object} loggedInUserProfile The logged in user's profile. - * @return {Promise} Renderer promise. */ var resetState = function(body, conversationId, loggedInUserProfile) { + // Reset all of the states back to the beginning if we're loading a new + // conversation. + isResetting = true; + isRendering = false; + renderBuffer = []; + isSendingMessage = false; + var loggedInUserId = loggedInUserProfile.id; var midnight = parseInt(body.attr('data-midnight'), 10); var initialState = StateManager.buildInitialState(midnight, loggedInUserId, conversationId); @@ -1510,7 +1534,7 @@ function( newMessagesPollTimer.stop(); } - return render(initialState); + render(initialState); }; /** @@ -1524,32 +1548,34 @@ function( var resetNoConversation = function(body, loggedInUserProfile, otherUserId) { // Always reset the state back to the initial state so that the // state manager and patcher can work correctly. - return resetState(body, null, loggedInUserProfile) - .then(function() { - if (loggedInUserProfile.id != otherUserId) { - // Private conversation between two different users. - return Repository.getConversationBetweenUsers( - loggedInUserProfile.id, - otherUserId, - true, - true, - 0, - 0, - LOAD_MESSAGE_LIMIT, - 0, - NEWEST_FIRST - ); - } else { - // Self conversation. - return Repository.getSelfConversation( - loggedInUserProfile.id, - LOAD_MESSAGE_LIMIT, - 0, - NEWEST_FIRST - ); - } - }) - .then(function(conversation) { + resetState(body, null, loggedInUserProfile); + + var resetNoConversationPromise = null; + + if (loggedInUserProfile.id != otherUserId) { + // Private conversation between two different users. + resetNoConversationPromise = Repository.getConversationBetweenUsers( + loggedInUserProfile.id, + otherUserId, + true, + true, + 0, + 0, + LOAD_MESSAGE_LIMIT, + 0, + NEWEST_FIRST + ); + } else { + // Self conversation. + resetNoConversationPromise = Repository.getSelfConversation( + loggedInUserProfile.id, + LOAD_MESSAGE_LIMIT, + 0, + NEWEST_FIRST + ); + } + + return resetNoConversationPromise.then(function(conversation) { // Looks like we have a conversation after all! Let's use that. return resetByConversation(body, conversation, loggedInUserProfile); }) @@ -1575,31 +1601,32 @@ function( // Always reset the state back to the initial state so that the // state manager and patcher can work correctly. - return resetState(body, conversationId, loggedInUserProfile) - .then(function() { - if (cache) { - // We've seen this conversation before so there is no need to - // send any network requests. - var newState = cache.state; - // Reset some loading states just in case they were left weirdly. - newState = StateManager.setLoadingMessages(newState, false); - newState = StateManager.setLoadingMembers(newState, false); - setMessagesOffset(cache.messagesOffset); - setLoadedAllMessages(cache.loadedAllMessages); - return render(newState); - } else { - return loadNewConversation( - conversationId, - loggedInUserProfile, - LOAD_MESSAGE_LIMIT, - 0, - NEWEST_FIRST - ); - } - }) - .then(function() { - return resetMessagePollTimer(conversationId); - }); + resetState(body, conversationId, loggedInUserProfile); + + var promise = $.Deferred().resolve({}).promise(); + if (cache) { + // We've seen this conversation before so there is no need to + // send any network requests. + var newState = cache.state; + // Reset some loading states just in case they were left weirdly. + newState = StateManager.setLoadingMessages(newState, false); + newState = StateManager.setLoadingMembers(newState, false); + setMessagesOffset(cache.messagesOffset); + setLoadedAllMessages(cache.loadedAllMessages); + render(newState); + } else { + promise = loadNewConversation( + conversationId, + loggedInUserProfile, + LOAD_MESSAGE_LIMIT, + 0, + NEWEST_FIRST + ); + } + + return promise.then(function() { + return resetMessagePollTimer(conversationId); + }); }; /** @@ -1618,30 +1645,31 @@ function( // Always reset the state back to the initial state so that the // state manager and patcher can work correctly. - return resetState(body, conversation.id, loggedInUserProfile) - .then(function() { - if (cache) { - // We've seen this conversation before so there is no need to - // send any network requests. - var newState = cache.state; - // Reset some loading states just in case they were left weirdly. - newState = StateManager.setLoadingMessages(newState, false); - newState = StateManager.setLoadingMembers(newState, false); - setMessagesOffset(cache.messagesOffset); - setLoadedAllMessages(cache.loadedAllMessages); - return render(newState); - } else { - return loadExistingConversation( - conversation, - loggedInUserProfile, - LOAD_MESSAGE_LIMIT, - NEWEST_FIRST - ); - } - }) - .then(function() { - return resetMessagePollTimer(conversation.id); - }); + resetState(body, conversation.id, loggedInUserProfile); + + var promise = $.Deferred().resolve({}).promise(); + if (cache) { + // We've seen this conversation before so there is no need to + // send any network requests. + var newState = cache.state; + // Reset some loading states just in case they were left weirdly. + newState = StateManager.setLoadingMessages(newState, false); + newState = StateManager.setLoadingMembers(newState, false); + setMessagesOffset(cache.messagesOffset); + setLoadedAllMessages(cache.loadedAllMessages); + render(newState); + } else { + promise = loadExistingConversation( + conversation, + loggedInUserProfile, + LOAD_MESSAGE_LIMIT, + NEWEST_FIRST + ); + } + + return promise.then(function() { + return resetMessagePollTimer(conversation.id); + }); }; /** @@ -1702,9 +1730,6 @@ function( } if (isNewConversation) { - // Reset all of the states back to the beginning if we're loading a new - // conversation. - isResetting = true; var renderPromise = null; var loggedInUserProfile = getLoggedInUserProfile(body); if (conversation) { From a3824e559b772147c16c3a9b34fdd720fc252c71 Mon Sep 17 00:00:00 2001 From: Amaia Anabitarte Date: Mon, 20 May 2019 15:38:54 +0200 Subject: [PATCH 023/786] MDL-65060 core_message: Group_message_message_content selector --- lib/behat/classes/partial_named_selector.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/behat/classes/partial_named_selector.php b/lib/behat/classes/partial_named_selector.php index b9233ef347467..b632895b649ce 100644 --- a/lib/behat/classes/partial_named_selector.php +++ b/lib/behat/classes/partial_named_selector.php @@ -95,6 +95,7 @@ public function __construct() { 'group_message_member' => 'group_message_member', 'group_message_tab' => 'group_message_tab', 'group_message_list_area' => 'group_message_list_area', + 'group_message_message_content' => 'group_message_message_content', 'icon' => 'icon', 'link' => 'link', 'link_or_button' => 'link_or_button', @@ -174,6 +175,9 @@ public function __construct() { XPATH , 'group_message_list_area' => << << << Date: Tue, 21 May 2019 09:59:39 +0800 Subject: [PATCH 024/786] MDL-59650 core_calendar: remove limit from event exporter --- calendar/classes/local/event/data_access/event_vault.php | 9 +++++---- calendar/export_execute.php | 4 ++-- calendar/lib.php | 6 ++++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/calendar/classes/local/event/data_access/event_vault.php b/calendar/classes/local/event/data_access/event_vault.php index 3d592088d58b1..8a8c20d2f3bb7 100644 --- a/calendar/classes/local/event/data_access/event_vault.php +++ b/calendar/classes/local/event/data_access/event_vault.php @@ -100,9 +100,6 @@ public function get_events( $ignorehidden = true, callable $filter = null ) { - if ($limitnum < 1 || $limitnum > 200) { - throw new limit_invalid_parameter_exception("Limit must be between 1 and 200 (inclusive)"); - } $fromquery = function($field, $timefrom, $lastseenmethod, $afterevent, $withduration) { if (!$timefrom) { @@ -186,7 +183,11 @@ public function get_events( } } - $offset += $limitnum; + if (!$limitnum) { + break; + } else { + $offset += $limitnum; + } } return $events; diff --git a/calendar/export_execute.php b/calendar/export_execute.php index f87e439e632ff..17b55010e8e6a 100644 --- a/calendar/export_execute.php +++ b/calendar/export_execute.php @@ -186,9 +186,9 @@ die(); } } - +$limitnum = 0; $events = calendar_get_legacy_events($timestart, $timeend, $users, $groups, array_keys($paramcourses), false, true, - $paramcategory); + $paramcategory, $limitnum); $ical = new iCalendar; $ical->add_property('method', 'PUBLISH'); diff --git a/calendar/lib.php b/calendar/lib.php index 02c2d971392f5..8e634806a80a4 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -3237,10 +3237,12 @@ function core_calendar_user_preferences() { * or events in progress/already started selected as well * @param boolean $ignorehidden whether to select only visible events or all events * @param array $categories array of category ids and/or objects. + * @param int $limitnum Number of events to fetch or zero to fetch all. + * * @return array $events of selected events or an empty array if there aren't any (or there was an error) */ function calendar_get_legacy_events($tstart, $tend, $users, $groups, $courses, - $withduration = true, $ignorehidden = true, $categories = []) { + $withduration = true, $ignorehidden = true, $categories = [], $limitnum = 0) { // Normalise the users, groups and courses parameters so that they are compliant with \core_calendar\local\api::get_events(). // Existing functions that were using the old calendar_get_events() were passing a mixture of array, int, boolean for these // parameters, but with the new API method, only null and arrays are accepted. @@ -3277,7 +3279,7 @@ function calendar_get_legacy_events($tstart, $tend, $users, $groups, $courses, null, null, null, - 40, + $limitnum, null, $userparam, $groupparam, From f25a7d2ac78f468d218da8aaf06307a25a288196 Mon Sep 17 00:00:00 2001 From: Simey Lameze Date: Tue, 21 May 2019 10:46:47 +0800 Subject: [PATCH 025/786] MDL-59650 core_calendar: remove limit from calendar UI --- calendar/lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/calendar/lib.php b/calendar/lib.php index 8e634806a80a4..be383703c3edc 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -3316,7 +3316,7 @@ function calendar_get_view(\calendar_information $calendar, $view, $includenavig $calendardate = $type->timestamp_to_date_array($calendar->time); $date = new \DateTime('now', core_date::get_user_timezone_object(99)); - $eventlimit = 200; + $eventlimit = 0; if ($view === 'day') { $tstart = $type->convert_to_timestamp($calendardate['year'], $calendardate['mon'], $calendardate['mday']); From d2680dbb27610a7525e5932c67e274b78d3422e6 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Fri, 17 May 2019 15:18:06 +0100 Subject: [PATCH 026/786] MDL-55197 filter_multilang: move preg_callback fn into class --- filter/multilang/filter.php | 78 ++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/filter/multilang/filter.php b/filter/multilang/filter.php index 4cf90f7a90916..5dcd572ef0a58 100644 --- a/filter/multilang/filter.php +++ b/filter/multilang/filter.php @@ -38,6 +38,12 @@ // Following new syntax is not compatible with old one: // one langanother language + +/** + * @copyright Gaetan Frenoy + * @copyright 2004 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class filter_multilang extends moodle_text_filter { function filter($text, array $options = array()) { global $CFG; @@ -59,7 +65,7 @@ function filter($text, array $options = array()) { $search = '/(<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.*?<\/(?:lang|span)>)(\s*<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.*?<\/(?:lang|span)>)+/is'; } - $result = preg_replace_callback($search, 'filter_multilang_impl', $text); + $result = preg_replace_callback($search, [$this, 'process_match'], $text); if (is_null($result)) { return $text; //error during regex processing (too many nested spans?) @@ -67,44 +73,46 @@ function filter($text, array $options = array()) { return $result; } } -} - -function filter_multilang_impl($langblock) { - global $CFG; - $mylang = current_language(); - static $parentcache; - if (!isset($parentcache)) { - $parentcache = array(); - } - if (!array_key_exists($mylang, $parentcache)) { - $parentlang = get_parent_language($mylang); - $parentcache[$mylang] = $parentlang; - } else { - $parentlang = $parentcache[$mylang]; - } + /** + * This is the callback used by the preg_replace_callback call above. + * + * @param array $langblock one of the matches from the regex match. + * @return string the replacement string (one of the possible translations). + */ + protected function process_match(array $langblock): string { + $mylang = current_language(); + static $parentcache; + if (!isset($parentcache)) { + $parentcache = array(); + } + if (!array_key_exists($mylang, $parentcache)) { + $parentlang = get_parent_language($mylang); + $parentcache[$mylang] = $parentlang; + } else { + $parentlang = $parentcache[$mylang]; + } - $searchtosplit = '/<(?:lang|span)[^>]+lang="([a-zA-Z0-9_-]+)"[^>]*>(.*?)<\/(?:lang|span)>/is'; + $searchtosplit = '/<(?:lang|span)[^>]+lang="([a-zA-Z0-9_-]+)"[^>]*>(.*?)<\/(?:lang|span)>/is'; - if (!preg_match_all($searchtosplit, $langblock[0], $rawlanglist)) { - //skip malformed blocks - return $langblock[0]; - } + if (!preg_match_all($searchtosplit, $langblock[0], $rawlanglist)) { + //skip malformed blocks + return $langblock[0]; + } - $langlist = array(); - foreach ($rawlanglist[1] as $index=>$lang) { - $lang = str_replace('-','_',strtolower($lang)); // normalize languages - $langlist[$lang] = $rawlanglist[2][$index]; - } + $langlist = array(); + foreach ($rawlanglist[1] as $index=>$lang) { + $lang = str_replace('-','_',strtolower($lang)); // normalize languages + $langlist[$lang] = $rawlanglist[2][$index]; + } - if (array_key_exists($mylang, $langlist)) { - return $langlist[$mylang]; - } else if (array_key_exists($parentlang, $langlist)) { - return $langlist[$parentlang]; - } else { - $first = array_shift($langlist); - return $first; + if (array_key_exists($mylang, $langlist)) { + return $langlist[$mylang]; + } else if (array_key_exists($parentlang, $langlist)) { + return $langlist[$parentlang]; + } else { + $first = array_shift($langlist); + return $first; + } } } - - From a586240cc0aef05d8c81997588e599ddf2edebe0 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Fri, 17 May 2019 15:35:54 +0100 Subject: [PATCH 027/786] MDL-55197 filter_multilang: handle 'en' as parent lang better --- filter/multilang/filter.php | 60 ++++++++++++++++---------- filter/multilang/tests/filter_test.php | 5 +++ 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/filter/multilang/filter.php b/filter/multilang/filter.php index 5dcd572ef0a58..2e9bac35575ee 100644 --- a/filter/multilang/filter.php +++ b/filter/multilang/filter.php @@ -40,6 +40,8 @@ /** + * Implementation of the Moodle filter API for the Multi-lang filter. + * * @copyright Gaetan Frenoy * @copyright 2004 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later @@ -81,38 +83,52 @@ function filter($text, array $options = array()) { * @return string the replacement string (one of the possible translations). */ protected function process_match(array $langblock): string { - $mylang = current_language(); - static $parentcache; - if (!isset($parentcache)) { - $parentcache = array(); - } - if (!array_key_exists($mylang, $parentcache)) { - $parentlang = get_parent_language($mylang); - $parentcache[$mylang] = $parentlang; - } else { - $parentlang = $parentcache[$mylang]; - } - $searchtosplit = '/<(?:lang|span)[^>]+lang="([a-zA-Z0-9_-]+)"[^>]*>(.*?)<\/(?:lang|span)>/is'; if (!preg_match_all($searchtosplit, $langblock[0], $rawlanglist)) { - //skip malformed blocks + // Skip malformed blocks. return $langblock[0]; } $langlist = array(); - foreach ($rawlanglist[1] as $index=>$lang) { - $lang = str_replace('-','_',strtolower($lang)); // normalize languages + foreach ($rawlanglist[1] as $index => $lang) { + $lang = str_replace('-', '_', strtolower($lang)); // Normalize languages. $langlist[$lang] = $rawlanglist[2][$index]; } - if (array_key_exists($mylang, $langlist)) { - return $langlist[$mylang]; - } else if (array_key_exists($parentlang, $langlist)) { - return $langlist[$parentlang]; - } else { - $first = array_shift($langlist); - return $first; + // Follow the stream of parent languages. + $lang = current_language(); + do { + if (isset($langlist[$lang])) { + return $langlist[$lang]; + } + } while ($lang = $this->get_parent_lang($lang)); + + // If we don't find a match, default to the first provided translation. + return array_shift($langlist); + } + + /** + * Puts some caching around get_parent_language(). + * + * Also handle parent == 'en' in a way that works better for us. + * + * @param string $lang a Moodle language code, e.g. 'fr'. + * @return string the parent language. + */ + protected function get_parent_lang(string $lang): string { + static $parentcache; + if (!isset($parentcache)) { + $parentcache = ['en' => '']; + } + if (!isset($parentcache[$lang])) { + $parentcache[$lang] = get_parent_language($lang); + // The standard get_parent_language method returns '' for parent == 'en'. + // That is less helpful for us, so change it back. + if ($parentcache[$lang] === '') { + $parentcache[$lang] = 'en'; + } } + return $parentcache[$lang]; } } diff --git a/filter/multilang/tests/filter_test.php b/filter/multilang/tests/filter_test.php index 116dc50f02ae9..2dbefa2c8219b 100644 --- a/filter/multilang/tests/filter_test.php +++ b/filter/multilang/tests/filter_test.php @@ -116,6 +116,11 @@ public function multilang_testcases() { Québécois', 'fr', ['fr_ca' => 'fr'], ], + 'Fallback to parent when child not present when parent is en' => [ + 'English', + 'DeutschEnglish', + 'en_us', + ], ]; } From 7a2beab44e932f7b9cf5f8df944fb799a93624f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Mudr=C3=A1k?= Date: Thu, 23 May 2019 07:48:54 +0200 Subject: [PATCH 028/786] MDL-65694 grade: Fix missing gradelib library In the be8f453b74fbd3 the gradelib loading was removed by mistake. So the library may not be loaded and executing the task may end with the exception - class 'grade_grade' not found. --- lib/classes/task/grade_cron_task.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/classes/task/grade_cron_task.php b/lib/classes/task/grade_cron_task.php index bfb3777f6817c..60d9f8a22d2ff 100644 --- a/lib/classes/task/grade_cron_task.php +++ b/lib/classes/task/grade_cron_task.php @@ -43,6 +43,7 @@ public function get_name() { */ public function execute() { global $CFG, $DB; + require_once($CFG->libdir . '/gradelib.php'); $now = time(); $sql = "SELECT i.* From 9a88b8ec35dd42eb6f5466d817b0842913b59fed Mon Sep 17 00:00:00 2001 From: Adrian Greeve Date: Thu, 23 May 2019 14:06:59 +0800 Subject: [PATCH 029/786] MDL-65692 backup: Default settings set on install and upgrade. Asynchronous backup settings are now filled out with the defaults on installation and upgrade. --- admin/settings/courses.php | 48 +++++++++++++++++++---------------- admin/settings/subsystems.php | 3 --- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/admin/settings/courses.php b/admin/settings/courses.php index 99892d68dd990..ace90d3f05745 100644 --- a/admin/settings/courses.php +++ b/admin/settings/courses.php @@ -459,27 +459,31 @@ $ADMIN->add('backups', $temp); // Create a page for asynchronous backup and restore configuration and defaults. - if (!empty($CFG->enableasyncbackup)) { // Only add settings if async mode is enable at site level. - $temp = new admin_settingpage('asyncgeneralsettings', new lang_string('asyncgeneralsettings', 'backup')); - - $temp->add(new admin_setting_configcheckbox( - 'backup/backup_async_message_users', - new lang_string('asyncemailenable', 'backup'), - new lang_string('asyncemailenabledetail', 'backup'), 0)); - - $temp->add(new admin_setting_configtext( - 'backup/backup_async_message_subject', - new lang_string('asyncmessagesubject', 'backup'), - new lang_string('asyncmessagesubjectdetail', 'backup'), - new lang_string('asyncmessagesubjectdefault', 'backup'))); - - $temp->add(new admin_setting_confightmleditor( - 'backup/backup_async_message', - new lang_string('asyncmessagebody', 'backup'), - new lang_string('asyncmessagebodydetail', 'backup'), - new lang_string('asyncmessagebodydefault', 'backup'))); - - $ADMIN->add('backups', $temp); - } + $temp = new admin_settingpage('asyncgeneralsettings', new lang_string('asyncgeneralsettings', 'backup')); + + $temp->add(new admin_setting_configcheckbox('enableasyncbackup', new lang_string('enableasyncbackup', 'backup'), + new lang_string('enableasyncbackup_help', 'backup'), 0, 1, 0)); + + $temp->add(new admin_setting_configcheckbox( + 'backup/backup_async_message_users', + new lang_string('asyncemailenable', 'backup'), + new lang_string('asyncemailenabledetail', 'backup'), 0)); + $temp->hide_if('backup/backup_async_message_users', 'enableasyncbackup'); + + $temp->add(new admin_setting_configtext( + 'backup/backup_async_message_subject', + new lang_string('asyncmessagesubject', 'backup'), + new lang_string('asyncmessagesubjectdetail', 'backup'), + new lang_string('asyncmessagesubjectdefault', 'backup'))); + $temp->hide_if('backup/backup_async_message_subject', 'backup/backup_async_message_users'); + + $temp->add(new admin_setting_confightmleditor( + 'backup/backup_async_message', + new lang_string('asyncmessagebody', 'backup'), + new lang_string('asyncmessagebodydetail', 'backup'), + new lang_string('asyncmessagebodydefault', 'backup'))); + $temp->hide_if('backup/backup_async_message', 'backup/backup_async_message_users'); + + $ADMIN->add('backups', $temp); } diff --git a/admin/settings/subsystems.php b/admin/settings/subsystems.php index 0b627494d65b9..e5c660b570a5f 100644 --- a/admin/settings/subsystems.php +++ b/admin/settings/subsystems.php @@ -51,7 +51,4 @@ $optionalsubsystems->add(new admin_setting_configcheckbox('enablecoursepublishing', new lang_string('enablecoursepublishing', 'hub'), new lang_string('enablecoursepublishing_help', 'hub'), 0)); - - $optionalsubsystems->add(new admin_setting_configcheckbox('enableasyncbackup', new lang_string('enableasyncbackup', 'backup'), - new lang_string('enableasyncbackup_help', 'backup'), 0, 1, 0)); } From d2c91281db25f929f9df9bbfd8f376d12738b066 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 23 May 2019 13:52:32 +0800 Subject: [PATCH 030/786] MDL-65695 forum: Bump digest time to next day if in past --- mod/forum/classes/task/cron_task.php | 5 ++ mod/forum/tests/maildigest_test.php | 81 ++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/mod/forum/classes/task/cron_task.php b/mod/forum/classes/task/cron_task.php index ca3b41e3a8e08..e3627c551c4bb 100644 --- a/mod/forum/classes/task/cron_task.php +++ b/mod/forum/classes/task/cron_task.php @@ -338,6 +338,11 @@ protected function queue_user_tasks() { $DB->insert_records('forum_queue', $digestpostdata); $digesttime = usergetmidnight($timenow, $sitetimezone) + ($CFG->digestmailtime * 3600); + if ($digesttime < $timenow) { + // Digest time is in the past. Get a new time for tomorrow. + $digesttime = usergetmidnight($timenow + DAYSECS, $sitetimezone) + ($CFG->digestmailtime * 3600); + } + $task = new \mod_forum\task\send_user_digests(); $task->set_userid($user->id); $task->set_component('mod_forum'); diff --git a/mod/forum/tests/maildigest_test.php b/mod/forum/tests/maildigest_test.php index 86a3613d46f72..76759b6020abb 100644 --- a/mod/forum/tests/maildigest_test.php +++ b/mod/forum/tests/maildigest_test.php @@ -518,4 +518,85 @@ public function test_cron_forum_digest_email() { $this->send_digests_and_assert($user, $fulldigests, $shortdigests); } + + /** + * The digest being in the past is queued til the next day. + */ + public function test_cron_digest_previous_day() { + global $DB, $CFG; + + $this->resetAfterTest(true); + + // Set up a basic user enrolled in a course. + $userhelper = $this->helper_setup_user_in_course(); + $user = $userhelper->user; + $course1 = $userhelper->courses->course1; + $forum1 = $userhelper->forums->forum1; + $forum2 = $userhelper->forums->forum2; + $fulldigests = []; + $shortdigests = []; + + // Add 1 discussions to forum 1. + list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]); + $fulldigests[] = $post; + + // Set the tested user's default maildigest setting. + $DB->set_field('user', 'maildigest', 1, array('id' => $user->id)); + + // Set the digest time to midnight. + $CFG->digestmailtime = 0; + // One digest e-mail should be sent, and no individual notifications. + $expect = [ + (object) [ + 'userid' => $user->id, + 'digests' => 1, + ], + ]; + $this->queue_tasks_and_assert($expect); + + $tasks = $DB->get_records('task_adhoc'); + $task = reset($tasks); + $this->assertGreaterThanOrEqual(time(), $task->nextruntime); + } + + /** + * The digest being in the past is queued til the next day. + */ + public function test_cron_digest_same_day() { + global $DB, $CFG; + + $this->resetAfterTest(true); + + // Set up a basic user enrolled in a course. + $userhelper = $this->helper_setup_user_in_course(); + $user = $userhelper->user; + $course1 = $userhelper->courses->course1; + $forum1 = $userhelper->forums->forum1; + $forum2 = $userhelper->forums->forum2; + $fulldigests = []; + $shortdigests = []; + + // Add 1 discussions to forum 1. + list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]); + $fulldigests[] = $post; + + // Set the tested user's default maildigest setting. + $DB->set_field('user', 'maildigest', 1, array('id' => $user->id)); + + // Set the digest time to the future (magic, shouldn't work). + $CFG->digestmailtime = 25; + // One digest e-mail should be sent, and no individual notifications. + $expect = [ + (object) [ + 'userid' => $user->id, + 'digests' => 1, + ], + ]; + $this->queue_tasks_and_assert($expect); + + $tasks = $DB->get_records('task_adhoc'); + $task = reset($tasks); + $digesttime = usergetmidnight(time(), \core_date::get_server_timezone()) + ($CFG->digestmailtime * 3600); + $this->assertLessThanOrEqual($digesttime, $task->nextruntime); + } } From 2a64720ac8c7e47ec9901c68fde2abdde8b07d12 Mon Sep 17 00:00:00 2001 From: Amaia Anabitarte Date: Mon, 20 May 2019 15:39:13 +0200 Subject: [PATCH 031/786] MDL-65060 core_message: Group message data generator --- lib/tests/behat/behat_data_generators.php | 52 ++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/tests/behat/behat_data_generators.php b/lib/tests/behat/behat_data_generators.php index ce1584b4bdfc9..e87f6c44f14ea 100644 --- a/lib/tests/behat/behat_data_generators.php +++ b/lib/tests/behat/behat_data_generators.php @@ -208,6 +208,11 @@ class behat_data_generators extends behat_base { 'required' => array('user', 'contact'), 'switchids' => array('user' => 'userid', 'contact' => 'contactid') ), + 'group messages' => array( + 'datagenerator' => 'group_messages', + 'required' => array('user', 'group', 'message'), + 'switchids' => array('user' => 'userid', 'group' => 'groupid') + ), 'language customisations' => array( 'datagenerator' => 'customlang', 'required' => array('component', 'stringid', 'value'), @@ -956,6 +961,10 @@ protected function get_contact_id($username) { * @return void */ protected function process_private_messages(array $data) { + if (empty($data['format'])) { + $data['format'] = 'FORMAT_PLAIN'; + } + if (!$conversationid = \core_message\api::get_conversation_between_users([$data['userid'], $data['contactid']])) { $conversation = \core_message\api::create_conversation( \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, @@ -963,7 +972,48 @@ protected function process_private_messages(array $data) { ); $conversationid = $conversation->id; } - \core_message\api::send_message_to_conversation($data['userid'], $conversationid, $data['message'], FORMAT_PLAIN); + \core_message\api::send_message_to_conversation( + $data['userid'], + $conversationid, + $data['message'], + constant($data['format']) + ); + } + + /** + * Send a new message from user to a group conversation + * + * @param array $data + * @return void + */ + protected function process_group_messages(array $data) { + global $DB; + + if (empty($data['format'])) { + $data['format'] = 'FORMAT_PLAIN'; + } + + $group = $DB->get_record('groups', ['id' => $data['groupid']]); + $coursecontext = context_course::instance($group->courseid); + if (!$conversation = \core_message\api::get_conversation_by_area('core_group', 'groups', $data['groupid'], + $coursecontext->id)) { + $members = $DB->get_records_menu('groups_members', ['groupid' => $data['groupid']], '', 'userid, id'); + $conversation = \core_message\api::create_conversation( + \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, + array_keys($members), + $group->name, + \core_message\api::MESSAGE_CONVERSATION_ENABLED, + 'core_group', + 'groups', + $group->id, + $coursecontext->id); + } + \core_message\api::send_message_to_conversation( + $data['userid'], + $conversation->id, + $data['message'], + constant($data['format']) + ); } /** From e39f3b7db215b61d68ea2a23ff850f0efa1853e8 Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Thu, 23 May 2019 20:35:31 +0200 Subject: [PATCH 032/786] weekly release 3.7+ --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 82299ae4aae81..627291ee3e3e0 100644 --- a/version.php +++ b/version.php @@ -29,11 +29,11 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2019052000.00; // 20190520 = branching date YYYYMMDD - do not modify! +$version = 2019052000.01; // 20190520 = branching date YYYYMMDD - do not modify! // RR = release increments - 00 in DEV branches. // .XX = incremental changes. -$release = '3.7 (Build: 20190520)'; // Human-friendly version name +$release = '3.7+ (Build: 20190524)'; // Human-friendly version name $branch = '37'; // This version's branch. $maturity = MATURITY_STABLE; // This version's maturity level. From a4e309709d2ae289d319c408738255b05cf030e9 Mon Sep 17 00:00:00 2001 From: Simey Lameze Date: Fri, 24 May 2019 07:01:24 +0800 Subject: [PATCH 033/786] MDL-65697 qtype_missingtype: include missing class --- question/type/missingtype/tests/missingtype_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/question/type/missingtype/tests/missingtype_test.php b/question/type/missingtype/tests/missingtype_test.php index cc2a922db3762..95c943772299f 100644 --- a/question/type/missingtype/tests/missingtype_test.php +++ b/question/type/missingtype/tests/missingtype_test.php @@ -30,7 +30,7 @@ require_once(__DIR__ . '/../../../engine/tests/helpers.php'); require_once(__DIR__ . '/../../../behaviour/deferredfeedback/behaviour.php'); require_once(__DIR__ . '/../question.php'); - +require_once($CFG->dirroot . '/question/type/missingtype/questiontype.php'); /** * Unit tests for the 'missing' question type. From 38a9ba9bcd5f33eb12490d806ee57241ed4c2f82 Mon Sep 17 00:00:00 2001 From: Amaia Anabitarte Date: Mon, 20 May 2019 15:39:41 +0200 Subject: [PATCH 034/786] MDL-65060 core_message: Delete messages behat test --- message/tests/behat/delete_messages.feature | 268 ++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 message/tests/behat/delete_messages.feature diff --git a/message/tests/behat/delete_messages.feature b/message/tests/behat/delete_messages.feature new file mode 100644 index 0000000000000..3f985ebce04f5 --- /dev/null +++ b/message/tests/behat/delete_messages.feature @@ -0,0 +1,268 @@ +@core @core_message @javascript +Feature: Delete messages from conversations + In order to manage a course group in a course + As a user + I need to be able to delete messages from conversations + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | student1 | Student | 1 | student1@example.com | + | student2 | Student | 2 | student2@example.com | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | student2 | C1 | student | + And the following "groups" exist: + | name | course | idnumber | enablemessaging | + | Group 1 | C1 | G1 | 1 | + And the following "group members" exist: + | user | group | + | student1 | G1 | + | student2 | G1 | + And the following "group messages" exist: + | user | group | message | + | student1 | G1 | Hi! | + | student2 | G1 | How are you? | + | student1 | G1 | Can somebody help me? | + And the following "private messages" exist: + | user | contact | message | + | student1 | student2 | Hi! | + | student2 | student1 | Hello! | + | student1 | student2 | Are you free? | + And the following config values are set as admin: + | messaging | 1 | + + Scenario: Delete a message sent by the user from a group conversation + Given I log in as "student1" + And I open messaging + And "Group 1" "group_message" should exist + And I select "Group 1" conversation in messaging + And I click on "Hi!" "group_message_message_content" + And I click on "How are you?" "group_message_message_content" + And I click on "Can somebody help me?" "group_message_message_content" + And I should see "3" in the "[data-region='message-selected-court']" "css_element" +# Clicking to unselect + And I click on "How are you?" "group_message_message_content" + And I click on "Can somebody help me?" "group_message_message_content" + And I should see "1" in the "[data-region='message-selected-court']" "css_element" + And "Delete selected messages" "button" should exist + When I click on "Delete selected messages" "button" +# Deleting, so messages should not be there + And I should see "Delete" + And I click on "//button[@data-action='confirm-delete-selected-messages']" "xpath_element" + Then I should not see "Delete" + And I should not see "Hi!" + And I should see "##today##j F##" in the "Group 1" "group_message_conversation" + And I should see "How are you?" in the "Group 1" "group_message_conversation" + And I should see "Can somebody help me?" in the "Group 1" "group_message_conversation" + And I should not see "Messages selected" + + Scenario: Delete two messages from a group conversation; one sent by another user. + Given I log in as "student1" + And I open messaging + And "Group 1" "group_message" should exist + And I select "Group 1" conversation in messaging + And I click on "Hi!" "group_message_message_content" + And I should see "1" in the "[data-region='message-selected-court']" "css_element" + And I click on "How are you?" "group_message_message_content" + And I should see "2" in the "[data-region='message-selected-court']" "css_element" + And "Delete selected messages" "button" should exist + When I click on "Delete selected messages" "button" +# Deleting, so messages should not be there + And I should see "Delete" + And I click on "//button[@data-action='confirm-delete-selected-messages']" "xpath_element" + Then I should not see "Delete" + And I should not see "Hi!" + And I should see "##today##j F##" in the "Group 1" "group_message_conversation" + And I should not see "How are you?" in the "Group 1" "group_message_conversation" + And I should see "Can somebody help me?" in the "Group 1" "group_message_conversation" + And I should not see "Messages selected" +# Check messages were not deleted for other users + And I log out + And I log in as "student2" + And I open messaging + And I select "Group 1" conversation in messaging + And I should see "Hi!" + And I should see "How are you?" + And I should see "Can somebody help me?" + + Scenario: Cancel deleting two messages from a group conversation + Given I log in as "student1" + And I open messaging + And "Group 1" "group_message" should exist + And I select "Group 1" conversation in messaging + And I click on "Hi!" "group_message_message_content" + And I click on "How are you?" "group_message_message_content" + And "Delete selected messages" "button" should exist + When I click on "Delete selected messages" "button" +# Canceling deletion, so messages should be there + And I should see "Cancel" + And I click on "//button[@data-action='cancel-confirm']" "xpath_element" + Then I should not see "Cancel" + And I should see "Hi!" + And I should see "How are you?" in the "Group 1" "group_message_conversation" + And I should see "2" in the "[data-region='message-selected-court']" "css_element" + + Scenario: Delete a message sent by the user from a private conversation + Given I log in as "student1" + And I open messaging + And I should see "Private" + And I open the "Private" conversations list + And I should see "Student 2" + And I select "Student 2" conversation in messaging + And I click on "Hi!" "group_message_message_content" + And I should see "1" in the "[data-region='message-selected-court']" "css_element" + And "Delete selected messages" "button" should exist + When I click on "Delete selected messages" "button" +# Deleting, so messages should not be there + And I should see "Delete" + And I click on "//button[@data-action='confirm-delete-selected-messages']" "xpath_element" + Then I should not see "Delete" + And I should not see "Hi!" + And I should see "##today##j F##" in the "Student 2" "group_message_conversation" + And I should see "Hello!" in the "Student 2" "group_message_conversation" + And I should see "Are you free?" in the "Student 2" "group_message_conversation" + And I should not see "Messages selected" + + Scenario: Delete two messages from a private conversation; one sent by another user + Given I log in as "student1" + And I open messaging + And I should see "Private" + And I open the "Private" conversations list + And I should see "Student 2" + And I select "Student 2" conversation in messaging + And I click on "Hi!" "group_message_message_content" + And I should see "1" in the "[data-region='message-selected-court']" "css_element" + And I click on "Hello!" "group_message_message_content" + And I should see "2" in the "[data-region='message-selected-court']" "css_element" + And "Delete selected messages" "button" should exist + When I click on "Delete selected messages" "button" +# Deleting, so messages should not be there + And I should see "Delete" + And I click on "//button[@data-action='confirm-delete-selected-messages']" "xpath_element" + Then I should not see "Delete" + And I should not see "Hi!" + And I should not see "Hello!" in the "Student 2" "group_message_conversation" + And I should see "##today##j F##" in the "Student 2" "group_message_conversation" + And I should see "Are you free?" in the "Student 2" "group_message_conversation" + And I should not see "Messages selected" +# Check messages were not deleted for the other user + And I log out + And I log in as "student2" + And I open messaging + And I open the "Private" conversations list + And I select "Student 1" conversation in messaging + And I should see "Hi!" + And I should see "Hello!" + And I should see "Are you free?" + + Scenario: Cancel deleting two messages from a private conversation + Given I log in as "student1" + And I open messaging + And I should see "Private" + And I open the "Private" conversations list + And I should see "Student 2" + And I select "Student 2" conversation in messaging + And I click on "Hi!" "group_message_message_content" + And I click on "Hello!" "group_message_message_content" + And "Delete selected messages" "button" should exist + When I click on "Delete selected messages" "button" +# Canceling deletion, so messages should be there + And I should see "Cancel" + And I click on "//button[@data-action='cancel-confirm']" "xpath_element" + Then I should not see "Cancel" + And I should see "Hi!" + And I should see "Hello!" in the "Student 2" "group_message_conversation" + And I should see "2" in the "[data-region='message-selected-court']" "css_element" + + Scenario: Delete a message sent by the user from a favorite conversation + Given the following "favourite conversations" exist: + | user | contact | + | student1 | student2 | + And I log in as "student1" + And I open messaging + And I should see "Student 2" + And I select "Student 2" conversation in messaging + And I click on "Hi!" "group_message_message_content" + And I should see "1" in the "[data-region='message-selected-court']" "css_element" + And "Delete selected messages" "button" should exist + When I click on "Delete selected messages" "button" +# Deleting, so messages should not be there + And I should see "Delete" + And I click on "//button[@data-action='confirm-delete-selected-messages']" "xpath_element" + Then I should not see "Delete" + And I should not see "Hi!" + And I should see "##today##j F##" in the "Student 2" "group_message_conversation" + And I should see "Hello!" in the "Student 2" "group_message_conversation" + And I should not see "Messages selected" + + Scenario: Delete two messages from a favourite conversation; one sent by another user + Given the following "favourite conversations" exist: + | user | contact | + | student1 | student2 | + And I log in as "student1" + And I open messaging + And I should see "Student 2" + And I select "Student 2" conversation in messaging + And I click on "Hi!" "group_message_message_content" + And I should see "1" in the "[data-region='message-selected-court']" "css_element" + And I click on "Hello!" "group_message_message_content" + And I should see "2" in the "[data-region='message-selected-court']" "css_element" + And "Delete selected messages" "button" should exist + When I click on "Delete selected messages" "button" +# Deleting, so messages should not be there + And I should see "Delete" + And I click on "//button[@data-action='confirm-delete-selected-messages']" "xpath_element" + Then I should not see "Delete" + And I should not see "Hi!" + And I should not see "Hello!" in the "Student 2" "group_message_conversation" + And I should see "##today##j F##" in the "Student 2" "group_message_conversation" + And I should see "Are you free?" in the "Student 2" "group_message_conversation" + And I should not see "Messages selected" + + Scenario: Cancel deleting two messages from a favourite conversation + Given the following "favourite conversations" exist: + | user | contact | + | student1 | student2 | + And I log in as "student1" + And I open messaging + And I should see "Student 2" + And I select "Student 2" conversation in messaging + And I click on "Hi!" "group_message_message_content" + And I click on "Hello!" "group_message_message_content" + And "Delete selected messages" "button" should exist + When I click on "Delete selected messages" "button" +# Canceling deletion, so messages should be there + And I should see "Cancel" + And I click on "//button[@data-action='cancel-confirm']" "xpath_element" + Then I should not see "Cancel" + And I should see "Hi!" + And I should see "Hello!" in the "Student 2" "group_message_conversation" + And I should see "2" in the "[data-region='message-selected-court']" "css_element" + + Scenario: Check an empty favourite conversation is still favourite + Given the following "favourite conversations" exist: + | user | contact | + | student1 | student2 | + And I log in as "student1" + And I open messaging + And I should see "Student 2" + And I select "Student 2" conversation in the "favourites" conversations list + And I click on "Hi!" "group_message_message_content" + And I click on "Hello!" "group_message_message_content" + And I click on "Are you free?" "group_message_message_content" + And "Delete selected messages" "button" should exist + When I click on "Delete selected messages" "button" + And I should see "Delete" + And I click on "//button[@data-action='confirm-delete-selected-messages']" "xpath_element" + And I go back in "view-conversation" message drawer + Then I should not see "Student 2" in the "//*[@data-region='message-drawer']//div[@data-region='view-overview-favourites']" "xpath_element" + And I send "Hi!" message to "Student 2" user + And I go back in "view-conversation" message drawer + And I go back in "view-search" message drawer + And I open the "Starred" conversations list + And I should see "Student 2" in the "//*[@data-region='message-drawer']//div[@data-region='view-overview-favourites']" "xpath_element" From c227fc61f1789dcce7a521b67c30c8fb0220a8bf Mon Sep 17 00:00:00 2001 From: David Matamoros Date: Thu, 23 May 2019 17:21:27 +0200 Subject: [PATCH 035/786] MDL-65699 core_calendar: Check string exists for event types --- calendar/classes/external/event_exporter_base.php | 4 +++- calendar/templates/event_details.mustache | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/calendar/classes/external/event_exporter_base.php b/calendar/classes/external/event_exporter_base.php index 08d14acf101b2..f761f705bcdc6 100644 --- a/calendar/classes/external/event_exporter_base.php +++ b/calendar/classes/external/event_exporter_base.php @@ -275,7 +275,9 @@ protected function get_other_values(renderer_base $output) { } $timesort = $event->get_times()->get_sort_time()->getTimestamp(); $iconexporter = new event_icon_exporter($event, ['context' => $context]); - $values['normalisedeventtypetext'] = get_string('type' . $values['normalisedeventtype'], 'calendar'); + $identifier = 'type' . $values['normalisedeventtype']; + $stringexists = get_string_manager()->string_exists($identifier, 'calendar'); + $values['normalisedeventtypetext'] = $stringexists ? get_string($identifier, 'calendar') : ''; $values['icon'] = $iconexporter->export($output); diff --git a/calendar/templates/event_details.mustache b/calendar/templates/event_details.mustache index 86fcda4cc9b53..1a1516fef7d37 100644 --- a/calendar/templates/event_details.mustache +++ b/calendar/templates/event_details.mustache @@ -59,10 +59,12 @@
{{#pix}} i/calendareventtime, core, {{#str}} when, core_calendar {{/str}} {{/pix}}
{{{formattedtime}}}
-
-
{{#pix}} i/calendar, core, {{#str}} eventtype, core_calendar {{/str}} {{/pix}}
-
{{normalisedeventtypetext}}
-
+{{#normalisedeventtypetext}} +
+
{{#pix}} i/calendar, core, {{#str}} eventtype, core_calendar {{/str}} {{/pix}}
+
{{normalisedeventtypetext}}
+
+{{/normalisedeventtypetext}} {{#description}}
{{#pix}} i/calendareventdescription, core, {{#str}} description {{/str}} {{/pix}}
From 1a6160df3c2dab1a58abd6048644a2e9c3999f58 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Sat, 25 May 2019 03:54:58 +1000 Subject: [PATCH 036/786] MDL-64523 core_access: Improve the title of the delete role links --- admin/roles/classes/permissions_table.php | 4 ++-- admin/roles/permissions.php | 2 +- lib/amd/build/permissionmanager.min.js | 2 +- lib/amd/src/permissionmanager.js | 2 ++ 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/admin/roles/classes/permissions_table.php b/admin/roles/classes/permissions_table.php index 80e4b2067cea7..b877a70c76905 100644 --- a/admin/roles/classes/permissions_table.php +++ b/admin/roles/classes/permissions_table.php @@ -96,7 +96,7 @@ protected function add_row_cells($capability) { "linkclass" => "preventlink", "adminurl" => $adminurl->out(), "icon" => "", "iconalt" => ""); if (isset($overridableroles[$id]) and ($allowoverrides or ($allowsafeoverrides and is_safe_capability($capability)))) { $templatecontext['icon'] = 't/delete'; - $templatecontext['iconalt'] = get_string('delete'); + $templatecontext['iconalt'] = get_string('deletexrole', 'core_role', $name); } $neededroles[$id] = $renderer->render_from_template('core/permissionmanager_role', $templatecontext); } @@ -109,7 +109,7 @@ protected function add_row_cells($capability) { "icon" => "", "iconalt" => ""); if (isset($overridableroles[$id]) and prohibit_is_removable($id, $context, $capability->name)) { $templatecontext['icon'] = 't/delete'; - $templatecontext['iconalt'] = get_string('delete'); + $templatecontext['iconalt'] = get_string('deletexrole', 'core_role', $name); } $forbiddenroles[$id] = $renderer->render_from_template('core/permissionmanager_role', $templatecontext); } diff --git a/admin/roles/permissions.php b/admin/roles/permissions.php index 89668dc53c5f9..bc549484400ce 100644 --- a/admin/roles/permissions.php +++ b/admin/roles/permissions.php @@ -213,7 +213,7 @@ $PAGE->requires->strings_for_js( array('roleprohibitinfo', 'roleprohibitheader', 'roleallowinfo', 'roleallowheader', 'confirmunassigntitle', 'confirmroleunprohibit', 'confirmroleprevent', 'confirmunassignyes', - 'confirmunassignno'), 'core_role'); + 'confirmunassignno', 'deletexrole'), 'core_role'); $PAGE->requires->js_call_amd('core/permissionmanager', 'initialize', array($arguments)); $table = new core_role_permissions_table($context, $contextname, $allowoverrides, $allowsafeoverrides, $overridableroles); echo $OUTPUT->box_start('generalbox capbox'); diff --git a/lib/amd/build/permissionmanager.min.js b/lib/amd/build/permissionmanager.min.js index 4a6c31bc1d1c9..63fae6aee17ba 100644 --- a/lib/amd/build/permissionmanager.min.js +++ b/lib/amd/build/permissionmanager.min.js @@ -1 +1 @@ -define(["jquery","core/config","core/notification","core/templates","core/yui"],function(a,b,c,d,e){var f,g,h,i,j={ADDROLE:"a.allowlink, a.prohibitlink",REMOVEROLE:"a.preventlink, a.unprohibitlink",UNPROHIBIT:"a.unprohibitlink"},k=a.Event("rolesloaded"),l=null,m=function(){var d={contextid:f,getroles:1,sesskey:b.sesskey};a.post(h+"roles/ajax.php",d,null,"json").done(function(b){try{i=b,m=function(){a("body").trigger(k)},m()}catch(d){c.exception(d)}}).fail(function(a,b,d){c.exception(d)})},n=function(b,e,g){var j={contextid:f,roleid:e,sesskey:M.cfg.sesskey,action:g,capability:b.data("name")};a.post(h+"roles/ajax.php",j,null,"json").done(function(f){var g=f;try{var j={rolename:i[e],roleid:e,adminurl:h,imageurl:M.util.image_url("t/delete","moodle")};switch(g){case"allow":j.spanclass="allowed",j.linkclass="preventlink",j.action="prevent",j.icon="t/delete";break;case"prohibit":j.spanclass="forbidden",j.linkclass="unprohibitlink",j.action="unprohibit",j.icon="t/delete";break;case"prevent":return void b.find('a[data-role-id="'+e+'"]').first().closest(".allowed").remove();case"unprohibit":return void b.find('a[data-role-id="'+e+'"]').first().closest(".forbidden").remove();default:return}d.render("core/permissionmanager_role",j).done(function(c){if("allow"==g)a(c).insertBefore(b.find(".allowmore:first"));else if("prohibit"==g){a(c).insertBefore(b.find(".prohibitmore:first"));var d=b.find(".allowedroles").first().find('a[data-role-id="'+e+'"]');d&&d.first().closest(".allowed").remove()}l.hide()}).fail(c.exception)}catch(k){c.exception(k)}}).fail(function(a,b,d){c.exception(d)})},o=function(b){b.preventDefault(),e.use("moodle-core-notification-dialogue",function(){a("body").one("rolesloaded",function(){var e=a(b.currentTarget),f=e.data("action"),h=e.closest("tr.rolecap"),k={cap:h.data("humanname"),context:g},m=M.util.get_string("role"+f+"info","core_role",k);null===l&&(l=new M.core.dialogue({draggable:!0,modal:!0,closeButton:!0,width:"450px"})),l.set("headerContent",M.util.get_string("role"+f+"header","core_role"));var o,p,q=[];switch(f){case"allow":p=h.find(j.REMOVEROLE);break;case"prohibit":p=h.find(j.UNPROHIBIT)}for(o in i){var r="",s=p.filter("[data-role-id='"+o+"']").length;s&&(r="disabled");var t={roleid:o,rolename:i[o],disabled:r};q.push(t)}d.render("core/permissionmanager_panelcontent",{message:m,roles:q}).done(function(b){l.set("bodyContent",b),l.show(),a("div.role_buttons").delegate("input","click",function(b){var c=a(b.currentTarget).data("role-id");n(h,c,f)})}).fail(c.exception)})}),m()},p=function(b){b.preventDefault(),a("body").one("rolesloaded",function(){var d=a(b.currentTarget),e=d.data("action"),f=d.data("role-id"),h=d.closest("tr.rolecap"),j={role:i[f],cap:h.data("humanname"),context:g};c.confirm(M.util.get_string("confirmunassigntitle","core_role"),M.util.get_string("confirmrole"+e,"core_role",j),M.util.get_string("confirmunassignyes","core_role"),M.util.get_string("confirmunassignno","core_role"),function(){n(h,f,e)})}),m()};return{initialize:function(b){f=b.contextid,g=b.contextname,h=b.adminurl;var c=a("body");c.delegate(j.ADDROLE,"click",o),c.delegate(j.REMOVEROLE,"click",p)}}}); \ No newline at end of file +define(["jquery","core/config","core/notification","core/templates","core/yui"],function(a,b,c,d,e){var f,g,h,i,j={ADDROLE:"a.allowlink, a.prohibitlink",REMOVEROLE:"a.preventlink, a.unprohibitlink",UNPROHIBIT:"a.unprohibitlink"},k=a.Event("rolesloaded"),l=null,m=function(){var d={contextid:f,getroles:1,sesskey:b.sesskey};a.post(h+"roles/ajax.php",d,null,"json").done(function(b){try{i=b,m=function(){a("body").trigger(k)},m()}catch(d){c.exception(d)}}).fail(function(a,b,d){c.exception(d)})},n=function(b,e,g){var j={contextid:f,roleid:e,sesskey:M.cfg.sesskey,action:g,capability:b.data("name")};a.post(h+"roles/ajax.php",j,null,"json").done(function(f){var g=f;try{var j={rolename:i[e],roleid:e,adminurl:h,imageurl:M.util.image_url("t/delete","moodle")};switch(g){case"allow":j.spanclass="allowed",j.linkclass="preventlink",j.action="prevent",j.icon="t/delete",j.iconalt=M.util.get_string("deletexrole","core_role",i[e]);break;case"prohibit":j.spanclass="forbidden",j.linkclass="unprohibitlink",j.action="unprohibit",j.icon="t/delete",j.iconalt=M.util.get_string("deletexrole","core_role",i[e]);break;case"prevent":return void b.find('a[data-role-id="'+e+'"]').first().closest(".allowed").remove();case"unprohibit":return void b.find('a[data-role-id="'+e+'"]').first().closest(".forbidden").remove();default:return}d.render("core/permissionmanager_role",j).done(function(c){if("allow"==g)a(c).insertBefore(b.find(".allowmore:first"));else if("prohibit"==g){a(c).insertBefore(b.find(".prohibitmore:first"));var d=b.find(".allowedroles").first().find('a[data-role-id="'+e+'"]');d&&d.first().closest(".allowed").remove()}l.hide()}).fail(c.exception)}catch(k){c.exception(k)}}).fail(function(a,b,d){c.exception(d)})},o=function(b){b.preventDefault(),e.use("moodle-core-notification-dialogue",function(){a("body").one("rolesloaded",function(){var e=a(b.currentTarget),f=e.data("action"),h=e.closest("tr.rolecap"),k={cap:h.data("humanname"),context:g},m=M.util.get_string("role"+f+"info","core_role",k);null===l&&(l=new M.core.dialogue({draggable:!0,modal:!0,closeButton:!0,width:"450px"})),l.set("headerContent",M.util.get_string("role"+f+"header","core_role"));var o,p,q=[];switch(f){case"allow":p=h.find(j.REMOVEROLE);break;case"prohibit":p=h.find(j.UNPROHIBIT)}for(o in i){var r="",s=p.filter("[data-role-id='"+o+"']").length;s&&(r="disabled");var t={roleid:o,rolename:i[o],disabled:r};q.push(t)}d.render("core/permissionmanager_panelcontent",{message:m,roles:q}).done(function(b){l.set("bodyContent",b),l.show(),a("div.role_buttons").delegate("input","click",function(b){var c=a(b.currentTarget).data("role-id");n(h,c,f)})}).fail(c.exception)})}),m()},p=function(b){b.preventDefault(),a("body").one("rolesloaded",function(){var d=a(b.currentTarget),e=d.data("action"),f=d.data("role-id"),h=d.closest("tr.rolecap"),j={role:i[f],cap:h.data("humanname"),context:g};c.confirm(M.util.get_string("confirmunassigntitle","core_role"),M.util.get_string("confirmrole"+e,"core_role",j),M.util.get_string("confirmunassignyes","core_role"),M.util.get_string("confirmunassignno","core_role"),function(){n(h,f,e)})}),m()};return{initialize:function(b){f=b.contextid,g=b.contextname,h=b.adminurl;var c=a("body");c.delegate(j.ADDROLE,"click",o),c.delegate(j.REMOVEROLE,"click",p)}}}); \ No newline at end of file diff --git a/lib/amd/src/permissionmanager.js b/lib/amd/src/permissionmanager.js index dcd8712bbbb9b..5812ef36df42d 100644 --- a/lib/amd/src/permissionmanager.js +++ b/lib/amd/src/permissionmanager.js @@ -105,12 +105,14 @@ define(['jquery', 'core/config', 'core/notification', 'core/templates', 'core/yu templatedata.linkclass = 'preventlink'; templatedata.action = 'prevent'; templatedata.icon = 't/delete'; + templatedata.iconalt = M.util.get_string('deletexrole', 'core_role', overideableroles[roleid]); break; case 'prohibit': templatedata.spanclass = 'forbidden'; templatedata.linkclass = 'unprohibitlink'; templatedata.action = 'unprohibit'; templatedata.icon = 't/delete'; + templatedata.iconalt = M.util.get_string('deletexrole', 'core_role', overideableroles[roleid]); break; case 'prevent': row.find('a[data-role-id="' + roleid + '"]').first().closest('.allowed').remove(); From 245de290f74ab458225fb404ae8d6f17d54910b4 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Thu, 23 May 2019 16:07:43 +1000 Subject: [PATCH 037/786] MDL-64523 core_access: Fix js racing issue when overriding permissions --- lib/amd/build/permissionmanager.min.js | 2 +- lib/amd/src/permissionmanager.js | 9 ++-- lib/tests/behat/permissionmanager.feature | 51 +++++++++++++++++++++++ 3 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 lib/tests/behat/permissionmanager.feature diff --git a/lib/amd/build/permissionmanager.min.js b/lib/amd/build/permissionmanager.min.js index 63fae6aee17ba..e48ff7d915055 100644 --- a/lib/amd/build/permissionmanager.min.js +++ b/lib/amd/build/permissionmanager.min.js @@ -1 +1 @@ -define(["jquery","core/config","core/notification","core/templates","core/yui"],function(a,b,c,d,e){var f,g,h,i,j={ADDROLE:"a.allowlink, a.prohibitlink",REMOVEROLE:"a.preventlink, a.unprohibitlink",UNPROHIBIT:"a.unprohibitlink"},k=a.Event("rolesloaded"),l=null,m=function(){var d={contextid:f,getroles:1,sesskey:b.sesskey};a.post(h+"roles/ajax.php",d,null,"json").done(function(b){try{i=b,m=function(){a("body").trigger(k)},m()}catch(d){c.exception(d)}}).fail(function(a,b,d){c.exception(d)})},n=function(b,e,g){var j={contextid:f,roleid:e,sesskey:M.cfg.sesskey,action:g,capability:b.data("name")};a.post(h+"roles/ajax.php",j,null,"json").done(function(f){var g=f;try{var j={rolename:i[e],roleid:e,adminurl:h,imageurl:M.util.image_url("t/delete","moodle")};switch(g){case"allow":j.spanclass="allowed",j.linkclass="preventlink",j.action="prevent",j.icon="t/delete",j.iconalt=M.util.get_string("deletexrole","core_role",i[e]);break;case"prohibit":j.spanclass="forbidden",j.linkclass="unprohibitlink",j.action="unprohibit",j.icon="t/delete",j.iconalt=M.util.get_string("deletexrole","core_role",i[e]);break;case"prevent":return void b.find('a[data-role-id="'+e+'"]').first().closest(".allowed").remove();case"unprohibit":return void b.find('a[data-role-id="'+e+'"]').first().closest(".forbidden").remove();default:return}d.render("core/permissionmanager_role",j).done(function(c){if("allow"==g)a(c).insertBefore(b.find(".allowmore:first"));else if("prohibit"==g){a(c).insertBefore(b.find(".prohibitmore:first"));var d=b.find(".allowedroles").first().find('a[data-role-id="'+e+'"]');d&&d.first().closest(".allowed").remove()}l.hide()}).fail(c.exception)}catch(k){c.exception(k)}}).fail(function(a,b,d){c.exception(d)})},o=function(b){b.preventDefault(),e.use("moodle-core-notification-dialogue",function(){a("body").one("rolesloaded",function(){var e=a(b.currentTarget),f=e.data("action"),h=e.closest("tr.rolecap"),k={cap:h.data("humanname"),context:g},m=M.util.get_string("role"+f+"info","core_role",k);null===l&&(l=new M.core.dialogue({draggable:!0,modal:!0,closeButton:!0,width:"450px"})),l.set("headerContent",M.util.get_string("role"+f+"header","core_role"));var o,p,q=[];switch(f){case"allow":p=h.find(j.REMOVEROLE);break;case"prohibit":p=h.find(j.UNPROHIBIT)}for(o in i){var r="",s=p.filter("[data-role-id='"+o+"']").length;s&&(r="disabled");var t={roleid:o,rolename:i[o],disabled:r};q.push(t)}d.render("core/permissionmanager_panelcontent",{message:m,roles:q}).done(function(b){l.set("bodyContent",b),l.show(),a("div.role_buttons").delegate("input","click",function(b){var c=a(b.currentTarget).data("role-id");n(h,c,f)})}).fail(c.exception)})}),m()},p=function(b){b.preventDefault(),a("body").one("rolesloaded",function(){var d=a(b.currentTarget),e=d.data("action"),f=d.data("role-id"),h=d.closest("tr.rolecap"),j={role:i[f],cap:h.data("humanname"),context:g};c.confirm(M.util.get_string("confirmunassigntitle","core_role"),M.util.get_string("confirmrole"+e,"core_role",j),M.util.get_string("confirmunassignyes","core_role"),M.util.get_string("confirmunassignno","core_role"),function(){n(h,f,e)})}),m()};return{initialize:function(b){f=b.contextid,g=b.contextname,h=b.adminurl;var c=a("body");c.delegate(j.ADDROLE,"click",o),c.delegate(j.REMOVEROLE,"click",p)}}}); \ No newline at end of file +define(["jquery","core/config","core/notification","core/templates","core/yui"],function(a,b,c,d,e){var f,g,h,i,j={ADDROLE:"a.allowlink, a.prohibitlink",REMOVEROLE:"a.preventlink, a.unprohibitlink",UNPROHIBIT:"a.unprohibitlink"},k=a.Event("rolesloaded"),l=null,m=function(){var d={contextid:f,getroles:1,sesskey:b.sesskey};a.post(h+"roles/ajax.php",d,null,"json").done(function(b){try{i=b,m=function(){a("body").trigger(k)},m()}catch(d){c.exception(d)}}).fail(function(a,b,d){c.exception(d)})},n=function(b,e,g){var j={contextid:f,roleid:e,sesskey:M.cfg.sesskey,action:g,capability:b.data("name")};a.post(h+"roles/ajax.php",j,null,"json").done(function(f){var g=f;try{var j={rolename:i[e],roleid:e,adminurl:h,imageurl:M.util.image_url("t/delete","moodle")};switch(g){case"allow":j.spanclass="allowed",j.linkclass="preventlink",j.action="prevent",j.icon="t/delete",j.iconalt=M.util.get_string("deletexrole","core_role",i[e]);break;case"prohibit":j.spanclass="forbidden",j.linkclass="unprohibitlink",j.action="unprohibit",j.icon="t/delete",j.iconalt=M.util.get_string("deletexrole","core_role",i[e]);break;case"prevent":return void b.find('a[data-role-id="'+e+'"]').first().closest(".allowed").remove();case"unprohibit":return void b.find('a[data-role-id="'+e+'"]').first().closest(".forbidden").remove();default:return}d.render("core/permissionmanager_role",j).done(function(c){if("allow"==g)a(c).insertBefore(b.find(".allowmore:first"));else if("prohibit"==g){a(c).insertBefore(b.find(".prohibitmore:first"));var d=b.find(".allowedroles").first().find('a[data-role-id="'+e+'"]');d&&d.first().closest(".allowed").remove()}l.hide()}).fail(c.exception)}catch(k){c.exception(k)}}).fail(function(a,b,d){c.exception(d)})},o=function(b){b.preventDefault();var f=a(b.currentTarget);a("body").one("rolesloaded",function(){e.use("moodle-core-notification-dialogue",function(){var b=f.data("action"),e=f.closest("tr.rolecap"),h={cap:e.data("humanname"),context:g},k=M.util.get_string("role"+b+"info","core_role",h);null===l&&(l=new M.core.dialogue({draggable:!0,modal:!0,closeButton:!0,width:"450px"})),l.set("headerContent",M.util.get_string("role"+b+"header","core_role"));var m,o,p=[];switch(b){case"allow":o=e.find(j.REMOVEROLE);break;case"prohibit":o=e.find(j.UNPROHIBIT)}for(m in i){var q="",r=o.filter("[data-role-id='"+m+"']").length;r&&(q="disabled");var s={roleid:m,rolename:i[m],disabled:q};p.push(s)}d.render("core/permissionmanager_panelcontent",{message:k,roles:p}).done(function(c){l.set("bodyContent",c),l.show(),a("div.role_buttons").delegate("input","click",function(c){var d=a(c.currentTarget).data("role-id");n(e,d,b)})}).fail(c.exception)})}),m()},p=function(b){b.preventDefault();var d=a(b.currentTarget);a("body").one("rolesloaded",function(){var a=d.data("action"),b=d.data("role-id"),e=d.closest("tr.rolecap"),f={role:i[b],cap:e.data("humanname"),context:g};c.confirm(M.util.get_string("confirmunassigntitle","core_role"),M.util.get_string("confirmrole"+a,"core_role",f),M.util.get_string("confirmunassignyes","core_role"),M.util.get_string("confirmunassignno","core_role"),function(){n(e,b,a)})}),m()};return{initialize:function(b){f=b.contextid,g=b.contextname,h=b.adminurl;var c=a("body");c.delegate(j.ADDROLE,"click",o),c.delegate(j.REMOVEROLE,"click",p)}}}); \ No newline at end of file diff --git a/lib/amd/src/permissionmanager.js b/lib/amd/src/permissionmanager.js index 5812ef36df42d..c799763b0386e 100644 --- a/lib/amd/src/permissionmanager.js +++ b/lib/amd/src/permissionmanager.js @@ -157,10 +157,11 @@ define(['jquery', 'core/config', 'core/notification', 'core/templates', 'core/yu var handleAddRole = function(e) { e.preventDefault(); + var link = $(e.currentTarget); + // TODO: MDL-57778 Convert to core/modal. - Y.use('moodle-core-notification-dialogue', function() { - $('body').one('rolesloaded', function() { - var link = $(e.currentTarget); + $('body').one('rolesloaded', function() { + Y.use('moodle-core-notification-dialogue', function() { var action = link.data('action'); var row = link.closest('tr.rolecap'); var confirmationDetails = { @@ -224,8 +225,8 @@ define(['jquery', 'core/config', 'core/notification', 'core/templates', 'core/yu */ var handleRemoveRole = function(e) { e.preventDefault(); + var link = $(e.currentTarget); $('body').one('rolesloaded', function() { - var link = $(e.currentTarget); var action = link.data('action'); var roleid = link.data('role-id'); var row = link.closest('tr.rolecap'); diff --git a/lib/tests/behat/permissionmanager.feature b/lib/tests/behat/permissionmanager.feature new file mode 100644 index 0000000000000..bd96363e0b9ee --- /dev/null +++ b/lib/tests/behat/permissionmanager.feature @@ -0,0 +1,51 @@ +@core @javascript +Feature: Override permissions on a context + In order to extend and restrict moodle features + As an admin or a teacher + I need to allow/deny the existing capabilities at different levels + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | t1@example.com | + And the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + + Scenario: Default system capabilities modification + Given I log in as "admin" + And I am on "Course 1" course homepage + And I navigate to "Users > Permissions" in current page administration + When I click on "Allow" "icon" in the "mod/forum:addnews" "table_row" + And I press "Student" + Then "Add announcementsmod/forum:addnews" row "Roles with permission" column of "permissions" table should contain "Student" + When I reload the page + And I click on "Delete Student role" "link" in the "mod/forum:addnews" "table_row" + And I click on "Remove" "button" in the "Confirm role change" "dialogue" + Then "Add announcementsmod/forum:addnews" row "Roles with permission" column of "permissions" table should not contain "Student" + When I reload the page + And I click on "Prohibit" "icon" in the "mod/forum:addnews" "table_row" + And I press "Student" + Then "Add announcementsmod/forum:addnews" row "Prohibited" column of "permissions" table should contain "Student" + + Scenario: Module capabilities overrides + Given I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I add a "Forum" to section "1" and I fill the form with: + | Forum name | Forum 1 | + And I follow "Forum 1" + And I navigate to "Permissions" in current page administration + When I click on "Allow" "icon" in the "mod/forum:addnews" "table_row" + And I press "Student" + Then "Add announcementsmod/forum:addnews" row "Roles with permission" column of "permissions" table should contain "Student" + When I reload the page + And I click on "Delete Student role" "link" in the "mod/forum:addnews" "table_row" + And I click on "Remove" "button" in the "Confirm role change" "dialogue" + Then "Add announcementsmod/forum:addnews" row "Roles with permission" column of "permissions" table should not contain "Student" + When I reload the page + And I click on "Prohibit" "icon" in the "mod/forum:addnews" "table_row" + And I press "Student" + Then "Add announcementsmod/forum:addnews" row "Prohibited" column of "permissions" table should contain "Student" From cee73270c75916fc31cf34a33c4ba2cf19a91f3e Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Thu, 14 Mar 2019 17:55:06 +1100 Subject: [PATCH 038/786] MDL-64523 core_access: replace .delegate with .on As of jQuery 3.0, .delegate() has been deprecated. It was superseded by the .on() method since jQuery 1.7, so its use was already discouraged. --- lib/amd/build/permissionmanager.min.js | 2 +- lib/amd/src/permissionmanager.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/amd/build/permissionmanager.min.js b/lib/amd/build/permissionmanager.min.js index e48ff7d915055..0ed75d137688e 100644 --- a/lib/amd/build/permissionmanager.min.js +++ b/lib/amd/build/permissionmanager.min.js @@ -1 +1 @@ -define(["jquery","core/config","core/notification","core/templates","core/yui"],function(a,b,c,d,e){var f,g,h,i,j={ADDROLE:"a.allowlink, a.prohibitlink",REMOVEROLE:"a.preventlink, a.unprohibitlink",UNPROHIBIT:"a.unprohibitlink"},k=a.Event("rolesloaded"),l=null,m=function(){var d={contextid:f,getroles:1,sesskey:b.sesskey};a.post(h+"roles/ajax.php",d,null,"json").done(function(b){try{i=b,m=function(){a("body").trigger(k)},m()}catch(d){c.exception(d)}}).fail(function(a,b,d){c.exception(d)})},n=function(b,e,g){var j={contextid:f,roleid:e,sesskey:M.cfg.sesskey,action:g,capability:b.data("name")};a.post(h+"roles/ajax.php",j,null,"json").done(function(f){var g=f;try{var j={rolename:i[e],roleid:e,adminurl:h,imageurl:M.util.image_url("t/delete","moodle")};switch(g){case"allow":j.spanclass="allowed",j.linkclass="preventlink",j.action="prevent",j.icon="t/delete",j.iconalt=M.util.get_string("deletexrole","core_role",i[e]);break;case"prohibit":j.spanclass="forbidden",j.linkclass="unprohibitlink",j.action="unprohibit",j.icon="t/delete",j.iconalt=M.util.get_string("deletexrole","core_role",i[e]);break;case"prevent":return void b.find('a[data-role-id="'+e+'"]').first().closest(".allowed").remove();case"unprohibit":return void b.find('a[data-role-id="'+e+'"]').first().closest(".forbidden").remove();default:return}d.render("core/permissionmanager_role",j).done(function(c){if("allow"==g)a(c).insertBefore(b.find(".allowmore:first"));else if("prohibit"==g){a(c).insertBefore(b.find(".prohibitmore:first"));var d=b.find(".allowedroles").first().find('a[data-role-id="'+e+'"]');d&&d.first().closest(".allowed").remove()}l.hide()}).fail(c.exception)}catch(k){c.exception(k)}}).fail(function(a,b,d){c.exception(d)})},o=function(b){b.preventDefault();var f=a(b.currentTarget);a("body").one("rolesloaded",function(){e.use("moodle-core-notification-dialogue",function(){var b=f.data("action"),e=f.closest("tr.rolecap"),h={cap:e.data("humanname"),context:g},k=M.util.get_string("role"+b+"info","core_role",h);null===l&&(l=new M.core.dialogue({draggable:!0,modal:!0,closeButton:!0,width:"450px"})),l.set("headerContent",M.util.get_string("role"+b+"header","core_role"));var m,o,p=[];switch(b){case"allow":o=e.find(j.REMOVEROLE);break;case"prohibit":o=e.find(j.UNPROHIBIT)}for(m in i){var q="",r=o.filter("[data-role-id='"+m+"']").length;r&&(q="disabled");var s={roleid:m,rolename:i[m],disabled:q};p.push(s)}d.render("core/permissionmanager_panelcontent",{message:k,roles:p}).done(function(c){l.set("bodyContent",c),l.show(),a("div.role_buttons").delegate("input","click",function(c){var d=a(c.currentTarget).data("role-id");n(e,d,b)})}).fail(c.exception)})}),m()},p=function(b){b.preventDefault();var d=a(b.currentTarget);a("body").one("rolesloaded",function(){var a=d.data("action"),b=d.data("role-id"),e=d.closest("tr.rolecap"),f={role:i[b],cap:e.data("humanname"),context:g};c.confirm(M.util.get_string("confirmunassigntitle","core_role"),M.util.get_string("confirmrole"+a,"core_role",f),M.util.get_string("confirmunassignyes","core_role"),M.util.get_string("confirmunassignno","core_role"),function(){n(e,b,a)})}),m()};return{initialize:function(b){f=b.contextid,g=b.contextname,h=b.adminurl;var c=a("body");c.delegate(j.ADDROLE,"click",o),c.delegate(j.REMOVEROLE,"click",p)}}}); \ No newline at end of file +define(["jquery","core/config","core/notification","core/templates","core/yui"],function(a,b,c,d,e){var f,g,h,i,j={ADDROLE:"a.allowlink, a.prohibitlink",REMOVEROLE:"a.preventlink, a.unprohibitlink",UNPROHIBIT:"a.unprohibitlink"},k=a.Event("rolesloaded"),l=null,m=function(){var d={contextid:f,getroles:1,sesskey:b.sesskey};a.post(h+"roles/ajax.php",d,null,"json").done(function(b){try{i=b,m=function(){a("body").trigger(k)},m()}catch(d){c.exception(d)}}).fail(function(a,b,d){c.exception(d)})},n=function(b,e,g){var j={contextid:f,roleid:e,sesskey:M.cfg.sesskey,action:g,capability:b.data("name")};a.post(h+"roles/ajax.php",j,null,"json").done(function(f){var g=f;try{var j={rolename:i[e],roleid:e,adminurl:h,imageurl:M.util.image_url("t/delete","moodle")};switch(g){case"allow":j.spanclass="allowed",j.linkclass="preventlink",j.action="prevent",j.icon="t/delete",j.iconalt=M.util.get_string("deletexrole","core_role",i[e]);break;case"prohibit":j.spanclass="forbidden",j.linkclass="unprohibitlink",j.action="unprohibit",j.icon="t/delete",j.iconalt=M.util.get_string("deletexrole","core_role",i[e]);break;case"prevent":return void b.find('a[data-role-id="'+e+'"]').first().closest(".allowed").remove();case"unprohibit":return void b.find('a[data-role-id="'+e+'"]').first().closest(".forbidden").remove();default:return}d.render("core/permissionmanager_role",j).done(function(c){if("allow"==g)a(c).insertBefore(b.find(".allowmore:first"));else if("prohibit"==g){a(c).insertBefore(b.find(".prohibitmore:first"));var d=b.find(".allowedroles").first().find('a[data-role-id="'+e+'"]');d&&d.first().closest(".allowed").remove()}l.hide()}).fail(c.exception)}catch(k){c.exception(k)}}).fail(function(a,b,d){c.exception(d)})},o=function(b){b.preventDefault();var f=a(b.currentTarget);a("body").one("rolesloaded",function(){e.use("moodle-core-notification-dialogue",function(){var b=f.data("action"),e=f.closest("tr.rolecap"),h={cap:e.data("humanname"),context:g},k=M.util.get_string("role"+b+"info","core_role",h);null===l&&(l=new M.core.dialogue({draggable:!0,modal:!0,closeButton:!0,width:"450px"})),l.set("headerContent",M.util.get_string("role"+b+"header","core_role"));var m,o,p=[];switch(b){case"allow":o=e.find(j.REMOVEROLE);break;case"prohibit":o=e.find(j.UNPROHIBIT)}for(m in i){var q="",r=o.filter("[data-role-id='"+m+"']").length;r&&(q="disabled");var s={roleid:m,rolename:i[m],disabled:q};p.push(s)}d.render("core/permissionmanager_panelcontent",{message:k,roles:p}).done(function(c){l.set("bodyContent",c),l.show(),a("div.role_buttons").on("click","input",function(c){var d=a(c.currentTarget).data("role-id");n(e,d,b)})}).fail(c.exception)})}),m()},p=function(b){b.preventDefault();var d=a(b.currentTarget);a("body").one("rolesloaded",function(){var a=d.data("action"),b=d.data("role-id"),e=d.closest("tr.rolecap"),f={role:i[b],cap:e.data("humanname"),context:g};c.confirm(M.util.get_string("confirmunassigntitle","core_role"),M.util.get_string("confirmrole"+a,"core_role",f),M.util.get_string("confirmunassignyes","core_role"),M.util.get_string("confirmunassignno","core_role"),function(){n(e,b,a)})}),m()};return{initialize:function(b){f=b.contextid,g=b.contextname,h=b.adminurl;var c=a("body");c.on("click",j.ADDROLE,o),c.on("click",j.REMOVEROLE,p)}}}); \ No newline at end of file diff --git a/lib/amd/src/permissionmanager.js b/lib/amd/src/permissionmanager.js index c799763b0386e..07721043e58eb 100644 --- a/lib/amd/src/permissionmanager.js +++ b/lib/amd/src/permissionmanager.js @@ -204,7 +204,7 @@ define(['jquery', 'core/config', 'core/notification', 'core/templates', 'core/yu .done(function(content) { panel.set('bodyContent', content); panel.show(); - $('div.role_buttons').delegate('input', 'click', function(e) { + $('div.role_buttons').on('click', 'input', function(e) { var roleid = $(e.currentTarget).data('role-id'); changePermissions(row, roleid, action); }); @@ -259,8 +259,8 @@ define(['jquery', 'core/config', 'core/notification', 'core/templates', 'core/yu contextname = args.contextname; adminurl = args.adminurl; var body = $('body'); - body.delegate(SELECTORS.ADDROLE, 'click', handleAddRole); - body.delegate(SELECTORS.REMOVEROLE, 'click', handleRemoveRole); + body.on('click', SELECTORS.ADDROLE, handleAddRole); + body.on('click', SELECTORS.REMOVEROLE, handleRemoveRole); } }; }); From fc00a6641c8ade7745493c7c8aaacecbe4f1f997 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Sat, 25 May 2019 04:57:22 +1000 Subject: [PATCH 039/786] MDL-65689 task: fix typo in help string --- admin/tool/task/cli/schedule_task.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/tool/task/cli/schedule_task.php b/admin/tool/task/cli/schedule_task.php index cf03700bd4f9d..85d7a4fd6ceeb 100644 --- a/admin/tool/task/cli/schedule_task.php +++ b/admin/tool/task/cli/schedule_task.php @@ -50,7 +50,7 @@ -h, --help Print out this help Example: -\$sudo -u www-data /usr/bin/php admin/tool/task/cli/scheduled_task.php --execute=\\\\core\\\\task\\\\session_cleanup_task +\$sudo -u www-data /usr/bin/php admin/tool/task/cli/schedule_task.php --execute=\\\\core\\\\task\\\\session_cleanup_task "; From 5d4bf77a169101b2559b43948f1884aaeede3681 Mon Sep 17 00:00:00 2001 From: AMOS bot Date: Sat, 25 May 2019 00:08:33 +0000 Subject: [PATCH 040/786] Automatically generated installer lang files --- install/lang/el/admin.php | 4 ++-- install/lang/el/error.php | 2 +- install/lang/el/install.php | 6 +++--- install/lang/pt/install.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/install/lang/el/admin.php b/install/lang/el/admin.php index a68438e39a6cd..4421c5ad64bb5 100644 --- a/install/lang/el/admin.php +++ b/install/lang/el/admin.php @@ -32,13 +32,13 @@ $string['clianswerno'] = 'ο'; $string['cliansweryes'] = 'ν'; -$string['cliincorrectvalueerror'] = 'Σφάλμα, λανθασμένη τιμή "{$a->value}" για το "{$a->option}"'; +$string['cliincorrectvalueerror'] = 'Σφάλμα, λανθασμένη τιμή «{$a->value}» για το «{$a->option}»'; $string['cliincorrectvalueretry'] = 'Λανθασμένη τιμή. Παρακαλούμε προσπαθήστε ξανά.'; $string['clitypevalue'] = 'πληκτρολογήστε μια τιμή'; $string['clitypevaluedefault'] = 'πληκτρολογήστε μια τιμή· πατήστε Enter για να χρησιμοποιήσετε τηνπροεπιλεγμένη τιμή ({$a})'; $string['cliunknowoption'] = 'Μη αναγνωρίσιμες επιλογές: {$a}
Παρακαλούμε χρησιμοποιήστε την επιλογή --βοήθεια'; -$string['cliyesnoprompt'] = 'πατώντας y (σημαίνει yes=ναι) αλλιώς πατώντας n (σημαίνει no=όχι)'; +$string['cliyesnoprompt'] = 'πατήστε y (σημαίνει yes=ναι) ή πατήστε n (σημαίνει no=όχι)'; $string['environmentrequireinstall'] = 'απαιτείται να εγκατασταθεί/ ενεργοποιηθεί'; $string['environmentrequireversion'] = 'απαιτείται η έκδοση {$a->needed} ενώ εσείς έχετε την {$a->current}'; $string['upgradekeyset'] = 'Κλειδί αναβάθμισης (αφήστε κενό για να μην το ορίσετε)'; diff --git a/install/lang/el/error.php b/install/lang/el/error.php index b4a6f49486599..bf4b25dd8b6d7 100644 --- a/install/lang/el/error.php +++ b/install/lang/el/error.php @@ -44,7 +44,7 @@ $string['downloadedfilecheckfailed'] = 'Αποτυχία ελέγχου αρχείου που έγινε λήψη'; $string['invalidmd5'] = 'Μη έγκυρο md5'; $string['missingrequiredfield'] = 'Κάποιο απαιτούμενο πεδίο λείπει'; -$string['remotedownloaderror'] = '

Απέτυχε η λήψη του τμήματος στον εξυπηρετητή σας. Παρακαλούμε επιβεβαιώστε τις ρυθμίσεις του διακομιστή μεσολάβησης (proxy)· η επέκταση PHP cURL συνιστάται θερμά.

Πρέπει να κατεβάσετε το {$a->url} χειροκίνητα, να το αντιγράψετε στο "{$a->dest}" στον εξυπηρετητή σας και να το αποσυμπιέσετε εκεί.

'; +$string['remotedownloaderror'] = '

Απέτυχε η λήψη του τμήματος στον εξυπηρετητή σας. Παρακαλούμε επιβεβαιώστε τις ρυθμίσεις του διακομιστή μεσολάβησης (proxy)· η επέκταση PHP cURL συνιστάται θερμά.

Πρέπει να κατεβάσετε το {$a->url} χειροκίνητα, να το αντιγράψετε στο «{$a->dest}» στον εξυπηρετητή σας και να το αποσυμπιέσετε εκεί.

'; $string['wrongdestpath'] = 'Λανθασμένη διαδρομή προορισμού (πλήρες όνομα).'; $string['wrongsourcebase'] = 'Λανθασμένη βάση πηγής URL.'; $string['wrongzipfilename'] = 'Λανθασμένo όνομα αρχείου ZIP.'; diff --git a/install/lang/el/install.php b/install/lang/el/install.php index 98744e2a185cd..37efea7bbbe26 100644 --- a/install/lang/el/install.php +++ b/install/lang/el/install.php @@ -49,7 +49,7 @@ Ο πλήρης έλεγχος του περιβάλλοντος πραγματοποιείται πριν κάθε εγκατάσταση και αναβάθμιση. Παρακαλούμε επικοινωνήστε με τον διαχειριστή του εξυπηρετητή εάν δεν ξέρετε πως να εγκαταστήσετε νέα έκδοση της PHP ή να ενεργοποιήσετε επεκτάσεις της.'; $string['errorsinenvironment'] = 'Ο έλεγχος του περιβάλλοντος απέτυχε!'; $string['installation'] = 'Εγκατάσταση'; -$string['langdownloaderror'] = 'Δυστυχώς η γλώσσα "{$a}" δεν είναι εγκατεστημένη. Η εγκατάσταση θα συνεχιστεί στα αγγλικά.'; +$string['langdownloaderror'] = 'Δυστυχώς η γλώσσα «{$a}» δεν είναι εγκατεστημένη. Η εγκατάσταση θα συνεχιστεί στα αγγλικά.'; $string['memorylimithelp'] = '

Το όριο μνήμης της PHP στον εξυπηρετητή σας είναι ορισμένο αυτή τη στιγμή στα {$a}.

Αυτό μπορεί να προκαλέσει προβλήματα μνήμης στο Moodle στη συνέχεια, ειδικά αν έχετε πολλά ενεργοποιημένα αρθρώματα και/ή πολλούς χρήστες.

Προτείνεται η ρύθμιση της PHP με μεγαλύτερο όριο, αν αυτό είναι δυνατό, π.χ. 40M. Υπάρχουν πολλοί τρόποι να το κάνετε αυτό, τους οποίους μπορείτε να δοκιμάσετε:

  1. Αν έχετε τη δυνατότητα, κάνετε επαναμεταγλώττιση την PHP με την παράμετρο --enable-memory-limit. Αυτό θα επιτρέψει στο Moodle να ορίσει μόνο του το όριο μνήμης.
  2. Αν έχετε πρόσβαση στο αρχείο php.ini, μπορείτε να αλλάξετε τη ρύθμιση memory_limit σε 40M. Αν δεν έχετε πρόσβαση ζητήστε από το διαχειριστή να το κάνει για εσάς.
  3. Σε κάποιους εξυπηρετητές PHP μπορείτε να δημιουργήσετε ένα αρχείο .htaccess στο φάκελο του Moodle που να περιέχει τις παρακάτω γραμμές:

    php_value memory_limit 40M

Ωστόσο, σε κάποιους εξυπηρετητές αυτό θα εμποδίσει τη λειτουργία όλων των σελιδών PHP (θα βλέπετε σφάλματα όταν ανοίγετε τις σελίδες), οπότε θα πρέπει να διαγράψετε το αρχείο .htaccess.

'; $string['paths'] = 'Διαδρομές'; $string['pathserrcreatedataroot'] = 'Ο Φάκελος δεδομένων ({$a->dataroot}) δεν μπορεί να δημιουργθεί από το πρόγραμμα εγκατάστασης.'; @@ -57,7 +57,7 @@ $string['pathsrodataroot'] = 'Ο Φάκελος Δεδομένων δεν είναι εγγράψιμος.'; $string['pathsroparentdataroot'] = 'Ο γονικός φάκελος ({$a->parent}) δεν είναι εγγράψιμος. Ο φάκελος δεδομένων ({$a->dataroot}) δεν μπορεί να δημιουργθεί από το πρόγραμμα εγκατάστασης.'; $string['pathssubadmindir'] = 'Κάποιοι λίγοι κεντρικοί υπολογιστές ιστού χρησιμοποιούν το /admin ως ειδική διεύθυνση URL για την πρόσβαση σε κάποιο πίνακα ελέγχου ή κάτι τέτοιο. Δυστυχώς αυτό έρχεται σε αντίθεση με την τυπική τοποθεσία των σελίδων διαχείρισης (admin) του Moodle. Αυτό μπορεί να διορθωθεί με την μετονομασία του admin φακέλου στην εγκατάστασή σας, και βάζοντας αυτό το καινούργιο όνομα εδώ. Για παράδειγμα: moodleadmin. Αυτό θα διορθώσει όλους τους συνδέσμους με το admin στην διεύθυνσή τους σε όλη την εγκατάσταση του Moodle σας.'; -$string['pathssubdataroot'] = '

Ένας φάκελος όπου το Moodle θα αποθηκεύει όλα τα ανεβασμένα από τους χρήστες αρχεία.

Αυτος ο φάκελος θα πρέπει να είναι αναγνώσιμος ΚΑΙ ΕΓΓΡΑΨΙΜΟΣ από τον χρήστη του εξυπηρετητή ιστού (συνήθως \'nobody\' ή \'apache\').

Δεν πρέπει να είναι προσβάσιμος κατευθείαν από τον ιστό.

Αν ο φάκελος δεν υπάρχει, η διαδικασία εγκατάστασης θα προσπαθήσει να τον δημιουργήσει.

'; +$string['pathssubdataroot'] = '

Ένας φάκελος όπου το Moodle θα αποθηκεύει όλα τα ανεβασμένα από τους χρήστες αρχεία.

Αυτος ο φάκελος θα πρέπει να είναι αναγνώσιμος ΚΑΙ ΕΓΓΡΑΨΙΜΟΣ από τον χρήστη του εξυπηρετητή ιστού (συνήθως «nobody» ή «apache»).

Δεν πρέπει να είναι προσβάσιμος κατευθείαν από τον ιστό.

Αν ο φάκελος δεν υπάρχει, η διαδικασία εγκατάστασης θα προσπαθήσει να τον δημιουργήσει.

'; $string['pathssubdirroot'] = '

Η πλήρης διαδρομή του φακέλου που περιέχει τα αρχεία κώδικα του Moodle.

'; $string['pathssubwwwroot'] = '

Η πλήρης διεύθυνση (ιστού) από την οποία θα γίνεται η πρόσβαση στο Moodle, δηλαδή η διεύθυνση που οι χρήστες θα εισάγουν στην γραμμή διεύθυνσης του περιηγητή, για να έχουν πρόσβαση στου Moodle.

Δεν είναι δυνατόν να έχετε πρόβαση στο Moodle χρησιμοποιώντας πολλαπλές διευθύνσεις. Εάν ο ιστότοπος θα είναι προσβάσιμος μέσω πολλαπλών διευθύνσεων τότε επιλέξτε την ευκολότερη και εγκαταστήστε μια μόνιμη ανακατεύθυνση για καθεμία από τις άλλες διευθύνσεις.

@@ -76,5 +76,5 @@ $string['welcomep40'] = 'Το πακέτο περιλαμβάνει επίσης το Moodle {$a->moodlerelease} ({$a->moodleversion}).'; $string['welcomep50'] = 'Η χρήση όλων των εφαρμογών σε αυτό το πακέτο υπόκειται στις αντίστοιχες άδειες. Ολόκληρο το πακέτο {$a->installername} είναι λογισμικό ανοικτού κώδικα και διανέμεται με την GPL άδεια.'; $string['welcomep60'] = 'Οι παρακάτω σελίδες θα σας καθοδηγήσουν με εύκολα βήματα στην εγκατάσταση και ρύθμιση του Moodle στον υπολογιστή σας. Μπορείτε να δεχθείτε τις προεπιλεγμένες ρυθμίσεις ή προαιρετικά, να τις τροποποιήσετε ανάλογα με τις ανάγκες σας.'; -$string['welcomep70'] = 'Πατήστε το κουμπί "Συνέχεια" για να συνεχίσετε με την εκγατάσταση του Moodle.'; +$string['welcomep70'] = 'Πατήστε το κουμπί «Συνέχεια» για να συνεχίσετε με την εγκατάσταση του Moodle.'; $string['wwwroot'] = 'Διεύθυνση ιστού'; diff --git a/install/lang/pt/install.php b/install/lang/pt/install.php index 4ff411011fe4e..4affb829e0b08 100644 --- a/install/lang/pt/install.php +++ b/install/lang/pt/install.php @@ -61,7 +61,7 @@

Não deve ser diretamente acessível através da web.

Se a diretoria não existir atualmente, o processo de instalação tentará criá-la.

'; $string['pathssubdirroot'] = 'Caminho completo para a diretoria que contém o código Moodle.'; -$string['pathssubwwwroot'] = 'Endereço web completo de acesso ao Moodle. Não é possível aceder ao Moodle usando mais do que um endereço. Se o site tiver mais do que um endereço público, devem ser configurados redirecionamentos permanentes em todos eles, à exceção deste. Se o site pode ser acedido a partir da Internet e de Intranet, então use o endereço público aqui. Se o endereço atual não está correto, altere o endereço indicado na barra de endereço do seu navegador e reinicie a instalação.'; +$string['pathssubwwwroot'] = 'Endereço web completo de acesso ao Moodle. Não é possível aceder ao Moodle usando mais do que um endereço. Se o site tiver mais do que um endereço público, devem ser configurados redirecionamentos permanentes em todos eles, à exceção deste. Se o site pode ser acedido a partir da Internet e de Intranet, use o endereço público aqui. Se o endereço atual não está correto, altere o endereço indicado na barra de endereço do seu navegador e reinicie a instalação.'; $string['pathsunsecuredataroot'] = 'A localização da pasta de dados não é segura'; $string['pathswrongadmindir'] = 'A pasta admin não existe'; $string['phpextension'] = 'Extensão {$a} do PHP'; From d855dcd29eda8a06c06d4c8f4afb0baacc6be2a5 Mon Sep 17 00:00:00 2001 From: AMOS bot Date: Sat, 25 May 2019 00:08:34 +0000 Subject: [PATCH 041/786] Automatically generated installer lang files --- install/lang/ca_wp/langconfig.php | 34 +++++++++++++++++++++++++++++++ install/lang/el_wp/langconfig.php | 34 +++++++++++++++++++++++++++++++ install/lang/rw/langconfig.php | 34 +++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 install/lang/ca_wp/langconfig.php create mode 100644 install/lang/el_wp/langconfig.php create mode 100644 install/lang/rw/langconfig.php diff --git a/install/lang/ca_wp/langconfig.php b/install/lang/ca_wp/langconfig.php new file mode 100644 index 0000000000000..2684abc29d59c --- /dev/null +++ b/install/lang/ca_wp/langconfig.php @@ -0,0 +1,34 @@ +. + +/** + * Automatically generated strings for Moodle installer + * + * Do not edit this file manually! It contains just a subset of strings + * needed during the very first steps of installation. This file was + * generated automatically by export-installer.php (which is part of AMOS + * {@link http://docs.moodle.org/dev/Languages/AMOS}) using the + * list of strings defined in /install/stringnames.txt. + * + * @package installer + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$string['parentlanguage'] = 'ca'; +$string['thislanguage'] = 'Català per a Workplace'; diff --git a/install/lang/el_wp/langconfig.php b/install/lang/el_wp/langconfig.php new file mode 100644 index 0000000000000..b7b20f5f32a76 --- /dev/null +++ b/install/lang/el_wp/langconfig.php @@ -0,0 +1,34 @@ +. + +/** + * Automatically generated strings for Moodle installer + * + * Do not edit this file manually! It contains just a subset of strings + * needed during the very first steps of installation. This file was + * generated automatically by export-installer.php (which is part of AMOS + * {@link http://docs.moodle.org/dev/Languages/AMOS}) using the + * list of strings defined in /install/stringnames.txt. + * + * @package installer + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$string['parentlanguage'] = 'el'; +$string['thislanguage'] = 'Ελληνικά για Χώρους Εργασίας'; diff --git a/install/lang/rw/langconfig.php b/install/lang/rw/langconfig.php new file mode 100644 index 0000000000000..a214772b2275f --- /dev/null +++ b/install/lang/rw/langconfig.php @@ -0,0 +1,34 @@ +. + +/** + * Automatically generated strings for Moodle installer + * + * Do not edit this file manually! It contains just a subset of strings + * needed during the very first steps of installation. This file was + * generated automatically by export-installer.php (which is part of AMOS + * {@link http://docs.moodle.org/dev/Languages/AMOS}) using the + * list of strings defined in /install/stringnames.txt. + * + * @package installer + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$string['thisdirection'] = 'ltr'; +$string['thislanguage'] = 'Kinyarwanda'; From 88dfc54de94059a0399cd855220c121e64b89b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Monlla=C3=B3?= Date: Fri, 24 May 2019 10:59:13 +0200 Subject: [PATCH 042/786] MDL-65680 analytics: Fix random failure on slow test environments --- analytics/tests/analysis_test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/analytics/tests/analysis_test.php b/analytics/tests/analysis_test.php index 0f5f3e6ff3f44..3ceb40e0c243c 100644 --- a/analytics/tests/analysis_test.php +++ b/analytics/tests/analysis_test.php @@ -65,7 +65,7 @@ public function test_fill_firstanalyses_cache() { $this->assertEquals($afewsecsago, $firstanalyses[$modelid . '_' . $course1->id]); $this->assertEquals($afewsecsago + 1, $firstanalyses[$modelid . '_' . $course2->id]); - // The cached elements gets refreshed. + // The cached elements get refreshed. $this->insert_used($modelid, $course1->id, 'prediction', $earliest); $firstanalyses = \core_analytics\analysis::fill_firstanalyses_cache($modelid, $course1->id); $this->assertCount(1, $firstanalyses); @@ -78,7 +78,7 @@ public function test_fill_firstanalyses_cache() { // The generated ranges should start from the cached firstanalysis value, which is $earliest. $ranges = $seconds->get_all_ranges(); - $this->assertCount(7, $ranges); + $this->assertGreaterThanOrEqual(7, count($ranges)); $firstrange = reset($ranges); $this->assertEquals($earliest, $firstrange['time']); } From 4e9e994da467113bebe083fd94c3a6217c5942ec Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 22 May 2019 11:04:51 +0800 Subject: [PATCH 043/786] MDL-65675 forum: Remove duplicate Re in subjects --- mod/forum/amd/build/posts_list.min.js | 2 +- mod/forum/amd/src/posts_list.js | 2 +- mod/forum/classes/local/exporters/post.php | 8 ++++++++ mod/forum/templates/forum_discussion_post.mustache | 6 +++++- mod/forum/templates/inpage_reply.mustache | 2 +- mod/forum/tests/externallib_test.php | 2 ++ 6 files changed, 18 insertions(+), 4 deletions(-) diff --git a/mod/forum/amd/build/posts_list.min.js b/mod/forum/amd/build/posts_list.min.js index df43413cab250..b888a7fb6b27f 100644 --- a/mod/forum/amd/build/posts_list.min.js +++ b/mod/forum/amd/build/posts_list.min.js @@ -1 +1 @@ -define(["jquery","core/templates","core/notification","mod_forum/selectors","mod_forum/inpage_reply"],function(a,b,c,d,e){var f=function(f){f.on("click",d.post.inpageReplyLink,function(f){if(f.preventDefault(),window.location.hash){var g=window.location.href.split("#")[0];history.pushState({},document.title,g)}var h=a(f.currentTarget).parents(d.post.forumCoreContent),i=h.find(d.post.forumSubject),j=a(f.currentTarget).parents(d.post.forumContent),k={postid:a(j).data("post-id"),reply_url:a(f.currentTarget).attr("href"),sesskey:M.cfg.sesskey,parentsubject:i.html(),canreplyprivately:a(f.currentTarget).data("can-reply-privately"),postformat:e.CONTENT_FORMATS.MOODLE};if(j.find(d.post.inpageReplyContent).length){var l=j.find(d.post.inpageReplyContent);l.slideToggle(300),l.is(":visible")&&l.find("textarea").focus()}else b.render("mod_forum/inpage_reply",k).then(function(a,c){return b.appendNodeContents(h,a,c)}).then(function(){return j.find(d.post.inpageReplyContent).slideToggle(300).find("textarea").focus()}).fail(c.exception)})};return{init:function(a){f(a),e.init(a)}}}); \ No newline at end of file +define(["jquery","core/templates","core/notification","mod_forum/selectors","mod_forum/inpage_reply"],function(a,b,c,d,e){var f=function(f){f.on("click",d.post.inpageReplyLink,function(f){if(f.preventDefault(),window.location.hash){var g=window.location.href.split("#")[0];history.pushState({},document.title,g)}var h=a(f.currentTarget).parents(d.post.forumCoreContent),i=h.find(d.post.forumSubject),j=a(f.currentTarget).parents(d.post.forumContent),k={postid:a(j).data("post-id"),reply_url:a(f.currentTarget).attr("href"),sesskey:M.cfg.sesskey,parentsubject:i.data("replySubject"),canreplyprivately:a(f.currentTarget).data("can-reply-privately"),postformat:e.CONTENT_FORMATS.MOODLE};if(j.find(d.post.inpageReplyContent).length){var l=j.find(d.post.inpageReplyContent);l.slideToggle(300),l.is(":visible")&&l.find("textarea").focus()}else b.render("mod_forum/inpage_reply",k).then(function(a,c){return b.appendNodeContents(h,a,c)}).then(function(){return j.find(d.post.inpageReplyContent).slideToggle(300).find("textarea").focus()}).fail(c.exception)})};return{init:function(a){f(a),e.init(a)}}}); \ No newline at end of file diff --git a/mod/forum/amd/src/posts_list.js b/mod/forum/amd/src/posts_list.js index 5e24d7a5baf48..3fbc5933c7370 100644 --- a/mod/forum/amd/src/posts_list.js +++ b/mod/forum/amd/src/posts_list.js @@ -59,7 +59,7 @@ define([ postid: $(currentRoot).data('post-id'), "reply_url": $(e.currentTarget).attr('href'), sesskey: M.cfg.sesskey, - parentsubject: currentSubject.html(), + parentsubject: currentSubject.data('replySubject'), canreplyprivately: $(e.currentTarget).data('can-reply-privately'), postformat: InPageReply.CONTENT_FORMATS.MOODLE }; diff --git a/mod/forum/classes/local/exporters/post.php b/mod/forum/classes/local/exporters/post.php index 4528c602d8e25..a5bff7d43c31c 100644 --- a/mod/forum/classes/local/exporters/post.php +++ b/mod/forum/classes/local/exporters/post.php @@ -92,6 +92,7 @@ protected static function define_other_properties() { return [ 'id' => ['type' => PARAM_INT], 'subject' => ['type' => PARAM_TEXT], + 'replysubject' => ['type' => PARAM_TEXT], 'message' => ['type' => PARAM_RAW], 'messageformat' => ['type' => PARAM_INT], 'author' => ['type' => author_exporter::read_properties_definition()], @@ -401,9 +402,16 @@ protected function get_other_values(renderer_base $output) { } } + $replysubject = $subject; + $strre = get_string('re', 'forum'); + if (!(substr($replysubject, 0, strlen($strre)) == $strre)) { + $replysubject = "{$strre} {$replysubject}"; + } + return [ 'id' => $post->get_id(), 'subject' => $subject, + 'replysubject' => $replysubject, 'message' => $message, 'messageformat' => $post->get_message_format(), 'author' => $exportedauthor, diff --git a/mod/forum/templates/forum_discussion_post.mustache b/mod/forum/templates/forum_discussion_post.mustache index e5a8e1d1c4812..73e202ca532fe 100644 --- a/mod/forum/templates/forum_discussion_post.mustache +++ b/mod/forum/templates/forum_discussion_post.mustache @@ -67,7 +67,11 @@ {{#parentauthorname}} {{#str}} inreplyto, mod_forum, {{.}} {{/str}} {{/parentauthorname}} -

{{$subject}}{{{subject}}}{{/subject}}

+

{{$subject}}{{{subject}}}{{/subject}}

{{^isdeleted}}
{{#html.authorsubheading}}{{{.}}}{{/html.authorsubheading}} diff --git a/mod/forum/templates/inpage_reply.mustache b/mod/forum/templates/inpage_reply.mustache index 8a99d1d356da8..5ceb5c93c1e23 100644 --- a/mod/forum/templates/inpage_reply.mustache +++ b/mod/forum/templates/inpage_reply.mustache @@ -41,7 +41,7 @@ - +
diff --git a/mod/forum/tests/externallib_test.php b/mod/forum/tests/externallib_test.php index 5e903acbee59a..177bf1a169bb9 100644 --- a/mod/forum/tests/externallib_test.php +++ b/mod/forum/tests/externallib_test.php @@ -668,6 +668,7 @@ public function test_mod_forum_get_discussion_posts() { 'hasparent' => true, 'timecreated' => $discussion1reply2->created, 'subject' => $discussion1reply2->subject, + 'replysubject' => get_string('re', 'mod_forum') . " {$discussion1reply2->subject}", 'message' => file_rewrite_pluginfile_urls($discussion1reply2->message, 'pluginfile.php', $forum1context->id, 'mod_forum', 'post', $discussion1reply2->id), 'messageformat' => 1, // This value is usually changed by external_format_text() function. @@ -721,6 +722,7 @@ public function test_mod_forum_get_discussion_posts() { 'hasparent' => true, 'timecreated' => $discussion1reply1->created, 'subject' => $discussion1reply1->subject, + 'replysubject' => get_string('re', 'mod_forum') . " {$discussion1reply1->subject}", 'message' => file_rewrite_pluginfile_urls($discussion1reply1->message, 'pluginfile.php', $forum1context->id, 'mod_forum', 'post', $discussion1reply1->id), 'messageformat' => 1, // This value is usually changed by external_format_text() function. From 1f686d7fdfe6283fbe9588a882cae300f90cd007 Mon Sep 17 00:00:00 2001 From: Mathew May Date: Fri, 24 May 2019 16:39:15 +0800 Subject: [PATCH 044/786] MDL-65708 output: Get a base config from Boost As a part of the removal of bootstrapbase & clean I removed some logic that got the base config of bootstrapbase, this should of been changed to get boosts config. See: e00f1c663c1 --- lib/outputlib.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/outputlib.php b/lib/outputlib.php index a62786a6c413a..5a2c8319346a3 100644 --- a/lib/outputlib.php +++ b/lib/outputlib.php @@ -739,7 +739,11 @@ private function __construct($config) { $this->name = $config->name; $this->dir = $config->dir; - $baseconfig = $config; + if ($this->name != self::DEFAULT_THEME) { + $baseconfig = self::find_theme_config(self::DEFAULT_THEME, $this->settings); + } else { + $baseconfig = $config; + } $configurable = array( 'parents', 'sheets', 'parents_exclude_sheets', 'plugins_exclude_sheets', 'usefallback', From 946533c6238985d934eccd4e92e485f929214d60 Mon Sep 17 00:00:00 2001 From: Ryan Wyllie Date: Tue, 21 May 2019 11:40:36 +0800 Subject: [PATCH 045/786] MDL-65657 message: revert polling timeout back to old algorithm --- .../message_drawer_view_conversation.min.js | 2 +- ..._drawer_view_conversation_constants.min.js | 2 +- ...wer_view_conversation_state_manager.min.js | 2 +- .../src/message_drawer_view_conversation.js | 27 ++++++++++++------- ...sage_drawer_view_conversation_constants.js | 2 +- ..._drawer_view_conversation_state_manager.js | 15 ++++++++++- message/classes/helper.php | 8 ++++++ ...age_drawer_view_conversation_body.mustache | 3 +++ 8 files changed, 47 insertions(+), 14 deletions(-) diff --git a/message/amd/build/message_drawer_view_conversation.min.js b/message/amd/build/message_drawer_view_conversation.min.js index 63ce8d317f59e..972fcc33ed965 100644 --- a/message/amd/build/message_drawer_view_conversation.min.js +++ b/message/amd/build/message_drawer_view_conversation.min.js @@ -1 +1 @@ -define(["jquery","core/auto_rows","core/backoff_timer","core/custom_interaction_events","core/notification","core/pubsub","core/str","core_message/message_repository","core_message/message_drawer_events","core_message/message_drawer_view_conversation_constants","core_message/message_drawer_view_conversation_patcher","core_message/message_drawer_view_conversation_renderer","core_message/message_drawer_view_conversation_state_manager","core_message/message_drawer_router","core_message/message_drawer_routes"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p={},q=null,r=!1,s=0,t=null,u=!1,v=[],w=!0,x=!1,y=null,z=[],A=j.NEWEST_MESSAGES_FIRST,B=j.LOAD_MESSAGE_LIMIT,C=j.INITIAL_NEW_MESSAGE_POLL_TIMEOUT,D=j.SELECTORS,E=j.CONVERSATION_TYPES,F=function(){if(!q||q.type==E.PUBLIC)return null;var a=q.loggedInUserId;if(q.type==E.SELF)return a;var b=Object.keys(q.members).filter(function(b){return a!=b});return b.length?b[0]:null},G=function(a){return Object.keys(p).reduce(function(b,c){if(!b){var d=p[c].state;d.type!=E.PUBLIC&&a in d.members&&(b=d.id)}return b},null)},H=function(a){return{id:parseInt(a.attr("data-user-id"),10),fullname:null,profileimageurl:null,profileimageurlsmall:null,isonline:null,showonlinestatus:null,isblocked:null,iscontact:null,isdeleted:null,canmessage:null,requirescontact:null,contactrequests:[]}},I=function(){return s},J=function(a){s=a,p[q.id].messagesOffset=a},K=function(){return r},L=function(a){r=a,p[q.id].loadedAllMessages=a},M=function(a){return a.find(D.MESSAGES_CONTAINER)},N=function(b){return{id:b.id,name:b.name,subname:b.subname,imageUrl:b.imageUrl,isFavourite:b.isFavourite,isMuted:b.isMuted,type:b.type,totalMemberCount:b.totalMemberCount,loggedInUserId:b.loggedInUserId,messages:b.messages.map(function(b){return a.extend({},b)}),members:Object.keys(b.members).map(function(c){var d=a.extend({},b.members[c]);return d.contactrequests=b.members[c].contactrequests.map(function(b){return a.extend({},b)}),d})}},O=function(a,b){var c=a.id,d=c==b?E.SELF:E.PRIVATE,f=m.setLoadingMembers(q,!0);return f=m.setLoadingMessages(f,!0),y(f),h.getMemberInfo(c,[b],!0,!0).then(function(a){if(a.length)return a[0];throw new Error("Unable to load other user profile")}).then(function(b){var c=d==E.SELF?[b]:[b,a],e=m.addMembers(q,c);return e=m.setLoadingMembers(e,!1),e=m.setLoadingMessages(e,!1),e=m.setName(e,b.fullname),e=m.setType(e,d),e=m.setImageUrl(e,b.profileimageurl),e=m.setTotalMemberCount(e,c.length),y(e),b})["catch"](function(a){var b=m.setLoadingMembers(q,!1);y(b),e.exception(a)})},P=function(a,b){var c=null;if(a.type==E.PRIVATE){var d=a.members.filter(function(a){return a.id!=b});c=d.length?d[0]:null}else a.type==E.SELF&&(c=a.members[0]);var e=a.name,f=a.imageurl;a.type!=E.PUBLIC&&(e=e||c?c.fullname:"",f=f||c?c.profileimageurl:"");var g=m.addMembers(q,a.members);return g=m.setName(g,e),g=m.setSubname(g,a.subname),g=m.setType(g,a.type),g=m.setImageUrl(g,f),g=m.setTotalMemberCount(g,a.membercount),g=m.setIsFavourite(g,a.isfavourite),g=m.setIsMuted(g,a.ismuted),g=m.addMessages(g,a.messages),g=m.setCanDeleteMessagesForAllUsers(g,a.candeletemessagesforallusers)},Q=function(a,b,c,d,f){var g=b.id,i=m.setLoadingMembers(q,!0);return i=m.setLoadingMessages(i,!0),y(i),h.getConversation(g,a,!0,!0,0,0,c+1,d,f).then(function(a){return a.messages.length>c?a.messages=a.messages.slice(1):L(!0),J(d+c),a}).then(function(a){var c=a.members.filter(function(a){return a.id==b.id});c.length<1&&(a.members=a.members.concat([b]));var d=P(a,b.id);return d=m.setLoadingMembers(d,!1),d=m.setLoadingMessages(d,!1),y(d).then(function(){return a})}).then(function(){return U(a)})["catch"](function(a){var b=m.setLoadingMembers(q,!1);b=m.setLoadingMessages(b,!1),y(b),e.exception(a)})},R=function(a,b,c,d){var f=a.members.filter(function(a){return a.id==b.id});f.length<1&&(a.members=a.members.concat([b]));var g=a.messages.length,h=g>=c,i=P(a,b.id);i=m.setLoadingMembers(i,!1),i=m.setLoadingMessages(i,!h);var j=y(i);return j.then(function(){return h?{messages:a.messages}:S(a.id,c,g,d,[])}).then(function(){var a=q.messages;return J(a.length),U(q.id),a})["catch"](e.exception)},S=function(a,b,c,d,e,f){return h.getMessages(q.loggedInUserId,a,b?b+1:b,c,d,f).then(function(a){return a.messages.length&&e.length&&(a.messages=a.messages.filter(function(a){return e.indexOf(parseInt(a.id,10))<0})),a}).then(function(a){return b?(a.messages.length>b?a.messages=a.messages.slice(0,-1):L(!0),a):a}).then(function(a){var b=a.members.filter(function(a){return!(a.id in q.members)}),c=m.addMembers(q,b);return c=m.addMessages(c,a.messages),c=m.setLoadingMessages(c,!1),y(c).then(function(){return a})})["catch"](function(a){var b=m.setLoadingMessages(q,!1);throw y(b),a})},T=function(b,c){return function(){var d=q.messages,e=d.length?d[d.length-1]:null;if(e&&!w&&!x){for(var g=[],h=d.length-1;h>=0;h--){var j=d[h];if(j.timeCreated!==e.timeCreated)break;g.push(j.id)}return S(b,0,0,c,g,e.timeCreated).then(function(a){if(a.messages.length){t.restart();var c=N(q);return f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c),U(b)}return a})}return a.Deferred().resolve().promise()}},U=function(a){var b=q.loggedInUserId;return h.markAllConversationMessagesAsRead(b,a).then(function(){var b=m.markMessagesAsRead(q,q.messages);return f.publish(i.CONVERSATION_READ,a),y(b)})},V=function(a){ja(a);var b=m.addPendingBlockUsersById(q,[a]);y(b)},W=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.blockUser(q.loggedInUserId,a).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingBlockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_BLOCKED,a),y(c)})},X=function(a){ja(a);var b=m.addPendingUnblockUsersById(q,[a]);y(b)},Y=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.unblockUser(q.loggedInUserId,a).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingUnblockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_UNBLOCKED,a),y(c)})},Z=function(a){ja(a);var b=m.addPendingRemoveContactsById(q,[a]);y(b)},$=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.deleteContacts(q.loggedInUserId,[a]).then(function(b){var c=m.addMembers(q,b);return c=m.removePendingRemoveContactsById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_REMOVED,a),y(c)})},_=function(a){ja(a);var b=m.addPendingAddContactsById(q,[a]);y(b)},aa=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.createContactRequest(q.loggedInUserId,a).then(function(a){if(!a.request)throw new Error(a.warnings[0].message);return a.request}).then(function(b){var c=m.removePendingAddContactsById(q,[a]);return c=m.addContactRequests(c,[b]),c=m.setLoadingConfirmAction(c,!1),y(c)})},ba=function(){var a=q.loggedInUserId,b=q.id;return h.setFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!0);return y(a)}).then(function(){return f.publish(i.CONVERSATION_SET_FAVOURITE,N(q))})},ca=function(){var a=q.loggedInUserId,b=q.id;return h.unsetFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!1);return y(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_FAVOURITE,N(q))})},da=function(){var a=q.loggedInUserId,b=q.id;return h.setMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!0);return y(a)}).then(function(){return f.publish(i.CONVERSATION_SET_MUTED,N(q))})},ea=function(){var a=q.loggedInUserId,b=q.id;return h.unsetMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!1);return y(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_MUTED,N(q))})},fa=function(a){var b=q.selectedMessageIds;ja(a);var c=m.addPendingDeleteMessagesById(q,b);y(c)},ga=function(){var a=q.pendingDeleteMessageIds,b=m.setLoadingConfirmAction(q,!0);y(b);var c=null;return c=b.deleteMessagesForAllUsers?h.deleteMessagesForAllUsers(q.loggedInUserId,a):h.deleteMessages(q.loggedInUserId,a),c.then(function(){var b=m.removeMessagesById(q,a);b=m.removePendingDeleteMessagesById(b,a),b=m.removeSelectedMessagesById(b,a),b=m.setLoadingConfirmAction(b,!1),b=m.setDeleteMessagesForAllUsers(b,!1);var c=q.messages[q.messages.length-1],d=b.messages.length?b.messages[b.messages.length-1]:null;if(d&&d.id!=c.id){var e=N(b);f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,e)}else b.messages.length||f.publish(i.CONVERSATION_DELETED,b.id);return y(b)})},ha=function(a){ja(a);var b=m.setPendingDeleteConversation(q,!0);y(b)},ia=function(){var a=m.setLoadingConfirmAction(q,!0);return y(a),h.deleteConversation(q.loggedInUserId,q.id).then(function(){var a=m.removeMessages(q,q.messages);return a=m.removeSelectedMessagesById(a,q.selectedMessageIds),a=m.setPendingDeleteConversation(a,!1),a=m.setLoadingConfirmAction(a,!1),f.publish(i.CONVERSATION_DELETED,a.id),y(a)})},ja=function(a){var b=q.pendingDeleteMessageIds,c=m.removePendingAddContactsById(q,[a]);c=m.removePendingRemoveContactsById(c,[a]),c=m.removePendingUnblockUsersById(c,[a]),c=m.removePendingBlockUsersById(c,[a]),c=m.removePendingDeleteMessagesById(c,b),c=m.setPendingDeleteConversation(c,!1),c=m.setDeleteMessagesForAllUsers(c,!1),y(c)},ka=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return y(e),h.acceptContactRequest(a,b).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),y(b)}).then(function(){f.publish(i.CONTACT_ADDED,q.members[a]),f.publish(i.CONTACT_REQUEST_ACCEPTED,d)})},la=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return y(e),h.declineContactRequest(a,b).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),y(b)}).then(function(){f.publish(i.CONTACT_REQUEST_DECLINED,d)})},ma=function(a,b){x=!0;var c=m.setSendingMessage(q,!0),d=null;y(c);var g=null,j=null;if(a||q.type==E.PUBLIC)g=h.sendMessageToConversation(a,b);else{var k=F();g=h.sendMessageToUser(k,b).then(function(a){return d=parseInt(a.conversationid,10),j=a.candeletemessagesforallusers,a})}g.then(function(a){var b=m.addMessages(q,[a]);b=m.setSendingMessage(b,!1);var c=N(b);b.id||(b=m.setId(b,d),c.id=d,Da(d),f.publish(i.CONVERSATION_CREATED,c),b=m.setCanDeleteMessagesForAllUsers(b,j)),y(b),x=!1,f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c)})["catch"](function(a){x=!1;var b=m.setSendingMessage(q,!1);y(b),e.exception(a)})},na=function(a){var b=q;b=q.selectedMessageIds.indexOf(a)>-1?m.removeSelectedMessagesById(q,[a]):m.addSelectedMessagesById(q,[a]),y(b)},oa=function(){ja(F());var a=m.removeSelectedMessagesById(q,q.selectedMessageIds);y(a)},pa=function(b,c,d){if(!u&&v.length){u=!0;var f=v.shift(),g=z.map(function(a){return a(f.patch)});a.when.apply(null,g).then(function(){u=!1,f.deferred.resolve(!0),pa(b,c,d)})["catch"](function(a){u=!1,f.deferred.reject(a),e.exception(a)})}},qa=function(b,c,d,e){var f=function(a){return l.render(b,c,d,a)};if(!e){var g=m.buildInitialState(q.midnight,q.loggedInUserId,q.id),h=k.buildPatch(g,q);f(h)}return z.push(f),function(e){var f=k.buildPatch(q,e),g=a.Deferred();return Object.keys(f).length?v.push({patch:f,deferred:g}):g.resolve(!0),q=e,e.id&&(p[e.id]={state:e,messagesOffset:I(),loadedAllMessages:K()}),pa(b,c,d),g.promise()}},ra=function(a){return function(b,c){if(!q.loadingConfirmAction){a(F());var d=m.setLoadingConfirmAction(q,!1);y(d)}c.originalEvent.preventDefault()}},sa=function(b,c){var d=a(b.target),e=d.closest(D.FOOTER_CONTAINER),f=e.find(D.MESSAGE_TEXT_AREA),g=f.val().trim();""!==g&&ma(q.id,g),c.originalEvent.preventDefault()},ta=function(b,c){var d=window.getSelection(),e=a(b.target);if(""==d.toString()&&!e.is("a")){var f=e.closest(D.MESSAGE),g=parseInt(f.attr("data-message-id"),10);na(g),c.originalEvent.preventDefault()}},ua=function(a,b){oa(),b.originalEvent.preventDefault()},va=function(a){return function(b,c){var d=F(),e=q.members[d];n.go(a,o.VIEW_CONTACT,e),c.originalEvent.preventDefault()}},wa=function(a,b){ba()["catch"](e.exception),b.originalEvent.preventDefault()},xa=function(a,b){ca()["catch"](e.exception),b.originalEvent.preventDefault()},ya=function(a,b){da()["catch"](e.exception),b.originalEvent.preventDefault()},za=function(a,b){ea()["catch"](e.exception),b.originalEvent.preventDefault()},Aa=function(b){var c=a(b.target).prop("checked"),d=m.setDeleteMessagesForAllUsers(q,c);y(d)},Ba=function(a){return function(b,c){n.go(a,o.VIEW_GROUP_INFO,{id:q.id,name:q.name,subname:q.subname,imageUrl:q.imageUrl,totalMemberCount:q.totalMemberCount},q.loggedInUserId),c.originalEvent.preventDefault()}},Ca=function(a,c,g,h){var j=!1,k=M(g),l=[[D.ACTION_REQUEST_BLOCK,ra(V)],[D.ACTION_REQUEST_UNBLOCK,ra(X)],[D.ACTION_REQUEST_ADD_CONTACT,ra(_)],[D.ACTION_REQUEST_REMOVE_CONTACT,ra(Z)],[D.ACTION_REQUEST_DELETE_CONVERSATION,ra(ha)],[D.ACTION_CANCEL_EDIT_MODE,ua],[D.ACTION_VIEW_CONTACT,va(a)],[D.ACTION_VIEW_GROUP_INFO,Ba(a)],[D.ACTION_CONFIRM_FAVOURITE,wa],[D.ACTION_CONFIRM_MUTE,ya],[D.ACTION_CONFIRM_UNFAVOURITE,xa],[D.ACTION_CONFIRM_UNMUTE,za]],n=[[D.ACTION_CANCEL_CONFIRM,ra(ja)],[D.ACTION_CONFIRM_BLOCK,ra(W)],[D.ACTION_CONFIRM_UNBLOCK,ra(Y)],[D.ACTION_CONFIRM_ADD_CONTACT,ra(aa)],[D.ACTION_CONFIRM_REMOVE_CONTACT,ra($)],[D.ACTION_CONFIRM_DELETE_SELECTED_MESSAGES,ra(ga)],[D.ACTION_CONFIRM_DELETE_CONVERSATION,ra(ia)],[D.ACTION_REQUEST_ADD_CONTACT,ra(_)],[D.ACTION_ACCEPT_CONTACT_REQUEST,ra(ka)],[D.ACTION_DECLINE_CONTACT_REQUEST,ra(la)],[D.MESSAGE,ta],[D.DELETE_MESSAGES_FOR_ALL_USERS_TOGGLE,Aa]],p=[[D.SEND_MESSAGE_BUTTON,sa],[D.ACTION_REQUEST_DELETE_SELECTED_MESSAGES,ra(fa)],[D.ACTION_REQUEST_ADD_CONTACT,ra(_)],[D.ACTION_REQUEST_UNBLOCK,ra(X)]];b.init(h),d.define(c,[d.events.activate]),d.define(g,[d.events.activate]),d.define(h,[d.events.activate,d.events.enter]),d.define(k,[d.events.scrollTop,d.events.scrollLock]),k.on(d.events.scrollTop,function(a,b){var c=Object.keys(q.members).length>1;if(!w&&!j&&!K()&&c){j=!0;var d=m.setLoadingMessages(q,!0);y(d),S(q.id,B,I(),A,[]).then(function(){j=!1,J(I()+B)})["catch"](function(a){j=!1,e.exception(a)})}b.originalEvent.preventDefault()}),l.forEach(function(a){var b=a[0],e=a[1];c.on(d.events.activate,b,e)}),n.forEach(function(a){var b=a[0],c=a[1];g.on(d.events.activate,b,c)}),p.forEach(function(a){var b=a[0],c=a[1];h.on(d.events.activate,b,c)}),h.on(d.events.enter,D.MESSAGE_TEXT_AREA,function(a,b){var c=h.attr("data-enter-to-send");c&&"false"!=c&&"0"!=c&&sa(a,b)}),f.subscribe(i.ROUTE_CHANGED,function(a){t&&a.route!=o.VIEW_CONVERSATION&&t.stop()})},Da=function(a){t&&t.stop(),t=new c(T(a,A),function(a){return a?2*a:C}),t.start()},Ea=function(a,b,c){w=!0,u=!1,v=[],x=!1;var d=c.id,e=parseInt(a.attr("data-midnight"),10),f=m.buildInitialState(e,d,b);q||(q=f),t&&t.stop(),y(f)},Fa=function(a,b,c){Ea(a,null,b);var d=null;return d=b.id!=c?h.getConversationBetweenUsers(b.id,c,!0,!0,0,0,B,0,A):h.getSelfConversation(b.id,B,0,A),d.then(function(c){return Ha(a,c,b)})["catch"](function(){return O(b,c)})},Ga=function(b,c,d){var e=null;c in p&&(e=p[c]),Ea(b,c,d);var f=a.Deferred().resolve({}).promise();if(e){var g=e.state;g=m.setLoadingMessages(g,!1),g=m.setLoadingMembers(g,!1),J(e.messagesOffset),L(e.loadedAllMessages),y(g)}else f=Q(c,d,B,0,A);return f.then(function(){return Da(c)})},Ha=function(b,c,d){var e=null;c.id in p&&(e=p[c.id]),Ea(b,c.id,d);var f=a.Deferred().resolve({}).promise();if(e){var g=e.state;g=m.setLoadingMessages(g,!1),g=m.setLoadingMembers(g,!1),J(e.messagesOffset),L(e.loadedAllMessages),y(g)}else f=R(c,d,B,A);return f.then(function(){return Da(c.id)})},Ia=function(b,c,d,f,g,h,i){var k=null,l=null;g&&null!==g&&"object"==typeof g?(k=g,l=parseInt(k.id,10)):(k=null,l=parseInt(g,10),l=isNaN(l)?null:l),!l&&h&&i&&(l=G(i));var m=!q||q.id!=l||i&&i!=F();if(d.attr("data-init")||(y=qa(c,d,f,m),Ca(b,c,d,f),d.attr("data-init",!0)),m){var n=null,o=H(d);return n=k?Ha(d,k,o,i):l?Ga(d,l,o,i):Fa(d,o,i),n.then(function(){w=!1,c.find(j.SELECTORS.CAN_RECEIVE_FOCUS).first().focus()})["catch"](function(a){w=!1,e.exception(a)})}if(Da(l),q.type==E.PRIVATE&&h){var p=F();switch(h){case"block":return V(p);case"unblock":return X(p);case"add-contact":return _(p);case"remove-contact":return Z(p)}}return a.Deferred().resolve().promise()},Ja=function(){return g.get_string("messagedrawerviewconversation","core_message",q.name)};return{show:Ia,description:Ja}}); \ No newline at end of file +define(["jquery","core/auto_rows","core/backoff_timer","core/custom_interaction_events","core/notification","core/pubsub","core/str","core_message/message_repository","core_message/message_drawer_events","core_message/message_drawer_view_conversation_constants","core_message/message_drawer_view_conversation_patcher","core_message/message_drawer_view_conversation_renderer","core_message/message_drawer_view_conversation_state_manager","core_message/message_drawer_router","core_message/message_drawer_routes"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p={},q=null,r=!1,s=0,t=null,u=!1,v=[],w=!0,x=!1,y=null,z=[],A=j.NEWEST_MESSAGES_FIRST,B=j.LOAD_MESSAGE_LIMIT,C=j.MILLISECONDS_IN_SEC,D=j.SELECTORS,E=j.CONVERSATION_TYPES,F=function(){if(!q||q.type==E.PUBLIC)return null;var a=q.loggedInUserId;if(q.type==E.SELF)return a;var b=Object.keys(q.members).filter(function(b){return a!=b});return b.length?b[0]:null},G=function(a){return Object.keys(p).reduce(function(b,c){if(!b){var d=p[c].state;d.type!=E.PUBLIC&&a in d.members&&(b=d.id)}return b},null)},H=function(a){return{id:parseInt(a.attr("data-user-id"),10),fullname:null,profileimageurl:null,profileimageurlsmall:null,isonline:null,showonlinestatus:null,isblocked:null,iscontact:null,isdeleted:null,canmessage:null,requirescontact:null,contactrequests:[]}},I=function(){return s},J=function(a){s=a,p[q.id].messagesOffset=a},K=function(){return r},L=function(a){r=a,p[q.id].loadedAllMessages=a},M=function(a){return a.find(D.MESSAGES_CONTAINER)},N=function(b){return{id:b.id,name:b.name,subname:b.subname,imageUrl:b.imageUrl,isFavourite:b.isFavourite,isMuted:b.isMuted,type:b.type,totalMemberCount:b.totalMemberCount,loggedInUserId:b.loggedInUserId,messages:b.messages.map(function(b){return a.extend({},b)}),members:Object.keys(b.members).map(function(c){var d=a.extend({},b.members[c]);return d.contactrequests=b.members[c].contactrequests.map(function(b){return a.extend({},b)}),d})}},O=function(a,b){var c=a.id,d=c==b?E.SELF:E.PRIVATE,f=m.setLoadingMembers(q,!0);return f=m.setLoadingMessages(f,!0),y(f),h.getMemberInfo(c,[b],!0,!0).then(function(a){if(a.length)return a[0];throw new Error("Unable to load other user profile")}).then(function(b){var c=d==E.SELF?[b]:[b,a],e=m.addMembers(q,c);return e=m.setLoadingMembers(e,!1),e=m.setLoadingMessages(e,!1),e=m.setName(e,b.fullname),e=m.setType(e,d),e=m.setImageUrl(e,b.profileimageurl),e=m.setTotalMemberCount(e,c.length),y(e),b})["catch"](function(a){var b=m.setLoadingMembers(q,!1);y(b),e.exception(a)})},P=function(a,b){var c=null;if(a.type==E.PRIVATE){var d=a.members.filter(function(a){return a.id!=b});c=d.length?d[0]:null}else a.type==E.SELF&&(c=a.members[0]);var e=a.name,f=a.imageurl;a.type!=E.PUBLIC&&(e=e||c?c.fullname:"",f=f||c?c.profileimageurl:"");var g=m.addMembers(q,a.members);return g=m.setName(g,e),g=m.setSubname(g,a.subname),g=m.setType(g,a.type),g=m.setImageUrl(g,f),g=m.setTotalMemberCount(g,a.membercount),g=m.setIsFavourite(g,a.isfavourite),g=m.setIsMuted(g,a.ismuted),g=m.addMessages(g,a.messages),g=m.setCanDeleteMessagesForAllUsers(g,a.candeletemessagesforallusers)},Q=function(a,b,c,d,f){var g=b.id,i=m.setLoadingMembers(q,!0);return i=m.setLoadingMessages(i,!0),y(i),h.getConversation(g,a,!0,!0,0,0,c+1,d,f).then(function(a){return a.messages.length>c?a.messages=a.messages.slice(1):L(!0),J(d+c),a}).then(function(a){var c=a.members.filter(function(a){return a.id==b.id});c.length<1&&(a.members=a.members.concat([b]));var d=P(a,b.id);return d=m.setLoadingMembers(d,!1),d=m.setLoadingMessages(d,!1),y(d).then(function(){return a})}).then(function(){return U(a)})["catch"](function(a){var b=m.setLoadingMembers(q,!1);b=m.setLoadingMessages(b,!1),y(b),e.exception(a)})},R=function(a,b,c,d){var f=a.members.filter(function(a){return a.id==b.id});f.length<1&&(a.members=a.members.concat([b]));var g=a.messages.length,h=g>=c,i=P(a,b.id);i=m.setLoadingMembers(i,!1),i=m.setLoadingMessages(i,!h);var j=y(i);return j.then(function(){return h?{messages:a.messages}:S(a.id,c,g,d,[])}).then(function(){var a=q.messages;return J(a.length),U(q.id),a})["catch"](e.exception)},S=function(a,b,c,d,e,f){return h.getMessages(q.loggedInUserId,a,b?b+1:b,c,d,f).then(function(a){return a.messages.length&&e.length&&(a.messages=a.messages.filter(function(a){return e.indexOf(parseInt(a.id,10))<0})),a}).then(function(a){return b?(a.messages.length>b?a.messages=a.messages.slice(0,-1):L(!0),a):a}).then(function(a){var b=a.members.filter(function(a){return!(a.id in q.members)}),c=m.addMembers(q,b);return c=m.addMessages(c,a.messages),c=m.setLoadingMessages(c,!1),y(c).then(function(){return a})})["catch"](function(a){var b=m.setLoadingMessages(q,!1);throw y(b),a})},T=function(b,c){return function(){var d=q.messages,e=d.length?d[d.length-1]:null;if(e&&!w&&!x){for(var g=[],h=d.length-1;h>=0;h--){var j=d[h];if(j.timeCreated!==e.timeCreated)break;g.push(j.id)}return S(b,0,0,c,g,e.timeCreated).then(function(a){if(a.messages.length){t.restart();var c=N(q);return f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c),U(b)}return a})}return a.Deferred().resolve().promise()}},U=function(a){var b=q.loggedInUserId;return h.markAllConversationMessagesAsRead(b,a).then(function(){var b=m.markMessagesAsRead(q,q.messages);return f.publish(i.CONVERSATION_READ,a),y(b)})},V=function(a){ja(a);var b=m.addPendingBlockUsersById(q,[a]);y(b)},W=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.blockUser(q.loggedInUserId,a).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingBlockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_BLOCKED,a),y(c)})},X=function(a){ja(a);var b=m.addPendingUnblockUsersById(q,[a]);y(b)},Y=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.unblockUser(q.loggedInUserId,a).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingUnblockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_UNBLOCKED,a),y(c)})},Z=function(a){ja(a);var b=m.addPendingRemoveContactsById(q,[a]);y(b)},$=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.deleteContacts(q.loggedInUserId,[a]).then(function(b){var c=m.addMembers(q,b);return c=m.removePendingRemoveContactsById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_REMOVED,a),y(c)})},_=function(a){ja(a);var b=m.addPendingAddContactsById(q,[a]);y(b)},aa=function(a){var b=m.setLoadingConfirmAction(q,!0);return y(b),h.createContactRequest(q.loggedInUserId,a).then(function(a){if(!a.request)throw new Error(a.warnings[0].message);return a.request}).then(function(b){var c=m.removePendingAddContactsById(q,[a]);return c=m.addContactRequests(c,[b]),c=m.setLoadingConfirmAction(c,!1),y(c)})},ba=function(){var a=q.loggedInUserId,b=q.id;return h.setFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!0);return y(a)}).then(function(){return f.publish(i.CONVERSATION_SET_FAVOURITE,N(q))})},ca=function(){var a=q.loggedInUserId,b=q.id;return h.unsetFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!1);return y(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_FAVOURITE,N(q))})},da=function(){var a=q.loggedInUserId,b=q.id;return h.setMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!0);return y(a)}).then(function(){return f.publish(i.CONVERSATION_SET_MUTED,N(q))})},ea=function(){var a=q.loggedInUserId,b=q.id;return h.unsetMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!1);return y(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_MUTED,N(q))})},fa=function(a){var b=q.selectedMessageIds;ja(a);var c=m.addPendingDeleteMessagesById(q,b);y(c)},ga=function(){var a=q.pendingDeleteMessageIds,b=m.setLoadingConfirmAction(q,!0);y(b);var c=null;return c=b.deleteMessagesForAllUsers?h.deleteMessagesForAllUsers(q.loggedInUserId,a):h.deleteMessages(q.loggedInUserId,a),c.then(function(){var b=m.removeMessagesById(q,a);b=m.removePendingDeleteMessagesById(b,a),b=m.removeSelectedMessagesById(b,a),b=m.setLoadingConfirmAction(b,!1),b=m.setDeleteMessagesForAllUsers(b,!1);var c=q.messages[q.messages.length-1],d=b.messages.length?b.messages[b.messages.length-1]:null;if(d&&d.id!=c.id){var e=N(b);f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,e)}else b.messages.length||f.publish(i.CONVERSATION_DELETED,b.id);return y(b)})},ha=function(a){ja(a);var b=m.setPendingDeleteConversation(q,!0);y(b)},ia=function(){var a=m.setLoadingConfirmAction(q,!0);return y(a),h.deleteConversation(q.loggedInUserId,q.id).then(function(){var a=m.removeMessages(q,q.messages);return a=m.removeSelectedMessagesById(a,q.selectedMessageIds),a=m.setPendingDeleteConversation(a,!1),a=m.setLoadingConfirmAction(a,!1),f.publish(i.CONVERSATION_DELETED,a.id),y(a)})},ja=function(a){var b=q.pendingDeleteMessageIds,c=m.removePendingAddContactsById(q,[a]);c=m.removePendingRemoveContactsById(c,[a]),c=m.removePendingUnblockUsersById(c,[a]),c=m.removePendingBlockUsersById(c,[a]),c=m.removePendingDeleteMessagesById(c,b),c=m.setPendingDeleteConversation(c,!1),c=m.setDeleteMessagesForAllUsers(c,!1),y(c)},ka=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return y(e),h.acceptContactRequest(a,b).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),y(b)}).then(function(){f.publish(i.CONTACT_ADDED,q.members[a]),f.publish(i.CONTACT_REQUEST_ACCEPTED,d)})},la=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return y(e),h.declineContactRequest(a,b).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),y(b)}).then(function(){f.publish(i.CONTACT_REQUEST_DECLINED,d)})},ma=function(a,b){x=!0;var c=m.setSendingMessage(q,!0),d=null;y(c);var g=null,j=null;if(a||q.type==E.PUBLIC)g=h.sendMessageToConversation(a,b);else{var k=F();g=h.sendMessageToUser(k,b).then(function(a){return d=parseInt(a.conversationid,10),j=a.candeletemessagesforallusers,a})}g.then(function(a){var b=m.addMessages(q,[a]);b=m.setSendingMessage(b,!1);var c=N(b);b.id||(b=m.setId(b,d),c.id=d,Da(d),f.publish(i.CONVERSATION_CREATED,c),b=m.setCanDeleteMessagesForAllUsers(b,j)),y(b),x=!1,f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c)})["catch"](function(a){x=!1;var b=m.setSendingMessage(q,!1);y(b),e.exception(a)})},na=function(a){var b=q;b=q.selectedMessageIds.indexOf(a)>-1?m.removeSelectedMessagesById(q,[a]):m.addSelectedMessagesById(q,[a]),y(b)},oa=function(){ja(F());var a=m.removeSelectedMessagesById(q,q.selectedMessageIds);y(a)},pa=function(b,c,d){if(!u&&v.length){u=!0;var f=v.shift(),g=z.map(function(a){return a(f.patch)});a.when.apply(null,g).then(function(){u=!1,f.deferred.resolve(!0),pa(b,c,d)})["catch"](function(a){u=!1,f.deferred.reject(a),e.exception(a)})}},qa=function(b,c,d,e){var f=function(a){return l.render(b,c,d,a)};if(!e){var g=m.buildInitialState(q.midnight,q.loggedInUserId,q.id),h=k.buildPatch(g,q);f(h)}return z.push(f),function(e){var f=k.buildPatch(q,e),g=a.Deferred();return Object.keys(f).length?v.push({patch:f,deferred:g}):g.resolve(!0),q=e,e.id&&(p[e.id]={state:e,messagesOffset:I(),loadedAllMessages:K()}),pa(b,c,d),g.promise()}},ra=function(a){return function(b,c){if(!q.loadingConfirmAction){a(F());var d=m.setLoadingConfirmAction(q,!1);y(d)}c.originalEvent.preventDefault()}},sa=function(b,c){var d=a(b.target),e=d.closest(D.FOOTER_CONTAINER),f=e.find(D.MESSAGE_TEXT_AREA),g=f.val().trim();""!==g&&ma(q.id,g),c.originalEvent.preventDefault()},ta=function(b,c){var d=window.getSelection(),e=a(b.target);if(""==d.toString()&&!e.is("a")){var f=e.closest(D.MESSAGE),g=parseInt(f.attr("data-message-id"),10);na(g),c.originalEvent.preventDefault()}},ua=function(a,b){oa(),b.originalEvent.preventDefault()},va=function(a){return function(b,c){var d=F(),e=q.members[d];n.go(a,o.VIEW_CONTACT,e),c.originalEvent.preventDefault()}},wa=function(a,b){ba()["catch"](e.exception),b.originalEvent.preventDefault()},xa=function(a,b){ca()["catch"](e.exception),b.originalEvent.preventDefault()},ya=function(a,b){da()["catch"](e.exception),b.originalEvent.preventDefault()},za=function(a,b){ea()["catch"](e.exception),b.originalEvent.preventDefault()},Aa=function(b){var c=a(b.target).prop("checked"),d=m.setDeleteMessagesForAllUsers(q,c);y(d)},Ba=function(a){return function(b,c){n.go(a,o.VIEW_GROUP_INFO,{id:q.id,name:q.name,subname:q.subname,imageUrl:q.imageUrl,totalMemberCount:q.totalMemberCount},q.loggedInUserId),c.originalEvent.preventDefault()}},Ca=function(a,c,g,h){var j=!1,k=M(g),l=[[D.ACTION_REQUEST_BLOCK,ra(V)],[D.ACTION_REQUEST_UNBLOCK,ra(X)],[D.ACTION_REQUEST_ADD_CONTACT,ra(_)],[D.ACTION_REQUEST_REMOVE_CONTACT,ra(Z)],[D.ACTION_REQUEST_DELETE_CONVERSATION,ra(ha)],[D.ACTION_CANCEL_EDIT_MODE,ua],[D.ACTION_VIEW_CONTACT,va(a)],[D.ACTION_VIEW_GROUP_INFO,Ba(a)],[D.ACTION_CONFIRM_FAVOURITE,wa],[D.ACTION_CONFIRM_MUTE,ya],[D.ACTION_CONFIRM_UNFAVOURITE,xa],[D.ACTION_CONFIRM_UNMUTE,za]],n=[[D.ACTION_CANCEL_CONFIRM,ra(ja)],[D.ACTION_CONFIRM_BLOCK,ra(W)],[D.ACTION_CONFIRM_UNBLOCK,ra(Y)],[D.ACTION_CONFIRM_ADD_CONTACT,ra(aa)],[D.ACTION_CONFIRM_REMOVE_CONTACT,ra($)],[D.ACTION_CONFIRM_DELETE_SELECTED_MESSAGES,ra(ga)],[D.ACTION_CONFIRM_DELETE_CONVERSATION,ra(ia)],[D.ACTION_REQUEST_ADD_CONTACT,ra(_)],[D.ACTION_ACCEPT_CONTACT_REQUEST,ra(ka)],[D.ACTION_DECLINE_CONTACT_REQUEST,ra(la)],[D.MESSAGE,ta],[D.DELETE_MESSAGES_FOR_ALL_USERS_TOGGLE,Aa]],p=[[D.SEND_MESSAGE_BUTTON,sa],[D.ACTION_REQUEST_DELETE_SELECTED_MESSAGES,ra(fa)],[D.ACTION_REQUEST_ADD_CONTACT,ra(_)],[D.ACTION_REQUEST_UNBLOCK,ra(X)]];b.init(h),d.define(c,[d.events.activate]),d.define(g,[d.events.activate]),d.define(h,[d.events.activate,d.events.enter]),d.define(k,[d.events.scrollTop,d.events.scrollLock]),k.on(d.events.scrollTop,function(a,b){var c=Object.keys(q.members).length>1;if(!w&&!j&&!K()&&c){j=!0;var d=m.setLoadingMessages(q,!0);y(d),S(q.id,B,I(),A,[]).then(function(){j=!1,J(I()+B)})["catch"](function(a){j=!1,e.exception(a)})}b.originalEvent.preventDefault()}),l.forEach(function(a){var b=a[0],e=a[1];c.on(d.events.activate,b,e)}),n.forEach(function(a){var b=a[0],c=a[1];g.on(d.events.activate,b,c)}),p.forEach(function(a){var b=a[0],c=a[1];h.on(d.events.activate,b,c)}),h.on(d.events.enter,D.MESSAGE_TEXT_AREA,function(a,b){var c=h.attr("data-enter-to-send");c&&"false"!=c&&"0"!=c&&sa(a,b)}),f.subscribe(i.ROUTE_CHANGED,function(a){t&&a.route!=o.VIEW_CONVERSATION&&t.stop()})},Da=function(a){t&&t.stop(),t=new c(T(a,A),c.getIncrementalCallback(q.messagePollMin*C,C,q.messagePollMax*C,q.messagePollAfterMax*C)),t.start()},Ea=function(a,b,c){w=!0,u=!1,v=[],x=!1;var d=c.id,e=parseInt(a.attr("data-midnight"),10),f=parseInt(a.attr("data-message-poll-min"),10),g=parseInt(a.attr("data-message-poll-max"),10),h=parseInt(a.attr("data-message-poll-after-max"),10),i=m.buildInitialState(e,d,b,f,g,h);q||(q=i),t&&t.stop(),y(i)},Fa=function(a,b,c){Ea(a,null,b);var d=null;return d=b.id!=c?h.getConversationBetweenUsers(b.id,c,!0,!0,0,0,B,0,A):h.getSelfConversation(b.id,B,0,A),d.then(function(c){return Ha(a,c,b)})["catch"](function(){return O(b,c)})},Ga=function(b,c,d){var e=null;c in p&&(e=p[c]),Ea(b,c,d);var f=a.Deferred().resolve({}).promise();if(e){var g=e.state;g=m.setLoadingMessages(g,!1),g=m.setLoadingMembers(g,!1),J(e.messagesOffset),L(e.loadedAllMessages),y(g)}else f=Q(c,d,B,0,A);return f.then(function(){return Da(c)})},Ha=function(b,c,d){var e=null;c.id in p&&(e=p[c.id]),Ea(b,c.id,d);var f=a.Deferred().resolve({}).promise();if(e){var g=e.state;g=m.setLoadingMessages(g,!1),g=m.setLoadingMembers(g,!1),J(e.messagesOffset),L(e.loadedAllMessages),y(g)}else f=R(c,d,B,A);return f.then(function(){return Da(c.id)})},Ia=function(b,c,d,f,g,h,i){var k=null,l=null;g&&null!==g&&"object"==typeof g?(k=g,l=parseInt(k.id,10)):(k=null,l=parseInt(g,10),l=isNaN(l)?null:l),!l&&h&&i&&(l=G(i));var m=!q||q.id!=l||i&&i!=F();if(d.attr("data-init")||(y=qa(c,d,f,m),Ca(b,c,d,f),d.attr("data-init",!0)),m){var n=null,o=H(d);return n=k?Ha(d,k,o,i):l?Ga(d,l,o,i):Fa(d,o,i),n.then(function(){w=!1,c.find(j.SELECTORS.CAN_RECEIVE_FOCUS).first().focus()})["catch"](function(a){w=!1,e.exception(a)})}if(Da(l),q.type==E.PRIVATE&&h){var p=F();switch(h){case"block":return V(p);case"unblock":return X(p);case"add-contact":return _(p);case"remove-contact":return Z(p)}}return a.Deferred().resolve().promise()},Ja=function(){return g.get_string("messagedrawerviewconversation","core_message",q.name)};return{show:Ia,description:Ja}}); \ No newline at end of file diff --git a/message/amd/build/message_drawer_view_conversation_constants.min.js b/message/amd/build/message_drawer_view_conversation_constants.min.js index 2abab80dce2ab..130466d9b8da5 100644 --- a/message/amd/build/message_drawer_view_conversation_constants.min.js +++ b/message/amd/build/message_drawer_view_conversation_constants.min.js @@ -1 +1 @@ -define([],function(){var a={ACTION_ACCEPT_CONTACT_REQUEST:'[data-action="accept-contact-request"]',ACTION_CANCEL_CONFIRM:'[data-action="cancel-confirm"]',ACTION_CANCEL_EDIT_MODE:'[data-action="cancel-edit-mode"]',ACTION_CONFIRM_ADD_CONTACT:'[data-action="confirm-add-contact"]',ACTION_CONFIRM_BLOCK:'[data-action="confirm-block"]',ACTION_CONFIRM_DELETE_SELECTED_MESSAGES:'[data-action="confirm-delete-selected-messages"]',ACTION_CONFIRM_DELETE_CONVERSATION:'[data-action="confirm-delete-conversation"]',ACTION_CONFIRM_FAVOURITE:'[data-action="confirm-favourite"]',ACTION_CONFIRM_MUTE:'[data-action="confirm-mute"]',ACTION_CONFIRM_UNFAVOURITE:'[data-action="confirm-unfavourite"]',ACTION_CONFIRM_REMOVE_CONTACT:'[data-action="confirm-remove-contact"]',ACTION_CONFIRM_UNBLOCK:'[data-action="confirm-unblock"]',ACTION_CONFIRM_UNMUTE:'[data-action="confirm-unmute"]',ACTION_DECLINE_CONTACT_REQUEST:'[data-action="decline-contact-request"]',ACTION_REQUEST_ADD_CONTACT:'[data-action="request-add-contact"]',ACTION_REQUEST_BLOCK:'[data-action="request-block"]',ACTION_REQUEST_DELETE_CONVERSATION:'[data-action="request-delete-conversation"]',ACTION_REQUEST_DELETE_SELECTED_MESSAGES:'[data-action="delete-selected-messages"]',ACTION_REQUEST_REMOVE_CONTACT:'[data-action="request-remove-contact"]',ACTION_REQUEST_UNBLOCK:'[data-action="request-unblock"]',ACTION_VIEW_CONTACT:'[data-action="view-contact"]',ACTION_VIEW_GROUP_INFO:'[data-action="view-group-info"]',CAN_RECEIVE_FOCUS:'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',CONFIRM_DIALOGUE_BUTTON_TEXT:'[data-region="dialogue-button-text"]',CONFIRM_DIALOGUE_CANCEL_BUTTON:'[data-action="cancel-confirm"]',CONFIRM_DIALOGUE_CONTAINER:'[data-region="confirm-dialogue-container"]',CONFIRM_DIALOGUE_HEADER:'[data-region="dialogue-header"]',CONFIRM_DIALOGUE_TEXT:'[data-region="dialogue-text"]',CONTACT_REQUEST_SENT_MESSAGE_CONTAINER:'[data-region="contact-request-sent-message-container"]',CONTENT_PLACEHOLDER_CONTAINER:'[data-region="content-placeholder"]',CONTENT_CONTAINER:'[data-region="content-container"]',CONTENT_MESSAGES_CONTAINER:'[data-region="content-message-container"]',CONTENT_MESSAGES_FOOTER_CONTAINER:'[data-region="content-messages-footer-container"]',CONTENT_MESSAGES_FOOTER_EDIT_MODE_CONTAINER:'[data-region="content-messages-footer-edit-mode-container"]',CONTENT_MESSAGES_FOOTER_REQUIRE_CONTACT_CONTAINER:'[data-region="content-messages-footer-require-contact-container"]',CONTENT_MESSAGES_FOOTER_REQUIRE_UNBLOCK_CONTAINER:'[data-region="content-messages-footer-require-unblock-container"]',CONTENT_MESSAGES_FOOTER_UNABLE_TO_MESSAGE_CONTAINER:'[data-region="content-messages-footer-unable-to-message"]',DAY_MESSAGES_CONTAINER:'[data-region="day-messages-container"]',DELETE_MESSAGES_FOR_ALL_USERS_TOGGLE:'[data-region="delete-messages-for-all-users-toggle"]',DELETE_MESSAGES_FOR_ALL_USERS_TOGGLE_CONTAINER:'[data-region="delete-messages-for-all-users-toggle-container"]',FAVOURITE_ICON_CONTAINER:'[data-region="favourite-icon-container"]',FOOTER_CONTAINER:'[data-region="content-messages-footer-container"]',HEADER:'[data-region="header-content"]',HEADER_EDIT_MODE:'[data-region="header-edit-mode"]',HEADER_PLACEHOLDER_CONTAINER:'[data-region="header-placeholder"]',LOADING_ICON_CONTAINER:'[data-region="loading-icon-container"]',MESSAGE:'[data-region="message"]',MESSAGE_NOT_SELECTED:'[data-region="message"][aria-checked="false"]',MESSAGE_NOT_SELECTED_ICON:'[data-region="not-selected-icon"]',MESSAGE_SELECTED_ICON:'[data-region="selected-icon"]',MESSAGES:'[data-region="content-message-container"]',MESSAGES_CONTAINER:'[data-region="content-message-container"]',MESSAGES_SELECTED_COUNT:'[data-region="message-selected-court"]',MESSAGE_TEXT_AREA:'[data-region="send-message-txt"]',MORE_MESSAGES_LOADING_ICON_CONTAINER:'[data-region="more-messages-loading-icon-container"]',MUTED_ICON_CONTAINER:'[data-region="muted-icon-container"]',PLACEHOLDER_CONTAINER:'[data-region="placeholder-container"]',SELF_CONVERSATION_MESSAGE_CONTAINER:'[data-region="self-conversation-message-container"]',SEND_MESSAGE_BUTTON:'[data-action="send-message"]',SEND_MESSAGE_ICON_CONTAINER:'[data-region="send-icon-container"]',TEXT:'[data-region="text"]',TITLE:'[data-region="title"]'},b={HEADER_PRIVATE:"core_message/message_drawer_view_conversation_header_content_type_private",HEADER_PRIVATE_NO_CONTROLS:"core_message/message_drawer_view_conversation_header_content_type_private_no_controls",HEADER_PUBLIC:"core_message/message_drawer_view_conversation_header_content_type_public",HEADER_SELF:"core_message/message_drawer_view_conversation_header_content_type_self",DAY:"core_message/message_drawer_view_conversation_body_day",MESSAGE:"core_message/message_drawer_view_conversation_body_message",MESSAGES:"core_message/message_drawer_view_conversation_body_messages"},c={PRIVATE:1,PUBLIC:2,SELF:3};return{SELECTORS:a,TEMPLATES:b,CONVERSATION_TYPES:c,NEWEST_MESSAGES_FIRST:!0,LOAD_MESSAGE_LIMIT:100,INITIAL_NEW_MESSAGE_POLL_TIMEOUT:1e3}}); \ No newline at end of file +define([],function(){var a={ACTION_ACCEPT_CONTACT_REQUEST:'[data-action="accept-contact-request"]',ACTION_CANCEL_CONFIRM:'[data-action="cancel-confirm"]',ACTION_CANCEL_EDIT_MODE:'[data-action="cancel-edit-mode"]',ACTION_CONFIRM_ADD_CONTACT:'[data-action="confirm-add-contact"]',ACTION_CONFIRM_BLOCK:'[data-action="confirm-block"]',ACTION_CONFIRM_DELETE_SELECTED_MESSAGES:'[data-action="confirm-delete-selected-messages"]',ACTION_CONFIRM_DELETE_CONVERSATION:'[data-action="confirm-delete-conversation"]',ACTION_CONFIRM_FAVOURITE:'[data-action="confirm-favourite"]',ACTION_CONFIRM_MUTE:'[data-action="confirm-mute"]',ACTION_CONFIRM_UNFAVOURITE:'[data-action="confirm-unfavourite"]',ACTION_CONFIRM_REMOVE_CONTACT:'[data-action="confirm-remove-contact"]',ACTION_CONFIRM_UNBLOCK:'[data-action="confirm-unblock"]',ACTION_CONFIRM_UNMUTE:'[data-action="confirm-unmute"]',ACTION_DECLINE_CONTACT_REQUEST:'[data-action="decline-contact-request"]',ACTION_REQUEST_ADD_CONTACT:'[data-action="request-add-contact"]',ACTION_REQUEST_BLOCK:'[data-action="request-block"]',ACTION_REQUEST_DELETE_CONVERSATION:'[data-action="request-delete-conversation"]',ACTION_REQUEST_DELETE_SELECTED_MESSAGES:'[data-action="delete-selected-messages"]',ACTION_REQUEST_REMOVE_CONTACT:'[data-action="request-remove-contact"]',ACTION_REQUEST_UNBLOCK:'[data-action="request-unblock"]',ACTION_VIEW_CONTACT:'[data-action="view-contact"]',ACTION_VIEW_GROUP_INFO:'[data-action="view-group-info"]',CAN_RECEIVE_FOCUS:'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',CONFIRM_DIALOGUE_BUTTON_TEXT:'[data-region="dialogue-button-text"]',CONFIRM_DIALOGUE_CANCEL_BUTTON:'[data-action="cancel-confirm"]',CONFIRM_DIALOGUE_CONTAINER:'[data-region="confirm-dialogue-container"]',CONFIRM_DIALOGUE_HEADER:'[data-region="dialogue-header"]',CONFIRM_DIALOGUE_TEXT:'[data-region="dialogue-text"]',CONTACT_REQUEST_SENT_MESSAGE_CONTAINER:'[data-region="contact-request-sent-message-container"]',CONTENT_PLACEHOLDER_CONTAINER:'[data-region="content-placeholder"]',CONTENT_CONTAINER:'[data-region="content-container"]',CONTENT_MESSAGES_CONTAINER:'[data-region="content-message-container"]',CONTENT_MESSAGES_FOOTER_CONTAINER:'[data-region="content-messages-footer-container"]',CONTENT_MESSAGES_FOOTER_EDIT_MODE_CONTAINER:'[data-region="content-messages-footer-edit-mode-container"]',CONTENT_MESSAGES_FOOTER_REQUIRE_CONTACT_CONTAINER:'[data-region="content-messages-footer-require-contact-container"]',CONTENT_MESSAGES_FOOTER_REQUIRE_UNBLOCK_CONTAINER:'[data-region="content-messages-footer-require-unblock-container"]',CONTENT_MESSAGES_FOOTER_UNABLE_TO_MESSAGE_CONTAINER:'[data-region="content-messages-footer-unable-to-message"]',DAY_MESSAGES_CONTAINER:'[data-region="day-messages-container"]',DELETE_MESSAGES_FOR_ALL_USERS_TOGGLE:'[data-region="delete-messages-for-all-users-toggle"]',DELETE_MESSAGES_FOR_ALL_USERS_TOGGLE_CONTAINER:'[data-region="delete-messages-for-all-users-toggle-container"]',FAVOURITE_ICON_CONTAINER:'[data-region="favourite-icon-container"]',FOOTER_CONTAINER:'[data-region="content-messages-footer-container"]',HEADER:'[data-region="header-content"]',HEADER_EDIT_MODE:'[data-region="header-edit-mode"]',HEADER_PLACEHOLDER_CONTAINER:'[data-region="header-placeholder"]',LOADING_ICON_CONTAINER:'[data-region="loading-icon-container"]',MESSAGE:'[data-region="message"]',MESSAGE_NOT_SELECTED:'[data-region="message"][aria-checked="false"]',MESSAGE_NOT_SELECTED_ICON:'[data-region="not-selected-icon"]',MESSAGE_SELECTED_ICON:'[data-region="selected-icon"]',MESSAGES:'[data-region="content-message-container"]',MESSAGES_CONTAINER:'[data-region="content-message-container"]',MESSAGES_SELECTED_COUNT:'[data-region="message-selected-court"]',MESSAGE_TEXT_AREA:'[data-region="send-message-txt"]',MORE_MESSAGES_LOADING_ICON_CONTAINER:'[data-region="more-messages-loading-icon-container"]',MUTED_ICON_CONTAINER:'[data-region="muted-icon-container"]',PLACEHOLDER_CONTAINER:'[data-region="placeholder-container"]',SELF_CONVERSATION_MESSAGE_CONTAINER:'[data-region="self-conversation-message-container"]',SEND_MESSAGE_BUTTON:'[data-action="send-message"]',SEND_MESSAGE_ICON_CONTAINER:'[data-region="send-icon-container"]',TEXT:'[data-region="text"]',TITLE:'[data-region="title"]'},b={HEADER_PRIVATE:"core_message/message_drawer_view_conversation_header_content_type_private",HEADER_PRIVATE_NO_CONTROLS:"core_message/message_drawer_view_conversation_header_content_type_private_no_controls",HEADER_PUBLIC:"core_message/message_drawer_view_conversation_header_content_type_public",HEADER_SELF:"core_message/message_drawer_view_conversation_header_content_type_self",DAY:"core_message/message_drawer_view_conversation_body_day",MESSAGE:"core_message/message_drawer_view_conversation_body_message",MESSAGES:"core_message/message_drawer_view_conversation_body_messages"},c={PRIVATE:1,PUBLIC:2,SELF:3};return{SELECTORS:a,TEMPLATES:b,CONVERSATION_TYPES:c,NEWEST_MESSAGES_FIRST:!0,LOAD_MESSAGE_LIMIT:100,MILLISECONDS_IN_SEC:1e3}}); \ No newline at end of file diff --git a/message/amd/build/message_drawer_view_conversation_state_manager.min.js b/message/amd/build/message_drawer_view_conversation_state_manager.min.js index baa15c2287bcf..759a316b042b3 100644 --- a/message/amd/build/message_drawer_view_conversation_state_manager.min.js +++ b/message/amd/build/message_drawer_view_conversation_state_manager.min.js @@ -1 +1 @@ -define(["jquery"],function(a){var b=function(b){return a.extend(!0,{},b)},c=function(a,b,c){return a.map(function(a){var d=a.useridfrom==b;return{id:parseInt(a.id,10),isRead:a.isread,fromLoggedInUser:d,userFrom:c[a.useridfrom],text:a.text,timeCreated:parseInt(a.timecreated,10)}})},d=function(a){return a.map(function(a){return{id:a.id,fullname:a.fullname,profileurl:a.profileurl,profileimageurl:a.profileimageurl,profileimageurlsmall:a.profileimageurlsmall,isonline:a.isonline,showonlinestatus:a.showonlinestatus,isblocked:a.isblocked,iscontact:a.iscontact,isdeleted:a.isdeleted,canmessage:a.canmessage,requirescontact:a.requirescontact,contactrequests:a.contactrequests||[]}})},e=function(a,b,c){return{midnight:a,loggedInUserId:b,id:c,name:null,subname:null,type:null,totalMemberCount:null,imageUrl:null,isFavourite:null,isMuted:null,canDeleteMessagesForAllUsers:!1,deleteMessagesForAllUsers:!1,members:{},messages:[],hasTriedToLoadMessages:!1,loadingMessages:!0,sendingMessage:!1,loadingMembers:!0,loadingConfirmAction:!1,pendingBlockUserIds:[],pendingUnblockUserIds:[],pendingRemoveContactIds:[],pendingAddContactIds:[],pendingDeleteMessageIds:[],pendingDeleteConversation:!1,selectedMessageIds:[]}},f=function(a,d){var e=b(a),f=c(d,a.loggedInUserId,a.members),g=a.messages.concat(f);return g.sort(function(a,b){return a.timeCreatedb.timeCreated?1:a.idb.id?1:0}),e.messages=g.filter(function(a,b,c){return!b||a.id!==c[b-1].id}),e},g=function(a,c){var d=b(a),e=c.map(function(a){return a.id});return d.messages=d.messages.filter(function(a){return e.indexOf(a.id)<0}),d},h=function(a,c){var d=b(a);return d.messages=d.messages.filter(function(a){return c.indexOf(a.id)<0}),d},i=function(a,c){var e=b(a),f=d(c);return f.forEach(function(a){e.members[a.id]=a}),e},j=function(a,c){var d=b(a);return c.forEach(function(a){delete d.members[a.id]}),d},k=function(a,c){var d=b(a);return d.loadingMessages=c,a.loadingMessages&&!c&&(d.hasTriedToLoadMessages=!0),d},l=function(a,c){var d=b(a);return d.sendingMessage=c,d},m=function(a,c){var d=b(a);return d.loadingMembers=c,d},n=function(a,c){var d=b(a);return d.id=c,d},o=function(a,c){var d=b(a);return d.name=c,d},p=function(a,c){var d=b(a);return d.subname=c,d},q=function(a,c){var d=b(a);return d.type=c,d},r=function(a,c){var d=b(a);return d.isFavourite=c,d},s=function(a,c){var d=b(a);return d.isMuted=c,d},t=function(a,c){var d=b(a);return d.totalMemberCount=c,d},u=function(a,c){var d=b(a);return d.imageUrl=c,d},v=function(a,c){var d=b(a);return d.loadingConfirmAction=c,d},w=function(a,c){var d=b(a);return d.pendingDeleteConversation=c,d},x=function(a,c){var d=b(a);return c.forEach(function(a){d.pendingBlockUserIds.push(a)}),d},y=function(a,c){var d=b(a);return c.forEach(function(a){d.pendingRemoveContactIds.push(a)}),d},z=function(a,c){var d=b(a);return c.forEach(function(a){d.pendingUnblockUserIds.push(a)}),d},A=function(a,c){var d=b(a);return c.forEach(function(a){d.pendingAddContactIds.push(a)}),d},B=function(a,c){var d=b(a);return c.forEach(function(a){d.pendingDeleteMessageIds.push(a)}),d},C=function(a,c){var d=b(a);return d.pendingBlockUserIds=d.pendingBlockUserIds.filter(function(a){return c.indexOf(a)<0}),d},D=function(a,c){var d=b(a);return d.pendingRemoveContactIds=d.pendingRemoveContactIds.filter(function(a){return c.indexOf(a)<0}),d},E=function(a,c){var d=b(a);return d.pendingUnblockUserIds=d.pendingUnblockUserIds.filter(function(a){return c.indexOf(a)<0}),d},F=function(a,c){var d=b(a);return d.pendingAddContactIds=d.pendingAddContactIds.filter(function(a){return c.indexOf(a)<0}),d},G=function(a,c){var d=b(a);return d.pendingDeleteMessageIds=d.pendingDeleteMessageIds.filter(function(a){return c.indexOf(a)<0}),d},H=function(a,c){var d=b(a);return d.selectedMessageIds=d.selectedMessageIds.concat(c),d},I=function(a,c){var d=b(a);return d.selectedMessageIds=d.selectedMessageIds.filter(function(a){return c.indexOf(a)<0}),d},J=function(a,c){var d=b(a),e=c.map(function(a){return a.id});return d.messages=d.messages.map(function(a){return e.indexOf(a.id)>=0&&(a.isRead=!0),a}),d},K=function(a,c){var d=b(a);return c.forEach(function(a){var b=a.userid,c=a.requesteduserid;d.members[b].contactrequests.push(a),d.members[c].contactrequests.push(a)}),d},L=function(a,c){var d=b(a);return c.forEach(function(a){var b=a.userid,c=a.requesteduserid;d.members[b].contactrequests=d.members[b].contactrequests.filter(function(a){return a.userid!=b}),d.members[c].contactrequests=d.members[c].contactrequests.filter(function(a){return a.requesteduserid!=c})}),d},M=function(a,c){var d=b(a);return d.canDeleteMessagesForAllUsers=c,d},N=function(a,c){var d=b(a);return d.deleteMessagesForAllUsers=c,d};return{buildInitialState:e,addMessages:f,removeMessages:g,removeMessagesById:h,addMembers:i,removeMembers:j,setLoadingMessages:k,setSendingMessage:l,setLoadingMembers:m,setId:n,setName:o,setSubname:p,setType:q,setIsFavourite:r,setIsMuted:s,setCanDeleteMessagesForAllUsers:M,setDeleteMessagesForAllUsers:N,setTotalMemberCount:t,setImageUrl:u,setLoadingConfirmAction:v,setPendingDeleteConversation:w,addPendingBlockUsersById:x,addPendingRemoveContactsById:y,addPendingUnblockUsersById:z,addPendingAddContactsById:A,addPendingDeleteMessagesById:B,removePendingBlockUsersById:C,removePendingRemoveContactsById:D,removePendingUnblockUsersById:E,removePendingAddContactsById:F,removePendingDeleteMessagesById:G,addSelectedMessagesById:H,removeSelectedMessagesById:I,markMessagesAsRead:J,addContactRequests:K,removeContactRequests:L}}); \ No newline at end of file +define(["jquery"],function(a){var b=function(b){return a.extend(!0,{},b)},c=function(a,b,c){return a.map(function(a){var d=a.useridfrom==b;return{id:parseInt(a.id,10),isRead:a.isread,fromLoggedInUser:d,userFrom:c[a.useridfrom],text:a.text,timeCreated:parseInt(a.timecreated,10)}})},d=function(a){return a.map(function(a){return{id:a.id,fullname:a.fullname,profileurl:a.profileurl,profileimageurl:a.profileimageurl,profileimageurlsmall:a.profileimageurlsmall,isonline:a.isonline,showonlinestatus:a.showonlinestatus,isblocked:a.isblocked,iscontact:a.iscontact,isdeleted:a.isdeleted,canmessage:a.canmessage,requirescontact:a.requirescontact,contactrequests:a.contactrequests||[]}})},e=function(a,b,c,d,e,f){return{midnight:a,loggedInUserId:b,id:c,messagePollMin:d,messagePollMax:e,messagePollAfterMax:f,name:null,subname:null,type:null,totalMemberCount:null,imageUrl:null,isFavourite:null,isMuted:null,canDeleteMessagesForAllUsers:!1,deleteMessagesForAllUsers:!1,members:{},messages:[],hasTriedToLoadMessages:!1,loadingMessages:!0,sendingMessage:!1,loadingMembers:!0,loadingConfirmAction:!1,pendingBlockUserIds:[],pendingUnblockUserIds:[],pendingRemoveContactIds:[],pendingAddContactIds:[],pendingDeleteMessageIds:[],pendingDeleteConversation:!1,selectedMessageIds:[]}},f=function(a,d){var e=b(a),f=c(d,a.loggedInUserId,a.members),g=a.messages.concat(f);return g.sort(function(a,b){return a.timeCreatedb.timeCreated?1:a.idb.id?1:0}),e.messages=g.filter(function(a,b,c){return!b||a.id!==c[b-1].id}),e},g=function(a,c){var d=b(a),e=c.map(function(a){return a.id});return d.messages=d.messages.filter(function(a){return e.indexOf(a.id)<0}),d},h=function(a,c){var d=b(a);return d.messages=d.messages.filter(function(a){return c.indexOf(a.id)<0}),d},i=function(a,c){var e=b(a),f=d(c);return f.forEach(function(a){e.members[a.id]=a}),e},j=function(a,c){var d=b(a);return c.forEach(function(a){delete d.members[a.id]}),d},k=function(a,c){var d=b(a);return d.loadingMessages=c,a.loadingMessages&&!c&&(d.hasTriedToLoadMessages=!0),d},l=function(a,c){var d=b(a);return d.sendingMessage=c,d},m=function(a,c){var d=b(a);return d.loadingMembers=c,d},n=function(a,c){var d=b(a);return d.id=c,d},o=function(a,c){var d=b(a);return d.name=c,d},p=function(a,c){var d=b(a);return d.subname=c,d},q=function(a,c){var d=b(a);return d.type=c,d},r=function(a,c){var d=b(a);return d.isFavourite=c,d},s=function(a,c){var d=b(a);return d.isMuted=c,d},t=function(a,c){var d=b(a);return d.totalMemberCount=c,d},u=function(a,c){var d=b(a);return d.imageUrl=c,d},v=function(a,c){var d=b(a);return d.loadingConfirmAction=c,d},w=function(a,c){var d=b(a);return d.pendingDeleteConversation=c,d},x=function(a,c){var d=b(a);return c.forEach(function(a){d.pendingBlockUserIds.push(a)}),d},y=function(a,c){var d=b(a);return c.forEach(function(a){d.pendingRemoveContactIds.push(a)}),d},z=function(a,c){var d=b(a);return c.forEach(function(a){d.pendingUnblockUserIds.push(a)}),d},A=function(a,c){var d=b(a);return c.forEach(function(a){d.pendingAddContactIds.push(a)}),d},B=function(a,c){var d=b(a);return c.forEach(function(a){d.pendingDeleteMessageIds.push(a)}),d},C=function(a,c){var d=b(a);return d.pendingBlockUserIds=d.pendingBlockUserIds.filter(function(a){return c.indexOf(a)<0}),d},D=function(a,c){var d=b(a);return d.pendingRemoveContactIds=d.pendingRemoveContactIds.filter(function(a){return c.indexOf(a)<0}),d},E=function(a,c){var d=b(a);return d.pendingUnblockUserIds=d.pendingUnblockUserIds.filter(function(a){return c.indexOf(a)<0}),d},F=function(a,c){var d=b(a);return d.pendingAddContactIds=d.pendingAddContactIds.filter(function(a){return c.indexOf(a)<0}),d},G=function(a,c){var d=b(a);return d.pendingDeleteMessageIds=d.pendingDeleteMessageIds.filter(function(a){return c.indexOf(a)<0}),d},H=function(a,c){var d=b(a);return d.selectedMessageIds=d.selectedMessageIds.concat(c),d},I=function(a,c){var d=b(a);return d.selectedMessageIds=d.selectedMessageIds.filter(function(a){return c.indexOf(a)<0}),d},J=function(a,c){var d=b(a),e=c.map(function(a){return a.id});return d.messages=d.messages.map(function(a){return e.indexOf(a.id)>=0&&(a.isRead=!0),a}),d},K=function(a,c){var d=b(a);return c.forEach(function(a){var b=a.userid,c=a.requesteduserid;d.members[b].contactrequests.push(a),d.members[c].contactrequests.push(a)}),d},L=function(a,c){var d=b(a);return c.forEach(function(a){var b=a.userid,c=a.requesteduserid;d.members[b].contactrequests=d.members[b].contactrequests.filter(function(a){return a.userid!=b}),d.members[c].contactrequests=d.members[c].contactrequests.filter(function(a){return a.requesteduserid!=c})}),d},M=function(a,c){var d=b(a);return d.canDeleteMessagesForAllUsers=c,d},N=function(a,c){var d=b(a);return d.deleteMessagesForAllUsers=c,d};return{buildInitialState:e,addMessages:f,removeMessages:g,removeMessagesById:h,addMembers:i,removeMembers:j,setLoadingMessages:k,setSendingMessage:l,setLoadingMembers:m,setId:n,setName:o,setSubname:p,setType:q,setIsFavourite:r,setIsMuted:s,setCanDeleteMessagesForAllUsers:M,setDeleteMessagesForAllUsers:N,setTotalMemberCount:t,setImageUrl:u,setLoadingConfirmAction:v,setPendingDeleteConversation:w,addPendingBlockUsersById:x,addPendingRemoveContactsById:y,addPendingUnblockUsersById:z,addPendingAddContactsById:A,addPendingDeleteMessagesById:B,removePendingBlockUsersById:C,removePendingRemoveContactsById:D,removePendingUnblockUsersById:E,removePendingAddContactsById:F,removePendingDeleteMessagesById:G,addSelectedMessagesById:H,removeSelectedMessagesById:I,markMessagesAsRead:J,addContactRequests:K,removeContactRequests:L}}); \ No newline at end of file diff --git a/message/amd/src/message_drawer_view_conversation.js b/message/amd/src/message_drawer_view_conversation.js index 4c98b0583f7eb..7ff0805234ade 100644 --- a/message/amd/src/message_drawer_view_conversation.js +++ b/message/amd/src/message_drawer_view_conversation.js @@ -112,7 +112,7 @@ function( var NEWEST_FIRST = Constants.NEWEST_MESSAGES_FIRST; var LOAD_MESSAGE_LIMIT = Constants.LOAD_MESSAGE_LIMIT; - var INITIAL_NEW_MESSAGE_POLL_TIMEOUT = Constants.INITIAL_NEW_MESSAGE_POLL_TIMEOUT; + var MILLISECONDS_IN_SEC = Constants.MILLISECONDS_IN_SEC; var SELECTORS = Constants.SELECTORS; var CONVERSATION_TYPES = Constants.CONVERSATION_TYPES; @@ -1495,13 +1495,12 @@ function( newMessagesPollTimer = new BackOffTimer( getLoadNewMessagesCallback(conversationId, NEWEST_FIRST), - function(time) { - if (!time) { - return INITIAL_NEW_MESSAGE_POLL_TIMEOUT; - } - - return time * 2; - } + BackOffTimer.getIncrementalCallback( + viewState.messagePollMin * MILLISECONDS_IN_SEC, + MILLISECONDS_IN_SEC, + viewState.messagePollMax * MILLISECONDS_IN_SEC, + viewState.messagePollAfterMax * MILLISECONDS_IN_SEC + ) ); newMessagesPollTimer.start(); @@ -1524,7 +1523,17 @@ function( var loggedInUserId = loggedInUserProfile.id; var midnight = parseInt(body.attr('data-midnight'), 10); - var initialState = StateManager.buildInitialState(midnight, loggedInUserId, conversationId); + var messagePollMin = parseInt(body.attr('data-message-poll-min'), 10); + var messagePollMax = parseInt(body.attr('data-message-poll-max'), 10); + var messagePollAfterMax = parseInt(body.attr('data-message-poll-after-max'), 10); + var initialState = StateManager.buildInitialState( + midnight, + loggedInUserId, + conversationId, + messagePollMin, + messagePollMax, + messagePollAfterMax + ); if (!viewState) { viewState = initialState; diff --git a/message/amd/src/message_drawer_view_conversation_constants.js b/message/amd/src/message_drawer_view_conversation_constants.js index 00a3bbb1243b7..8dd66efac3b4d 100644 --- a/message/amd/src/message_drawer_view_conversation_constants.js +++ b/message/amd/src/message_drawer_view_conversation_constants.js @@ -110,6 +110,6 @@ define([], function() { CONVERSATION_TYPES: CONVERSATION_TYPES, NEWEST_MESSAGES_FIRST: true, LOAD_MESSAGE_LIMIT: 100, - INITIAL_NEW_MESSAGE_POLL_TIMEOUT: 1000 + MILLISECONDS_IN_SEC: 1000 }; }); diff --git a/message/amd/src/message_drawer_view_conversation_state_manager.js b/message/amd/src/message_drawer_view_conversation_state_manager.js index 3f67cb7436ff7..5ed8eccbfda63 100644 --- a/message/amd/src/message_drawer_view_conversation_state_manager.js +++ b/message/amd/src/message_drawer_view_conversation_state_manager.js @@ -101,13 +101,26 @@ define(['jquery'], function($) { * @param {Number} midnight Midnight time. * @param {Number} loggedInUserId The logged in user id. * @param {Number} id The conversation id. + * @param {Number} messagePollMin The message poll start timeout in seconds. + * @param {Number} messagePollMax The message poll max timeout limit in seconds. + * @param {Number} messagePollAfterMax The message poll frequency in seconds to reset to after max limit is reached. * @return {Object} Initial state. */ - var buildInitialState = function(midnight, loggedInUserId, id) { + var buildInitialState = function( + midnight, + loggedInUserId, + id, + messagePollMin, + messagePollMax, + messagePollAfterMax + ) { return { midnight: midnight, loggedInUserId: loggedInUserId, id: id, + messagePollMin: messagePollMin, + messagePollMax: messagePollMax, + messagePollAfterMax: messagePollAfterMax, name: null, subname: null, type: null, diff --git a/message/classes/helper.php b/message/classes/helper.php index aa061c2345071..5136ce81f2c97 100644 --- a/message/classes/helper.php +++ b/message/classes/helper.php @@ -26,6 +26,8 @@ defined('MOODLE_INTERNAL') || die(); +require_once($CFG->dirroot . '/message/lib.php'); + /** * Helper class for the message area. * @@ -741,6 +743,12 @@ public static function render_messaging_widget(bool $isdrawer, int $sendtouser = 'id' => $USER->id, 'midnight' => usergetmidnight(time()) ], + // The starting timeout value for message polling. + 'messagepollmin' => $CFG->messagingminpoll ?? MESSAGE_DEFAULT_MIN_POLL_IN_SECONDS, + // The maximum value that message polling timeout can reach. + 'messagepollmax' => $CFG->messagingmaxpoll ?? MESSAGE_DEFAULT_MAX_POLL_IN_SECONDS, + // The timeout to reset back to after the max polling time has been reached. + 'messagepollaftermax' => $CFG->messagingtimeoutpoll ?? MESSAGE_DEFAULT_TIMEOUT_POLL_IN_SECONDS, 'contacts' => [ 'sectioncontacts' => [ 'placeholders' => array_fill(0, $contactscount > 50 ? 50 : $contactscount, true) diff --git a/message/templates/message_drawer_view_conversation_body.mustache b/message/templates/message_drawer_view_conversation_body.mustache index 463f89a0a6868..8f87320fe366d 100644 --- a/message/templates/message_drawer_view_conversation_body.mustache +++ b/message/templates/message_drawer_view_conversation_body.mustache @@ -40,6 +40,9 @@ data-region="view-conversation" data-user-id="{{loggedinuser.id}}" data-midnight="{{loggedinuser.midnight}}" + data-message-poll-min="{{messagepollmin}}" + data-message-poll-max="{{messagepollmax}}" + data-message-poll-after-max="{{messagepollaftermax}}" style="overflow-y: auto; overflow-x: hidden" >
From 8a8a02c903a10eb5410b4f339379e1187d9a4724 Mon Sep 17 00:00:00 2001 From: Mathew May Date: Wed, 15 May 2019 11:21:27 +0800 Subject: [PATCH 046/786] MDL-65606 mod_data: Add approvalstatusclass to template --- mod/data/db/upgrade.php | 17 +++++++++++++++++ mod/data/lib.php | 6 +++++- mod/data/version.php | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/mod/data/db/upgrade.php b/mod/data/db/upgrade.php index 0ecbeff5166a6..a38a100dedc89 100644 --- a/mod/data/db/upgrade.php +++ b/mod/data/db/upgrade.php @@ -56,5 +56,22 @@ function xmldb_data_upgrade($oldversion) { // Automatically generated Moodle v3.7.0 release upgrade line. // Put any upgrade step following this. + if ($oldversion < 2019052001) { + + $columns = $DB->get_columns('data'); + + $oldclass = "mod-data-default-template ##approvalstatus##"; + $newclass = "mod-data-default-template ##approvalstatusclass##"; + + // Update existing classes. + $DB->replace_all_text('data', $columns['singletemplate'], $oldclass, $newclass); + $DB->replace_all_text('data', $columns['listtemplate'], $oldclass, $newclass); + $DB->replace_all_text('data', $columns['addtemplate'], $oldclass, $newclass); + $DB->replace_all_text('data', $columns['rsstemplate'], $oldclass, $newclass); + $DB->replace_all_text('data', $columns['asearchtemplate'], $oldclass, $newclass); + + // Data savepoint reached. + upgrade_mod_savepoint(true, 2019052001, 'data'); + } return true; } diff --git a/mod/data/lib.php b/mod/data/lib.php index 37519ceb2fdab..9b3d93d8ff755 100644 --- a/mod/data/lib.php +++ b/mod/data/lib.php @@ -608,7 +608,7 @@ function data_generate_default_template(&$data, $template, $recordid=0, $form=fa if ($fields = $DB->get_records('data_fields', array('dataid'=>$data->id), 'id')) { $table = new html_table(); - $table->attributes['class'] = 'mod-data-default-template ##approvalstatus##'; + $table->attributes['class'] = 'mod-data-default-template ##approvalstatusclass##'; $table->colclasses = array('template-field', 'template-token'); $table->data = array(); foreach ($fields as $field) { @@ -1507,12 +1507,16 @@ function data_print_template($template, $records, $data, $search='', $page=0, $r } $patterns[] = '##approvalstatus##'; + $patterns[] = '##approvalstatusclass##'; if (!$data->approval) { $replacement[] = ''; + $replacement[] = ''; } else if ($record->approved) { $replacement[] = get_string('approved', 'data'); + $replacement[] = 'approved'; } else { $replacement[] = get_string('notapproved', 'data'); + $replacement[] = 'notapproved'; } $patterns[]='##comments##'; diff --git a/mod/data/version.php b/mod/data/version.php index d3bcc4f12cb5e..d2b5d3febf628 100644 --- a/mod/data/version.php +++ b/mod/data/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2019052000; // The current module version (Date: YYYYMMDDXX) +$plugin->version = 2019052001; // The current module version (Date: YYYYMMDDXX) $plugin->requires = 2019051100; // Requires this Moodle version $plugin->component = 'mod_data'; // Full name of the plugin (used for diagnostics) $plugin->cron = 0; From e2ea9b4c097dc6c898f5f968f444d0f4c4e00894 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 24 May 2019 14:51:29 +0800 Subject: [PATCH 047/786] MDL-64330 course: Correct course test assumptions --- course/tests/courselib_test.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/course/tests/courselib_test.php b/course/tests/courselib_test.php index 26197f01b8e0c..8cd7d25a87cc9 100644 --- a/course/tests/courselib_test.php +++ b/course/tests/courselib_test.php @@ -5021,6 +5021,7 @@ public function test_core_course_core_calendar_get_valid_event_timestart_range_w * Test the course_get_recent_courses function. */ public function test_course_get_recent_courses() { + global $DB; $this->resetAfterTest(); $generator = $this->getDataGenerator(); @@ -5043,9 +5044,15 @@ public function test_course_get_recent_courses() { // No course accessed. $this->assertCount(0, $result); + $time = time(); foreach ($courses as $course) { $context = context_course::instance($course->id); course_view($context); + $DB->set_field('user_lastaccess', 'timeaccess', $time, [ + 'userid' => $student->id, + 'courseid' => $course->id, + ]); + $time++; } // Every course accessed. @@ -5056,10 +5063,10 @@ public function test_course_get_recent_courses() { $result = course_get_recent_courses($student->id, 2); $this->assertCount(2, $result); - // Every course accessed, with limit and offset. Should return only the last created course ($course[2]). + // Every course accessed, with limit and offset should return the first course. $result = course_get_recent_courses($student->id, 3, 2); $this->assertCount(1, $result); - $this->assertArrayHasKey($courses[2]->id, $result); + $this->assertArrayHasKey($courses[0]->id, $result); // Every course accessed, order by shortname DESC. The last create course ($course[2]) should have the greater shortname. $result = course_get_recent_courses($student->id, 0, 0, 'shortname DESC'); From ec920f79014fa99d928ba1a34b8cab7d92a97546 Mon Sep 17 00:00:00 2001 From: Dmitrii Metelkin Date: Tue, 28 May 2019 10:46:26 +1000 Subject: [PATCH 048/786] MDL-65326 backup: check caps exist before assigning --- backup/moodle2/restore_stepslib.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/backup/moodle2/restore_stepslib.php b/backup/moodle2/restore_stepslib.php index fe699b3f6603d..683e90225bee5 100644 --- a/backup/moodle2/restore_stepslib.php +++ b/backup/moodle2/restore_stepslib.php @@ -1980,6 +1980,12 @@ protected function after_execute() { } $capability = 'mod/' . $modname . ':addinstance'; + + if (!get_capability_info($capability)) { + $this->log("Capability '{$capability}' was not found!", backup::LOG_WARNING); + continue; + } + foreach ($roleids as $roleid) { assign_capability($capability, CAP_PREVENT, $roleid, $context); } @@ -2107,9 +2113,12 @@ public function process_override($data) { $newroleid = $this->get_mappingid('role', $data->roleid); // If newroleid and context are valid assign it via API (it handles dupes and so on) if ($newroleid && $this->task->get_contextid()) { - // TODO: assign_capability() needs one userid param to be able to specify our restore userid - // TODO: it seems that assign_capability() doesn't check for valid capabilities at all ??? - assign_capability($data->capability, $data->permission, $newroleid, $this->task->get_contextid()); + if (!get_capability_info($data->capability)) { + $this->log("Capability '{$data->capability}' was not found!", backup::LOG_WARNING); + } else { + // TODO: assign_capability() needs one userid param to be able to specify our restore userid. + assign_capability($data->capability, $data->permission, $newroleid, $this->task->get_contextid()); + } } } } From 48b3e4e9b24dc47905b62a4cbc15061345cb5da6 Mon Sep 17 00:00:00 2001 From: Ryan Wyllie Date: Tue, 28 May 2019 09:59:14 +0800 Subject: [PATCH 049/786] MDL-65657 message: reduce message poll timer for behat tests --- message/tests/behat/delete_messages.feature | 3 ++- message/tests/behat/favourite_conversations.feature | 3 ++- message/tests/behat/group_conversation.feature | 3 +++ message/tests/behat/message_delete_conversation.feature | 1 + message/tests/behat/message_drawer_manage_contacts.feature | 3 ++- message/tests/behat/message_manage_preferences.feature | 3 ++- message/tests/behat/message_send_messages.feature | 3 ++- message/tests/behat/self_conversation.feature | 3 ++- message/tests/behat/unread_messages.feature | 3 ++- 9 files changed, 18 insertions(+), 7 deletions(-) diff --git a/message/tests/behat/delete_messages.feature b/message/tests/behat/delete_messages.feature index 3f985ebce04f5..9de5bc3f0d62b 100644 --- a/message/tests/behat/delete_messages.feature +++ b/message/tests/behat/delete_messages.feature @@ -34,7 +34,8 @@ Feature: Delete messages from conversations | student2 | student1 | Hello! | | student1 | student2 | Are you free? | And the following config values are set as admin: - | messaging | 1 | + | messaging | 1 | + | messagingminpoll | 1 | Scenario: Delete a message sent by the user from a group conversation Given I log in as "student1" diff --git a/message/tests/behat/favourite_conversations.feature b/message/tests/behat/favourite_conversations.feature index 4f8b25cda1ef7..842b55ed4e71b 100644 --- a/message/tests/behat/favourite_conversations.feature +++ b/message/tests/behat/favourite_conversations.feature @@ -24,7 +24,8 @@ Feature: Star and unstar conversations | student1 | G1 | | student2 | G1 | And the following config values are set as admin: - | messaging | 1 | + | messaging | 1 | + | messagingminpoll | 1 | Scenario: Star a group conversation Given I log in as "student1" diff --git a/message/tests/behat/group_conversation.feature b/message/tests/behat/group_conversation.feature index 105164e792356..e9907274b4b25 100644 --- a/message/tests/behat/group_conversation.feature +++ b/message/tests/behat/group_conversation.feature @@ -39,6 +39,9 @@ Feature: Create conversations for course's groups | teacher1 | G2 | | teacher1 | G3 | | student0 | G3 | + And the following config values are set as admin: + | messaging | 1 | + | messagingminpoll | 1 | Scenario: Group conversations are restricted to members Given I log in as "teacher1" diff --git a/message/tests/behat/message_delete_conversation.feature b/message/tests/behat/message_delete_conversation.feature index 02bfe52c452fc..183c07a741d6e 100644 --- a/message/tests/behat/message_delete_conversation.feature +++ b/message/tests/behat/message_delete_conversation.feature @@ -19,6 +19,7 @@ Feature: Message delete conversations And the following config values are set as admin: | messaging | 1 | | messagingallusers | 1 | + | messagingminpoll | 1 | And the following "private messages" exist: | user | contact | message | | student1 | student2 | Hi! | diff --git a/message/tests/behat/message_drawer_manage_contacts.feature b/message/tests/behat/message_drawer_manage_contacts.feature index 4c57223ac820a..1b8c3b01f0055 100644 --- a/message/tests/behat/message_drawer_manage_contacts.feature +++ b/message/tests/behat/message_drawer_manage_contacts.feature @@ -24,8 +24,9 @@ Feature: Manage contacts | user | contact | | student1 | student2 | And the following config values are set as admin: - | messaging | 1 | + | messaging | 1 | | messagingallusers | 1 | + | messagingminpoll | 1 | Scenario: Send a 'contact request' to someone to add a contact Given I log in as "student1" diff --git a/message/tests/behat/message_manage_preferences.feature b/message/tests/behat/message_manage_preferences.feature index f8c304abe4076..65c013e92bbb6 100644 --- a/message/tests/behat/message_manage_preferences.feature +++ b/message/tests/behat/message_manage_preferences.feature @@ -33,8 +33,9 @@ Feature: Manage preferences | user | contact | | student1 | student2 | And the following config values are set as admin: - | messaging | 1 | + | messaging | 1 | | messagingallusers | 1 | + | messagingminpoll | 1 | # Recipient has 'My contacts only' set. Scenario: Allow sending a message when you are a contact diff --git a/message/tests/behat/message_send_messages.feature b/message/tests/behat/message_send_messages.feature index 1596073932f20..45f1a93c555b7 100644 --- a/message/tests/behat/message_send_messages.feature +++ b/message/tests/behat/message_send_messages.feature @@ -24,7 +24,8 @@ Feature: Message send messages | student1 | G1 | | student2 | G1 | And the following config values are set as admin: - | messaging | 1 | + | messaging | 1 | + | messagingminpoll | 1 | Scenario: Send a message to a group conversation Given I log in as "student1" diff --git a/message/tests/behat/self_conversation.feature b/message/tests/behat/self_conversation.feature index 14f6a543909c2..5063b3cd2ed62 100644 --- a/message/tests/behat/self_conversation.feature +++ b/message/tests/behat/self_conversation.feature @@ -9,7 +9,8 @@ Feature: Self conversation | username | firstname | lastname | email | | student1 | Student | 1 | student1@example.com | And the following config values are set as admin: - | messaging | 1 | + | messaging | 1 | + | messagingminpoll | 1 | Scenario: Self conversation exists Given I log in as "student1" diff --git a/message/tests/behat/unread_messages.feature b/message/tests/behat/unread_messages.feature index 07b47f5a87e3c..97f5ffa02fdfe 100644 --- a/message/tests/behat/unread_messages.feature +++ b/message/tests/behat/unread_messages.feature @@ -24,7 +24,8 @@ Feature: Unread messages | student1 | NG | | student2 | NG | And the following config values are set as admin: - | messaging | 1 | + | messaging | 1 | + | messagingminpoll | 1 | Scenario: Unread messages for group conversation Given I log in as "student1" From b32974f12a7c512575867f31dcd5d456e79f5216 Mon Sep 17 00:00:00 2001 From: Sara Arjona Date: Fri, 24 May 2019 13:59:15 +0200 Subject: [PATCH 050/786] MDL-65705 badges: fix issued date for external badges The preg_match('~^[1-9][0-9]*$~', x) calls have been replaced to is_numeric(x). --- badges/renderer.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/badges/renderer.php b/badges/renderer.php index 7e86ba2b9547e..74ce368abefd3 100644 --- a/badges/renderer.php +++ b/badges/renderer.php @@ -420,12 +420,14 @@ protected function render_issued_badge(\core_badges\output\issued_badge $ibadge) $output .= $this->output->heading(get_string('issuancedetails', 'badges'), 3); $dl = array(); - $issued['issuedOn'] = !preg_match( '~^[1-9][0-9]*$~', $issued['issuedOn'] ) ? - strtotime($issued['issuedOn']) : $issued['issuedOn']; + if (!is_numeric($issued['issuedOn'])) { + $issued['issuedOn'] = strtotime($issued['issuedOn']); + } $dl[get_string('dateawarded', 'badges')] = userdate($issued['issuedOn']); if (isset($issued['expires'])) { - $issued['expires'] = !preg_match( '~^[1-9][0-9]*$~', $issued['expires'] ) ? - strtotime($issued['expires']) : $issued['expires']; + if (!is_numeric($issued['expires'])) { + $issued['expires'] = strtotime($issued['expires']); + } if ($issued['expires'] < $now) { $dl[get_string('expirydate', 'badges')] = userdate($issued['expires']) . get_string('warnexpired', 'badges'); @@ -508,7 +510,7 @@ protected function render_external_badge(\core_badges\output\external_badge $iba } $output .= html_writer::empty_tag('img', array('src' => $issued->image, 'width' => '100')); if (isset($assertion->expires)) { - $expiration = !strtotime($assertion->expires) ? s($assertion->expires) : strtotime($assertion->expires); + $expiration = is_numeric($assertion->expires) ? $assertion->expires : strtotime($assertion->expires); if ($expiration < $today) { $output .= $this->output->pix_icon('i/expired', get_string('expireddate', 'badges', userdate($expiration)), @@ -564,7 +566,7 @@ protected function render_external_badge(\core_badges\output\external_badge $iba $dl = array(); if (isset($assertion->issued_on)) { - $issuedate = !strtotime($assertion->issued_on) ? s($assertion->issued_on) : strtotime($assertion->issued_on); + $issuedate = is_numeric($assertion->issued_on) ? $assertion->issued_on : strtotime($assertion->issued_on); $dl[get_string('dateawarded', 'badges')] = userdate($issuedate); } if (isset($assertion->expires)) { From d6c2bf620cca2d6710f58bcb4e94e417d3db6de4 Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Mon, 27 May 2019 17:45:58 +0200 Subject: [PATCH 051/786] MDL-65726 role: do not fail unittest if plugins create their roles --- lib/tests/accesslib_test.php | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/tests/accesslib_test.php b/lib/tests/accesslib_test.php index 0d7f24b1968a9..0136b40db4bca 100644 --- a/lib/tests/accesslib_test.php +++ b/lib/tests/accesslib_test.php @@ -727,8 +727,13 @@ public function test_get_all_roles() { $this->resetAfterTest(); $allroles = get_all_roles(); - $this->assertInternalType('array', $allroles); - $this->assertCount(8, $allroles); // There are 8 roles is standard install. + $this->assertIsArray($allroles); + $initialrolescount = count($allroles); + $this->assertTrue($initialrolescount >= 8); // There are 8 roles is standard install. + $rolenames = array_column($allroles, 'shortname'); + foreach (get_role_archetypes() as $archetype) { + $this->assertContains($archetype, $rolenames); + } $role = reset($allroles); $role = (array)$role; @@ -750,8 +755,8 @@ public function test_get_all_roles() { $renames = $DB->get_records_menu('role_names', array('contextid'=>$coursecontext->id), '', 'roleid, name'); $allroles = get_all_roles($coursecontext); - $this->assertInternalType('array', $allroles); - $this->assertCount(9, $allroles); + $this->assertIsArray($allroles); + $this->assertCount($initialrolescount + 1, $allroles); $role = reset($allroles); $role = (array)$role; @@ -784,11 +789,11 @@ public function test_get_role_archetypes() { public function test_get_archetype_roles() { $this->resetAfterTest(); - // New install should have 1 role for each archetype. + // New install should have at least 1 role for each archetype. $archetypes = get_role_archetypes(); foreach ($archetypes as $archetype) { $roles = get_archetype_roles($archetype); - $this->assertCount(1, $roles); + $this->assertGreaterThanOrEqual(1, count($roles)); $role = reset($roles); $this->assertSame($archetype, $role->archetype); } @@ -818,8 +823,11 @@ public function test_role_get_name() { $renames = $DB->get_records_menu('role_names', array('contextid'=>$coursecontext->id), '', 'roleid, name'); foreach ($allroles as $role) { + if (in_array($role->shortname, get_role_archetypes())) { + // Standard roles do not have a set name. + $this->assertSame('', $role->name); + } // Get localised name from lang pack. - $this->assertSame('', $role->name); $name = role_get_name($role, null, ROLENAME_ORIGINAL); $this->assertNotEmpty($name); $this->assertNotEquals($role->shortname, $name); From 308046f1bc719c14f73c651ad7b718e03646b080 Mon Sep 17 00:00:00 2001 From: AMOS bot Date: Wed, 29 May 2019 00:09:19 +0000 Subject: [PATCH 052/786] Automatically generated installer lang files --- install/lang/es_ve/langconfig.php | 2 +- install/lang/km/error.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/install/lang/es_ve/langconfig.php b/install/lang/es_ve/langconfig.php index 65aaeb6d25c67..12bed67bc5b81 100644 --- a/install/lang/es_ve/langconfig.php +++ b/install/lang/es_ve/langconfig.php @@ -31,4 +31,4 @@ defined('MOODLE_INTERNAL') || die(); $string['parentlanguage'] = 'es'; -$string['thislanguage'] = 'Español Venezuela'; +$string['thislanguage'] = 'Español - Venezuela'; diff --git a/install/lang/km/error.php b/install/lang/km/error.php index 114fcfe083e2c..c39229547588d 100644 --- a/install/lang/km/error.php +++ b/install/lang/km/error.php @@ -41,7 +41,7 @@ $string['componentisuptodate'] = 'សមាសភាគគឺទាន់សម័យ ។'; $string['downloadedfilecheckfailed'] = 'បានបរាជ័យក្នុងការពិនិត្យឯកសារដែលបានទាញយក ។'; $string['invalidmd5'] = 'md5 មិនត្រឹមត្រូវ'; -$string['missingrequiredfield'] = 'បាត់វាលដែលត្រូវការមួយចំនួន'; +$string['missingrequiredfield'] = 'បាត់ប្រអប់ទិន្នន័យដែលត្រូវទាមទារមួយចំនួន'; $string['remotedownloaderror'] = 'បរាជ័យក្នុងការទាញយកសមាសភាគទៅម៉ាស៊ីនបម្រើរបស់អ្នក សូមផ្ទៀងផ្ទាត់ប្រូកស៊ី ផ្នែកបន្ថែម PHP cURL ត្រូវបានផ្ដល់អនុសាសន៍ ។

អ្នកត្រូវតែទាញយកឯកសារ {$a->url} ដោយដៃ ចម្លងវាទៅ "{$a->dest}" ក្នុងម៉ាស៊ីនបម្រើរបស់អ្នក និងពន្លាវានៅទីនោះ ។'; $string['wrongdestpath'] = 'ផ្លូវទិសដៅមិនត្រឹមត្រូវ ។'; $string['wrongsourcebase'] = 'មូលដ្ឋាន URL ប្រភពមិនត្រឹមត្រូវ ។'; From 04288af505d47904441bc826d90bb82ec6130dc8 Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Wed, 29 May 2019 09:55:23 +0800 Subject: [PATCH 053/786] MDL-57729 enrol_lti: Escape the property values of the xpath elements --- enrol/lti/classes/helper.php | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/enrol/lti/classes/helper.php b/enrol/lti/classes/helper.php index c8fadbafc4c91..a101b0d2437ba 100644 --- a/enrol/lti/classes/helper.php +++ b/enrol/lti/classes/helper.php @@ -576,18 +576,19 @@ protected static function get_cartridge_parameters($toolid) { // Work out the name of the tool. $title = self::get_name($tool); $launchurl = self::get_launch_url($toolid); - $launchurl = $launchurl->out(); - $icon = self::get_icon($tool); + $launchurl = $launchurl->out(false); + $iconurl = self::get_icon($tool); + $iconurl = $iconurl->out(false); $securelaunchurl = null; - $secureicon = null; + $secureiconurl = null; $vendorurl = new \moodle_url('/'); - $vendorurl = $vendorurl->out(); + $vendorurl = $vendorurl->out(false); $description = self::get_description($tool); // If we are a https site, we can add the launch url and icon urls as secure equivalents. if (\is_https()) { $securelaunchurl = $launchurl; - $secureicon = $icon; + $secureiconurl = $iconurl; } return array( @@ -595,13 +596,13 @@ protected static function get_cartridge_parameters($toolid) { "/blti:title" => $title, "/blti:description" => $description, "/blti:extensions" => array( - "/lticm:property[@name='icon_url']" => $icon, - "/lticm:property[@name='secure_icon_url']" => $secureicon + "/lticm:property[@name='icon_url']" => $iconurl, + "/lticm:property[@name='secure_icon_url']" => $secureiconurl ), "/blti:launch_url" => $launchurl, "/blti:secure_launch_url" => $securelaunchurl, - "/blti:icon" => $icon, - "/blti:secure_icon" => $secureicon, + "/blti:icon" => $iconurl, + "/blti:secure_icon" => $secureiconurl, "/blti:vendor" => array( "/lticp:code" => $SITE->shortname, "/lticp:name" => $SITE->fullname, @@ -634,7 +635,7 @@ protected static function set_xpath($xpath, $parameters, $prefix = '') { if (is_null($value)) { $node->parentNode->removeChild($node); } else { - $node->nodeValue = $value; + $node->nodeValue = s($value); } } } else { From 09304bcbff40855908a3dac1c320016b616f751a Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Tue, 28 May 2019 15:08:00 +0800 Subject: [PATCH 054/786] MDL-55592 lti: Forget the key and secret When the "Enter your consumer key and shared secret" form is displayed, it should not contain the same values it had the last time it was opened. --- mod/lti/amd/build/tool_configure_controller.min.js | 2 +- mod/lti/amd/src/tool_configure_controller.js | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/mod/lti/amd/build/tool_configure_controller.min.js b/mod/lti/amd/build/tool_configure_controller.min.js index 2be614155e08c..655e33e455fcb 100644 --- a/mod/lti/amd/build/tool_configure_controller.min.js +++ b/mod/lti/amd/build/tool_configure_controller.min.js @@ -1 +1 @@ -define(["jquery","core/ajax","core/notification","core/templates","mod_lti/events","mod_lti/keys","mod_lti/tool_type","mod_lti/tool_proxy","core/str"],function(a,b,c,d,e,f,g,h,i){var j={EXTERNAL_REGISTRATION_CONTAINER:"#external-registration-container",EXTERNAL_REGISTRATION_PAGE_CONTAINER:"#external-registration-page-container",CARTRIDGE_REGISTRATION_CONTAINER:"#cartridge-registration-container",CARTRIDGE_REGISTRATION_FORM:"#cartridge-registration-form",ADD_TOOL_FORM:"#add-tool-form",TOOL_LIST_CONTAINER:"#tool-list-container",TOOL_CREATE_BUTTON:"#tool-create-button",REGISTRATION_CHOICE_CONTAINER:"#registration-choice-container",TOOL_URL:"#tool-url"},k=function(){return a(j.TOOL_CREATE_BUTTON)},l=function(){return a(j.TOOL_LIST_CONTAINER)},m=function(){return a(j.EXTERNAL_REGISTRATION_CONTAINER)},n=function(){return a(j.CARTRIDGE_REGISTRATION_CONTAINER)},o=function(){return a(j.REGISTRATION_CHOICE_CONTAINER)},p=function(){return a(j.TOOL_URL).val()},q=function(){m().addClass("hidden")},r=function(){n().addClass("hidden")},s=function(){o().addClass("hidden")},t=function(){r(),s(),m().removeClass("hidden"),w(m())},u=function(a){q(),s(),n().removeClass("hidden"),n().find(j.CARTRIDGE_REGISTRATION_FORM).attr("data-cartridge-url",a),w(n())},v=function(){q(),r(),o().removeClass("hidden"),w(o())},w=function(a){var b=a.children().detach();b.appendTo(a)},x=function(){l().addClass("hidden")},y=function(){l().removeClass("hidden")},z=function(a){var b=a.error?"error":"success";c.addNotification({message:a.message,type:b})},A=function(a){a.addClass("loading")},B=function(a){a.removeClass("loading")},C=function(){var b=a.Deferred(),e=l();A(e),a.when(g.query(),h.query({orphanedonly:!0})).done(function(a,c){d.render("mod_lti/tool_list",{tools:a,proxies:c}).done(function(a,c){e.empty(),e.append(a),d.runTemplateJS(c),b.resolve()}).fail(b.reject)}).fail(b.reject),b.fail(c.exception).always(function(){B(e)})},D=function(){var b=a.trim(p());if(""===b)return a.Deferred().resolve();var d=k();A(d);var f=g.isCartridge(b);return f.always(function(){B(d)}),f.done(function(c){c.iscartridge?(a(j.TOOL_URL).val(""),a(document).trigger(e.START_CARTRIDGE_REGISTRATION,b)):a(document).trigger(e.START_EXTERNAL_REGISTRATION,{url:b})}),f.fail(function(){i.get_string("errorbadurl","mod_lti").done(function(b){a(document).trigger(e.REGISTRATION_FEEDBACK,{message:b,error:!0})}).fail(c.exception)}),f},E=function(){a(document).on(e.NEW_TOOL_TYPE,function(){C()}),a(document).on(e.START_EXTERNAL_REGISTRATION,function(){t(),a(j.TOOL_URL).val(""),x()}),a(document).on(e.STOP_EXTERNAL_REGISTRATION,function(){y(),v()}),a(document).on(e.START_CARTRIDGE_REGISTRATION,function(a,b){u(b)}),a(document).on(e.STOP_CARTRIDGE_REGISTRATION,function(){n().find(j.CARTRIDGE_REGISTRATION_FORM).removeAttr("data-cartridge-url"),v()}),a(document).on(e.REGISTRATION_FEEDBACK,function(a,b){z(b)});var b=a(j.ADD_TOOL_FORM);b.submit(function(a){a.preventDefault(),D()})};return{init:function(){E(),C()}}}); \ No newline at end of file +define(["jquery","core/ajax","core/notification","core/templates","mod_lti/events","mod_lti/keys","mod_lti/tool_type","mod_lti/tool_proxy","core/str"],function(a,b,c,d,e,f,g,h,i){var j={EXTERNAL_REGISTRATION_CONTAINER:"#external-registration-container",EXTERNAL_REGISTRATION_PAGE_CONTAINER:"#external-registration-page-container",CARTRIDGE_REGISTRATION_CONTAINER:"#cartridge-registration-container",CARTRIDGE_REGISTRATION_FORM:"#cartridge-registration-form",ADD_TOOL_FORM:"#add-tool-form",TOOL_LIST_CONTAINER:"#tool-list-container",TOOL_CREATE_BUTTON:"#tool-create-button",REGISTRATION_CHOICE_CONTAINER:"#registration-choice-container",TOOL_URL:"#tool-url"},k=function(){return a(j.TOOL_CREATE_BUTTON)},l=function(){return a(j.TOOL_LIST_CONTAINER)},m=function(){return a(j.EXTERNAL_REGISTRATION_CONTAINER)},n=function(){return a(j.CARTRIDGE_REGISTRATION_CONTAINER)},o=function(){return a(j.REGISTRATION_CHOICE_CONTAINER)},p=function(){return a(j.TOOL_URL).val()},q=function(){m().addClass("hidden")},r=function(){n().addClass("hidden")},s=function(){o().addClass("hidden")},t=function(){r(),s(),m().removeClass("hidden"),w(m())},u=function(a){q(),s();var b=n();b.find("input").val(""),b.removeClass("hidden"),b.find(j.CARTRIDGE_REGISTRATION_FORM).attr("data-cartridge-url",a),w(b)},v=function(){q(),r(),o().removeClass("hidden"),w(o())},w=function(a){var b=a.children().detach();b.appendTo(a)},x=function(){l().addClass("hidden")},y=function(){l().removeClass("hidden")},z=function(a){var b=a.error?"error":"success";c.addNotification({message:a.message,type:b})},A=function(a){a.addClass("loading")},B=function(a){a.removeClass("loading")},C=function(){var b=a.Deferred(),e=l();A(e),a.when(g.query(),h.query({orphanedonly:!0})).done(function(a,c){d.render("mod_lti/tool_list",{tools:a,proxies:c}).done(function(a,c){e.empty(),e.append(a),d.runTemplateJS(c),b.resolve()}).fail(b.reject)}).fail(b.reject),b.fail(c.exception).always(function(){B(e)})},D=function(){var b=a.trim(p());if(""===b)return a.Deferred().resolve();var d=k();A(d);var f=g.isCartridge(b);return f.always(function(){B(d)}),f.done(function(c){c.iscartridge?(a(j.TOOL_URL).val(""),a(document).trigger(e.START_CARTRIDGE_REGISTRATION,b)):a(document).trigger(e.START_EXTERNAL_REGISTRATION,{url:b})}),f.fail(function(){i.get_string("errorbadurl","mod_lti").done(function(b){a(document).trigger(e.REGISTRATION_FEEDBACK,{message:b,error:!0})}).fail(c.exception)}),f},E=function(){a(document).on(e.NEW_TOOL_TYPE,function(){C()}),a(document).on(e.START_EXTERNAL_REGISTRATION,function(){t(),a(j.TOOL_URL).val(""),x()}),a(document).on(e.STOP_EXTERNAL_REGISTRATION,function(){y(),v()}),a(document).on(e.START_CARTRIDGE_REGISTRATION,function(a,b){u(b)}),a(document).on(e.STOP_CARTRIDGE_REGISTRATION,function(){n().find(j.CARTRIDGE_REGISTRATION_FORM).removeAttr("data-cartridge-url"),v()}),a(document).on(e.REGISTRATION_FEEDBACK,function(a,b){z(b)});var b=a(j.ADD_TOOL_FORM);b.submit(function(a){a.preventDefault(),D()})};return{init:function(){E(),C()}}}); \ No newline at end of file diff --git a/mod/lti/amd/src/tool_configure_controller.js b/mod/lti/amd/src/tool_configure_controller.js index a8fed075de291..40dc88589eba2 100644 --- a/mod/lti/amd/src/tool_configure_controller.js +++ b/mod/lti/amd/src/tool_configure_controller.js @@ -162,9 +162,12 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e var showCartridgeRegistration = function(url) { hideExternalRegistration(); hideRegistrationChoices(); - getCartridgeRegistrationContainer().removeClass('hidden'); - getCartridgeRegistrationContainer().find(SELECTORS.CARTRIDGE_REGISTRATION_FORM).attr('data-cartridge-url', url); - screenReaderAnnounce(getCartridgeRegistrationContainer()); + // Don't save the key and secret from the last tool. + var container = getCartridgeRegistrationContainer(); + container.find('input').val(''); + container.removeClass('hidden'); + container.find(SELECTORS.CARTRIDGE_REGISTRATION_FORM).attr('data-cartridge-url', url); + screenReaderAnnounce(container); }; /** From a024a024e80663b5a00af55c492907f88319306d Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Wed, 29 May 2019 10:28:03 +0200 Subject: [PATCH 055/786] MDL-65726 core_roles: allow to create roles in install.php --- enrol/self/tests/self_test.php | 4 ++-- lib/tests/accesslib_test.php | 22 +++++++++------------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/enrol/self/tests/self_test.php b/enrol/self/tests/self_test.php index 0a6fcffe03483..7c701ed08d06b 100644 --- a/enrol/self/tests/self_test.php +++ b/enrol/self/tests/self_test.php @@ -669,7 +669,7 @@ public function test_get_welcome_email_contact() { $context = context_course::instance($course1->id); // Get editing teacher role. - $editingteacherrole = $DB->get_record('role', ['archetype' => 'editingteacher']); + $editingteacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']); $this->assertNotEmpty($editingteacherrole); // Enable self enrolment plugin and set to send email from course contact. @@ -700,7 +700,7 @@ public function test_get_welcome_email_contact() { $this->assertEquals($user1->email, $contact->email); // Get manager role, and enrol user as manager. - $managerrole = $DB->get_record('role', ['archetype' => 'manager']); + $managerrole = $DB->get_record('role', ['shortname' => 'manager']); $this->assertNotEmpty($managerrole); $instance1->customint4 = ENROL_SEND_EMAIL_FROM_KEY_HOLDER; $DB->update_record('enrol', $instance1); diff --git a/lib/tests/accesslib_test.php b/lib/tests/accesslib_test.php index 0136b40db4bca..e6834a491b630 100644 --- a/lib/tests/accesslib_test.php +++ b/lib/tests/accesslib_test.php @@ -340,7 +340,9 @@ public function test_has_coursecontact_role() { $user = $this->getDataGenerator()->create_user(); $course = $this->getDataGenerator()->create_course(); - role_assign($CFG->coursecontact, $user->id, context_course::instance($course->id)); + $contactroles = preg_split('/,/', $CFG->coursecontact); + $roleid = reset($contactroles); + role_assign($roleid, $user->id, context_course::instance($course->id)); $this->assertTrue(has_coursecontact_role($user->id)); } @@ -800,7 +802,7 @@ public function test_get_archetype_roles() { create_role('New student role', 'student2', 'New student description', 'student'); $roles = get_archetype_roles('student'); - $this->assertCount(2, $roles); + $this->assertGreaterThanOrEqual(2, count($roles)); } /** @@ -1508,14 +1510,8 @@ public function test_get_default_enrol_roles() { $allroles = get_all_roles(); $expected = array($id2=>$allroles[$id2]); - foreach (get_role_archetypes() as $archetype) { - $defaults = get_default_contextlevels($archetype); - if (in_array(CONTEXT_COURSE, $defaults)) { - $roles = get_archetype_roles($archetype); - foreach ($roles as $role) { - $expected[$role->id] = $role; - } - } + foreach (get_roles_for_contextlevels(CONTEXT_COURSE) as $roleid) { + $expected[$roleid] = $roleid; } $roles = get_default_enrol_roles($coursecontext); @@ -2694,7 +2690,7 @@ public function test_permission_evaluation() { $testcourses = array(); $testpages = array(); $testblocks = array(); - $allroles = $DB->get_records_menu('role', array(), 'id', 'archetype, id'); + $allroles = $DB->get_records_menu('role', array(), 'id', 'shortname, id'); $systemcontext = context_system::instance(); $frontpagecontext = context_course::instance(SITEID); @@ -3616,8 +3612,8 @@ public function test_update_capabilities() { $this->resetAfterTest(true); $froncontext = context_course::instance($SITE->id); - $student = $DB->get_record('role', array('archetype'=>'student')); - $teacher = $DB->get_record('role', array('archetype'=>'teacher')); + $student = $DB->get_record('role', array('shortname'=>'student')); + $teacher = $DB->get_record('role', array('shortname'=>'teacher')); $existingcaps = $DB->get_records('capabilities', array(), 'id', 'name, captype, contextlevel, component, riskbitmask'); From ec60f63f59eb5243a2a75f22bf184fd7e343b6e1 Mon Sep 17 00:00:00 2001 From: Kathrin Osswald Date: Thu, 23 May 2019 15:01:10 +0200 Subject: [PATCH 056/786] MDL-63240 theme Boost: Removed z-indexes for border styling in navdrawer --- theme/boost/scss/moodle/drawer.scss | 11 +++++++++++ theme/boost/style/moodle.css | 10 +++++++++- theme/classic/style/moodle.css | 10 +++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/theme/boost/scss/moodle/drawer.scss b/theme/boost/scss/moodle/drawer.scss index 90030e216ad6c..88a924dadf5b1 100644 --- a/theme/boost/scss/moodle/drawer.scss +++ b/theme/boost/scss/moodle/drawer.scss @@ -47,6 +47,17 @@ $drawer-bg: $gray-lighter !default; #nav-drawer { right: auto; left: 0; + + /* Override the z-indexes defined in bootstrap/_list-group.scss that + lead to side effects on the user tours positioning. */ + .list-group-item-action.active, + .list-group-item.active { + z-index: inherit; + } + .list-group-item-action.active + .list-group-item, + .list-group-item.active + .list-group-item { + border-top: none; + } } #page { margin-top: $fixed-header-y; diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css index 9d351158aa3b3..3cc2e83466ec3 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -12602,7 +12602,15 @@ span.editinstructions { #nav-drawer { right: auto; - left: 0; } + left: 0; + /* Override the z-indexes defined in bootstrap/_list-group.scss that + lead to side effects on the user tours positioning. */ } + #nav-drawer .list-group-item-action.active, + #nav-drawer .list-group-item.active { + z-index: inherit; } + #nav-drawer .list-group-item-action.active + .list-group-item, + #nav-drawer .list-group-item.active + .list-group-item { + border-top: none; } #page { margin-top: 50px; } diff --git a/theme/classic/style/moodle.css b/theme/classic/style/moodle.css index c28589ff5c3e4..8fc9102ad82cd 100644 --- a/theme/classic/style/moodle.css +++ b/theme/classic/style/moodle.css @@ -12849,7 +12849,15 @@ span.editinstructions { #nav-drawer { right: auto; - left: 0; } + left: 0; + /* Override the z-indexes defined in bootstrap/_list-group.scss that + lead to side effects on the user tours positioning. */ } + #nav-drawer .list-group-item-action.active, + #nav-drawer .list-group-item.active { + z-index: inherit; } + #nav-drawer .list-group-item-action.active + .list-group-item, + #nav-drawer .list-group-item.active + .list-group-item { + border-top: none; } #page { margin-top: 50px; } From 15d5c9a276b42c8a9f5e265cef7ab33ad0875bb4 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 29 May 2019 13:38:41 +0100 Subject: [PATCH 057/786] MDL-65731 quiz manual grading: fix ambiguous order by idnumber --- mod/quiz/report/grading/report.php | 3 +++ mod/quiz/report/grading/tests/behat/grading.feature | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/mod/quiz/report/grading/report.php b/mod/quiz/report/grading/report.php index c4e843fb7cf6a..39c0c407d77e8 100644 --- a/mod/quiz/report/grading/report.php +++ b/mod/quiz/report/grading/report.php @@ -551,6 +551,9 @@ protected function get_usage_ids_where_question_in_state($summarystate, $slot, case "studentfirstname": $orderby = "u.firstname, u.lastname"; break; + case "idnumber": + $orderby = "u.idnumber"; + break; } } diff --git a/mod/quiz/report/grading/tests/behat/grading.feature b/mod/quiz/report/grading/tests/behat/grading.feature index 840902b045ff8..e2d793bdfe4a7 100644 --- a/mod/quiz/report/grading/tests/behat/grading.feature +++ b/mod/quiz/report/grading/tests/behat/grading.feature @@ -1,4 +1,4 @@ -@mod @mod_quiz +@mod @mod_quiz @quiz @quiz_grading Feature: Basic use of the Manual grading report In order to easily find students attempts that need manual grading As a teacher @@ -50,8 +50,15 @@ Feature: Basic use of the Manual grading report And "Short answer 001" row "To grade" column of "questionstograde" table should contain "0" And "Short answer 001" row "Already graded" column of "questionstograde" table should contain "0" - # Adjust the mark for Student1. + # Go to the grading page. And I click on "update grades" "link" in the "Short answer 001" "table_row" + And I should see "Grading attempts 1 to 1 of 1" + + # Test the display options. + And I set the field "Order attempts" to "By student id number" + And I press "Change options" + + # Adjust the mark for Student1. And I set the field "Comment" to "I have adjusted your mark to 0.6" And I set the field "Mark" to "0.6" And I press "Save and go to next page" From 794391b978ca40f6efbf0f59864595d09cf810f2 Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Thu, 30 May 2019 12:18:38 +0200 Subject: [PATCH 058/786] weekly release 3.7+ --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 627291ee3e3e0..e9dbb71262a0e 100644 --- a/version.php +++ b/version.php @@ -29,11 +29,11 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2019052000.01; // 20190520 = branching date YYYYMMDD - do not modify! +$version = 2019052000.02; // 20190520 = branching date YYYYMMDD - do not modify! // RR = release increments - 00 in DEV branches. // .XX = incremental changes. -$release = '3.7+ (Build: 20190524)'; // Human-friendly version name +$release = '3.7+ (Build: 20190530)'; // Human-friendly version name $branch = '37'; // This version's branch. $maturity = MATURITY_STABLE; // This version's maturity level. From c9be953f05f0aacd3726282912560f4bef2a1f89 Mon Sep 17 00:00:00 2001 From: Matteo Scaramuccia Date: Sat, 25 May 2019 21:22:26 +0200 Subject: [PATCH 059/786] MDL-65686 setuplib: Fix missing round brackets --- lib/filelib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/filelib.php b/lib/filelib.php index 16d17fb220f09..6512933e3ef5c 100644 --- a/lib/filelib.php +++ b/lib/filelib.php @@ -4237,7 +4237,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null, $offlin } else if ($filearea == GRADE_FEEDBACK_FILEAREA || $filearea == GRADE_HISTORY_FEEDBACK_FILEAREA) { if ($context->contextlevel != CONTEXT_MODULE) { - send_file_not_found; + send_file_not_found(); } require_login($course, false); From 57b83a4f41eae1d9155a0a88f2f5ef1a459c3a6d Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Mon, 6 May 2019 01:57:01 +0200 Subject: [PATCH 060/786] MDL-64794 tcpdf: Bump to tcpdf 6.2.26 --- lib/tcpdf/CHANGELOG.TXT | 15 ++ lib/tcpdf/README.md | 84 ++++++++ lib/tcpdf/composer.json | 80 +++---- lib/tcpdf/include/barcodes/pdf417.php | 20 +- lib/tcpdf/include/sRGB.icc | Bin 3048 -> 6922 bytes lib/tcpdf/include/tcpdf_fonts.php | 18 +- lib/tcpdf/include/tcpdf_images.php | 8 +- lib/tcpdf/include/tcpdf_static.php | 86 ++++---- lib/tcpdf/readme_moodle.txt | 19 +- lib/tcpdf/tcpdf.php | 287 ++++++++++++++------------ lib/thirdpartylibs.xml | 2 +- 11 files changed, 387 insertions(+), 232 deletions(-) create mode 100644 lib/tcpdf/README.md diff --git a/lib/tcpdf/CHANGELOG.TXT b/lib/tcpdf/CHANGELOG.TXT index 64c3d47adcc9a..3bdae3e2450c6 100644 --- a/lib/tcpdf/CHANGELOG.TXT +++ b/lib/tcpdf/CHANGELOG.TXT @@ -1,3 +1,18 @@ +6.2.25 + - Fix support for image URLs. + +6.2.24 + - Support remote urls when checking if file exists. + +6.2.23 + - Simplify file_exists function. + +6.2.22 + - Fix for security vulnerability: Using the phar:// wrapper it was possible to trigger the unserialization of user provided data. + +6.2.19 + - Merge various fixes for PHP 7.3 compatibility and security. + 6.2.13 (2016-06-10) - IMPORTANT: A new version of this library is under development at https://github.com/tecnickcom/tc-lib-pdf and as a consequence this version will not receive any additional development or support. This version should be considered obsolete, new projects should use the new version as soon it will become stable. diff --git a/lib/tcpdf/README.md b/lib/tcpdf/README.md new file mode 100644 index 0000000000000..baa518137cb47 --- /dev/null +++ b/lib/tcpdf/README.md @@ -0,0 +1,84 @@ +# TCPDF +*PHP PDF Library* + +[![Donate via PayPal](https://img.shields.io/badge/donate-paypal-87ceeb.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations¤cy_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20TCPDF%20project) +*Please consider supporting this project by making a donation via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations¤cy_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20TCPDF%20project)* + +* **category** Library +* **author** Nicola Asuni +* **copyright** 2002-2018 Nicola Asuni - Tecnick.com LTD +* **license** http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT) +* **link** http://www.tcpdf.org +* **source** https://github.com/tecnickcom/TCPDF + + +## IMPORTANT +A new version of this library is under development at https://github.com/tecnickcom/tc-lib-pdf and as a consequence this version will not receive any additional development or support. +This version should be considered obsolete, new projects should use the new version as soon it will become stable. + + + +## Description + +PHP library for generating PDF documents on-the-fly. + +### Main Features: +* no external libraries are required for the basic functions; +* all standard page formats, custom page formats, custom margins and units of measure; +* UTF-8 Unicode and Right-To-Left languages; +* TrueTypeUnicode, OpenTypeUnicode v1, TrueType, OpenType v1, Type1 and CID-0 fonts; +* font subsetting; +* methods to publish some XHTML + CSS code, Javascript and Forms; +* images, graphic (geometric figures) and transformation methods; +* supports JPEG, PNG and SVG images natively, all images supported by GD (GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM) and all images supported via ImagMagick (http://www.imagemagick.org/script/formats.php) +* 1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extension, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC (Royal Mail 4-state Customer Code), CBC (Customer Bar Code), KIX (Klant index - Customer index), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, Datamatrix, QR-Code, PDF417; +* JPEG and PNG ICC profiles, Grayscale, RGB, CMYK, Spot Colors and Transparencies; +* automatic page header and footer management; +* document encryption up to 256 bit and digital signature certifications; +* transactions to UNDO commands; +* PDF annotations, including links, text and file attachments; +* text rendering modes (fill, stroke and clipping); +* multiple columns mode; +* no-write page regions; +* bookmarks, named destinations and table of content; +* text hyphenation; +* text stretching and spacing (tracking); +* automatic page break, line break and text alignments including justification; +* automatic page numbering and page groups; +* move and delete pages; +* page compression (requires php-zlib extension); +* XOBject Templates; +* Layers and object visibility. +* PDF/A-1b support. + +### Third party fonts: + +This library may include third party font files released with different licenses. + +All the PHP files on the fonts directory are subject to the general TCPDF license (GNU-LGPLv3), +they do not contain any binary data but just a description of the general properties of a particular font. +These files can be also generated on the fly using the font utilities and TCPDF methods. + +All the original binary TTF font files have been renamed for compatibility with TCPDF and compressed using the gzcompress PHP function that uses the ZLIB data format (.z files). + +The binary files (.z) that begins with the prefix "free" have been extracted from the GNU FreeFont collection (GNU-GPLv3). +The binary files (.z) that begins with the prefix "pdfa" have been derived from the GNU FreeFont, so they are subject to the same license. +For the details of Copyright, License and other information, please check the files inside the directory fonts/freefont-20120503 +Link : http://www.gnu.org/software/freefont/ + +The binary files (.z) that begins with the prefix "dejavu" have been extracted from the DejaVu fonts 2.33 (Bitstream) collection. +For the details of Copyright, License and other information, please check the files inside the directory fonts/dejavu-fonts-ttf-2.33 +Link : http://dejavu-fonts.org + +The binary files (.z) that begins with the prefix "ae" have been extracted from the Arabeyes.org collection (GNU-GPLv2). +Link : http://projects.arabeyes.org/ + +### ICC profile: + +TCPDF includes the sRGB.icc profile from the icc-profiles-free Debian package: +https://packages.debian.org/source/stable/icc-profiles-free + + +## Developer(s) Contact + +* Nicola Asuni diff --git a/lib/tcpdf/composer.json b/lib/tcpdf/composer.json index 578649e546f02..1ffb6a6af7abd 100644 --- a/lib/tcpdf/composer.json +++ b/lib/tcpdf/composer.json @@ -1,38 +1,46 @@ { - "name": "tecnickcom/tcpdf", - "version": "6.2.13", - "homepage": "http://www.tcpdf.org/", - "type": "library", - "description": "TCPDF is a PHP class for generating PDF documents and barcodes.", - "keywords": ["PDF","tcpdf","PDFD32000-2008","qrcode","datamatrix","pdf417","barcodes"], - "license": "LGPLv3", - "authors": [ - { - "name": "Nicola Asuni", - "email": "info@tecnick.com", - "homepage": "http://nicolaasuni.tecnick.com" - } - ], - "require": { - "php": ">=5.3.0" - }, - "autoload": { - "classmap": [ - "config", - "include", - "tcpdf.php", - "tcpdf_parser.php", - "tcpdf_barcodes_1d.php", - "tcpdf_barcodes_2d.php", - "include/tcpdf_colors.php", - "include/tcpdf_filters.php", - "include/tcpdf_font_data.php", - "include/tcpdf_fonts.php", - "include/tcpdf_images.php", - "include/tcpdf_static.php", - "include/barcodes/datamatrix.php", - "include/barcodes/pdf417.php", - "include/barcodes/qrcode.php" - ] - } + "name": "tecnickcom/tcpdf", + "version": "6.2.26", + "homepage": "http://www.tcpdf.org/", + "type": "library", + "description": "TCPDF is a PHP class for generating PDF documents and barcodes.", + "keywords": [ + "PDF", + "tcpdf", + "PDFD32000-2008", + "qrcode", + "datamatrix", + "pdf417", + "barcodes" + ], + "license": "LGPL-3.0", + "authors": [ + { + "name": "Nicola Asuni", + "email": "info@tecnick.com", + "role": "lead" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "classmap": [ + "config", + "include", + "tcpdf.php", + "tcpdf_parser.php", + "tcpdf_barcodes_1d.php", + "tcpdf_barcodes_2d.php", + "include/tcpdf_colors.php", + "include/tcpdf_filters.php", + "include/tcpdf_font_data.php", + "include/tcpdf_fonts.php", + "include/tcpdf_images.php", + "include/tcpdf_static.php", + "include/barcodes/datamatrix.php", + "include/barcodes/pdf417.php", + "include/barcodes/qrcode.php" + ] + } } diff --git a/lib/tcpdf/include/barcodes/pdf417.php b/lib/tcpdf/include/barcodes/pdf417.php index 4fbe6522c9231..3b1774eaae46d 100644 --- a/lib/tcpdf/include/barcodes/pdf417.php +++ b/lib/tcpdf/include/barcodes/pdf417.php @@ -740,16 +740,6 @@ public function getBarcodeArray() { * @protected */ protected function getErrorCorrectionLevel($ecl, $numcw) { - // get maximum correction level - $maxecl = 8; // starting error level - $maxerrsize = (928 - $numcw); // available codewords for error - while ($maxecl > 0) { - $errsize = (2 << $ecl); - if ($maxerrsize >= $errsize) { - break; - } - --$maxecl; - } // check for automatic levels if (($ecl < 0) OR ($ecl > 8)) { if ($numcw < 41) { @@ -764,6 +754,16 @@ protected function getErrorCorrectionLevel($ecl, $numcw) { $ecl = $maxecl; } } + // get maximum correction level + $maxecl = 8; // starting error level + $maxerrsize = (928 - $numcw); // available codewords for error + while ($maxecl > 0) { + $errsize = (2 << $ecl); + if ($maxerrsize >= $errsize) { + break; + } + --$maxecl; + } if ($ecl > $maxecl) { $ecl = $maxecl; } diff --git a/lib/tcpdf/include/sRGB.icc b/lib/tcpdf/include/sRGB.icc index 71e33830223c4c05c61002462e13df02bb30ae02..1d8f7419c3bf2c6a3dd78f2c679fdefbda1776a3 100644 GIT binary patch delta 484 zcmZ{gKS;ws6vn@6QEP};N>QoH3B}2xleoAj)J0Kh2Njn#xu!~!#!JK&2MccEP^g0n zf*@{gf;x$VtCK}H=T0tyv+t6jI(Wm~kMDi={&j|rrt`q4RxxZZG6mRYs z9mRXT>jRM$;-sXq#1uoa7;;Uq74mW5$>-+Da|y(BD`4$LaWUY;gJPpBZ6K3+rVnYu zl~f?5ij9R$5CL)3CbxtmWWg6Er;e8sz%NISN1IS`tHJu?{{>o4Ov`@F2E((VQ?uJ$AL?HE`bqMm}!aOpkT1Y&ZsGi>i!Q??8SZSbPD_&Vlg~ f<=XT`jiv*fDmSWbU2a)re}eCNf|sNal{&N^xK(OJ delta 691 zcmYjPJ!lj`6n?vhB<`Ik_!Gh6rZ~h%R+0;xUSX3vk#xrz#n{d6&h0JPKXzwL0)mB# zVq=c8v5R7@g`$l`O0ls}1bDwJ&&3yP672rct}MS0#z75ecj)CVUg| zX=}idQ+2Yg?B^LLDJsK*;sHbXLV-sLM8ohY? zY*VdGw#O_^p_-NQuITgBlZ<>jp%!GyajOd6Ws{ak*{9y zD`t^nWyq&|wIo%J095AjQXiMG@Dae7-x%LWT!)dYV=S?;0(C?5MJxiW;gTy>-N3=Z z0^5~t7%(@W?#ueI;~sS!ln+6QH5?<_hS7TLIs?fT11aKwlL7bgE@QGx!dSYgKf{`{ pvu%K+Ki?!BD77xYo^M(9>o~x~eSn>NS@!>7mhE8amCpcM=`QZps%!uN diff --git a/lib/tcpdf/include/tcpdf_fonts.php b/lib/tcpdf/include/tcpdf_fonts.php index 70ca89393d926..9242ca4bfdb52 100644 --- a/lib/tcpdf/include/tcpdf_fonts.php +++ b/lib/tcpdf/include/tcpdf_fonts.php @@ -70,7 +70,7 @@ class TCPDF_FONTS { * @public static */ public static function addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $outpath='', $platid=3, $encid=1, $addcbbox=false, $link=false) { - if (!file_exists($fontfile)) { + if (!TCPDF_STATIC::file_exists($fontfile)) { // Could not find file return false; } @@ -95,7 +95,7 @@ public static function addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $ $outpath = self::_getfontpath(); } // check if this font already exist - if (@file_exists($outpath.$font_name.'.php')) { + if (@TCPDF_STATIC::file_exists($outpath.$font_name.'.php')) { // this font already exist (delete it from fonts folder to rebuild it) return $font_name; } @@ -665,7 +665,7 @@ public static function addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $ $glyphIdArray[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } - for ($k = 0; $k < $segCount; ++$k) { + for ($k = 0; $k < $segCount - 1; ++$k) { for ($c = $startCount[$k]; $c <= $endCount[$k]; ++$c) { if ($idRangeOffset[$k] == 0) { $g = ($idDelta[$k] + $c) % 65536; @@ -1543,11 +1543,11 @@ public static function _getfontpath() { public static function getFontFullPath($file, $fontdir=false) { $fontfile = ''; // search files on various directories - if (($fontdir !== false) AND @file_exists($fontdir.$file)) { + if (($fontdir !== false) AND @TCPDF_STATIC::file_exists($fontdir.$file)) { $fontfile = $fontdir.$file; - } elseif (@file_exists(self::_getfontpath().$file)) { + } elseif (@TCPDF_STATIC::file_exists(self::_getfontpath().$file)) { $fontfile = self::_getfontpath().$file; - } elseif (@file_exists($file)) { + } elseif (@TCPDF_STATIC::file_exists($file)) { $fontfile = $file; } return $fontfile; @@ -2003,7 +2003,11 @@ public static function UTF8StringToArray($str, $isunicode=true, &$currentfont) { $chars = str_split($str); $carr = array_map('ord', $chars); } - $currentfont['subsetchars'] += array_fill_keys($carr, true); + if (is_array($currentfont['subsetchars']) && is_array($carr)) { + $currentfont['subsetchars'] += array_fill_keys($carr, true); + } else { + $currentfont['subsetchars'] = array_merge($currentfont['subsetchars'], $carr); + } return $carr; } diff --git a/lib/tcpdf/include/tcpdf_images.php b/lib/tcpdf/include/tcpdf_images.php index c2e3c36f93058..86b3c20dbd8b5 100644 --- a/lib/tcpdf/include/tcpdf_images.php +++ b/lib/tcpdf/include/tcpdf_images.php @@ -161,12 +161,8 @@ public static function _toJPEG($image, $quality, $tempfile) { */ public static function _parsejpeg($file) { // check if is a local file - if (!@file_exists($file)) { - // try to encode spaces on filename - $tfile = str_replace(' ', '%20', $file); - if (@file_exists($tfile)) { - $file = $tfile; - } + if (!@TCPDF_STATIC::file_exists($file)) { + return false; } $a = getimagesize($file); if (empty($a)) { diff --git a/lib/tcpdf/include/tcpdf_static.php b/lib/tcpdf/include/tcpdf_static.php index 16353e0068509..df1b28e1ef874 100644 --- a/lib/tcpdf/include/tcpdf_static.php +++ b/lib/tcpdf/include/tcpdf_static.php @@ -55,7 +55,7 @@ class TCPDF_STATIC { * Current TCPDF version. * @private static */ - private static $tcpdf_version = '6.2.13'; + private static $tcpdf_version = '6.2.26'; /** * String alias for total number of pages. @@ -1774,39 +1774,6 @@ public static function getVectorsAngle($x1, $y1, $x2, $y2) { return $angle; } - - - - - - - - - - - - - - - - -// ==================================================================================================================== -// REIMPLEMENTED -// ==================================================================================================================== - - - - - - - - - - - - - - /** * Split string by a regular expression. * This is a wrapper for the preg_split function to avoid the bug: https://bugs.php.net/bug.php?id=45850 @@ -1854,6 +1821,49 @@ public static function fopenLocal($filename, $mode) { return fopen($filename, $mode); } + /** + * Check if the URL exist. + * @param url (string) URL to check. + * @return Returns TRUE if the URL exists; FALSE otherwise. + * @public static + */ + public static function url_exists($url) { + $crs = curl_init(); + curl_setopt($crs, CURLOPT_URL, $url); + curl_setopt($crs, CURLOPT_NOBODY, true); + curl_setopt($crs, CURLOPT_FAILONERROR, true); + if ((ini_get('open_basedir') == '') && (!ini_get('safe_mode'))) { + curl_setopt($crs, CURLOPT_FOLLOWLOCATION, true); + } + curl_setopt($crs, CURLOPT_CONNECTTIMEOUT, 5); + curl_setopt($crs, CURLOPT_TIMEOUT, 30); + curl_setopt($crs, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($crs, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($crs, CURLOPT_USERAGENT, 'tc-lib-file'); + curl_exec($crs); + $code = curl_getinfo($crs, CURLINFO_HTTP_CODE); + curl_close($crs); + return ($code == 200); + } + + /** + * Wrapper for file_exists. + * Checks whether a file or directory exists. + * Only allows some protocols and local files. + * @param filename (string) Path to the file or directory. + * @return Returns TRUE if the file or directory specified by filename exists; FALSE otherwise. + * @public static + */ + public static function file_exists($filename) { + if (preg_match('|^https?://|', $filename) == 1) { + return self::url_exists($filename); + } + if (strpos($filename, '://')) { + return false; // only support http and https wrappers for security reasons + } + return @file_exists($filename); + } + /** * Reads entire file into a string. * The file can be also an URL. @@ -1910,12 +1920,14 @@ public static function fileGetContents($file) { && !preg_match('%^//%', $file) ) { $urldata = @parse_url($_SERVER['SCRIPT_URI']); - return $urldata['scheme'].'://'.$urldata['host'].(($file[0] == '/') ? '' : '/').$file; + $alt[] = $urldata['scheme'].'://'.$urldata['host'].(($file[0] == '/') ? '' : '/').$file; } // $alt = array_unique($alt); - //var_dump($alt);exit;//DEBUG foreach ($alt as $path) { + if (!self::file_exists($path)) { + return false; + } $ret = @file_get_contents($path); if ($ret !== false) { return $ret; @@ -1949,8 +1961,6 @@ public static function fileGetContents($file) { return false; } - - /** * Get ULONG from string (Big Endian 32-bit unsigned integer). * @param $str (string) string from where to extract value diff --git a/lib/tcpdf/readme_moodle.txt b/lib/tcpdf/readme_moodle.txt index 6c124ac19e4a8..f3ea107f06ff1 100644 --- a/lib/tcpdf/readme_moodle.txt +++ b/lib/tcpdf/readme_moodle.txt @@ -1,12 +1,23 @@ -Description of TCPDF library import 6.2.13 -=========================================== +Description of TCPDF library import 6.2.26 +========================================== * download library from https://github.com/tecnickcom/TCPDF/releases * delete examples/, tools/ and tcpdf_import.php * remove tcpdf_import.php from composer.json * remove all fonts that were not already present * visit http://127.0.0.1/lib/tests/other/pdflibtestpage.php and view the pdf -* check the status of https://github.com/tecnickcom/TCPDF/pull/74 and re-apply if not merged/closed (6.2.16 and up should contain it). -* verify that https://github.com/tecnickcom/TCPDF/pull/91 is included in the imported library (6.2.25 and up should contain it). + +Important +--------- +A new version of the libray is being developed @ https://github.com/tecnickcom/tc-lib-pdf . Check periodically when it's ready +and if it's a drop-in replacement for the legacy tcpdf one. + +2019/05/06 +---------- +Upgrade to tcpdf TCPDF 6.2.26 (MDL-64794) +by Eloy Lafuente + +- https://github.com/tecnickcom/TCPDF/pull/74 has been already merged upstream (6.2.16 and up), so we don't need to apply it. +- https://github.com/tecnickcom/TCPDF/pull/91 has been already merged upstream (6.2.19 and up), so we don't need to apply it. 2017/10/02 ---------- diff --git a/lib/tcpdf/tcpdf.php b/lib/tcpdf/tcpdf.php index 23025a0c7af3c..24ef434ab8a58 100644 --- a/lib/tcpdf/tcpdf.php +++ b/lib/tcpdf/tcpdf.php @@ -1,13 +1,13 @@ * @package com.tecnick.tcpdf * @author Nicola Asuni - * @version 6.2.8 + * @version 6.2.26 */ // TCPDF configuration @@ -128,8 +128,11 @@ * TCPDF project (http://www.tcpdf.org) has been originally derived in 2002 from the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org), but now is almost entirely rewritten.
* @package com.tecnick.tcpdf * @brief PHP class for generating PDF documents without requiring external extensions. - * @version 6.2.8 + * @version 6.2.26 * @author Nicola Asuni - info@tecnick.com + * @IgnoreAnnotation("protected") + * @IgnoreAnnotation("public") + * @IgnoreAnnotation("pre") */ class TCPDF { @@ -1994,10 +1997,6 @@ public function __construct($orientation='P', $unit='mm', $format='A4', $unicode * @since 1.53.0.TC016 */ public function __destruct() { - // restore internal encoding - if (isset($this->internal_encoding) AND !empty($this->internal_encoding)) { - mb_internal_encoding($this->internal_encoding); - } // cleanup $this->_destroy(true); } @@ -4257,7 +4256,7 @@ public function AddFont($family, $style='', $fontfile='', $subset='default') { // true when the font style variation is missing $missing_style = false; // search and include font file - if (TCPDF_STATIC::empty_string($fontfile) OR (!@file_exists($fontfile))) { + if (TCPDF_STATIC::empty_string($fontfile) OR (!@TCPDF_STATIC::file_exists($fontfile))) { // build a standard filenames for specified font $tmp_fontfile = str_replace(' ', '', $family).strtolower($style).'.php'; $fontfile = TCPDF_FONTS::getFontFullPath($tmp_fontfile, $fontdir); @@ -4269,7 +4268,7 @@ public function AddFont($family, $style='', $fontfile='', $subset='default') { } } // include font file - if (!TCPDF_STATIC::empty_string($fontfile) AND (@file_exists($fontfile))) { + if (!TCPDF_STATIC::empty_string($fontfile) AND (@TCPDF_STATIC::file_exists($fontfile))) { include($fontfile); } else { $this->Error('Could not include font definition file: '.$family.''); @@ -4453,6 +4452,7 @@ public function SetFont($family, $style='', $size=null, $fontfile='', $subset='d * @see SetFont() */ public function SetFontSize($size, $out=true) { + $size = (float)$size; // font size in points $this->FontSizePt = $size; // font size in user units @@ -4809,19 +4809,19 @@ public function Annotation($x, $y, $w, $h, $text, $opt=array('Subtype'=>'Text'), $this->PageAnnots[$page][] = array('n' => ++$this->n, 'x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'txt' => $text, 'opt' => $opt, 'numspaces' => $spaces); if (!$this->pdfa_mode) { if ((($opt['Subtype'] == 'FileAttachment') OR ($opt['Subtype'] == 'Sound')) AND (!TCPDF_STATIC::empty_string($opt['FS'])) - AND (@file_exists($opt['FS']) OR TCPDF_STATIC::isValidURL($opt['FS'])) + AND (@TCPDF_STATIC::file_exists($opt['FS']) OR TCPDF_STATIC::isValidURL($opt['FS'])) AND (!isset($this->embeddedfiles[basename($opt['FS'])]))) { $this->embeddedfiles[basename($opt['FS'])] = array('f' => ++$this->n, 'n' => ++$this->n, 'file' => $opt['FS']); } } // Add widgets annotation's icons - if (isset($opt['mk']['i']) AND @file_exists($opt['mk']['i'])) { + if (isset($opt['mk']['i']) AND @TCPDF_STATIC::file_exists($opt['mk']['i'])) { $this->Image($opt['mk']['i'], '', '', 10, 10, '', '', '', false, 300, '', false, false, 0, false, true); } - if (isset($opt['mk']['ri']) AND @file_exists($opt['mk']['ri'])) { + if (isset($opt['mk']['ri']) AND @TCPDF_STATIC::file_exists($opt['mk']['ri'])) { $this->Image($opt['mk']['ri'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true); } - if (isset($opt['mk']['ix']) AND @file_exists($opt['mk']['ix'])) { + if (isset($opt['mk']['ix']) AND @TCPDF_STATIC::file_exists($opt['mk']['ix'])) { $this->Image($opt['mk']['ix'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true); } } @@ -5769,10 +5769,9 @@ public function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false, $ln= $this->resetLastH(); } if (!TCPDF_STATIC::empty_string($y)) { - $this->SetY($y); - } else { - $y = $this->GetY(); + $this->SetY($y); // set y in order to convert negative y values to positive ones } + $y = $this->GetY(); $resth = 0; if (($h > 0) AND $this->inPageBody() AND (($y + $h + $mc_margin['T'] + $mc_margin['B']) > $this->PageBreakTrigger)) { // spit cell in more pages/columns @@ -6845,13 +6844,9 @@ public function Image($file, $x='', $y='', $w=0, $h=0, $type='', $link='', $alig $file = substr($file, 1); $exurl = $file; } - // check if is a local file - if (!@file_exists($file)) { - // try to encode spaces on filename - $tfile = str_replace(' ', '%20', $file); - if (@file_exists($tfile)) { - $file = $tfile; - } + // check if file exist and it is valid + if (!@TCPDF_STATIC::file_exists($file)) { + return false; } if (($imsize = @getimagesize($file)) === FALSE) { if (in_array($file, $this->imagekeys)) { @@ -7750,6 +7745,10 @@ public function Output($name='doc.pdf', $dest='I') { * @since 4.5.016 (2009-02-24) */ public function _destroy($destroyall=false, $preserve_objcopy=false) { + // restore internal encoding + if (isset($this->internal_encoding) AND !empty($this->internal_encoding)) { + mb_internal_encoding($this->internal_encoding); + } if ($destroyall AND !$preserve_objcopy) { // remove all temporary files $tmpfiles = glob(K_PATH_CACHE.'__tcpdf_'.$this->file_id.'_*'); @@ -8157,7 +8156,9 @@ protected function _putannotsobjs() { $annots .= ' /FT /'.$pl['opt']['ft']; $formfield = true; } - $annots .= ' /Contents '.$this->_textstring($pl['txt'], $annot_obj_id); + if ($pl['opt']['subtype'] !== 'Link') { + $annots .= ' /Contents '.$this->_textstring($pl['txt'], $annot_obj_id); + } $annots .= ' /P '.$this->page_obj_id[$n].' 0 R'; $annots .= ' /NM '.$this->_datastring(sprintf('%04u-%04u', $n, $key), $annot_obj_id); $annots .= ' /M '.$this->_datestring($annot_obj_id, $this->doc_modification_timestamp); @@ -9646,7 +9647,7 @@ protected function _putXMP() { protected function _putcatalog() { // put XMP $xmpobj = $this->_putXMP(); - // if required, add standard sRGB_IEC61966-2.1 blackscaled ICC colour profile + // if required, add standard sRGB ICC colour profile if ($this->pdfa_mode OR $this->force_srgb) { $iccobj = $this->_newobj(); $icc = file_get_contents(dirname(__FILE__).'/include/sRGB.icc'); @@ -12582,7 +12583,7 @@ protected function _addfield($type, $name, $x, $y, $w, $h, $prop) { $k = $this->k; $this->javascript .= sprintf("f".$name."=this.addField('%s','%s',%u,[%F,%F,%F,%F]);", $name, $type, $this->PageNo()-1, $x*$k, ($this->h-$y)*$k+1, ($x+$w)*$k, ($this->h-$y-$h)*$k+1)."\n"; $this->javascript .= 'f'.$name.'.textSize='.$this->FontSizePt.";\n"; - foreach ($prop as $key => $val) { + foreach($prop as $key => $val) { if (strcmp(substr($key, -5), 'Color') == 0) { $val = TCPDF_COLORS::_JScolor($val); } else { @@ -15190,7 +15191,7 @@ public function getBarcode() { * @since 3.1.000 (2008-06-09) * @public */ - public function write1DBarcode($code, $type, $x='', $y='', $w='', $h='', $xres='', $style='', $align='') { + public function write1DBarcode($code, $type, $x='', $y='', $w='', $h='', $xres='', $style=array(), $align='') { if (TCPDF_STATIC::empty_string(trim($code))) { return; } @@ -15509,7 +15510,7 @@ public function write1DBarcode($code, $type, $x='', $y='', $w='', $h='', $xres=' * @since 4.5.037 (2009-04-07) * @public */ - public function write2DBarcode($code, $type, $x='', $y='', $w='', $h='', $style='', $align='', $distort=false) { + public function write2DBarcode($code, $type, $x='', $y='', $w='', $h='', $style=array(), $align='', $distort=false) { if (TCPDF_STATIC::empty_string(trim($code))) { return; } @@ -16545,9 +16546,9 @@ protected function getHtmlDomArray($html) { // get attributes preg_match_all('/([^=\s]*)[\s]*=[\s]*"([^"]*)"/', $element, $attr_array, PREG_PATTERN_ORDER); $dom[$key]['attribute'] = array(); // reset attribute array - foreach ($attr_array[1] as $id => $name) { - $dom[$key]['attribute'][strtolower($name)] = $attr_array[2][$id]; - } + foreach($attr_array[1] as $id => $name) { + $dom[$key]['attribute'][strtolower($name)] = $attr_array[2][$id]; + } if (!empty($css)) { // merge CSS style to current style list($dom[$key]['csssel'], $dom[$key]['cssdata']) = TCPDF_STATIC::getCSSdataArray($dom, $key, $css); @@ -16558,10 +16559,10 @@ protected function getHtmlDomArray($html) { // get style attributes preg_match_all('/([^;:\s]*):([^;]*)/', $dom[$key]['attribute']['style'], $style_array, PREG_PATTERN_ORDER); $dom[$key]['style'] = array(); // reset style attribute array - foreach ($style_array[1] as $id => $name) { - // in case of duplicate attribute the last replace the previous - $dom[$key]['style'][strtolower($name)] = trim($style_array[2][$id]); - } + foreach($style_array[1] as $id => $name) { + // in case of duplicate attribute the last replace the previous + $dom[$key]['style'][strtolower($name)] = trim($style_array[2][$id]); + } // --- get some style attributes --- // text direction if (isset($dom[$key]['style']['direction'])) { @@ -17176,10 +17177,10 @@ public function writeHTML($html, $ln=true, $fill=false, $reseth=false, $cell=fal if ($cell) { if ($this->rtl) { $this->x -= $this->cell_padding['R']; - $this->lMargin += $this->cell_padding['R']; + $this->lMargin += $this->cell_padding['L']; } else { $this->x += $this->cell_padding['L']; - $this->rMargin += $this->cell_padding['L']; + $this->rMargin += $this->cell_padding['R']; } } if ($this->customlistindent >= 0) { @@ -18316,7 +18317,8 @@ public function writeHTML($html, $ln=true, $fill=false, $reseth=false, $cell=fal } // text $this->htmlvspace = 0; - if ((!$this->premode) AND $this->isRTLTextDir()) { + $isRTLString = preg_match(TCPDF_FONT_DATA::$uni_RE_PATTERN_RTL, $dom[$key]['value']) || preg_match(TCPDF_FONT_DATA::$uni_RE_PATTERN_ARABIC, $dom[$key]['value']); + if ((!$this->premode) AND $this->isRTLTextDir() AND !$isRTLString) { // reverse spaces order $lsp = ''; // left spaces $rsp = ''; // right spaces @@ -18331,7 +18333,7 @@ public function writeHTML($html, $ln=true, $fill=false, $reseth=false, $cell=fal if ($newline) { if (!$this->premode) { $prelen = strlen($dom[$key]['value']); - if ($this->isRTLTextDir()) { + if ($this->isRTLTextDir() AND !$isRTLString) { // right trim except non-breaking space $dom[$key]['value'] = $this->stringRightTrim($dom[$key]['value']); } else { @@ -18815,100 +18817,122 @@ protected function openHTMLTagHandler($dom, $key, $cell) { break; } case 'img': { - if (!empty($tag['attribute']['src'])) { - if ($tag['attribute']['src'][0] === '@') { - // data stream - $tag['attribute']['src'] = '@'.base64_decode(substr($tag['attribute']['src'], 1)); - $type = ''; - } else { - // get image type - $type = TCPDF_IMAGES::getImageFileType($tag['attribute']['src']); - } - if (!isset($tag['width'])) { - $tag['width'] = 0; - } - if (!isset($tag['height'])) { - $tag['height'] = 0; - } - //if (!isset($tag['attribute']['align'])) { - // the only alignment supported is "bottom" - // further development is required for other modes. - $tag['attribute']['align'] = 'bottom'; - //} - switch($tag['attribute']['align']) { - case 'top': { - $align = 'T'; - break; - } - case 'middle': { - $align = 'M'; - break; - } - case 'bottom': { - $align = 'B'; - break; + if (empty($tag['attribute']['src'])) { + break; + } + $imgsrc = $tag['attribute']['src']; + if ($imgsrc[0] === '@') { + // data stream + $imgsrc = '@'.base64_decode(substr($imgsrc, 1)); + $type = ''; + } else { + if (($imgsrc[0] === '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) { + // fix image path + $findroot = strpos($imgsrc, $_SERVER['DOCUMENT_ROOT']); + if (($findroot === false) OR ($findroot > 1)) { + if (substr($_SERVER['DOCUMENT_ROOT'], -1) == '/') { + $imgsrc = substr($_SERVER['DOCUMENT_ROOT'], 0, -1).$imgsrc; + } else { + $imgsrc = $_SERVER['DOCUMENT_ROOT'].$imgsrc; + } } - default: { - $align = 'B'; - break; + $imgsrc = urldecode($imgsrc); + $testscrtype = @parse_url($imgsrc); + if (empty($testscrtype['query'])) { + // convert URL to server path + $imgsrc = str_replace(K_PATH_URL, K_PATH_MAIN, $imgsrc); + } elseif (preg_match('|^https?://|', $imgsrc) !== 1) { + // convert URL to server path + $imgsrc = str_replace(K_PATH_MAIN, K_PATH_URL, $imgsrc); } } - $prevy = $this->y; - $xpos = $this->x; - $imglink = ''; - if (isset($this->HREF['url']) AND !TCPDF_STATIC::empty_string($this->HREF['url'])) { - $imglink = $this->HREF['url']; - if ($imglink[0] == '#') { - // convert url to internal link - $lnkdata = explode(',', $imglink); - if (isset($lnkdata[0])) { - $page = intval(substr($lnkdata[0], 1)); - if (empty($page) OR ($page <= 0)) { - $page = $this->page; - } - if (isset($lnkdata[1]) AND (strlen($lnkdata[1]) > 0)) { - $lnky = floatval($lnkdata[1]); - } else { - $lnky = 0; - } - $imglink = $this->AddLink(); - $this->SetLink($imglink, $lnky, $page); + // get image type + $type = TCPDF_IMAGES::getImageFileType($imgsrc); + } + if (!isset($tag['width'])) { + $tag['width'] = 0; + } + if (!isset($tag['height'])) { + $tag['height'] = 0; + } + //if (!isset($tag['attribute']['align'])) { + // the only alignment supported is "bottom" + // further development is required for other modes. + $tag['attribute']['align'] = 'bottom'; + //} + switch($tag['attribute']['align']) { + case 'top': { + $align = 'T'; + break; + } + case 'middle': { + $align = 'M'; + break; + } + case 'bottom': { + $align = 'B'; + break; + } + default: { + $align = 'B'; + break; + } + } + $prevy = $this->y; + $xpos = $this->x; + $imglink = ''; + if (isset($this->HREF['url']) AND !TCPDF_STATIC::empty_string($this->HREF['url'])) { + $imglink = $this->HREF['url']; + if ($imglink[0] == '#') { + // convert url to internal link + $lnkdata = explode(',', $imglink); + if (isset($lnkdata[0])) { + $page = intval(substr($lnkdata[0], 1)); + if (empty($page) OR ($page <= 0)) { + $page = $this->page; + } + if (isset($lnkdata[1]) AND (strlen($lnkdata[1]) > 0)) { + $lnky = floatval($lnkdata[1]); + } else { + $lnky = 0; } + $imglink = $this->AddLink(); + $this->SetLink($imglink, $lnky, $page); } } - $border = 0; - if (isset($tag['border']) AND !empty($tag['border'])) { - // currently only support 1 (frame) or a combination of 'LTRB' - $border = $tag['border']; - } - $iw = ''; - if (isset($tag['width'])) { - $iw = $this->getHTMLUnitToUnits($tag['width'], ($tag['fontsize'] / $this->k), 'px', false); - } - $ih = ''; - if (isset($tag['height'])) { - $ih = $this->getHTMLUnitToUnits($tag['height'], ($tag['fontsize'] / $this->k), 'px', false); - } - if (($type == 'eps') OR ($type == 'ai')) { - $this->ImageEps($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, $imglink, true, $align, '', $border, true); - } elseif ($type == 'svg') { - $this->ImageSVG($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, $imglink, $align, '', $border, true); - } else { - $this->Image($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, '', $imglink, $align, false, 300, '', false, false, $border, false, false, true); + } + $border = 0; + if (isset($tag['border']) AND !empty($tag['border'])) { + // currently only support 1 (frame) or a combination of 'LTRB' + $border = $tag['border']; + } + $iw = ''; + if (isset($tag['width'])) { + $iw = $this->getHTMLUnitToUnits($tag['width'], ($tag['fontsize'] / $this->k), 'px', false); + } + $ih = ''; + if (isset($tag['height'])) { + $ih = $this->getHTMLUnitToUnits($tag['height'], ($tag['fontsize'] / $this->k), 'px', false); + } + if (($type == 'eps') OR ($type == 'ai')) { + $this->ImageEps($imgsrc, $xpos, $this->y, $iw, $ih, $imglink, true, $align, '', $border, true); + } elseif ($type == 'svg') { + $this->ImageSVG($imgsrc, $xpos, $this->y, $iw, $ih, $imglink, $align, '', $border, true); + } else { + $this->Image($imgsrc, $xpos, $this->y, $iw, $ih, '', $imglink, $align, false, 300, '', false, false, $border, false, false, true); + } + switch($align) { + case 'T': { + $this->y = $prevy; + break; } - switch($align) { - case 'T': { - $this->y = $prevy; - break; - } - case 'M': { - $this->y = (($this->img_rb_y + $prevy - ($this->getCellHeight($tag['fontsize'] / $this->k))) / 2); - break; - } - case 'B': { - $this->y = $this->img_rb_y - ($this->getCellHeight($tag['fontsize'] / $this->k) - ($this->getFontDescent($tag['fontname'], $tag['fontstyle'], $tag['fontsize']) * $this->cell_height_ratio)); - break; - } + case 'M': { + $this->y = (($this->img_rb_y + $prevy - ($this->getCellHeight($tag['fontsize'] / $this->k))) / 2); + break; + } + case 'B': { + $this->y = $this->img_rb_y - ($this->getCellHeight($tag['fontsize'] / $this->k) - ($this->getFontDescent($tag['fontname'], $tag['fontstyle'], $tag['fontsize']) * $this->cell_height_ratio)); + break; } } break; @@ -21511,7 +21535,7 @@ public function addHTMLTOC($page='', $toc_name='TOC', $templates=array(), $corre } else { // placemark to be replaced with the correct number $pagenum = '{#'.($outline['p']).'}'; - if ($templates['F'.$outline['l']]) { + if (isset($templates['F'.$outline['l']]) && $templates['F'.$outline['l']]) { $pagenum = '{'.$pagenum.'}'; } $maxpage = max($maxpage, $outline['p']); @@ -24204,9 +24228,12 @@ protected function startSVGElementHandler($parser, $name, $attribs, $ctm=array() } $img = urldecode($img); $testscrtype = @parse_url($img); - if (!isset($testscrtype['query']) OR empty($testscrtype['query'])) { + if (empty($testscrtype['query'])) { // convert URL to server path $img = str_replace(K_PATH_URL, K_PATH_MAIN, $img); + } elseif (preg_match('|^https?://|', $img) !== 1) { + // convert server path to URL + $img = str_replace(K_PATH_MAIN, K_PATH_URL, $img); } } // get image type diff --git a/lib/thirdpartylibs.xml b/lib/thirdpartylibs.xml index 85d046baea289..e2e1d1e72a68f 100644 --- a/lib/thirdpartylibs.xml +++ b/lib/thirdpartylibs.xml @@ -130,7 +130,7 @@ tcpdf TCPDF LGPL - 6.2.13 + 6.2.26 3 From dfddaa8ab666667f3f07dfa30c3954a54d16c899 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 23 May 2019 14:11:29 +0800 Subject: [PATCH 061/786] MDL-65660 mod_forum: Allow guest users to view post buttons and links For a self enrolment enabled course allow guest users to see the add discussion and reply buttons --- mod/forum/classes/local/exporters/forum.php | 1 + mod/forum/classes/local/exporters/post.php | 11 ++++++-- .../classes/local/managers/capability.php | 26 +++++++++++++++++++ mod/forum/templates/discussion_list.mustache | 12 +++++++++ .../templates/forum_discussion_post.mustache | 15 +++++++++++ mod/forum/tests/exporters_post_test.php | 20 ++++++++++++-- mod/forum/tests/externallib_test.php | 6 +++-- 7 files changed, 85 insertions(+), 6 deletions(-) diff --git a/mod/forum/classes/local/exporters/forum.php b/mod/forum/classes/local/exporters/forum.php index 40d4dd6604520..ad39615922885 100644 --- a/mod/forum/classes/local/exporters/forum.php +++ b/mod/forum/classes/local/exporters/forum.php @@ -119,6 +119,7 @@ protected function get_other_values(renderer_base $output) { 'capabilities' => [ 'viewdiscussions' => $capabilitymanager->can_view_discussions($user), 'create' => $capabilitymanager->can_create_discussions($user, $currentgroup), + 'selfenrol' => $capabilitymanager->can_self_enrol($user), 'subscribe' => $capabilitymanager->can_subscribe_to_forum($user), ], 'urls' => [ diff --git a/mod/forum/classes/local/exporters/post.php b/mod/forum/classes/local/exporters/post.php index 4528c602d8e25..f0f8d52a4c609 100644 --- a/mod/forum/classes/local/exporters/post.php +++ b/mod/forum/classes/local/exporters/post.php @@ -146,6 +146,11 @@ protected static function define_other_properties() { 'null' => NULL_ALLOWED, 'description' => 'Whether the user can reply to the post', ], + 'selfenrol' => [ + 'type' => PARAM_BOOL, + 'null' => NULL_ALLOWED, + 'description' => 'Whether the user can self enrol into the course', + ], 'export' => [ 'type' => PARAM_BOOL, 'null' => NULL_ALLOWED, @@ -360,6 +365,7 @@ protected function get_other_values(renderer_base $output) { $canreply = $capabilitymanager->can_reply_to_post($user, $discussion, $post); $canexport = $capabilitymanager->can_export_post($user, $post); $cancontrolreadstatus = $capabilitymanager->can_manually_control_post_read_status($user); + $canselfenrol = $capabilitymanager->can_self_enrol($user); $canreplyprivately = $capabilitymanager->can_reply_privately_to_post($user, $post); $urlfactory = $this->related['urlfactory']; @@ -369,7 +375,7 @@ protected function get_other_values(renderer_base $output) { $editurl = $canedit ? $urlfactory->get_edit_post_url_from_post($forum, $post) : null; $deleteurl = $candelete ? $urlfactory->get_delete_post_url_from_post($post) : null; $spliturl = $cansplit ? $urlfactory->get_split_discussion_at_post_url_from_post($post) : null; - $replyurl = $canreply ? $urlfactory->get_reply_to_post_url_from_post($post) : null; + $replyurl = $canreply || $canselfenrol ? $urlfactory->get_reply_to_post_url_from_post($post) : null; $exporturl = $canexport ? $urlfactory->get_export_post_url_from_post($post) : null; $markasreadurl = $cancontrolreadstatus ? $urlfactory->get_mark_post_as_read_url_from_post($post) : null; $markasunreadurl = $cancontrolreadstatus ? $urlfactory->get_mark_post_as_unread_url_from_post($post) : null; @@ -424,7 +430,8 @@ protected function get_other_values(renderer_base $output) { 'reply' => $canreply, 'export' => $canexport, 'controlreadstatus' => $cancontrolreadstatus, - 'canreplyprivately' => $canreplyprivately + 'canreplyprivately' => $canreplyprivately, + 'selfenrol' => $canselfenrol ], 'urls' => [ 'view' => $viewurl ? $viewurl->out(false) : null, diff --git a/mod/forum/classes/local/managers/capability.php b/mod/forum/classes/local/managers/capability.php index 76ba7c127dc2f..ece049e94f0c6 100644 --- a/mod/forum/classes/local/managers/capability.php +++ b/mod/forum/classes/local/managers/capability.php @@ -607,4 +607,30 @@ public function can_manage_forum(stdClass $user) { public function can_manage_tags(stdClass $user) : bool { return has_capability('moodle/tag:manage', context_system::instance(), $user); } + + /** + * Checks whether the user can self enrol into the course. + * Mimics the checks on the add button in deprecatedlib/forum_print_latest_discussions + * + * @param stdClass $user + * @return bool + */ + public function can_self_enrol(stdClass $user) : bool { + $canstart = false; + + if ($this->forum->get_type() != 'news') { + if (isguestuser($user) or !isloggedin()) { + $canstart = true; + } + + if (!is_enrolled($this->context) and !is_viewing($this->context)) { + // Allow guests and not-logged-in to see the button - they are prompted to log in after clicking the link, + // Normal users with temporary guest access see this button too, they are asked to enrol instead, + // Do not show the button to users with suspended enrolments here. + $canstart = enrol_selfenrol_available($this->forum->get_course_id()); + } + } + + return $canstart; + } } diff --git a/mod/forum/templates/discussion_list.mustache b/mod/forum/templates/discussion_list.mustache index 60e3704d270f0..1224277132abc 100644 --- a/mod/forum/templates/discussion_list.mustache +++ b/mod/forum/templates/discussion_list.mustache @@ -51,6 +51,18 @@
{{/forum.capabilities.create}} + {{^forum.capabilities.create}} + {{#forum.capabilities.selfenrol}} + + {{/forum.capabilities.selfenrol}} + {{/forum.capabilities.create}} + {{#state.hasdiscussions}} {{$discussion_top_pagination}} diff --git a/mod/forum/templates/forum_discussion_post.mustache b/mod/forum/templates/forum_discussion_post.mustache index e5a8e1d1c4812..564d1b5528765 100644 --- a/mod/forum/templates/forum_discussion_post.mustache +++ b/mod/forum/templates/forum_discussion_post.mustache @@ -258,6 +258,21 @@ {{/replyoutput}} {{/reply}} + {{^reply}} + {{#selfenrol}} + {{$replyoutput}} + + {{#str}} reply, mod_forum {{/str}} + + {{/replyoutput}} + {{/selfenrol}} + {{/reply}} {{#export}} assertEquals($cansplit, $exportedpost->capabilities['split']); $this->assertEquals($canreply, $exportedpost->capabilities['reply']); $this->assertEquals($canexport, $exportedpost->capabilities['export']); + $this->assertEquals($canenrol, $exportedpost->capabilities['selfenrol']); $this->assertEquals($cancontrolreadstatus, $exportedpost->capabilities['controlreadstatus']); $this->assertNotEmpty($exportedpost->urls['view']); $this->assertNotEmpty($exportedpost->urls['viewisolated']); @@ -416,6 +419,8 @@ class test_capability_manager extends capability_manager { private $controlreadstatus; /** @var bool $controlreadstatus Value for can_reply_privately_to_post */ private $canreplyprivatelytopost; + /** @var bool $canenrol Value for can_self_enrol */ + private $canenrol; /** * Constructor. @@ -436,7 +441,8 @@ public function __construct( bool $reply = true, bool $export = true, bool $controlreadstatus = true, - bool $canreplyprivatelytopost = true + bool $canreplyprivatelytopost = true, + bool $canenrol = true ) { $this->view = $view; $this->edit = $edit; @@ -446,6 +452,7 @@ public function __construct( $this->export = $export; $this->controlreadstatus = $controlreadstatus; $this->canreplyprivatelytopost = $canreplyprivatelytopost; + $this->canenrol = $canenrol; } /** @@ -538,4 +545,13 @@ public function can_manually_control_post_read_status(stdClass $user) : bool { public function can_reply_privately_to_post(stdClass $user, post_entity $post) : bool { return $this->canreplyprivatelytopost; } + + /** + * Override can_self_enrol + * @param stdClass $user + * @return bool + */ + public function can_self_enrol(stdClass $user) : bool { + return $this->canenrol; + } } diff --git a/mod/forum/tests/externallib_test.php b/mod/forum/tests/externallib_test.php index 5e903acbee59a..390cfbba5532e 100644 --- a/mod/forum/tests/externallib_test.php +++ b/mod/forum/tests/externallib_test.php @@ -692,7 +692,8 @@ public function test_mod_forum_get_discussion_posts() { 'reply' => 1, 'export' => 0, 'controlreadstatus' => 0, - 'canreplyprivately' => 0 + 'canreplyprivately' => 0, + 'selfenrol' => 0 ], 'urls' => [ 'view' => $urlfactory->get_view_post_url_from_post_id($discussion1reply2->discussion, $discussion1reply2->id), @@ -745,7 +746,8 @@ public function test_mod_forum_get_discussion_posts() { 'reply' => 1, 'export' => 0, 'controlreadstatus' => 0, - 'canreplyprivately' => 0 + 'canreplyprivately' => 0, + 'selfenrol' => 0 ], 'urls' => [ 'view' => $urlfactory->get_view_post_url_from_post_id($discussion1reply1->discussion, $discussion1reply1->id), From 24e0b238d34a3fa359109b1ddecf6c4679f4c80e Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Mon, 13 May 2019 14:12:25 +0800 Subject: [PATCH 062/786] MDL-65576 behat: Reset Selenium driver between scorm scenarios --- mod/scorm/tests/behat/behat_mod_scorm.php | 54 +++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 mod/scorm/tests/behat/behat_mod_scorm.php diff --git a/mod/scorm/tests/behat/behat_mod_scorm.php b/mod/scorm/tests/behat/behat_mod_scorm.php new file mode 100644 index 0000000000000..ed7e16f182174 --- /dev/null +++ b/mod/scorm/tests/behat/behat_mod_scorm.php @@ -0,0 +1,54 @@ +. + +/** + * Steps definitions related to the SCORM activity module. + * + * @package mod_scorm + * @category test + * @copyright 2019 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../../../lib/behat/behat_base.php'); + +use Behat\Behat\Hook\Scope\AfterScenarioScope; + +/** + * Steps definitions related to the SCORM activity module. + * + * @package mod_scorm + * @category test + * @copyright 2019 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_mod_scorm extends behat_base { + + /** + * Restart the Seleium Session after each mod_scorm Scenario. + * + * This prevents issues with the scorm player's onbeforeunload event, and cached SCORM content being served to the + * browser in subsequent tests. + * + * @AfterScenario @mod_scorm + * @param AfterScenarioScope $scope The scenario scope + */ + public function reset_after_scorm(AfterScenarioScope $scope) { + $this->getSession()->stop(); + } +} From 33b74df1494b3a95c28d0930e017a1ba32a0559a Mon Sep 17 00:00:00 2001 From: Mathew May Date: Tue, 21 May 2019 13:41:46 +0800 Subject: [PATCH 063/786] MDL-65658 mod_forum: Group images links and titles groups After a change in Moodle 3.6 some links & titles went missing. Here I am adding them back & incresing the output image to 100x100px --- lang/en/group.php | 1 + mod/forum/classes/local/exporters/author.php | 17 ++++++++-- .../classes/local/exporters/discussion.php | 2 +- mod/forum/classes/local/factories/url.php | 12 +++++++ mod/forum/styles.css | 3 +- mod/forum/templates/discussion_list.mustache | 19 +++++++++--- .../templates/forum_discussion_post.mustache | 31 ++++++++++++++----- 7 files changed, 67 insertions(+), 18 deletions(-) diff --git a/lang/en/group.php b/lang/en/group.php index 9d448ec385d48..9f32f85f89049 100644 --- a/lang/en/group.php +++ b/lang/en/group.php @@ -196,3 +196,4 @@ $string['usercount'] = 'User count'; $string['usercounttotal'] = 'User count ({$a})'; $string['usergroupmembership'] = 'Selected user\'s membership:'; +$string['memberofgroup'] = 'Group member of: {$a}'; diff --git a/mod/forum/classes/local/exporters/author.php b/mod/forum/classes/local/exporters/author.php index 7ac48221d2c00..7beb5d56564d5 100644 --- a/mod/forum/classes/local/exporters/author.php +++ b/mod/forum/classes/local/exporters/author.php @@ -140,15 +140,26 @@ protected function get_other_values(renderer_base $output) { $author = $this->author; $authorcontextid = $this->authorcontextid; $urlfactory = $this->related['urlfactory']; + $context = $this->related['context']; if ($this->canview) { - $groups = array_map(function($group) { - $imageurl = get_group_picture_url($group, $group->courseid); + $groups = array_map(function($group) use ($urlfactory, $context) { + $imageurl = null; + $groupurl = null; + if (!$group->hidepicture) { + $imageurl = get_group_picture_url($group, $group->courseid, true); + } + if (course_can_view_participants($context)) { + $groupurl = $urlfactory->get_author_group_url($group); + } + return [ 'id' => $group->id, 'name' => $group->name, 'urls' => [ - 'image' => $imageurl ? $imageurl->out(false) : null + 'image' => $imageurl ? $imageurl->out(false) : null, + 'group' => $groupurl ? $groupurl->out(false) : null + ] ]; }, $this->authorgroups); diff --git a/mod/forum/classes/local/exporters/discussion.php b/mod/forum/classes/local/exporters/discussion.php index 16d682a1619ea..a008de4a73f53 100644 --- a/mod/forum/classes/local/exporters/discussion.php +++ b/mod/forum/classes/local/exporters/discussion.php @@ -179,7 +179,7 @@ protected function get_other_values(renderer_base $output) { ]; if (!$group->hidepicture) { - $url = get_group_picture_url($group, $forum->get_course_id()); + $url = get_group_picture_url($group, $forum->get_course_id(), true); if (!empty($url)) { $groupdata['urls']['picture'] = $url; } diff --git a/mod/forum/classes/local/factories/url.php b/mod/forum/classes/local/factories/url.php index ab0fc75b0569c..cfb6b4b083fe4 100644 --- a/mod/forum/classes/local/factories/url.php +++ b/mod/forum/classes/local/factories/url.php @@ -427,6 +427,18 @@ public function get_author_profile_image_url( return $userpicture->get_url($PAGE); } + /** + * Get the url to view an author's group. + * + * @param \stdClass $group The group + * @return moodle_url + */ + public function get_author_group_url(\stdClass $group) : moodle_url { + return new moodle_url('/user/index.php', [ + 'id' => $group->courseid, + 'group' => $group->id + ]); + } /** * Get the url to mark a discussion as read. * diff --git a/mod/forum/styles.css b/mod/forum/styles.css index c7f31dd9a452b..6343e1d9192a0 100644 --- a/mod/forum/styles.css +++ b/mod/forum/styles.css @@ -216,7 +216,8 @@ margin: 5px 0; } -.discussion-list .userpicture { +.discussion-list .userpicture, +.discussion-list .grouppicture { height: 35px; width: 35px; } diff --git a/mod/forum/templates/discussion_list.mustache b/mod/forum/templates/discussion_list.mustache index 60e3704d270f0..fbb2744a1aecc 100644 --- a/mod/forum/templates/discussion_list.mustache +++ b/mod/forum/templates/discussion_list.mustache @@ -155,6 +155,7 @@ class="rounded-circle userpicture" src="{{urls.profileimage}}" alt="{{#str}}pictureof, moodle, {{fullname}}{{/str}}" + title="{{fullname}}" >
@@ -164,21 +165,28 @@ {{/firstpostauthor}} {{#forum.state.groupmode}} - + {{#discussion.group}} {{#urls.picture}} {{#urls.userlist}} - - + + {{/urls.userlist}} {{^urls.userlist}} - + {{#str}} pictureof, core, {{name}} {{/str}} {{/urls.userlist}} {{/urls.picture}} {{^urls.picture}} {{#urls.userlist}} - {{name}} + {{name}} {{/urls.userlist}} {{^urls.userlist}} {{name}} @@ -220,6 +228,7 @@ class="rounded-circle userpicture" src="{{latestpostauthor.urls.profileimage}}" alt="{{#str}}pictureof, moodle, {{latestpostauthor.fullname}}{{/str}}" + title="{{latestpostauthor.fullname}}" >
diff --git a/mod/forum/templates/forum_discussion_post.mustache b/mod/forum/templates/forum_discussion_post.mustache index e5a8e1d1c4812..bf8c39f6ae1b8 100644 --- a/mod/forum/templates/forum_discussion_post.mustache +++ b/mod/forum/templates/forum_discussion_post.mustache @@ -58,6 +58,7 @@ src="{{{.}}}" alt="{{#str}} pictureof, core, {{author.fullname}} {{/str}}" aria-hidden="true" + title="{{author.fullname}}" > {{/urls.profileimage}}
@@ -94,14 +95,28 @@ {{#author}}
{{#groups}} - {{#urls.image}} - - {{/urls.image}} + {{#urls.group}} + {{#urls.image}} + + + + {{/urls.image}} + {{/urls.group}} + {{^urls.group}} + {{#urls.image}} + {{#str}} pictureof, core, {{name}} {{/str}} + {{/urls.image}} + {{/urls.group}} {{/groups}}
{{/author}} From f0782cc57be33d8cbd771924efa26d27140c5b1d Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 17 May 2019 12:19:25 +0800 Subject: [PATCH 064/786] MDL-65578 forum: Hide action menu where no actions exist --- mod/forum/classes/local/renderers/discussion.php | 6 ++++++ mod/forum/classes/local/renderers/discussion_list.php | 7 +++++++ mod/forum/templates/discussion_list.mustache | 8 +++++--- mod/forum/templates/forum_discussion.mustache | 2 ++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/mod/forum/classes/local/renderers/discussion.php b/mod/forum/classes/local/renderers/discussion.php index 084122a7af7a3..7559b2bf5c451 100644 --- a/mod/forum/classes/local/renderers/discussion.php +++ b/mod/forum/classes/local/renderers/discussion.php @@ -183,9 +183,15 @@ public function render( $exporteddiscussion = $this->get_exported_discussion($user); } + $hasanyactions = false; + $hasanyactions = $hasanyactions || $capabilitymanager->can_favourite_discussion($user); + $hasanyactions = $hasanyactions || $capabilitymanager->can_pin_discussions($user); + $hasanyactions = $hasanyactions || $capabilitymanager->can_manage_forum($user); + $exporteddiscussion = array_merge($exporteddiscussion, [ 'notifications' => $this->get_notifications($user), 'html' => [ + 'hasanyactions' => $hasanyactions, 'posts' => $this->postsrenderer->render($user, [$this->forum], [$this->discussion], $posts), 'modeselectorform' => $this->get_display_mode_selector_html($displaymode), 'subscribe' => null, diff --git a/mod/forum/classes/local/renderers/discussion_list.php b/mod/forum/classes/local/renderers/discussion_list.php index ef136a35c0788..24879b1c2bb93 100644 --- a/mod/forum/classes/local/renderers/discussion_list.php +++ b/mod/forum/classes/local/renderers/discussion_list.php @@ -160,8 +160,15 @@ public function render(stdClass $user, \cm_info $cm, ?int $groupid, ?int $sortor // Get all forum discussion summaries. $discussions = mod_forum_get_discussion_summaries($forum, $user, $groupid, $sortorder, $pageno, $pagesize); + $capabilitymanager = $this->capabilitymanager; + $hasanyactions = false; + $hasanyactions = $hasanyactions || $capabilitymanager->can_favourite_discussion($user); + $hasanyactions = $hasanyactions || $capabilitymanager->can_pin_discussions($user); + $hasanyactions = $hasanyactions || $capabilitymanager->can_manage_forum($user); + $forumview = [ 'forum' => (array) $forumexporter->export($this->renderer), + 'hasanyactions' => $hasanyactions, 'groupchangemenu' => groups_print_activity_menu( $cm, $this->urlfactory->get_forum_view_url_from_forum($forum), diff --git a/mod/forum/templates/discussion_list.mustache b/mod/forum/templates/discussion_list.mustache index 60e3704d270f0..07b399984b1d2 100644 --- a/mod/forum/templates/discussion_list.mustache +++ b/mod/forum/templates/discussion_list.mustache @@ -123,9 +123,7 @@ {{/state.sortorder.iscreateddesc}}   - {{#forum.capabilities.subscribe}} - - {{/forum.capabilities.subscribe}} + {{/discussion_list_header}} @@ -266,12 +264,16 @@
{{#pix}}i/lock, core, {{#str}}locked, forum{{/str}}{{/pix}}
+ {{#forum.capabilities.subscribe}}
{{> mod_forum/discussion_subscription_toggle}}
+ {{/forum.capabilities.subscribe}} + {{#hasanyactions}}
{{> mod_forum/forum_action_menu}}
+ {{/hasanyactions}} {{/discussion}} diff --git a/mod/forum/templates/forum_discussion.mustache b/mod/forum/templates/forum_discussion.mustache index f4d37ff11016a..8d661ff164876 100644 --- a/mod/forum/templates/forum_discussion.mustache +++ b/mod/forum/templates/forum_discussion.mustache @@ -32,6 +32,7 @@
{{#html}} + {{#hasanyactions}}
@@ -41,6 +42,7 @@
{{{subscribe}}}
+ {{/hasanyactions}} {{{neighbourlinks}}}
From 5ed8d694ee36f077cda2fbd1f606b945a4c3e183 Mon Sep 17 00:00:00 2001 From: Kristian Ringer Date: Fri, 31 May 2019 16:18:06 +1000 Subject: [PATCH 065/786] MDL-65696 assign: Fix width of editpdf comments --- mod/assign/feedback/editpdf/styles.css | 1 + 1 file changed, 1 insertion(+) diff --git a/mod/assign/feedback/editpdf/styles.css b/mod/assign/feedback/editpdf/styles.css index 48d87f819be92..573fab2771b6e 100644 --- a/mod/assign/feedback/editpdf/styles.css +++ b/mod/assign/feedback/editpdf/styles.css @@ -358,6 +358,7 @@ ul.assignfeedback_editpdf_menu { .assignfeedback_editpdf_widget .commentdrawable.commentcollapsed { z-index: auto; + width: 24px; } .assignfeedback_editpdf_widget .commentdrawable.commentcollapsed textarea, From e998b1468661ddc96097b1a7ab89674e20c216d6 Mon Sep 17 00:00:00 2001 From: AMOS bot Date: Mon, 3 Jun 2019 00:08:17 +0000 Subject: [PATCH 066/786] Automatically generated installer lang files --- install/lang/el_wp/moodle.php | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 install/lang/el_wp/moodle.php diff --git a/install/lang/el_wp/moodle.php b/install/lang/el_wp/moodle.php new file mode 100644 index 0000000000000..1189b3181be5a --- /dev/null +++ b/install/lang/el_wp/moodle.php @@ -0,0 +1,33 @@ +. + +/** + * Automatically generated strings for Moodle installer + * + * Do not edit this file manually! It contains just a subset of strings + * needed during the very first steps of installation. This file was + * generated automatically by export-installer.php (which is part of AMOS + * {@link http://docs.moodle.org/dev/Languages/AMOS}) using the + * list of strings defined in /install/stringnames.txt. + * + * @package installer + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$string['language'] = 'Γλώσσα'; From f5131809c85d5092c47a8bc0f3686246df3427cc Mon Sep 17 00:00:00 2001 From: AMOS bot Date: Tue, 4 Jun 2019 00:08:14 +0000 Subject: [PATCH 067/786] Automatically generated installer lang files --- install/lang/el_wp/moodle.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/install/lang/el_wp/moodle.php b/install/lang/el_wp/moodle.php index 1189b3181be5a..6375cf9547e46 100644 --- a/install/lang/el_wp/moodle.php +++ b/install/lang/el_wp/moodle.php @@ -31,3 +31,7 @@ defined('MOODLE_INTERNAL') || die(); $string['language'] = 'Γλώσσα'; +$string['moodlelogo'] = 'Λογότυπο Moodle'; +$string['next'] = 'Επόμενο'; +$string['previous'] = 'Προηγούμενο'; +$string['reload'] = 'Eπαναφόρτωση'; From bafa907941a03dd023e8651395c7fd048248d911 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 4 Jun 2019 11:18:43 +0800 Subject: [PATCH 068/786] MDL-65656 core: Update composer.json for new PHPUnit version --- composer.lock | 70 ++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/composer.lock b/composer.lock index 948ff212bcddb..fb217d95701d2 100644 --- a/composer.lock +++ b/composer.lock @@ -1633,16 +1633,16 @@ }, { "name": "phpunit/phpunit", - "version": "7.5.9", + "version": "7.5.12", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "134669cf0eeac3f79bc7f0c793efbc158bffc160" + "reference": "9ba59817745b0fe0c1a5a3032dfd4a6d2994ad1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/134669cf0eeac3f79bc7f0c793efbc158bffc160", - "reference": "134669cf0eeac3f79bc7f0c793efbc158bffc160", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9ba59817745b0fe0c1a5a3032dfd4a6d2994ad1c", + "reference": "9ba59817745b0fe0c1a5a3032dfd4a6d2994ad1c", "shasum": "" }, "require": { @@ -1713,7 +1713,7 @@ "testing", "xunit" ], - "time": "2019-04-19T15:50:46+00:00" + "time": "2019-05-28T11:59:40+00:00" }, { "name": "psr/container", @@ -2469,16 +2469,16 @@ }, { "name": "symfony/browser-kit", - "version": "v4.2.8", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "c09c18cca96d7067152f78956faf55346c338283" + "reference": "3fa7d8cbd2e5006038a09b8ef93f3859a89b627e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/c09c18cca96d7067152f78956faf55346c338283", - "reference": "c09c18cca96d7067152f78956faf55346c338283", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/3fa7d8cbd2e5006038a09b8ef93f3859a89b627e", + "reference": "3fa7d8cbd2e5006038a09b8ef93f3859a89b627e", "shasum": "" }, "require": { @@ -2487,6 +2487,8 @@ }, "require-dev": { "symfony/css-selector": "~3.4|~4.0", + "symfony/http-client": "^4.3", + "symfony/mime": "^4.3", "symfony/process": "~3.4|~4.0" }, "suggest": { @@ -2495,7 +2497,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2522,11 +2524,11 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2019-04-07T09:56:43+00:00" + "time": "2019-04-15T20:15:25+00:00" }, { "name": "symfony/class-loader", - "version": "v3.4.27", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", @@ -2582,7 +2584,7 @@ }, { "name": "symfony/config", - "version": "v3.4.27", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/config.git", @@ -2714,7 +2716,7 @@ }, { "name": "symfony/css-selector", - "version": "v3.4.27", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -2767,16 +2769,16 @@ }, { "name": "symfony/debug", - "version": "v3.4.27", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "681afbb26488903c5ac15e63734f1d8ac430c9b9" + "reference": "671fc55bd14800668b1d0a3708c3714940e30a8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/681afbb26488903c5ac15e63734f1d8ac430c9b9", - "reference": "681afbb26488903c5ac15e63734f1d8ac430c9b9", + "url": "https://api.github.com/repos/symfony/debug/zipball/671fc55bd14800668b1d0a3708c3714940e30a8c", + "reference": "671fc55bd14800668b1d0a3708c3714940e30a8c", "shasum": "" }, "require": { @@ -2819,7 +2821,7 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2019-04-11T09:48:14+00:00" + "time": "2019-05-18T13:32:47+00:00" }, { "name": "symfony/dependency-injection", @@ -2893,16 +2895,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v4.2.8", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "53c97769814c80a84a8403efcf3ae7ae966d53bb" + "reference": "28edb1d371640654fbfb9df53d70fa03fdf69fb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/53c97769814c80a84a8403efcf3ae7ae966d53bb", - "reference": "53c97769814c80a84a8403efcf3ae7ae966d53bb", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/28edb1d371640654fbfb9df53d70fa03fdf69fb6", + "reference": "28edb1d371640654fbfb9df53d70fa03fdf69fb6", "shasum": "" }, "require": { @@ -2910,7 +2912,11 @@ "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0" }, + "conflict": { + "masterminds/html5": "<2.6" + }, "require-dev": { + "masterminds/html5": "^2.6", "symfony/css-selector": "~3.4|~4.0" }, "suggest": { @@ -2919,7 +2925,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2946,11 +2952,11 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2019-02-23T15:17:42+00:00" + "time": "2019-04-26T05:53:56+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v3.4.27", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -3013,16 +3019,16 @@ }, { "name": "symfony/filesystem", - "version": "v4.2.8", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "e16b9e471703b2c60b95f14d31c1239f68f11601" + "reference": "988ab7d70c267c34efa85772ca20de3fad11c74b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/e16b9e471703b2c60b95f14d31c1239f68f11601", - "reference": "e16b9e471703b2c60b95f14d31c1239f68f11601", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/988ab7d70c267c34efa85772ca20de3fad11c74b", + "reference": "988ab7d70c267c34efa85772ca20de3fad11c74b", "shasum": "" }, "require": { @@ -3032,7 +3038,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -3059,7 +3065,7 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2019-02-07T11:40:08+00:00" + "time": "2019-05-24T12:50:04+00:00" }, { "name": "symfony/polyfill-ctype", From 202cfa2987fac673dde2aba11b5531af5021d146 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 4 Jun 2019 10:16:08 +0800 Subject: [PATCH 069/786] MDL-65656 analytics: Stop covering memory-intensive tests --- analytics/tests/prediction_test.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/analytics/tests/prediction_test.php b/analytics/tests/prediction_test.php index 1382c9789c9e9..4294cad827bc2 100644 --- a/analytics/tests/prediction_test.php +++ b/analytics/tests/prediction_test.php @@ -436,6 +436,7 @@ public function provider_ml_classifiers_return() { /** * Basic test to check that prediction processors work as expected. * + * @coversNothing * @dataProvider provider_ml_test_evaluation_configuration * @param string $modelquality * @param int $ncourses @@ -486,6 +487,7 @@ public function test_ml_evaluation_configuration($modelquality, $ncourses, $expe /** * Tests the evaluation of already trained models. * + * @coversNothing * @dataProvider provider_ml_processors * @param string $predictionsprocessorclass * @return null From af098adec299fc8fe7e02d4930b113aeed805abd Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 30 May 2019 11:32:26 +0800 Subject: [PATCH 070/786] MDL-65779 mod_forum: Add privatereplies to the backup process --- mod/forum/backup/moodle2/backup_forum_stepslib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/forum/backup/moodle2/backup_forum_stepslib.php b/mod/forum/backup/moodle2/backup_forum_stepslib.php index 75b3456974a87..09498e5af944d 100644 --- a/mod/forum/backup/moodle2/backup_forum_stepslib.php +++ b/mod/forum/backup/moodle2/backup_forum_stepslib.php @@ -58,7 +58,7 @@ protected function define_structure() { $post = new backup_nested_element('post', array('id'), array( 'parent', 'userid', 'created', 'modified', 'mailed', 'subject', 'message', 'messageformat', - 'messagetrust', 'attachment', 'totalscore', 'mailnow')); + 'messagetrust', 'attachment', 'totalscore', 'mailnow', 'privatereplyto')); $tags = new backup_nested_element('poststags'); $tag = new backup_nested_element('tag', array('id'), array('itemid', 'rawname')); From 12e04336a0043a0301d4dd5d484b1a4dc1edf619 Mon Sep 17 00:00:00 2001 From: Mathew May Date: Tue, 4 Jun 2019 13:42:07 +0800 Subject: [PATCH 071/786] MDL-65658 mod_forum: Update the group image titles --- mod/forum/templates/discussion_list.mustache | 8 ++++---- mod/forum/templates/forum_discussion_post.mustache | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mod/forum/templates/discussion_list.mustache b/mod/forum/templates/discussion_list.mustache index 164fa5abed474..c59e87ebf5396 100644 --- a/mod/forum/templates/discussion_list.mustache +++ b/mod/forum/templates/discussion_list.mustache @@ -167,7 +167,7 @@ class="rounded-circle userpicture" src="{{urls.profileimage}}" alt="{{#str}}pictureof, moodle, {{fullname}}{{/str}}" - title="{{fullname}}" + title="{{#str}}pictureof, moodle, {{fullname}}{{/str}}" >
@@ -186,14 +186,14 @@ aria-hidden="true" class="border rounded h-auto rounded-circle grouppicture" src="{{{urls.picture}}}" - title="{{name}}"> + title="{{#str}} pictureof, core, {{name}} {{/str}}"> {{/urls.userlist}} {{^urls.userlist}} {{#str}} pictureof, core, {{name}} {{/str}} + title="{{#str}} pictureof, core, {{name}} {{/str}}"> {{/urls.userlist}} {{/urls.picture}} {{^urls.picture}} @@ -240,7 +240,7 @@ class="rounded-circle userpicture" src="{{latestpostauthor.urls.profileimage}}" alt="{{#str}}pictureof, moodle, {{latestpostauthor.fullname}}{{/str}}" - title="{{latestpostauthor.fullname}}" + title="{{#str}}pictureof, moodle, {{latestpostauthor.fullname}}{{/str}}" >
diff --git a/mod/forum/templates/forum_discussion_post.mustache b/mod/forum/templates/forum_discussion_post.mustache index 7b915eb85b12d..5023af89beb09 100644 --- a/mod/forum/templates/forum_discussion_post.mustache +++ b/mod/forum/templates/forum_discussion_post.mustache @@ -58,7 +58,7 @@ src="{{{.}}}" alt="{{#str}} pictureof, core, {{author.fullname}} {{/str}}" aria-hidden="true" - title="{{author.fullname}}" + title="{{#str}} pictureof, core, {{author.fullname}} {{/str}}" > {{/urls.profileimage}}
@@ -107,7 +107,7 @@ src="{{{.}}}" alt="{{#str}} pictureof, core, {{name}} {{/str}}" aria-hidden="true" - title="{{name}}" + title="{{#str}} pictureof, core, {{name}} {{/str}}" > {{/urls.image}} @@ -117,7 +117,7 @@ {{#str}} pictureof, core, {{name}} {{/str}} {{/urls.image}} {{/urls.group}} From e1f4756dfb5987b432d9fc00789d7592691e9cdf Mon Sep 17 00:00:00 2001 From: Andreas Grabs Date: Thu, 23 May 2019 21:32:14 +0200 Subject: [PATCH 072/786] MDL-65703 core_calendar: fix user event type filtering logic --- calendar/managesubscriptions.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/calendar/managesubscriptions.php b/calendar/managesubscriptions.php index 4837733629e37..2bc85428dde55 100644 --- a/calendar/managesubscriptions.php +++ b/calendar/managesubscriptions.php @@ -129,6 +129,10 @@ $usedefaultfilters = true; if (!empty($courseid) && $courseid == SITEID && !empty($types['site'])) { $searches[] = "(eventtype = 'site')"; + $usedefaultfilters = false; +} + +if (!empty($types['user'])) { $searches[] = "(eventtype = 'user' AND userid = :userid)"; $params['userid'] = $USER->id; $usedefaultfilters = false; From ca66ad24c826e9c75732a66cf2a5b458cefb78a0 Mon Sep 17 00:00:00 2001 From: Simey Lameze Date: Tue, 4 Jun 2019 19:03:19 +0800 Subject: [PATCH 073/786] MDL-65703 calendar: do not add course param for site calendar --- calendar/classes/external/footer_options_exporter.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/calendar/classes/external/footer_options_exporter.php b/calendar/classes/external/footer_options_exporter.php index 5d7f198fecbfe..da7b69de58538 100644 --- a/calendar/classes/external/footer_options_exporter.php +++ b/calendar/classes/external/footer_options_exporter.php @@ -100,8 +100,6 @@ protected function get_link_params() { $params['course'] = $this->calendar->course->id; } else if (null !== $this->calendar->categoryid && $this->calendar->categoryid > 0) { $params['category'] = $this->calendar->categoryid; - } else { - $params['course'] = SITEID; } return $params; From 29e40f3c133f35e3e5019517bc17b718e585d131 Mon Sep 17 00:00:00 2001 From: AMOS bot Date: Wed, 5 Jun 2019 00:08:19 +0000 Subject: [PATCH 074/786] Automatically generated installer lang files --- install/lang/el_wp/admin.php | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 install/lang/el_wp/admin.php diff --git a/install/lang/el_wp/admin.php b/install/lang/el_wp/admin.php new file mode 100644 index 0000000000000..edf1d437f830b --- /dev/null +++ b/install/lang/el_wp/admin.php @@ -0,0 +1,41 @@ +. + +/** + * Automatically generated strings for Moodle installer + * + * Do not edit this file manually! It contains just a subset of strings + * needed during the very first steps of installation. This file was + * generated automatically by export-installer.php (which is part of AMOS + * {@link http://docs.moodle.org/dev/Languages/AMOS}) using the + * list of strings defined in /install/stringnames.txt. + * + * @package installer + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$string['clianswerno'] = 'ο'; +$string['cliansweryes'] = 'ν'; +$string['cliincorrectvalueerror'] = 'Σφάλμα, λανθασμένη τιμή «{$a->value}» για το «{$a->option}»'; +$string['cliincorrectvalueretry'] = 'Λανθασμένη τιμή. Παρακαλούμε προσπαθήστε ξανά.'; +$string['clitypevalue'] = 'πληκτρολογήστε μια τιμή'; +$string['clitypevaluedefault'] = 'πληκτρολογήστε μια τιμή· πατήστε Enter για να χρησιμοποιήσετε τηνπροεπιλεγμένη τιμή ({$a})'; +$string['cliunknowoption'] = 'Μη αναγνωρίσιμες επιλογές: {$a}
+Παρακαλούμε χρησιμοποιήστε την επιλογή --βοήθεια'; +$string['cliyesnoprompt'] = 'πατήστε y (σημαίνει yes=ναι) ή πατήστε n (σημαίνει no=όχι)'; From 24bc58278f9c5e660d2348f46ea2f05960b23cb8 Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Wed, 5 Jun 2019 11:12:57 +0800 Subject: [PATCH 075/786] MDL-65777 assignment: Respect user full name in downloaded submissions --- mod/assign/feedback/file/importzipform.php | 2 +- mod/assign/locallib.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mod/assign/feedback/file/importzipform.php b/mod/assign/feedback/file/importzipform.php index 433d205251d61..2e6840eb2026f 100644 --- a/mod/assign/feedback/file/importzipform.php +++ b/mod/assign/feedback/file/importzipform.php @@ -80,7 +80,7 @@ public function definition() { if ($importer->is_valid_filename_for_import($assignment, $unzippedfile, $participants, $user, $plugin, $filename)) { if ($importer->is_file_modified($assignment, $user, $plugin, $filename, $unzippedfile)) { // Get a string we can show to identify this user. - $userdesc = fullname($user); + $userdesc = fullname($user, has_capability('moodle/site:viewfullnames', $assignment->get_context())); $path = pathinfo($filename); if ($assignment->is_blind_marking()) { $userdesc = get_string('hiddenuser', 'assign') . diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index a9f0174335bb9..bef787c7c01d1 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -3517,7 +3517,8 @@ protected function download_submissions($userids = false) { $prefix = str_replace('_', ' ', $groupname . get_string('participant', 'assign')); $prefix = clean_filename($prefix . '_' . $this->get_uniqueid_for_user($userid)); } else { - $prefix = str_replace('_', ' ', $groupname . fullname($student)); + $fullname = fullname($student, has_capability('moodle/site:viewfullnames', $this->get_context())); + $prefix = str_replace('_', ' ', $groupname . $fullname); $prefix = clean_filename($prefix . '_' . $this->get_uniqueid_for_user($userid)); } From b31ec4dfbf2a84a07aa418be6f08b4b7ece07b0b Mon Sep 17 00:00:00 2001 From: Sara Arjona Date: Wed, 29 May 2019 15:09:39 +0200 Subject: [PATCH 076/786] MDL-65787 badges: fix warning count() with PHP 7.2 --- badges/classes/form/collections.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/badges/classes/form/collections.php b/badges/classes/form/collections.php index 6f221b79e0adb..5a57ba2b426d1 100644 --- a/badges/classes/form/collections.php +++ b/badges/classes/form/collections.php @@ -79,24 +79,25 @@ public function definition() { $hasgroups = false; if (!empty($groups)) { foreach ($groups as $group) { - // Assertions or badges. $count = 0; - + // Handle attributes based on backpack's supported version. if ($sitebackpack->apiversion == OPEN_BADGES_V2) { + // OpenBadges v2 data attributes. if (empty($group->published)) { // Only public collections. continue; } - } - if (!empty($group->assertions)) { + + // Get the number of badges associated with this collection from the assertions array returned. $count = count($group->assertions); - } - if (!empty($group->badges)) { - $count = count($group->badges); - } - if (!empty($group->groupId)) { + } else { + // OpenBadges v1 data attributes. $group->entityId = $group->groupId; + + // Get the number of badges associated with this collection. In that case, the number is returned directly. + $count = $group->badges; } + if (!$hasgroups) { $mform->addElement('static', 'selectgroup', '', get_string('selectgroup_start', 'badges')); } From 33113481b530a474ee7c79a3e906c0fc62b7126d Mon Sep 17 00:00:00 2001 From: AMOS bot Date: Thu, 6 Jun 2019 00:08:17 +0000 Subject: [PATCH 077/786] Automatically generated installer lang files --- install/lang/el_wp/admin.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/lang/el_wp/admin.php b/install/lang/el_wp/admin.php index edf1d437f830b..8e5c8f0ffdccb 100644 --- a/install/lang/el_wp/admin.php +++ b/install/lang/el_wp/admin.php @@ -39,3 +39,5 @@ $string['cliunknowoption'] = 'Μη αναγνωρίσιμες επιλογές: {$a}
Παρακαλούμε χρησιμοποιήστε την επιλογή --βοήθεια'; $string['cliyesnoprompt'] = 'πατήστε y (σημαίνει yes=ναι) ή πατήστε n (σημαίνει no=όχι)'; +$string['environmentrequireinstall'] = 'απαιτείται να εγκατασταθεί/ ενεργοποιηθεί'; +$string['environmentrequireversion'] = 'απαιτείται η έκδοση {$a->needed} ενώ εσείς έχετε την {$a->current}'; From e8b50bbe34de0b1652a7e78a8d5695b075284316 Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Thu, 6 Jun 2019 13:26:51 +0800 Subject: [PATCH 078/786] MDL-64383 user: Make username required Username is a required field, we should indicate this even if it has a help icon. --- user/editadvanced_form.php | 1 + 1 file changed, 1 insertion(+) diff --git a/user/editadvanced_form.php b/user/editadvanced_form.php index 6506249ae57a0..59f64cdd81219 100644 --- a/user/editadvanced_form.php +++ b/user/editadvanced_form.php @@ -99,6 +99,7 @@ public function definition() { $purpose = user_edit_map_field_purpose($userid, 'username'); $mform->addElement('text', 'username', get_string('username'), 'size="20"' . $purpose); + $mform->addRule('username', get_string('required'), 'required', null, 'client'); $mform->addHelpButton('username', 'username', 'auth'); $mform->setType('username', PARAM_RAW); From 46f7f67db179c27a105c4922e9e60b932413e1bb Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Tue, 28 May 2019 11:27:01 +0800 Subject: [PATCH 079/786] MDL-55821 assign: Show assign grade When marking workflow is enabled and the grade is not released yet, it would be helpful to show the assignment grade in the grading form. --- mod/assign/lang/en/assign.php | 1 + mod/assign/locallib.php | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/mod/assign/lang/en/assign.php b/mod/assign/lang/en/assign.php index e5033dc1066f7..01888a344e848 100644 --- a/mod/assign/lang/en/assign.php +++ b/mod/assign/lang/en/assign.php @@ -131,6 +131,7 @@ $string['couldnotcreatenewassignmentinstance'] = 'Could not create new assignment instance.'; $string['couldnotfindassignmenttoupgrade'] = 'Could not find old assignment instance to upgrade.'; $string['crontask'] = 'Background processing for assignment module'; +$string['currentassigngrade'] = 'Current grade in assignment'; $string['currentgrade'] = 'Current grade in gradebook'; $string['currentattempt'] = 'This is attempt {$a}.'; $string['currentattemptof'] = 'This is attempt {$a->attemptnumber} ( {$a->maxattempts} attempts allowed ).'; diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index a9f0174335bb9..210f96e1db3bc 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -7585,6 +7585,14 @@ public function add_grade_form_elements(MoodleQuickForm $mform, stdClass $data, $options = array('' => get_string('markingworkflowstatenotmarked', 'assign')) + $states; $mform->addElement('select', 'workflowstate', get_string('markingworkflowstate', 'assign'), $options); $mform->addHelpButton('workflowstate', 'markingworkflowstate', 'assign'); + $gradingstatus = $this->get_grading_status($userid); + if ($gradingstatus != ASSIGN_MARKING_WORKFLOW_STATE_RELEASED) { + if ($grade->grade && $grade->grade != -1) { + $assigngradestring = html_writer::span(grade_floatval($grade->grade), 'currentgrade'); + $label = get_string('currentassigngrade', 'assign'); + $mform->addElement('static', 'currentassigngrade', $label, $assigngradestring); + } + } } if ($this->get_instance()->markingworkflow && @@ -7606,6 +7614,7 @@ public function add_grade_form_elements(MoodleQuickForm $mform, stdClass $data, $mform->disabledIf('allocatedmarker', 'workflowstate', 'eq', ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE); $mform->disabledIf('allocatedmarker', 'workflowstate', 'eq', ASSIGN_MARKING_WORKFLOW_STATE_RELEASED); } + $gradestring = '' . $gradestring . ''; $mform->addElement('static', 'currentgrade', get_string('currentgrade', 'assign'), $gradestring); From 078699a1a5117470335ef2e5f89e7b9b04ca34b6 Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Thu, 6 Jun 2019 16:46:52 +0200 Subject: [PATCH 080/786] weekly release 3.7+ --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index e9dbb71262a0e..70d40f3a11db6 100644 --- a/version.php +++ b/version.php @@ -29,11 +29,11 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2019052000.02; // 20190520 = branching date YYYYMMDD - do not modify! +$version = 2019052000.03; // 20190520 = branching date YYYYMMDD - do not modify! // RR = release increments - 00 in DEV branches. // .XX = incremental changes. -$release = '3.7+ (Build: 20190530)'; // Human-friendly version name +$release = '3.7+ (Build: 20190606)'; // Human-friendly version name $branch = '37'; // This version's branch. $maturity = MATURITY_STABLE; // This version's maturity level. From 840d6ba543e0f2625014ed96dfb759077f4e38c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Monlla=C3=B3?= Date: Mon, 3 Jun 2019 11:57:57 +0200 Subject: [PATCH 081/786] MDL-65829 analytics: Accept enrol start time after analysis time --- .../analytics/target/course_competencies.php | 5 ---- .../analytics/target/course_completion.php | 4 ---- .../analytics/target/course_dropout.php | 5 ---- .../analytics/target/course_enrolments.php | 23 ------------------- .../analytics/target/course_gradetopass.php | 5 ---- lib/tests/targets_test.php | 12 +--------- 6 files changed, 1 insertion(+), 53 deletions(-) diff --git a/course/classes/analytics/target/course_competencies.php b/course/classes/analytics/target/course_competencies.php index 046013b54bf57..0aea6268db6bb 100644 --- a/course/classes/analytics/target/course_competencies.php +++ b/course/classes/analytics/target/course_competencies.php @@ -118,11 +118,6 @@ public function is_valid_analysable(\core_analytics\analysable $course, $fortrai */ protected function calculate_sample($sampleid, \core_analytics\analysable $course, $starttime = false, $endtime = false) { - if ($this->enrolment_starts_after_calculation_start($sampleid, $starttime)) { - // Discard user enrolments whose start date is after $starttime. - return null; - } - $userenrol = $this->retrieve('user_enrolments', $sampleid); $key = $course->get_id(); diff --git a/course/classes/analytics/target/course_completion.php b/course/classes/analytics/target/course_completion.php index 75f0d82c1c377..9c187ca76b7d7 100644 --- a/course/classes/analytics/target/course_completion.php +++ b/course/classes/analytics/target/course_completion.php @@ -96,10 +96,6 @@ public function is_valid_analysable(\core_analytics\analysable $course, $fortrai */ protected function calculate_sample($sampleid, \core_analytics\analysable $course, $starttime = false, $endtime = false) { - if ($this->enrolment_starts_after_calculation_start($sampleid, $starttime)) { - // Discard user enrolments whose start date is after $starttime. - return null; - } $userenrol = $this->retrieve('user_enrolments', $sampleid); // We use completion as a success metric. diff --git a/course/classes/analytics/target/course_dropout.php b/course/classes/analytics/target/course_dropout.php index 4cb43c7a82acb..694b05810793c 100644 --- a/course/classes/analytics/target/course_dropout.php +++ b/course/classes/analytics/target/course_dropout.php @@ -118,11 +118,6 @@ public function is_valid_analysable(\core_analytics\analysable $course, $fortrai */ protected function calculate_sample($sampleid, \core_analytics\analysable $course, $starttime = false, $endtime = false) { - if ($this->enrolment_starts_after_calculation_start($sampleid, $starttime)) { - // Discard user enrolments whose start date is after $starttime. - return null; - } - $userenrol = $this->retrieve('user_enrolments', $sampleid); // We use completion as a success metric only when it is enabled. diff --git a/course/classes/analytics/target/course_enrolments.php b/course/classes/analytics/target/course_enrolments.php index e3384132438d3..57b8ee6356035 100644 --- a/course/classes/analytics/target/course_enrolments.php +++ b/course/classes/analytics/target/course_enrolments.php @@ -197,27 +197,4 @@ public function prediction_actions(\core_analytics\prediction $prediction, $incl return array_merge($actions, parent::prediction_actions($prediction, $includedetailsaction)); } - - /** - * Does the user enrolment created after this time range start time or starts after it? - * - * We need to identify these enrolments because the indicators can not be calculated properly - * if the student enrolment started half way through this time range. - * - * User enrolments whose end date is before time() have already been discarded in - * course_enrolments::is_valid_sample. - * - * @param int $sampleid - * @param int $starttime - * @return bool - */ - protected function enrolment_starts_after_calculation_start(int $sampleid, int $starttime) { - - $userenrol = $this->retrieve('user_enrolments', $sampleid); - if ($userenrol->timestart && $userenrol->timestart > $starttime) { - return true; - } - - return false; - } } diff --git a/course/classes/analytics/target/course_gradetopass.php b/course/classes/analytics/target/course_gradetopass.php index 84152eb2b70e9..cb5727c393d81 100644 --- a/course/classes/analytics/target/course_gradetopass.php +++ b/course/classes/analytics/target/course_gradetopass.php @@ -164,11 +164,6 @@ public function is_valid_analysable(\core_analytics\analysable $course, $fortrai */ protected function calculate_sample($sampleid, \core_analytics\analysable $course, $starttime = false, $endtime = false) { - if ($this->enrolment_starts_after_calculation_start($sampleid, $starttime)) { - // Discard user enrolments whose start date is after $starttime. - return null; - } - $userenrol = $this->retrieve('user_enrolments', $sampleid); // Get course grade to pass. diff --git a/lib/tests/targets_test.php b/lib/tests/targets_test.php index a61cb8365d3e4..248737470857e 100644 --- a/lib/tests/targets_test.php +++ b/lib/tests/targets_test.php @@ -413,15 +413,11 @@ public function test_core_target_course_gradetopass_calculate() { $student1 = $dg->create_user(); $student2 = $dg->create_user(); $student3 = $dg->create_user(); - $student4 = $dg->create_user(); $studentrole = $DB->get_record('role', array('shortname' => 'student')); $dg->enrol_user($student1->id, $course1->id, $studentrole->id); $dg->enrol_user($student2->id, $course1->id, $studentrole->id); $dg->enrol_user($student3->id, $course1->id, $studentrole->id); - $enrolstart = mktime(0, 0, 0, 10, 25, 2015); - $dg->enrol_user($student4->id, $course1->id, $studentrole->id, 'manual', $enrolstart); - // get_all_samples() does not guarantee any order, so let's // explicitly define the expectations here for later comparing. // Expectations format being array($userid => expectation, ...) @@ -439,9 +435,6 @@ public function test_core_target_course_gradetopass_calculate() { // Student 3 (has no grade) fails, so it's non achieved sample. $expectations[$student3->id] = 1; - // Student 4 should be null as its enrolment timestart is after the this range. - $expectations[$student4->id] = null; - $courseitem->gradepass = 50; $DB->update_record('grade_items', $courseitem); @@ -460,12 +453,9 @@ public function test_core_target_course_gradetopass_calculate() { $method = $class->getMethod('calculate_sample'); $method->setAccessible(true); - $starttime = mktime(0, 0, 0, 10, 24, 2015); - // Verify all the expectations are fulfilled. foreach ($sampleids as $sampleid => $key) { - $this->assertEquals($expectations[$samplesdata[$key]['user']->id], $method->invoke($target, $sampleid, - $analysable, $starttime)); + $this->assertEquals($expectations[$samplesdata[$key]['user']->id], $method->invoke($target, $sampleid, $analysable)); } } } From dc8b92e0b2a4773dc64ae14a141a81cd1fbfa8f9 Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Tue, 4 Jun 2019 00:29:31 +0200 Subject: [PATCH 082/786] MDL-65817 behat: switch to forked repo towards php73 compatibility It seems that https://github.com/instaclick/php-webdriver/pull/91 is being ignored (in fact the repository itself doesn't show much activity). So we have decided to fork it and apply any fix able to keep our (non-marionette) runs working. Hopefully, soon, the new W3C drivers will be supported by our behat->mink stack... and we'll be able to move to it (from current JSonwire drivers). So all this will be hostory. --- composer.json | 9 ++++- composer.lock | 101 +++++++++++++++++++++++++++++--------------------- 2 files changed, 67 insertions(+), 43 deletions(-) diff --git a/composer.json b/composer.json index 6dc963d3ddce5..5dba48b03f03c 100644 --- a/composer.json +++ b/composer.json @@ -4,10 +4,17 @@ "description": "Moodle - the world's open source learning platform", "type": "project", "homepage": "https://moodle.org", + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/moodlehq/php-webdriver.git" + } + ], "require-dev": { "phpunit/phpunit": "7.5.*", "phpunit/dbunit": "4.0.*", "moodlehq/behat-extension": "3.37.0", - "mikey179/vfsstream": "^1.6" + "mikey179/vfsstream": "^1.6", + "instaclick/php-webdriver": "dev-local as 1.x-dev" } } diff --git a/composer.lock b/composer.lock index 948ff212bcddb..4da555e522559 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3517a4473544055cd8523bb076cad8f6", + "content-hash": "6a672c1cc2c9d005b5eab7c22af1ac49", "packages": [], "packages-dev": [ { @@ -808,16 +808,16 @@ }, { "name": "instaclick/php-webdriver", - "version": "1.4.5", + "version": "dev-local", "source": { "type": "git", - "url": "https://github.com/instaclick/php-webdriver.git", - "reference": "6fa959452e774dcaed543faad3a9d1a37d803327" + "url": "https://github.com/moodlehq/php-webdriver.git", + "reference": "e311e55bf2c4746db9df72707f3cf1a731ad98aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/6fa959452e774dcaed543faad3a9d1a37d803327", - "reference": "6fa959452e774dcaed543faad3a9d1a37d803327", + "url": "https://api.github.com/repos/moodlehq/php-webdriver/zipball/e311e55bf2c4746db9df72707f3cf1a731ad98aa", + "reference": "e311e55bf2c4746db9df72707f3cf1a731ad98aa", "shasum": "" }, "require": { @@ -839,7 +839,6 @@ "WebDriver": "lib/" } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], @@ -863,7 +862,10 @@ "webdriver", "webtest" ], - "time": "2017-06-30T04:02:48+00:00" + "support": { + "source": "https://github.com/moodlehq/php-webdriver/tree/local" + }, + "time": "2019-06-03T22:55:37+00:00" }, { "name": "mikey179/vfsStream", @@ -1633,16 +1635,16 @@ }, { "name": "phpunit/phpunit", - "version": "7.5.9", + "version": "7.5.12", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "134669cf0eeac3f79bc7f0c793efbc158bffc160" + "reference": "9ba59817745b0fe0c1a5a3032dfd4a6d2994ad1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/134669cf0eeac3f79bc7f0c793efbc158bffc160", - "reference": "134669cf0eeac3f79bc7f0c793efbc158bffc160", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9ba59817745b0fe0c1a5a3032dfd4a6d2994ad1c", + "reference": "9ba59817745b0fe0c1a5a3032dfd4a6d2994ad1c", "shasum": "" }, "require": { @@ -1713,7 +1715,7 @@ "testing", "xunit" ], - "time": "2019-04-19T15:50:46+00:00" + "time": "2019-05-28T11:59:40+00:00" }, { "name": "psr/container", @@ -2469,16 +2471,16 @@ }, { "name": "symfony/browser-kit", - "version": "v4.2.8", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "c09c18cca96d7067152f78956faf55346c338283" + "reference": "3fa7d8cbd2e5006038a09b8ef93f3859a89b627e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/c09c18cca96d7067152f78956faf55346c338283", - "reference": "c09c18cca96d7067152f78956faf55346c338283", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/3fa7d8cbd2e5006038a09b8ef93f3859a89b627e", + "reference": "3fa7d8cbd2e5006038a09b8ef93f3859a89b627e", "shasum": "" }, "require": { @@ -2487,6 +2489,8 @@ }, "require-dev": { "symfony/css-selector": "~3.4|~4.0", + "symfony/http-client": "^4.3", + "symfony/mime": "^4.3", "symfony/process": "~3.4|~4.0" }, "suggest": { @@ -2495,7 +2499,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2522,11 +2526,11 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2019-04-07T09:56:43+00:00" + "time": "2019-04-15T20:15:25+00:00" }, { "name": "symfony/class-loader", - "version": "v3.4.27", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", @@ -2582,7 +2586,7 @@ }, { "name": "symfony/config", - "version": "v3.4.27", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/config.git", @@ -2714,7 +2718,7 @@ }, { "name": "symfony/css-selector", - "version": "v3.4.27", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -2767,16 +2771,16 @@ }, { "name": "symfony/debug", - "version": "v3.4.27", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "681afbb26488903c5ac15e63734f1d8ac430c9b9" + "reference": "671fc55bd14800668b1d0a3708c3714940e30a8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/681afbb26488903c5ac15e63734f1d8ac430c9b9", - "reference": "681afbb26488903c5ac15e63734f1d8ac430c9b9", + "url": "https://api.github.com/repos/symfony/debug/zipball/671fc55bd14800668b1d0a3708c3714940e30a8c", + "reference": "671fc55bd14800668b1d0a3708c3714940e30a8c", "shasum": "" }, "require": { @@ -2819,7 +2823,7 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2019-04-11T09:48:14+00:00" + "time": "2019-05-18T13:32:47+00:00" }, { "name": "symfony/dependency-injection", @@ -2893,16 +2897,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v4.2.8", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "53c97769814c80a84a8403efcf3ae7ae966d53bb" + "reference": "28edb1d371640654fbfb9df53d70fa03fdf69fb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/53c97769814c80a84a8403efcf3ae7ae966d53bb", - "reference": "53c97769814c80a84a8403efcf3ae7ae966d53bb", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/28edb1d371640654fbfb9df53d70fa03fdf69fb6", + "reference": "28edb1d371640654fbfb9df53d70fa03fdf69fb6", "shasum": "" }, "require": { @@ -2910,7 +2914,11 @@ "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0" }, + "conflict": { + "masterminds/html5": "<2.6" + }, "require-dev": { + "masterminds/html5": "^2.6", "symfony/css-selector": "~3.4|~4.0" }, "suggest": { @@ -2919,7 +2927,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2946,11 +2954,11 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2019-02-23T15:17:42+00:00" + "time": "2019-04-26T05:53:56+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v3.4.27", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -3013,16 +3021,16 @@ }, { "name": "symfony/filesystem", - "version": "v4.2.8", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "e16b9e471703b2c60b95f14d31c1239f68f11601" + "reference": "988ab7d70c267c34efa85772ca20de3fad11c74b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/e16b9e471703b2c60b95f14d31c1239f68f11601", - "reference": "e16b9e471703b2c60b95f14d31c1239f68f11601", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/988ab7d70c267c34efa85772ca20de3fad11c74b", + "reference": "988ab7d70c267c34efa85772ca20de3fad11c74b", "shasum": "" }, "require": { @@ -3032,7 +3040,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -3059,7 +3067,7 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2019-02-07T11:40:08+00:00" + "time": "2019-05-24T12:50:04+00:00" }, { "name": "symfony/polyfill-ctype", @@ -3439,9 +3447,18 @@ "time": "2018-12-25T11:19:39+00:00" } ], - "aliases": [], + "aliases": [ + { + "alias": "1.x-dev", + "alias_normalized": "1.9999999.9999999.9999999-dev", + "version": "dev-local", + "package": "instaclick/php-webdriver" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "instaclick/php-webdriver": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": [], From e48dd422f97e52eca8f10b6a2ede087be9cf8ec7 Mon Sep 17 00:00:00 2001 From: Kristian Ringer Date: Thu, 30 May 2019 16:25:44 +1000 Subject: [PATCH 083/786] MDL-65183 block_timeline: escape newline characters --- blocks/timeline/templates/event-list-item.mustache | 8 ++++---- lib/amd/build/templates.min.js | 2 +- lib/amd/src/templates.js | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/blocks/timeline/templates/event-list-item.mustache b/blocks/timeline/templates/event-list-item.mustache index b89e8083160d2..73b275efff7d2 100644 --- a/blocks/timeline/templates/event-list-item.mustache +++ b/blocks/timeline/templates/event-list-item.mustache @@ -50,10 +50,10 @@
{{{name}}}
- {{{course.fullnamedisplay}}} + title={{#quote}}{{{name}}}{{/quote}} + aria-label='{{#str}} ariaeventlistitem, block_timeline, { "name": {{#quote}}{{{name}}}{{/quote}}, "course": {{#quote}}{{{course.fullnamedisplay}}}{{/quote}}, "date": "{{#userdate}} {{timesort}}, {{#str}} strftimedatetime, core_langconfig {{/str}} {{/userdate}}" } {{/str}}' + >
{{#quote}}{{{name}}}{{/quote}}
+ {{#quote}}{{{course.fullnamedisplay}}}{{/quote}} {{#action.actionable}}
{{{action.name}}} diff --git a/lib/amd/build/templates.min.js b/lib/amd/build/templates.min.js index 606dc855bddfc..1293f1a4ade4e 100644 --- a/lib/amd/build/templates.min.js +++ b/lib/amd/build/templates.min.js @@ -1 +1 @@ -define(["core/mustache","jquery","core/ajax","core/str","core/notification","core/url","core/config","core/localstorage","core/icon_system","core/event","core/yui","core/log","core/truncate","core/user_date","core/pending"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q={},r={},s={},t={},u=[],v=!1,w=function(a){if(a in r)return r[a];if(a in q)return r[a]=b.Deferred().resolve(q[a]).promise(),r[a];var c=h.get("core_template/"+a);return c?(q[a]=c,r[a]=b.Deferred().resolve(c).promise(),r[a]):null},x=function(){if(u.length&&!v){v=!0;var a=u.slice(),e=b.Deferred(),f=[],g=a.map(function(a){var c=a.component,i=a.name,j=a.searchKey,k=a.theme,l=a.deferred,m=null,n=w(j);if(n)m=n;else{f.push({methodname:"core_output_load_template_with_dependencies",args:{component:c,template:i,themename:k,lang:b("html").attr("lang").replace(/-/g,"_")}});var o=f.length-1;m=e.promise().then(function(a){return g[j]=a[o].then(function(a){var b=null;return a.templates.forEach(function(a){var d=[k,a.component,a.name].join("/");q[d]=a.value,h.set("core_template/"+d,a.value),a.component==c&&a.name==i&&(b=a.value)}),a.strings.length&&d.cache_strings(a.strings.map(function(a){return{component:a.component,key:a.name,value:a.value}})),b}),g[j]})}return m.then(function(a){return l.resolve(a)})["catch"](function(a){throw l.reject(a),a})});f.length?e.resolve(c.call(f,!0,!1)):e.resolve(),b.when.apply(null,g).then(function(){u.splice(0,a.length),v=!1,x()})["catch"](function(){u.splice(0,a.length),v=!1,x()})}},y=function(){this.requiredStrings=[],this.requiredJS=[],this.requiredDates=[],this.currentThemeName=""};y.prototype.requiredStrings=null,y.prototype.requiredDates=[],y.prototype.requiredJS=null,y.prototype.currentThemeName="",y.prototype.getTemplate=function(a){var c=this.currentThemeName,d=c+"/"+a,e=w(d);if(e)return e;var f=u.filter(function(a){return a.searchKey==d});if(f.length)return f[0].deferred.promise();var g=a.split("/"),h=g.shift(),i=g.shift(),j=b.Deferred();return u.push({component:h,name:i,theme:c,searchKey:d,deferred:j}),x(),j.promise()},y.prototype.partialHelper=function(a){var b=this.currentThemeName+"/"+a;return b in q||e.exception(new Error("Failed to pre-fetch the template: "+a)),q[b]},y.prototype.renderIcon=function(a,c,d){var f=g.iconsystemmodule,h=b.Deferred();return require([f],function(a){var b=new a;b instanceof i?(t=b,b.init().then(h.resolve)["catch"](e.exception)):h.reject("Invalid icon system specified"+g.iconsystemmodule)}),h.then(function(a){return this.getTemplate(a.getTemplateName())}.bind(this)).then(function(b){return t.renderIcon(a,c,d,b)})},y.prototype.pixHelper=function(a,b,c){var d=b.split(","),e="",f="",g="";d.length>0&&(e=c(d.shift().trim(),a)),d.length>0&&(f=c(d.shift().trim(),a)),d.length>0&&(g=c(d.join(",").trim(),a));var h=t.getTemplateName(),i=this.currentThemeName+"/"+h,j=q[i];return e=e.replace(///gi,"/"),t.renderIcon(e,f,g,j)},y.prototype.jsHelper=function(a,b,c){return this.requiredJS.push(c(b,a)),""},y.prototype.stringHelper=function(a,b,c){var d=b.split(","),e="",f="",g="";d.length>0&&(e=d.shift().trim()),d.length>0&&(f=d.shift().trim()),d.length>0&&(g=d.join(",").trim()),""!==g&&(g=c(g,a)),0===g.indexOf("{")&&0!==g.indexOf("{{")&&(g=JSON.parse(g));var h=this.requiredStrings.length;return this.requiredStrings.push({key:e,component:f,param:g}),"[[_s"+h+"]]"},y.prototype.quoteHelper=function(a,b,c){var d=c(b.trim(),a);return d=d.replace('"','\\"').replace(/([\{\}]{2,3})/g,"{{=<% %>=}}$1<%={{ }}=%>"),'"'+d+'"'},y.prototype.shortenTextHelper=function(a,b,c){var d=/(.*?),(.*)/,e=b.match(d),f=e[1].trim(),g=e[2].trim(),h=c(g,a);return m.truncate(h,{length:f,words:!0,ellipsis:"..."})},y.prototype.userDateHelper=function(a,b,c){var d=/(.*?),(.*)/,e=b.match(d),f=c(e[1].trim(),a),g=c(e[2].trim(),a),h=this.requiredDates.length;return this.requiredDates.push({timestamp:f,format:g}),"[[_t_"+h+"]]"},y.prototype.addHelpers=function(a,b){this.currentThemeName=b,this.requiredStrings=[],this.requiredJS=[],a.uniqid=p++,a.str=function(){return this.stringHelper.bind(this,a)}.bind(this),a.pix=function(){return this.pixHelper.bind(this,a)}.bind(this),a.js=function(){return this.jsHelper.bind(this,a)}.bind(this),a.quote=function(){return this.quoteHelper.bind(this,a)}.bind(this),a.shortentext=function(){return this.shortenTextHelper.bind(this,a)}.bind(this),a.userdate=function(){return this.userDateHelper.bind(this,a)}.bind(this),a.globals={config:g},a.currentTheme=b},y.prototype.getJS=function(){var a="";return this.requiredJS.length>0&&(a=this.requiredJS.join(";\n")),a},y.prototype.treatStringsInContent=function(a,b){var c,d,e,f,g,h,i=/\[\[_s\d+\]\]/;do{for(c="",d=a.search(i);d>-1;){c+=a.substring(0,d),a=a.substr(d),e="",f=4,g=a.substr(f,1);do e+=g,f++,g=a.substr(f,1);while("]"!=g);h=b[parseInt(e,10)],"undefined"==typeof h&&(l.debug("Could not find string for pattern [[_s"+e+"]]."),h=""),c+=h,a=a.substr(6+e.length),d=a.search(i)}a=c+a,d=a.search(i)}while(d>-1);return a},y.prototype.treatDatesInContent=function(a,b){return b.forEach(function(b,c){var d="\\[\\[_t_"+c+"\\]\\]",e=new RegExp(d,"g");a=a.replace(e,b)}),a},y.prototype.doRender=function(c,e,f){this.currentThemeName=f;var g=t.getTemplateName(),h=new o("core/templates:doRender");return this.getTemplate(g).then(function(){this.addHelpers(e,f);var d=a.render(c,e,this.partialHelper.bind(this));return b.Deferred().resolve(d.trim(),this.getJS()).promise()}.bind(this)).then(function(a,c){return this.requiredStrings.length>0?d.get_strings(this.requiredStrings).then(function(d){return this.requiredDates=this.requiredDates.map(function(a){return{timestamp:this.treatStringsInContent(a.timestamp,d),format:this.treatStringsInContent(a.format,d)}}.bind(this)),a=this.treatStringsInContent(a,d),c=this.treatStringsInContent(c,d),b.Deferred().resolve(a,c).promise()}.bind(this)):b.Deferred().resolve(a,c).promise()}.bind(this)).then(function(a,c){return this.requiredDates.length>0?n.get(this.requiredDates).then(function(d){return a=this.treatDatesInContent(a,d),c=this.treatDatesInContent(c,d),b.Deferred().resolve(a,c).promise()}.bind(this)):b.Deferred().resolve(a,c).promise()}.bind(this)).then(function(a,c){return h.resolve(),b.Deferred().resolve(a,c).promise()})};var z=function(a){if(""!==a.trim()){var c=b("