Compare commits

..

309 Commits

Author SHA1 Message Date
Jun Pataleta 4b69c11978 Moodle release 4.1.1 2023-01-14 14:17:03 +08:00
Jun Pataleta 2d628ba8d6 weekly release 4.1+ 2023-01-13 10:52:14 +08:00
Andrew Nicols 3528887bb6 Merge branch 'MDL-76820-401' of https://github.com/cameron1729/moodle into MOODLE_401_STABLE 2023-01-12 12:09:35 +08:00
Jun Pataleta 217a32f033 Merge branch 'MDL-76649_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-01-12 12:06:45 +08:00
Jun Pataleta d24c201b6d Merge branch 'MDL-76474-401-2' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2023-01-12 11:55:41 +08:00
Huong Nguyen 4d9960ace2 MDL-76474 tiny_h5p: Prevent H5P Formatter placeholder to be assessed 2023-01-12 10:53:06 +07:00
Huong Nguyen 4e1c4f4483 MDL-76474 tiny_accessibilitychecker: Prevent placeholders to be assessed 2023-01-12 10:53:04 +07:00
Huong Nguyen b4e7d5300a MDL-76474 editor_tiny: Implement placeholder selector list
We created a list of placeholder selectors in placeholderSelectors option.
The purpose of this list is to indicate the contents that are only shown
in the editor and not to the users, by that way, we can decide to apply or
not to apply rules, styles, etc... to these contents
2023-01-12 10:52:39 +07:00
Michael Hawkins 313d44f83a MDL-76861 blog: Ensure correct escaping applied to search string 2023-01-12 11:43:11 +08:00
Jake Dallimore 6a6f5b79dd MDL-76862 user: Unit test for setting user home page preferences 2023-01-12 11:35:26 +08:00
Paul Holden f3c335b376 MDL-76862 user: ensure user can only update own preferred start page. 2023-01-12 11:35:26 +08:00
Andrew Nicols 5eb91a54c3 Merge branch 'MDL-76839-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-12 10:57:01 +08:00
Cameron Ball 1e72ef978a MDL-76820 core_search: Reset manager::$coursedeleting between tests 2023-01-12 10:54:44 +08:00
Jun Pataleta 28ccae3b7a Merge branch 'MDL-76739-401' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-01-12 10:17:37 +08:00
Jun Pataleta f06b222aa8 MDL-76739 behat: Replace occurrences of "surname" in Behat tests
Replace occurrences of "surname" in Behat tests with "last name"
2023-01-12 09:52:48 +08:00
Ilya Tregubov a4aeb20a30 Merge branch 'MDL-76607-401' of https://github.com/davewoloszyn/moodle into MOODLE_401_STABLE 2023-01-11 19:16:29 +07:00
Andrew Nicols b50964d2e2 Merge branch '66924-view-own-private-reply-401' of https://github.com/DSI-Universite-Rennes2/moodle into MOODLE_401_STABLE 2023-01-11 15:53:27 +08:00
Tim Hunt 2ea89b98a7 MDL-76810 redirect handling: ensure return URLs are properly sanitised 2023-01-11 11:43:12 +08:00
Andrew Nicols 833bc53bbb Merge branch 'MDL-76356_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2023-01-11 10:30:25 +08:00
Jake Dallimore 5123d2bf53 Merge branch 'MDL-76597-401-2' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-01-11 10:12:08 +08:00
David Mudrák acd82d3a86 MDL-76739 lang: Use the fixed strings in the tests, too 2023-01-10 21:15:06 +01:00
Helen Foster 152bbd76c5 MDL-76739 lang: Import fixed English strings (en_fix) 2023-01-10 21:13:14 +01:00
Paul Holden 02df248fbd Merge branch 'MDL-76811-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-01-10 16:40:06 +00:00
Paul Holden f5844e80fd Merge branch 'MDL-76803-401' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-01-10 16:24:16 +00:00
Paul Holden a789bf5b24 Merge branch 'MDL-76653-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-01-10 15:29:16 +00:00
Marina Glancy ff5fc3820a MDL-76356 various: avoid implicit conversion to int
PHP before version 8.1 automatically converted to int if the function
parameter (or array key) is expected to be int. PHP 8.1 shows notice in
this case
2023-01-10 15:25:57 +01:00
Marina Glancy 66dcb1683b MDL-76356 various: avoid implicit conversion to arrays
PHP before version 8.1 automatically converted stdClass or 'false' to arrays if
function parameter expects array (for example, "reset").
PHP 8.1 shows notices in these situations
2023-01-10 15:03:40 +01:00
Paul Holden 9cdafb6cad MDL-76839 mod_data: correct external test class coverage notation. 2023-01-10 13:02:29 +00:00
Paul Holden 89c59f32cf Merge branch 'MDL-76833-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-01-10 12:29:14 +00:00
Jun Pataleta 8280476728 MDL-76803 lang: Update usages of reworded email display options 2023-01-10 16:01:44 +08:00
Jun Pataleta 4fc9c3bba1 MDL-76803 lang: Make email display options more concise 2023-01-10 16:01:44 +08:00
Andrew Nicols 74f1a285a1 MDL-76833 core: Bump phpunit/php-code-coverage version
This includes a bug fix for a display issue with code coverage reporting
in phpunit's HTML output report.
2023-01-10 12:09:01 +08:00
Andrew Nicols d9ae9e51cd MDL-76811 mod_data: Remove duplicate tests 2023-01-10 11:39:40 +08:00
Andrew Nicols cd42aa554f MDL-76811 mod_data: Stop testing template creation on field creation
The default template is no longer created when creating the fields with
the generator, so we should stop testing that it is.
2023-01-10 11:39:40 +08:00
Andrew Nicols e8ea4916e9 MDL-76811 mod_data: Generator test cleanup 2023-01-10 11:39:40 +08:00
Simey Lameze d1f75e4dce MDL-76653 behat: add coverage for SCORM availability 2023-01-10 10:26:04 +08:00
Jun Pataleta 1b54b120ad Merge branch 'MDL-76061-MOODLE_401_STABLE' of https://github.com/PhMemmel/moodle into MOODLE_401_STABLE 2023-01-10 09:41:46 +08:00
Philipp Memmel 3c5413f02a MDL-76061 core_calendar: Fix changing event type from 'user' 2023-01-09 15:03:15 +01:00
Julien Boulen 4ea254faf2 MDL-66924 mod_forum: Allow users to see their own private messages
Allow users to see their own private messages even if they don't have
mod/forum:readprivatereplies capability

Add behat test to avoid MDL-67109 issue.

Co-authored-by: Martin Putzlocher <mputzi@users.noreply.github.com>
2023-01-09 14:43:51 +01:00
Tim Hunt d71ada1952 MDL-76649 quiz statistics task: output more useful trace info
At the moment, quiz_statistics\task\recalculate gives no useful
information about what it is doing, which makes it hard to investigate
if the task fails. This commit makes it more usefully verbose.

Also, following this change, one instance of this task will not
run for more than one hour at a time.

As part of this commit, I have added a new helper mtrace_exception.
to consistently log exceptions in scheduled tasks. It is sad to
add a new function to moodlelib.php, but that seemed the logical place.
Looking at other tasks, this method is badly needed. Many are just
logging the ->getMessage() which is normaly insufficient for proper
debugging. However, swiching all existing tasks to use the new function
will need to wait for a future MDL.
2023-01-09 13:34:14 +00:00
Paul Holden 29efbedc8b Merge branch 'MDL-75532-401' of https://github.com/snake/moodle into MOODLE_401_STABLE 2023-01-09 11:50:59 +00:00
Jun Pataleta 8ea2421cd4 Merge branch 'MDL-76785-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-09 19:38:42 +08:00
Jun Pataleta 1361e6ad92 Merge branch 'MDL-76506_m41' of https://github.com/jrchamp/moodle into MOODLE_401_STABLE 2023-01-09 19:33:59 +08:00
Paul Holden 3387060fe1 MDL-76785 tiny_media: define video width/height language strings.
AMOS BEGIN
 CPY [videoheight,atto_media],[videoheight,tiny_media]
 CPY [videowidth,atto_media],[videowidth,tiny_media]
AMOS END
2023-01-09 10:52:18 +00:00
Jun Pataleta 5d27f595d7 Merge branch 'MDL-76787-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-09 18:38:55 +08:00
Paul Holden 6f2d09dc5a Merge branch 'MDL-76601-401' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-01-09 10:11:10 +00:00
Jun Pataleta e101b6f195 Merge branch 'MDL-76812-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-09 17:46:13 +08:00
Jun Pataleta 934d8a2866 MDL-76597 mod_quiz: Add a default heading name for Behat tests 2023-01-09 15:41:59 +08:00
Jun Pataleta 6a7668e350 MDL-76597 mod_quiz: Set presentation role for the question list
Since the <ul> and <li> elements for listing the quiz questions and
elements are mainly used for layout purposes, it is better to set the
role of these elements to presentation only.
The aria-label for the <li> element is inappropriate and can also cause
confusion to screen reader users. Better to remove this. Though this is
being used in the confirmation modal so better to just change it to a
data attribute.
2023-01-09 15:41:59 +08:00
Jun Pataleta d2bacb04ff MDL-76597 mod_quiz: Set presentation role for the question list
Since the <ul> and <li> elements for listing the quiz questions and
elements are mainly used for layout purposes, it is better to set the
role of these elements to presentation only.
2023-01-09 15:41:59 +08:00
Jun Pataleta 77a0f1b129 MDL-76597 mod_quiz: Add label for question checkboxes 2023-01-09 15:41:59 +08:00
Jun Pataleta ca841d1489 MDL-76597 mod_quiz: Darken section heading on quiz questions page 2023-01-09 15:41:59 +08:00
Jun Pataleta c2216eefa6 MDL-76597 mod_quiz: Add label for version selector 2023-01-09 15:41:59 +08:00
Jun Pataleta 241da816db MDL-76597 mod_quiz: Add a default sr-only section heading
Add a default sr-only section heading in order to prevent having an
empty heading for the quiz section which is not good for accessibility.

Plus:
- There's also an existing issue where filters are never applied to
section headings on load. This has been fixed in this commit as well.
- Button role added for the edit section button which enables it to
take advantage of the theme highlighting when it receives focus.
2023-01-09 15:41:59 +08:00
Jake Dallimore 18302e1244 MDL-75532 enrol_lti: fix optional lineitemsurl in grade sync task
As in MDL-74691, we need either or both of these fields, meaning either
one could be omitted. This just supports that as per the fix made in
MDL-74691.
2023-01-09 11:39:17 +08:00
Jake Dallimore 2080ba7c83 MDL-75532 enrol_lti: add tests for coupled and decoupled line items
This covers the following cases:
1. Where only the 'lineitem' service endpoint is provided
2. Where only the 'lineitems' service endpoint is provided.
Existing tests already cover the case where both are provided.
2023-01-09 11:39:09 +08:00
Paul Holden b99d68087d Merge branch 'MDL-32114-401' of https://github.com/srobotta/moodle into MOODLE_401_STABLE 2023-01-06 11:20:47 +00:00
Paul Holden 93d95cf1fe Merge branch 'MDL-76578-401' of https://github.com/aanabit/moodle into MOODLE_401_STABLE 2023-01-06 10:41:36 +00:00
Paul Holden 13a6018b6d Merge branch 'MDL-76781-401' of https://github.com/lucaboesch/moodle into MOODLE_401_STABLE 2023-01-06 10:23:55 +00:00
Paul Holden ee507d22ec MDL-76812 reportbuilder: ensure audience key is incremented correctly. 2023-01-06 09:58:05 +00:00
Ilya Tregubov 145317b2b3 MDL-76251 mod_forum: Fix illegal whitespace. Another try. 2023-01-06 16:41:25 +07:00
Ilya Tregubov c3fdfc996c Merge branch 'MDL-76251-patch-401' of https://github.com/ilyatregubov/moodle into MOODLE_401_STABLE 2023-01-06 16:14:38 +07:00
Ilya Tregubov 6ee2865fcc MDL-76251 mod_forum: Fix illegal whitespace. 2023-01-06 16:11:51 +07:00
Ilya Tregubov 4943d24d50 Merge branch 'MDL-76251-401' of https://github.com/aya-saad1/moodle into MOODLE_401_STABLE 2023-01-06 15:37:55 +07:00
Stephan Robotta 64b8061180 MDL-32114 form: markdown must be preserved on saving post
- Markdown is saved to the DB, no conversion to HTML to keep
  ability to reedit the content without beaking it.
- Blockquote element is styled that it's distingishable from
  normal text.
2023-01-05 18:36:16 +01:00
Andrew Nicols b24414554f Merge branch 'MDL-76508-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2023-01-05 21:30:22 +08:00
Luca Bösch 325ca6568b MDL-76781 gradebook: support multilingual group names. 2023-01-05 13:27:02 +01:00
Paul Holden cd072308e5 weekly release 4.1+ 2023-01-05 10:53:10 +00:00
Aya Saad 3e0ad5831a MDL-76251 mod_forum: fix responsive issues in discussion 2023-01-05 11:41:19 +02:00
David Woloszyn a5430f1022 MDL-76607 timeline: Reordered message to account for long course name 2023-01-05 12:13:50 +11:00
David Woloszyn 46fca91bc4 MDL-76607 css: Fixed various classes where long strings break layout 2023-01-05 12:13:49 +11:00
Paul Holden f8b463e394 MDL-76787 tiny_h5p: correct capability for plugin enabled state. 2023-01-04 16:07:47 +00:00
Sara Arjona 717e049627 Merge branch 'MDL-76375-401' of https://github.com/lucaboesch/moodle into MOODLE_401_STABLE 2023-01-04 16:21:42 +01:00
Luca Bösch 6e286481e0 MDL-76375 quiz generator: Allow more than one attempt by Behat tests. 2023-01-04 15:15:46 +01:00
Sara Arjona 1cf0f78b9a Merge branch 'MDL-76221-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-04 13:09:18 +01:00
Paul Holden d95ab775ac MDL-76657 grade: load required test libraries for grade helper. 2023-01-04 11:22:42 +00:00
Paul Holden 56a3828cf7 Merge branch 'MDL-76657-401' of https://github.com/rezaies/moodle into MOODLE_401_STABLE 2023-01-04 11:10:39 +00:00
Paul Holden 4ecd652189 MDL-76221 reportbuilder: improve report test generator methods.
Test generators for creating report columns, filters and conditions
now allow for setting all persistent properties.
2023-01-04 10:56:23 +00:00
Jun Pataleta 9c4b8bf7e8 Merge branch 'MDL-74822-401' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2023-01-04 17:29:21 +08:00
Jun Pataleta c380811bb2 MDL-76601 block_myoverview: Remove hover action before clicking on menu
With the course card menu now always displayed, there's no need to hover
first before clicking on the menus on block_myoverview Behat tests.
2023-01-04 17:22:38 +08:00
Jun Pataleta 3e175706ff MDL-76601 blocks: Always display course card menus
Displaying the course card menu only on hover is bad in terms of
accessibility as it prevents keyboard-only users from accessing the
menu. So it's better to always display them.
2023-01-04 17:22:38 +08:00
Sara Arjona db3bc708c4 Merge branch 'MDL-76181-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-04 09:20:19 +01:00
Sara Arjona 87b3be343e Merge branch 'MDL-76308-401' of https://github.com/BruceGoodGuy/moodle into MOODLE_401_STABLE 2023-01-03 14:13:00 +01:00
Paul Holden a25f2d0d7e Merge branch 'MDL-53137-401' of https://github.com/lucisgit/moodle into MOODLE_401_STABLE 2023-01-03 12:14:36 +00:00
Sara Arjona 0eb65f27ba Merge branch 'MDL-71506-401' of https://github.com/lucaboesch/moodle into MOODLE_401_STABLE 2023-01-03 13:10:17 +01:00
Paul Holden a4dfd67aed Merge branch 'MDL-75346-reset_dashboard_error-401' of https://github.com/leonstr/moodle into MOODLE_401_STABLE 2023-01-03 11:28:28 +00:00
Shamim Rezaie 3a5820f3c4 MDL-76657 gradebook: Remove hard-coded plugin names from unit test 2023-01-03 20:23:48 +11:00
Andrew Nicols a9abcf1af7 MDL-32105 mod_glossary: Improve behat test 2023-01-03 15:32:12 +08:00
Andrew Nicols 72f4f8ec7c Merge branch 'MDL-32105-401' of https://github.com/Chocolate-lightning/moodle into MOODLE_401_STABLE 2023-01-03 15:32:04 +08:00
Peter 9fd77db89a MDL-32105 mod_glossary: Restrict glossary aliases by set of keywords 2023-01-03 13:50:19 +08:00
Huong Nguyen c6a1770682 MDL-74822 usertours: Fix accessibility issues with user tours
Including in this commit:
 - Prevent the tour to be displayed if the CSS is disabled by the browser
 - Removed redundant tabindex=0 attribute on the target
 - Created extra code to re-calculate the suitable position of the tour
 - Fixed tour issue in 200% and 400% zoom
 - Fixed tour highlight is not correct in 200% and 400%
2023-01-03 10:35:24 +07:00
Sara Arjona 3e4ba8af5c Merge branch 'MDL-60038-401' of https://github.com/aneno-m-e/moodle into MOODLE_401_STABLE 2023-01-02 16:35:23 +01:00
Luca Bösch dcb0de7c92 MDL-71506 mod_choice: suppress non respondents in downloads if set so. 2023-01-02 15:53:20 +01:00
Sara Arjona e2c8f3db7c Merge branch 'MDL-76106-401' of https://github.com/NashTechOpenUniversity/moodle into MOODLE_401_STABLE 2023-01-02 13:07:39 +01:00
Sara Arjona b7b2097f50 Merge branch 'MDL-76760-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-02 12:27:40 +01:00
Paul Holden 0dbc7187ff MDL-76181 reportbuilder: sort columns during stress testing. 2022-12-29 13:57:37 +00:00
Sara Arjona 7e1aa845c7 weekly release 4.1+ 2022-12-29 12:57:44 +01:00
Sara Arjona 810cffb702 Merge branch 'MDL-76399-patch-401' of https://github.com/ilyatregubov/moodle into MOODLE_401_STABLE 2022-12-29 09:13:32 +01:00
Ilya Tregubov 5271bd9237 MDL-76399 behat: switch to appropriate Behat step for selects. 2022-12-29 14:53:16 +07:00
Ilya Tregubov f84d8e3c37 Merge branch 'MDL-76399-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-29 09:43:28 +07:00
Sara Arjona a3a3fd451c Merge branch 'MDL-76004-401' of https://github.com/aanabit/moodle into MOODLE_401_STABLE 2022-12-28 18:22:35 +01:00
Sara Arjona 52d5ebbb21 Merge branch 'MDL-72523-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-28 13:01:39 +01:00
Sara Arjona c72b7b7edc Merge branch 'MDL-76617_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2022-12-28 12:42:21 +01:00
Paul Holden c4960a2adf MDL-72523 calendar: return original focus from event modals. 2022-12-28 11:14:44 +00:00
Huong Nguyen 510bf00643 MDL-72523 javascript: Introduce setReturnElement for core/modal 2022-12-28 11:14:44 +00:00
Sara Arjona d3fca5e689 Merge branch 'MDL-72563-401' of https://github.com/KepaUrzelai/moodle into MOODLE_401_STABLE 2022-12-28 12:13:16 +01:00
Sara Arjona 1be732e913 Merge branch 'MDL-69071-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-28 11:41:11 +01:00
Paul Holden d2f55155a8 MDL-76760 tool_behat: defer library loading until service execution.
Ensures that API documentation can be generated without requiring
the presence of the `vendor/` directory.
2022-12-28 10:39:48 +00:00
Sara Arjona 430c7ff4e7 Merge branch 'MDL-76734-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2022-12-28 10:04:31 +01:00
Ilya Tregubov 181cab2fbd Merge branch 'MDL-76731_401' of https://github.com/PhilippImhof/moodle into MOODLE_401_STABLE 2022-12-28 15:14:07 +07:00
Sara Arjona f4f0207693 Merge branch 'MDL-76679-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-27 16:55:25 +01:00
Amaia Anabitarte ad8a10e7b6 MDL-76578 core_course: One section per page summary information 2022-12-26 16:03:34 +01:00
Meirza 9d822d41d8 MDL-76508 templates: Handling non-JSON string
When the param string contains a left curly bracket as the first character,
the system will assume the string is a JSON string and will be parsed and returned as an object.
But in some cases, the string is not JSON and will return an error if the system parses it.
For example, a user might have used the course name with a left curly bracket as the first character.
Adding a double quote after the left curly bracket to differentiate between string and JSON string,
so it can be safe to parse the string.
2022-12-24 05:50:56 +07:00
Noemie Ariste e89ed4b463 MDL-60038 moodlelib: ignore site policy if user auth type = 'webservice' 2022-12-23 10:09:09 +13:00
Eloy Lafuente (stronk7) 5db1ac4e98 MDL-76617 store_mongodb: Adjust moodle to mongo-php-library to v1.15.0
The new library version should work without problems with older
php-mongodb extension versions:
- v1.15.0 (paired version, tested).
- v1.14.1 (tested)

So, here, in 401_STABLE, we aren't raising the requirements. We have
done that in master, in order to get php82 support, but not here. For
more details about compatibilities, see:

https://www.mongodb.com/docs/drivers/php/#compatibility
2022-12-22 19:36:40 +01:00
Eloy Lafuente (stronk7) c22b39a650 MDL-76617 store_mongodb: Update mongo-php-library to v1.15.0
This updates the library from v1.13.1. Fixes some php81 warnings
leading to failed/risky tests.

The new library version should work without problems with older
php-mongodb extension versions:
- v1.15.0 (paired version, tested).
- v1.14.1 (tested)
2022-12-22 19:36:40 +01:00
Philipp Imhof 9d64ad1416 MDL-76731 behat: add steps to check for version
Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
2022-12-22 17:12:47 +01:00
Tony Butler 11816b9e41 MDL-53137 qtype_numerical: Swap geo tolerance limits for -ve answers 2022-12-22 15:32:39 +00:00
Ilya Tregubov 178aa05227 weekly release 4.1+ 2022-12-22 19:16:29 +07:00
Ilya Tregubov 9f2e81004c Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2022-12-22 19:16:26 +07:00
Ilya Tregubov 0b7102abcc Merge branch 'MDL-76667-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-22 12:27:51 +07:00
Paul Holden fe16fea153 Merge branch 'MDL-75965-401' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2022-12-22 12:27:51 +07:00
Andrew Nicols 86f9ffc274 MDL-75105 tool_behat: Correct version number 2022-12-22 12:27:51 +07:00
Andrew Nicols a439461f03 MDL-75105 tool_behat: Coding style fixes 2022-12-22 12:27:51 +07:00
Andrew Nicols 5c15c1f211 Merge branch 'MDL-75105_401_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_401_STABLE 2022-12-22 12:27:51 +07:00
Paul Holden 86d02a9239 Merge branch 'MDL-75914-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2022-12-22 12:27:51 +07:00
AMOS bot 68706da86a Automatically generated installer lang files 2022-12-22 00:07:43 +00:00
Meirza 296fd70a2c MDL-75914 webservice: Added fake URL to avoid debugging output.
Webservice doesn't need to set the page URL. Hence,
any function that requires a page URL will raise debugging output.
The patch fixes it by adding a fake URL for the webservice.
The patch also removed assertDebuggingCalled because it is no longer needed.
2022-12-21 16:33:00 +07:00
Mark Johnson 0c448af668 MDL-75105 tool_behat: List available data generators
This will find all data generators that can be used in behat via the
'the following "something" exist:' step, and display them in a select
list on the step definitions page.

When a generator is selected, it will fetch the required fields for that
generator and display them on the page.
2022-12-21 08:38:28 +00:00
Huong Nguyen 1f7bb3a50d MDL-75965 question_multichoice: Misalignment of feedback icons 2022-12-21 14:15:42 +07:00
Andrew Nicols 744e1dbaea MDL-76734 editor_tiny: Listen to TinyMCE submit events
jQuery submit events do not trigger the native submit event, and
therefore the TinyMCE submit listener is not called. This means that the
tinymce.triggerSave() function is not called, and the editor content is
not saved.

To work around this, if there is a form for the Node that the editor is
attached to, the jQuery submit event is listened to and the save event
called.

Unfortunately it is not possible to use a global jQuery submit listener
added to the document to save all editors on the page.
In some cases, this is too late because the bubbling process means that
a child node consumer may attempt to consume the data before the
delegated handler is called for the document.
2022-12-21 13:03:14 +08:00
Ilya Tregubov 5b47024f13 Merge branch 'MDL-76727-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2022-12-21 09:50:18 +07:00
Paul Holden dcf4a4629b Merge branch 'MDL-75279-401' of https://github.com/spvickers/moodle into MOODLE_401_STABLE 2022-12-20 10:27:38 +00:00
Andrew Nicols bb7cce1e56 MDL-76727 core: Allow phpcs configuration to be overridden locally
This change reduces the priority of the shipped phpcs configuration to
allow for local overrides.

This is beneficial in several situations:
- when users wish to apply stricter or additional standards
- when the integration team wishes to trial new rules
2022-12-20 09:35:45 +08:00
Stephen Vickers 27cc23ca7a MDL-75279 mod_lti: Add username to NRPS response 2022-12-19 18:09:27 +00:00
Paul Holden e8123832fb Merge branch 'MDL-72906-401' of https://github.com/tdjones/moodle into MOODLE_401_STABLE 2022-12-19 10:23:10 +00:00
Ilya Tregubov 6b47dc3b29 Merge branch 'MDL-74779-401' of https://github.com/ssj365/moodle into MOODLE_401_STABLE 2022-12-19 09:44:48 +07:00
Leon Stringer a77b23cdb7 MDL-75346 core_my: Handle missing blocks on reset
If the default dashboard contained a block that was missing from disk
then "Exception - Call to a member function instance_copy() on bool"
was shown to users.  This change only shows an error with debugging
enabled which now includes the name of the missing block.
2022-12-17 17:39:44 +00:00
Paul Holden 7708594e89 MDL-76399 question: switch to appropriate Behat step for selects. 2022-12-16 13:09:46 +00:00
Paul Holden 1dda343f05 MDL-76399 behat: improvements to "should exist in" thrown exception. 2022-12-16 12:29:57 +00:00
Paul Holden 4f19d454ea Merge branch 'MDL-76026_401' of https://github.com/AnupamaSarjoshi/moodle into MOODLE_401_STABLE 2022-12-16 09:54:15 +00:00
Andrew Nicols 24c009f222 weekly release 4.1+ 2022-12-16 09:05:52 +08:00
Andrew Nicols 5556693437 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2022-12-16 09:05:50 +08:00
Paul Holden b874e20b55 MDL-69071 core: retrieve full result from remote content.
Use the full result from download_file_content within the component
installer to ensure that spurious debugging is not emitted during
operation. Handle validation of the returned data consistently.
2022-12-15 17:19:17 +00:00
Paul Holden 06383b0b8a MDL-76679 admin: correct password config field template.
The template changes were missed as part of 0795b579, update them
to match so that they continue to work with the unmask JS module.
2022-12-14 19:12:05 +00:00
Sara Arjona 4979a5e988 Merge branch 'MDL-76674_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2022-12-14 18:34:50 +01:00
Amaia Anabitarte 76ce30ca98 MDL-76004 core_h5p: Ensure the browser is serving updated file 2022-12-14 16:22:46 +01:00
Eloy Lafuente (stronk7) 1e54868139 MDL-76674 core_lang: Add string for new America/Ciudad_Juarez 2022-12-14 15:51:10 +01:00
Paul Holden a33d1c8903 Merge branch 'MDL-76666_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2022-12-14 13:22:03 +00:00
Eloy Lafuente (stronk7) c5213c103b MDL-76666 local_langimport: Better handling of long locales
Under some linux versions, and depending of the configured
locale categories, it's possible to get a current locally
which length > 255 when calling to setlocale(LC_ALL, 0).

Later, if that long locale is tried to be restored, there
is a "setlocale(): Specified locale name is too long" warning
error.

When that happens we need to split the long locale into
individual chunks and set all the (six) locale categories
supported one by one.

Covered with tests, note that, in practice, this only
happens with linux because it supports 12 locale categories
@ OS level. Both BSD (6) and Windows (5) hardly can reach the limit.

No matter of that, the tests have been designed to ensure that
they pass on all OSs, just the new code only will be executed
on linux.
2022-12-14 12:25:17 +01:00
Sara Arjona 4ce5c57547 Merge branch 'MDL-75441-401' of https://github.com/aanabit/moodle into MOODLE_401_STABLE 2022-12-14 09:57:12 +01:00
AMOS bot 7496e9df75 Automatically generated installer lang files 2022-12-14 00:07:43 +00:00
Anupama Sarjoshi fe094a3705 MDL-76026 Question bank: Fix errors related to categories renaming
This part of the code in 'question_category_object.php' 'update_category' method was used before Moodle 4.0 version for renaming
the random questions in an updated category. For Moodle 4.1, it is unnecessary as the details of random questions are no more
stored in 'question' table but in 'question_set_references' table. The method call move_question_set_references handles the same.
2022-12-13 18:01:24 +00:00
Amaia Anabitarte 93bd773ee9 MDL-75441 mod_forum: Show add new post button to guest users 2022-12-13 17:38:30 +01:00
Paul Holden 0d20d1e8aa MDL-76667 forms: mark modal form as submitted upon success.
Ensure the form change checker module doesn't warn user about it.
2022-12-13 14:48:10 +00:00
Andrew Nicols 361ebe960b Merge branch 'MDL-76509-401' of https://github.com/safatshahin/moodle into MOODLE_401_STABLE 2022-12-13 20:31:35 +08:00
Andrew Nicols 0d5d3a0c49 Merge branch 'MDL-76536-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-13 11:42:35 +08:00
Andrew Nicols 4d94f7e677 MDL-76293 gradebook: Address coding violations
This includes a data provider which had the 'test_' prefix and was
therefore run as a test.
2022-12-13 11:07:02 +08:00
Andrew Nicols 6f68abf715 Merge branch 'MDL-76293_401' of https://github.com/mkassaei/moodle into MOODLE_401_STABLE 2022-12-13 11:06:59 +08:00
Safat ac21fa9a1c MDL-76509 core: Upgrade error resolve for slot tags 2022-12-13 13:39:02 +11:00
Shamiso.Jaravaza f954848667 MDL-74779 mod_bigbluebuttonbn: Fix recording sort
AMOS BEGIN
 MOV [config_recordings_sortorder,mod_bigbluebuttonbn],[config_recordings_asc_sort,mod_bigbluebuttonbn]
 MOV [config_recordings_sortorder_description,mod_bigbluebuttonbn],[config_recordings_asc_sort_description,mod_bigbluebuttonbn]
AMOS END
2022-12-12 13:33:22 -07:00
hieuvu a42c52bf4e MDL-76106 qtype_ddmarker: fix the missing maker issue.
We will not calculate old maker position again and using old data.
This will make sure the position of makers is correct
when the background image is smaller than dropzone.
2022-12-12 20:31:24 +07:00
Sara Arjona 987542f609 Merge branch 'MDL-75571-401' of https://github.com/jacdsouza/moodle into MOODLE_401_STABLE 2022-12-12 11:23:18 +01:00
Khoa Nguyen Dang 959b58e132 MDL-76308 Question\D&D: The draggable area is slim characters to select 2022-12-12 13:53:57 +07:00
Andrew Nicols be5cf43aa4 Merge branch 'MDL-76398-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-11 20:20:19 +08:00
Jackson D'souza de182b9a22 MDL-75571 tool_componentlibrary: Custom activity icon 2022-12-09 15:56:07 +00:00
Jackson D'souza c48f443c32 MDL-75571 theme_boost: Activity icon
* Use Activity get_icon_url helper method to fetch icon.
2022-12-09 15:56:07 +00:00
Jackson D'souza fc67298a27 MDL-75571 block_timeline: Display custom activity icon if available. 2022-12-09 15:56:07 +00:00
Jackson D'souza c3db3298dd MDL-75571 calendar: Activity icon
* Use Activity get_icon_url helper method to fetch icon.
2022-12-09 15:56:07 +00:00
Sara Arjona 6bb2b9aa69 Merge branch 'MDL-76274-401' of https://github.com/cameron1729/moodle into MOODLE_401_STABLE 2022-12-09 16:18:08 +01:00
Paul Holden 187a7f7ac5 MDL-76536 enrol: prevent invalid role assignments in course creation.
Upgrade step to fixup existing bad data.
2022-12-09 11:39:19 +00:00
Sara Arjona 6b24f59302 weekly release 4.1+ 2022-12-09 08:56:58 +01:00
Sara Arjona 797a20a597 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2022-12-09 08:56:55 +01:00
Jun Pataleta 7a1e9ad82c Merge branch 'MDL-76556-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2022-12-08 10:07:47 +08:00
Andrew Nicols bd40bc0341 Merge branch 'MDL-76491-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-08 08:10:44 +08:00
AMOS bot 398fc9b0d3 Automatically generated installer lang files 2022-12-08 00:07:41 +00:00
Andrew Nicols 2a69a46a71 Merge branch 'MDL-76550_401' of https://github.com/AnupamaSarjoshi/moodle into MOODLE_401_STABLE 2022-12-08 08:06:49 +08:00
Andrew Nicols 41b48aeea5 Merge branch 'MDL-76074-401' of https://github.com/srobotta/moodle into MOODLE_401_STABLE 2022-12-08 07:28:45 +08:00
Andrew Nicols 3a544f384b Merge branch 'MDL-76116-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2022-12-08 06:17:10 +08:00
Sara Arjona d8f2ead786 Merge branch 'MDL-75588-401' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2022-12-07 19:31:11 +01:00
Trevor Jones 50f06cb2be MDL-72906 Quiz: Prevent scrollbar on multichoice
Remove negative margin from the "clear my choice" anchor.
With the negative margin, when the containing box height is calculated
the anchor's hidden style overflows beyond the boundary and triggers
the overflow:auto to add a scroll bar.
2022-12-07 11:23:35 -07:00
Mahmoud Kassaei d4abc697b8 MDL-76293 Gradebook: PHPUnit fails when plugins are not expected 2022-12-07 17:41:19 +00:00
Sara Arjona 10c1a7de42 Merge branch 'MDL-76575-401' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2022-12-07 18:32:19 +01:00
Sara Arjona dc444f4634 Merge branch 'MDL-76500-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-07 18:27:53 +01:00
Sara Arjona 151de4586d Merge branch 'MDL-76193-401' of https://github.com/JBThong/moodle into MOODLE_401_STABLE 2022-12-07 17:26:22 +01:00
Sara Arjona 52890694bf Merge branch 'MDL-76571_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2022-12-07 17:17:41 +01:00
Tim Hunt 95f073453b MDL-76571 quiz reports: should not show description items
... or anything else with length = 0. This got broken in MDL-71696.

The only way to fix this kind-of involves and API change to
quiz_report_get_significant_questions. However, it is only changing
the external API of this function back to how it was before the 4.0 release,
and the chnages in 4.0 were never documented, nor, I would guess, intended,
since they just broke things.
2022-12-07 14:53:41 +00:00
Jun Pataleta 6661a3eb45 Merge branch 'MDL-76559-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2022-12-07 22:41:07 +08:00
Andrew Nicols 0f8f164a07 MDL-76559 core: validate_email does not take false either 2022-12-07 21:40:18 +08:00
Sara Arjona 4cc96c42fa Merge branch 'MDL-76273-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-07 12:51:37 +01:00
Huong Nguyen 208c9fb5af MDL-75588 assign: Reset completion status when resetting a submission 2022-12-07 16:16:01 +07:00
Huong Nguyen 8884da3d8b MDL-76575 tiny_media: Remove unnecessary console log 2022-12-07 15:50:40 +07:00
Jun Pataleta e0f34d5049 Merge branch 'MDL-73017-M401_add-environment-check-for-versions-not-supporting-php-8-1' of https://github.com/ziegenberg/moodle into MOODLE_401_STABLE 2022-12-07 13:47:12 +08:00
Meirza 09e171c522 MDL-76116 mnet: styling the delete key confirmation window properly 2022-12-07 11:26:26 +07:00
Jun Pataleta 4426e21204 Merge branch 'MDL-76559-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2022-12-06 23:19:37 +08:00
Andrew Nicols fb7d1b34ef MDL-76559 core: validate_email should not accept empty values 2022-12-06 20:53:47 +08:00
Jun Pataleta 32bb535cb6 Merge branch 'MDL-76476-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-06 19:41:17 +08:00
Jun Pataleta dd3b92545e Merge branch 'MDL-75381-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-06 19:24:34 +08:00
Ilya Tregubov e572943d21 Merge branch 'MDL-76490-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-06 13:09:38 +03:00
Paul Holden 2d2b2e3244 MDL-76500 grade: fix grade form when item cannot be overridden. 2022-12-06 09:20:01 +00:00
Ilya Tregubov e03c52acbe Merge branch 'MDL-76446-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-06 12:19:09 +03:00
Cameron Ball c503238978 MDL-76274 assignfeedback_editpdf: Fix upgrade step for stale conversions 2022-12-06 16:05:44 +08:00
Ilya Tregubov bc5c812db3 Merge branch 'MDL-75516_401' of https://github.com/larsbonczek/moodle into MOODLE_401_STABLE 2022-12-06 10:38:12 +03:00
Stephan Robotta d7734740b2 MDL-76074 completion: fixed filter in reports with custom user fields
When the site uses custom user text fields that would show up in a
user list, the filter for firstname or lastname didnt work anymore.
If a filter was used, no result would show up. Users where shown only
when the course reports where used without filters.
2022-12-06 08:24:46 +01:00
Andrew Nicols ba38d916be Merge branch 'MDL-75446-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2022-12-06 15:19:47 +08:00
Andrew Nicols e7c70fd2c0 Merge branch 'MDL-75573-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-06 13:55:58 +08:00
Andrew Nicols fa309d0650 Merge branch 'MDL-76145-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2022-12-06 13:36:16 +08:00
Paul Holden 1efd88b2c8 MDL-76273 core: multi-byte character filename support for TCPDF.
See: https://github.com/tecnickcom/TCPDF/pull/562
2022-12-05 15:04:23 +00:00
Paul Holden 20ac0d1626 MDL-76490 behat: use defined step for interaction with autocomplete. 2022-12-05 14:22:19 +00:00
Marina Glancy 40ee69ea8b MDL-76490 behat: correct step for opening autocomplete in container. 2022-12-05 14:21:53 +00:00
Anupama Sarjoshi 87d5f8eb0f MDL-76550 Quiz and qbank: Fix display of Category and question names 2022-12-05 12:19:14 +00:00
Sara Arjona 05c53f2c44 Merge branch 'MDL-75789-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-05 12:53:43 +01:00
Sara Arjona 1b9bcbf19d Merge branch 'MDL-76166-username-logging-MOODLE_401_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_401_STABLE 2022-12-05 12:44:23 +01:00
Ilya Tregubov a3ed6cea5f Merge branch 'MDL-75788-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2022-12-05 14:31:44 +03:00
Sara Arjona f2dd9867ab Merge branch 'MDL-76482-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2022-12-05 12:04:02 +01:00
Daniel Ziegenberg bbd49c9533 MDL-73017 env: Moodle 3.9.x, 3.11.x and 4.0.x do not support PHP 8.1
This commit adds an additional environment check for the unsupported
PHP 8.1 version to Moodle 3.9.x, 3.11.x and 4.0.x.

It also updates the lang string for unsupported PHP version.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2022-12-05 11:29:09 +01:00
Angelia Dela Cruz bc82295f6a MDL-75446 behat: Workshop behat generators use UI
Replace steps that manually add Workshop instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
2022-12-05 16:05:07 +08:00
Ilya Tregubov 2e1118fa62 Merge branch 'MDL-76330-MOODLE_401_STABLE' of https://github.com/sh-csg/moodle into MOODLE_401_STABLE 2022-12-05 09:22:05 +03:00
Ferran Recio 272a458099 MDL-76225 core_courseformat: fix section title id 2022-12-05 13:48:05 +08:00
Thong Bui 2370255e4c MDL-76193 Questions: Backup and Restore with tags fails 2022-12-05 10:01:48 +07:00
AMOS bot 9cf6e7128e Automatically generated installer lang files 2022-12-04 00:08:32 +00:00
Andrew Nicols ed29852851 MDL-76556 tool_log: Set the store property correctly 2022-12-03 11:48:26 +08:00
Ilya Tregubov a7e9836173 Merge branch 'MDL-76495-401' of https://github.com/marinaglancy/moodle into MOODLE_401_STABLE 2022-12-02 13:49:13 +03:00
Lars Bonczek add1d29339 MDL-75516 core: Perform proper JSON encoding in mustache quote helper 2022-12-02 11:22:23 +01:00
Paul Holden 68dc955abe MDL-76491 javascript: add missing core/notification imports. 2022-12-02 10:06:21 +00:00
Paul Holden 258fe36e10 MDL-76491 javascript: prevent eslint undefined Notification import. 2022-12-02 10:06:04 +00:00
Paul Holden 76fde950c1 MDL-76398 reportbuilder: use improved action menu steps in Behat.
Improved steps for using actions menus were added in 232ebac3, so
make use of them here for consistency/reliability.
2022-12-02 09:55:55 +00:00
Paul Holden d4681259bc MDL-76398 behat: broader action menu partial matching by element.
For action menu elements whose trigger element isn't plain text
(e.g. a pix icon), we should be able to match via the title of
that element.
2022-12-02 09:55:45 +00:00
Ilya Tregubov e6dec9c0fb Merge branch 'MDL-75951-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2022-12-02 11:55:54 +03:00
Dani Palou 8b153fb67d MDL-75788 behat: Use profile field generators in existing tests 2022-12-02 14:58:28 +08:00
Dani Palou 1145b8f597 MDL-75788 testing: Handle new lines in menu profile field generator 2022-12-02 14:58:28 +08:00
Andrew Nicols 743fc68b4f MDL-75951 core: Update box/spout to address PHP 8.1 deprecation
This change is a direct pull from an upstream fix:
https://github.com/openspout/openspout/commit/64a09a748d04992d63b38712599a9d8742bd77f7

This addresses the deprecation of auto_detect_line_endings in PHP 8.1.
2022-12-02 13:58:39 +08:00
Ilya Tregubov 9d801ab8a0 Merge branch 'MDL-76494-401' of https://github.com/marinaglancy/moodle into MOODLE_401_STABLE 2022-12-02 08:41:34 +03:00
hieuvu b7f08d7ecc MDL-76106 qtype_ddmarker: Improve loading consistency.
Wait for the image to load completely before running the js.
2022-12-02 12:39:23 +07:00
Andrew Nicols 715ec40ad6 Merge branch 'MDL-76493-401' of https://github.com/marinaglancy/moodle into MOODLE_401_STABLE 2022-12-02 12:15:30 +08:00
Paul Holden 1d98d162a1 MDL-75573 backup: translate async operation type in messages. 2022-12-01 19:48:58 +00:00
Stefan Hanauska d42189d71a MDL-76330 enrol: Check permission to show edit icon 2022-12-01 20:07:13 +01:00
Sara Arjona 7f5f04dbc2 weekly release 4.1+ 2022-12-01 16:07:58 +01:00
Sara Arjona 82d90a8950 NOBUG: Fixed file access permissions 2022-12-01 16:07:57 +01:00
Simey Lameze e581bd6cde MDL-76507 behat: change step to use 'Recent and next 60 days' option
It was detected that 'This month' option may cause failures in builds in between months
so using the 'Recent and next 60 days' still fixes the weekend scenario and also the
in between months issue.
2022-12-01 08:51:26 +01:00
Andrew Nicols 68cd224ef3 Merge branch 'MDL-75604-401' of https://github.com/ssj365/moodle into MOODLE_401_STABLE 2022-12-01 08:59:07 +03:00
Andrew Nicols afef05b07c Merge branch 'MDL-75281-401' of https://github.com/call-learning/moodle into MOODLE_401_STABLE 2022-12-01 08:59:07 +03:00
Jun Pataleta d9cd25c2fb MDL-76497 upgrade: add the 4.1.0 separation line to all upgrade scripts 2022-12-01 08:59:07 +03:00
Sara Arjona 960bc4e3c5 Merge branch 'MDL-76226-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-01 08:59:07 +03:00
Sara Arjona cf06e4207f Merge branch 'MDL-76507-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2022-12-01 08:59:07 +03:00
Jun Pataleta 9f06111278 Merge branch 'MDL-76250-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-01 08:59:06 +03:00
Andrew Nicols a8bcb23134 MDL-76483 core: Handle default value for get_docs_url() 2022-12-01 08:59:06 +03:00
Ilya Tregubov 5c96f74a06 Merge branch 'MDL-74853-401' of https://github.com/marinaglancy/moodle into MOODLE_401_STABLE 2022-12-01 08:59:06 +03:00
Ilya Tregubov 7cc3d06276 Merge branch 'MDL-76487-401' of https://github.com/ilyatregubov/moodle into MOODLE_401_STABLE 2022-12-01 08:59:06 +03:00
Andrew Nicols b00f1464a8 Merge branch 'MDL-75826-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2022-12-01 08:59:06 +03:00
Andrew Nicols 88393518f5 MDL-76487 tiny_autosave: Clarify autosave store rejection message 2022-12-01 08:59:06 +03:00
Jun Pataleta 57e5cc1588 Merge branch 'MDL-68981-401' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2022-12-01 08:59:06 +03:00
Andrew Nicols a0efc27d31 MDL-76487 tiny_autosave: Use navigator.sendBeacon instead of fetch
Firefox does not support the keepalive flag for fetch, despite every
other browser except IE supporting it.
2022-12-01 08:59:06 +03:00
David Woloszyn 0be376fdc0 MDL-76183 lib: Update Github URLs 2022-12-01 08:59:05 +03:00
Jun Pataleta 8bf788a1bd Merge branch 'MDL-76284-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-01 08:59:05 +03:00
Eloy Lafuente (stronk7) 864a2ea990 MDL-76429 composer: Bump to phpwebdriver 1.2.1 for php81 compat
Note this comes with a bunch of other small updates, all them
pretty minor and should not be problematic. Better we get them
than keeping them apart.
2022-12-01 08:59:05 +03:00
Andrew Nicols 73f10723b3 Merge branch 'MDL-76380-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2022-12-01 08:59:05 +03:00
sam marshall be11ee3383 MDL-76218 cachestore_redis: delete_many can fail with no keys
In some cases, we get an error message such as:

Wrong parameter count for Redis::zRem()

Within the delete_many function. This function requires at least one
key to be supplied, but if delete_many is called with an empty array,
we will call it with no keys.
2022-12-01 08:59:05 +03:00
Eloy Lafuente (stronk7) fbb0fd952d MDL-75977 xmldb: Avoid using null params on built-in DB functions
This changes a couple of cases, in postgres and oracle where we
were trying to calculate strlen() on null values (that causes a
PHP 8.1 warning).

Also, at the same time, fixing another case in xmldb_field, it
was detected that it had a bug around precision (being set to the
value of type), being used as object property, when it's not, so
it was also fixed by moving the code logic a little bit.

Note that the bug has been there since inception because there
isn't any code in Moodle using that ->precision property. It
was just detected thanks to PHP 8.2, but that's another story. :-)

Verified that with the patch:
- All DBs can be installed (phpunit install)
- Both DDL and DML pass without any ddl/dml warning (in all DBs).
2022-12-01 08:59:05 +03:00
Meirza 0cc4492303 MDL-76127 Profiling: Make the breadcrumb of the profiling URL clickable
Boost has the behavior to remove the last item action.
To avoid that, we need to add an action item.
2022-12-01 08:59:05 +03:00
Ilya Tregubov dcc2d22a74 Merge branch 'MDL-72019-401' of https://github.com/ilyatregubov/moodle into MOODLE_401_STABLE 2022-12-01 08:59:05 +03:00
Meirza 1c2503a6de MDL-72019 user: Allows data to be formatted when exporting. 2022-12-01 08:59:05 +03:00
Laurent David c86d6510ce MDL-75281 mod_bigbluebuttonbn: Upgrade failure when table exists
* Fix several upgrade script issue when the recording table exists or plugin has been
downgraded prior to 4.x upgrade
2022-11-30 20:18:27 +01:00
Shamiso.Jaravaza a8f889acbf MDL-75604 mod_bigbluebuttonbn: Fix welcome section
* Removed welcome message from General settings
* Cleaned settings.php file to remove hardcoded add($item) after adding conditional element
2022-11-30 12:10:07 -07:00
Kepa Urzelai 5a07bcf871 MDL-72563 theme_boost: rubric area style fix 2022-11-30 15:13:50 +01:00
Marina Glancy 12ac6ce86b MDL-76494 libs: patch Box::Spout for PHP 8.1 - calling basename on null 2022-11-30 10:45:58 +01:00
Meirza 2db281b197 MDL-76145 course: Avoid long course names that exceed available space
Co-authored-by: Stephen Sharpe <stephen.sharpe@synergy-learning.com>
2022-11-30 11:36:24 +07:00
Andrew Nicols 805559cb48 MDL-76482 output: The javascript mustache helper should return a string 2022-11-30 12:18:47 +08:00
Huong Nguyen 19ed64f2d9 MDL-68981 tool_recyclebin: Force necessary settings when restoring
Created code to force the necessary settings for restore_item in:
  + course_bin class
  + category_bin class
2022-11-30 10:18:54 +07:00
Huong Nguyen dcc115786d MDL-68981 tool_recyclebin: Extra PHPUnit with General restore config 2022-11-30 10:18:54 +07:00
Huong Nguyen 2ef01c0fdf MDL-68981 tool_recyclebin: Extra Behat test with General restore config
Including in this commit:
 - Convert existing Behat scenario to use Data generators
 - Convert existing Behat scenario to use Provider
 - Add new scenario for Include users setting in General restore page
2022-11-30 10:18:54 +07:00
Brendan Heywood 2696f446ac MDL-76166 calendar: Ensure user is in server access logs 2022-11-30 13:26:27 +11:00
Brendan Heywood c45c98f6f2 MDL-76166 auth: Ensure user is in server access logs 2022-11-30 13:26:27 +11:00
Jonathan Champ 181ecedb11 MDL-76506 cache_application: Fix MDL_PERF and perfdebug checks 2022-11-29 13:28:05 -05:00
Paul Holden 7e8efa870d MDL-76446 user: correct logic for multiple keyword search.
When the keyword participant filter was used with multiple values
in conjunction with other participants filters, the boolean logic
was effectively:

 X AND Y OR Z

When what we actually wanted was:

 X AND (Y OR Z)
2022-11-29 16:31:05 +00:00
Paul Holden b363723f9a MDL-76476 tiny_media: don't load image preview if none exists. 2022-11-29 16:28:15 +00:00
Ilya Tregubov e0ef5d0638 Merge branch 'MDL-75463-401' of https://github.com/ilyatregubov/moodle into MOODLE_401_STABLE 2022-11-29 13:32:16 +03:00
Kevin Percy 38250aec8e MDL-75463 lib: Update Bennu version number to 0.2 2022-11-29 13:31:25 +03:00
Andrew Nicols 5475fb8a15 Merge branch 'MDL-76355-401' of https://github.com/marinaglancy/moodle into MOODLE_401_STABLE 2022-11-29 17:30:02 +08:00
Angelia Dela Cruz 5384f872bb MDL-75960 behat: Survey behat generators use UI
Replace steps that manually add Survey instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
2022-11-29 17:06:42 +08:00
Paul Holden eb3ee12852 MDL-75381 gradereport_grader: ensure valid paging preference value.
Set type of the report paging setting to integer, to ensure usage
of it is predictable. Unsupported operated type errors were thrown
on PHP8.0 when it's value contained a string or was empty.
2022-11-29 08:42:02 +00:00
Daniel Ziegenberg dded69ad15 MDL-74823 lib: HTMLPurifier upgrade to 4.16.0
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2022-11-29 16:39:48 +08:00
Daniel Ziegenberg 2cfaa895aa MDL-74823 lib: normalize line endings for HTMLPurifier
Prior to this change, all the line endings in the imported HTMLPurifier
library were using CRLF (\r\n aka Windows style), but the HTMLPurifier
source and also the downloadable artefacts use LF (\n aka Linux style)
as line endings. This has been the case since
510d190382 when with the commit
"MDL-38672 import HTML Purifier 4.5.0" all line endings were changed
from LF to CRLF. There was no comment in the commit on why this change
was done.

As the original source uses LF, this commit partly reverts
510d190382 and goes back to LF as line
endings.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2022-11-29 16:39:35 +08:00
Daniel Ziegenberg 60e176b50d MDL-74823 lib: HTMLPurifier upgrade to 4.14.0
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2022-11-29 16:39:22 +08:00
Paul Holden 530e06da6d MDL-75789 restore: multi-byte safe substring calculating course names.
Co-authored-by: Leon Stringer <leon.stringer@ntlworld.com>
2022-11-29 08:36:00 +00:00
info@eWallah.net 4d9c6785ff MDL-65939 phpunit: Maildigest tests can query a wrong adhoc task 2022-11-29 15:41:31 +08:00
Simey Lameze 1b8456dbb1 MDL-76058 behat: send message using data generator 2022-11-29 15:37:15 +08:00
Andrew Nicols 3e26150eae Merge branch 'MDL-76088-401' of https://github.com/marinaglancy/moodle into MOODLE_401_STABLE 2022-11-29 15:09:46 +08:00
Pablo Amaya 5cf31d7445 MDL-74454 mod_scorm: Fixed problems in lateral navigation.
Fixed problems in lateral navigation and grading when
a SCORM has more than three levels

The SCORM module has problems with full screen display,
completion tracking and grading in SCORM.

Also resolves issues MDL-74992, MDL-73249, MDL-75407
2022-11-29 14:18:30 +08:00
Andrew Nicols 62238568a2 MDL-76258 mod_lti: Codign style fixes 2022-11-29 12:28:46 +08:00
Stefan Hanauska 6e9e2be8f4 MDL-76258 mod_lti: Reset clientid after restore 2022-11-29 12:28:46 +08:00
Andrew Nicols 34f8f82288 MDL-69570 assignfeedback_editpdf: Whitespace fix 2022-11-29 11:50:41 +08:00
Adrian Greeve ac8b7e9f0a MDL-69570 assignfeedback_editpdf: Upgrade step to remove files.
This upgrade step removes all orphaned editpdf feedback files and
records.
2022-11-29 11:50:41 +08:00
Adrian Greeve b50c240ab5 MDL-69570 assignfeedback_editpdf: Remove temp pdf files
This adds a new method to the assignfeedback edit pdf library
to specify user data file areas that will return just the meaningful
annotated feedback pdf.

get_file_areas has been updated for this plugin to return all
file areas related to assignfeedback_editpdf, and should stop
producing orphaned files and records when a course reset is done.

Thanks to @toniginard who provided a base solution for me to work
off.
2022-11-29 11:50:41 +08:00
Jonathan Champ 189c4ce4de MDL-76506 core\lock: Fix MDL_PERF and perfdebug checks 2022-11-28 18:54:13 -05:00
Paul Holden e3840909f5 MDL-76380 tool_oauth2: remove double persistent load on update.
The method already loaded the validated persistent model data on the
previous line, there's no need to do it again (while also trying to
load unvalidated properties).
2022-11-28 19:38:52 +00:00
Paul Holden 523b590711 MDL-76250 mod_assign: disable form change checker for grading options.
This was previously fixed in 8e9efe60, but seems to have regressed
somewhere along the way.
2022-11-28 16:07:29 +00:00
Paul Holden b391ed9941 MDL-76226 admin: account for preset config checkboxes other than bool.
The assumption that the settings checkbox always stores boolean values
(e.g. 0/1) isn't correct. The `perfdebug` configuration instead uses
the values 7/15.
2022-11-28 16:04:43 +00:00
Marina Glancy a5f92c041e MDL-74853 various: add second parameter to htmlentities functions
Default value of the $flag argument changed in PHP 8.1 from ENT_COMPAT to ENT_QUOTES | ENT_SUBSTITUTE
To ensure consistent behavior across different PHP version the second parameter is now required for the functions:
htmlspecialchars(), htmlentities(), htmlspecialchars_decode(), html_entity_decode() and get_html_translation_table()
2022-11-28 16:12:32 +01:00
Marina Glancy cfe0945ffb MDL-76495 libs: patch TCPDF for PHP 8.1 compatibility 2022-11-28 16:02:03 +01:00
Marina Glancy 6989097a3c MDL-76495 lib: test for qrcode in TCPDF 2022-11-28 16:02:03 +01:00
Marina Glancy 847f08dcd4 MDL-76494 libs: patch Box::Spout for PHP 8.1 compatibility 2022-11-28 15:56:54 +01:00
Marina Glancy 02430ee562 MDL-76494 core_reportbuilder: behat test for downloading report 2022-11-28 15:56:54 +01:00
Marina Glancy a8e90aaae1 MDL-76494 dataformat: tests for Excel and ODS writers 2022-11-28 15:56:53 +01:00
Paul Holden fac0c27efb MDL-76284 webservice: early exit if no users for missing capabilities. 2022-11-28 11:53:23 +00:00
Marina Glancy a7e7cd71cb MDL-76355 lib: apply a patch to googleapi for php 8.1 compatibility 2022-11-28 12:01:05 +01:00
Marina Glancy 37be6bfa4d MDL-76088 blocks: fixed incorrect use of static cache 2022-11-28 11:59:46 +01:00
Marina Glancy d311cab0c0 MDL-76493 core: make sure format_string(null) works on PHP 8.1 2022-11-28 11:55:50 +01:00
Meirza fb5a3dd643 MDL-75826 profile: Redirect to profile page if returnto is profile. 2022-11-28 16:39:11 +07:00
22802 changed files with 597073 additions and 1047419 deletions
+94 -31
View File
@@ -1,12 +1,8 @@
{
'plugins': [
'@babel',
'babel',
'promise',
'jsdoc'
],
'extends': [
'eslint:recommended',
'plugin:promise/recommended'
'jsdoc',
],
'env': {
'browser': true,
@@ -20,19 +16,42 @@
'M': true,
'Y': true
},
// Warn about unused eslint-disable statements.
'reportUnusedDisableDirectives': true,
'rules': {
// See http://eslint.org/docs/rules/ for all rules and explanations of all
// rules.
// === Possible Errors ===
'comma-dangle': 'off',
'no-compare-neg-zero': 'error',
'no-cond-assign': 'error',
'no-console': 'error',
'no-constant-condition': 'error',
'no-control-regex': 'error',
'no-debugger': 'error',
'no-dupe-args': 'error',
'no-dupe-keys': 'error',
'no-duplicate-case': 'error',
'no-empty': 'warn',
'no-empty-character-class': 'error',
'no-ex-assign': 'error',
'no-extra-boolean-cast': 'error',
'no-extra-parens': 'off',
'no-extra-semi': 'error',
'no-func-assign': 'error',
'no-inner-declarations': 'error',
'no-invalid-regexp': 'error',
'no-irregular-whitespace': 'error',
'no-obj-calls': 'error',
'no-prototype-builtins': 'off',
'no-regex-spaces': 'error',
'no-sparse-arrays': 'error',
'no-unexpected-multiline': 'error',
'no-unreachable': 'warn',
'no-unsafe-finally': 'error',
'no-unsafe-negation': 'error',
'use-isnan': 'error',
'valid-jsdoc': ['warn', { 'requireReturn': false, 'requireParamDescription': false, 'requireReturnDescription': false }],
'valid-typeof': 'error',
// === Best Practices ===
// (these mostly match our jshint config)
@@ -44,12 +63,15 @@
'dot-notation': 'warn',
'no-alert': 'warn',
'no-caller': 'error',
'no-case-declarations': 'error',
'no-div-regex': 'error',
'no-empty-pattern': 'error',
'no-empty-function': 'warn',
'no-eq-null': 'error',
'no-eval': 'error',
'no-extend-native': 'error',
'no-extra-bind': 'warn',
'no-fallthrough': 'error',
'no-floating-decimal': 'warn',
'no-global-assign': 'warn',
'no-implied-eval': 'error',
@@ -61,22 +83,28 @@
'no-multi-str': 'error',
'no-new-func': 'error',
'no-new-wrappers': 'error',
'no-octal': 'error',
'no-octal-escape': 'error',
'no-proto': 'error',
'no-redeclare': 'warn',
'no-restricted-globals': ['error', { 'name': 'Notification' }],
'no-return-assign': 'error',
'no-script-url': 'error',
'no-self-assign': 'error',
'no-self-compare': 'error',
'no-sequences': 'warn',
'no-throw-literal': 'warn',
'no-unmodified-loop-condition': 'error',
'no-unused-expressions': 'error',
'no-unused-labels': 'error',
'no-useless-call': 'warn',
'no-useless-escape': 'warn',
'no-with': 'error',
'wrap-iife': ['error', 'any'],
// === Variables ===
'no-delete-var': 'error',
'no-undef': 'error',
'no-undef-init': 'error',
'no-unused-vars': ['error', { 'caughtErrors': 'none' }],
@@ -109,6 +137,8 @@
'max-statements-per-line': ['warn', { max: 2 }],
'new-cap': ['warn', { 'properties': false }],
'new-parens': 'warn',
'newline-after-var': 'off',
'newline-before-return': 'off',
'newline-per-chained-call': 'off',
'no-array-constructor': 'off',
'no-bitwise': 'error',
@@ -116,6 +146,7 @@
'no-inline-comments': 'off',
'no-lonely-if': 'off',
'no-mixed-operators': 'off',
'no-mixed-spaces-and-tabs': 'error',
'no-multiple-empty-lines': 'warn',
'no-negated-condition': 'off',
'no-nested-ternary': 'warn',
@@ -137,6 +168,7 @@
'padded-blocks': 'off',
'quote-props': ['warn', 'as-needed', {'unnecessary': false, 'keywords': true, 'numbers': true}],
'quotes': 'off',
'require-jsdoc': 'warn',
'semi': 'error',
'semi-spacing': ['warn', {'before': false, 'after': true}],
'sort-vars': 'off',
@@ -149,19 +181,21 @@
'unicode-bom': 'error',
'wrap-regex': 'off',
// === Promises (override plugin:promise/recommended) ===
// === Promises ===
'promise/always-return': 'warn',
'promise/no-return-wrap': 'warn',
'promise/param-names': 'warn',
'promise/catch-or-return': ['warn', {terminationMethod: ['catch', 'fail', 'always'], allowFinally: true}],
'promise/catch-or-return': ['warn', {terminationMethod: ['catch', 'fail']}],
'promise/no-native': 'warn',
'promise/no-promise-in-callback': 'warn',
'promise/no-callback-in-promise': 'warn',
'promise/avoid-new': 'warn',
// === Deprecations ===
"no-restricted-properties": ['warn', {
'object': 'M',
'property': 'str',
'message': 'Use "core/str" module or M.util.get_string()'
'message': 'Use AMD module "core/str" or M.util.get_string()'
}],
},
overrides: [
@@ -201,6 +235,7 @@
parser: '@babel/eslint-parser',
// Check AMD with some slightly stricter rules.
rules: {
'no-unused-vars': 'error',
'no-implicit-globals': 'error',
// Disable all of the rules that have babel versions.
'new-cap': 'off',
@@ -212,37 +247,65 @@
'semi': 'off',
'no-unused-expressions': 'off',
// Enable all of the babel version of these rules.
'@babel/new-cap': ['warn', { 'properties': false }],
'babel/new-cap': ['warn', { 'properties': false }],
// Not using this rule for the time being because it isn't
// compatible with jQuery and ES6.
'@babel/no-invalid-this': 'off',
'@babel/object-curly-spacing': 'warn',
'@babel/semi': 'error',
'@babel/no-unused-expressions': 'error',
'babel/no-invalid-this': 'off',
'babel/object-curly-spacing': 'warn',
// This is off in the original style int.
'babel/quotes': 'off',
'babel/semi': 'error',
'babel/no-unused-expressions': 'error',
// === Promises ===
// We have Promise now that we're using ES6.
'promise/no-native': 'off',
'promise/avoid-new': 'off',
// === JSDocs ===
'jsdoc/check-access': 'error',
'jsdoc/check-alignment': 1, // Recommended.
'jsdoc/check-param-names': 'error',
'jsdoc/check-property-names': 'error',
'jsdoc/empty-tags': 'error',
'jsdoc/implements-on-classes': 'error',
'jsdoc/multiline-blocks': 'error',
'jsdoc/require-jsdoc': 'error',
'jsdoc/require-param': 'error',
'jsdoc/require-param-name': 'error',
'jsdoc/require-param-type': 'error',
'jsdoc/require-property': 'error',
'jsdoc/require-property-name': 'error',
'jsdoc/require-property-type': 'error'
"jsdoc/check-access": [
'error',
],
"jsdoc/check-alignment": 1, // Recommended.
"jsdoc/check-param-names": [
'error',
],
"jsdoc/check-property-names": [
'error',
],
"jsdoc/empty-tags": [
'error',
],
"jsdoc/implements-on-classes": [
'error',
],
"jsdoc/multiline-blocks": [
'error',
],
"jsdoc/require-jsdoc": [
'error',
],
"jsdoc/require-param": [
'error',
],
"jsdoc/require-param-name": [
'error',
],
"jsdoc/require-param-type": [
'error',
],
"jsdoc/require-property": [
'error',
],
"jsdoc/require-property-name": [
'error',
],
"jsdoc/require-property-type": [
'error',
],
},
parserOptions: {
'sourceType': 'module',
'requireConfigFile': false
'requireConfigFile': false,
}
}
]
-7
View File
@@ -1,7 +0,0 @@
*** PLEASE DO NOT OPEN PULL REQUESTS VIA GITHUB ***
The moodle.git repository at Github is just a mirror of the official repository. We do not accept pull requests at Github.
See CONTRIBUTING.md guidelines for how to contribute patches for Moodle. Thank you.
--
-6
View File
@@ -1,6 +0,0 @@
> [!IMPORTANT]
> PLEASE DO NOT PUBLISH SECURITY FINDINGS PUBLICLY.
If you discover a potential security issue, please report it via our [Security Submission Form](https://moodle.org/security/report).
For more information about our security processes and responsible disclosure policy, see the [Security Procedures documentation](https://moodledev.io/general/development/process/security).
-1
View File
@@ -1 +0,0 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1231.24 314.44" preserveAspectRatio="xMinYMid meet"><defs><style>.cls-1{fill:#f48020;}.cls-2,.cls-3{fill:#383738;stroke:#4a4a4c;}.cls-2{stroke-width:2.37px;}.cls-3{stroke-width:2.38px;}.cls-4{fill:#585858;}</style></defs><title>Moodle_Logo_UseonBlack_RGB</title><path class="cls-1" d="M1086.3,235.34a53.42,53.42,0,0,0,16.71,29q13.26,12.27,29.48,12.27,11.29,0,24.56-5.89,16.23-6.88,16.22-16.22l58-.49q-12.29,29-41.76,45.2-27.52,15.23-60.43,15.24-42.25,0-70-26.29t-27.75-68.54q0-43.73,27.75-69.51t72-25.8q48.15,0,75.17,31.94,25.07,29.47,25.06,79.1Zm89.91-33.91q-3.43-17.69-14.73-29-12.8-12.28-29.49-12.29-17.21,0-28.74,11.79t-15.47,29.48Z"/><path class="cls-1" d="M965.45,308.54V0h55V308.54Z"/><path class="cls-1" d="M892.69,308.54V290.36q-7.38,9.83-25.06,15.72a92.31,92.31,0,0,1-30,5.41q-39.31,0-63.13-27T750.7,217.65q0-39.3,23.34-65.84t62.15-26.53q43.71,0,56.5,23.58V0h53.55V308.54Zm0-102.68q0-14.75-14-28.26t-28.74-13.51q-21.12,0-33.41,17.2-10.8,15.24-10.8,37.33,0,21.63,10.8,36.85,12.29,17.71,33.41,17.69,12.78,0,27.76-12t15-24.81Z"/><path class="cls-1" d="M647,313.45q-41.77,0-69-26.53t-27.27-68.3q0-41.73,27.27-68.28t69-26.53q41.75,0,69.27,26.53t27.52,68.28q0,41.79-27.52,68.3T647,313.45ZM647,168q-19.89,0-30.58,15.07t-10.68,35.79q0,20.73,9.94,35.05,11.43,16.31,31.32,16.28t31.32-16.28q10.44-14.31,10.44-35.05t-9.94-35Q667.42,168,647,168Z"/><path class="cls-1" d="M448.07,313.45q-41.76,0-69-26.53t-27.27-68.3q0-41.73,27.27-68.28t69-26.53q41.74,0,69.28,26.53t27.5,68.28q0,41.79-27.5,68.3T448.07,313.45Zm0-145.43q-19.89,0-30.59,15.07t-10.69,35.79q0,20.73,9.94,35.05,11.43,16.31,31.34,16.28t31.32-16.28q10.42-14.31,10.44-35.05t-9.94-35Q468.45,168,448.07,168Z"/><path class="cls-1" d="M288.89,309.11V201q0-33.9-28-33.9t-28,33.9V309.11h-55V201q0-33.9-27.52-33.9-28,0-28,33.9V309.11h-55V194.65q0-35.37,24.56-53.54,21.61-16.22,58.46-16.22,37.35,0,55,19.16,15.23-19.16,55.51-19.16,36.86,0,58.45,16.22,24.57,18.16,24.57,53.54V309.11Z"/><path class="cls-2" d="M.76,145.76"/><path class="cls-3" d="M1.73,145.32"/><path class="cls-4" d="M173.86,116.85l55.08-40.1-.7-2.44C135,83.92,80.42,96.44,0,144.13l.73,2.38,21-.67c15.17.52,30.85,1.26,46,1.32-1,24.09.83,32.65.83,32.65,51.92,17.58,101.22,1.53,127.14-43.9A248.72,248.72,0,0,0,173.86,116.85Z"/><path class="cls-4" d="M113.78,110c-.3-1.08-2.23-1.48-4.28-.9a4.73,4.73,0,0,0-3.14,2.19c-18.53,5-49.16,13.72-70.73,21l-1.33.45c-16.68,5.61-24.73,8.49-25.22,12.55-2.29,18.44-.87,42.18-.86,42.48l.19,6.4c-9.74,27.56.06,49.6,8.38,69.77.06-24.92,1.07-45.22-6-71-.2-3.82-1.49-30.36.61-47.34.34-2.75,11.65-6.56,23.63-10.59l1.33-.44c22-7.42,53.57-16.39,71.9-21.29a6.75,6.75,0,0,0,2.29-.25C112.64,112.43,114.08,111.09,113.78,110Z"/></svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

-31
View File
@@ -1,31 +0,0 @@
name: 'Close Pull Requests'
on:
pull_request_target:
types: opened
workflow_dispatch:
jobs:
close:
# Avoid forks to run this job
if: github.repository_owner == 'moodle'
name: Close Pull Requests
runs-on: ubuntu-latest
steps:
- uses: dessant/repo-lockdown@v4
with:
process-only: prs
close-pr: true
skip-closed-pr-comment: true
pr-comment: >
**Please, don't open pull requests via GitHub.**
This repository (moodle.git) at GitHub is just a mirror of the official Moodle repository.
For how to contribute patches for Moodle see
[CONTRIBUTING.md](https://github.com/moodle/moodle/blob/main/CONTRIBUTING.md).
Closing this pull request.
-143
View File
@@ -1,143 +0,0 @@
name: One by One Testing
# Run all the individual unit tests one by one, with
# fully independent PHPUnit executions. Useful to
# detect issues with some tests that are using stuff
# that has been made available by others, but is not
# available when running individually.
#
# Note that we aren't using PHPUnit's own isolation
# here but completely separated runs, one for each
# test.
#
# The workflow will fail reporting all the tests
# that have failed (and will pass if no failure is
# detected, of course).
#
# It's only executed via workflow dispatch (automated
# or manual), not by push/tag. And acceptd configuration
# of phpunit, specially useful to run it with PHPUnit's
# own isolation or any other option.
on:
workflow_dispatch:
inputs:
phpunit_extra_options:
description: Additional options to apply to PHPUnit
required: false
default: ''
env:
chunks: 7
jobs:
collect:
name: Collect individual unit tests
runs-on: ubuntu-latest
outputs:
matrix: ${{steps.individual-tests.outputs.matrix }}
steps:
- name: Checking out code
uses: actions/checkout@v4
- name: Looking for all individual tests
id: individual-tests
run: |
count=0 # Number of individual tests found.
while read -r testfile; do # For each test file.
while read -r testname; do # For each unit test in a file.
count=$((count + 1))
# Sent it to the correct chunk file.
chunk=$(((($count % $chunks)) + 1))
echo "$testname $testfile" >> ./chunk_$chunk.txt
done < <(grep "function test_" "${testfile}" | sed -r "s/^.*function (test_[a-zA-Z0-9_]+).*/\1/")
done < <(find . -name "*_test.php")
# Generate the matrix to run tests.
echo "matrix=$(ls -1 chunk_*.txt | jq -R -s -c 'split("\n")[:-1]')" >> $GITHUB_OUTPUT
echo "$count individual tests collected in $chunks files"
- name: Upload individual tests files
uses: actions/upload-artifact@v4
with:
name: individual_tests
path: chunk_*.txt
retention-days: 1
test:
name: Run tests
needs: collect
runs-on: ubuntu-latest
services:
exttests:
image: moodlehq/moodle-exttests
ports:
- 8080:80
redis:
image: redis
ports:
- 6379:6379
strategy:
fail-fast: false
matrix:
file: ${{ fromJson(needs.collect.outputs.matrix) }}
steps:
- name: Setting up DB pgsql
uses: m4nu56/postgresql-action@v1
with:
postgresql version: 13
postgresql db: test
postgresql user: test
postgresql password: test
- name: Setting up PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
ini-values: max_input_vars=5000
coverage: none
- name: Checking out code
uses: actions/checkout@v4
- name: Download individual test files
uses: actions/download-artifact@v4
with:
name: individual_tests # Make all the chunk files available for the next steps.
- name: Setting up PHPUnit
env:
dbtype: pgsql
run: |
echo "pathtophp=$(which php)" >> $GITHUB_ENV
cp .github/workflows/config-template.php config.php
mkdir ../moodledata
sudo locale-gen en_AU.UTF-8
php admin/tool/phpunit/cli/init.php --no-composer-self-update
- name: Run PHPUnit test (one by one)
env:
dbtype: pgsql
run: |
status=0
count=0
while read -r line; do # For each line in the chunk file
count=$((count + 1))
filter="${line% *}"
file="${line#* }"
# Run the individual unit test and report problems if needed to.
if ! php vendor/bin/phpunit \
--fail-on-empty-test-suite \
--fail-on-warning \
--fail-on-risky \
--filter "$filter" ${{ inputs.phpunit_extra_options }} \
"$file" >/dev/null 2>&1; then
if [ $status -eq 0 ]; then
echo "Problems found, list of PHPUnit commands failing:"
fi
echo "vendor/bin/phpunit --filter '${filter}' ${{ inputs.phpunit_extra_options }} $file"
status=$((status + 1))
fi
done < ${{ matrix.file }}
echo "Finished: $count individual tests executed, $status tests failed"
exit $status
+12 -24
View File
@@ -3,19 +3,13 @@ name: Core
on:
push:
branches-ignore:
- main
- master
- MOODLE_[0-9]+_STABLE
tags-ignore:
- v[0-9]+.[0-9]+.[0-9]+*
workflow_dispatch:
inputs:
phpunit_extra_options:
description: Additional options to apply to PHPUnit
required: false
default: ''
env:
php: 8.3
php: 8.0
jobs:
Grunt:
@@ -23,10 +17,10 @@ jobs:
steps:
- name: Checking out code
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Configuring node & npm
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
@@ -60,35 +54,32 @@ jobs:
fail-fast: false
matrix:
include:
# MySQL builds always run with the lowest PHP supported version.
- os: ubuntu-22.04
php: 8.1
php: 7.4
extensions:
db: mysqli
# PostgreSQL builds always run with the highest PHP supported version.
- os: ubuntu-22.04
php: 8.3
php: 8.0
db: pgsql
extensions: xmlrpc-beta
steps:
- name: Setting up DB mysql
if: ${{ matrix.db == 'mysqli' }}
uses: moodlehq/mysql-action@v1
uses: johanmeiring/mysql-action@tmpfs-patch
with:
collation server: utf8mb4_bin
mysql version: 8.0
mysql version: 5.7
mysql database: test
mysql user: test
mysql password: test
use tmpfs: true
tmpfs size: '1024M'
extra conf: --skip-log-bin
- name: Setting up DB pgsql
if: ${{ matrix.db == 'pgsql' }}
uses: m4nu56/postgresql-action@v1
with:
postgresql version: 13
postgresql version: 12
postgresql db: test
postgresql user: test
postgresql password: test
@@ -105,7 +96,7 @@ jobs:
coverage: none
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Setting up PHPUnit
env:
@@ -121,7 +112,4 @@ jobs:
env:
dbtype: ${{ matrix.db }}
phpunit_options: ${{ secrets.phpunit_options }}
run: vendor/bin/phpunit $phpunit_options ${{ inputs.phpunit_extra_options }}
- name: Git status
run: git status
run: vendor/bin/phpunit $phpunit_options
-23
View File
@@ -1,23 +0,0 @@
name: Web Installer Testing
on:
workflow_dispatch:
jobs:
InstallationTest:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
php: [8.1, 8.3]
steps:
- name: Construct repository URL
run: echo "REPOSITORY_URL=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" >> $GITHUB_ENV
shell: bash
- uses: moodlehq/moodle-webinstaller-test@main
with:
repository: ${{ env.REPOSITORY_URL }}
branch: ${{ github.ref_name }}
php: ${{ matrix.php }}
-149
View File
@@ -1,149 +0,0 @@
name: Windows Testing
on:
workflow_dispatch:
inputs:
phpunit_extra_options:
description: Additional options to apply to PHPUnit
required: false
default: ''
env:
php: 8.3
jobs:
Grunt:
runs-on: windows-latest
steps:
- name: Set git to use LF
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checking out code
uses: actions/checkout@v4
- name: Configuring node & npm
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- name: Installing node stuff
run: npm ci
- name: Running grunt
run: npx grunt
- name: Looking for uncommitted changes
# Add all files to the git index and then run diff --cached to see all changes.
# This ensures that we get the status of all files, including new files.
# We ignore npm-shrinkwrap.json to make the tasks immune to npm changes.
run: |
git add .
git reset -- npm-shrinkwrap.json
git diff --cached --exit-code
PHPUnit:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
php: 8.3
# Ideally we should use mysql/mariadb, but they are 4x slower without tweaks and configuration
# so let's run only postgres (1.5h vs 6h) only, If some day we want to improve the mysql runs,
# this is the place to enable them.
# db: mysqli
db: pgsql
extensions: exif, fileinfo, gd, intl, pgsql, mysql, redis, soap, sodium, zip
- os: windows-latest
php: 8.1
db: pgsql
extensions: exif, fileinfo, gd, intl, pgsql, mysql, redis, soap, sodium
steps:
- name: Setting up DB mysql
if: ${{ matrix.db == 'mysqli' }}
uses: shogo82148/actions-setup-mysql@v1
with:
mysql-version: 8.0
user: test
password: test
- name: Creating DB mysql
if: ${{ matrix.db == 'mysqli' }}
run: mysql --host 127.0.0.1 -utest -ptest -e 'CREATE DATABASE IF NOT EXISTS test COLLATE = utf8mb4_bin;';
- name: Setting up DB pgsql
if: ${{ matrix.db == 'pgsql' }}
run: |
# TODO: Remove these conf. modifications when php74 or php80 are lowest.
# Change to old md5 auth, because php73 does not support it.
# #password_encryption = scram-sha-256
(Get-Content "$env:PGDATA\postgresql.conf"). `
replace('#password_encryption = scram-sha-256', 'password_encryption = md5') | `
Set-Content "$env:PGDATA\postgresql.conf"
(Get-Content "$env:PGDATA\pg_hba.conf"). `
replace('scram-sha-256', 'md5') | `
Set-Content "$env:PGDATA\pg_hba.conf"
$pgService = Get-Service -Name postgresql*
Set-Service -InputObject $pgService -Status running -StartupType automatic
Start-Process -FilePath "$env:PGBIN\pg_isready" -Wait -PassThru
& $env:PGBIN\psql --command="CREATE USER test PASSWORD 'test'" --command="\du"
- name: Creating DB pgsql
if: ${{ matrix.db == 'pgsql' }}
run: |
& $env:PGBIN\createdb --owner=test test
$env:PGPASSWORD = 'test'
& $env:PGBIN\psql --username=test --host=localhost --list test
- name: Configuring git vars
uses: rlespinasse/github-slug-action@v4
- name: Setting up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: ${{ matrix.extensions }}
ini-values: max_input_vars=5000
coverage: none
- name: Set git to use LF
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
uses: actions/checkout@v4
# Needs to be done after php is available, git configured and Moodle checkout has happened.
- name: Setting up moodle-exttests service
run: |
git clone https://github.com/moodlehq/moodle-exttests.git
nssm install php-built-in C:\tools\php\php.exe -S localhost:8080 -t D:\a\moodle\moodle\moodle-exttests
nssm start php-built-in
- name: Setting up redis service
run: |
choco install redis-64 --version 3.0.503 --no-progress
nssm install redis redis-server
nssm start redis
- name: Setting up PHPUnit
env:
dbtype: ${{ matrix.db }}
shell: bash
run: |
echo "pathtophp=$(which php)" >> $GITHUB_ENV # Inject installed pathtophp to env. The template config needs it.
cp .github/workflows/config-template.php config.php
mkdir ../moodledata
php admin/tool/phpunit/cli/init.php --no-composer-self-update
- name: Running PHPUnit tests
env:
dbtype: ${{ matrix.db }}
phpunit_options: ${{ secrets.phpunit_options }}
run: vendor/bin/phpunit $phpunit_options ${{ inputs.phpunit_extra_options }}
+1 -4
View File
@@ -20,15 +20,13 @@
*~
#
/config.php
/lib/editor/tinymce/extra/tools/temp/
/tags
/TAGS
/cscope.*
/.patches/
/.idea/
.phpstorm.*
!/.phpstorm.meta.php/
/.phpstorm.meta.php/*
!/.phpstorm.meta.php/di.php
/nbproject/
CVS
.DS_Store
@@ -58,4 +56,3 @@ moodle-plugin-ci.phar
.hugo_build.lock
phpcs.xml
jsconfig.json
UPGRADING-CURRENT.md
+3 -178
View File
@@ -40,20 +40,9 @@ const fetchComponentData = () => {
if (!Object.entries(componentData).length) {
componentData.subsystems = {};
componentData.pathList = [];
componentData.components = {};
componentData.standardComponents = {};
// Fetch the component definiitions from the distributed JSON file.
const components = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/components.json`));
const pluginData = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/plugins.json`));
componentData.pluginTypes = components.plugintypes;
const standardPlugins = Object.entries(pluginData.standard).map(
([pluginType, pluginNames]) => {
return pluginNames.map(pluginName => `${pluginType}_${pluginName}`);
}
).reduce((acc, val) => acc.concat(val), []);
// Build the list of moodle subsystems.
componentData.subsystems.lib = 'core';
@@ -66,8 +55,8 @@ const fetchComponentData = () => {
}
}
// The list of components includes the list of subsystems.
componentData.components = {...componentData.subsystems};
// The list of components incldues the list of subsystems.
componentData.components = componentData.subsystems;
// Go through each of the plugintypes.
Object.entries(components.plugintypes).forEach(([pluginType, pluginTypePath]) => {
@@ -98,20 +87,6 @@ const fetchComponentData = () => {
});
});
// Create a list of the standard subsystem and plugins.
componentData.standardComponents = Object.fromEntries(
Object.entries(componentData.components).filter(([, name]) => {
if (name === 'core' || name.startsWith('core_')) {
return true;
}
return standardPlugins.indexOf(name) !== -1;
})
);
componentData.componentMapping = Object.fromEntries(
Object.entries(componentData.components).map(([path, name]) => [name, path])
);
}
return componentData;
@@ -181,7 +156,7 @@ const getThirdPartyLibsList = relativeTo => {
* @returns {array}
*/
const getThirdPartyPaths = () => {
const DOMParser = require('@xmldom/xmldom').DOMParser;
const DOMParser = require('xmldom').DOMParser;
const fs = require('fs');
const path = require('path');
const xpath = require('xpath');
@@ -257,155 +232,6 @@ const getOwningComponentDirectory = checkPath => {
return null;
};
/**
* Get the latest tag in a remote GitHub repository.
*
* @param {string} url The remote repository.
* @returns {Array}
*/
const getRepositoryTags = async(url) => {
const gtr = require('git-tags-remote');
try {
const tags = await gtr.get(url);
if (tags !== undefined) {
return tags;
}
} catch (error) {
return [];
}
return [];
};
/**
* Get the list of thirdparty libraries that could be upgraded.
*
* @returns {Array}
*/
const getThirdPartyLibsUpgradable = async() => {
const libraries = getThirdPartyLibsData().filter((library) => !!library.repository);
const upgradableLibraries = [];
const versionCompare = (a, b) => {
if (a === b) {
return 0;
}
const aParts = a.split('.');
const bParts = b.split('.');
for (let i = 0; i < Math.min(aParts.length, bParts.length); i++) {
const aPart = parseInt(aParts[i], 10);
const bPart = parseInt(bParts[i], 10);
if (aPart > bPart) {
// 1.1.0 > 1.0.9
return 1;
} else if (aPart < bPart) {
// 1.0.9 < 1.1.0
return -1;
} else {
// Same version.
continue;
}
}
if (aParts.length > bParts.length) {
// 1.0.1 > 1.0
return 1;
}
// 1.0 < 1.0.1
return -1;
};
for (let library of libraries) {
upgradableLibraries.push(
getRepositoryTags(library.repository).then((tagMap) => {
library.version = library.version.replace(/^v/, '');
const currentVersion = library.version.replace(/moodle-/, '');
const currentMajorVersion = library.version.split('.')[0];
const tags = [...tagMap]
.map((tagData) => tagData[0])
.filter((tag) => !tag.match(/(alpha|beta|rc)/))
.map((tag) => tag.replace(/^v/, ''))
.sort((a, b) => versionCompare(b, a));
if (!tags.length) {
library.warning = "Unable to find any comparable tags.";
return library;
}
library.latestVersion = tags[0];
tags.some((tag) => {
if (!tag) {
return false;
}
// See if the version part matches.
const majorVersion = tag.split('.')[0];
if (majorVersion === currentMajorVersion) {
library.latestSameMajorVersion = tag;
return true;
}
return false;
});
if (versionCompare(currentVersion, library.latestVersion) > 0) {
// Moodle somehow has a newer version than the latest version.
library.warning = `Newer version found: ${currentVersion} > ${library.latestVersion} for ${library.name}`;
return library;
}
if (library.version !== library.latestVersion) {
// Delete version and add it again at the end of the array. That way, current and new will stay closer.
delete library.version;
library.version = currentVersion;
return library;
}
return null;
})
);
}
return (await Promise.all(upgradableLibraries)).filter((library) => !!library);
};
/**
* Get the list of thirdparty libraries.
*
* @returns {Array}
*/
const getThirdPartyLibsData = () => {
const DOMParser = require('@xmldom/xmldom').DOMParser;
const fs = require('fs');
const xpath = require('xpath');
const path = require('path');
const libraryList = [];
const libraryFields = [
'location',
'name',
'version',
'repository',
];
const thirdpartyfiles = getThirdPartyLibsList(fs.realpathSync('./'));
thirdpartyfiles.forEach(function(libraryPath) {
const xmlContent = fs.readFileSync(libraryPath, 'utf8');
const doc = new DOMParser().parseFromString(xmlContent);
const libraries = xpath.select("/libraries/library", doc);
for (const library of libraries) {
const libraryData = [];
for (const field of libraryFields) {
libraryData[field] = xpath.select(`${field}/text()`, library)?.toString();
}
libraryData.location = path.join(path.dirname(libraryPath), libraryData.location);
libraryList.push(libraryData);
}
});
return libraryList.sort((a, b) => a.location.localeCompare(b.location));
};
module.exports = {
fetchComponentData,
getAmdSrcGlobList,
@@ -415,5 +241,4 @@ module.exports = {
getYuiSrcGlobList,
getThirdPartyLibsList,
getThirdPartyPaths,
getThirdPartyLibsUpgradable,
};
+1 -1
View File
@@ -16,4 +16,4 @@ Moodle - the world's open source learning platform
This generated documentation includes API documentation for JavaScript written in the AMD and ES2015 module formats within Moodle.
## Related information
See [https://moodledev.io](https://moodledev.io) for other related Developer Documentation.
See [https://docs.moodle.org/dev](https://docs.moodle.org/dev) for other related Developer Documentation.
+1 -1
View File
@@ -114,7 +114,7 @@ module.exports = {
],
"menu": {
"Developer Docs": {
href: "https://moodledev.io",
href: "https://docs.moodle.org/dev",
target: "_blank",
"class": "menu-item",
id: "devdocs"
-138
View File
@@ -1,138 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
import * as Components from '../../components.js';
const componentData = Components.fetchComponentData();
/**
* The standard components shipped with core Moodle.
*
* @type {Object}
*/
export const standardComponents = componentData.standardComponents;
/**
* All components of the current Moodle instance.
*
* @type {Object}
*/
export const allComponents = componentData.components;
/**
* Get all components of the current Moodle instance.
*
* @returns {Array}
*/
export const getAllComponents = () => {
let components = new Map(Object.entries(componentData.pluginTypes).map(([value, path]) => ([path,{
path,
value,
name: `${value} (plugin type)`,
}])));
Object
.entries(componentData.components)
.filter(([path, value]) => Object.values(componentData.standardComponents).includes(value))
.forEach(([path, value]) => {
const entry = {
path,
value,
name: value,
};
if (Object.values(componentData.subsystems).includes(value)) {
if (components.has(path)) {
entry.name = `${value} (subsystem / plugintype)`;
} else {
entry.name = `${value} (subsystem)`;
}
}
components.set(path, entry);
});
return Array.from(components.values());
};
/**
* Whether the specified component is a standard component shipped with core Moodle.
*
* @param {string} componentName
* @returns {boolean}
*/
export const isStandardComponent = (componentName) => {
if (Object.values(componentData.standardComponents).includes(componentName)) {
return true;
}
if (Object.keys(componentData.pluginTypes).includes(componentName)) {
return true;
}
return false;
};
export const rewritePlugintypeAsSubsystem = (componentName) => {
if (Object.keys(componentData.pluginTypes).includes(componentName)) {
const pluginTypePath = componentData.pluginTypes[componentName];
if (Object.keys(componentData.subsystems).includes(pluginTypePath)) {
return true;
}
}
return false;
};
/**
* Whether the specified component is a community component.
*
* @param {string} componentName
* @returns {boolean}
*/
export const isCommunityComponent = (componentName) => {
if (isStandardComponent(componentName)) {
return false;
}
return Object.values(componentData.components).indexOf(componentName) !== -1;
};
/**
* Sort method for components.
*
* This method sorts components putting `core` first, followed by core subsystems, then everything else.
*
* @param {String} a
* @param {String} b
* @returns {Number}
*/
export const sortComponents = (a, b) => {
// Always put 'core' first.
if (a === 'core') {
return -1;
} else if (b === 'core') {
return 1;
}
// Put core subsystems next.
if (a.startsWith('core_') && !b.startsWith('core_')) {
return -1;
} else if (b.startsWith('core_') && !a.startsWith('core_')) {
return 1;
}
// Sort alphabetically for everything else.
return a.localeCompare(b);
};
-85
View File
@@ -1,85 +0,0 @@
#!/usr/bin/env node
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
import inquirer from 'inquirer';
import chalk from 'chalk';
import { createNote } from './note.mjs';
import { getInitialValues } from './helpers.mjs';
import * as Prompts from './prompts.mjs';
import logger from './logger.mjs';
export default async (options) => {
// Processs the initial values.
const initialValues = getInitialValues(options);
// Fetch information.
const messages = [];
const { issueNumber } = await inquirer.prompt([
Prompts.getIssuePrompt(),
], initialValues);
let selection = {};
let notePath;
do {
selection = {};
selection = await inquirer.prompt([
Prompts.getComponentsPrompt(),
Prompts.getTypePrompt(),
Prompts.getMessagePromptInput(),
], initialValues);
if (selection.message === '') {
selection = Object.assign(
selection,
await inquirer.prompt([
Prompts.getMessagePromptEditor(),
]),
);
}
logger.info(`
Creating upgrade note with the following options:
- Issue: ${chalk.bold(issueNumber)}
- Component: ${chalk.bold(selection.components)}
- Type: ${chalk.bold(selection.type)}
- Message:
${chalk.bold(selection.message)}
`);
messages.push({
components: [selection.components],
type: selection.type,
message: selection.message,
});
// Save the note so far.
if (notePath) {
await createNote(issueNumber, messages, notePath);
logger.info(`Updated note at: ${chalk.underline(chalk.bold(notePath))}`);
} else {
notePath = await createNote(issueNumber, messages);
logger.info(`Note created at: ${chalk.underline(chalk.bold(notePath))}`);
}
selection = Object.assign(
selection,
await inquirer.prompt([
Prompts.getAddAnotherPrompt(),
], initialValues),
);
} while (selection.addAnother);
};
-357
View File
@@ -1,357 +0,0 @@
#!/usr/bin/env node
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
import chalk from 'chalk';
import { getAllComponents } from './components.mjs';
import { getCombinedNotesByComponent, deleteAllNotes } from './note.mjs';
import { getNoteName } from './noteTypes.mjs';
import { writeFile, readFile, unlink } from 'fs/promises';
import { join as joinPath } from 'path';
import logger from './logger.mjs';
import { getCurrentVersion } from './helpers.mjs';
/**
* Helper to fetch the current notes from a file.
*
* @param {string} file
* @returns {Promise<string>}
*/
const getCurrentNotes = async (file) => {
try {
return await readFile(file, 'utf8');
} catch (error) {
return null;
}
}
/**
* Update the UPGRADING.md file.
*
* @param {string} upgradeNotes
* @param {Object} options
* @param {boolean} options.deleteNotes
* @returns {Promise<void>}
*/
const updateUpgradeNotes = async (upgradeNotes, options) => {
const fileName = 'UPGRADING.md';
// Write the notes to a file.
logger.info(`Writing notes to ${chalk.underline(chalk.bold(fileName))}`);
// Prepend to the existing file.
const existingContent = await getCurrentNotes(fileName);
if (existingContent) {
await writeFile(fileName, getUpdatedNotes(existingContent, upgradeNotes));
} else {
// This should not normally happen.
await writeFile(fileName, upgradeNotes);
}
if (options.deleteNotes) {
logger.warn(`>>> Deleting all notes <<<`)
// Delete the notes.
deleteAllNotes();
}
};
/**
* Create the current summary notes.
*
* @param {string} upgradeNotes
* @returns {Promise<void>}
*/
const createCurrentSummary = async (upgradeNotes) => {
const fileName = 'UPGRADING-CURRENT.md';
const notes = `# Moodle upgrade notes\n\n${upgradeNotes}`;
await writeFile(fileName, notes);
logger.info(`Running upgrade notes written to ${chalk.underline(chalk.bold(fileName))}`);
};
/**
* Get the indexes of the lines that contain the version headings.
*
* @param {array<string>} lines
* @returns {array<object>}
*/
const getVersionLineIndexes = (lines) => {
const h2Indexes = [];
lines.forEach((line, index) => {
const matches = line.match(/^##\s(?<version>.*)$/);
if (matches) {
h2Indexes.push({
index,
line,
version: matches.groups.version,
});
}
});
return h2Indexes;
};
/**
* Find the index of the Unreleased heading.
*
* @param {array<object>} versionHeadings
* @returns {number}
*/
const findUnreleasedHeadingIndex = (versionHeadings) => versionHeadings.findIndex((heading) => {
if (heading.version === 'Unreleased') {
// Used if version cannot be guessed.
return true;
}
if (heading.version.endsWith('+')) {
// Weekly release for a stable branch.
return true;
}
if (heading.version.match(/beta|rc\d/)) {
// Beta and RC rolls are treated as weeklies.
return true;
}
if (heading.version.endsWith('dev')) {
// Development version.
return true;
}
return false;
});
/**
* Get the before and after content, to facilitate replacing any existing Unreleased notes.
*
* @param {array<string>} lines
* @returns {Object} {beforeContent: string, afterContent: string}
*/
const getBeforeAndAfterContent = (lines) => {
const existingLines = lines.split('\n');
const versionHeadings = getVersionLineIndexes(existingLines);
if (versionHeadings.length > 0) {
const unreleasedHeadingIndex = findUnreleasedHeadingIndex(versionHeadings);
if (unreleasedHeadingIndex !== -1) {
const beforeContent = existingLines.slice(0, versionHeadings[unreleasedHeadingIndex].index).join('\n');
if (versionHeadings.length > unreleasedHeadingIndex + 1) {
const afterContent = existingLines.slice(versionHeadings[unreleasedHeadingIndex + 1].index).join('\n');
return {
beforeContent,
afterContent,
};
}
return {
beforeContent,
afterContent: '',
};
}
return {
beforeContent: existingLines.slice(0, versionHeadings[0].index).join('\n'),
afterContent: existingLines.slice(versionHeadings[0].index).join('\n'),
};
}
return {
beforeContent: existingLines.join('\n'),
afterContent: '',
}
};
/**
* Get the notes for the component.
*
* @param {string} types
* @param {Number} headingLevel
* @returns {string}
*/
const getNotesForComponent = (types, headingLevel) => {
let upgradeNotes = '';
Object.entries(types).forEach(([type, notes]) => {
upgradeNotes += '#'.repeat(headingLevel);
upgradeNotes += ` ${getNoteName(type)}\n\n`;
notes.forEach(({ message, issueNumber }) => {
// Split the message into lines, removing empty lines.
const messageLines = message
.split('\n')
// Remove empty lines between tables, and list entries, but not after lists.
.filter((line, index, lines) => {
if (line.trim().length === 0) {
// This line is empty.
// If it's the first line in the file, remove it.
if (index === 0) {
return false;
}
// This is the last line in the file, remove it.
if (index === lines.length - 1) {
return false;
}
// If the previous line relates to a table, remove this line.
if (lines[index - 1].match(/^\s*\|/)) {
return false;
}
// If the next line is also empty, do not remove this line.
if (lines[index + 1].trim().length === 0) {
return true;
}
// Do not remove the line if the previous line was a list item.
if (lines[index - 1].match(/^\s*[-*]\s/)) {
return true;
}
if (lines[index - 1].match(/^\s*\d+\.\s/)) {
return true;
}
// Preserve all other empty lines by default.
return true;
}
// Keep any line which has content.
return true;
});
const firstLine = messageLines.shift().trim();
upgradeNotes += `- ${firstLine}\n`;
messageLines
.forEach((line) => {
upgradeNotes += ` ${line}`.trimEnd() + `\n`;
});
upgradeNotes += `\n For more information see [${issueNumber}](https://tracker.moodle.org/browse/${issueNumber})\n`;
});
upgradeNotes += '\n';
});
return upgradeNotes;
};
/**
* Get the updated notes mixed with existing content.
*
* @param {string} existingContent
* @param {string} upgradeNotes
*/
const getUpdatedNotes = (existingContent, upgradeNotes) => {
const { beforeContent, afterContent } = getBeforeAndAfterContent(existingContent);
const newContent = `${beforeContent}\n${upgradeNotes}\n${afterContent}`
.split('\n')
.filter((line, index, lines) => {
if (line === '' && lines[index - 1] === '') {
// Remove multiple consecutive empty lines.
return false;
}
return true;
})
.join('\n');
return newContent;
};
/**
* Update the notes for each component.
*/
const updateComponentNotes = (
notes,
version,
notesFileName = 'UPGRADING.md',
removeEmpty = false,
) => {
return getAllComponents().map(async (component) => {
logger.verbose(`Updating notes for ${component.name} into ${component.path}`);
const fileName = joinPath(component.path, notesFileName);
const existingContent = await getCurrentNotes(fileName);
if (!existingContent) {
if (!notes[component.value]) {
// No existing notes, and no new notes to add.
return;
}
} else {
if (!notes[component.value]) {
// There is existing content, but nothing to add.
if (removeEmpty) {
logger.verbose(`Removing empty notes file ${fileName}`);
await unlink(fileName);
}
return;
}
}
const componentNotes = notes[component.value];
let upgradeNotes = `## ${version}\n\n`;
upgradeNotes += getNotesForComponent(componentNotes, 3);
if (existingContent) {
await writeFile(fileName, getUpdatedNotes(existingContent, upgradeNotes));
} else {
await writeFile(
fileName,
`# ${component.name} Upgrade notes\n\n${upgradeNotes}`,
);
}
});
}
/**
* Generate the upgrade notes for a new release.
*
* @param {string|undefined} version
* @param {Object} options
* @param {boolean} options.generateUpgradeNotes
* @param {boolean} options.deleteNotes
* @returns {Promise<void>}
*/
export default async (version, options = {}) => {
const notes = await getCombinedNotesByComponent();
if (Object.keys(notes).length === 0) {
logger.warn('No notes to generate');
return;
}
if (!version) {
version = await getCurrentVersion();
}
// Generate the upgrade notes for this release.
// We have
// - a title with the release name
// - the change types
// - which contain the components
// - which document each change
let upgradeNotes = `## ${version}\n\n`;
Object.entries(notes).forEach(([component, types]) => {
upgradeNotes += `### ${component}\n\n`;
upgradeNotes += getNotesForComponent(types, 4);
});
await Promise.all([
createCurrentSummary(upgradeNotes),
...updateComponentNotes(notes, version, 'UPGRADING-CURRENT.md', true),
]);
if (options.generateUpgradeNotes) {
await Promise.all(updateComponentNotes(notes, version));
await updateUpgradeNotes(upgradeNotes, options);
}
};
-230
View File
@@ -1,230 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
import chalk from 'chalk';
import { isStandardComponent, isCommunityComponent, rewritePlugintypeAsSubsystem } from './components.mjs';
import { isValidNoteName } from './noteTypes.mjs';
import logger from './logger.mjs';
import { readFile } from 'fs/promises';
/**
* Validate an issue number input
*
* @param {string} input
* @returns {string|boolean}
*/
export const validateIssueNumber = (input) => {
if (!input) {
return 'You must provide a tracker issue number';
}
if (input.match(/^[a-zA-Z]*-\d+$/)) {
return true;
}
if (input.match(/^\d+$/)) {
return true;
}
return 'The issue number was not recognised as a valid issue number';
};
/**
* Format an issue number input.
*
* @param {string} input
* @returns {string}
*/
export const formatIssueNumber = (input) => {
if (input.match(/^[a-zA-Z]*-\d+$/)) {
return input;
}
if (input.match(/^\d+$/)) {
return `MDL-${input}`;
}
return input;
};
/**
* Validate a component.
*
* @param {string} input
* @returns {string|boolean}
*/
export const validateComponent = (input) => {
if (isStandardComponent(input)) {
return true;
}
if (isCommunityComponent(input)) {
return 'Currently only core plugins are supported.';
}
return 'The component was not recognised as a standard component';
};
export const formatComponent = (input) => {
if (rewritePlugintypeAsSubsystem(input)) {
return `core_${input}`;
}
return input;
}
/**
* Get the initial values from the options.
*
* @param {object} options
* @returns {object}
*/
export const getInitialValues = (options) => {
const initialValues = {};
const type = getInitialTypeValue(options);
if (type) {
initialValues.type = type;
}
const issueNumber = getInitialIssueValue(options);
if (issueNumber) {
initialValues.issueNumber = issueNumber;
}
const component = getInitialComponentValue(options);
if (component) {
initialValues.components = component;
}
const message = getInitialMessageValue(options);
if (message) {
initialValues.message = message
initialValues.addAnother = false;
}
return initialValues;
};
/**
* Get the initial type value.
*
* @param {Object} options
* @returns {string|undefined}
*/
const getInitialTypeValue = (options) => {
if (!options.type) {
return;
}
options.type = options.type.trim().toLowerCase();
if (isValidNoteName(options.type)) {
return options.type;
}
logger.warn(`Note type "${chalk.underline(chalk.red(options.type))}" is not valid.`);
};
/**
* Get the initial issue number value.
*
* @param {Object} options
* @returns {string|undefined}
*/
const getInitialIssueValue = (options) => {
if (!options.issue) {
return;
}
options.issue = options.issue.trim().toUpperCase();
const issueNumberValidated = validateIssueNumber(options.issue);
if (issueNumberValidated === true) {
const issueNumber = formatIssueNumber(options.issue);
if (issueNumber !== options.issue) {
logger.warn(
`Issue number "${chalk.underline(chalk.red(options.issue))}" was updated to ` +
`"${chalk.underline(chalk.green(issueNumber))}"`
);
}
return issueNumber;
} else {
logger.warn(`Issue number "${chalk.underline(chalk.red(options.issue))}" is not valid: ${issueNumberValidated}`);
}
};
/**
* Get the initial component value.
*
* @param {Object} options
* @returns {string|undefined}
*/
const getInitialComponentValue = (options) => {
if (!options.component) {
return;
}
options.component = options.component.trim().toLowerCase();
const componentValidated = validateComponent(options.component);
if (componentValidated === true) {
const component = formatComponent(options.component);
if (component !== options.component) {
logger.warn(
`Component "${chalk.underline(chalk.red(options.component))}" was updated to ` +
`"${chalk.underline(chalk.green(component))}"`
);
}
return component;
} else {
logger.warn(`Component "${chalk.underline(chalk.red(options.component))}" is not valid: ${componentValidated}`);
}
};
/**
* Get the initial message value.
*
* @param {Object} options
* @returns {string|undefined}
*/
const getInitialMessageValue = (options) => {
if (!options.message) {
return;
}
return options.message.trim();
};
/**
* Get the current version from the project /version.php file.
*
* @returns {Promise<string>}
*/
export const getCurrentVersion = async () => {
const versionRegex = new RegExp(/^ *\$release *= *['\"](?<release>[^ \+]+\+?) *\(Build:.*/m);
try {
const versionFile = await readFile('version.php', 'utf8');
const match = versionFile.match(versionRegex);
if (match) {
return match.groups.release;
}
} catch(error) {
logger.error('Unable to read the version file');
}
return "Unreleased";
}
-30
View File
@@ -1,30 +0,0 @@
#!/usr/bin/env node
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
import winston from 'winston';
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple()
),
transports: [
new winston.transports.Console(),
],
});
export default logger;
-194
View File
@@ -1,194 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
import yaml from 'js-yaml';
import path from 'path';
import { writeFile, mkdir, readdir, readFile, unlink } from 'fs/promises';
import { isValidNoteName, sortNoteTypes } from './noteTypes.mjs';
import { sortComponents } from './components.mjs';
const unreleasedPath = path.resolve('.upgradenotes');
/**
* Get the filename for the note.
*
* @param {string} issueNumnber The issue number
* @returns {string}
*/
const getFilename = (issueNumber) => {
const dateTimeFormat = new Intl.DateTimeFormat(undefined, {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
fractionalSecondDigits: 2,
timeZone: 'UTC',
});
const date = Object.fromEntries(
dateTimeFormat.formatToParts(new Date())
.filter((p) => p.type !== 'literal')
.map((p) => ([p.type, p.value]))
);
const dateString = [
date.year,
date.month,
date.day,
date.hour,
date.minute,
date.second,
date.fractionalSecond,
].join('');
return `${issueNumber}-${dateString}.yml`;
};
/**
* Create a new note.
*
* @param {string} issueNumber
* @param {[type: string]: {message: string}} messages
* @returns {string} The path to the note on disk
*/
export const createNote = async (
issueNumber,
messages,
notePath,
) => {
const note = {
issueNumber,
notes: {},
};
messages.forEach(({components, type, message}) => {
note.notes[components] = note.notes[components] || [];
note.notes[components].push({message, type});
});
if (!notePath) {
notePath = path.resolve(unreleasedPath, getFilename(issueNumber));
}
const noteContent = yaml.dump(note);
await mkdir(unreleasedPath, {recursive: true});
await writeFile(notePath, noteContent);
return notePath;
};
/**
* Get all unreleased notes.
*
* @returns {Promise<{issueNumber: string, components: string[], types: {[type: string]: {message: string}[]}}[]>
*/
export const getAllNotes = async () => {
const files = await readdir(unreleasedPath);
const notes = files
.filter((file) => file.endsWith('.yml'))
.map(async (file) => {
const filePath = path.resolve(unreleasedPath, file);
const fileContent = await readFile(filePath, 'utf8');
return {
...yaml.load(fileContent),
filePath,
};
});
return Promise.all(notes);
};
/**
* Get the list of notes, grouped by note type, then component.
*
* @returns {Promise<{[type: string]: {[components: string]: {message: string, issueNumber: string}[]}}>}
*/
export const getCombinedNotes = async () => {
const notes = await getAllNotes();
const combinedNotes = {};
notes.forEach((note) => {
Object.entries(note.notes).forEach(([components, data]) => {
data.forEach((entry) => {
if (!isValidNoteName(entry.type)) {
throw new Error(`Invalid note type: "${entry.type}" in file ${note.filePath}`);
}
combinedNotes[entry.type] = combinedNotes[entry.type] || {};
combinedNotes[entry.type][components] = combinedNotes[entry.type][components] || [];
combinedNotes[entry.type][components].push({message: entry.message, issueNumber: note.issueNumber});
});
});
});
return combinedNotes;
};
/**
* Get the list of notes, grouped by component, then by note type.
*
* @returns {Promise<{[component: string]: {[type: string]: {message: string, issueNumber: string}[]}}>}
*/
export const getCombinedNotesByComponent = async () => {
const notes = await getAllNotes();
const combinedNotes = {};
notes.forEach((note) => {
Object.entries(note.notes).forEach(([component, data]) => {
combinedNotes[component] = combinedNotes[component] || {};
data.forEach((entry) => {
if (!isValidNoteName(entry.type)) {
throw new Error(`Invalid note type: "${entry.type}" in file ${note.filePath}`);
}
combinedNotes[component][entry.type] = combinedNotes[component][entry.type] || [];
combinedNotes[component][entry.type].push({
component,
message: entry.message,
issueNumber: note.issueNumber,
type: entry.type,
});
});
});
});
// Sort notes by note type.
Object.entries(combinedNotes).forEach(([component, types]) => {
combinedNotes[component] = Object.fromEntries(
Object.entries(types).sort(([a], [b]) => sortNoteTypes(a, b))
);
});
// Sort components.
return Object.fromEntries(
Object.entries(combinedNotes).sort(([a], [b]) => sortComponents(a, b))
);
};
/**
* Delete all unreleased notes.
*
* @returns {Promise<void>}
*/
export const deleteAllNotes = async () => {
const files = await readdir(unreleasedPath);
return Promise.all(
files
.filter((item, index) => files.indexOf(item) === index)
.filter((file) => file.endsWith('.yml'))
.map((file) => unlink(`${unreleasedPath}/${file}`))
);
};
-80
View File
@@ -1,80 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* The note types.
*
* Matches the suggested order in https://keepachangelog.com/en/1.1.0/.
* @type {Object<string, string>}
*/
const noteTypes = {
'improved': 'Added',
'changed': 'Changed',
'deprecated': 'Deprecated',
'removed': 'Removed',
'fixed': 'Fixed',
};
/**
* The preferred order of note types.
*
* @type {string[]}
*/
const preferredOrder = Object.keys(noteTypes);
/**
* Comparison method to sort note types.
*
* @param {String} a
* @param {String} b
* @returns {Number}
*/
export const sortNoteTypes = (a, b) => {
const aIndex = preferredOrder.indexOf(a);
const bIndex = preferredOrder.indexOf(b);
if (aIndex === -1) {
return 1;
}
if (bIndex === -1) {
return -1;
}
return aIndex - bIndex;
};
/**
* Get the note names.
*
* @returns {string[]}
*/
export const getNoteNames = () => Object.keys(noteTypes);
/**
* Get the human-readable note name.
*
* @param {string} type
* @returns {string}
*/
export const getNoteName = (type) => noteTypes[type];
/**
* Whether the note name is valid.
*
* @param {string} type
* @returns {boolean}
*/
export const isValidNoteName = (type) => noteTypes[type] !== undefined;
-153
View File
@@ -1,153 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
import inquirer from 'inquirer';
import SearchList from 'inquirer-search-list';
import { getNoteNames } from './noteTypes.mjs';
import { getAllComponents } from './components.mjs';
import {
formatComponent,
formatIssueNumber,
validateComponent,
validateIssueNumber,
} from './helpers.mjs';
/**
* A Search List which accepts an initial value.
*/
class SearchListWithInitialValue extends SearchList {
constructor(options, ...args) {
super(options, ...args);
if (options.default) {
const pointer = this.filterList.findIndex((item) => {
return item.value === options.default;
});
if (pointer > -1) {
this.pointer = pointer;
}
}
}
}
inquirer.registerPrompt('search-list', SearchListWithInitialValue);
/**
* Get the issue type prompt.
*
* @param {string} defaultData The initially selected value
* @returns {Object}
*/
export const getTypePrompt = (defaultData) => ({
default: defaultData,
type: 'search-list',
message: 'Type of change',
name: 'type',
choices: getNoteNames(),
validate: (selection) => {
if (selection.length < 1) {
return 'You must select at least one type of change';
}
return true;
},
});
/**
* Get the component prompt.
*
* @param {string} [defaultValue='core'] The initally selected value.
* @returns
*/
export const getComponentsPrompt = (defaultValue) => {
if (!defaultValue ) {
defaultValue = 'core';
}
return {
choices: getAllComponents(),
default: defaultValue,
type: 'search-list',
message: 'Component',
name: 'components',
validate: validateComponent,
filter: formatComponent,
};
};
/**
* Get the issue number prompt as an inline input.
*
* @param {string} defaultData
* @returns {object}
*/
export const getIssuePrompt = (defaultData) => ({
default: defaultData,
type: 'input',
message: 'Tracker issue number',
name: 'issueNumber',
validate: validateIssueNumber,
filter: formatIssueNumber,
});
/**
* Get a message prompt.
*
* @param {string} defaultData
* @returns
*/
export const getMessagePromptEditor = (defaultData) => ({
default: defaultData,
type: process.stdin.isTTY ? 'editor' : 'input',
postfix: '.md',
message: 'Message',
name: 'message',
waitUserInput: false,
validate: (input) => {
if (!input) {
return 'You must provide a message';
}
return true;
},
// Remove any trailing whitespace.
filter: (input) => input.split('\n').map((line) => line.trimEnd()).join('\n'),
});
/**
* Get a message prompt.
*
* @param {string} defaultData
* @returns
*/
export const getMessagePromptInput = (defaultData) => ({
default: defaultData,
type: 'input',
message: 'Message (leave empty to use editor)',
name: 'message',
filter: (input) => input.trim(),
});
/**
* Get a prompt to ask the user if they wish to add another entry.
*
* @returns {Object}
*/
export const getAddAnotherPrompt = () => ({
type: 'confirm',
message: 'Do you want to add another note?',
default: false,
name: 'addAnother',
});
+6 -8
View File
@@ -45,7 +45,6 @@ module.exports = grunt => {
grunt.log.write(result);
if (error) {
grunt.log.error(result.stdout);
process.exit(code);
}
done();
@@ -57,7 +56,7 @@ module.exports = grunt => {
* @param {array} args
* @returns {object}
*/
const spawnNodeCall = (args) => grunt.util.spawn({
const spawnNodeCall = args => grunt.util.spawn({
cmd: 'node',
args,
}, getSpawnHandler(grunt.task.current.async()));
@@ -92,14 +91,13 @@ module.exports = grunt => {
* @returns {Object} Reference to the spawned task
*/
const cssBuild = () => spawnNodeCall([
'node_modules/sass/sass.js',
'--style', 'expanded',
'--source-map',
'--embed-sources',
'node_modules/node-sass/bin/node-sass',
'--output-style', 'expanded',
'--source-map', true,
'--source-map-contents', true,
'--precision', 6,
'--load-path', process.cwd(),
getCLPath('hugo/scss/docs.scss'),
getCLPath('hugo/dist/css/docs.css'),
'-o', getCLPath('hugo/dist/css/'),
]);
// Register the various component library tasks.
+22 -9
View File
@@ -21,7 +21,7 @@
*/
/**
* Function to generate the destination for the minification task
* Function to generate the destination for the uglify task
* (e.g. build/file.min.js). This function will be passed to
* the rename property of files array when building dynamically:
* http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically
@@ -30,9 +30,10 @@
* @param {String} srcPath the matched src path
* @return {String} The rewritten destination path.
*/
const babelRename = function(destPath, srcPath) {
destPath = srcPath.replace(`amd/src`, `amd/build`);
destPath = destPath.replace(/\.js$/, '.min.js');
destPath = srcPath.replace('src', 'build');
destPath = destPath.replace('.js', '.min.js');
return destPath;
};
@@ -60,6 +61,7 @@ module.exports = grunt => {
grunt.registerTask('js', ['amd', 'yui']);
// Register NPM tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-rollup');
@@ -103,7 +105,6 @@ module.exports = grunt => {
// The queue runner will run the next `size` items in the queue.
const runQueue = (size = 1) => {
queue.splice(0, size).forEach(resolve => {
grunt.log.debug(`Item resolved. Kicking off next one.`);
resolve();
});
};
@@ -113,17 +114,15 @@ module.exports = grunt => {
// The options hook is run in parallel.
// We can return an unresolved Promise which is queued for later resolution.
options: async(options) => {
options: async() => {
return new Promise(resolve => {
queue.push(resolve);
startQueue();
return options;
});
},
// When an item in the queue completes, start the next item in the queue.
generateBundle: (options, bundle) => {
grunt.log.debug(`Finished output phase for ${Object.keys(bundle).join(', ')}`);
buildEnd: () => {
runQueue();
},
};
@@ -153,10 +152,24 @@ module.exports = grunt => {
//
// It also adds the Moodle plugin name to the AMD module definition
// so that it can be imported as expected in other modules.
path.resolve('.grunt/babel-plugin-add-module-to-define.js')
path.resolve('.grunt/babel-plugin-add-module-to-define.js'),
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-syntax-import-meta',
['@babel/plugin-proposal-class-properties', {'loose': false}],
'@babel/plugin-proposal-json-strings'
],
presets: [
['@babel/preset-env', {
targets: {
browsers: [
">0.3%",
"last 2 versions",
"not ie >= 0",
"not op_mini all",
"not Opera > 0",
"not dead"
]
},
modules: false,
useBuiltIns: false
}]
+12 -28
View File
@@ -20,33 +20,17 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = (grunt) => {
const path = require('path');
grunt.registerTask('jsdoc', 'Generate JavaScript documentation using jsdoc', function() {
const done = this.async();
const configuration = path.resolve('.grunt/jsdoc/jsdoc.conf.js');
grunt.util.spawn({
cmd: 'jsdoc',
args: [
'--configure',
configuration,
]
}, function(error, result, code) {
if (result.stdout) {
grunt.log.write(result.stdout);
}
if (result.stderr) {
grunt.log.error(result.stderr);
}
if (error) {
grunt.fail.fatal(`JSDoc failed with error code ${code}`);
} else {
grunt.log.write('JSDoc completed successfully'.green);
}
done();
});
module.exports = grunt => {
// Project configuration.
grunt.config.merge({
jsdoc: {
dist: {
options: {
configure: ".grunt/jsdoc/jsdoc.conf.js",
},
},
},
});
grunt.loadNpmTasks('grunt-jsdoc');
};
+1 -1
View File
@@ -32,7 +32,7 @@ module.exports = grunt => {
}
},
options: {
implementation: require('sass'),
implementation: require('node-sass'),
includePaths: ["theme/boost/scss/", "theme/classic/scss/"]
}
},
+1 -5
View File
@@ -29,7 +29,6 @@ module.exports = grunt => {
// Use a fully-qualified path.
src: files,
options: {
quietDeprecationWarnings: true,
configOverrides: {
rules: {
// These rules have to be disabled in .stylelintrc for scss compat.
@@ -46,10 +45,7 @@ module.exports = grunt => {
return {
stylelint: {
scss: {
options: {
quietDeprecationWarnings: true,
customSyntax: 'postcss-scss',
},
options: {syntax: 'scss'},
src: files,
},
},
-42
View File
@@ -1,42 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2023 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = grunt => {
/**
* Generate upgradable third-party libraries (utilising thirdpartylibs.xml data)
*/
grunt.registerTask('upgradablelibs', 'Generate upgradable third-party libraries', async function() {
const done = this.async();
const path = require('path');
const ComponentList = require(path.join(process.cwd(), '.grunt', 'components.js'));
// An array of third party libraries that have a newer version in their repositories.
const thirdPartyLibs = await ComponentList.getThirdPartyLibsUpgradable({progress: true});
for (let library of thirdPartyLibs) {
grunt.log.ok(JSON.stringify(Object.assign({}, library), null, 4));
}
done();
});
};
-103
View File
@@ -1,103 +0,0 @@
#!/usr/bin/env node
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
import { Argument, Option, program } from 'commander';
import chalk from 'chalk';
import { getNoteNames } from './notes/src/noteTypes.mjs';
import createAction from './notes/src/create.mjs';
import generateAction from './notes/src/generate.mjs';
import logger from './notes/src/logger.mjs';
console.log(`
${chalk.bold(chalk.underline(chalk.green('Moodle Upgrade Notes Generator')))}
This tool is used to generate the upgrade notes for changes you make in Moodle.
Please remember that the intended audience of these changes is
${chalk.italic('plugin developers')} who need to know how to update their plugins
for a new Moodle version.
Upgrade notes should not be used to document changes for site administrators, or
for internal API changes which are not expected to be used outside of the
relevant component.
`)
program.configureHelp({
helpWidth: 100,
});
program.on('option:verbose', () => {
logger.level = 'verbose';
});
program.addOption(
new Option(
'-v, --verbose',
'Output more information during the generation process',
)
.default(false)
);
// Define the command line options.
program
.command('create')
.summary('Generate a new upgrade note')
.addOption(
new Option('-t, --type <type>', `The type of change to document. Valid types are: ${getNoteNames().join(', ')}`)
)
.addOption(new Option('-i, --issue <issue>', 'The tracker issue number'))
.addOption(new Option('-c, --component <component>', 'The component to write a note for'))
.addOption(new Option(
'-m, --message <message>',
'The message to use for the upgrade note',
))
.action((options) => createAction(options));
program
.command('summary')
.summary('Generate a local copy of the upgrade notes summary')
.addArgument(
new Argument('[version]', 'The Moodle version to create the summary notes for')
)
.action((version) => generateAction(version));
program
.command('release')
.summary('Generate the markdown copies of the upgrade notes for a Moodle release')
.addArgument(
new Argument('[version]', 'The Moodle version to create the release notes for')
)
.addOption(
new Option(
'--generate-upgrade-notes',
'Generate the UPGRADING.md notes for the release. ' +
'Note: This option is intended for use by the release manager when generating the upgrade notes.',
)
.default(true)
)
.addOption(
new Option(
'-d, --delete-notes',
'Delete the notes after generating the UPGRADING.md notes for the release. ' +
'Note: This option is intended for use by the release manager when generating the upgrade notes.' +
'This option has no effect unless --generate-upgrade-notes is also set.'
)
.default(false)
)
.action((version, options) => generateAction(version, options));
program.parse();
+1 -1
View File
@@ -1 +1 @@
lts/iron
lts/gallium
-40
View File
@@ -1,40 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Helper file for PhpStorm, and other IDEs, to provide better code completion.
*
* @package core
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace PHPSTORM_META;
// Assume that anything returned by \core\di::get('...') is an instance of the first argument.
override(\core\di::get(0), map([
'' => '@',
]));
// Assume that anything returned by \Psr\Container\ContainerInterface::get('...') is an instance of the first argument.
override(\Psr\Container\ContainerInterface::get(0), map([
'' => '@',
]));
// Assume that anything returned by \DI\Container::get('...') is an instance of the first argument.
override(\DI\Container::get(0), map([
'' => '@',
]));
+4 -16
View File
@@ -1,14 +1,9 @@
{
"customSyntax": "postcss-scss",
"plugins": [
"stylelint-csstree-validator"
],
"rules": {
"csstree/validator": {
"syntaxExtensions": [
"sass"
]
},
"csstree/validator": true,
"at-rule-empty-line-before": [ "always",
{"except": [ "blockless-after-blockless"], ignore: ["after-comment", "inside-block"]}
],
@@ -50,7 +45,7 @@
"function-name-case": "lower",
"function-parentheses-newline-inside": "always-multi-line",
"function-parentheses-space-inside": "never-single-line",
"function-url-scheme-disallowed-list": ["data"],
"function-url-scheme-blacklist": ["data"],
"function-whitespace-after": "always",
"indentation": 4,
"keyframe-declaration-no-important": true,
@@ -89,19 +84,12 @@
"selector-type-no-unknown": true,
"string-no-newline": true,
"time-min-milliseconds": 100,
"unit-disallowed-list": ["pt"],
"unit-blacklist": ["pt"],
"unit-case": "lower",
"unit-no-unknown": true,
"value-keyword-case": ["lower", {"ignoreKeywords": ["/(@|$)/"]}],
"value-list-comma-newline-after": "always-multi-line",
"value-list-comma-space-after": "always-single-line",
"value-list-comma-space-before": "never",
},
"overrides": [
{
"files": ["**/yui/**/*.css"],
"rules": {
}
}
]
}
}
+276
View File
@@ -0,0 +1,276 @@
# PLEASE NOTE: Travis is not currently utilised by the Moodle core integration
# process (which uses our internal CI system) this file is here for the benefit
# of community developers git clones - see MDL-51458.
notifications:
email:
if: env(MOODLE_EMAIL) != no
language: php
os: linux
dist: focal
services:
- mysql
- docker
addons:
postgresql: "12"
apt:
packages:
- postgresql-12
- postgresql-client-12
branches:
except:
- master
- /MOODLE_[0-9]+_STABLE/
- /^v[0-9]+\.[0-9]+\.[0-9]+.*/
jobs:
# Enable fast finish.
# This will fail the build if a single job fails (except those in allow_failures).
# It will not stop the jobs from running.
fast_finish: true
include:
# First all the lowest php ones (7.4)
- php: 7.4
env: DB=none TASK=CITEST
- php: 7.4
env: DB=none TASK=GRUNT
- if: env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present
php: 7.4
env: DB=pgsql TASK=PHPUNIT
- if: env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all"
php: 7.4
env: DB=mysqli TASK=PHPUNIT
# Then, conditionally, all the highest php ones (8.0)
- if: env(MOODLE_PHP) = "all"
php: 8.0
env: DB=none TASK=CITEST
- if: env(MOODLE_PHP) = "all"
php: 8.0
env: DB=none TASK=GRUNT
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present)
php: 8.0
env: DB=pgsql TASK=PHPUNIT
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all")
php: 8.0
env: DB=mysqli TASK=PHPUNIT
cache:
directories:
- $HOME/.composer/cache
- $HOME/.npm
before_install:
- docker run -d -p 127.0.0.1:8080:80 --name exttests moodlehq/moodle-exttests
# Avoid IPv6 default binding as service (causes redis not to start).
- sudo service redis-server start --bind 127.0.0.1
env:
global:
- PGVER=12
- PGPORT=5433
install:
- >
if [ "$DB" = 'mysqli' ];
then
sudo mkdir /mnt/ramdisk
sudo mount -t tmpfs -o size=1024m tmpfs /mnt/ramdisk
sudo service mysql stop
sudo mv /var/lib/mysql /mnt/ramdisk
sudo ln -s /mnt/ramdisk/mysql /var/lib/mysql
sudo service mysql restart
fi
- >
if [ "$DB" = 'pgsql' ];
then
sudo mkdir /mnt/ramdisk
sudo mount -t tmpfs -o size=1024m tmpfs /mnt/ramdisk
sudo service postgresql stop
sudo mv /var/lib/postgresql /mnt/ramdisk
sudo ln -s /mnt/ramdisk/postgresql /var/lib/postgresql
sudo service postgresql start
fi
- >
if [ "$TASK" = 'PHPUNIT' ];
then
if [ -n "$GITHUB_APITOKEN" ]; then
composer config github-oauth.github.com $GITHUB_APITOKEN;
echo 'auth.json' >> .git/info/exclude
fi
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.
# Typically it should be able to use the Composer cache if any other job has already completed before we started here.
travis_retry composer install --prefer-dist --no-interaction;
fi
- >
if [ "$TASK" = 'GRUNT' ];
then
nvm install
nvm use
fi
before_script:
- if [[ ${TRAVIS_PHP_VERSION:0:1} -gt 7 ]]; then pecl install xmlrpc-beta; fi
- echo 'max_input_vars=5000' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
- phpenv config-rm xdebug.ini
- >
if [ "$TASK" = 'PHPUNIT' ];
then
# Copy generic configuration in place.
cp config-dist.php config.php ;
# Create the moodledata directory.
mkdir -p "$HOME"/roots/base
# The database name and password.
sed -i \
-e "s%= 'moodle'%= 'travis_ci_test'%" \
-e "s%= 'password'%= ''%" \
config.php ;
# The wwwroot and dataroot.
sed -i \
-e "s%http://example.com/moodle%https://localhost%" \
-e "s%/home/example/moodledata%/home/travis/roots/base%" \
config.php ;
if [ "$DB" = 'pgsql' ];
then
# Postgres-specific setup.
sed -i \
-e "s%= 'username'%= 'travis'%" \
-e "s%'dbsocket' => false%'dbsocket' => true%" \
config.php ;
psql -c 'CREATE DATABASE travis_ci_test;' -U travis;
fi
if [ "$DB" = 'mysqli' ];
then
# MySQL-specific setup.
sed -i \
-e "s%= 'pgsql'%= 'mysqli'%" \
-e "s%= 'username'%= 'travis'%" \
-e "s%=> 'utf8mb4_unicode_ci'%=> 'utf8mb4_bin'%" \
config.php;
mysql -u root -e 'SET GLOBAL innodb_file_format=barracuda;' ;
mysql -u root -e 'SET GLOBAL innodb_file_per_table=ON;' ;
mysql -u root -e 'SET GLOBAL innodb_large_prefix=ON;' ;
mysql -e 'CREATE DATABASE travis_ci_test DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_bin;' ;
fi
fi
- >
if [ "$TASK" = 'PHPUNIT' ];
then
# Create a directory for the phpunit dataroot.
mkdir -p "$HOME"/roots/phpunit
# The phpunit dataroot and prefix..
sed -i \
-e "/require_once/i \\\$CFG->phpunit_dataroot = '\/home\/travis\/roots\/phpunit';" \
-e "/require_once/i \\\$CFG->phpunit_prefix = 'p_';" \
config.php ;
# Enable test external resources
sed -i \
-e "/require_once/i \\define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://127.0.0.1:8080');" \
-e "/require_once/i \\define('TEST_EXTERNAL_FILES_HTTPS_URL', 'http://127.0.0.1:8080');" \
config.php ;
# Redis cache store tests
sed -i \
-e "/require_once/i \\define('TEST_CACHESTORE_REDIS_TESTSERVERS', '127.0.0.1');" \
config.php ;
# Redis session tests
sed -i \
-e "/require_once/i \\define('TEST_SESSION_REDIS_HOST', '127.0.0.1');" \
config.php ;
# Initialise PHPUnit for Moodle.
php admin/tool/phpunit/cli/init.php
fi
- >
if [ "$TASK" = 'GRUNT' ];
then
npm install --no-spin;
npm install --no-spin -g grunt ;
fi
########################################################################
# CI Tests
########################################################################
- >
if [ "$TASK" = 'CITEST' ];
then
# Note - this is deliberately placed in the script section as we
# should not add any code until after phpunit has run.
# The following repositories are required.
# The local_ci repository does the actual checking.
git clone https://github.com/moodlehq/moodle-local_ci.git local/ci
# We need the official upstream for comparison
git remote add upstream https://github.com/moodle/moodle.git;
git fetch upstream MOODLE_401_STABLE;
export GIT_PREVIOUS_COMMIT="`git merge-base FETCH_HEAD $TRAVIS_COMMIT`";
export GIT_COMMIT="$TRAVIS_COMMIT";
export UPSTREAM_FETCH_HEAD=`git rev-parse FETCH_HEAD`
# Variables required by our linter.
export gitcmd=`which git`;
export gitdir="$TRAVIS_BUILD_DIR";
export phpcmd=`which php`;
fi
script:
- >
if [ "$TASK" = 'PHPUNIT' ];
then
vendor/bin/phpunit --fail-on-risky --disallow-test-output --verbose;
fi
- >
if [ "$TASK" = 'CITEST' ];
then
bash local/ci/php_lint/php_lint.sh;
fi
- >
if [ "$TASK" = 'GRUNT' ];
then
grunt ;
# Add all files to the git index and then run diff --cached to see all changes.
# This ensures that we get the status of all files, including new files.
# We ignore npm-shrinkwrap.json to make the tasks immune to npm changes.
git add . ;
git reset -- npm-shrinkwrap.json ;
git diff --cached --exit-code ;
fi
after_script:
- >
if [ "$TASK" = 'PHPUNIT' ];
then
EXTTESTS_HITS=$(docker logs exttests 2>&1 | grep -Fv -e 'AH00558' -e '[pid 1]' | wc -l)
echo -e "\nTest local resources number of hits: ${EXTTESTS_HITS}.\n"
fi
View File
@@ -1,7 +0,0 @@
issueNumber: MDL-43938
notes:
core_badges:
- message: >-
The `badges/newbadge.php` page has been deprecated and merged with
`badges/edit.php`. Please, use `badges/edit.php` instead.
type: deprecated
@@ -1,6 +0,0 @@
issueNumber: MDL-48940
notes:
core:
- message: >
The previously deprecated function `search_generate_text_SQL` has been removed and can no longer be used.
type: removed
@@ -1,8 +0,0 @@
issueNumber: MDL-52046
notes:
core_reportbuilder:
- message: >-
The return type of the `set_checkbox_toggleall` callback, defined by
system reports, can now be null. Use if the checkbox should not be shown
for the row.
type: improved
@@ -1,11 +0,0 @@
issueNumber: MDL-54105
notes:
mod_assign:
- message: |
Added 2 new settings:
- `mod_assign/defaultgradetype`
- The value of this setting dictates which of the `GRADE_TYPE_X` constants is the default option when creating new instances of the assignment.
- The default value is `GRADE_TYPE_VALUE` (Point)
- `mod_assign/defaultgradescale`
- The value of this setting dictates which of the existing scales is the default option when creating new instances of the assignment.
type: improved
@@ -1,8 +0,0 @@
issueNumber: MDL-64148
notes:
core:
- message: >-
The following method has been deprecated and should no longer be used:
`reset_password_and_mail`. Please consider using `setnew_password_and_mail` as
a replacement.
type: deprecated
@@ -1,6 +0,0 @@
issueNumber: MDL-64148
notes:
core:
- message: >-
A new method, `\core_user::get_name_placeholders()`, has been added to return an array of user name fields.
type: improved
@@ -1,19 +0,0 @@
issueNumber: MDL-66151
notes:
core_role:
- message: |
All session management has been moved to the `\core\session\manager` class.
This removes the dependancy to use the `sessions` table.
Session management plugins (like Redis) should now inherit
the base `\core\session\handler` class, which implements
`SessionHandlerInterface`, and override methods as required.
The following methods in `\core\session\manager` have been deprecated:
| Old method name | New method name |
| --- | --- |
| `kill_all_sessions` | `destroy_all` |
| `kill_session` | `destroy` |
| `kill_sessions_for_auth_plugin` | `destroy_by_auth_plugin` |
| `kill_user_sessions` | `destroy_user_sessions` |
type: improved
@@ -1,11 +0,0 @@
issueNumber: MDL-66903
notes:
core:
- message: |
The following classes have been renamed and now support autoloading.
Existing classes are currently unaffected.
| Old class name | New class name |
| --- | --- |
| `\core_component` | `\core\component` |
type: improved
@@ -1,20 +0,0 @@
issueNumber: MDL-66903
notes:
core:
- message: >
Added the ability for unit tests to autoload classes in the
`\[component]\tests\`
namespace from the `[path/to/component]/tests/classes` directory.
type: improved
- message: >
Added a helper to load fixtures from a components `tests/fixtures/`
folder:
```php
advanced_testcase::load_fixture(string $component, string $fixture): void;
```
type: improved
@@ -1,8 +0,0 @@
issueNumber: MDL-67554
notes:
tool_oauth2:
- message: >
The `\core\oautuh2\client::get_additional_login_parameters()` method now supports adding the
language code to the authentication request so that the OAuth2 login
page matches the language in Moodle.
type: improved
@@ -1,11 +0,0 @@
issueNumber: MDL-69684
notes:
core:
- message: >-
Redis session cache has been improved to make a single call where two
were used before.
type: improved
- message: >-
The minimum Redis server version is now 2.6.12.
The minimum PHP Redis extension version is now 2.2.4.
type: changed
@@ -1,5 +0,0 @@
issueNumber: MDL-70854
notes:
core:
- message: Added stored progress bars
type: improved
@@ -1,7 +0,0 @@
issueNumber: MDL-70983
notes:
core_badges:
- message: Final removal of `BADGE_BACKPACKAPIURL` and `BADGE_BACKPACKWEBURL` constants.
type: removed
- message: The `OPEN_BADGES_V1` constant is deprecated and should not be used anymore.
type: deprecated
@@ -1,13 +0,0 @@
issueNumber: MDL-71326
notes:
core:
- message: >+
- The following methods have been finally deprecated and removed:
- `\plagiarism_plugin::get_configs()`
- `\plagiarism_plugin::get_file_results()`
- `\plagiarism_plugin::update_status()`, please use `{plugin name}_before_standard_top_of_body_html` instead.
- Final deprecation and removal of `\plagiarism_get_file_results()`. Please use `\plagiarism_get_links()` instead.
- Final deprecation and removal of `\plagiarism_update_status()`. Please use `\{plugin name}_before_standard_top_of_body_html()` instead.
type: deprecated
@@ -1,6 +0,0 @@
issueNumber: MDL-71748
notes:
core:
- message: >
The previously deprecated function `\core_text::reset_caches()` has been removed and can no longer be used.
type: removed
@@ -1,7 +0,0 @@
issueNumber: MDL-71823
notes:
core_user:
- message: >-
New `\core_user\hook\extend_user_menu` hook added to allow third party
plugins to extend the user menu navigation.
type: improved
@@ -1,6 +0,0 @@
issueNumber: MDL-72353
notes:
core_report:
- message: >-
The previously deprecated `\core\report_helper::save_selected_report()` method has been removed and can no longer be used.
type: removed
@@ -1,11 +0,0 @@
issueNumber: MDL-72397
notes:
qbank_managecategories:
- message: >
Category lists are now generated by templates.
The following classes have been deprecated:
- `\qbank_managecategories\question_category_list`
- `\qbank_managecategories\question_category_list_item`
type: deprecated
@@ -1,28 +0,0 @@
issueNumber: MDL-72397
notes:
qbank_managecategories:
- message: >
The `\qbank_managecategories\question_category_object` class has been deprecated.
Methods previously part of this class have been moved to either
- `\qbank_managecategories\question_categories`,
for the parts used within this plugin for display a list of categories; or
`\core_question\category_manager`,
for the parts used for generate CRUD operations on question categories, including outside of this plugin.
This change will allow `\qbank_managecategories\question_category_object` to be deprecated, and avoids
other parts of the system wishing to manipulate question categories from
having to violate cross-component communication rules.
type: changed
- message: |
The following methods of `\qbank_managecategories\helper`have been deprecated and moved to
`\core_question\category_manager`:
| Method | Replacement |
| --- | --- |
| `question_is_only_child_of_top_category_in_context` | `\core_question\category_manager::is_only_child_of_top_category_in_context` |
| `question_is_top_category` | `\core_question\category_manager::is_top_category` |
| `question_can_delete_cat` | `\core_question\category_manager::can_delete_cat` |
type: deprecated
@@ -1,18 +0,0 @@
issueNumber: MDL-72397
notes:
qbank_managecategories:
- message: >
`\qbank_managecategories\question_category_object` is now completely
deprecated. Its methods have either been migrated to
`\qbank_managecategories\question_categories`,
`\core_question\category_manager`, or are no longer used at all.
type: deprecated
core:
- message: >
`\moodle_list` and `\list_item` were only used by
`qbank_managecategories`, and these usages have been removed, so
these classes, and the `lib/listlib.php` file have now been deprecated.
This method was the only usage of the `QUESTION_PAGE_LENGTH`
constant, which was defined in `question_category_object.php`,
and so is also now deprecated.
type: deprecated
@@ -1,7 +0,0 @@
issueNumber: MDL-72424
notes:
mod_feedback:
- message: >-
The `\feedback_check_is_switchrole()` function has been deprecated as it
didn't work.
type: deprecated
@@ -1,11 +0,0 @@
issueNumber: MDL-72620
notes:
repository_onedrive:
- message: >
The following previously deprecated methods have been removed and can no
longer be used:
- `\repository_onedrive::can_import_skydrive_files()`
- `\repository_onedrive::import_skydrive_files()`
type: removed
@@ -1,11 +0,0 @@
issueNumber: MDL-72786
notes:
report_eventlist:
- message: >-
The following deprecated methods in `report_eventlist_list_generator` have
been removed:
- `\report_eventlist_list_generator::get_core_events_list()`
- `\report_eventlist_list_generator::get_non_core_event_list()`
type: deprecated
@@ -1,7 +0,0 @@
issueNumber: MDL-73165
notes:
core:
- message: >
The following previously deprecated methods have been removed and can no longer be used:
- `\renderer_base::should_display_main_logo()`
type: removed
@@ -1,5 +0,0 @@
issueNumber: MDL-73284
notes:
core_message:
- message: Final deprecation of the `MESSAGE_DEFAULT_LOGGEDOFF`, and `MESSAGE_DEFAULT_LOGGEDIN` constants.
type: removed
@@ -1,7 +0,0 @@
issueNumber: MDL-73976
notes:
core_course:
- message: >-
The previously deprecated `\print_course_request_buttons()` method has been
removed and can no longer be used.
type: removed
@@ -1,8 +0,0 @@
issueNumber: MDL-74050
notes:
mod_assign:
- message: >
A new web service called `mod_assign_remove_submission` has been created
to remove the submission for a specific user ID and assignment activity
ID.
type: improved
@@ -1,7 +0,0 @@
issueNumber: MDL-74251
notes:
theme:
- message: >-
Removed all references to `iconhelp`, `icon-pre`, `icon-post`, `iconlarge`, and
`iconsort` CSS classes.
type: removed
@@ -1,5 +0,0 @@
issueNumber: MDL-74484
notes:
core:
- message: Final deprecation of `\print_error()`. Please use the `\moodle_exception` class instead.
type: removed
@@ -1,9 +0,0 @@
issueNumber: MDL-74581
notes:
core_grades:
- message: >
The following previously deprecated Behat step helper methods have been
removed and can no longer be used:
- `\behat_grade::select_in_gradebook_navigation_selector()`
- `\behat_grade::select_in_gradebook_tabs()`
type: removed
@@ -1,18 +0,0 @@
issueNumber: MDL-74583
notes:
core_reportbuilder:
- message: >-
Support for the following entity classes, renamed since 4.1, have now
been removed completely:
- `\core_admin\local\entities\task_log`
- `\core_cohort\local\entities\cohort`
- `\core_cohort\local\entities\cohort_member`
- `\core_course\local\entities\course_category`
- `\report_configlog\local\entities\config_change`
type: removed
@@ -1,5 +0,0 @@
issueNumber: MDL-74843
notes:
core:
- message: 'Final deprecation of `\core\task\manager::ensure_adhoc_task_qos()`.'
type: removed
@@ -1,7 +0,0 @@
issueNumber: MDL-74939
notes:
core:
- message: >-
Support for the deprecated block and activity namespaces `<component>\local\views\secondary`,
which supported the overriding of secondary navigation, has now been entirely removed.
type: removed
@@ -1,6 +0,0 @@
issueNumber: MDL-75022
notes:
core_backup:
- message: >-
The `\core_backup\copy\copy` class has been deprecated and removed. Please use `\copy_helper` instead.
type: removed
@@ -1,11 +0,0 @@
issueNumber: MDL-75025
notes:
core_backup:
- message: |
The following methods in the `\base_controller` class have been removed:
| Method | Replacement |
| --- | --- |
| `\base_controller::set_copy()` | Use a restore controller for storing copy information instead. |
| `\base_controller::get_copy()` | `\restore_controller::get_copy()` |
type: removed
@@ -1,6 +0,0 @@
issueNumber: MDL-75850
notes:
core_files:
- message: |
A new hook, `\core_files\hook\after_file_created`, has been created to allow the inspection of files after they have been saved in the filesystem.
type: improved
@@ -1,7 +0,0 @@
issueNumber: MDL-76392
notes:
core_reportbuilder:
- message: >-
System reports now support native entity column aggregation via each
columns `set_aggregation()` method
type: improved
@@ -1,8 +0,0 @@
issueNumber: MDL-76690
notes:
core_reportbuilder:
- message: >
The following previously deprecated local helper methods have been removed and can no longer be used:
- `\core_reportbuilder\local\helpers\audience::get_all_audiences_menu_types()`
- `\core_reportbuilder\local\helpers\report::get_available_columns()`
type: removed
@@ -1,5 +0,0 @@
issueNumber: MDL-77167
notes:
core:
- message: Remove deprecation layer for YUI JS Events. The deprecation layer was introduced with MDL-70990 and MDL-72291.
type: removed
@@ -1,8 +0,0 @@
issueNumber: MDL-78030
notes:
core_user:
- message: >-
The `\core_user\table\participants_search::get_total_participants_count()` is no longer
used since the total count can be obtained from
`\core_user\table\participants_search::get_participants()`.
type: deprecated
@@ -1,21 +0,0 @@
issueNumber: MDL-78030
notes:
core:
- message: |
Two new functions have been introduced in the `\moodle_database` class:
- `\moodle_database::get_counted_records_sql()`
- `\moodle_database::get_counted_recordset_sql()`
These methods are compatible with all databases.
They will check the current running database engine and apply the `COUNT` window function if it is supported,
otherwise, they will use the usual `COUNT` function.
The `COUNT` window function optimization is applied to the following databases:
- PostgreSQL
- MariaDB
- Oracle
Note: MySQL and SQL Server do not use this optimization due to insignificant performance differences before and
after the improvement.
type: improved
@@ -1,10 +0,0 @@
issueNumber: MDL-78293
notes:
core_user:
- message: >
The visibility of the following methods have been increased to public:
- `\core_user\form\private_files::check_access_for_dynamic_submission()`
- `\core_user\form\private_files::get_options()`
type: changed
@@ -1,7 +0,0 @@
issueNumber: MDL-78662
notes:
core_question:
- message: >
A new utility function `\question_utils::format_question_fragment()` has been created so
that question content can filter based on filters.
type: improved
@@ -1,8 +0,0 @@
issueNumber: MDL-78773
notes:
core_report:
- message: >
The `\core\report_helper::print_report_selector()` method accepts a new `$additional``
argument for adding content to the tertiary navigation to align with the
report selector.
type: changed
@@ -1,5 +0,0 @@
issueNumber: MDL-78776
notes:
tool:
- message: The Convert to InnoDB plugin (`tool_innodb`) has been completely removed.
type: removed
@@ -1,7 +0,0 @@
issueNumber: MDL-79011
notes:
core:
- message: >-
The `after_config()` callback has been converted to a hook,
`\core\hook\after_config`.
type: improved
@@ -1,10 +0,0 @@
issueNumber: MDL-79546
notes:
mod_quiz:
- message: >+
The following methods of the `quiz_overview_report` class now take a new optional `$slots` parameter used to only regrade some slots in each attempt (default all):
- `\quiz_overview_report::regrade_attempts()`
- `\quiz_overview_report::regrade_batch_of_attempts()`
type: improved
@@ -1,7 +0,0 @@
issueNumber: MDL-79628
notes:
core:
- message: >-
The `\navigation_cache` class now uses the Moodle Universal Cache (MUC) to store the navigation cache data instead of storing
it in the global `$SESSION` variable.
type: fixed
@@ -1,6 +0,0 @@
issueNumber: MDL-79628
notes:
core:
- message: >-
The `$timeout` property of the `\navigation_cache` class has been deprecated.
type: deprecated
@@ -1,9 +0,0 @@
issueNumber: MDL-80017
notes:
core_grades:
- message: >
The grade `itemname` property contained in the return structure of
the following external methods is now PARAM_RAW:
- `core_grades_get_gradeitems`
- `gradereport_user_get_grade_items`
type: changed
-11
View File
@@ -1,11 +0,0 @@
issueNumber: MDL-80275
notes:
core:
- message: >
The class autoloader has been moved to an earlier point in the Moodle
bootstrap.
Autoloaded classes are now available to scripts using the
`ABORT_AFTER_CONFIG` constant.
type: changed
@@ -1,18 +0,0 @@
issueNumber: MDL-80741
notes:
mod_assign:
- message: >
The default option "Never" for the `attemptreopenmethod` setting, which
disallowed multiple attempts at the assignment, has been removed. This
option was unnecessary because limiting attempts to 1 through the
`maxattempts` setting achieves the same behavior.
type: removed
- message: >
The constant `ASSIGN_ATTEMPT_REOPEN_METHOD_NONE` has been deprecated,
and a new default value for `attemptreopenmethod` has been set to
"Automatically until pass".
type: deprecated
- message: >
A new default value for `attemptreopenmethod` has been set to
"Automatically until pass".
type: improved
@@ -1,20 +0,0 @@
issueNumber: MDL-80744
notes:
core_grades:
- message: >-
The behat step definition
`\behat_grade::i_confirm_in_search_within_the_gradebook_widget_exists()` has
been deprecated. Please use
`\behat_general::i_confirm_in_search_combobox_exists()` instead.
type: deprecated
- message: >-
The behat step definition
`\behat_grade::i_confirm_in_search_within_the_gradebook_widget_does_not_exist()`
has been deprecated. Please use
`\behat_general::i_confirm_in_search_combobox_does_not_exist()` instead.
type: deprecated
- message: >-
The behat step definition `\behat_grade::i_click_on_in_search_widget()` has
been deprecated. Please use `\behat_general::i_click_on_in_search_combobox()`
instead.
type: deprecated
@@ -1,23 +0,0 @@
issueNumber: MDL-80745
notes:
core_grades:
- message: >
The `\core_grades_renderer::group_selector()` method has been deprecated.
Please use `\core_course\output\actionbar\renderer` to render a
`group_selector` renderable instead.
type: deprecated
gradereport_grader:
- message: >
The `gradereport_grader/group` ESM has been deprecated. Please use
`core_course/actionbar/group` instead.
type: deprecated
gradereport_singleview:
- message: >
The `gradereport_singleview/group` ESM has been deprecated. Please use
`core_course/actionbar/group` instead.
type: deprecated
gradereport_user:
- message: >
The `gradereport_user/group` ESM has been deprecated. Please use
`core_course/actionbar/group` instead.
type: deprecated
@@ -1,9 +0,0 @@
issueNumber: MDL-80747
notes:
core:
- message: >
The `\core\output\select_menu` widget now supports rendering dividers
between menu options. Empty elements (`null` or empty strings) within the
array of options are considered and rendered as dividers in the dropdown
menu.
type: improved
@@ -1,9 +0,0 @@
issueNumber: MDL-80747
notes:
core:
- message: >
The `\core\output\select_menu` widget now supports a new feature: inline
labels. You can render the label inside the combobox widget by passing
`true` to the `$inlinelabel` parameter when calling the `->set_label()`
method.
type: improved
@@ -1,11 +0,0 @@
issueNumber: MDL-80748
notes:
core_table:
- message: >+
A new `$reponsive` property (defaulting to `true`) has been added to the
`\core_table\flexible_table` class.
This property allows you to control whether the table is rendered as a
responsive table.
type: improved
@@ -1,19 +0,0 @@
issueNumber: MDL-80750
notes:
mod_assign:
- message: >
A new method, `\assign_feedback_plugin::get_grading_batch_operation_details()`, has been added
to the `assign_feedback_plugin` abstract class. Assignment feedback
plugins can now override this method to define bulk action buttons that
will appear in the sticky footer on the assignment grading page.
type: improved
- message: >
The `\assign_feedback_plugin::get_grading_batch_operations()` method is now
deprecated. Use
`assign_feedback_plugin::get_grading_batch_operation_details` instead.
type: deprecated
- message: >
The `\assign_grading_table::plugingradingbatchoperations` property has been
removed. You can use
`\assign_feedback_plugin::get_grading_batch_operation_details()` instead.
type: deprecated
@@ -1,8 +0,0 @@
issueNumber: MDL-80752
notes:
mod_assign:
- message: >
The `$submissionpluginenabled` and `$submissioncount` parameters from
the constructor of the `\mod_assign\output::grading_actionmenu` class
have been deprecated.
type: deprecated
@@ -1,8 +0,0 @@
issueNumber: MDL-80890
notes:
core:
- message: >
A new hook called `\core\hook\output\after_http_headers` has been
created. This hook allow plugins to modify the content after headers are
sent.
type: improved
@@ -1,12 +0,0 @@
issueNumber: MDL-80962
notes:
factor_sms:
- message: >
The following classes are removed as the SMS feature now takes advantage of `core_sms` API:
- `\factor_sms\event\sms_sent`
- `\factor_sms\local\smsgateway\aws_sns`
- `\factor_sms\local\smsgateway\gateway_interface`
type: removed
@@ -1,12 +0,0 @@
issueNumber: MDL-80962
notes:
core:
- message: >
The following classes are deprecated as they are handled by core_sms API and smsgateway_aws plugin:
- `\core\aws\admin_settings_aws_region`
- `\core\aws\aws_helper`
- `\core\aws\client_factory`
type: deprecated
@@ -1,11 +0,0 @@
issueNumber: MDL-81031
notes:
core:
- message: |
The following classes have been renamed.
Existing classes are currently unaffected.
| Old class name | New class name |
| --- | --- |
| `\core_user` | `\core\user` |
type: improved
@@ -1,11 +0,0 @@
issueNumber: MDL-81168
notes:
core_reportbuilder:
- message: >
In order to better support float values in filter forms, the following
filter types now cast given SQL prior to comparison:
- `duration`
- `filesize`
- `number`
type: changed
@@ -1,6 +0,0 @@
issueNumber: MDL-81274
notes:
mod_data:
- message: >-
The `\data_add_record()` method accepts a new `$approved` parameter to set the corresponding state of the new record.
type: improved
@@ -1,7 +0,0 @@
issueNumber: MDL-81282
notes:
core:
- message: >-
New DML constant `SQL_INT_MAX` to define the size of a large integer
with cross database platform support.
type: improved
@@ -1,7 +0,0 @@
issueNumber: MDL-81321
notes:
mod_data:
- message: >-
The `\mod_data_renderer::render_fields_footer()` method has been deprecated
as it's no longer used.
type: deprecated

Some files were not shown because too many files have changed in this diff Show More