Compare commits

..

1325 Commits

Author SHA1 Message Date
Ilya Tregubov 76fe404dd5 Moodle release 4.1.4 2023-06-10 14:08:05 +08:00
Ilya Tregubov f3400f4fc5 weekly release 4.1.3+ 2023-06-09 13:14:27 +08:00
Sara Arjona c872490dcf Merge branch 'MDL-78415-401-enfix' of https://github.com/vmdef/moodle into MOODLE_401_STABLE 2023-06-08 20:33:14 +02:00
Helen Foster e518de15f3 MDL-78415 lang: Import fixed English strings (en_fix) 2023-06-08 12:02:34 +01:00
Sara Arjona 4fffa81e41 Merge branch 'MDL-77946-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-06-08 06:56:56 +02:00
Sara Arjona fcd946c862 Merge branch 'MDL-78308-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-06-08 06:48:40 +02:00
Andrew Nicols b272406c74 Merge branch 'MDL-75696_401_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_401_STABLE 2023-06-08 12:31:16 +08:00
Andrew Nicols d0e0225a1a Merge branch 'MDL-78364-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-06-08 12:19:31 +08:00
Andrew Nicols 2649d1a01e Merge branch 'MDL-78008_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-06-08 12:10:42 +08:00
Andrew Nicols aa77a76c7a Merge branch 'MDL-77933-401' of https://github.com/snake/moodle into MOODLE_401_STABLE 2023-06-08 12:03:37 +08:00
Andrew Nicols 1b27cfd795 MDL-76838 core: Add unit test for invalid unicode sequences 2023-06-08 11:59:23 +08:00
Jake Dallimore da10ccd8d4 MDL-77933 enrol_lti: return site name and logo during registration
Instead of the Moodle icon and the 'moodle' lang string, return the
site fullname and compact logo during dynamic registration.
2023-06-08 11:56:31 +08:00
Andrew Nicols cc7ea9fecd Merge branch 'MDL-76838-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-06-08 11:54:42 +08:00
Jun Pataleta 2cf0da5dc6 Merge branch 'MDL-75898-41' of https://github.com/matthewhilton/moodle into MOODLE_401_STABLE 2023-06-08 11:43:06 +08:00
Andrew Nicols a6fde372ab Merge branch 'MDL-78026-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-06-08 11:36:54 +08:00
Andrew Nicols 7dc747ea99 Merge branch 'MDL-77264-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-06-08 11:32:46 +08:00
Andrew Nicols 5a8881ac37 Merge branch 'MDL-76821-401' of https://github.com/snake/moodle into MOODLE_401_STABLE 2023-06-08 11:30:09 +08:00
Andrew Nicols b4eb274d7a Merge branch 'MDL-77799-m401' of https://github.com/sammarshallou/moodle into MOODLE_401_STABLE 2023-06-08 11:21:35 +08:00
Andrew Nicols 21443080c8 Merge branch 'MDL-78408-401' of https://github.com/snake/moodle into MOODLE_401_STABLE 2023-06-08 11:05:34 +08:00
Jun Pataleta ea1a8336e5 Merge branch 'MDL-78036_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2023-06-08 11:03:24 +08:00
Andrew Nicols f68fedcf77 Merge branch 'wip_MDL-78400_m41' of https://github.com/gjb2048/moodle into MOODLE_401_STABLE 2023-06-08 10:51:50 +08:00
Andrew Nicols cf3ae5bc2a Merge branch 'MDL-76406-401' of https://github.com/safatshahin/moodle into MOODLE_401_STABLE 2023-06-08 10:38:58 +08:00
Jun Pataleta c8bb7a6911 Merge branch 'MDL-76842-401' of https://github.com/snake/moodle into MOODLE_401_STABLE 2023-06-08 10:34:17 +08:00
Jun Pataleta bf448de7aa Merge branch 'MDL-78229-401' of https://github.com/lucaboesch/moodle into MOODLE_401_STABLE 2023-06-08 10:30:23 +08:00
Jake Dallimore cbacf8ee58 MDL-76842 enrol_lti: fix user record updates in user_repository
Only call user_update_user when the relevant user data has changed,
preventing unnecessary user_updated events. This also removes the
line setting timemodified on the user since user_update_user already
handles this.
2023-06-08 10:29:01 +08:00
Jun Pataleta 37a29f7950 Merge branch 'MDL-78431-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-06-08 10:28:18 +08:00
Jake Dallimore b1dcb08e3f MDL-76842 enrol_lti: test confirming the erroneous user_updated events
This test will fail until the fix - only updating users when data has
changed - is put in place in the following commit.
2023-06-08 09:40:29 +08:00
Jake Dallimore 0ccf800f01 MDL-76842 auth_lti: don't update the user unless data has changed
When receiving data from the LTI launch, or service call, only update
the user record when we know something has changed. This prevents the
creation of many \core\event\user_updated events.
2023-06-08 09:40:28 +08:00
Jake Dallimore b097d38fb3 MDL-76842 auth_lti: don't update the user after membership creation
This isn't required and generates excess events. The only thing update
does, other than update the user fields, is to update the picture, but
in this case, that's unset in membership-based auths anyway, so it's
entirely safe to remove this.
2023-06-08 09:39:09 +08:00
Jake Dallimore 1858e29d23 MDL-76842 auth_lti: test confirming the erroneous user_updated events
This test will fail until the fix - only updating users when data has
changed - is put in place in the following commit.
2023-06-08 09:39:09 +08:00
Stevani Andolo bd5329b1a5 MDL-78215 core: Added support unit test 2023-06-08 09:37:02 +08:00
Stevani Andolo 69596a6bb2 MDL-78215 core: support checking if 0.0.0.0 is in subnet 2023-06-08 09:37:01 +08:00
Jun Pataleta 79510d5d73 Merge branch 'MDL-78378-401' of https://github.com/sarjona/moodle into MOODLE_401_STABLE 2023-06-07 23:25:19 +08:00
Jun Pataleta fce2d2f407 Merge branch 'MDL-78368-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-06-07 23:22:25 +08:00
Jun Pataleta 3b8e3ba59e Merge branch 'MDL-76745_401_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_401_STABLE 2023-06-07 22:53:45 +08:00
Andrew Nicols 2279eee0ab MDL-78431 core: Abort after config for source maps 2023-06-07 21:07:52 +08:00
Sara Arjona 411f43dc5a Merge branch 'MDL-78322-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-06-07 12:43:08 +02:00
Sara Arjona ef2a553bd4 Merge branch 'MDL-78352-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-06-07 12:41:16 +02:00
Sara Arjona af1bd51b99 Merge branch 'MDL-78047-401' of https://github.com/stevandoMoodle/moodle into MOODLE_401_STABLE 2023-06-07 18:17:40 +08:00
Sara Arjona b89ece2484 Merge branch 'MDL-78010-401' of https://github.com/ferranrecio/moodle into MOODLE_401_STABLE 2023-06-07 18:17:40 +08:00
sam marshall 0c3b3c9b92 MDL-77799 webservice_rest: unhandled exception should go in server log 2023-06-07 10:04:07 +01:00
Jake Dallimore 7fd423acfc MDL-78408 core: fix restoration of anchor to wantsurl during login 2023-06-07 14:30:37 +08:00
Stevani Andolo abac304ba9 MDL-78047 core_courseformat: Wrapping added to text and media activity 2023-06-07 12:58:38 +08:00
Paul Holden 677b67ac05 MDL-77193 mnet: correct sorting of access control table. 2023-06-07 09:53:44 +08:00
Ferran Recio 5f30a47660 MDL-78010 mod_label: improve upgrade performance 2023-06-06 21:33:14 +02:00
Eloy Lafuente (stronk7) 7abeaf37ea MDL-78036 behat: Move all links from old docs to new counterparts 2023-06-06 12:39:21 +02:00
Petr Skoda 79981290d9 MDL-76683 core_group: fix template 2023-06-06 09:30:27 +00:00
Sara Arjona e96dab8594 Merge branch 'MDL-76936-401' of https://github.com/HirotoKagotani/moodle into MOODLE_401_STABLE 2023-06-06 11:22:15 +02:00
Paul Holden 6843ba0aad MDL-78364 reportbuilder: earlier calculation of schedule recipients. 2023-06-05 16:22:33 +01:00
Gareth Barnard 257e2b414a MDL-78400 JavaScript: Building JS puts build files in src dir on Win. 2023-06-05 14:52:16 +01:00
Sara Arjona b17d91c6f8 MDL-78378 survey: Display default introduction when description is empty
This is a regression when the activity pages were redessigned in Moodle
4.0. The default introduction should be displayed when the activity
description is empty.
2023-06-02 08:19:49 +02:00
Safat 7debcb85b4 MDL-76406 core: Add environment check for versions not supporting 8.2 2023-06-02 12:09:15 +10:00
Ilya Tregubov 03b605f2eb weekly release 4.1.3+ 2023-06-02 09:55:42 +08:00
Ilya Tregubov de0bab848d Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-06-02 09:55:39 +08:00
Mark Johnson dfdf8ba7c9 MDL-76745 cache: Implement cache_loader_with_locking in cache_disabled
If a plugin attempts to do something that would lock coursemodinfo cache
during install (such as creating a course module), this currently fails
as check_lock_state is not implemented in cache_disabled. Adding the
cache_loader_with_locking interface ensures that all lock methods are
implemented.
2023-06-01 15:03:33 +01:00
Andrew Nicols f1f87dbd6b Merge branch 'MDL-77749-unset-config-duration-MOODLE_401_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_401_STABLE 2023-06-01 12:03:26 +08:00
Jun Pataleta 2885b47377 Merge branch 'MDL-78092-m401' of https://github.com/sammarshallou/moodle into MOODLE_401_STABLE 2023-06-01 11:36:21 +08:00
Andrew Nicols 036cb9a997 Merge branch 'MDL-78327_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-06-01 10:52:47 +08:00
Ilya Tregubov 732f27c770 Merge branch 'MDL-78196-401' of https://github.com/jleyva/moodle into MOODLE_401_STABLE 2023-06-01 10:40:36 +08:00
Andrew Nicols d6a8581abe Merge branch 'MDL-78262-401' of https://github.com/danghieu1407/moodle into MOODLE_401_STABLE 2023-06-01 09:57:03 +08:00
Ilya Tregubov d37efc5160 Merge branch 'MDL-77259-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-06-01 09:30:02 +08:00
Ilya Tregubov e0dc9aa297 Merge branch 'MDL-75961-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-06-01 09:08:28 +08:00
AMOS bot e939cee281 Automatically generated installer lang files 2023-06-01 00:11:03 +00:00
Sara Arjona 17be7f62d6 Merge branch 'MDL-76693-401' of https://github.com/roland04/moodle into MOODLE_401_STABLE 2023-05-31 17:09:03 +02:00
Simey Lameze b512186fce MDL-77547 behat: run recalculate task before checking values 2023-05-31 15:04:56 +02:00
Tim Hunt ee3752e639 MDL-78327 question stats: store same timestamp for all question stats 2023-05-31 12:03:56 +01:00
Sara Arjona e47c5527f6 Merge branch 'MDL-77547-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-05-31 12:51:34 +02:00
Sara Arjona 99a48299f0 Merge branch 'MDL-77907-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-05-31 12:18:12 +02:00
Sara Arjona 5a84debc90 Merge branch 'MDL-78148-401' of https://github.com/ferranrecio/moodle into MOODLE_401_STABLE 2023-05-31 11:42:16 +02:00
Sara Arjona 70e6fb0a7d Merge branch 'MDL-73648-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-31 11:38:21 +02:00
Ilya Tregubov 95ec4161f5 Merge branch 'MDL-73138-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-30 12:54:24 +08:00
Ilya Tregubov bd41a5bbec Merge branch 'MDL-77723-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-30 12:44:54 +08:00
AMOS bot f02891c647 Automatically generated installer lang files 2023-05-30 00:10:36 +00:00
Jun Pataleta 2d99010fc9 Merge branch 'MDL-78314-401' of https://github.com/lucaboesch/moodle into MOODLE_401_STABLE 2023-05-29 17:35:04 +08:00
Luca Bösch 23ba0d96ef MDL-78314 quiz: style button fieldset in "Manually grade question". 2023-05-29 10:54:27 +02:00
Mikel Martín 11205ec5ef MDL-76693 core_course: Fix activity chooser summary overlap
In activity chooser modal, there is an overlap issue in the information "sub-page".
Changing some classes in the layout solves the problem.
2023-05-29 09:38:28 +02:00
Ferran Recio b01dd76331 MDL-78148 core_courseformat: reduce the use of uniqid in templates 2023-05-29 08:40:18 +02:00
Eloy Lafuente (stronk7) 278ce49b7f MDL-78036 behat: Fix php81 deprecation warning 2023-05-26 18:04:26 +02:00
Dani Palou 4cbe98f2e7 MDL-78368 airnotifier: Fix data encrypted several times
Backport of MDL-78054.
2023-05-26 21:46:35 +08:00
Paul Holden a22aabb29f MDL-78352 webservice: use default user context page heading. 2023-05-26 12:27:46 +01:00
Paul Holden 1ff279717e MDL-73648 badges: add Behat generator class for creating badges. 2023-05-26 12:19:27 +01:00
Paul Holden 017f8a9c4d MDL-73138 group: remove double encoding of group/role names. 2023-05-26 10:25:50 +01:00
Paul Holden 16c5835a80 MDL-73138 user: avoid double encoding participant filter values. 2023-05-26 10:25:50 +01:00
Sara Arjona 090baf556e weekly release 4.1.3+ 2023-05-26 09:28:53 +02:00
Sara Arjona 0b46994b0c Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-05-26 09:28:45 +02:00
Adrien Loison a229905760 MDL-78262 lib_spout: Update box/spout to address PHP 8.1 deprecation 2023-05-26 08:50:17 +07:00
Jun Pataleta 1c7f1e0bed Merge branch 'MDL-78346-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-05-25 16:56:14 +02:00
Jun Pataleta 59596ddedc Merge branch 'MDL-76065-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-05-25 16:56:14 +02:00
Jun Pataleta 34dd7e7978 Merge branch 'MDL-78320-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-25 16:56:14 +02:00
Jun Pataleta e7d2f494c3 Merge branch 'MDL-78346-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-05-25 16:56:14 +02:00
Andrew Nicols 9c5febc47c MDL-78346 tool_langimport: Print any notifications before redirect 2023-05-25 14:55:01 +08:00
Andrew Nicols 4ddbcf2aec MDL-78346 tool_langimport: Redirect after action to prevent resubmission 2023-05-25 11:14:15 +08:00
Andrew Nicols 9dc72be2d4 MDL-78346 tool_langimport: Prevent uninstallation of invalid targets 2023-05-25 11:14:14 +08:00
Andrew Nicols 05a5ed676c Merge branch 'MDL-77995-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-25 09:50:47 +08:00
Paul Holden aaf17fc8b6 MDL-78320 quiz_overview: format group names in overview report. 2023-05-24 16:19:34 +01:00
Andrew Nicols b870bc0577 Merge branch 'MDL-77983-401' of https://github.com/rjnl/moodle into MOODLE_401_STABLE 2023-05-24 21:15:17 +08:00
Jun Pataleta 9e582a6099 Merge branch 'MDL-78072-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-05-24 17:56:27 +08:00
Jun Pataleta ff402c26e5 Merge branch 'MDL-78005-401' of https://github.com/davewoloszyn/moodle into MOODLE_401_STABLE 2023-05-24 12:06:17 +08:00
Simey Lameze b12f914708 MDL-75961 behat: review and enhance mod_imscp tests
This commit makes the following improvements to mod_imscp tests:
* Removes unnecessary @javascript and @_file_upload tags from non-JS tests.
* Removes user/enrol data generation from tests that can be performed as admin.
* Removes "I log out" and other unnecessary steps.
2023-05-24 10:41:41 +08:00
Angelia Dela Cruz e7d32b89ac MDL-75961 behat: IMSCP behat generators use UI
Replace steps that manually add IMSCP instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
2023-05-24 10:41:41 +08:00
Sara Arjona 22705fa4fb Merge branch 'MDL-78176_401' of https://github.com/AnupamaSarjoshi/moodle into MOODLE_401_STABLE 2023-05-23 17:45:57 +02:00
Sara Arjona 7c0954ccd1 Merge branch 'MDL-78242-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-23 17:37:00 +02:00
Jun Pataleta 0479c711c2 Merge branch 'MDL-76688/401' of https://github.com/skodak/moodle into MOODLE_401_STABLE 2023-05-23 15:22:04 +08:00
Angelia Dela Cruz de6c14ee71 MDL-77547 Behat: Coverage to check for bad multichoice questions 2023-05-23 15:17:43 +08:00
Simey Lameze 1936b30c88 MDL-76065 behat: Review and enhance mod_lti Behat tests
In this commit, the following improvements were made to the mod_lti Behat tests:

* Replaced manual steps with data generators to set completion.
* Eliminated unnecessary user and course enrolments data generation as some tests can be performed as an admin.
* Removed the @javascript tag from non-JS tests.
* Updated the LTI data generator to generate an internal Moodle URL in the toolurl field, enabling the use of XML files.
2023-05-23 12:23:26 +08:00
Angelia Dela Cruz f19f31736a MDL-76065 behat: LTI behat generators use UI
Replace steps that manually add LTI instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
2023-05-23 12:15:25 +08:00
Andrew Nicols 2b01af17be Merge branch 'MDL-78170-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-23 10:28:33 +08:00
AMOS bot 439f75e6e1 Automatically generated installer lang files 2023-05-23 00:10:27 +00:00
Paul Holden dec3d56032 MDL-76838 backup: remove invalid utf8 code sequences writing XML.
The surrogate blocks FFFE and FFFF are non-characters, specifically
disallowed in the character range for XML documents.
2023-05-22 21:04:12 +01:00
Paul Holden 452c7c72e0 MDL-78322 tool_cohortroles: don't assign roles to deleted users. 2023-05-22 20:14:39 +01:00
Tim Hunt 0d0868ee97 MDL-78008 qtype_multianswer: random guess score with missing subqs
Sometimes, due to other bugs, subquestions can get lost, so the code
needs to be robust to this.
2023-05-22 17:02:22 +01:00
Sara Arjona c98e7e7dbf Merge branch 'MDL-78211-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-22 17:41:48 +02:00
Sara Arjona 90e18e28a2 Merge branch 'MDL-78226-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-22 17:29:27 +02:00
Sara Arjona db7c650f8c Merge branch 'MDL-78225-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-22 12:04:19 +02:00
sam marshall 79d0e63b18 MDL-78092 Cache: Modinfo locking with Redis store does not work
The feature added in 4.1 to lock the modinfo cache does not work when
using Redis, because:

* The API to acquire a cache lock is confusing, and the code did not
  check that it successfully acquired a lock before going on to build
  the cache anyway.

* Unlike the other types of cache lock, the Redis store did not retry
  the lock for a timeout period before giving up and failing.

This change fixes both points.
2023-05-22 10:45:13 +01:00
Jun Pataleta 962c8ef477 Merge branch 'MDL-78157-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-05-22 15:29:30 +08:00
Andrew Nicols 2036f2439e MDL-78157 js: Be more careful about inserting missing module names
It is perfectly legitimate to create and/or use a method named `define`
in JS outside of RequireJS.

Unfortunately our requirejs.php wrapper is dumb and does not understand
this.

In the long term we need to stop doing this at all. We really should be
able to already, but every time I try to something prevents it.

In the interim, this change adds a secondary check to see if there is an
existing define which _does_ have the right name in it already.
2023-05-22 14:40:41 +08:00
Luca Bösch 6bb4351e8b MDL-78229 quiz: quiz editing page less narrow.
This is a backport of MDL-77872.
2023-05-19 18:13:07 +02:00
Anupama Sarjoshi 80fa181a26 MDL-78176 Question: Fix D&D onto image and D&D markers theme issue 2023-05-19 16:28:53 +01:00
Jun Pataleta 6ca70dd59f weekly release 4.1.3+ 2023-05-19 21:13:57 +08:00
Jun Pataleta 712737e955 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-05-19 21:13:54 +08:00
Andrew Nicols 5e32d574c6 MDL-77733 behat: Remove extraneous no-axe option
There is no need for no-axe if we make axe a boolean value. We already
have automatic support for negated boolean flags.
2023-05-19 11:28:08 +08:00
Mark Johnson 5620e0059a MDL-75696 quiz: Fix restoring pre-4.0 quizzes with random questions
Restoring multiple quizzes from a pre-4.0 backup was broken when
the quizzes shared a random question. This is because after the
first quiz created a set reference in place of the random question,
it deleted the question record so it was not there for the second
quiz to use. This change tracks the IDs of random questions so
they can be deleted at the end.
2023-05-18 15:59:53 +01:00
Mark Johnson 85b1e992e9 MDL-75696 quiz: Set default value for includingsubcategories on restore 2023-05-18 15:56:02 +01:00
Mark Johnson 8d50911af5 MDL-75696 backup: Fix backup version checks
Several version checks were incorrectly using
restore_controller::info::moodle_release instead of moodle_version as a
version number. This replaces all of those checks with a common pair of
methods to make the checks clearer and more maintainable.
2023-05-18 15:56:02 +01:00
Paul Holden 5c871bff29 MDL-78308 output: better parsing of custom menu item configuration.
Previously certain values would cause deprecation notices in PHP8.1.
2023-05-18 10:19:18 +01:00
Jun Pataleta 096f1e67c8 Merge branch 'MDL-78116-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-05-18 12:11:31 +08:00
Andrew Nicols 21cc09fa2d Merge branch 'MDL-77451-401' of https://github.com/rezaies/moodle into MOODLE_401_STABLE 2023-05-18 11:56:33 +08:00
Jun Pataleta e2a7a44d3e Merge branch 'MDL-78135-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-18 11:54:46 +08:00
Andrew Nicols b28a28ef0f Merge branch 'MDL-78260_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-05-18 11:51:47 +08:00
Andrew Nicols 30e9810589 Merge branch 'MDL-78151-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-18 11:48:39 +08:00
Andrew Nicols cf83791269 Merge branch 'MDL-77733-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-05-18 11:44:18 +08:00
David Woloszyn 3f07fc246f MDL-78005 editor_tiny: Declared vars to supress error logging 2023-05-18 13:03:04 +10:00
Tim Hunt 3d023db5b0 MDL-78260 quiz stats: fix View details for random questions 2023-05-17 09:04:49 +01:00
Rajneel Totaram 13b48a0ae8 MDL-77983 core_user: Avoid passing nulls to base64_decode 2023-05-17 19:39:52 +12:00
Ilya Tregubov 87223abc7a Merge branch 'MDL-78152-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-17 15:07:38 +08:00
AMOS bot e7458d017a Automatically generated installer lang files 2023-05-17 00:10:58 +00:00
Jun Pataleta d2b81dd116 Merge branch 'MDL-77439-401' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-05-16 20:39:09 +08:00
Peter Mayer 361f0fa524 MDL-77439 lib_filebrowser: Splitup query to speedup get_courses 2023-05-16 20:37:57 +08:00
Paul Holden 7a23da59ce MDL-78026 group: format retrieved group names from external methods. 2023-05-16 10:10:06 +01:00
Paul Holden 01ae473823 MDL-77264 grade: define fallback name of abstract export event. 2023-05-16 09:54:40 +01:00
Paul Holden 0aff5ccd01 MDL-77259 tool_monitor: use core component API for event list.
The previous method of hardcoded filepaths, specifically for events
belonging to core, meant that any events belongs to core subsystems
were omitted (core_customfield, core_h5p, core_payment, etc).
2023-05-16 09:50:22 +01:00
Angelia Dela Cruz 7a511874b8 MDL-77907 Behat: Coverage for duplicating competency framework 2023-05-16 16:11:58 +08:00
Andrew Nicols a1b37845a8 MDL-78072 core: Skip mobile encryption if Sodium is not available 2023-05-16 12:51:14 +08:00
Jake Dallimore 071adb2fb1 Merge branch 'MDL-77930-401' of https://github.com/rjnl/moodle into MOODLE_401_STABLE 2023-05-16 10:50:04 +08:00
Jake Dallimore aa39ebbb99 Merge branch 'MDL-78120-401' of https://github.com/lucaboesch/moodle into MOODLE_401_STABLE 2023-05-16 10:45:27 +08:00
Jun Pataleta 4818dae2fc Merge branch 'MDL-75576_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-05-16 09:59:01 +08:00
Ilya Tregubov dc38a92ec6 Merge branch 'MDL-77840-401' of https://github.com/davewoloszyn/moodle into MOODLE_401_STABLE 2023-05-16 09:47:48 +08:00
Andrew Nicols 946405d44b Merge branch 'MDL-77432-401' of https://github.com/lucaboesch/moodle into MOODLE_401_STABLE 2023-05-15 22:12:44 +08:00
Andrew Nicols bdeda3ea9b Merge branch 'MDL-78149-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-15 22:07:13 +08:00
Andrew Nicols 01c04f4cf8 Merge branch 'MDL-78140-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-15 22:03:30 +08:00
Paul Holden 9ef8025e4c MDL-78242 roles: consistently check course contact config. 2023-05-15 13:04:48 +01:00
Tim Hunt efe895f1bb MDL-75576 quiz/question statistics: don't expire by time
Previously, a set of calculated quiz statistics would only 'last' for
15 minutes. Then they would be considered invalid and not used.

Now, computed statistics are kept indefinitely. Instead, when a new
batch of values are computed for a particular set of settings, older numbers
for the same settings are deleted first. Therefore,
question_stats_cleanup_task is no more.
2023-05-15 10:04:34 +01:00
Tim Hunt a532f407bb MDL-75576 quiz statistics: don't time-limit the use of cached values
This should have been done as part of  MDL-74762, but was missed.
2023-05-15 10:04:33 +01:00
Tim Hunt 86932a330b MDL-75576 quiz statistics: don't compute when a user views the qbank
Previously, when users viewed the question bank, if the quiz statistics
had not already been calculated, we would try to compute them there an then.
This could be very, very slow, leading to session lock problems.

Now, we never try to compute the statistics on the fly. Instead, we rely
on the existing \quiz_statistics\task\recalculate scheduled task to do it.
2023-05-15 10:04:33 +01:00
Tim Hunt db9a0e296a MDL-75576 question bank: bulk-load statistics for all questions at once
There is a new method on the column class, for the column to declare any
statistics it requires. The question then efficiently loads all those
statistics in one go, and makes them available as the columns are
rendererd, or do any subsequent processing.
2023-05-15 10:04:33 +01:00
Tim Hunt 9ff59e99ff MDL-75576 qbank_statistics: remove copy-pasted PHPdoc comments
These methods are already correctly documented on the base class.
2023-05-15 10:04:32 +01:00
Luca Bösch 997990f94f MDL-78120 login: handle empty wantsurl on login with alternateloginurl. 2023-05-15 10:19:00 +02:00
Paul Holden e5132eff2f MDL-77995 javascript: more precise path matching building JS. 2023-05-15 09:05:51 +01:00
Paul Holden 7093578baf MDL-77723 user: ensure identity refers to a valid custom profile field. 2023-05-15 09:03:40 +01:00
Jun Pataleta 28026b923a Merge branch 'MDL-76903-401' of https://github.com/laurentdavid/moodle into MOODLE_401_STABLE 2023-05-15 12:06:02 +08:00
Andrew Nicols 0e4426818a Merge branch 'MDL-78125-401' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-05-15 11:58:59 +08:00
Jun Pataleta e9f6b9c2d6 MDL-78125 qtype_multianswer: Convert popover trigger to link
According to Boostrap Popovers documentation for popovers triggered
on focus:
"For proper cross-browser and cross-platform behavior, you must use the
<a> tag, not the <button> tag, and you also must include a tabindex
attribute."
2023-05-12 22:47:11 +08:00
Luca Bösch f1dd604fce MDL-77432 mod_assign: Confirm submission page standard and not incourse 2023-05-12 09:44:22 +02:00
Ilya Tregubov 017a3274fe weekly release 4.1.3+ 2023-05-12 08:56:50 +08:00
Ilya Tregubov 3b9bfc1d79 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-05-12 08:56:48 +08:00
Cameron Ball 77eb2ed79b MDL-75898 assignfeedback_editpdf: Add randomness to PDF annotations
The behat step "I draw on the pdf" creates the exact same line every
time it is called. This can cause issues in a situation like the following:

- Student uploads PDF
- Teacher annotates page 1
- Student edits submission, adding another PDF
- Teacher annotates page 1 again
- When the student looks at their annotated PDF it appears the same as
  before they added the second PDF (i.e., they don't see extra pages for
  the second PDF)

Exactly why this happens isn't clear, and in practice this probably never
happens because the chances of drawing the exact same line twice are almost
0. However, when testing the functionality added in MDL-45580 it was causing
issues.
2023-05-12 09:14:03 +10:00
Cameron Ball 90350915c2 MDL-75898 assignfeedback_editpdf: Don't poll readonly pages
When requesting the readonly version of pages (which contain
teacher annotations), they should always be available - the
PHP side even throws an exception when they're not. This
means we don't need to worry about polling document converters
from the JS side and can just return the pages immediately.
2023-05-12 09:14:03 +10:00
Cameron Ball 825609ae08 MDL-75898 assignfeedback_editpdf: Improve page count mismatch logic
MDL-45580 introduced the readonlypages filearea, and when loading
page images for an attempt, the code would check if the pages existed
, creating them if not. The code inside this block also contained
a guard clause for the case where no readonly pages existed - which
is a situation that should not happen. Whenever readonly pages are
requested, they should exist.

MDL-66626 introduced a situation where page counts not matching would
also retrigger page generation. However this led to a situation where
the guard clause could be entered when requesting readonly pages.

This patch refactors the guard clause, and improves the logic to
regenerate pages.
2023-05-12 09:14:03 +10:00
Paul Holden 5b3d55def7 MDL-78226 contentbank: verify presence of bank heading element. 2023-05-11 23:16:33 +01:00
Paul Holden 67effa603e MDL-78225 output: add sesskey for post requests only in renderables. 2023-05-11 22:48:54 +01:00
Laurent David 20b4efad5c MDL-76903 mod_book: Fix activity completion
* Check only visibles pages to set completion status.
* Make sure we have consistent completion value in API and on the view page.
2023-05-11 12:09:24 +02:00
Paul Holden 11af0c5388 MDL-78140 analytics: improve context restrictions manager test.
This test apparently fails sporadically on Oracle, without obvious
causes. The failure however was hard to interpret, and the test
itself made a lot of assumptions about the system re. naming of
categories/courses. This could be prone to errors, so improve that.
2023-05-11 09:38:01 +01:00
Paul Holden 683840999d MDL-77946 access: fix category sort order of capability contexts. 2023-05-11 08:33:32 +01:00
Jun Pataleta f8537a9536 Merge branch 'MDL-76344-401-fix' of https://github.com/stevandoMoodle/moodle into MOODLE_401_STABLE 2023-05-11 14:35:30 +08:00
Stevani Andolo 7b1e0a6980 MDL-76344 course: Fixed course image 'non image file' layout 2023-05-11 14:11:16 +08:00
Jake Dallimore 838047106d Merge branch 'MDL-75552-401' of https://github.com/sarjona/moodle into MOODLE_401_STABLE 2023-05-11 11:23:49 +08:00
Sara Arjona 84175f399f Merge branch 'MDL-78040-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-10 19:45:18 +02:00
Paul Holden 9e0f8fc7bf MDL-78211 contentbank: fix context option when formatting categories. 2023-05-10 17:42:29 +01:00
Paul Holden c228866a46 MDL-78151 core: account for timezone differences in intl extension.
Recent additions to timezones from the IANA TZDB are not necessarily
reflected in those used by the intl extension and/or ICU zones:

 * America/Ciudad_Juarez
 * America/Nuuk
 * Europe/Kyiv
 * Pacific/Kanton

Create mapping to allow these zones to be used without errors.
2023-05-10 17:12:33 +01:00
Juan Leyva d82f68742b MDL-78196 user: Fix files used space check 2023-05-10 17:17:48 +02:00
Andrew Nicols da78523b15 Merge branch 'MDL-77592-401' of https://github.com/golenkovm/moodle into MOODLE_401_STABLE 2023-05-10 13:03:57 +08:00
Andrew Nicols 5ceb711355 Merge branch 'MDL-78034-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-10 13:00:30 +08:00
Ilya Tregubov 1d5ef6aa9a Merge branch 'MDL-75623-MOODLE_401_STABLE' of https://github.com/sh-csg/moodle into MOODLE_401_STABLE 2023-05-10 11:46:40 +08:00
Paul Holden d3b4e4a9a5 MDL-78170 rating: consistently calculate average rating aggregation.
Ensure it's always cast by the database as a float, to avoid loss of
precision.
2023-05-09 15:57:43 +01:00
Paul Holden d7ba3f656d MDL-78149 mod_data: ensure group selector is always present. 2023-05-09 12:20:35 +01:00
Paul Holden 48963bb7a7 MDL-78152 mod_book: set permissions required for page editing. 2023-05-09 12:11:32 +01:00
Shamim Rezaie f36c96411d MDL-77451 gradereport: stress handling for multiple clicks 2023-05-09 19:15:37 +10:00
Andrew Nicols 50d1e69df6 MDL-75552 badges: move apiBase consumption to backpack
The apiBase in .well-known/badgeconnect.json was ignored and it was
causing some failures when connecting or sending badges to an
external backpack.
For OBv2.1, it has been changed to always use the apiBase defined
in the badgeconnect.json backpack provider.
2023-05-09 08:51:30 +02:00
Rajneel Totaram f6c5fa3bfc MDL-77930 accesslib: php81 deprecation warnings on missing plugins 2023-05-09 17:37:00 +12:00
Juan Leyva d838917d28 MDL-78072 airnotifier: Apply payload size optimisation to all push
Backport of MDL-77893.

Co-authored by: Andrew Lyons <andrew@nicols.co.uk>
2023-05-09 13:07:10 +08:00
Juan Leyva 1af4ace4d6 MDL-78072 airnotifier: Allow configuring how to process encrypted notifs
Backport of MDL-77893.

Co-authored by: Andrew Lyons <andrew@nicols.co.uk>
2023-05-09 13:07:09 +08:00
Juan Leyva 5c85fb975d MDL-78072 airnotifier: Leave only message data processed by: Airnotifier
Backport of MDL-77893.

Co-authored by: Andrew Lyons <andrew@nicols.co.uk>
2023-05-09 13:07:09 +08:00
Juan Leyva 2ad6fecca5 MDL-78072 airnotifier: Allow to set publickey when creating new device
Backport of MDL-77893.

Co-authored by: Andrew Lyons <andrew@nicols.co.uk>
2023-05-09 13:07:09 +08:00
Sara Arjona 1201526dbc MDL-78072 core: Fix upgrade failures with MariaDB
Backport of MDL-76722.

Co-authored by: Andrew Lyons <andrew@nicols.co.uk>

The 'enable' field doesn't exist, and this is causing some failures
with MariaDB (and probably with MySQL too).
2023-05-09 12:26:00 +08:00
Alex Morris 6ccb50ea9d MDL-78072 message_airnotifier: Add encrypted notifications
Backport of MDL-76722.

Co-authored by: Andrew Lyons <andrew@nicols.co.uk>
2023-05-09 12:25:47 +08:00
Alex Morris 25498b6b62 MDL-78072 user: Add new update_user_device_public_key webservice
Backport of MDL-76722.

Co-authored by: Andrew Lyons <andrew@nicols.co.uk>
2023-05-09 12:25:29 +08:00
Alex Morris a2179f028c MDL-78072 lib/db: Add new publickey field to user_devices table
Backport of MDL-76722.

Co-authored by: Andrew Lyons <andrew@nicols.co.uk>
2023-05-09 12:25:16 +08:00
Petr Skoda a7920b3860 MDL-76688 filter_text: prevent LaTeX3 syntax 2023-05-08 10:12:46 +02:00
AMOS bot 893fe94c89 Automatically generated installer lang files 2023-05-07 00:07:26 +00:00
Paul Holden ba904934ec MDL-78135 completion: include required criteria library in test. 2023-05-05 16:45:48 +01:00
Jake Dallimore b3feea921d MDL-76821 enrol_lti: prevent legacy launches via upgraded enrolment
If the enrolment instance (the 'published resource') has been upgraded
from LTI 1.1/2.0 to LTI 1.3 (i.e. a new instance was not created),
prevent legacy launches which may occur from old resource links. Only
LTI Advantage launches should be permitted through the method.
2023-05-05 17:11:09 +08:00
Jake Dallimore 22c346831e MDL-76821 enrol_lti: fix bug in repo causing return of legacy lti users
If the enrolment method is updated from an LTI 1.1/2.0 tool to an LTI
1.3 tool, it may have associated enrol_lti_users records not having
ltideploymentid values. These are legacy users and must not be returned
by the repository, which deals only with LTI 1.3 LTI users.
2023-05-05 17:11:06 +08:00
Jun Pataleta 0703a8db55 Merge branch 'MDL-76344-401' of https://github.com/stevandoMoodle/moodle into MOODLE_401_STABLE 2023-05-05 10:34:56 +08:00
Sara Arjona 176a323b4e weekly release 4.1.3+ 2023-05-04 12:42:50 +02:00
Eloy Lafuente (stronk7) 42f3874b80 MDL-78116 core: Run tests against Windows on GHA
Signed-off-by: Andrew Nicols <andrew@nicols.co.uk>
2023-05-04 15:40:18 +08:00
Stevani Andolo 1f07219332 MDL-76344 course: Fixed course image 'non image file' layout 2023-05-04 10:28:15 +08:00
Paul Holden 0c7e7645d5 MDL-78040 block_glossary_random: switch to block test generator.
Random failures after manually adding block instances (specifically
on slow/Oracle systems) can be entirely avoided by using the block
test generator for scenarios that are not specifically concerned with
manually adding blocks.
2023-05-03 17:16:22 +01:00
Laurent David 9117af48ac MDL-77781 core_completion: Completion view must be deleted too
When resetting a course, completion view entries should also be
deleted

Co-authored-by: Georg Moser <georg@moser.link>
2023-05-03 16:05:28 +02:00
Jun Pataleta d1c24b02ab Merge branch 'MDL-77398-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-03 20:36:18 +08:00
Jake Dallimore 79fe493ab4 Merge branch 'MDL-77384-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-03 16:52:45 +08:00
Jake Dallimore d66398c356 Merge branch 'MDL-78023-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-03 16:15:59 +08:00
Sara Arjona 6064ce62f5 Merge branch 'MDL-77312-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-03 09:59:22 +02:00
Ilya Tregubov 88113fc983 Merge branch 'MDL-77320-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-03 15:37:00 +08:00
Ilya Tregubov e19573d6bf Merge branch 'MDL-77810-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-03 13:08:52 +08:00
Ilya Tregubov 3994ab206b Merge branch 'MDL-77987_401' of https://github.com/AnupamaSarjoshi/moodle into MOODLE_401_STABLE 2023-05-03 12:40:34 +08:00
Ilya Tregubov b9d84d03ca Merge branch 'MDL-77546-401' of https://github.com/mihailges/moodle into MOODLE_401_STABLE 2023-05-03 10:57:29 +08:00
Jun Pataleta f8fdd198a9 Merge branch 'MDL-77394-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-03 10:31:00 +08:00
Jun Pataleta 394d592fab Merge branch 'MDL-78038-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-03 10:25:30 +08:00
Jun Pataleta 64c625e590 Merge branch 'MDL-78011-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-03 09:57:56 +08:00
Ilya Tregubov be0eb4369b Merge branch 'MDL-76835-401' of https://github.com/aya-saad1/moodle into MOODLE_401_STABLE 2023-05-03 09:29:59 +08:00
David Woloszyn b3424d620d MDL-77840 enrol_lti: Avoid passing nulls to base64_encode 2023-05-03 09:36:17 +10:00
Sara Arjona 767419571e Merge branch 'MDL-77858-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-05-02 16:49:53 +02:00
Sara Arjona aa63dca768 Merge branch 'MDL-77791_401' of https://github.com/dvdcastro/moodle into MOODLE_401_STABLE 2023-05-02 12:03:59 +02:00
Jun Pataleta 2dc4853ba5 Merge branch 'MDL-76857-401' of https://github.com/sarjona/moodle into MOODLE_401_STABLE 2023-05-02 15:44:55 +08:00
David Woloszyn 5ab74afad4 MDL-77840 lti: Avoid passing nulls to base64_encode 2023-05-02 13:52:12 +10:00
David Woloszyn f25ecd9bfa MDL-77840 backup: Avoid passing nulls to base64_encode 2023-05-02 13:52:12 +10:00
David Woloszyn 88496af850 MDL-77840 mnet: Avoid passing nulls to base64_encode 2023-05-02 13:52:12 +10:00
Ilya Tregubov d28386a29d Merge branch 'MDL-78025_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-05-02 11:43:30 +08:00
Jake Dallimore 4fa9ed7956 Merge branch 'MDL-78009-401' of https://github.com/marinaglancy/moodle into MOODLE_401_STABLE 2023-04-28 13:26:02 +08:00
Paul Holden 569a71daea MDL-77810 gradereport_summary: show localised plugin name in report. 2023-04-27 15:19:33 +01:00
Ilya Tregubov 4901ffe1ba weekly release 4.1.3+ 2023-04-27 19:28:38 +08:00
Sara Arjona b10f6f5036 MDL-76857 filter_displayh5p: Improve behat tests
Although the screenshots in the failures for some of the scenarios in
filter/displayh5p/tests/behat/h5p_filter.feature, like "Render a local
H5P file as teacher" were displaying the expected result, there were
some javascript errors (probably due to behat is quicker and the
iframes were not always ready).
I've added one extra step before accessing the iframe to give more
time to the H5P player to load and confirm the page is displayed
properly.
2023-04-27 11:21:36 +02:00
Paul Holden 30e419078f MDL-77320 tool_licensemanager: restrict exposure of user sesskey. 2023-04-27 09:32:37 +01:00
Mihail Geshoski f90a55979a MDL-77546 gradereport_singleview: Fix item order in grade item selector 2023-04-27 12:01:23 +08:00
Jun Pataleta 013735af51 Merge branch 'MDL-77883-401' of https://github.com/danghieu1407/moodle into MOODLE_401_STABLE 2023-04-27 11:08:54 +08:00
Jun Pataleta 6c890a6330 Merge branch 'MDL-77997_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-04-27 10:40:43 +08:00
Paul Holden 4f7dd1a54b MDL-78038 mod_bigbluebuttonbn: observe course format section config. 2023-04-26 16:10:52 +01:00
Tim Hunt de8607067f MDL-78025 questions: improve the comment on question_references.version 2023-04-26 15:45:12 +01:00
Tim Hunt 15ff1352c2 MDL-78025 questions: fix PHPdoc on question_require_capability_on 2023-04-26 15:45:00 +01:00
Tim Hunt 384ab12c55 MDL-78025 quiz: fix the quiz_questions_in_use logic 2023-04-26 15:44:54 +01:00
Tim Hunt 4a9c0b1410 MDL-78025 questions: questions_in_use should check question_references
This avoids the needs for plugins to do separate queries, which is
easier for them, and better performing.
2023-04-26 15:40:41 +01:00
Tim Hunt d2d9d762ad MDL-78025 question generator: make the behaviour less surprising
* The object returned by update_question is alwasy a new clone
  and the $question passed in will not be modified.

* The returned object has the fields like questionbankentryid and
  the ones related to versionning, so it is more like the data
  returned by question_bank::load_question_data.
2023-04-26 15:40:36 +01:00
Tim Hunt a9fa52295a MDL-78025 question: move hiding logic into question_delete_question
This logic belongs in the API, so it is applied consistently.

Also this avoids calling the expensive function questions_in_use
twice per question.
2023-04-26 15:38:57 +01:00
Paul Holden eca7a9ce2b MDL-78034 mod_bigbluebuttonbn: format instance group names. 2023-04-26 15:31:44 +01:00
Aya Saad bba6cc2f02 MDL-76835 theme: Fix unordered lists indentation 2023-04-26 13:57:49 +02:00
David Castro e5c89630af MDL-77791 data: Fix file attachment to search doc 2023-04-25 19:49:33 -05:00
Paul Holden 491ee67cd9 MDL-78023 tool_policy: cast timemodified column on table download. 2023-04-25 14:51:13 +01:00
Sara Arjona 9a3430f3fe Merge branch 'MDL-77313-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-04-25 15:18:42 +02:00
Paul Holden 79982a82a4 Merge branch 'MDL-78007-401' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2023-04-25 12:36:09 +01:00
Paul Holden 4ee0bdfda6 Merge branch 'MDL-73331_401_toolbrickfieldadvancedtab' of https://github.com/brickfield/moodle into MOODLE_401_STABLE 2023-04-25 11:54:17 +01:00
Paul Holden d10d553890 Merge branch 'MDL-77766-401-2' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-04-25 09:38:37 +01:00
Paul Holden 22b481f73c MDL-77384 check: clarify statistics check name. 2023-04-25 09:04:41 +01:00
Paul Holden b867e4db40 MDL-78011 qbank_managecategories: require library for pagesize const. 2023-04-24 15:35:54 +01:00
Marina Glancy ccdaef7a68 MDL-78009 auth: require necessary files 2023-04-24 13:38:58 +01:00
Jun Pataleta 952c8770b6 MDL-77766 qtype_truefalse: Respect showstandardinstruction
* When showstandardinstruction is set to no, replace the standard
instruction with the generic "Answer" text for the answer options
fieldset's legend.
2023-04-24 20:11:20 +08:00
Jun Pataleta 132ac7486d MDL-77766 qtype_multichoice: Respect showstandardinstruction
* When showstandardinstruction is set to no, replace the standard
instruction with the generic "Answer" text for the answer options
fieldset's legend.
2023-04-24 20:11:20 +08:00
Tim Hunt a9f629fbf9 MDL-77997 questions: add back Export as XML to the preview screen
The used the exist in Moodle up to 3.11, but then was removed with
insufficient thought in 4.0 (because we had grander long-term plans
which still have not happened). Until those plans happen, this
commit adds the simple link back on the preview screen.
2023-04-24 11:23:47 +01:00
Anupama Sarjoshi c6708db889 MDL-77987 Backup: add progress tracking to some slow steps 2023-04-24 11:17:34 +01:00
Paul Holden 0d7393c7ee MDL-77312 files: exclude drafts when determining license usage. 2023-04-24 11:07:38 +01:00
Paul Holden f3ae5116d0 MDL-77313 restore: re-add field to indicate course/category search.
When the two restore forms for searching courses and categories were
converted to core templates in eb9935c9 they lost the named submit
button, which broke searching.
2023-04-24 11:04:26 +01:00
Paul Holden b01ce337f6 MDL-77858 javascript: correct core/notification exception imports. 2023-04-24 10:44:14 +01:00
Paul Holden bb433919cc MDL-77394 mod_forum: de-couple discussion pinned/starred options. 2023-04-24 10:38:01 +01:00
Paul Holden 1e16260ba7 MDL-77398 mod_assign: disable form submit protection for batch options. 2023-04-24 10:35:15 +01:00
Huong Nguyen 4ec5aac734 MDL-78007 tiny_media: Fix wrong condition for the Tiny Media
Including in this commit:
 - Switched to Tiny editor in manually_mark_question.feature
2023-04-24 15:59:32 +07:00
danghieu1407 b04fab1a2a MDL-77883 forms: fix display of client-side validation for textareas 2023-04-24 13:54:37 +07:00
Jun Pataleta b2d0712748 Moodle release 4.1.3 2023-04-22 16:22:40 +08:00
Eloy Lafuente (stronk7) f70a6d32cd weekly release 4.1.2+ 2023-04-21 19:19:12 +02:00
Eloy Lafuente (stronk7) f691ccf8c6 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-04-21 19:19:07 +02:00
Jun Pataleta ceb2f856b0 Merge branch 'MDL-77927-401' of https://github.com/stevandoMoodle/moodle into MOODLE_401_STABLE 2023-04-21 16:52:21 +08:00
Jun Pataleta 955d89710e Merge branch 'MDL-77229-patch-401' of https://github.com/ilyatregubov/moodle into MOODLE_401_STABLE 2023-04-21 16:44:38 +08:00
Jun Pataleta 526e1af88b MDL-77927 core: mod_assignment subplugins environment check 2023-04-21 15:53:32 +08:00
Ilya Tregubov b142840de1 MDL-77229 mod_lesson: Black list detailed statistics in classic Behat.
The nav element to go to detailed stats page is missing in classic
2023-04-21 15:07:36 +08:00
Ilya Tregubov 8fb9177b74 Merge branch 'MDL-77229-401' of https://github.com/ilyatregubov/moodle into MOODLE_401_STABLE 2023-04-21 12:11:40 +08:00
Ilya Tregubov 6e15a26dce MDL-77229 lesson: Add Behat test 2023-04-21 12:04:17 +08:00
Jun Pataleta b5a65e56fd Merge branch 'MDL-77896-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-04-21 11:10:39 +08:00
AMOS bot a6a0e98e53 Automatically generated installer lang files 2023-04-21 00:07:41 +00:00
Paul Holden c28cd3215b MDL-77896 editor_tiny: approximate height for non-visible editors.
When an editor is renderer initially invisible to the browser, e.g.
the forum "Add discussion" form, it has a `clientHeight` value of
zero. We can approximate an alternative value based on the number
of rows in the textarea.

Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
2023-04-20 15:24:34 +01:00
Juan Leyva 39084a098b MDL-77229 lesson: Fix error for empty responses (numerical pagetype) 2023-04-20 12:46:42 +02:00
Jun Pataleta 9290627da9 Merge branch 'MDL-73012-401' of https://github.com/ferranrecio/moodle into MOODLE_401_STABLE 2023-04-20 16:29:14 +08:00
Ilya Tregubov bb5bd2eed8 Merge branch 'MDL-77436-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2023-04-20 16:23:19 +08:00
Jun Pataleta 12195684b4 Merge branch 'MDL-77922-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-04-20 16:10:10 +08:00
Ferran Recio f01ad40145 MDL-73012 core_courseformat: add pending to move section modal 2023-04-20 09:56:10 +02:00
Ferran Recio 1d64897a3c MDL-77922 core_courseformat: add pending to move activity modal 2023-04-20 14:42:30 +08:00
Ilya Tregubov 339dfec420 Merge branch 'MDL-77577-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-04-20 12:33:38 +08:00
Andrew Nicols 1d16c049f3 MDL-77718 editor_tiny: Restrict the revision to int for loaders
The revision should always be an int. I suspect this was missed during
debugging and not corrected.
2023-04-19 13:20:25 +00:00
Paul Holden 4d4635228d MDL-77187 mod_wiki: validate external method sort parameters. 2023-04-19 13:20:25 +00:00
Paul Holden ce9cb1156c Merge branch 'MDL-77897-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-04-19 14:13:04 +01:00
Paul Holden c0429c1c90 Merge branch 'MDL-77960-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-04-19 13:41:32 +01:00
Paul Holden be8c02fc2c Merge branch 'MDL-77944-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-04-19 13:06:41 +01:00
Max Larkin 60a2798da7 MDL-73331 tool_brickfield: Update advanced tab display 2023-04-19 12:57:37 +01:00
Paul Holden 99b5e1059d Merge branch 'MDL-77898-401' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-04-19 09:03:22 +01:00
Andrew Nicols ee519b690c MDL-77897 editor_tiny: Save editor content on editor blur 2023-04-19 14:57:26 +08:00
Ilya Tregubov 814c63fcc3 git fetch https://github.com/paulholden/moodle.git MDL-77935 && git merge --no-ff FETCH_HEADMerge branch 'MDL-77935-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-04-19 13:32:36 +08:00
Jun Pataleta 799e962f1f Merge branch 'MDL-77953_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2023-04-19 12:37:45 +08:00
Simey Lameze c0bea2a82d MDL-77960 behat: make verification steps more specific 2023-04-19 11:57:37 +08:00
Eloy Lafuente (stronk7) e9fcdec98b MDL-77953 pagelib: Ensure that null $SCRIPT continues behaving the same
It's possible to have some Moodle components soft linked instead
of being real directories within codebase (within dirroot).

For example, Composer's "vendor" directory can be soft linked
(from elsewhere), or also plugins can be installed using soft
links.

In those cases, Moodle calculates the $SCRIPT global as null. And,
then, string operations on it are emitting a PHP deprecation message
with PHP 8.1 and up.

This fix just ensures that the behaviour is the same than before
PHP 8.1, aka: ltrim(null) = '' (empty string), without any PHP warning.
2023-04-18 18:50:37 +02:00
Andrew Nicols fc6764324a Merge branch 'MDL-77895-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-04-18 23:35:19 +08:00
Andrew Nicols b71f01981a weekly release 4.1.2+ 2023-04-18 22:28:09 +08:00
Andrew Nicols 5d1fcb942a Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-04-18 22:28:06 +08:00
Jun Pataleta 24335d67bb MDL-77898 calendar: Add iconclass for upcoming_mini template
The icon's iconclass context data adds additional CSS class(es) to
calendar event icons to better control how the event icon is displayed.
e.g. without filtering for activity events that don't hae monologo
versions of their icons.
2023-04-18 15:58:46 +08:00
Paul Holden 1b828701a6 MDL-77895 editor_tiny: standardize quickbar selection toolbar.
Ensure the same heading tags are available as those defined in the
editor block formats configuration (c51b7e2c).

Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
2023-04-18 07:45:23 +01:00
Ilya Tregubov f8e468c41a Merge branch 'MDL-77916-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-04-18 14:28:44 +08:00
Andrew Nicols b07df211ce Merge branch 'MDL-77829-401' of https://github.com/stevandoMoodle/moodle into MOODLE_401_STABLE 2023-04-18 12:31:46 +08:00
Andrew Nicols 4c289966d3 Merge branch 'MDL-77735-401' of https://github.com/sarjona/moodle into MOODLE_401_STABLE 2023-04-18 12:10:56 +08:00
Ilya Tregubov 0d0fbec616 Merge branch 'MDL-77770-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-04-18 12:01:46 +08:00
Ilya Tregubov ca751bdc1f Merge branch 'MDL-76855-401' of https://github.com/Chocolate-lightning/moodle into MOODLE_401_STABLE 2023-04-18 11:18:32 +08:00
Andrew Nicols bc85007834 MDL-77944 behat: Rename chrome options for w3c support
From Selenium 4.8.0, support for non-w3c browser control has ended.

We only use W3C browser control these days, and this was missed as part
of the move to W3C. All browser options must be vendor-prefixed.
2023-04-18 09:04:08 +08:00
Ilya Tregubov dd553c1406 Merge branch 'MDL-77827-401' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2023-04-18 08:59:30 +08:00
AMOS bot 76ab8a1c51 Automatically generated installer lang files 2023-04-18 00:07:38 +00:00
Paul Holden 242ecbf7f3 Merge branch 'MDL-77878-401-enfix' of https://github.com/vmdef/moodle into MOODLE_401_STABLE 2023-04-17 19:12:36 +01:00
Shamim Rezaie cbfde8c11a Merge branch 'MDL-76998-401' of https://github.com/aanabit/moodle into MOODLE_401_STABLE 2023-04-17 21:27:56 +10:00
Paul Holden df4f8dd322 Merge branch 'MDL-76212-401-nav' of https://github.com/kevpercy/moodle into MOODLE_401_STABLE 2023-04-17 11:50:54 +01:00
Paul Holden 60ab09ac87 Merge branch 'MDL-77324-401-2' of https://github.com/ilyatregubov/moodle into MOODLE_401_STABLE 2023-04-17 11:06:14 +01:00
Paul Holden 40fad4d6b7 MDL-77935 contentbank: avoid phpunit crashes during isolated tests.
Simplify the test for allowed contexts by removing problematic use of
data provider annotation.

See: https://github.com/sebastianbergmann/phpunit/issues/2739
2023-04-17 09:28:38 +01:00
Víctor Déniz 1265b0ad84 MDL-77878 lang: Use fixed strings in tests 2023-04-17 09:26:52 +01:00
Mathew May faa121ad30 MDL-76855 gradereport_user: Prevent parent access errors 2023-04-17 11:26:03 +08:00
Andrew Nicols 797cbcc3da Merge branch 'MDL-76995-401' of https://github.com/aanabit/moodle into MOODLE_401_STABLE 2023-04-17 11:17:04 +08:00
Ilya Tregubov 6bac910434 MDL-76994 core_course: Fix version for weeks and topics course formats 2023-04-17 11:04:37 +08:00
Andrew Nicols a9b4b297ac Merge branch 'MDL-77606' of https://github.com/skodak/moodle into MOODLE_401_STABLE 2023-04-17 10:34:55 +08:00
Petr Skoda 073deca0e1 MDL-77606 grunt: fix Windows compatibility
Backport of MDL-77748.
2023-04-17 10:34:09 +08:00
Petr Skoda 2cc1182b16 MDL-77606 core: switch to Dart sass
Backport of MDL-73144.
2023-04-17 10:33:50 +08:00
Ilya Tregubov 82a7b26648 Merge branch 'MDL-76994-401' of https://github.com/aanabit/moodle into MOODLE_401_STABLE 2023-04-17 09:47:04 +08:00
Helen Foster 2db1ddd290 MDL-77878 lang: Import fixed English strings (en_fix) 2023-04-16 20:54:48 +01:00
Sara Arjona 96f0478ec1 Merge branch 'MDL-77913-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-04-14 14:02:18 +02:00
Sara Arjona 38f5c818cb MDL-77735 core: Check $CFG->lang isset
In some cases, $CFG->lang might not be set, and this is causing a
Notice to be displayed when, for instance, database connection fails.
This patch should fix this case.
2023-04-14 13:46:51 +02:00
Sara Arjona 38c35247e9 weekly release 4.1.2+ 2023-04-14 10:50:08 +02:00
Sara Arjona 242dcfbc55 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-04-14 10:50:03 +02:00
Huong Nguyen 2f601f1e51 MDL-77827 events: Changed JSON comparison to be less strict 2023-04-14 12:29:32 +07:00
Paul Holden 31a3c8cda4 MDL-77916 h5p: register autoloader in helper testcase. 2023-04-13 23:14:57 +01:00
Paul Holden 39cf556111 MDL-77913 qbank_previewquestion: deterministic ordering of versions.
Ensure the ordering of loaded question versions is consistent, avoids
random Oracle failures.
2023-04-13 21:45:28 +01:00
Sara Arjona 4c4be40c77 Merge branch 'MDL-76986-401' of https://github.com/davewoloszyn/moodle into MOODLE_401_STABLE 2023-04-13 17:32:03 +02:00
Amaia Anabitarte c8f105800c MDL-76995 core_courseindex: Apply indentation in the course index 2023-04-13 16:59:05 +02:00
Amaia Anabitarte 3502ad3da7 MDL-76998 admin: Option to reset course indentation 2023-04-13 16:52:19 +02:00
Amaia Anabitarte 15a5a938b6 MDL-76994 tool_mobile: Return course format indentation setting 2023-04-13 16:51:05 +02:00
Amaia Anabitarte ec4eacd1da MDL-76994 core_course: New course format setting to enable indentation 2023-04-13 16:50:58 +02:00
Sara Arjona bc34e3fef3 Merge branch 'MDL-76859-401' of https://github.com/sarjona/moodle into MOODLE_401_STABLE 2023-04-13 16:24:28 +02:00
Sara Arjona 6aef92c24a Merge branch 'MDL77833-course-content-chng-notificatn-multilang' of https://github.com/Amrita1991/moodle into MOODLE_401_STABLE 2023-04-13 16:20:06 +02:00
Sara Arjona 4b7c58febf Merge branch 'MDL-77860-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-04-13 13:45:00 +02:00
Sara Arjona 4ed6c8fbce Merge branch 'MDL-77788-401' of https://github.com/rmady/moodle into MOODLE_401_STABLE 2023-04-13 13:17:28 +02:00
Sara Arjona af585fc755 Merge branch 'MDL-77618-admin-password-autocomplete-MOODLE_401_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_401_STABLE 2023-04-13 12:19:16 +02:00
Amrita Deb Dutta 6ae5ee18a0 MDL-77833 course: content change notification multilang processing
adding context to format string

content change notificatn coursename multilang processing

change context param
2023-04-13 11:28:41 +02:00
Sara Arjona ead7958219 Merge branch 'MDL-77256-401' of https://github.com/rbravod/moodle into MOODLE_401_STABLE 2023-04-13 11:20:32 +02:00
Ilya Tregubov 8dc9cd6cdc MDL-77324 gradereport_singleview: Make action menus consistent 2023-04-13 16:59:23 +08:00
Sara Arjona 69749509ab Merge branch 'MDL-77856-401' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-04-13 09:43:05 +02:00
Sara Arjona 59eac981eb Merge branch 'MDL-77468-401' of https://github.com/rmady/moodle into MOODLE_401_STABLE 2023-04-13 09:19:58 +02:00
David Woloszyn ab0038da84 MDL-76986 editor_tiny: Convert language code format for getting strings 2023-04-13 16:05:14 +10:00
Juan Leyva 2cde957897 MDL-77468 user: Fix invalid check for group belonging 2023-04-12 22:13:22 -03:00
Sara Arjona a8eb481980 Merge branch 'MDL-73610_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2023-04-12 18:19:40 +02:00
Juan Leyva 4c533b8204 MDL-77468 user: Make user profile visibility consistent web and ws 2023-04-12 09:15:47 -03:00
Sara Arjona 26aaa7486a Merge branch 'MDL-77012-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-04-12 14:09:33 +02:00
Petr Skoda f336875b1a MDL-76859 h5p: Fix behat failures
- Only resize if the H5P EmbedCommunicator is defined (otherwise, it was causing a
JS error)
- An unnecessary image has been removed from the greeting-card.h5p fixture package.
That way, the text will always be displayed (even if the iframe is still not
resized). Instead of replacing the original greeting-card-887.h5p file, I've
renamed it to greeting-card.h5p, to remove these ugly and unnecessary numbers
at the end of the file name).
2023-04-12 12:27:06 +02:00
Sara Arjona 6381daf52a Merge branch 'MDL-76993-401' of https://github.com/aanabit/moodle into MOODLE_401_STABLE 2023-04-12 09:54:22 +02:00
Kevin Percy 5b8ad6ae30 MDL-76212 gradebook_nav: Fixed tertiary nav for smaller screens 2023-04-12 14:12:50 +08:00
Amaia Anabitarte 3a38791d62 MDL-76993 core_course: Recover move right/left functionality
This is a backport of MDL-76990
2023-04-11 13:28:00 +02:00
Sara Arjona 5563e99f2c Merge branch 'MDL-77837-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-04-11 12:12:49 +02:00
Sara Arjona 8bc1c231d6 Merge branch 'MDL-77552-401' of https://github.com/ferranrecio/moodle into MOODLE_401_STABLE 2023-04-11 11:13:41 +02:00
Sara Arjona 1226208a64 Merge branch 'MDL-77148_401' of https://github.com/AnupamaSarjoshi/moodle into MOODLE_401_STABLE 2023-04-11 10:17:08 +02:00
Sara Arjona 725277eb8b Merge branch 'MDL-77612-401' of https://github.com/laurentdavid/moodle into MOODLE_401_STABLE 2023-04-11 10:04:41 +02:00
Laurent David b631966a70 MDL-77612 mod_label: Label name fix
* The @@PLUGINFILE@@ placeholder or URLs should not be displayed in the
course index for labels
2023-04-11 05:24:39 +02:00
Stevani Andolo b796cbd03c MDL-77829 core: Added environment check for mod_assignment
Decided to add an environment check before uninstalling the
mod_assignment plugin to prevent data lost.
2023-04-10 13:54:00 +08:00
AMOS bot 1066f5fe68 Automatically generated installer lang files 2023-04-07 00:07:35 +00:00
Andrew Nicols 202718f968 MDL-77837 core: Improve usage docs for cron_setup_user 2023-04-06 23:21:29 +08:00
Andrew Nicols 44d734147a MDL-77837 phpunit: Ensure that the cron user setter is used
When running an adhoc task in a unit test we should use the cron variant
of the set user method to mimic the behaviour of a real cron run.
2023-04-06 23:21:29 +08:00
Andrew Nicols 346cb39cff MDL-77837 cron: Ensure user is set when running tasks
We should be proactive in ensuring that the environment is clean when
running a task. We already ensure that we have a clean renderer and
other parts of the output chain, but we were not setting a clean user.

This change adds a call to setup the cron user before each task is
actually executed.
2023-04-06 23:21:29 +08:00
Paul Holden eb12428324 MDL-77770 gradereport_user: fix errors when no users to navigate. 2023-04-06 14:41:03 +01:00
Anupama Sarjoshi 8b31922739 MDL-77148 core: Fix to export params for templates in correct format
When questions are filtered by tags in the question bank, the qtagids
params are passed in the array format. Though moodle_url handles this,
single_button::export_for_template cannot. Hence changes done in
weblib.php to provide params for export_for_template in the
suitable format.
Thanks Huong. I have added the Behat test you provided in the patch.
2023-04-06 14:38:29 +01:00
Eloy Lafuente (stronk7) 127174088a MDL-73610 nodejs: Small updates to required packages
The main goal of this issue is to avoid scanners (Dependabot
and friends), reporting about security issues with the current
xmldom 0.6.0 package.

Note that this doesn't affect prod at all, because it's a dev
dependency, hardly exploitable. So it's not a security fix, just
a security_benefit, if something.

So here, we are updating from xmldom 0.6.0 to @xmldom/xmldom 0.8.7
(note that the package was renamed in 0.7.0, so it's the very same)

Also, when proceeding with the changes, it was detected that we
are incorrectly declaring @babel/eslint-parser as a normal dependency
instead of a development one, so we are also fixing that little detail.

The commands executed to get the changes above applied have been:

- nvm use
- npm install @xmldom/xmldom@^0.8.7 --save-dev
- npm uninstall xmldom
- npm install @babel/eslint-parser@^7.17.0 --save-dev

(we haven't run a complete re-install because we only want to modify
the minimum possible at this stage).
2023-04-06 14:59:43 +02:00
Sara Arjona f8e2445513 weekly release 4.1.2+ 2023-04-06 14:02:16 +02:00
Sara Arjona cb8bf1e001 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-04-06 14:02:12 +02:00
Sara Arjona 1f7063cc09 Merge branch 'MDL-75301-fix' of https://github.com/sarjona/moodle into MOODLE_401_STABLE 2023-04-06 08:12:03 +02:00
Sara Arjona 60954253d4 MDL-75301 quiz: Fix failing behat test
I cherry-picked this branch from master (because the current 401
had some conflicts). In master, quiz has been moved to quiz_settings,
so that's why the behat test start failing. Using the proper name
fixes it.
2023-04-06 07:15:57 +02:00
Paul Holden d49ebb79c5 MDL-77860 tool_moodlenet: use localised language strings for import. 2023-04-05 23:05:23 +01:00
Jun Pataleta 85a7c17414 MDL-77856 qtype_multianswer: Use Bootstrap Popover for subq feedback
The YUI Overlay widget encloses the subquestion feedback in a div
which causes a div element to be enclosed in the subquestion span. This
leads to an accessibility issue in terms of HTML parsing as inline
elements (span) should not contain block elements (div)
The YUI Overlay widget is also not accessible as it does not really hide
the overlay contents via aria-hidden when the overlay is not being
shown. It's better if we stop using this and use Bootstrap's
popover component which is more accessible by default.

This patch also removes module.js for the qtype_multianswer plugin as
it only contains codes related to rendering the feedback contents in the
YUI overlay widget which is no longer necessary.
2023-04-06 05:35:11 +08:00
Sara Arjona c9b7b94ed4 Merge branch 'MDL-73642_MOODLE_401_STABLE' of https://github.com/tasosb/moodle into MOODLE_401_STABLE 2023-04-05 17:17:35 +02:00
Mark Johnson 0bc265e900 MDL-75301 quiz: Use "always latest" option for question previews
This will set the "alwayslatest" option when previewing a question from
the quiz according to the version setting used in the quiz slot.
2023-04-05 12:50:05 +02:00
Mark Johnson 6417d795b9 MDL-75301 question: Add "always latest" option to previews 2023-04-05 12:49:58 +02:00
Mark Johnson c55473ad2e MDL-75301 question: Add behat generator for updating questions
This adds "core_question > updated question" as an entity for `the
following "X" exist` and calls the existing update_question() generator
which will create a new question version with the supplied data.
2023-04-05 12:49:51 +02:00
Shamim Rezaie ddaf4b7a58 Merge branch 'MDL-77555-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-04-05 20:15:39 +10:00
Paul Holden be58d68f20 MDL-77555 reportbuilder: improve SQL generation within filters.
Use native ANSI SQL syntax for numeric comparisons where possible,
define filter API for the case where filters must re-use the given
field SQL while ensuring uniqueness of any field parameters.

Currently only necessary in the category filter type.
2023-04-05 09:40:31 +01:00
Paul Holden 131d80441a Merge branch 'MDL-69551_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-04-05 08:56:45 +01:00
AMOS bot 8a588f963c Automatically generated installer lang files 2023-04-05 00:07:43 +00:00
Juan Leyva 4e32a42415 MDL-77788 mod_assign: Apply format_string to group names in WS 2023-04-04 18:11:03 -03:00
Tim Hunt aa9a462a4b MDL-69551 quiz: start quiz password field should be a passwordunmask
This help accessibility and usability
2023-04-04 12:19:49 +01:00
Paul Holden 571c59b60e Merge branch 'MDL-77712-401' of https://github.com/laurentdavid/moodle into MOODLE_401_STABLE 2023-04-04 12:06:42 +01:00
Paul Holden 360f9e37f8 MDL-77012 editor_tiny: correct block formats property syntax.
Co-authored-by: Hiroto Kagotani <hiroto.kagotani@gmail.com>
2023-04-04 09:53:20 +01:00
Andrew Nicols 65ba7df04b Merge branch 'MDL-77584-401' of https://github.com/ewallah/moodle into MOODLE_401_STABLE 2023-04-04 12:07:23 +08:00
Simey Lameze 5d000c6f35 MDL-77733 behat: enable Axe accessibility tests by default 2023-04-04 09:18:19 +08:00
AMOS bot 02aed7f6fc Automatically generated installer lang files 2023-04-04 00:07:43 +00:00
Paul Holden 2a4f86051b Merge branch 'MDL-75906-401' of https://github.com/mickhawkins/moodle into MOODLE_401_STABLE 2023-04-03 14:54:05 +01:00
Paul Holden 701541f35b Merge branch 'MDL-77227-401' of https://github.com/aanabit/moodle into MOODLE_401_STABLE 2023-04-03 10:56:19 +01:00
Sara Arjona 839681dc77 Merge branch 'MDL-77807-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-04-03 11:53:19 +02:00
Michael Hawkins b33e5466df MDL-75906 core: Updated security.txt expiry 2023-04-03 17:27:30 +08:00
Laurent David fbbdfefdb6 MDL-77712 core_course: Fix exception with inplace editor
* On fresh install, an exception is raised when we try to modify
the name of a newly inserted activity in the front page
2023-04-03 10:43:11 +02:00
Ferran Recio 8656271a63 MDL-77552 core_courseformat: add plugin and module to cm state
Backport of MDL-77386
2023-04-03 09:35:08 +02:00
Ilya Tregubov e1f3e7f232 Merge branch 'MDL-77603' of https://github.com/ilyatregubov/moodle into MOODLE_401_STABLE 2023-04-03 10:03:53 +08:00
Andrew Nicols f6c4303c58 MDL-77603 theme_boost: Add reference to CL update 2023-04-03 10:02:41 +08:00
Petr Skoda 134dc470c7 MDL-77603 theme_boost: remove Bootstrap version reference 2023-04-03 10:02:36 +08:00
Petr Skoda 45cd887f3b MDL-77603 tool_componentlibrary: import Bootstrap v4.6.2 2023-04-03 10:02:31 +08:00
Petr Skoda b65ec774c5 MDL-77603 theme_boost: import Bootstrap v4.6.2 2023-04-03 10:02:19 +08:00
AMOS bot 215e9f0688 Automatically generated installer lang files 2023-04-02 00:07:37 +00:00
Stefan Hanauska df0f9fa06d MDL-75623 backup: Encode pluginfile URLs 2023-04-01 09:09:39 +02:00
AMOS bot 035ebed95b Automatically generated installer lang files 2023-04-01 00:07:46 +00:00
Paul Holden a78f3a02c6 weekly release 4.1.2+ 2023-03-31 18:11:53 +01:00
Paul Holden 2890546f44 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-03-31 18:11:51 +01:00
Jake Dallimore a1df38dfc6 Merge branch 'MDL-59175-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-31 11:57:27 +08:00
Jake Dallimore 82f9585f55 Merge branch 'MDL-77794-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-31 11:48:42 +08:00
Mikhail Golenkov af7422edc0 MDL-77592 filter_tex: Use request dir instead of temp shared storage 2023-03-31 14:34:54 +11:00
Andrew Nicols 0f092b86b5 Merge branch 'MDL-77783-401' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-03-31 11:31:05 +08:00
Ilya Tregubov 74f3c34cbf Merge branch 'MDL-70976-401' of https://github.com/laurentdavid/moodle into MOODLE_401_STABLE 2023-03-31 09:41:45 +08:00
AMOS bot 1f337e7665 Automatically generated installer lang files 2023-03-31 00:07:40 +00:00
Paul Holden fbb6dc4ca3 MDL-77807 files: normalise file entity size/type column fields.
The `filename` field was only used by each to determine whether the
file was itself a directory, and it's presence meant that aggregation
of each column wasn't working properly.
2023-03-30 20:46:57 +01:00
Laurent David ab3a244568 MDL-77456 core_courseformat: Fix highlight in course index
* When navigating to a restricted activity as a student from the course index
the item is not highlighted when refreshing the page.
2023-03-30 18:57:33 +02:00
Sara Arjona 7b13a543ad Merge branch 'MDL-77761-401' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-03-30 17:53:20 +02:00
Sara Arjona dd10dead0f Merge branch 'MDL-77764-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-30 16:31:21 +02:00
Paul Holden b84a48d1ee Merge branch 'MDL-76481_401_Brickfield_TCPDF_error' of https://github.com/brickfield/moodle into MOODLE_401_STABLE 2023-03-30 12:50:09 +01:00
Sara Arjona 3794210019 Merge branch 'MDL-77762-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-30 13:45:18 +02:00
Jun Pataleta cca75ca956 Merge branch 'MDL-77333_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2023-03-30 19:03:40 +08:00
Paul Holden 93c91af6a9 Merge branch 'MDL-77773-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-03-30 10:41:20 +01:00
Paul Holden 8755738360 MDL-77794 contentbank: fix plugin type language strings.
AMOS BEGIN
 CPY [type_contentbank,core_plugin],[type_contenttype,core_plugin]
 CPY [type_contentbank_plural,core_plugin],[type_contenttype_plural,core_plugin]
AMOS END
2023-03-30 09:58:32 +01:00
Max Larkin 4f8c5ef086 MDL-76481 tool_brickfield: Fix PHP 8 report download 2023-03-30 09:15:05 +01:00
Paul Holden 5d10e53ba1 Merge branch 'MDL-75017_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-03-30 08:47:54 +01:00
Ilya Tregubov cc0c62d564 Merge branch 'MDL-73771_401' of https://github.com/lostrogit/moodle into MOODLE_401_STABLE 2023-03-30 14:22:53 +08:00
AMOS bot 48fb5b6e88 Automatically generated installer lang files 2023-03-30 00:07:44 +00:00
Amaia Anabitarte bc4b6cf8f7 MDL-77227 roles: Remove extra information for override page 2023-03-29 18:20:23 +02:00
Carlos Castillo f17b006dcb MDL-73771 theme: Fix scrollbar position 2023-03-29 09:15:39 -05:00
Shamim Rezaie d50bb07b2b Merge branch 'MDL-74452_401_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_401_STABLE 2023-03-29 15:27:15 +11:00
Ilya Tregubov b85f6a660b Merge branch 'MDL-77740-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-03-29 10:58:47 +08:00
Jun Pataleta dd584ab981 Merge branch 'MDL-77382-401' of https://github.com/snake/moodle into MOODLE_401_STABLE 2023-03-29 09:48:17 +08:00
Jun Pataleta ab9b09908a Merge branch 'MDL-76941-401-2' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2023-03-29 09:31:51 +08:00
Jun Pataleta c99abd65ca MDL-77783 core: Validate sublugins.json
* Validate the decoded subplugins.json before processing it.
* Log errors if subplugins.json is invalid or if plugintypes is not
defined.
2023-03-29 09:29:57 +08:00
Jun Pataleta 436ed2c4cb MDL-77761 core_form: Add label for editor format selector 2023-03-29 08:09:54 +08:00
Eloy Lafuente (stronk7) d0ddc7692b MDL-77333 mod_resource: fixes generator uploading files + tests
MDL-76499 revealed a few problems with resource generators:

1. We were not covering with unit tests the upload of files from disk
   (and here it's where the problem was).
2. There was a little of confusion between disk paths (only needed
   to upload files) and file_area paths (the generator only creates
   or uploads files to the root directory of the file area.
3. It was possible to request the upload of a file to the generator
   without that file effectively existing.

This commit fixes those points  and covers 99% of the generator code.
2023-03-28 19:06:18 +02:00
Paul Holden 449a8b0b31 weekly release 4.1.2+ 2023-03-28 15:55:18 +01:00
Paul Holden 0f251ce165 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-03-28 15:55:16 +01:00
Andrew Nicols 5df8e8fa5f MDL-77773 editor_tiny: Improve initial editor size 2023-03-28 20:48:05 +08:00
Paul Holden 7f6888bd53 Merge branch 'MDL-77105-401-4' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-03-28 12:38:52 +01:00
Jun Pataleta 95d5b0aab0 MDL-77105 core: Cast custom data to an array when evaluating filtericon
Since other modules may treat custom data as an object, we need to make
cast it to an array before evaluating for the `filtericon` custom data.
2023-03-28 18:49:27 +08:00
Huong Nguyen 9a05e393dd MDL-76941 tool_usertours: Fix accessibility issue when resizing 2023-03-28 12:18:17 +07:00
Meirza 110ec6a703 MDL-77436 auth_oauth2: Update profile fields based on data mapping.
After the user creation, the system must call an update function to update profile_fields_*.
We also provided two functions into user/profile/lib.php to get available from other areas.
We added PHP unit testing for new public functions and
the Behat tests for custom profile fields with locked and unlocked statuses.

Co-authored-by: Matt Porritt <matt.porritt@moodle.com>
2023-03-28 11:47:23 +07:00
Matt Porritt 714764d966 MDL-77436 auth_oauth2: Allow admin to choose profile fields for mapping
Update oauth2 to allow mapping of provider attributes against
user profile fields. Fields can also be locked to prevent
user changes.

Co-Authored-By: Michael Milette <michael.milette@tngconsulting.ca>
2023-03-28 11:46:51 +07:00
Jun Pataleta ae63139985 Merge branch 'MDL-77630-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2023-03-28 12:06:17 +08:00
Jake Dallimore e144ff8a43 Merge branch 'MDL-77105-401-4' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-03-28 11:42:42 +08:00
Meirza cd528df093 MDL-77630 mod_forum: correct typo in variable names 2023-03-28 09:39:01 +07:00
Jun Pataleta 6b96cf8676 Merge branch 'MDL-77670-401' of https://github.com/juancs/moodle into MOODLE_401_STABLE 2023-03-28 07:05:04 +08:00
Paul Holden 2b0a0cecdf MDL-77762 contentbank: always provide exit button when appropriate.
If the current user can access the content bank in the context of the
current item, then provide link back to it.
2023-03-27 18:08:53 +01:00
Paul Holden 7b614d6f51 MDL-77764 contentbank: add field label to context selection element. 2023-03-27 16:54:53 +01:00
Sara Arjona e7cda153a2 Merge branch 'MDL-76376_m41' of https://github.com/jrchamp/moodle into MOODLE_401_STABLE 2023-03-27 16:56:30 +02:00
Sara Arjona 0d6eaef200 Merge branch 'MDL-77659_401' of https://github.com/AnupamaSarjoshi/moodle into MOODLE_401_STABLE 2023-03-27 16:50:31 +02:00
Sara Arjona f32c46bf0c Merge branch 'MDL-73226-401' of https://github.com/jleyva/moodle into MOODLE_401_STABLE 2023-03-27 16:08:26 +02:00
Juan Leyva eeae99afc7 MDL-73226 files: Add quota checks to core_user_add_user_private_files 2023-03-27 13:25:43 +02:00
Sara Arjona 8c9b54cc5d Merge branch 'MDL-76303-401' of https://github.com/ssj365/moodle into MOODLE_401_STABLE 2023-03-27 12:41:18 +02:00
Paul Holden da42c76300 Merge branch 'MDL-77729_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-03-27 11:09:26 +01:00
Sara Arjona c2714ff1af Merge branch 'MDL-77561-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-03-27 11:43:26 +02:00
Paul Holden f2cbacbd24 MDL-77555 reportbuilder: method to ensure unique parameters in SQL. 2023-03-27 10:29:31 +01:00
Jun Pataleta bc1d7e854b MDL-77105 core: Add upgrade.txt notes 2023-03-27 14:00:58 +08:00
Jun Pataleta 99bc8f2b30 MDL-77105 mod_url: Declare filtericon custom data
* Set a custom data `filtericon` when the icon being rendered for the
URL resource is not equal to the default plugin icon.
2023-03-27 14:00:58 +08:00
Jun Pataleta 67f739499b MDL-77105 mod_lti: Add 'nofilter' class for custom tool icons
Add a '.nofilter' class when rendering custom tool icons in order
to render them as is and without CSS filter on the activity chooser.
2023-03-27 14:00:38 +08:00
Jun Pataleta 538e17e199 MDL-77105 core_course: Add 'nofilter' class for non-monologo icons
When rendering content items, check whether the plugin has monologo
icons. If so, add a 'nofilter' class so the plugin icon can be
rendered as is and without the CSS filter.
2023-03-27 14:00:18 +08:00
Jun Pataleta 28d8c9c1e7 MDL-77105 block_timeline: Add 'nofilter' class when necessary
Add the `.nofilter` class for activity icons when the icon URL's
`filtericon` parameter is not set, so they get rendered as they are on
the timeline block.
2023-03-27 13:59:54 +08:00
Jun Pataleta 18703b71ac MDL-77105 block_recentlyaccesseditems: Add 'nofilter' class
Add the `.nofilter` class for activity icons when the icon URL's
`filtericon` parameter is not set, so they get rendered as they are on
the recently accessed items block.
2023-03-27 13:59:33 +08:00
Jun Pataleta f59220a76d MDL-77105 theme_boost: Add 'nofilter' class when necessary
Add the `.nofilter` class for activity icons when the icon URL's
`filtericon` parameter is not set, so they get rendered as they are on
the context header on the activity page.
2023-03-27 13:42:43 +08:00
Jun Pataleta 84198e03c7 MDL-77105 course_format: Add 'nofilter' class when necessary
Add the `.nofilter` class for activity icons when the icon URL's
`filtericon` parameter is not set, so they get rendered as they are on
the course homepage.
2023-03-27 13:42:43 +08:00
Jun Pataleta f5d445a68f MDL-77105 core: Conditionally apply icon filter
* Apply the filter CSS property only to activity icons
that don't have the ".nofilter" class. This will allow
activities with non-SVG icons to be rendered as they are.
2023-03-27 13:42:41 +08:00
Jun Pataleta 30b0b0cf40 MDL-77105 core: Add a filtericon parameter to course mod icon URLs
* If a plugin defines a `filtericon` custom data or uses its monologo
version of the icon, a `filtericon` parameter is being added to the
icon's URL. This information can help plugins determine whether to
render the activity icon as is or with CSS filtering.
2023-03-27 13:36:42 +08:00
Jun Pataleta 69948eda10 MDL-77105 core: Method to determine whether a plugin has monolog icons 2023-03-27 13:36:38 +08:00
Brendan Heywood 25edc77d10 MDL-77749 admin: Fix code error with unset config duration 2023-03-26 16:18:13 +11:00
AMOS bot 1f4daa7402 Automatically generated installer lang files 2023-03-26 00:07:41 +00:00
Tim Hunt c1c1ca6e4d MDL-77729 qformat_missingword: fix form of help link 2023-03-25 15:39:27 +00:00
Andrew Nicols 50d1671a54 MDL-77740 editor_tiny: Set the Editor window from the iFrame element
This is a workaround for an upstream bug which I have not been able to
reproduce outside of Moodle whereby the editor.contentWindow does not
math the editor.iframeElement.contentWindow when it should.

This issue only seems to affect Firefox, and it may even be a bug in
Firefox. It can only be reproduced when using a fresh browser which has
never had a TinyMCE window open.
2023-03-24 21:34:21 +08:00
Tim Hunt fd9b8bf4d0 MDL-75017 questions: give a clear error if the context type is invalid 2023-03-24 13:00:09 +00:00
Tim Hunt e405e6fd6a MDL-75017 questions: fix weird setup in qformat_xml_import_export_test 2023-03-24 13:00:07 +00:00
Sara Arjona 5898c3e5dd weekly release 4.1.2+ 2023-03-24 13:59:31 +01:00
Jun Pataleta d2bc54fba9 Merge branch 'MDL-77669-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-03-24 11:51:36 +08:00
Jun Pataleta 9b07f56add Merge branch 'MDL-77626_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-03-24 10:40:36 +08:00
Simey Lameze 7c1c1071e7 MDL-77561 behat: add step to accept dpa and enable bigbluebutton
The step i_enable_plugin cannot be used as bigbluebuttonbn_default_dpa_accepted
setting needs to be enable in order for the BigBlueButton plugin to be enabled.
2023-03-24 08:21:05 +08:00
Sara Arjona d2d49e150b Merge branch 'MDL-77705-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-23 18:30:27 +01:00
Sara Arjona a7d71e0e2d Merge branch 'MDL-77666-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-23 17:53:45 +01:00
Shamiso.Jaravaza b924f6a355 MDL-76303 mod_bigbluebuttonbn: Fix userlimit 2023-03-23 08:23:23 -06:00
Paul Holden 3fa384384e Merge branch 'MDL-77392-401' of https://github.com/srobotta/moodle into MOODLE_401_STABLE 2023-03-23 12:25:29 +00:00
Stephan Robotta 66e88ace0f MDL-77392 calendar: calendar items are hidden because of settings 2023-03-23 12:53:09 +01:00
Paul Holden fe07140e27 Merge branch 'MDL-77691-401' of https://github.com/roland04/moodle into MOODLE_401_STABLE 2023-03-23 11:43:41 +00:00
Sara Arjona fad4e118a4 Merge branch 'MDL-77380-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-03-22 14:06:07 +01:00
Sara Arjona 0d80eea9af Merge branch 'MDL-77692-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-22 13:50:11 +01:00
Ilya Tregubov 0b973b52e9 weekly release 4.1.2+ 2023-03-22 09:37:08 +08:00
Ilya Tregubov b158354710 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-03-22 09:37:06 +08:00
Paul Holden ee3924702f MDL-77705 reportbuilder: avoid re-using field alias between entities.
Ensure that when the user entity is added multiple times to a report,
when there are custom profile fields, each of those gets a unique table
alias per-entity.
2023-03-21 17:29:09 +00:00
Mark Johnson 0d4d201a8c MDL-74452 quiz: Display an error if all versions are in draft status 2023-03-21 15:25:02 +00:00
Mikel Martín 0b2085648e MDL-77691 behat: Add step to navigate to profile page directly 2023-03-21 08:08:10 +01:00
Simey Lameze 939a416308 MDL-77380 block_myoverview: improve show toggle functionality test 2023-03-21 14:47:25 +08:00
Jun Pataleta 28d1db2f1d Merge branch 'MDL-75746_401_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_401_STABLE 2023-03-21 12:01:01 +08:00
Angelia Dela Cruz 084c120c79 MDL-77577 Behat: Replaced the use of "Install selected language pack(s)
Evaluated usage of "Install selected language pack(s)" in Behat and
replaced the steps to use generator to install language packs as part
of test setup.
2023-03-21 12:00:53 +08:00
Meirza 29a1cf86a3 MDL-77669 dml: Added extrainfo in the DB options config.
extrainfo is an extra information for the DB driver, e.g. SQL Server,
has additional configuration according to its environment,
which the administrator can specify to alter and override any connection options.

Co-authored-by: LukeCarrier <luke@carrier.im>

This is a backport of MDL-64153.
2023-03-21 08:48:39 +08:00
Ilya Tregubov ea915c29e5 Merge branch 'mdl-72533-event-table-performance-MOODLE_401_STABLE' of https://github.com/petersistrom/moodle into MOODLE_401_STABLE 2023-03-21 08:24:59 +08:00
Paul Holden deced83b06 Merge branch 'MDL-72124_401_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_401_STABLE 2023-03-20 17:04:54 +00:00
Paul Holden fac1828222 MDL-77692 reportbuilder: format custom field condition/filter names. 2023-03-20 16:32:08 +00:00
Sara Arjona 502536c16e Merge branch 'MDL-77574-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-03-20 17:06:06 +01:00
Anupama Sarjoshi 3fee9d949f MDL-77659 core_reportbuilder: fix user profile fields phpunit tests 2023-03-20 13:53:46 +00:00
Sara Arjona 1bfc0a1d14 Merge branch 'MDL-77523-401' of https://github.com/juancs/moodle into MOODLE_401_STABLE 2023-03-20 13:42:49 +01:00
Mark Sharp f8301fb4bc MDL-72533 core_calendar: improve calendar event table peformance
- Filter searchable courses if set.
- Sites with large groups should now experience better performance.
- Applies and optimises query against a proper date range.

Co-authored-by: Mark Sharp <mark.sharp@solent.ac.uk>
Co-authored-by: Peter Sistrom <petersistrom@catalyst-au.net>
Co-authored-by: Kevin Pham <keevan.pham@gmail.com>
2023-03-20 12:09:24 +11:00
AMOS bot 9e97a353ad Automatically generated installer lang files 2023-03-20 00:07:41 +00:00
Brendan Heywood 6e27e9e481 MDL-77618 admin: Passwords should not auto complete 2023-03-18 13:02:58 +11:00
AMOS bot e8cbc0b653 Automatically generated installer lang files 2023-03-18 00:07:42 +00:00
Juan Segarra Montesinos b296667ebf MDL-77670 course: Preserve course summary format 2023-03-17 20:54:07 +01:00
Sara Arjona 231c25e498 weekly release 4.1.2+ 2023-03-17 17:58:21 +01:00
Sara Arjona 3ff1293c12 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-03-17 17:58:12 +01:00
Jun Pataleta eda00e2c73 Merge branch 'MDL-76257-401' of https://github.com/juancs/moodle into MOODLE_401_STABLE 2023-03-17 11:01:22 +08:00
Jun Pataleta 85b4e2312e Merge branch 'MDL-77608-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-17 10:29:48 +08:00
AMOS bot 5707e7d40f Automatically generated installer lang files 2023-03-17 00:07:43 +00:00
Paul Holden 71e751565c MDL-77666 contentbank: format category names for display. 2023-03-16 23:27:13 +00:00
info@eWallah.net b3adaaf47f MDL-77584 currencies: Fix outdated ISO 4217 code for Zambian Kwacha
On 2013-01-01 the ZMK code got replaced by the new ZMW code.

AMOS BEGIN
 MOV [ZMK,core_currencies],[ZMW,core_currencies]
AMOS END
2023-03-16 19:53:38 +01:00
Jake Dallimore 282df774a4 Merge branch 'MDL-76309-MOODLE_401_STABLE' of https://github.com/sh-csg/moodle into MOODLE_401_STABLE 2023-03-16 15:47:16 +08:00
Stefan Hanauska 9f5492df71 MDL-76309 mod_assign: Compatibility with zip download 2023-03-16 07:18:35 +01:00
Paul Holden 0920bd0810 MDL-76339 mod_bigbluebuttonbn: correct upgrade note fix versions.
Use agreed task name language string.
2023-03-15 19:15:29 +00:00
Paul Holden a89cba84a1 Merge branch 'MDL-76339-401' of https://github.com/call-learning/moodle into MOODLE_401_STABLE 2023-03-15 19:05:57 +00:00
Andrew Nicols f0b3ff2134 Merge branch 'MDL-77550-401' of https://github.com/dpalou/moodle into MOODLE_401_STABLE 2023-03-15 14:26:26 +08:00
Juan Segarra Montesinos dbd7cedd24 MDL-77523 mod_data: textarea field should honor editor preferred format 2023-03-15 06:49:02 +01:00
Jun Pataleta d5331827c4 Merge branch 'MDL-77611_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-03-15 10:01:04 +08:00
AMOS bot 91f503c3f6 Automatically generated installer lang files 2023-03-15 00:07:40 +00:00
Paul Holden 4ee053a278 MDL-59175 theme_boost: style inherited permission on overide page. 2023-03-14 20:58:07 +00:00
Tim Hunt 4bc3782c4c MDL-77626 quiz statistics: Divide by zero if a random Q has max mark 0 2023-03-14 16:34:30 +00:00
Mark Johnson 5a7ad7b284 MDL-75746 mod_quiz: Fix backup and restore of quiz slots 2023-03-14 16:07:46 +00:00
Mark Johnson 34c452afb4 MDL-72124 question: Fix system-level URLs in question events 2023-03-14 15:40:26 +00:00
Eloy Lafuente (stronk7) 6c260e6ae7 weekly release 4.1.2+ 2023-03-14 16:07:32 +01:00
Eloy Lafuente (stronk7) 09e74578a1 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-03-14 16:07:27 +01:00
Jun Pataleta f1a9181a77 Merge branch 'MDL-76680/401' of https://github.com/skodak/moodle into MOODLE_401_STABLE 2023-03-14 21:43:31 +08:00
Laurent David 8ee689f612 MDL-70976 core_files: Allow for draft files url inserted in content
* The file file_remove_editor_orphaned_files should take into account URL that
have been embedded in a tag content instead of an attribute (like src attribute)
* This will fix issue with inserting H5P content in calendar events.
2023-03-14 08:48:32 +01:00
Juan Segarra Montesinos a003b3b882 MDL-76257 core: Activity intro should honor user preference on creation 2023-03-14 06:07:28 +01:00
AMOS bot 9617555887 Automatically generated installer lang files 2023-03-14 00:07:42 +00:00
Tim Hunt a5238d8c94 MDL-77611 tool_uploaduser: fix phpunit assumptions about profile fields 2023-03-13 13:35:38 +00:00
Paul Holden 34e2d74921 MDL-77608 mod_h5pactivity: namespace component lib testcase. 2023-03-13 09:43:57 +00:00
Simey Lameze 76cb263244 MDL-77574 myoverview: wait until next button exists before clicking 2023-03-13 14:12:26 +08:00
Jake Dallimore 4ce5755a63 MDL-77382 core: fix error handling in oauth2 callback for auth'd users
Pass the errors back to the calling code when the user is authenticated,
otherwise, fall back on the existing redirection to the login page.
2023-03-13 10:48:21 +08:00
AMOS bot a509b37926 Automatically generated installer lang files 2023-03-12 00:07:50 +00:00
Petr Skoda 7e96a1c887 MDL-76680 core: disable $USER->ignoresesskey on next page 2023-03-11 10:37:24 +01:00
Jun Pataleta 033858e249 Moodle release 4.1.2 2023-03-11 13:10:39 +08:00
Jun Pataleta 83c3ac53bf weekly release 4.1.1+ 2023-03-10 22:09:52 +08:00
Jun Pataleta 1e5f8ee1a2 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-03-10 22:09:50 +08:00
Ilya Tregubov d5d64e1c8b Merge branch 'MDL-77429-401-fix' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-03-10 14:52:02 +08:00
Andrew Nicols f8b1b4092f MDL-77429 course: Change course date to previous day
When a test runs just after midnight, and the user time zone is not the
same as the server timezone, and the course is created using a generator
(which runs in server time zone) but the UI presented in the user
timezone, the course start time is still in the future.

We need to create the course a day earlier to ensure that the "This
week" indicator is in the correct day.
2023-03-10 14:11:23 +08:00
Andrew Nicols ca01668e32 MDL-77037 core_course: Add new courseindex test to classic excludelist 2023-03-10 13:32:04 +08:00
Jun Pataleta 70108cf09b Merge branch 'MDL-77458-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-03-10 12:06:10 +08:00
Jake Dallimore b9dedcd53e Merge branch 'MDL-77517-401' of https://github.com/juancs/moodle into MOODLE_401_STABLE 2023-03-10 11:39:52 +08:00
Andrew Nicols aca52fa5f0 Merge branch 'MDL-77530-tool-task-checks-MOODLE_401_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_401_STABLE 2023-03-10 11:30:45 +08:00
Jake Dallimore 65cb8e0792 Merge branch 'MDL-77219-401' of https://github.com/sarjona/moodle into MOODLE_401_STABLE 2023-03-10 10:36:25 +08:00
Jun Pataleta 9bdbff4f3a Merge branch 'MDL-76603-401' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-03-10 10:14:57 +08:00
Shamim Rezaie 47a1789f12 MDL-76603 gradingforms: Some A11y fixes on editing form
- Use span instead of dummy input elements because form elements need a
  label
- Sufficient size for target is at least 24px by 24px (Success Criteria
  2.5.8)
2023-03-10 10:11:34 +08:00
Shamim Rezaie 394a0520d0 MDL-76603 mod_assign: Move advanced grading grades out of the tables 2023-03-10 10:11:34 +08:00
Shamim Rezaie 79491b8a90 MDL-76603 gradingform_rubric: preserve bg colour on hover 2023-03-10 10:11:34 +08:00
Shamim Rezaie 68460cad9b MDL-76603 gradingform_rubric: fix roles
- set the role of table to none
- moved aria-label from <table> element (that doesn't has role="none")
  to the element that has the radiogroup role
- if it's not radiogroup/radio, it is list/listitem
- removed aria-label from the rubric table and used caption instead
2023-03-10 10:11:34 +08:00
Andrew Nicols 23e2b0358c Merge branch 'MDL-76849-401-5' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-03-10 09:29:40 +08:00
Jun Pataleta 98f95845b1 Merge branch 'MDL-70613-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-10 09:19:39 +08:00
Sara Arjona 69a91b30cc Merge branch 'MDL-77323-401' of https://github.com/NashTechOpenUniversity/moodle into MOODLE_401_STABLE 2023-03-09 16:48:39 +01:00
Paul Holden 2ff317ac8a MDL-70613 mod_feedback: cast feedback text values for table sorting.
Specifically avoids Oracle ORA-00932 (inconsistent CLOB datatype).
2023-03-09 14:59:11 +00:00
Andrew Nicols 8112ce8376 Merge branch 'MDL-77329-401-clr' of https://github.com/ferranrecio/moodle into MOODLE_401_STABLE 2023-03-09 22:19:08 +08:00
Andrew Nicols 5feea19e46 Merge branch 'MDL-77463-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-03-09 22:10:25 +08:00
Andrew Nicols d5b43c03a5 Merge branch 'MDL-77429-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-03-09 22:03:46 +08:00
Andrew Nicols f262b2223f MDL-77037 core_course: Coding style fix in Behat feature 2023-03-09 21:59:41 +08:00
Andrew Nicols 3c1c543c53 Merge branch 'MDL-77037-401' of https://github.com/laurentdavid/moodle into MOODLE_401_STABLE 2023-03-09 21:59:37 +08:00
James C 370c67e7dc MDL-77329 course: Prevent collapse state loss 2023-03-09 11:56:00 +01:00
Sara Arjona ab34f215a9 Merge branch 'MDL-76940-401' of https://github.com/laurentdavid/moodle into MOODLE_401_STABLE 2023-03-09 10:54:50 +01:00
Jun Pataleta 002f9eb7da Merge branch 'MDL-77533-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-09 16:35:24 +08:00
Jun Pataleta bb61d8392b Merge branch 'MDL-77559-401-2' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-03-09 15:57:44 +08:00
Laurent David bdd1708455 MDL-77037 core_courseformat: Refresh course index
* Refresh course index when language change
2023-03-09 08:44:22 +01:00
Brendan Heywood 3c86170a8d MDL-77530 tool_task: Fix coding errors in checks 2023-03-09 15:44:01 +11:00
Andrew Nicols 155f08fc68 Merge branch 'MDL-77420-401' of https://github.com/ferranrecio/moodle into MOODLE_401_STABLE 2023-03-09 11:58:41 +08:00
Andrew Nicols 3a8b5523d5 Merge branch 'MDL-77014-401' of https://github.com/lucaboesch/moodle into MOODLE_401_STABLE 2023-03-09 11:42:03 +08:00
Andrew Nicols fbc3f7f245 Merge branch '76945-bootstrap-dropdowns-401' of https://github.com/DSI-Universite-Rennes2/moodle into MOODLE_401_STABLE 2023-03-09 10:54:35 +08:00
Tim Hunt 42f41fc174 MDL-77467 retore: add progress tracking to potentially slow steps 2023-03-09 10:46:51 +08:00
Jun Pataleta ed6b43b4f2 Merge branch 'MDL-77225_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-03-09 10:43:06 +08:00
Andrew Nicols 6a25c5c8d0 Merge branch 'MDL-77418-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-09 10:36:06 +08:00
Andrew Nicols 3a363d0eec Merge branch 'MOODLE_401_STABLE' of https://github.com/fcbsd/moodle into MOODLE_401_STABLE 2023-03-09 10:29:43 +08:00
Andrew Nicols 783c542d31 Merge branch 'MDL-77539-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-09 10:09:41 +08:00
Andrew Nicols cd48ae56c7 MDL-77559 js: Rebuild all JS with Node 16 2023-03-09 09:53:19 +08:00
Jun Pataleta d5cf25faf5 MDL-76849 qtype_essay: Allow question number inclusion in answer fields
* Have the following classes extend qtype_essay_format_renderer_base
  as they have been meant to:
  - qtype_essay_format_editor_renderer
  - qtype_essay_format_noinline_renderer
  - qtype_essay_format_plain_renderer
* Add a question_display_options instance variable for
qtype_essay_format_renderer_base so its subclasses can use it to
generate the label for their respective answer fields.
2023-03-09 08:57:47 +08:00
Jun Pataleta 787278601c MDL-76849 qtype_shortanswer: Include question number in answer fields 2023-03-09 08:57:47 +08:00
Jun Pataleta 880532c71a MDL-76849 qtype_numerical: Include question number in answer fields
* Also covers its qtype_calculated and qtype_calculatedsimple
which extend its renderer class
2023-03-09 08:57:47 +08:00
Jun Pataleta 03b549f225 MDL-76849 qtype_multianswer: Include question number in answer fields
* Add the question number to the answer fields if it's available.
* Improve multiple choice question accessibility:
  - Label the multiple choice question groups appropriately by
    enclosing them in fieldset tags and applying sr-only legend tags to
    label them.
  - Apply Bootstrap form-check classes to the radio buttons, so they
    are rendered better and become responsive as well. This also helps
    avoid the use of the table element for layout purposes when
    rendering horizontal multiple choice sub-questions.
2023-03-09 08:57:47 +08:00
Jun Pataleta 7b6ff446f4 MDL-76849 qtype_match: Include question number in answer fields 2023-03-09 08:57:47 +08:00
Jun Pataleta 9ddbc2d7f0 MDL-76849 qtype_truefalse: Include question number in answer fields
* Improve accessibility as well by grouping the radio buttons
in a fieldset.
2023-03-09 08:57:47 +08:00
Jun Pataleta fbffd9b148 MDL-76849 qtype_multichoice: Include question number in answer fields
* Improve accessibility as well by grouping the radio buttons/checkboxes
in a fieldset.
2023-03-09 08:57:47 +08:00
Jun Pataleta 2ad0871a82 MDL-76849 qtype_ddwtos: Include question number in answer fields
* Plus include the item number so users will have an idea which blank
numbers they are currently on.
2023-03-09 08:57:47 +08:00
Jun Pataleta 5847b0026e MDL-76849 qtype_gapselect: Include question number in answer fields 2023-03-09 08:57:47 +08:00
Jun Pataleta 6c3f1d55a8 MDL-76849 qtype: Add a questionidentifier instance variable
* Add an instance variable to question_display_options to store the
identifier associated with the question being rendered.
* This information can be used by question type plugins to improve the
accessibility of the answer fields being rendered by adding the
question identifier to the answer fields' labels.
* Adding the question identifier to the label can be achieved by using
question_display_options::add_question_identifier_to_label().

Co-authored-by: Tim Hunt <t.j.hunt@open.ac.uk>
2023-03-09 08:57:47 +08:00
Andrew Nicols 04787fbbc9 MDL-77559 js: Revert "MDL-75012 core: Bump NodeJS version requirements"
This reverts commit 3416ee9890.
2023-03-09 08:21:36 +08:00
Andrew Nicols 8c13a1b817 MDL-77559 js: Revert "MDL-75012 js: Bump standard dependencies"
This reverts commit 456446215e.
2023-03-09 08:21:22 +08:00
Andrew Nicols fefd6f2bd8 MDL-77559 js: Revert "MDL-75012 js: Remove grunt-contrib-uglify"
This reverts commit ca4614c299.
2023-03-09 08:21:19 +08:00
Andrew Nicols d209e2cc57 MDL-77559 js: Revert "MDL-75012 js: Bump stylelint and components"
This reverts commit 644e9da8bb.
2023-03-09 08:21:15 +08:00
Andrew Nicols a96fcc22ca MDL-77559 js: Revert "MDL-75012 js: Update browserslist"
This reverts commit bf81d5f0ba.
2023-03-09 08:21:12 +08:00
Andrew Nicols 230f8247e8 MDL-77559 js: Revert "MDL-75012 js: Bump node-sass"
This reverts commit 0a0266ae5e.
2023-03-09 08:21:07 +08:00
Andrew Nicols 91eb06347e MDL-77559 js: Revert "MDL-75012 js: Audit fix"
This reverts commit 8960a6ee91.
2023-03-09 08:21:03 +08:00
Andrew Nicols 63ecbc57d6 MDL-77559 js: Revert "MDL-75012 js: Use our own jsdoc wrapper"
This reverts commit 89f7402fc2.
2023-03-09 08:20:57 +08:00
Andrew Nicols f483380e01 MDL-77559 js: Revert "MDL-75012 js: Bump shifter to new version"
This reverts commit c2c1727dd5.
2023-03-09 08:20:53 +08:00
Andrew Nicols 0da20453f7 MDL-77559 js: Revert "MDL-75012 js: Put shifter on a diet"
This reverts commit 73181c1310.
2023-03-09 08:20:49 +08:00
Andrew Nicols c90a6263bc MDL-77559 js: Revert "MDL-75012 js: Remove unused babel-preset-minify dependency"
This reverts commit 364458e36a.
2023-03-09 08:20:45 +08:00
Andrew Nicols df1dc82fee MDL-77559 js: Revert "MDL-75012 js: Bump Babel dependencies"
This reverts commit b963401b8f.
2023-03-09 08:20:42 +08:00
Andrew Nicols 34cae8d339 MDL-77559 js: Revert "MDL-75012 js: Remove orphaned source maps"
This reverts commit 05cdfa4da4.
2023-03-09 08:20:05 +08:00
AMOS bot 733702e72f Automatically generated installer lang files 2023-03-09 00:07:41 +00:00
Tim Hunt 7db1da61ee MDL-77225 questions: fix regrade of descriptions in finished attempts
The added logic is similar to the logic in other behaviours, and the new test fails without it.
2023-03-08 19:00:43 +00:00
Sara Arjona 6aafa1eea6 Merge branch 'MDL-77464_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-03-08 16:14:47 +01:00
Laurent David ed08a4ee52 MDL-76940 core_courseformat: Index refreshing when role switch
* Hidden sections and content should not visible to students when switching role
2023-03-08 11:51:51 +01:00
Ilya Tregubov 4eb1b67d68 Merge branch 'MDL-77414-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-03-08 17:05:13 +08:00
Angelia Dela Cruz 598b18417d MDL-77463 Behat: Coverage for assign submission notification to teacher 2023-03-08 17:01:35 +08:00
Angelia Dela Cruz cd609bd915 MDL-77429 Behat: Add coverage for changing course format as teacher 2023-03-08 15:48:28 +08:00
Luca Bösch 5e4d3c4d5b MDL-77014 course: Single activity format course title multilang. 2023-03-08 08:05:14 +01:00
Angelia Dela Cruz 311eb0ddd2 MDL-77414 Behat: Coverage for "Require all group members submit" setting 2023-03-08 14:47:53 +08:00
Dani Palou c90c9b04f6 MDL-77550 lesson: Format decimals in feedback page 2023-03-08 07:46:16 +01:00
Sara Arjona 6d70b125a8 Merge branch 'MDL-77440_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-03-08 07:23:43 +01:00
Jun Pataleta 38cc21db3c Merge branch 'MDL-77472-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-08 11:53:41 +08:00
Petr Skoda 3caeef44d2 MDL-77524 filter_algebra: fix error message 2023-03-08 11:26:58 +08:00
Paul Holden 9a6fdc2aeb MDL-75517 report_participation: filter report by viewable roles only. 2023-03-08 10:37:42 +08:00
Michael Hawkins 5e57bfffac MDL-77204 mod_wiki: Clean filename in Moodle1 backup 2023-03-08 10:33:34 +08:00
Paul Holden fac46a19f7 MDL-77046 availability: validate profile field in condition. 2023-03-08 10:24:17 +08:00
Paul Holden 01fc104779 MDL-76809 gradereport_history: pre-filter report userids filter.
Ensure current user is able to access each of the provided userids.
2023-03-08 10:00:50 +08:00
Ilya Tregubov e7e5b659e8 Merge branch 'MDL-77446-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-03-08 09:18:54 +08:00
Andrew Nicols b9f8373e3f MDL-77470 editor_tiny: Apply upstream security fixes
- CVE-2022-23494
2023-03-08 01:00:30 +00:00
Petr Skoda 0292427f51 MDL-76645 filter_data: fix link title attribute 2023-03-08 01:00:30 +00:00
Paul Holden 0518f875cf MDL-77129 tool_lp: remove redundant call to set page header. 2023-03-08 01:00:30 +00:00
Paul Holden c2d0c7359d MDL-77008 mod_data: require sesskey to reset module templates. 2023-03-08 01:00:30 +00:00
Lars Bonczek d5ec540381 MDL-75659 core: Don't render component argument twice in mustache pix helper 2023-03-08 01:00:30 +00:00
Jun Pataleta 3c00ca0bb2 Merge branch 'MDL-77416-401-enfix' of https://github.com/vmdef/moodle into MOODLE_401_STABLE 2023-03-08 08:50:24 +08:00
AMOS bot 3800bd6cfd Automatically generated installer lang files 2023-03-08 00:07:44 +00:00
Roberto Bravo 9fbd5fb219 MDL-77256 tool_uploaduser: fix get allowed roles for courses
During user upload the permission to assign roles is checked in the wrong context
2023-03-07 18:41:00 +01:00
Tim Hunt bdcf29ab29 MDL-77464 questions: regrading was losing question_attempt metadata
This is very similar to MDL-77090, but at the time, I missed that this
also needed to be handled. (Question metadata is, I think, only used
by the quiz 'Try another question like this one' feature.)
2023-03-07 13:45:04 +00:00
Tim Hunt 795e8ac70a MDL-77464 questions: update comments in question_attempt_step
The class comment had some inaccuracies which I fixed.
I also replaced all uses of @link with @see.
2023-03-07 13:44:59 +00:00
Jun Pataleta 550d9c51ca MDL-76849 question: New lang strings for answer fields 2023-03-07 21:00:32 +08:00
Sara Arjona e3066f3efd MDL-77219 behat: Fix issue with headless
Although the error in the "I check that I can import recordings into
the Recording activity and then if I delete them" scenario is unrelated
to this patch, this commit needs to be applied too, in order to avoid
behat failures (because the "Import recording links" button is in the
edge of the window).

This is a backport of MDL-74272.
2023-03-07 11:03:23 +01:00
Sara Arjona acc250a824 MDL-77219 theme_boost: Remove plugin name on course page
In 4.0, the plugin name was added above their name. Based on the community
feedback and the research done by the UX team, this needs to be removed.
This commit removes the activity name when edit mode is disabled.

This is a backport of MDL-74272.
2023-03-07 11:03:23 +01:00
Angelia Dela Cruz 602061bf21 MDL-77446 Behat: Add coverage for changing uploaded file details 2023-03-07 16:12:07 +08:00
Andrew Nicols 7a5f859f08 Merge branch 'MDL-77094_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-03-07 12:10:18 +08:00
Andrew Nicols 7f4d60b38a Merge branch 'MDL-77336-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2023-03-07 12:02:08 +08:00
AMOS bot ca6167bd2d Automatically generated installer lang files 2023-03-07 00:07:41 +00:00
Tim Hunt 99a6ea40ac MDL-77440 quiz: fix nav error reviewing after redoing a question 2023-03-06 16:12:26 +00:00
Sara Arjona f7ac8b3ff9 Merge branch 'MDL-77460-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-03-06 16:34:03 +01:00
Paul Holden 1818a6841b MDL-77539 blog: null coalesce external blog form name/description.
We can't pass null to most string related functions (e.g. `trim`) in
PHP8.1 onwards.
2023-03-06 14:49:56 +00:00
Paul Holden f46fe1e78e MDL-77472 grade: correct URL param type for adding tracking params. 2023-03-06 09:49:54 +00:00
Meirza 35ea7d00c0 MDL-77336 admin: fix typo in adminpreset data settings. 2023-03-06 16:32:25 +07:00
Paul Holden 859f2c9d5d MDL-77533 customfield: fix exception thrown during handler retrieval. 2023-03-06 09:27:14 +00:00
Andrew Nicols 91ae0abd0a Merge branch 'MDL-77462_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-03-05 22:12:35 +08:00
Juan Segarra Montesinos f9ec44d858 MDL-77517 js: Disable "Edit mode" button when clicked
When clicked, disable the "Edit mode" button just before doing a
redirection. It's been reported that after clicling several times the
button, an inconsistent state between the button and the editing mode is
achieved. The patch mitigates the issue.
2023-03-05 07:09:24 +01:00
Víctor Déniz 98f10149d6 MDL-77416 lang: Use fixed strings in tests 2023-03-03 13:27:01 +00:00
Helen Foster 192bad5ba2 MDL-77416 lang: Import fixed English strings (en_fix) 2023-03-03 13:25:53 +00:00
Tim Hunt 633ad42d6e MDL-77462 core_question: avoid passing null to preg_match 2023-03-03 08:48:09 +00:00
Jun Pataleta 21ef5c5f84 Merge branch 'MDL-77428-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-03-03 16:35:12 +08:00
Laurent David a00d72c622 MDL-76339 mod_bigbluebuttonbn: Update dismissed recordings
* When the server is not reachable (or recordings are not reacheable)
the recording is set to RECORDING_STATUS_DISMISSED and is then
not visible in the list.
* Add a CLI script to solve potential issue with DISMISSED recordings
2023-03-03 06:39:02 +01:00
Jake Dallimore f49f934786 weekly release 4.1.1+ 2023-03-03 11:08:32 +08:00
Jake Dallimore 74fe22032b Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-03-03 11:08:29 +08:00
Andrew Nicols 2169252d26 MDL-77458 core: Add supported php version info to phpcs config 2023-03-02 20:37:52 +08:00
Simey Lameze 889290257d MDL-77460 behat: improve roles.feature test 2023-03-02 18:25:11 +08:00
Angelia Dela Cruz 8422698a06 MDL-77428 Behat: Add coverage for forum post word count 2023-03-02 13:46:02 +08:00
Jun Pataleta 05cdfa4da4 MDL-75012 js: Remove orphaned source maps 2023-03-02 13:11:43 +08:00
Jun Pataleta a377bf30c4 Merge branch 'MDL-75012-401-5' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-03-02 12:31:09 +08:00
Andrew Nicols 288620b0b4 MDL-75012 js: Full build of all grunt things 2023-03-02 12:15:25 +08:00
Andrew Nicols b963401b8f MDL-75012 js: Bump Babel dependencies
Please note that whilst some dependencies have higher versions
available, these are not compatible at this time.
2023-03-02 12:15:25 +08:00
Andrew Nicols 364458e36a MDL-75012 js: Remove unused babel-preset-minify dependency 2023-03-02 12:15:25 +08:00
Andrew Nicols ccec093aaa Merge branch 'MDL-76825-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2023-03-02 12:05:25 +08:00
Jun Pataleta 3b9a4c5e69 Merge branch 'MDL-75719-401-4' of https://github.com/ilyatregubov/moodle into MOODLE_401_STABLE 2023-03-02 12:02:29 +08:00
Andrew Nicols 74fe0b04be MDL-77141 gradereport_user: Adjust course name to fix test 2023-03-02 11:50:08 +08:00
Andrew Nicols 4e8cd1c7da Merge branch 'MDL-77141-401' of https://github.com/lucaboesch/moodle into MOODLE_401_STABLE 2023-03-02 11:49:55 +08:00
Jake Dallimore 841f61af08 Merge branch 'MDL-77461-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-03-02 11:42:40 +08:00
Jake Dallimore 0792cbf3c8 Merge branch 'MDL-77400-401' of https://github.com/dpalou/moodle into MOODLE_401_STABLE 2023-03-02 11:27:16 +08:00
Paul Holden 1eed4bca84 MDL-77368 forms: remove console logging of upload DOM element. 2023-03-02 11:19:48 +08:00
Andrew Nicols d784e19d9b MDL-77461 behat: Use get_course_id instead of DB fetch 2023-03-02 11:06:45 +08:00
Ilya Tregubov 1e26496cdd MDL-75719 completion: Add Behat scenario for completion states. 2023-03-02 11:04:08 +08:00
Ilya Tregubov 23915a35ae MDL-75719 completion: Fix unit tests and Behat tests.
Fix tests since we changed behavior of completions (completion
state an UI).
2023-03-02 11:04:08 +08:00
Ilya Tregubov 3ebd25ff48 MDL-75719 completion: Fix viewed criteria.
When we unlock completion criteria and save changes 'viewed' criteria
still should be completed if user has viewed activity before. Seems
that that was broken by recent changes. Fixing here.
2023-03-02 11:04:08 +08:00
Ilya Tregubov 7e3d9db579 MDL-75719 completion: Fix completion state for hidden grade items.
For hidden grade items we used to mark students as completed if
they have any grade. But this was not working correctly when we
also set pass grade for activity and completion criteria based
on pass grade. So we will have these completion states

Competion criteria 'Receive grade':
No grade - COMPLETION_INCOMPLETE
Grade visible, achieved passing grade - COMPLETION_COMPLETE_PASS
Grade visible, failed passing grade - COMPLETION_COMPLETE_FAIL
Grade hidden - COMPLETION_COMPLETE

Completion criteris 'Receive passing grade'
No grade - COMPLETION_INCOMPLETE
Grade visible, achieved passing grade - COMPLETION_COMPLETE_PASS
Grade visible, failed passing grade - COMPLETION_COMPLETE_FAIL
Grade hidden, achieved passing grade - COMPLETION_COMPLETE_PASS
Grade hidden, failed passing grade - COMPLETION_COMPLETE_FAIL_HIDDEN
2023-03-02 11:04:08 +08:00
Jake Dallimore b9ee80aae7 Merge branch 'MDL-77318-401' of https://github.com/Utdanningsdirektoratet/moodle into MOODLE_401_STABLE 2023-03-02 10:55:56 +08:00
Andrew Nicols 746580aa68 Merge branch 'MDL-77150-401' of https://github.com/roland04/moodle into MOODLE_401_STABLE 2023-03-02 10:48:47 +08:00
David Mudrák a31b0acaa5 MDL-75534 Fix usermodified in very old forum discussions
Very early Moodle versions used to leave the field empty. Recent Moodle
versions expect that the value always links to an existing user account.
2023-03-02 10:41:41 +08:00
Jake Dallimore b4944cadca Merge branch 'MDL-76298_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-03-02 10:13:04 +08:00
Jun Pataleta 4dda4e69fe Merge branch 'MDL-77413-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-03-02 09:45:56 +08:00
Andrew Nicols 044e573ea1 Merge branch 'MDL-77391-m401' of https://github.com/jrchamp/moodle into MOODLE_401_STABLE 2023-03-02 09:26:56 +08:00
Andrew Nicols 12843909d1 Merge branch 'MDL-77321-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-02 09:25:03 +08:00
Jun Pataleta ba428c3255 Merge branch 'MDL-74586-401-sqlrss' of https://github.com/mudrd8mz/moodle into MOODLE_401_STABLE 2023-03-02 08:58:22 +08:00
Jun Pataleta a3b8e7867a Merge branch 'MDL-76938_restore_comments_401' of https://github.com/davosmith/moodle into MOODLE_401_STABLE 2023-03-02 08:42:05 +08:00
AMOS bot 58d27b5e04 Automatically generated installer lang files 2023-03-02 00:07:48 +00:00
fcbsd d35affa0fd MDL-77365 count_words: Make span> an inline tag
This commit merges the fix and test for the incorrect counting of
words in essay type questions. The issue is due <span> tags not being
counted as inline tags.
2023-03-01 16:13:44 +00:00
Jun Pataleta 2c290f4bb8 Merge branch 'MDL-77430_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2023-03-01 23:59:28 +08:00
Jun Pataleta 73f5e82992 Merge branch 'MDL-77417_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2023-03-01 23:54:21 +08:00
Mikel Martín 855839d195 MDL-77150 core_table: Fix classes added as columnsattributes are ignored
Fix columnattributes with key 'class' being ingored by adding them to every 'column_class'.
2023-03-01 11:17:05 +01:00
hieuvu d07d010288 MDL-77323 question: Prevent drag item sent into two drop zone 2023-03-01 14:47:41 +07:00
Andrew Nicols 576afc3ba6 Merge branch 'MDL-58945_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-03-01 10:55:38 +08:00
Andrew Nicols 3df3b9dfb2 Merge branch 'MDL-74585-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-01 10:51:45 +08:00
Andrew Nicols 61f38c0663 Merge branch 'MDL-77322_basicauth_checkbox-401' of https://github.com/leonstr/moodle into MOODLE_401_STABLE 2023-03-01 10:49:38 +08:00
Andrew Nicols 4ade597a20 Merge branch 'MDL-72727-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-03-01 10:46:49 +08:00
AMOS bot 9e79eff429 Automatically generated installer lang files 2023-03-01 00:07:39 +00:00
Jonathan Champ 35a59dd032 MDL-77391 question admin: further improve query peformance in qtypes.php 2023-02-28 10:18:28 -05:00
Andrew Nicols bac48ffee3 Merge branch 'MDL-73018-M401_bump-travis-and-gha-to-use-php81-instead-of-php80' of https://github.com/ziegenberg/moodle into MOODLE_401_STABLE 2023-02-28 23:03:08 +08:00
Andrew Nicols 2a0980837d Merge branch 'MDL-77097_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2023-02-28 22:13:39 +08:00
David Mudrák cfc2fca94a MDL-74586 rss: Make rss_get_userid_from_token() use table index
Due to missing `AND k.script = 'rss'` condition, the query did not make
use of the existing script-value compound index defined for the table.
So it had to perform the full sequential scan for all rows when
searching for the token. This had serious performance issues on sites
with many users, especially in case on non-existing token / key.
2023-02-28 13:25:45 +01:00
Eloy Lafuente (stronk7) be32856374 MDL-77430 plugininfo: php81 deprecation warnings on missing plugins
Whenever some plugin is missing from disk but installed, the plugins
page (and the upgrade) shows them as "missing from disk". Still, the
code tries to do things with their directory that, now, is null.

That was silently defaulting to '' in previous php versions, but
php81 emits a deprecated warning. So we have to check for them.
2023-02-28 11:41:04 +01:00
Daniel Ziegenberg 5ab061ca7d MDL-73018 ci: Move highest PHP to 8.1 (from current 8.0)
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2023-02-28 11:24:28 +01:00
Dani Palou 8045e5e3dd MDL-77400 reportbuilder: Fix enrolment status return type 2023-02-28 10:41:38 +01:00
Angelia Dela Cruz 03035dcf71 MDL-77413 Behat: Minor changes to optimise the existing tests 2023-02-28 17:22:25 +08:00
Angelia Dela Cruz 93525ebdd9 MDL-77413 Behat: Add coverage to verify groups can have a picture 2023-02-28 17:22:04 +08:00
Jun Pataleta 21afd4548b Merge branch 'MDL-77248-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-02-28 15:46:49 +08:00
Andrew Nicols 1ca40fa664 MDL-77248 mod_bigbluebuttonbn: Remove unused dpa pages 2023-02-28 12:04:51 +08:00
Andrew Nicols 3c262bb46f MDL-77248 mod_bigbluebuttonbn: Set dpa accepted when creating activities
This only applies when creating activities using the test data
generator.
2023-02-28 12:04:51 +08:00
Andrew Nicols 9d5e363b41 MDL-77248 core: Move pre_enable_plugin_actions callback to enable_plugin 2023-02-28 12:04:51 +08:00
Andrew Nicols 73181c1310 MDL-75012 js: Put shifter on a diet
This commit switches to a new custom version of Shifter which sees it
put on a massive diet.

Many of the standard Shifter features are totally unused by Moodle, but
they add dependency spaghetti. Some of those dependencies will start to
cause us issues as they have not been updated for a very long time, are
no longer maintained, and are no longer compatible with anything
resembling a recent version of NodeJS.
2023-02-28 10:22:45 +08:00
Andrew Nicols c2c1727dd5 MDL-75012 js: Bump shifter to new version
This resolves an issue identified in 77083 which identified that GitHub
hashes shouldn't be treated as repeatable.

Whilst GitHub have reverted this change, it's still worth making this
change.
2023-02-28 10:19:51 +08:00
Andrew Nicols 89f7402fc2 MDL-75012 js: Use our own jsdoc wrapper
grunt-jsdoc is abandoned and only works with an older version of jsdoc.

This is a very simple wrapper around jsdoc itself.
2023-02-28 10:19:51 +08:00
Andrew Nicols 8960a6ee91 MDL-75012 js: Audit fix 2023-02-28 10:19:51 +08:00
Andrew Nicols 0a0266ae5e MDL-75012 js: Bump node-sass 2023-02-28 10:19:51 +08:00
Andrew Nicols bf81d5f0ba MDL-75012 js: Update browserslist
To avoid build changes we exclude older versions of Android browser
2023-02-28 10:19:51 +08:00
Andrew Nicols 644e9da8bb MDL-75012 js: Bump stylelint and components 2023-02-28 10:19:50 +08:00
Andrew Nicols ca4614c299 MDL-75012 js: Remove grunt-contrib-uglify
We stopped using this when we updated our processes to support ESMs in
MDL-62497. Removal of the dependency was missed at the time.
2023-02-28 10:19:50 +08:00
Andrew Nicols 456446215e MDL-75012 js: Bump standard dependencies
This change bumps dependencies which have no impact upon the build
process
2023-02-28 10:19:50 +08:00
Andrew Nicols 3416ee9890 MDL-75012 core: Bump NodeJS version requirements 2023-02-28 10:19:50 +08:00
Jun Pataleta b8a85811ec Merge branch 'MDL-76956-m401' of https://github.com/sammarshallou/moodle into MOODLE_401_STABLE 2023-02-28 10:07:16 +08:00
Jun Pataleta bef0d516b4 Merge branch 'MDL-77276-401' of https://github.com/sarjona/moodle into MOODLE_401_STABLE 2023-02-28 10:04:59 +08:00
Paul Holden cf25f53743 MDL-72727 mod_forum: prevent default favourite toggle click event.
Allow the repository call to the web service method to complete before
re-directing, otherwise the call may not complete and/or races against
the page reload causing random Behat errors.
2023-02-27 23:30:33 +00:00
Paul Holden 53c2d0ad15 MDL-77321 reportbuilder: cache list of loaded reports per user.
Since 0188af39 we've cached loaded reports, however there was an
edge case in those report sources that relied on the current user
as part of their own initialization (e.g. checking capabilities).

Co-authored-by: Marina Glancy <marina@moodle.com>
2023-02-27 21:16:23 +00:00
Paul Holden 72f7128665 MDL-77418 mod_feedback: defensive use of analysis item data. 2023-02-27 19:21:27 +00:00
Ferran Recio c91c4b39e9 MDL-77420 core: fix modal close button on remove on close 2023-02-27 19:15:12 +01:00
Eloy Lafuente (stronk7) 4e5ed8fdcd MDL-77417 behat: behat_error_handler meets deprecation error types
Right now, any E_DEPRECATED, E_USER_DEPRECATED error type leads
to exception in behat runs, because the behat error handled is
not aware of them. See MDL-38041 for the initial implementation.

We don't want that to happen and they must behave like other "low"
error types (notices, warnings...), that will be reported in logs
or output, but won't trigger any exception, so the test can continue.

This commit just adds those 2 "new" error types to the handler,
providing the very same behaviour for them than the rest.
2023-02-27 09:37:42 +01:00
Leon Stringer 76b8862518 MDL-77322 oauth2: Fix basicauth checkbox
Following MDL-61880 you could turn on "Authenticate token requests via
HTTP headers" but not turn this off again.  This change fixes this and
adds a Behat scenario to test toggling this checkbox is saved
correctly.
2023-02-24 17:27:05 +00:00
Eloy Lafuente (stronk7) 7aeb3a8b6e MDL-77097 store_mongodb: keep compatibility with PHP 7.4
Replaced 4 occurrences of get_debug_type() by gettype() to keep PHP 7.4 compatibility. Note this
has not been applied to 4.2dev and up because, there, it's safe to use get_debug_type().
2023-02-24 12:38:47 +01:00
Sara Arjona a8bb233a56 MDL-77276 mod_data: Update reset single template string
When a single template is reset, the string displayed in the modal should
not reference to "all templates" to avoid confusion, as it was shown in the
original prototype for the 4.1 database project.
2023-02-24 11:23:09 +01:00
Luca Bösch c7d9fa690d MDL-77141 gradebook: Correct course name in user report 2023-02-24 10:43:16 +01:00
Jun Pataleta a31f5830bd weekly release 4.1.1+ 2023-02-24 15:43:22 +08:00
Jun Pataleta 47db6bc3f9 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-02-24 15:43:19 +08:00
Matt Porritt 3258f4cf3e MDL-77376 Licensing: Update trademark.txt
Update Trademark policy in TRADEMARK.txt to
be in line with advice from the Moodle HQ
legal team
2023-02-24 12:33:36 +08:00
Andrew Nicols 96ca10cc73 Merge branch 'MDL-76611-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-23 12:01:30 +08:00
Andrew Nicols 6c97d7ba5b Merge branch 'MDL-76843_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-02-23 11:52:47 +08:00
Andrew Nicols 01cdda182c Merge branch 'MDL-77271-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-02-23 11:49:26 +08:00
Ilya Tregubov a47e5311af MDL-74433 mod_assign: Fix version.php 2023-02-23 11:47:27 +08:00
Andrew Nicols 296ed92898 Merge branch 'MDL-77290-401' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2023-02-23 11:46:24 +08:00
Andrew Nicols 1e28db3e01 Merge branch 'MDL-76735-401' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2023-02-23 11:34:36 +08:00
Ilya Tregubov 1f88fcdb09 Merge branch 'MDL-74433_401' of https://github.com/larsbonczek/moodle into MOODLE_401_STABLE 2023-02-23 11:22:32 +08:00
Andrew Nicols 352db923e1 Merge branch 'MDL-77352-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-23 11:20:16 +08:00
Andrew Nicols a0c79271fc Merge branch 'MDL-77354-401' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE 2023-02-23 10:49:51 +08:00
Andrew Nicols 9d97d0c519 Merge branch 'MDL-76577/401' of https://github.com/skodak/moodle into MOODLE_401_STABLE 2023-02-23 10:46:38 +08:00
Andrew Nicols 352affa056 Merge branch 'MDL-75005_41' of https://github.com/skodak/moodle into MOODLE_401_STABLE 2023-02-23 10:29:23 +08:00
Andrew Nicols f8d2c0207b MDL-77230 mod_feedback: Coding style violation fixes 2023-02-23 10:06:03 +08:00
Andrew Nicols 506604c911 Merge branch 'MDL-77230-401' of https://github.com/sarjona/moodle into MOODLE_401_STABLE 2023-02-23 10:05:58 +08:00
Ilya Tregubov 183b705fe4 Merge branch 'MDL-76873-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-23 09:58:09 +08:00
Andrew Nicols f559c0ad59 Merge branch 'MDL-77210_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-02-23 09:22:52 +08:00
Andrew Nicols 2781ef309c Merge branch 'MDL-77149-m401' of https://github.com/sammarshallou/moodle into MOODLE_401_STABLE 2023-02-23 09:20:44 +08:00
Paul Holden 58d85f21da MDL-74585 core: pass string identifier/component to network keepalive.
Avoid passing potentially large amounts of data in the page AMD call,
allow the `core/network` module to load actual string content itself.
2023-02-22 16:20:34 +00:00
Tim Hunt c4de73821a MDL-76843 quiz: add test to verify random essay stats now work 2023-02-22 15:07:45 +00:00
Tim Hunt 291d241981 MDL-76843 quiz: fix statistics questions for missing questions 2023-02-22 15:07:40 +00:00
Tim Hunt d6f0ad4980 MDL-76843 questions behat: enhancements requried to test this issue
* New steps to set up certian sorts of broken test data.
* Fix qtype_essay_question::un_summarise_response().
2023-02-22 15:05:41 +00:00
Tim Hunt 40d6ba9505 MDL-76298 drag-drop questions: validate the questions are complete
Previously, it was possible to create drag-drop markers and onto image
questions without any drag items or drop zones. This was non-sensical,
and broke statistics calculations.

So, missing validation added, and random guess score calculation made
robust.
2023-02-22 12:06:34 +00:00
Tim Hunt 32bf205db3 MDL-58945 qbank: showing q text should give option of plain or full 2023-02-22 11:17:52 +00:00
Ilya Tregubov 30cd583d5d Merge branch 'MDL-77285-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-02-22 12:27:13 +08:00
Huong Nguyen 45877b9c1b MDL-77354 tool_behat: Fix deprecated strlen() of null in PHP 8.1 2023-02-22 11:08:23 +07:00
Huong Nguyen c5916d6303 MDL-77290 tiny_media: Fix cannot update the created media
Including in this commit:
 - Changed the button text to Update media when the user is updating the media
 - Added new Behat tests
2023-02-22 09:36:44 +07:00
Paul Holden c3504d5e4c MDL-77352 javascript: declare debouncer outside the event handler.
It needs to be declared as such, otherwise each time the event is
triggered a new debouncer is created.
2023-02-21 22:47:50 +00:00
Paul Holden fa9ef9baf8 MDL-76602 mod_lti: array syntax/whitespace cleanup. 2023-02-21 17:06:25 +00:00
Paul Holden fe9bc4d5c0 Merge branch 'MDL-76602-401-lti13claims' of https://github.com/cengage/moodle into MOODLE_401_STABLE 2023-02-21 16:46:25 +00:00
sam marshall dadceea8f5 MDL-77149 core_files: Network filesystem (Amazon EFS) can warn
If you delete a file with a hash and then create another file with
the same hash, sometimes on EFS filesystems while trying to create
the new file, it returns true to the file_exists check even though
the file doesn't exist, but then fails other calls.

This change makes Moodle tolerate that behaviour.
2023-02-21 10:55:10 +00:00
Huong Nguyen 20d103f014 MDL-76735 editor_tiny: Fix random behat failure for Media image 2023-02-21 14:30:56 +07:00
Simey Lameze 6e3242d677 MDL-77271 behat: verify user licence preference is remembered 2023-02-21 15:25:47 +08:00
AMOS bot d79fbf80a2 Automatically generated installer lang files 2023-02-21 00:07:37 +00:00
Paul Holden 2bf6bfcac8 Merge branch 'MDL-76545-401' of https://github.com/ferranrecio/moodle into MOODLE_401_STABLE 2023-02-20 10:28:53 +00:00
Audun Jørstad Lillekjendlie de4739338a MDL-77318 core: Add role attribute to user navigation div 2023-02-20 10:56:42 +01:00
Paul Holden bc30c47ad7 Merge branch 'MDL-77287-401' of https://github.com/snake/moodle into MOODLE_401_STABLE 2023-02-20 09:55:09 +00:00
Paul Holden d227c27ca7 MDL-76873 user: method for returning profile field instance of type.
Re-factor implementation of profile field access within user fields
class to use that already provided by the fields themselves.
2023-02-20 09:24:11 +00:00
Paul Holden 9829e77a6d MDL-76873 reportbuilder: correct checks for profile field visibility. 2023-02-20 09:22:07 +00:00
Andrew Nicols f6d38b13a2 Merge branch 'MDL-77020-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-20 09:54:25 +08:00
Ferran Recio ddcd60552b MDL-76545 core: fix reactive debug panel
The reactive debug panel stops working when a new reactive instance is
created in the fly. This was not detected until the new dragf and drop
files into course uses a second reactive UI component in the same page.
2023-02-17 17:18:25 +01:00
Sara Arjona cc4b43a57b MDL-77230 mod_feedback: Validate feedback access
The get_items() and get_page_items() external methods should return
items only when the user has access. Otherwise, empty array for items
will be returned, with the exact error in the warnings parameter.
2023-02-17 12:41:20 +01:00
Petr Skoda 4ca23b917b MDL-76577 block_html: fix incorrect use of draft files 2023-02-17 09:52:55 +01:00
Petr Skoda 507306a6ca MDL-75005 core: remove invalid addslashes() 2023-02-17 09:49:55 +01:00
Jake Dallimore efe9ac66be MDL-77287 tool_oauth2: fix issuer form validation
This ensures validation errors from the issuer persistent are seen.
2023-02-17 15:14:39 +08:00
Ilya Tregubov 3312a6814a weekly release 4.1.1+ 2023-02-17 09:12:20 +08:00
Ilya Tregubov 995d6a3301 Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-02-17 09:12:18 +08:00
Simey Lameze 0d7642b8e8 MDL-77285 behat: change window size to large to prevent error 2023-02-17 08:44:18 +08:00
AMOS bot 3da0488fbc Automatically generated installer lang files 2023-02-17 00:07:51 +00:00
Paul Holden 9be10c0dd1 MDL-77020 behat: refer to search input fields by name/role.
Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
2023-02-16 10:53:46 +00:00
Audun Jørstad Lillekjendlie 3ff714acbe MDL-77020 core: Include a unique id in the search input field id 2023-02-16 10:19:08 +00:00
Meirza 75f729911e MDL-76825 tiny: restyling link on focus for sufficient colour contrast.
Text elements must have sufficient colour contrast against the background,
restyling the link element when it is focused is to ensure colour contrast of at least 4.5:1
2023-02-16 13:12:29 +07:00
Meirza 854f67cf65 MDL-76825 tiny_media: Make IDs and labels unique. 2023-02-16 13:12:29 +07:00
Meirza 476abf4610 MDL-76825 theme: ensure button role has an accessible name. 2023-02-16 13:12:29 +07:00
Andrew Nicols 09534ee3f9 Merge branch 'MDL-75578-401' of https://github.com/mackensen/moodle into MOODLE_401_STABLE 2023-02-16 12:01:28 +08:00
Jun Pataleta fc3aaf9c67 Merge branch 'MDL-72182-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-16 11:58:52 +08:00
Andrew Nicols 1b1e1801b7 Merge branch 'MDL-77102-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-16 11:51:31 +08:00
Jun Pataleta 5f61f7f3e7 Merge branch 'MDL-76584-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-16 11:49:06 +08:00
Andrew Nicols 41c1731431 Merge branch 'MDL-74698_401' of https://github.com/jonof/moodle into MOODLE_401_STABLE 2023-02-16 11:06:44 +08:00
Ilya Tregubov 9cb0e85cf9 MDL-76313 forum: code style changes. 2023-02-16 11:00:28 +08:00
Ilya Tregubov dd9073a232 Merge branch '76313-forum-improve-accessibility-401' of https://github.com/DSI-Universite-Rennes2/moodle into MOODLE_401_STABLE 2023-02-16 11:00:12 +08:00
Andrew Nicols de285364c5 Merge branch 'MDL-76791-m401' of https://github.com/sammarshallou/moodle into MOODLE_401_STABLE 2023-02-16 10:53:39 +08:00
Ilya Tregubov 8d585d0c79 MDL-75379 core: Code style changes. 2023-02-16 10:49:51 +08:00
Ilya Tregubov 960bff3227 Merge branch 'MDL-75379_401' of https://github.com/larsbonczek/moodle into MOODLE_401_STABLE 2023-02-16 10:49:37 +08:00
Andrew Nicols eed3f09aa0 Merge branch 'MDL-76878-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-16 10:43:56 +08:00
Ilya Tregubov a001500897 Merge branch 'MDL-73519-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2023-02-16 09:34:17 +08:00
Andrew Nicols 8c16eb18f6 Merge branch 'MDL-76478-password-unmask-MOODLE_401_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_401_STABLE 2023-02-15 23:25:35 +08:00
Andrew Nicols 927b0fc34d Merge branch 'MDL-76948_401' of https://github.com/larsbonczek/moodle into MOODLE_401_STABLE 2023-02-15 23:01:41 +08:00
Paul Holden a457f1b1cd Merge branch 'MDL-77147_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-02-15 11:49:22 +00:00
Ilya Tregubov 946504b58d Merge branch 'MDL-75230-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-02-15 16:12:50 +08:00
Andrew Nicols ae1447060e Merge branch 'MDL-77241-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-15 11:14:35 +08:00
Jun Pataleta e9e2c481fd Merge branch 'MDL-77156-401' of https://github.com/lucaboesch/moodle into MOODLE_401_STABLE 2023-02-15 11:12:11 +08:00
Jun Pataleta 16e62aa2ad Merge branch 'MDL-77212-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-15 11:09:11 +08:00
Jun Pataleta 5432766411 Merge branch 'MDL-77223-401' of https://github.com/roland04/moodle into MOODLE_401_STABLE 2023-02-15 11:07:11 +08:00
AMOS bot 2a77c6f1d5 Automatically generated installer lang files 2023-02-15 00:07:52 +00:00
Paul Holden e9a32f3463 Merge branch 'MDL-77140-401' of https://github.com/snake/moodle into MOODLE_401_STABLE 2023-02-14 15:51:37 +00:00
Paul Holden 42c58dce39 Merge branch 'MDL-75454-401' of https://github.com/davewoloszyn/moodle into MOODLE_401_STABLE 2023-02-14 15:06:03 +00:00
Paul Holden be6cb6ab13 MDL-77241 course: optional chaining safety for section toggles. 2023-02-14 13:15:29 +00:00
Paul Holden 51254db574 Merge branch 'MDL-63608_401' of https://github.com/AnupamaSarjoshi/moodle into MOODLE_401_STABLE 2023-02-14 11:59:53 +00:00
Ilya Tregubov cffc56a17c Merge branch 'MDL-76947-401' of https://github.com/davewoloszyn/moodle into MOODLE_401_STABLE 2023-02-14 13:53:04 +08:00
Ilya Tregubov ff449751d9 Merge branch 'MDL-76620-401' of https://github.com/call-learning/moodle into MOODLE_401_STABLE 2023-02-14 13:26:21 +08:00
David Woloszyn a869fbf33e MDL-75454 cache: Reduced exposure of sesskey param 2023-02-14 11:28:51 +11:00
Tim Hunt bdcc5b7a59 MDL-77210 quiz: fix regrade for attempts with redone questions 2023-02-13 16:58:26 +00:00
Mikel Martín 8d9a898bb5 MDL-77223 reportbuilder: Fix first report column as integer 2023-02-13 16:17:39 +01:00
Lars Bonczek 35792ea06a MDL-75379 core: Use non-static template cache 2023-02-13 12:40:20 +01:00
Paul Holden 9f7219844e MDL-76611 cohort: prevent duplicate idnumber in inplace editable. 2023-02-13 10:33:29 +00:00
Paul Holden 21986200d7 MDL-77212 tiny_accessibilitychecker: remove unused lang string fetch. 2023-02-13 08:49:33 +00:00
Ilya Tregubov 94bb9b2b73 Merge branch 'MDL-77189-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-02-13 13:43:34 +08:00
Simey Lameze fde83c33a8 MDL-77189 behat: basic coverage for wikimedia repository 2023-02-13 13:23:45 +08:00
Jun Pataleta 301fa85c26 Merge branch '76314-forum-fix-forumtype-and-groupmode-validation-401' of https://github.com/DSI-Universite-Rennes2/moodle into MOODLE_401_STABLE 2023-02-13 11:38:55 +08:00
Anupama Sarjoshi 7bee650a24 MDL-63608 quiz: Fix Access order when manually grading quizzes
Changes done to fix access order of attempts that need manual grading.
Changed button text from 'Save and go to next page' to 'Save and show next' to improve UI.
2023-02-10 17:46:39 +00:00
Luca Bösch 46d8e08a16 MDL-77156 enrol_self: deprecated trim() of null in PHP 8.1 2023-02-10 18:16:58 +01:00
Paul Holden eb84455a05 weekly release 4.1.1+ 2023-02-10 13:47:33 +00:00
Paul Holden 3da5ef8e9c Merge branch 'install_401_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_401_STABLE 2023-02-10 13:47:32 +00:00
Julien Boulen 2b568f1c93 MDL-76314 forum: add form check to prevent combining wrong parameters
Form validation prevents combining the forum type "single discussion" and the group mode "separate groups".
2023-02-10 11:07:45 +01:00
Jake Dallimore ec02c39dbb MDL-77140 mod_lti: fix content item return for new TinyMCE versions 2023-02-10 10:10:24 +08:00
Andrew Nicols 0dc15ee619 Merge branch 'MDL-76904-401' of https://github.com/NashTechOpenUniversity/moodle into MOODLE_401_STABLE 2023-02-09 12:04:33 +08:00
Andrew Nicols 1cddc8edcb Merge branch 'MDL-74755-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-09 11:44:27 +08:00
Jun Pataleta fbe9dc4ecf Merge branch 'MDL-77052-401' of https://github.com/Utdanningsdirektoratet/moodle into MOODLE_401_STABLE 2023-02-09 11:27:30 +08:00
Andrew Nicols 7906636a3a Merge branch 'MDL-76354-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-09 10:59:21 +08:00
Andrew Nicols 58814af9f1 Merge branch 'MDL-77018_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-02-09 10:51:48 +08:00
Andrew Nicols df96d98c39 Merge branch 'MDL-76066-401' of https://github.com/aanabit/moodle into MOODLE_401_STABLE 2023-02-09 10:47:58 +08:00
Andrew Nicols d3040a763a Merge branch 'MDL-77057-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-09 10:21:06 +08:00
Andrew Nicols c3b36c6a34 Merge branch 'MDL-76499-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-02-09 10:04:30 +08:00
Andrew Nicols 1ee066cecd Merge branch 'MDL-70586-401' of https://github.com/sarjona/moodle into MOODLE_401_STABLE 2023-02-09 09:42:29 +08:00
Paul Holden 72c8793ae7 Merge branch 'MDL-76672-401' of https://github.com/Utdanningsdirektoratet/moodle into MOODLE_401_STABLE 2023-02-08 14:57:34 +00:00
Paul Holden 130f5c1dd6 Merge branch 'MDL-76542-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-02-08 14:22:11 +00:00
Laurent David 96aaae3f19 MDL-76620 mod_bigbluebuttonbn: Fix guest behat test
* Refactor guest_access.feature behat test
2023-02-08 14:28:06 +01:00
Laurent David 52ed4a47f7 MDL-76620 mod_bigbluebuttonbn: Fix guest access with forcelogin
*With "forcelogin" setting turned on, the new external guest
 links in the bigbluebutton plugin do not work but show the login screen instead
2023-02-08 14:28:06 +01:00
Paul Holden daa7e5b4e2 Merge branch 'MDL-73692-401-Add-support-for-missing-timestamps-to-rss-block' of https://github.com/melanietreitinger/moodle into MOODLE_401_STABLE 2023-02-08 11:22:50 +00:00
Melanie Treitinger ab619ae38d MDL-73692 blocks: Add support for missing timestamps to rss block. 2023-02-08 11:19:27 +01:00
Jun Pataleta 6cb71e3e8b Merge branch 'MDL-74905_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2023-02-08 17:19:27 +08:00
Angelia Dela Cruz 3b4246cd89 MDL-75230 behat: Lesson Behat tests optimised
Replace steps that manually add Lesson instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
2023-02-08 15:49:42 +08:00
Simey Lameze d17117ab02 MDL-76542 behat: add step to go to user edit page directly 2023-02-08 12:24:27 +08:00
Simey Lameze 2158f5c2e6 MDL-76542 behat: create custom profile fields using data generators
This commit also adds a new test to verify the custom profile fields
works using the user interface.
2023-02-08 12:24:26 +08:00
Jun Pataleta dbe40db138 Merge branch 'MDL-76569-401' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-02-07 22:49:08 +08:00
Lars Bonczek 53ad452d6c MDL-74433 mod_assign: Fix logging of submission removal 2023-02-07 12:34:42 +01:00
Jun Pataleta a574be993c Merge branch 'MDL-76089-401' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-02-07 15:34:51 +08:00
Marina Glancy d9d9d42c81 MDL-76089 lib: upgrade horde library 2023-02-07 15:29:32 +08:00
Andrew Nicols 0b586e839d Merge branch 'MDL-77023-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-07 12:48:09 +08:00
Andrew Nicols 22141c2f8d Merge branch 'MDL-77123-401' of https://github.com/cameron1729/moodle into MOODLE_401_STABLE 2023-02-07 12:39:48 +08:00
Andrew Nicols 61f1700fbf Merge branch 'mdl-76729_401' of https://github.com/james-cnz/moodle into MOODLE_401_STABLE 2023-02-07 12:37:16 +08:00
Andrew Nicols 0ce350e78a Merge branch 'MDL-75946-401' of https://github.com/davewoloszyn/moodle into MOODLE_401_STABLE 2023-02-07 10:44:40 +08:00
sam marshall d2c0dd4f6b MDL-76791 core_cache: Locking breaks for multiple-identifiers store
Cache locking fails if the cache store supports multiple identifiers
(in core, the only two which do are cachestore_static and
cachestore_mongodb, so this is unlikely to cause severe problems).
2023-02-06 15:47:25 +00:00
Paul Holden 5f5355065a Merge branch 'MDL-77078-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-02-06 13:33:04 +00:00
Andrew Nicols b9dece93d8 Merge branch 'MDL-77042-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-06 21:17:04 +08:00
Audun Jørstad Lillekjendlie b84ad66fbe MDL-76672 block_myoverview: add role attribute for filter div 2023-02-06 14:07:37 +01:00
Audun Jørstad Lillekjendlie 7b787cd99f MDL-77052 block_recentlyaccesseditems: HTML role attribute
HTML elements with role=list must contain children with role=listitem
2023-02-06 13:49:18 +01:00
Tim Hunt 6e72a4ed50 MDL-77147 question admin: optimised the query in admin/qtypes.php 2023-02-06 12:47:06 +00:00
Paul Holden d69579a060 Merge branch 'MDL-76370-publicpaths-proxying-MOODLE_401_STABLE' of https://github.com/jaydn/moodle into MOODLE_401_STABLE 2023-02-06 11:02:45 +00:00
Marina Glancy 5f3524f3df MDL-72182 my: tests for resetting dashboard
Co-authored-by: Paul Holden <paulh@moodle.com>
2023-02-06 09:34:27 +00:00
Paul Holden bdd380ffea MDL-72182 user: cross-DB compatibility for getting user pages/blocks. 2023-02-06 09:34:27 +00:00
Paul Holden cd0d9b910e MDL-74755 block_accessreview: stricter checking of enabled config. 2023-02-06 09:31:39 +00:00
David Woloszyn 177f619b12 MDL-76947 css: Fixed layout regression on dropdown menus 2023-02-06 16:05:31 +11:00
Andrew Nicols b21e31b016 Merge branch 'MDL-77091-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-06 12:59:33 +08:00
Angelia Dela Cruz 6ce00e289f MDL-77078 Behat: Coverage for assignment submission statement 2023-02-06 10:47:36 +08:00
AMOS bot f5e6601ab5 Automatically generated installer lang files 2023-02-06 00:07:41 +00:00
Anastasios Bithas f23463f8d6 MDL-73642 mod_assign: Disable draft option if submission already made 2023-02-04 18:38:10 +02:00
Andrew Nicols a41a3281de Merge branch 'MDL-76662-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-04 21:38:10 +08:00
Eloy Lafuente (stronk7) f24f47992a MDL-74905 ci: travis and gha, some adjustments
Apply for some of the improvements made for 4.2:
- Use our own moodlehq/mysql-action
- Define the tmpfs size and ensure that binlogs are disabled.
- 401_STABLE doesn't require the php-xmlrpc extension.
2023-02-03 19:48:05 +01:00
Eloy Lafuente (stronk7) ec9f3e8976 MDL-74905 environment: Apply agreed changes:
- PHP 8.0 required.
- Moodle 3.11.8 required (first minor supporting PHP 8.0 officially).
- MySQL 8.0 required.
- MariaDB 10.6.7 required.
- PostgreSQL 13 required.
- php-sodium extension required.
- 64-bit PHP required.
2023-02-03 19:48:05 +01:00
Eloy Lafuente (stronk7) e8e1faad78 MDL-74905 environment: 4.2 base information
This is a direct copy of the 4.1 information, to
have all the real changes under control in next commit(s).
2023-02-03 19:48:05 +01:00
Eloy Lafuente (stronk7) a8ff0f7271 MDL-74905 composer: Small update to behat/behat 3.12.0
It comes with some fixes for PHP 8.1 that we may need here.

Generated following the instructions @ https://docs.moodle.org/dev/Composer .
2023-02-03 19:48:05 +01:00
Paul Holden 79b9e6f36e Merge branch 'MDL-76869-401' of https://github.com/cameron1729/moodle into MOODLE_401_STABLE 2023-02-03 14:58:27 +00:00
Paul Holden 9fe490b715 Merge branch 'MDL-77090_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-02-03 14:46:51 +00:00
Paul Holden ae355c5749 Merge branch 'MDL-76447-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2023-02-03 14:31:30 +00:00
Tim Hunt f93fa35ecf MDL-77090 questions: regrade of interactive attempts lose tries count
The behaviour-specific data was getting corrupted when the regrade
recreated the first step, because $oldstep->get_behaviour_data() was
stripping off the leading '-' characters from the names, and they were
not being added back.
2023-02-03 10:52:45 +00:00
Jun Pataleta cb6dc699b8 weekly release 4.1.1+ 2023-02-03 15:43:36 +08:00
Angelia Dela Cruz 9cc3769ba6 MDL-76499 behat: Resource Behat tests optimised
Replace steps that manually add resource instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.

Co-authored-by: David Woloszyn <david.woloszyn@moodle.com>
2023-02-03 13:32:58 +08:00
David Woloszyn 562d62474e MDL-75946 lib_horde: Fixed deprecated FILTER_SANITIZE_STRING 2023-02-03 12:58:32 +11:00
David Woloszyn 226bfb0348 MDL-75946 core_h5p: Fixed deprecated FILTER_SANITIZE_STRING 2023-02-03 12:58:32 +11:00
Jonathon Fowler 39e58054b1 MDL-74698 backup: correctly restore course format options
Old-version backups (< 3.11.7, < 4.0.1) lose their course-level format
options when restoring into newer versions after the backup structure
was changed.

Also, course-level format options were not accurately restored against
the appropriate format type. And section-level format options were
redundantly stored at course-level and restored without mapping their
sectionids, thus creating lint.
2023-02-03 10:18:19 +10:00
Cameron Ball c0c478acb4 MDL-77123 message_airnotifier: Don't test configured providers 2023-02-02 14:49:51 +08:00
Andrew Nicols d7e9b065cb Merge branch 'MDL-75870-401' of https://github.com/nwp90/moodle into MOODLE_401_STABLE 2023-02-02 12:34:40 +08:00
Andrew Nicols aa1b0c5ebd Merge branch 'MDL-75085-401-4' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE 2023-02-02 12:02:47 +08:00
Andrew Nicols 1780d6a5e8 Merge branch 'MDL-75830-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-02-02 11:58:02 +08:00
Andrew Nicols c4840c6b0c Merge branch 'MDL-77024_401' of https://github.com/timhunt/moodle into MOODLE_401_STABLE 2023-02-02 11:52:41 +08:00
Andrew Nicols f0d9073159 Merge branch 'MDL-76675_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2023-02-02 11:03:38 +08:00
Jun Pataleta b90bccd3d8 Merge branch 'MDL-69690-401' of https://github.com/ilyatregubov/moodle into MOODLE_401_STABLE 2023-02-02 10:34:00 +08:00
Ilya Tregubov 7e7628b806 Merge branch 'MDL-77058-401' of https://github.com/dravek/moodle into MOODLE_401_STABLE 2023-02-02 10:04:58 +08:00
Jun Pataleta 920ac6dbe5 Merge branch 'MDL-77092-m401' of https://github.com/sammarshallou/moodle into MOODLE_401_STABLE 2023-02-02 09:57:06 +08:00
Andrew Nicols 662d2e1f0f Merge branch 'MDL-75912-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-02-02 09:49:25 +08:00
Ilya Tregubov e247320845 Merge branch 'MDL-77079-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-02-02 09:16:50 +08:00
Jun Pataleta e87a6484bf MDL-75085 external: Pass proper $required param value in tests 2023-02-02 09:07:17 +08:00
Angelia Dela Cruz 0a66a77054 MDL-75830 behat: Book behat tests optimised
Replace steps that manually add Book instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
Additionally, performed Behat cleanup and optimisation to affected
files.
2023-02-02 09:05:38 +08:00
Andrew Nicols 4bd7c57be5 Merge branch 'MDL-77100-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-02 08:32:38 +08:00
Andrew Nicols 6f073ebe6d Merge branch 'MDL-77001-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-02 08:27:21 +08:00
Andrew Nicols 885d191df2 Merge branch 'MDL-77003-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-02 08:20:51 +08:00
Andrew Nicols 3ef9c4c5d0 Merge branch 'MDL-75345-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-02-02 08:17:54 +08:00
Nick Phillips e4e7ec5efb MDL-75870 course: only section togglers to toggle sections 2023-02-02 11:17:31 +13:00
Paul Holden a3c9194bef Merge branch 'MDL-76658-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-02-01 16:34:39 +00:00
Paul Holden c125d5f3f2 MDL-75345 reportbuilder: improve course/user custom report tests.
Ensure column and filters provided by each source have sufficient
coverage. Re-factor individual entity/helper class tests to test
their own specific implementation only.

Remove now-defunct test fixtures.
2023-02-01 15:41:28 +00:00
Paul Holden 4b9e614eaf MDL-77091 reportbuilder: set base time in schedule test generator.
The base time allows for the setting of the "current time" for the
purposes of the schedule test against recurrence configuration.

We should ensure the generator method allows this property so that
it can be used when calculating the initial "next send time" of the
schedule upon creation (and avoiding excessive recursion when the
actual current time is used for the calculation).
2023-02-01 14:39:36 +00:00
Paul Holden 858b26feb2 Merge branch 'MDL-76311-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2023-02-01 14:16:15 +00:00
Meirza a6a6fbc5ec MDL-76311 user: redirect to proper URL if a new user creation cancelled 2023-02-01 20:14:01 +07:00
Sara Arjona 242060661a MDL-70586 mod_feedback: Hide the Preview questions icon for students
The Preview questions icon shouldn't be displayed unless the user can
edit the feedback or access to the reports; otherwise, it's causing
confusion (especially when the feedback is not opened).
2023-02-01 12:36:20 +01:00
Meirza e7f9631b7e MDL-76447 editor_tiny: revert the z-index.
Nesting the dropdown menu inside the parent DOM makes the menu can display correctly
without changing the z-index.
2023-02-01 17:39:34 +07:00
Meirza f37f6e3439 MDL-76447 editor_tiny: Nest the dropdown menu in the parent DOM.
The TinyMCE menu has a significant issue with the Overflow style,
and the Boost theme heavily uses Overflow for drawer navigation.
Nest the dropdown menu container into the parent editor container makes it work correctly.

Co-authored-by: davewoloszyn <david.woloszyn@moodle.com>
Co-authored-by: xr0master <xr0master@gmail.com>
2023-02-01 17:39:34 +07:00
Paul Holden b59bb37819 Merge branch 'MDL-73847_401' of https://github.com/jonof/moodle into MOODLE_401_STABLE 2023-02-01 10:00:27 +00:00
Paul Holden 03a1ca582b MDL-77102 mod_wiki: remove deprecated mbstring overload checks. 2023-02-01 08:34:09 +00:00
Jun Pataleta e3dd47671c Merge branch 'MDL-76985-MOODLE_401_STABLE' of https://github.com/sh-csg/moodle into MOODLE_401_STABLE 2023-02-01 14:11:53 +08:00
Ilya Tregubov fc2a1536f7 Merge branch 'MDL-76587-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-02-01 13:25:54 +08:00
Jun Pataleta bdd3e5efb1 MDL-75085 external: Fix external_multiple_structure parameter passing
Some calls to the external_multiple_structure's constructor incorrectly
pass parameters where the value for the $description parameter is not
being passed. This results to invalid values being passed for the
$required parameter.
2023-02-01 11:39:53 +08:00
Jun Pataleta 1753e85f1a MDL-75085 webservice: Fix parameter passed to external_format_value 2023-02-01 11:39:44 +08:00
Angelia Dela Cruz 725af41225 MDL-75912 behat: Wiki Behat tests optimised
Behat cleanup and optimisation
2023-02-01 11:11:03 +08:00
Angelia Dela Cruz 5a6481006d MDL-75912 behat: Wiki Behat tests now use generators
Replace steps that manually add Wiki instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
2023-02-01 11:03:20 +08:00
Simey Lameze d350fcc040 MDL-77079 behat: use different step to validate presets table data 2023-02-01 09:03:50 +08:00
Paul Holden 2ea379e0b0 MDL-77100 mod_data: replace calls to str_ends_with, fix assertions.
Calls to `str_ends_with` are polyfilled currently, as the method is
not present in PHP7.4 or earlier. We should avoid uses of it so as
to not trip up compatibility standard checkers.
2023-01-31 21:36:32 +00:00
Tim Hunt 514b6f13d9 MDL-77094 quiz_statistics: improve efficiency of the recalculate task
quiz_settings::create() requires at least 3 DB queries, so the point is
that we can avoid doing that until after we have worked out if we need
to calculate statistics for this quiz.

Also, we order the list of quizzes to consier, to process the ones with
more recent attempts first.
2023-01-31 17:01:53 +00:00
Julien Boulen b20ca4b471 MDL-76945 theme: fix the rendering of arrows on dropdown variants 2023-01-31 15:22:25 +01:00
Andrew Nicols 421ae9cb83 Merge branch 'MDL-75945-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2023-01-31 22:12:28 +08:00
sam marshall f5dc8c4f9f MDL-77092 Behat: Expand all fieldsets fails with single fieldset
The Behat step to expand all fieldsets did not work if the page
contains only one fieldset.
2023-01-31 13:58:08 +00:00
Andrew Nicols 7dfb4c229c Merge branch 'MDL-77081-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-31 21:45:05 +08:00
Angelia Dela Cruz df1d34bea8 MDL-76658 Behat: Coverage for course cohort enrolment groups
Co-authored-by: Simey Lameze <simey@moodle.com>
2023-01-31 21:24:12 +08:00
Paul Holden 6acc34a097 MDL-77081 forms: PHP8.1 compatibility for group/textarea elements.
See related changes in b0a83aa7, we can no longer pass null values
to some string related methods.
2023-01-31 10:51:20 +00:00
Ilya Tregubov 0338a74dfb Merge branch 'MDL-77077-401' of https://github.com/snake/moodle into MOODLE_401_STABLE 2023-01-31 18:13:49 +08:00
hieuvu 06c3d068a6 MDL-76904 question: Keep question highlight in url 2023-01-31 16:32:36 +07:00
Simey Lameze ed544dd0f3 MDL-76587 behat: make grading page wider to avoid 'out of bounds' fail
This is because on classic theme the navigation block pushes the content
to the right and once behat changes the grades the 'Save changes' button
is no longer visible.
2023-01-31 11:18:09 +08:00
Charles Fulton 5cd9e69b6a MDL-75578 course: require course library to resolve namespace issues 2023-01-30 10:44:57 -05:00
Jake Dallimore a6bd5ae245 MDL-77077 mod_lti: Fix JWT signature verify when alg missing from JWKS
Infer the algorithm, where necessary, using a combination of JWT
headers and known valid LTI algorithms.
2023-01-30 16:44:58 +08:00
Andrew Nicols cd0935a33e Merge branch 'MDL-77040-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-30 12:28:01 +08:00
Tim Hunt db861ee6d3 MDL-77018 qbank_statistics: only load stats for contexts that exist
Also, pre-load the contexts for efficiency.
2023-01-27 20:51:51 +00:00
David Matamoros 2307060239 MDL-77058 reportbuilder: Fix for cohort null idnumber column 2023-01-27 14:09:03 +01:00
Paul Holden d78d372a1e MDL-77057 group: format group names in module override pages. 2023-01-27 11:50:55 +00:00
Eloy Lafuente (stronk7) 8b31b8e8d0 MDL-76675 date: Only test all TZ names with PHPUNIT_LONGTEST enabled
It happens often that some timezone is renamed, split, added to the
IANAs list of timezones (that, for PHP is kept updated by the
php-timezonedb PECL extension).

When the information coming from the extension changes, all the
PHPUnit jobs in the world start failing (that's when CIs update
their PHP images, when devs update their packages, ...).

So, what we are doing here is to move that test that check for
every single string existing to be run only when PHPUNIT_LONGTEST
is enabled. That way only places running all tests will run that
one. And every other run just will skip it.

This corresponds to point 1 & 2 of the issue, lower impact in general
and, still be able to enable the tests to run.
2023-01-27 08:48:22 +01:00
Andrew Nicols 62118364f2 Merge branch 'MDL-76562-401' of https://github.com/meirzamoodle/moodle into MOODLE_401_STABLE 2023-01-27 14:24:26 +08:00
Andrew Nicols 0a4f551fff Merge branch 'MDL-75978-401' of https://github.com/JBThong/moodle into MOODLE_401_STABLE 2023-01-27 12:34:04 +08:00
Paul Holden d8f7fb803f MDL-77040 core: assert types of returned Geoplugin data, not values.
The results we get from these tests are beyond our control, and are
unreliable for use in testing.

See also previous change 215cd2d8 in similar tests.
2023-01-26 13:24:06 +00:00
Paul Holden 64293da947 MDL-76662 tool_log: correct supported reports test assertions. 2023-01-26 13:09:13 +00:00
Davo Smith dcd48987f7 MDL-76938 backup: fix restore of comments linked to a course format 2023-01-26 12:32:35 +00:00
Sara Arjona 67bbf6c416 weekly release 4.1.1+ 2023-01-26 09:59:12 +01:00
Lars Bonczek d238db5f36 MDL-76948 mod_assign: Fix description of submission_unlocked event 2023-01-25 19:20:56 +01:00
Paul Holden 522ee5ae4c MDL-77042 mod_data: fix empty/zero equality check for numeric field. 2023-01-25 17:04:47 +00:00
Tim Hunt deed4fe251 MDL-77024 quiz: fix metatdata on log events
Some had the wrong edulevel or crud
2023-01-25 16:12:37 +00:00
Jun Pataleta a360fd0601 Merge branch 'MDL-76977-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-25 16:10:18 +08:00
Jun Pataleta 5e75da7598 Merge branch 'MDL-77036-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-01-25 16:02:23 +08:00
Stefan Hanauska 928633a33e MDL-76985 course: Redirect to moved section 2023-01-25 09:00:06 +01:00
Simey Lameze 6bf5c32402 MDL-77036 core_iplookup: update test_ipv4 test expectations 2023-01-25 15:15:07 +08:00
Jun Pataleta 6d90fc7c5b Merge branch 'MDL-76967-401' of https://github.com/lucaboesch/moodle into MOODLE_401_STABLE 2023-01-25 08:57:16 +08:00
Paul Holden 0a86c6a123 MDL-77003 javascript: improve string helper JSON detection.
Changes in fbc2732d made the JS template string helper method
too strict in regards to what it considers a valid JSON object.

Co-authored-by: Mike Churchward <mike@brickfieldlabs.ie>
2023-01-24 22:16:21 +00:00
Paul Holden 4b43da100c MDL-77023 javascript: always normalise component of lang strings.
Co-authored-by: David Matamoros <davidmc@moodle.com>
2023-01-24 16:44:06 +00:00
Jun Pataleta addbbfdaae Merge branch 'MDL-76639-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-01-24 18:59:29 +08:00
Jun Pataleta 0006557b59 Merge branch 'MDL-76652-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-01-24 18:45:24 +08:00
Jun Pataleta 0813b938a3 Merge branch 'MDL-76655-401' of https://github.com/andelacruz/moodle into MOODLE_401_STABLE 2023-01-24 18:27:00 +08:00
Andrew Nicols 710d0ef8f2 MDL-75945 core: Convert a floating value to an integer.
In PHP 8.1, any implicit conversion of float to int, which leads to a loss in precision, is now deprecated.
To avoid the error warning, the code must explicitly convert a floating value to an integer.
2023-01-24 16:53:34 +07:00
Jun Pataleta fa51e1a149 Merge branch 'MDL-76362-401-extra' of https://github.com/andrewnicols/moodle into MOODLE_401_STABLE 2023-01-24 10:38:49 +08:00
Angelia Dela Cruz 066740a127 MDL-76655 behat: Coverage for workshop grading strategies 2023-01-24 09:09:26 +08:00
Paul Holden 26754aacd1 MDL-76354 competency: export user privacy data unconditionally.
We should ensure that any past competency data for a user is always
exported, regardless whether competencies are currently enabled.
2023-01-23 22:15:23 +00:00
Paul Holden e0358d2eca MDL-77001 tiny_autosave: use valid lang string during privacy export. 2023-01-23 22:06:33 +00:00
Amaia Anabitarte 3fd5c885a1 MDL-76066 mod_data: Trigger field_deleted event when importing 2023-01-23 18:54:35 +01:00
sam marshall 40081f5342 MDL-76956 core_grades: Regrade progress bar should be more granular
This change makes the regrade progress bar send frequent updates to
the web browser, even when processing within the same grade item, to
avoid timeout problems when there are a large number of users.
2023-01-23 11:43:15 +00:00
Paul Holden 1aa113fd1f MDL-76584 question: correct temporary questionid upgrade field.
Pass correct parameter/type in field constructor (`XMLDB_NOTNULL`)
for consistency. This corrects the definition and preserves the
truthyness of the value that was incorrectly passed previously.
2023-01-23 09:16:39 +00:00
Eloy Lafuente (stronk7) 36b4f13e9b MDL-76362 workshop: check for empty (null included) feedbackreviewer
As far as feedbackreviewer can be null, we cannot, since PHP 8.1
apply any string operation (trim, strlen...) on it, hence, checking
before applying.
2023-01-23 09:19:32 +08:00
Eloy Lafuente (stronk7) 03bc275093 MDL-76362 enrol_lti: Prevent calling to DataConnector with null keys
While it could have been fixed in DataConnector (3rd part lib), better
prevent in our code to call to it with null keys.

Covered by unit tests.
2023-01-23 09:17:48 +08:00
Eloy Lafuente (stronk7) e6dfa9ff3c MDL-76362 output: Preserve original behaviour for PHP 8.1
Whenever the page_requirements_manager::js_fix_url()
is called with null url, it must throw an exception and emit 0 warnings.

It's covered by an explicit test:

test_js_fix_url_coding_exception with data set "Provide a null argument"
2023-01-23 09:17:48 +08:00
Andrew Nicols 8f4bd4ce11 MDL-76362 core: Coding style fixes 2023-01-23 09:16:08 +08:00
Andrew Nicols 77a0a535b3 MDL-76362 core_privacy: Shortcircuit URL rewriting on empty content 2023-01-23 09:16:08 +08:00
Andrew Nicols a4ea607c24 MDL-76362 core: Short circuit s() on empty values 2023-01-23 09:16:08 +08:00
Andrew Nicols dbfb5eaa45 MDL-76362 core: Short-circuit strip_querystring on empty values 2023-01-23 09:16:08 +08:00
Andrew Nicols 788d86d7a3 MDL-76362 core_file: Check prefix exists before checking length 2023-01-23 09:16:07 +08:00
Andrew Nicols a1f4f7bac5 MDL-76362 core: plugin names must be strings to be valid 2023-01-23 09:16:07 +08:00
Andrew Nicols d08319ddf7 MDL-76362 core: Update core_component plugin name tests 2023-01-23 09:16:07 +08:00
Andrew Nicols de4de9cec5 MDL-76362 core: Test coursealias before using 2023-01-23 09:16:07 +08:00
Andrew Nicols ddf0f08cc9 MDL-76362 h5p: Use string as default lang param 2023-01-23 09:16:07 +08:00
Andrew Nicols 2250ab07e6 MDL-76362 qtype_numerical: Fix bug in phpdoc 2023-01-23 09:16:07 +08:00
Andrew Nicols 71c1fa0d8e MDL-76362 qtype_calculated*: Address issues with null strings 2023-01-23 09:16:07 +08:00
Andrew Nicols 5fbd2eac32 MDL-76362 qtype: Update formatting of qtype_calculated* upgradelib 2023-01-23 09:16:07 +08:00
Andrew Nicols 12b36d2a32 MDL-76362 qtype_numerical: Support empty units for apply_units 2023-01-23 09:16:07 +08:00
Andrew Nicols 5f412b3301 MDL-76362 qtype_numeric: Refactor answer tests 2023-01-23 09:16:07 +08:00
Andrew Nicols 4ff3447c8c MDL-76362 question: Add test for number(null) 2023-01-23 09:16:07 +08:00
Andrew Nicols 745080671b MDL-76362 question: Refactor question number unit tests 2023-01-23 09:16:07 +08:00
Andrew Nicols 5fbbb51882 MDL-76362 core: Use empty default string when getting prefs
The json_decode function does not accept a null, which is the
traditional default for get_user_preferences. By passing a default of
am empty string we avoid issues in PHP 8.1.
2023-01-23 09:16:06 +08:00
Marina Glancy 2dd7290ccb MDL-76362 various: Avoid passing nulls to functions that don't allow nulls
PHP 8.1 is more strict on the parameter type. Functions such as trim(), strlen(), str_replace(), etc
show notice when null is passed as an argument
2023-01-23 09:16:06 +08:00
Marina Glancy d83368a475 MDL-76362 mustache: Override parent method to avoid PHP notices
Parent method checks baseDir that is null in this case. This shows notices under PHP 8.1
2023-01-23 09:16:06 +08:00
Paul Holden a68f5c6d37 MDL-76977 phpunit: ensure unique data provider keys in mustache test. 2023-01-20 17:21:27 +00:00
Luca Bösch 8bb813e461 MDL-76967 questions: Questions last used line height 2023-01-20 09:57:21 +01:00
Meirza fb935957b8 MDL-76562 editor_tiny: Added functions to remove button/menu/submenu.
Added a few functions to remove the toolbar button, menubar and sub-menu items.
One of the implementations is to remove the justify alignment in the toolbar and
the sub-menu items to aid the accessibility aspect of the TinyMCE editor.
2023-01-20 10:02:06 +07:00
Ilya Tregubov 8de12b7997 weekly release 4.1.1+ 2023-01-20 09:41:41 +08:00
Paul Holden 1c6f0e8a19 MDL-76878 user: amend permission callbacks for preference definitions.
Ensure those preferences that are used for storing state can always be
updated via web service requests for the current user.
2023-01-19 15:28:45 +00:00
Hiroto Kagotani 5fa1ec0dfa MDL-76936 course: purge course cache on resetting start date 2023-01-19 20:08:58 +09:00
Jun Pataleta 0f28e2b02c Merge branch 'MDL-76725-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-19 12:05:06 +08:00
Jun Pataleta 396fff3d0b Merge branch 'MDL-76537_401' of https://github.com/stronk7/moodle into MOODLE_401_STABLE 2023-01-19 11:23:51 +08:00
Ilya Tregubov e98b3fe183 Merge branch 'MDL-76870-401' of https://github.com/lameze/moodle into MOODLE_401_STABLE 2023-01-19 11:15:14 +08:00
Ilya Tregubov 69fbf97923 Merge branch 'MDL-76766-401' of https://github.com/aanabit/moodle into MOODLE_401_STABLE 2023-01-19 11:04:23 +08:00
Ilya Tregubov c4df4906bc Merge branch 'MDL-74756-MOODLE_401_STABLE' of https://github.com/sh-csg/moodle into MOODLE_401_STABLE 2023-01-19 10:30:32 +08:00
Andrew Nicols dd1efc4312 Merge branch 'MDL-76841-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-19 08:55:09 +08:00
Andrew Nicols 3309157233 Merge branch 'MDL-70070-401' of https://github.com/paulholden/moodle into MOODLE_401_STABLE 2023-01-19 08:50:37 +08:00
Jun Pataleta abd969cb50 Merge branch 'MDL-76525-MOODLE_401_STABLE' of https://github.com/PhMemmel/moodle into MOODLE_401_STABLE 2023-01-18 22:55:51 +08:00
Philipp Memmel 888ed072c0 MDL-76525 mod_data: Add param validation for data fields 2023-01-18 12:10:45 +01:00
Claude Vervoort 1210c71703 MDL-76602 mod_lti: move lti13 claim declaration in subplugin 2023-01-17 16:55:10 -05:00
Jake Dallimore 17659466cc Merge branch 'MDL-66221-401' of https://github.com/raortegar/moodle into MOODLE_401_STABLE 2023-01-17 11:28:53 +08:00
Stefan Hanauska 61b77b3bb6 MDL-74756 availability_completion: Prev activity (completion n/enabled) 2023-01-16 22:20:45 +01:00
Paul Holden a74c5f0073 MDL-76841 tool_mobile: improve potential config issues test.
Avoid certificate checking of the default test site (`example.com`),
and update the assertion so we get clearer failures in the future.
2023-01-16 08:30:43 +00:00
Paul Holden 70a5e38b2c MDL-70070 phpunit: correct data provider method names.
They should not be prefixed `test_` because that's how actual
test methods containing assertions are identified by PHPUnit.
2023-01-16 08:28:31 +00:00
Jaydn Cunningham a2e37371a6 MDL-76370 curl: suppress CONNECT header when using HTTP proxy 2023-01-16 14:04:26 +10:30
Eloy Lafuente (stronk7) 2c7773b365 MDL-76537 behat: Month and day names are lang-dependent correct utf-8
Just verify that calendars are always displayed with correct UTF-8
and in the language the user is currently using.
2023-01-14 12:16:48 +01:00
Eloy Lafuente (stronk7) 7c66344323 MDL-76537 core: Fix date_format_string() to work with php-intl
With Moodle 4.1 and up, we have stopped to work with strftime(),
because it's deprecated for PHP 8.1 and up and, instead we are
using core_date::strftime() that performs the conversions using
the php-intl extension.

The original strftime() had a lot of OS-specific dependencies,
both about locale names and charsets used to provide the information.

Instead, the php-intl gets rid of all those OS-specific nightmares
and only uses ICU/Unicode locales and UTF-8.

Because of that, the old utf-8 => windows charset => utf-8
conversions aren't needed anymore. Hence, removing them.
2023-01-14 12:16:48 +01:00
Jun Pataleta 4b69c11978 Moodle release 4.1.1 2023-01-14 14:17:03 +08:00
raortegar c812f450bb MDL-66221 tool_recyclebin: Fix recycle bin with activity settings
If backup_auto_activities setting from Automated backup is disabled
the activities will not be stored for the recycle bin
2023-01-13 11:31:33 +01:00
Simey Lameze 4b2834439e MDL-76870 question: change assertion to assertEqualsCanonicalizing
By using that assertion the arrays will be sorted before comparison
preventing any Oracle sorting related failures.

Credits for the solution go to Tim Hunt!
2023-01-13 18:13:12 +08:00
Angelia Dela Cruz 6bd3f18949 MDL-76639 behat: Add Behat test coverage for quiz with limited attempts 2023-01-13 16:11:22 +08:00
Jonathon Fowler cc290a84e4 MDL-73847 lti: fetch keyset URLs using configured proxy settings 2023-01-13 14:30:05 +10:00
Jun Pataleta 2d628ba8d6 weekly release 4.1+ 2023-01-13 10:52:14 +08:00
Cameron Ball 83c1ddc19d MDL-76869 gradebook: Pass exception to rollback 2023-01-12 16:35:47 +08:00
Ilya Tregubov 66ad660acc MDL-69690 mod_workshop: Fix fieldname for workshop. 2023-01-12 14:41:13 +07: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
Amaia Anabitarte 959c34de04 MDL-76766 mod_quiz: Allow shuffling quizes with no questions 2023-01-11 11:16:09 +01: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
Julien Boulen e50831318e MDL-76313 forum: improve accessibility on subscribers page
- add header on table of subscribers
- remove one redundant header
2023-01-10 11:17:22 +01: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
Meirza 687e276fe3 MDL-73519 core_course: re-styling the unordered list.
Currently, the unordered list in the course content follows the original style and
is ordered from the top of the content section, which is not part of the description.
That's why the first occurrence of the list is the 2nd level which uses the circle as the marker/list type
instead of the disc. In contrast, the editor always uses the original style.

so we need to reset the CSS of the unordered list in the description to the original
which the disc as the first marker, a circle for the second marker,
and a square for the following levels.
2023-01-10 12:18:39 +07: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
james-cnz bc574f252d MDL-76729 filepicker: Restore file picker thumbnails in tree view 2023-01-10 12:01:27 +13: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
Simey Lameze e1204dc4f1 MDL-76652 behat: use data generator and remove duplicated steps 2023-01-09 10:16:50 +08:00
Simey Lameze 33b7115024 MDL-76652 behat: add coverage for postwithoutthrottling logic 2023-01-09 10:16:50 +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
Paul Holden 0563f72142 MDL-76725 mod_wiki: avoid named arguments in real path callback.
See also f4fb91ae. PHP8 now supports named arguments in calls to
the `call_user_func_array` method, which can result in differing
behaviour compared to PHP7, e.g. in this case it was throwing an
exception due to an unknown named parameter.
2023-01-04 14:08:14 +00: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
Thong Bui a93d6e5f2d MDL-75978 Quiz\D&D: on mobile, a moving line-wrap can bork the question 2022-12-22 10:08:03 +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
Brendan Heywood 11721f7ff5 MDL-76478 formslib: Fix autocomplete bug of existing passwords 2022-12-06 12:34:25 +11: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
Andrew Nicols 9e1caf81ce MDL-76569 editor_tiny: Set table row header style
Configure Tiny to use markup of:

table > thead > tr > th

For all table headers.
2022-12-05 20:50:06 +08: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
Mark Holliday c55f219d77 MDL-76376 scorm: fix PHP8 TypeError (null is not Countable) 2022-11-28 17:52:10 -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
23354 changed files with 585442 additions and 1039805 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,
}
}
]
-3
View File
@@ -1,6 +1,3 @@
**/yui/build/** -diff
**/amd/build/** -diff
lib/dml/oci_native_moodle_package.sql text eol=lf
**.js.map -diff
**-min.js -diff
**.min.js -diff
+1 -1
View File
@@ -1,2 +1,2 @@
# Primary donations pages.
custom: ["https://moodle.com/donations/", "https://fund.moodle.org"]
custom: ["https://moodle.com/donations/", moodle.org]
-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
+13 -24
View File
@@ -3,30 +3,24 @@ 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.1
jobs:
Grunt:
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
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,14 +54,12 @@ jobs:
fail-fast: false
matrix:
include:
# MySQL builds always run with the lowest PHP supported version.
- os: ubuntu-24.04
php: 8.1
- os: ubuntu-22.04
php: 7.4
extensions:
db: mysqli
# PostgreSQL builds always run with the highest PHP supported version.
- os: ubuntu-24.04
php: 8.3
- os: ubuntu-22.04
php: 8.1
db: pgsql
steps:
@@ -76,7 +68,7 @@ jobs:
uses: moodlehq/mysql-action@v1
with:
collation server: utf8mb4_bin
mysql version: 8.0
mysql version: 5.7
mysql database: test
mysql user: test
mysql password: test
@@ -88,7 +80,7 @@ jobs:
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 +97,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 +113,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 }}
+10 -15
View File
@@ -1,14 +1,9 @@
name: Windows Testing
on:
workflow_dispatch:
inputs:
phpunit_extra_options:
description: Additional options to apply to PHPUnit
required: false
default: ''
workflow_dispatch
env:
php: 8.3
php: 8.1
jobs:
Grunt:
@@ -21,10 +16,10 @@ jobs:
git config --global core.eol lf
- 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'
@@ -51,15 +46,15 @@ jobs:
matrix:
include:
- os: windows-latest
php: 8.3
php: 8.1
# 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
extensions: exif, fileinfo, gd, intl, pgsql, mysql, redis, soap, sodium
- os: windows-latest
php: 8.1
php: 8.0
db: pgsql
extensions: exif, fileinfo, gd, intl, pgsql, mysql, redis, soap, sodium
@@ -117,7 +112,7 @@ jobs:
git config --global core.eol lf
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
uses: actions/checkout@v4
uses: actions/checkout@v3
# Needs to be done after php is available, git configured and Moodle checkout has happened.
- name: Setting up moodle-exttests service
@@ -128,7 +123,7 @@ jobs:
- name: Setting up redis service
run: |
choco install redis --version 5.0.7 --no-progress
choco install redis-64 --version 3.0.503 --no-progress
nssm install redis redis-server
nssm start redis
@@ -146,4 +141,4 @@ jobs:
env:
dbtype: ${{ matrix.db }}
phpunit_options: ${{ secrets.phpunit_options }}
run: vendor/bin/phpunit $phpunit_options ${{ inputs.phpunit_extra_options }}
run: vendor/bin/phpunit $phpunit_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
+2 -177
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;
@@ -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',
});
+19 -7
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
@@ -60,6 +60,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 +104,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 +113,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 +151,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 -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/jod
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": {
}
}
]
}
}
+277
View File
@@ -0,0 +1,277 @@
# 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.1)
- if: env(MOODLE_PHP) = "all"
php: 8.1
env: DB=none TASK=CITEST
- if: env(MOODLE_PHP) = "all"
php: 8.1
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.1
env: DB=pgsql TASK=PHPUNIT
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all")
php: 8.1
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
echo -e "[mysqld]\nskip-log-bin" | sudo tee -a /etc/mysql/my.cnf
sudo service mysql start
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
sh -c 'until pg_isready -p $PGPORT; do echo "Waiting for the DB to be up..."; sleep 2; done'
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:
- 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
-52
View File
@@ -1,52 +0,0 @@
# Contributing to Moodle
[Moodle][1] is made by people like you. We are members of a big worldwide community of developers, designers, teachers, testers, translators and many more. We work in universities, schools, companies and other places. You are very welcome to join us and contribute to the project.
There are many ways that you can contribute to Moodle, not just through development. See our [community contribution guide][2] for some of the many ways that you can help.
## Github
> [!NOTE]
> Please do not open pull requests via Github.
All issues should be reported via, and patched provided to the [Moodle Tracker][3].
The Moodle [Github][4] repository is a clone of the official Moodle repository, whcih can be found at https://git.moodle.org.
## Moodle core bug fixes and new features
Over the years, Moodle has developed a mature process for reporting, reviewing, and accepting patches. This is fully documented in our [documentation on development processes][6], but in summary:
- Every bug fix or new feature must have a tracker issue.
- You publish the branch implementing the fix or new feature in your public clone of the moodle.git repository (typically on Github).
- Your patch is peer-reviewed, discussed, integrated, tested and then released as a part of one of our weekly releases.
- New features are developed on the `main` branch. Bug fixes are also backported to currently supported maintenance (stable) branches.
> [!IMPORTANT]
> Please do not publish security issues, or patches releating to them publicly.
> See our [Responsible Disclosure Policy][5] for more information.
## Moodle plugins
Moodle has a framework for additional plugins to extend its functionality. We
have a Moodle plugins directory <https://moodle.org/plugins/> where you can
register and maintain your plugin. Plugins hosted in the plugins directory can
be easily installed and updated via the Moodle administration interface.
* You are expected to have a public source code repository with your plugin
code.
* After registering your plugin in the plugins directory it is reviewed before
being published.
* You are expected to continuously release updated versions of the plugin via
the plugins directory. We do not pull from your code repository; you must do
it explicitly.
For further details, see <https://moodledev.io/general/community/plugincontribution>.
[1]: https://moodle.org
[2]: https://moodledev.io/general/community/contribute
[3]: https://tracker.moodle.org
[4]: https://github.com/moodle/moodle
[5]: https://moodledev.io/general/development/process/security
[6]: https://moodledev.io/general/development/process
+56
View File
@@ -0,0 +1,56 @@
CONTRIBUTING TO MOODLE
======================
Moodle is made by people like you. We are members of a big worldwide community
of developers, designers, teachers, testers, translators and other users. We
work in universities, schools, companies and other places. You are very welcome
to join us and contribute to the project.
See <https://docs.moodle.org/dev/Contributing_to_Moodle> for the many ways you
can help, not only with coding.
Moodle is open to community contributions to core, though all code must go
through peer-review, automated behaviour testing, continuous integration and
human post-integration checks.
Pull requests
-------------
Please do not open pull requests via Github. The repository there is just a
mirror of the official repository at <https://git.moodle.org>. Issues are
reported and patches provided via <https://tracker.moodle.org>. See below for
more information.
Moodle core bug fixes and new features
--------------------------------------
During the years of intensive development, a mature process of including
submitted patches has evolved.
* Every bug fix or new feature must have a tracker issue.
* You publish the branch implementing the fix or new feature in your public
clone of the moodle.git repository (typically on Github).
* Your patch is peer-reviewed, discussed, integrated, tested and then released
as a part of moodle.git.
* New features are developed on the master branch. Bug fixes are also
backported to currently supported maintenance (stable) branches.
For further details, see <https://docs.moodle.org/dev/Process>.
Moodle plugins
--------------
Moodle has a framework for additional plugins to extend its functionality. We
have a Moodle plugins directory <https://moodle.org/plugins/> where you can
register and maintain your plugin. Plugins hosted in the plugins directory can
be easily installed and updated via the Moodle administration interface.
* You are expected to have a public source code repository with your plugin
code.
* After registering your plugin in the plugins directory it is reviewed before
being published.
* You are expected to continuously release updated versions of the plugin via
the plugins directory. We do not pull from your code repository; you must do
it explicitly.
For further details, see <https://docs.moodle.org/dev/Plugin_contribution>.
-2
View File
@@ -260,8 +260,6 @@ module.exports = function(grunt) {
addTask('watch', grunt);
addTask('startup', grunt);
addTask('upgradablelibs', grunt);
// Register the default task.
grunt.registerTask('default', ['startup']);
};
+7
View File
@@ -0,0 +1,7 @@
*** 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.txt guidelines for how to contribute patches for Moodle. Thank you.
--
-48
View File
@@ -1,48 +0,0 @@
# Moodle
<p align="center"><a href="https://moodle.org" target="_blank" title="Moodle Website">
<img src="https://raw.githubusercontent.com/moodle/moodle/main/.github/moodlelogo.svg" alt="The Moodle Logo">
</a></p>
[Moodle][1] is the World's Open Source Learning Platform, widely used around the world by countless universities, schools, companies, and all manner of organisations and individuals.
Moodle is designed to allow educators, administrators and learners to create personalised learning environments with a single robust, secure and integrated system.
## Documentation
- Read our [User documentation][3]
- Discover our [developer documentation][5]
- Take a look at our [demo site][4]
## Community
[moodle.org][1] is the central hub for the Moodle Community, with spaces for educators, administrators and developers to meet and work together.
You may also be interested in:
- attending a [Moodle Moot][6]
- our regular series of [developer meetings][7]
- the [Moodle User Association][8]
## Installation and hosting
Moodle is Free, and Open Source software. You can easily [download Moodle][9] and run it on your own web server, however you may prefer to work with one of our experienced [Moodle Partners][10].
Moodle also offers hosting through both [MoodleCloud][11], and our [partner network][10].
## License
Moodle is provided freely as open source software, under version 3 of the GNU General Public License. For more information on our license see
[1]: https://moodle.org
[2]: https://moodle.com
[3]: https://docs.moodle.org/
[4]: https://sandbox.moodledemo.net/
[5]: https://moodledev.io
[6]: https://moodle.com/events/mootglobal/
[7]: https://moodledev.io/general/community/meetings
[8]: https://moodleassociation.org/
[9]: https://download.moodle.org
[10]: https://moodle.com/partners
[11]: https://moodle.com/cloud
[12]: https://moodledev.io/general/license
+28
View File
@@ -0,0 +1,28 @@
.-..-.
_____ | || |
/____/-.---_ .---. .---. .-.| || | .---.
| | _ _ |/ _ \/ _ \/ _ || |/ __ \
* | | | | | || |_| || |_| || |_| || || |___/
|_| |_| |_|\_____/\_____/\_____||_|\_____)
Moodle - the world's open source learning platform
Moodle <https://moodle.org> is a learning platform designed to provide
educators, administrators and learners with a single robust, secure and
integrated system to create personalised learning environments.
You can download Moodle <https://download.moodle.org> and run it on your own
web server, ask one of our Moodle Partners <https://moodle.com/partners/> to
assist you, or have a MoodleCloud site <https://moodle.com/cloud/> set up for
you.
Moodle is widely used around the world by universities, schools, companies and
all manner of organisations and individuals.
Moodle is provided freely as open source software, under the GNU General Public
License <https://docs.moodle.org/dev/License>.
Moodle is written in PHP and JavaScript and uses an SQL database for storing
the data.
See <https://docs.moodle.org> for details of Moodle's many features.
-1591
View File
File diff suppressed because it is too large Load Diff
-9
View File
@@ -1,9 +0,0 @@
# core_admin (subsystem) Upgrade notes
## 4.5rc1
### Removed
- The HTTP Server setting "Use slash arguments" (slasharguments) configuration setting and related to it has been removed. Calling the option with $CFG->slasharguments or get_config('slasharguments') is no longer available.
For more information see [MDL-62640](https://tracker.moodle.org/browse/MDL-62640)
-65
View File
@@ -1,65 +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/>.
/**
* Manage AI subsystem plugins settings.
*
* @package core_admin
* @copyright 2024 Matt Porritt <matt.porritt@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../config.php');
require_once($CFG->libdir . '/adminlib.php');
$action = required_param('action', PARAM_ALPHANUMEXT);
$type = required_param('type', PARAM_PLUGIN); // Must be provider or placement.
$name = required_param('name', PARAM_PLUGIN); // Plugin name, e.g openai.
$syscontext = context_system::instance();
$PAGE->set_url('/admin/ai.php');
$PAGE->set_context($syscontext);
require_admin();
require_sesskey();
$return = new moodle_url('/admin/settings.php', ['section' => "aisettings$type"]);
$plugins = core_plugin_manager::instance()->get_plugins_of_type("ai$type");
$sortorder = array_flip(array_keys($plugins));
if (!isset($plugins[$name])) {
throw new moodle_exception('aipluginnotfound', 'core_ai', $return, $name);
}
$plugintypename = $plugins[$name]->type . '_' . $plugins[$name]->name;
switch ($action) {
case 'disable':
if ($plugins[$name]->is_enabled()) {
$class = core_plugin_manager::resolve_plugininfo_class("aisettings$type");
$class::enable_plugin($name, false);
}
break;
case 'enable':
if (!$plugins[$name]->is_enabled()) {
$class = core_plugin_manager::resolve_plugininfo_class("aisettings$type");
$class::enable_plugin($name, true);
}
break;
}
redirect($return);
-3
View File
@@ -1,3 +0,0 @@
define("core_admin/block_management_table",["exports","./plugin_management_table","core_table/dynamic","core/ajax","core/pending","core/notification"],(function(_exports,_plugin_management_table,_dynamic,_ajax,_pending,_notification){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_plugin_management_table=_interopRequireDefault(_plugin_management_table),_pending=_interopRequireDefault(_pending);class _default extends _plugin_management_table.default{constructor(){super(),this.addClickHandler(this.handleBlockProtectToggle)}setBlockProtectState(plugin,state){return(0,_ajax.call)([{methodname:"core_admin_set_block_protection",args:{plugin:plugin,state:state}}])[0]}async handleBlockProtectToggle(tableRoot,e){const stateToggle=e.target.closest('[data-action="toggleprotectstate"]');if(stateToggle){e.preventDefault();const pendingPromise=new _pending.default("core_table/dynamic:processAction");await this.setBlockProtectState(stateToggle.dataset.plugin,"1"===stateToggle.dataset.targetState?1:0);const[updatedRoot]=await Promise.all([(0,_dynamic.refreshTableContent)(tableRoot),(0,_notification.fetchNotifications)()]);updatedRoot.querySelector('[data-action="toggleprotectstate"][data-plugin="'.concat(stateToggle.dataset.plugin,'"]')).focus(),pendingPromise.resolve()}}}return _exports.default=_default,_exports.default}));
//# sourceMappingURL=block_management_table.min.js.map
@@ -1 +0,0 @@
{"version":3,"file":"block_management_table.min.js","sources":["../src/block_management_table.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\nimport PluginManagementTable from './plugin_management_table';\nimport {refreshTableContent} from 'core_table/dynamic';\nimport {call as fetchMany} from 'core/ajax';\nimport Pending from 'core/pending';\nimport {fetchNotifications} from 'core/notification';\n\nexport default class extends PluginManagementTable {\n constructor() {\n super();\n this.addClickHandler(this.handleBlockProtectToggle);\n }\n\n /**\n * Set the block protection state.\n *\n * @param {string} plugin\n * @param {number} state\n * @returns {Promise}\n */\n setBlockProtectState(plugin, state) {\n return fetchMany([{\n methodname: 'core_admin_set_block_protection',\n args: {\n plugin,\n state,\n },\n }])[0];\n }\n\n /**\n * Handle toggling of block protection.\n *\n * @param {HTMLElement} tableRoot\n * @param {Event} e\n */\n async handleBlockProtectToggle(tableRoot, e) {\n const stateToggle = e.target.closest('[data-action=\"toggleprotectstate\"]');\n if (stateToggle) {\n e.preventDefault();\n const pendingPromise = new Pending('core_table/dynamic:processAction');\n\n await this.setBlockProtectState(\n stateToggle.dataset.plugin,\n stateToggle.dataset.targetState === '1' ? 1 : 0\n );\n\n const [updatedRoot] = await Promise.all([\n refreshTableContent(tableRoot),\n fetchNotifications(),\n ]);\n\n // Refocus on the link that as pressed in the first place.\n updatedRoot.querySelector(`[data-action=\"toggleprotectstate\"][data-plugin=\"${stateToggle.dataset.plugin}\"]`).focus();\n pendingPromise.resolve();\n }\n }\n}\n"],"names":["PluginManagementTable","constructor","addClickHandler","this","handleBlockProtectToggle","setBlockProtectState","plugin","state","methodname","args","tableRoot","e","stateToggle","target","closest","preventDefault","pendingPromise","Pending","dataset","targetState","updatedRoot","Promise","all","querySelector","focus","resolve"],"mappings":"uhBAqB6BA,iCACzBC,2BAESC,gBAAgBC,KAAKC,0BAU9BC,qBAAqBC,OAAQC,cAClB,cAAU,CAAC,CACdC,WAAY,kCACZC,KAAM,CACFH,OAAAA,OACAC,MAAAA,UAEJ,kCASuBG,UAAWC,SAChCC,YAAcD,EAAEE,OAAOC,QAAQ,yCACjCF,YAAa,CACbD,EAAEI,uBACIC,eAAiB,IAAIC,iBAAQ,0CAE7Bd,KAAKE,qBACPO,YAAYM,QAAQZ,OACgB,MAApCM,YAAYM,QAAQC,YAAsB,EAAI,SAG3CC,mBAAqBC,QAAQC,IAAI,EACpC,gCAAoBZ,YACpB,wCAIJU,YAAYG,wEAAiEX,YAAYM,QAAQZ,cAAYkB,QAC7GR,eAAeS"}
-10
View File
@@ -1,10 +0,0 @@
define("core_admin/bulk_user_actions",["exports","core_reportbuilder/local/selectors","core_table/local/dynamic/events","core_form/changechecker","core/custom_interaction_events","jquery"],(function(_exports,reportSelectors,tableEvents,FormChangeChecker,CustomEvents,_jquery){var obj;function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}
/**
* Add bulk actions to the users list report
*
* @module core_admin/bulk_user_actions
* @copyright 2024 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,reportSelectors=_interopRequireWildcard(reportSelectors),tableEvents=_interopRequireWildcard(tableEvents),FormChangeChecker=_interopRequireWildcard(FormChangeChecker),CustomEvents=_interopRequireWildcard(CustomEvents),_jquery=(obj=_jquery)&&obj.__esModule?obj:{default:obj};const Selectors_bulkActionsForm="form#user-bulk-action-form",Selectors_userReportWrapper='[data-region="report-user-list-wrapper"]',Selectors_checkbox='input[type="checkbox"][data-togglegroup="report-select-all"][data-toggle="slave"]',Selectors_masterCheckbox='input[type="checkbox"][data-togglegroup="report-select-all"][data-toggle="master"]',Selectors_checkedRows='[data-togglegroup="report-select-all"][data-toggle="slave"]:checked';_exports.init=()=>{var _userBulkForm$closest;const userBulkForm=document.querySelector(Selectors_bulkActionsForm),userReport=null==userBulkForm||null===(_userBulkForm$closest=userBulkForm.closest(Selectors_userReportWrapper))||void 0===_userBulkForm$closest?void 0:_userBulkForm$closest.querySelector(reportSelectors.regions.report);if(!userBulkForm||!userReport)return;const actionSelect=userBulkForm.querySelector("select");CustomEvents.define(actionSelect,[CustomEvents.events.accessibleChange]),(0,_jquery.default)(actionSelect).on(CustomEvents.events.accessibleChange,(event=>{if(event.target.value&&"0"!=="".concat(event.target.value)){const e=new Event("submit",{cancelable:!0});userBulkForm.dispatchEvent(e),e.defaultPrevented||(FormChangeChecker.markFormSubmitted(userBulkForm),userBulkForm.submit())}}));const updateUserIds=()=>{const selectedUsers=[...userReport.querySelectorAll(Selectors_checkedRows)],selectedUserIds=selectedUsers.map((check=>parseInt(check.value)));userBulkForm.querySelector('[name="userids"]').value=selectedUserIds.join(","),actionSelect.disabled=0===selectedUsers.length,actionSelect.disabled&&(actionSelect.value="0");const selectedUsersNames=selectedUsers.map((check=>document.querySelector('label[for="'.concat(check.id,'"]')).textContent));userBulkForm.data={userids:selectedUserIds,usernames:selectedUsersNames}};updateUserIds(),document.addEventListener("change",(event=>{(event.target.matches(Selectors_checkbox)||event.target.matches(Selectors_masterCheckbox))&&userReport.contains(event.target)&&updateUserIds()})),document.addEventListener(tableEvents.tableContentRefreshed,(event=>{userReport.contains(event.target)&&updateUserIds()}))}}));
//# sourceMappingURL=bulk_user_actions.min.js.map
File diff suppressed because one or more lines are too long
-12
View File
@@ -1,12 +0,0 @@
define("core_admin/expand_hash",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=_exports.expandSection=void 0;
/**
* Expand the collapse section element.
*
* @module core_admin/expand_hash
* @copyright Meirza <meirza.arson@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 4.5
*/
const SELECTORS_COLLAPSE_ELEMENTS='[data-toggle="collapse"]',SELECTORS_FOCUSTHENEXPAND_ELEMENTS=".focus-expand";_exports.init=()=>{const focusexpand=document.querySelector(SELECTORS_FOCUSTHENEXPAND_ELEMENTS);null==focusexpand||focusexpand.addEventListener("click",(()=>{expandSection("".concat(focusexpand.getAttribute("href")))}))};const expandSection=hash=>{const container=document.querySelector(hash),targetContainer=null==container?void 0:container.querySelector(SELECTORS_COLLAPSE_ELEMENTS);if("false"===(null==targetContainer?void 0:targetContainer.getAttribute("aria-expanded"))){const collapseId=targetContainer.getAttribute("aria-controls"),collapseContainer=document.getElementById(collapseId);collapseContainer.classList.remove("collapse"),collapseContainer.classList.add("show"),targetContainer.setAttribute("aria-expanded","true"),targetContainer.classList.remove("collapsed");const collapseElement=document.querySelector(".collapseexpand.collapsemenu");collapseElement.setAttribute("aria-expanded","true"),collapseElement.classList.remove("collapsed")}};_exports.expandSection=expandSection}));
//# sourceMappingURL=expand_hash.min.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"expand_hash.min.js","sources":["../src/expand_hash.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Expand the collapse section element.\n *\n * @module core_admin/expand_hash\n * @copyright Meirza <meirza.arson@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.5\n */\n\nconst SELECTORS = {\n COLLAPSE_ELEMENTS: '[data-toggle=\"collapse\"]',\n FOCUSTHENEXPAND_ELEMENTS: '.focus-expand',\n};\n\n/**\n * Initializes the focus and expand functionality.\n */\nexport const init = () => {\n // Select all collapsible elements only.\n const focusexpand = document.querySelector(SELECTORS.FOCUSTHENEXPAND_ELEMENTS);\n\n // Add click event listener to the anchor element\n focusexpand?.addEventListener('click', () => {\n expandSection(`${focusexpand.getAttribute('href')}`);\n });\n};\n\n/**\n * Expands a section based on the provided URL hash.\n *\n * This function takes a hash string, finds the corresponding element in the DOM,\n * and expands it if it is currently collapsed. It updates the necessary ARIA\n * attributes and classes to reflect the expanded state.\n *\n * @param {string} hash - The hash (e.g., '#elementId') of the element to expand.\n */\nexport const expandSection = (hash) => {\n const container = document.querySelector(hash);\n const targetContainer = container?.querySelector(SELECTORS.COLLAPSE_ELEMENTS);\n\n if (targetContainer?.getAttribute('aria-expanded') === 'false') {\n const collapseId = targetContainer.getAttribute('aria-controls');\n const collapseContainer = document.getElementById(collapseId);\n\n // Show the content.\n collapseContainer.classList.remove('collapse');\n collapseContainer.classList.add('show');\n\n // Update aria-expanded attribute to reflect the new state.\n targetContainer.setAttribute('aria-expanded', 'true');\n targetContainer.classList.remove('collapsed');\n\n // Get collapse expand menu element.\n const collapseElement = document.querySelector('.collapseexpand.collapsemenu');\n // Ensure it gets noticed to make it work.\n collapseElement.setAttribute('aria-expanded', 'true');\n collapseElement.classList.remove('collapsed');\n }\n};\n"],"names":["SELECTORS","focusexpand","document","querySelector","addEventListener","expandSection","getAttribute","hash","container","targetContainer","collapseId","collapseContainer","getElementById","classList","remove","add","setAttribute","collapseElement"],"mappings":";;;;;;;;;MAwBMA,4BACiB,2BADjBA,mCAEwB,8BAMV,WAEVC,YAAcC,SAASC,cAAcH,oCAG3CC,MAAAA,aAAAA,YAAaG,iBAAiB,SAAS,KACnCC,wBAAiBJ,YAAYK,aAAa,oBAarCD,cAAiBE,aACpBC,UAAYN,SAASC,cAAcI,MACnCE,gBAAkBD,MAAAA,iBAAAA,UAAWL,cAAcH,gCAEM,WAAnDS,MAAAA,uBAAAA,gBAAiBH,aAAa,kBAA8B,OACtDI,WAAaD,gBAAgBH,aAAa,iBAC1CK,kBAAoBT,SAASU,eAAeF,YAGlDC,kBAAkBE,UAAUC,OAAO,YACnCH,kBAAkBE,UAAUE,IAAI,QAGhCN,gBAAgBO,aAAa,gBAAiB,QAC9CP,gBAAgBI,UAAUC,OAAO,mBAG3BG,gBAAkBf,SAASC,cAAc,gCAE/Cc,gBAAgBD,aAAa,gBAAiB,QAC9CC,gBAAgBJ,UAAUC,OAAO"}
-3
View File
@@ -1,3 +0,0 @@
define("core_admin/plugin_management_table",["exports","core_table/dynamic","core_table/local/dynamic/selectors","core/ajax","core/pending","core/notification"],(function(_exports,_dynamic,Selectors,_ajax,_pending,_notification){var obj;function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,Selectors=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Selectors),_pending=(obj=_pending)&&obj.__esModule?obj:{default:obj};let watching=!1;return _exports.default=class{constructor(){!function(obj,key,value){key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value}(this,"clickHandlers",[]),this.addClickHandler(this.handleStateToggle),this.addClickHandler(this.handleMoveUpDown),this.registerEventListeners()}static init(){watching||(watching=!0,new this)}addClickHandler(handler){this.clickHandlers.push(handler.bind(this))}registerEventListeners(){document.addEventListener("click",function(e){const tableRoot=this.getTableRoot(e);tableRoot&&this.clickHandlers.forEach((handler=>handler(tableRoot,e)))}.bind(this))}getTableRoot(e){const tableRoot=e.target.closest(Selectors.main.region);return tableRoot||!1}setPluginState(methodname,plugin,state){return(0,_ajax.call)([{methodname:methodname,args:{plugin:plugin,state:state}}])[0]}setPluginOrder(methodname,plugin,direction){return(0,_ajax.call)([{methodname:methodname,args:{plugin:plugin,direction:direction}}])[0]}async handleStateToggle(tableRoot,e){const stateToggle=e.target.closest('[data-action="togglestate"][data-toggle-method]');if(stateToggle){e.preventDefault();const pendingPromise=new _pending.default("core_table/dynamic:togglestate");await this.setPluginState(stateToggle.dataset.toggleMethod,stateToggle.dataset.plugin,"1"===stateToggle.dataset.state?0:1);const[updatedRoot]=await Promise.all([(0,_dynamic.refreshTableContent)(tableRoot),(0,_notification.fetchNotifications)()]);updatedRoot.querySelector('[data-action="togglestate"][data-plugin="'.concat(stateToggle.dataset.plugin,'"]')).focus(),this.removeTooltips(),pendingPromise.resolve()}}async handleMoveUpDown(tableRoot,e){const actionLink=e.target.closest('[data-action="move"][data-method][data-direction]');if(!actionLink)return;e.preventDefault();const pendingPromise=new _pending.default("core_table/dynamic:processAction");await this.setPluginOrder(actionLink.dataset.method,actionLink.dataset.plugin,"up"===actionLink.dataset.direction?-1:1);const[updatedRoot]=await Promise.all([(0,_dynamic.refreshTableContent)(tableRoot),(0,_notification.fetchNotifications)()]),exactMatch=updatedRoot.querySelector('[data-action="move"][data-plugin="'.concat(actionLink.dataset.plugin,'"][data-direction="').concat(actionLink.dataset.direction,'"]'));var _updatedRoot$querySel;exactMatch?exactMatch.focus():null===(_updatedRoot$querySel=updatedRoot.querySelector('[data-action="move"][data-plugin="'.concat(actionLink.dataset.plugin,'"]')))||void 0===_updatedRoot$querySel||_updatedRoot$querySel.focus();pendingPromise.resolve()}removeTooltips(){const tooltips=document.querySelectorAll('[id*="tooltip"]');tooltips.length>0&&tooltips.forEach((tooltip=>{tooltip.remove()}))}},_exports.default}));
//# sourceMappingURL=plugin_management_table.min.js.map
File diff suppressed because one or more lines are too long
-11
View File
@@ -1,11 +0,0 @@
define("core_admin/plugins_overview",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){const filters=document.querySelectorAll(SELECTORS_PLUGIN_FILTERS),pluginRows=document.querySelectorAll(SELECTORS_PLUGIN_ROWS),pluginTypeRows=document.querySelectorAll(SELECTORS_PLUGIN_TYPE_ROWS),filterPlugins=target=>{const filterBy=target.getAttribute("data-filterby"),headerVisibility={};for(const row of pluginRows){const type=[...row.classList].find((s=>s.startsWith("type-"))),visible="all"===filterBy||row.classList.contains(filterBy);row.style.display=visible?null:"none",visible&&type&&(headerVisibility[type]=!0)}for(const row of pluginTypeRows){const type=[...row.classList].find((s=>s.startsWith("type-")));if(type){const visible="all"===filterBy||headerVisibility[type];row.style.display=visible?null:"none"}}filters.forEach((el=>el.classList.remove("active"))),target.classList.add("active")};if(filters.forEach((target=>target.addEventListener("click",(e=>{e.preventDefault(),window.history.replaceState({},null,e.target.href),filterPlugins(target)})))),window.location.hash.length>1){const anchor=window.location.hash.substring(1),target=[...filters].find((t=>t.getAttribute("data-filterby")===anchor));target&&filterPlugins(target)}};
/**
* Allows to filter the plugin list on plugins overview page
*
* @module core_admin/plugins_overview
* @copyright 2024 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
const SELECTORS_PLUGIN_FILTERS="#plugins-overview-panel [data-filterby]",SELECTORS_PLUGIN_ROWS="table#plugins-control-panel tbody tr:not(.plugintypeheader)",SELECTORS_PLUGIN_TYPE_ROWS="table#plugins-control-panel tbody tr.plugintypeheader"}));
//# sourceMappingURL=plugins_overview.min.js.map
@@ -1 +0,0 @@
{"version":3,"file":"plugins_overview.min.js","sources":["../src/plugins_overview.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allows to filter the plugin list on plugins overview page\n *\n * @module core_admin/plugins_overview\n * @copyright 2024 Marina Glancy\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst SELECTORS = {\n PLUGIN_FILTERS: '#plugins-overview-panel [data-filterby]',\n PLUGIN_ROWS: 'table#plugins-control-panel tbody tr:not(.plugintypeheader)',\n PLUGIN_TYPE_ROWS: 'table#plugins-control-panel tbody tr.plugintypeheader',\n};\n\n/**\n * Initialise filters for the \"Plugins overview\" page\n */\nexport function init() {\n const filters = document.querySelectorAll(SELECTORS.PLUGIN_FILTERS);\n const pluginRows = document.querySelectorAll(SELECTORS.PLUGIN_ROWS);\n const pluginTypeRows = document.querySelectorAll(SELECTORS.PLUGIN_TYPE_ROWS);\n\n const filterPlugins = (target) => {\n const filterBy = target.getAttribute('data-filterby');\n const headerVisibility = {};\n\n // Hide all plugin rows in the plugin table that do not match the filter and show all others.\n for (const row of pluginRows) {\n const type = [...row.classList].find(s => s.startsWith('type-'));\n const visible = filterBy === 'all' ? true : row.classList.contains(filterBy);\n row.style.display = visible ? null : 'none';\n if (visible && type) {\n headerVisibility[type] = true;\n }\n }\n\n // Hide all the plugin type headers that do not have any visible plugins and show all others.\n for (const row of pluginTypeRows) {\n const type = [...row.classList].find(s => s.startsWith('type-'));\n if (type) {\n const visible = filterBy === 'all' || headerVisibility[type];\n row.style.display = visible ? null : 'none';\n }\n }\n\n // Toggle 'active' class for the selected filter.\n filters.forEach(el => el.classList.remove('active'));\n target.classList.add('active');\n };\n\n // Add event listeners for the links changing plugins filters.\n filters\n .forEach(target => target.addEventListener('click', (e) => {\n e.preventDefault();\n window.history.replaceState({}, null, e.target.href);\n filterPlugins(target);\n }));\n\n // Pre-filter plugins based on the current url anchor.\n if (window.location.hash.length > 1) {\n const anchor = window.location.hash.substring(1);\n const target = [...filters].find(t => t.getAttribute('data-filterby') === anchor);\n if (target) {\n filterPlugins(target);\n }\n }\n}\n"],"names":["filters","document","querySelectorAll","SELECTORS","pluginRows","pluginTypeRows","filterPlugins","target","filterBy","getAttribute","headerVisibility","row","type","classList","find","s","startsWith","visible","contains","style","display","forEach","el","remove","add","addEventListener","e","preventDefault","window","history","replaceState","href","location","hash","length","anchor","substring","t"],"mappings":"4JAiCUA,QAAUC,SAASC,iBAAiBC,0BACpCC,WAAaH,SAASC,iBAAiBC,uBACvCE,eAAiBJ,SAASC,iBAAiBC,4BAE3CG,cAAiBC,eACbC,SAAWD,OAAOE,aAAa,iBAC/BC,iBAAmB,OAGpB,MAAMC,OAAOP,WAAY,OACpBQ,KAAO,IAAID,IAAIE,WAAWC,MAAKC,GAAKA,EAAEC,WAAW,WACjDC,QAAuB,QAAbT,UAA4BG,IAAIE,UAAUK,SAASV,UACnEG,IAAIQ,MAAMC,QAAUH,QAAU,KAAO,OACjCA,SAAWL,OACXF,iBAAiBE,OAAQ,OAK5B,MAAMD,OAAON,eAAgB,OACxBO,KAAO,IAAID,IAAIE,WAAWC,MAAKC,GAAKA,EAAEC,WAAW,cACnDJ,KAAM,OACAK,QAAuB,QAAbT,UAAsBE,iBAAiBE,MACvDD,IAAIQ,MAAMC,QAAUH,QAAU,KAAO,QAK7CjB,QAAQqB,SAAQC,IAAMA,GAAGT,UAAUU,OAAO,YAC1ChB,OAAOM,UAAUW,IAAI,cAIzBxB,QACCqB,SAAQd,QAAUA,OAAOkB,iBAAiB,SAAUC,IACjDA,EAAEC,iBACFC,OAAOC,QAAQC,aAAa,GAAI,KAAMJ,EAAEnB,OAAOwB,MAC/CzB,cAAcC,aAIdqB,OAAOI,SAASC,KAAKC,OAAS,EAAG,OAC3BC,OAASP,OAAOI,SAASC,KAAKG,UAAU,GACxC7B,OAAS,IAAIP,SAASc,MAAKuB,GAAKA,EAAE5B,aAAa,mBAAqB0B,SACtE5B,QACAD,cAAcC;;;;;;;;MAvDpBJ,yBACc,0CADdA,sBAEW,8DAFXA,2BAGgB"}
-10
View File
@@ -1,10 +0,0 @@
define("core_admin/themeselector/preview_modal",["exports","core/modal_events","core/modal_cancel","core/modal_save_cancel","core/notification","core/templates","core/str"],(function(_exports,_modal_events,_modal_cancel,_modal_save_cancel,_notification,_templates,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
/**
* Modal for theme previews.
*
* @module core_admin/themeselector/preview_modal
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modal_events=_interopRequireDefault(_modal_events),_modal_cancel=_interopRequireDefault(_modal_cancel),_modal_save_cancel=_interopRequireDefault(_modal_save_cancel),_notification=_interopRequireDefault(_notification),_templates=_interopRequireDefault(_templates);const SELECTORS_THEMES_CONTAINER="themelist",SELECTORS_PREVIEW='[data-action="preview"]';_exports.init=()=>{registerListenerEvents()};const registerListenerEvents=()=>{document.addEventListener("click",(e=>{const preview=e.target.closest(SELECTORS_PREVIEW);preview&&buildModal(preview).catch(_notification.default.exception)}))},buildModal=async element=>{let description=await(0,_str.getString)("choosereadme","theme_"+element.getAttribute("data-choose"));const themesContainer=document.getElementById(SELECTORS_THEMES_CONTAINER),definedInConfig=parseInt(themesContainer.dataset.definedinconfig),data={name:element.getAttribute("data-name"),image:element.getAttribute("data-image"),description:description.replace(/<[^>]+>/g," "),current:element.getAttribute("data-current"),actionurl:element.getAttribute("data-actionurl"),choose:element.getAttribute("data-choose"),sesskey:element.getAttribute("data-sesskey"),definedinconfig:definedInConfig};let modalTemplate=_modal_save_cancel.default;(data.current||data.definedinconfig)&&(modalTemplate=_modal_cancel.default);const modal=await modalTemplate.create({title:data.name,body:_templates.default.render("core_admin/themeselector/theme_preview_modal",data),large:!0,buttons:{save:(0,_str.getString)("selecttheme","moodle"),cancel:(0,_str.getString)("closebuttontitle","moodle")},show:!0});modal.getRoot().on(_modal_events.default.save,(()=>{modal.getRoot().find("form").submit()}))}}));
//# sourceMappingURL=preview_modal.min.js.map
@@ -1 +0,0 @@
{"version":3,"file":"preview_modal.min.js","sources":["../../src/themeselector/preview_modal.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Modal for theme previews.\n *\n * @module core_admin/themeselector/preview_modal\n * @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalEvents from 'core/modal_events';\nimport ModalCancel from 'core/modal_cancel';\nimport ModalSaveCancel from 'core/modal_save_cancel';\nimport Notification from 'core/notification';\nimport Templates from 'core/templates';\nimport {getString} from 'core/str';\n\nconst SELECTORS = {\n THEMES_CONTAINER: 'themelist',\n PREVIEW: '[data-action=\"preview\"]',\n};\n\n/**\n * Entrypoint of the js.\n *\n * @method init\n */\nexport const init = () => {\n registerListenerEvents();\n};\n\n/**\n * Register theme related event listeners.\n *\n * @method registerListenerEvents\n */\nconst registerListenerEvents = () => {\n document.addEventListener('click', (e) => {\n const preview = e.target.closest(SELECTORS.PREVIEW);\n if (preview) {\n buildModal(preview).catch(Notification.exception);\n }\n });\n};\n\n/**\n * Build the modal with the provided data.\n *\n * @method buildModal\n * @param {object} element\n */\nconst buildModal = async(element) => {\n\n // This string can be long. We will fetch it with JS as opposed to passing it as an attribute.\n let description = await getString('choosereadme', 'theme_' + element.getAttribute('data-choose'));\n\n const themesContainer = document.getElementById(SELECTORS.THEMES_CONTAINER);\n const definedInConfig = parseInt(themesContainer.dataset.definedinconfig);\n // Prepare data for modal.\n const data = {\n name: element.getAttribute('data-name'),\n image: element.getAttribute('data-image'),\n description: description.replace(/<[^>]+>/g, ' '), // Strip out HTML tags.\n current: element.getAttribute('data-current'),\n actionurl: element.getAttribute('data-actionurl'),\n choose: element.getAttribute('data-choose'),\n sesskey: element.getAttribute('data-sesskey'),\n definedinconfig: definedInConfig,\n };\n\n // Determine which modal template we should use.\n let modalTemplate = ModalSaveCancel;\n if (data.current || data.definedinconfig) {\n modalTemplate = ModalCancel;\n }\n\n const modal = await modalTemplate.create({\n title: data.name,\n body: Templates.render('core_admin/themeselector/theme_preview_modal', data),\n large: true,\n buttons: {\n 'save': getString('selecttheme', 'moodle'),\n 'cancel': getString('closebuttontitle', 'moodle'),\n },\n show: true,\n });\n\n modal.getRoot().on(ModalEvents.save, () => {\n modal.getRoot().find('form').submit();\n });\n};\n"],"names":["SELECTORS","registerListenerEvents","document","addEventListener","e","preview","target","closest","buildModal","catch","Notification","exception","async","description","element","getAttribute","themesContainer","getElementById","definedInConfig","parseInt","dataset","definedinconfig","data","name","image","replace","current","actionurl","choose","sesskey","modalTemplate","ModalSaveCancel","ModalCancel","modal","create","title","body","Templates","render","large","buttons","show","getRoot","on","ModalEvents","save","find","submit"],"mappings":";;;;;;;gWA8BMA,2BACgB,YADhBA,kBAEO,wCAQO,KAChBC,gCAQEA,uBAAyB,KAC3BC,SAASC,iBAAiB,SAAUC,UAC1BC,QAAUD,EAAEE,OAAOC,QAAQP,mBAC7BK,SACAG,WAAWH,SAASI,MAAMC,sBAAaC,eAW7CH,WAAaI,MAAAA,cAGXC,kBAAoB,kBAAU,eAAgB,SAAWC,QAAQC,aAAa,sBAE5EC,gBAAkBd,SAASe,eAAejB,4BAC1CkB,gBAAkBC,SAASH,gBAAgBI,QAAQC,iBAEnDC,KAAO,CACTC,KAAMT,QAAQC,aAAa,aAC3BS,MAAOV,QAAQC,aAAa,cAC5BF,YAAaA,YAAYY,QAAQ,WAAY,KAC7CC,QAASZ,QAAQC,aAAa,gBAC9BY,UAAWb,QAAQC,aAAa,kBAChCa,OAAQd,QAAQC,aAAa,eAC7Bc,QAASf,QAAQC,aAAa,gBAC9BM,gBAAiBH,qBAIjBY,cAAgBC,4BAChBT,KAAKI,SAAWJ,KAAKD,mBACrBS,cAAgBE,6BAGdC,YAAcH,cAAcI,OAAO,CACrCC,MAAOb,KAAKC,KACZa,KAAMC,mBAAUC,OAAO,+CAAgDhB,MACvEiB,OAAO,EACPC,QAAS,OACG,kBAAU,cAAe,kBACvB,kBAAU,mBAAoB,WAE5CC,MAAM,IAGVR,MAAMS,UAAUC,GAAGC,sBAAYC,MAAM,KACjCZ,MAAMS,UAAUI,KAAK,QAAQC"}
-72
View File
@@ -1,72 +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 PluginManagementTable from './plugin_management_table';
import {refreshTableContent} from 'core_table/dynamic';
import {call as fetchMany} from 'core/ajax';
import Pending from 'core/pending';
import {fetchNotifications} from 'core/notification';
export default class extends PluginManagementTable {
constructor() {
super();
this.addClickHandler(this.handleBlockProtectToggle);
}
/**
* Set the block protection state.
*
* @param {string} plugin
* @param {number} state
* @returns {Promise}
*/
setBlockProtectState(plugin, state) {
return fetchMany([{
methodname: 'core_admin_set_block_protection',
args: {
plugin,
state,
},
}])[0];
}
/**
* Handle toggling of block protection.
*
* @param {HTMLElement} tableRoot
* @param {Event} e
*/
async handleBlockProtectToggle(tableRoot, e) {
const stateToggle = e.target.closest('[data-action="toggleprotectstate"]');
if (stateToggle) {
e.preventDefault();
const pendingPromise = new Pending('core_table/dynamic:processAction');
await this.setBlockProtectState(
stateToggle.dataset.plugin,
stateToggle.dataset.targetState === '1' ? 1 : 0
);
const [updatedRoot] = await Promise.all([
refreshTableContent(tableRoot),
fetchNotifications(),
]);
// Refocus on the link that as pressed in the first place.
updatedRoot.querySelector(`[data-action="toggleprotectstate"][data-plugin="${stateToggle.dataset.plugin}"]`).focus();
pendingPromise.resolve();
}
}
}
-97
View File
@@ -1,97 +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/>.
/**
* Add bulk actions to the users list report
*
* @module core_admin/bulk_user_actions
* @copyright 2024 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import * as reportSelectors from 'core_reportbuilder/local/selectors';
import * as tableEvents from 'core_table/local/dynamic/events';
import * as FormChangeChecker from 'core_form/changechecker';
import * as CustomEvents from 'core/custom_interaction_events';
import jQuery from 'jquery';
const Selectors = {
bulkActionsForm: 'form#user-bulk-action-form',
userReportWrapper: '[data-region="report-user-list-wrapper"]',
checkbox: 'input[type="checkbox"][data-togglegroup="report-select-all"][data-toggle="slave"]',
masterCheckbox: 'input[type="checkbox"][data-togglegroup="report-select-all"][data-toggle="master"]',
checkedRows: '[data-togglegroup="report-select-all"][data-toggle="slave"]:checked',
};
/**
* Initialise module
*/
export const init = () => {
const userBulkForm = document.querySelector(Selectors.bulkActionsForm);
const userReport = userBulkForm?.closest(Selectors.userReportWrapper)?.querySelector(reportSelectors.regions.report);
if (!userBulkForm || !userReport) {
return;
}
const actionSelect = userBulkForm.querySelector('select');
CustomEvents.define(actionSelect, [CustomEvents.events.accessibleChange]);
jQuery(actionSelect).on(CustomEvents.events.accessibleChange, event => {
if (event.target.value && `${event.target.value}` !== "0") {
const e = new Event('submit', {cancelable: true});
userBulkForm.dispatchEvent(e);
if (!e.defaultPrevented) {
FormChangeChecker.markFormSubmitted(userBulkForm);
userBulkForm.submit();
}
}
});
// Every time the checkboxes in the report are changed, update the list of users in the form values
// and enable/disable the action select.
const updateUserIds = () => {
const selectedUsers = [...userReport.querySelectorAll(Selectors.checkedRows)];
const selectedUserIds = selectedUsers.map(check => parseInt(check.value));
userBulkForm.querySelector('[name="userids"]').value = selectedUserIds.join(',');
// Disable the action selector if nothing selected, and reset the current selection.
actionSelect.disabled = selectedUsers.length === 0;
if (actionSelect.disabled) {
actionSelect.value = "0";
}
const selectedUsersNames = selectedUsers.map(check => document.querySelector(`label[for="${check.id}"]`).textContent);
// Add the user ids and names to the form data attributes so they can be available from the
// other JS modules that listen to the form submit event.
userBulkForm.data = {userids: selectedUserIds, usernames: selectedUsersNames};
};
updateUserIds();
document.addEventListener('change', event => {
// When checkboxes are checked next to individual users or the master toggle (Select all/none).
if ((event.target.matches(Selectors.checkbox) || event.target.matches(Selectors.masterCheckbox))
&& userReport.contains(event.target)) {
updateUserIds();
}
});
document.addEventListener(tableEvents.tableContentRefreshed, event => {
// When the report contents is updated (i.e. page is changed, filters applied, etc).
if (userReport.contains(event.target)) {
updateUserIds();
}
});
};
-74
View File
@@ -1,74 +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/>.
/**
* Expand the collapse section element.
*
* @module core_admin/expand_hash
* @copyright Meirza <meirza.arson@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 4.5
*/
const SELECTORS = {
COLLAPSE_ELEMENTS: '[data-toggle="collapse"]',
FOCUSTHENEXPAND_ELEMENTS: '.focus-expand',
};
/**
* Initializes the focus and expand functionality.
*/
export const init = () => {
// Select all collapsible elements only.
const focusexpand = document.querySelector(SELECTORS.FOCUSTHENEXPAND_ELEMENTS);
// Add click event listener to the anchor element
focusexpand?.addEventListener('click', () => {
expandSection(`${focusexpand.getAttribute('href')}`);
});
};
/**
* Expands a section based on the provided URL hash.
*
* This function takes a hash string, finds the corresponding element in the DOM,
* and expands it if it is currently collapsed. It updates the necessary ARIA
* attributes and classes to reflect the expanded state.
*
* @param {string} hash - The hash (e.g., '#elementId') of the element to expand.
*/
export const expandSection = (hash) => {
const container = document.querySelector(hash);
const targetContainer = container?.querySelector(SELECTORS.COLLAPSE_ELEMENTS);
if (targetContainer?.getAttribute('aria-expanded') === 'false') {
const collapseId = targetContainer.getAttribute('aria-controls');
const collapseContainer = document.getElementById(collapseId);
// Show the content.
collapseContainer.classList.remove('collapse');
collapseContainer.classList.add('show');
// Update aria-expanded attribute to reflect the new state.
targetContainer.setAttribute('aria-expanded', 'true');
targetContainer.classList.remove('collapsed');
// Get collapse expand menu element.
const collapseElement = document.querySelector('.collapseexpand.collapsemenu');
// Ensure it gets noticed to make it work.
collapseElement.setAttribute('aria-expanded', 'true');
collapseElement.classList.remove('collapsed');
}
};
-195
View File
@@ -1,195 +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 {refreshTableContent} from 'core_table/dynamic';
import * as Selectors from 'core_table/local/dynamic/selectors';
import {call as fetchMany} from 'core/ajax';
import Pending from 'core/pending';
import {fetchNotifications} from 'core/notification';
let watching = false;
export default class {
/**
* @property {function[]} clickHandlers a list of handlers to call on click.
*/
clickHandlers = [];
constructor() {
this.addClickHandler(this.handleStateToggle);
this.addClickHandler(this.handleMoveUpDown);
this.registerEventListeners();
}
/**
* Initialise an instance of the class.
*
* This is just a way of making it easier to initialise an instance of the class from PHP.
*/
static init() {
if (watching) {
return;
}
watching = true;
new this();
}
/**
* Add a click handler to the list of handlers.
*
* @param {Function} handler A handler to call on a click event
*/
addClickHandler(handler) {
this.clickHandlers.push(handler.bind(this));
}
/**
* Register the event listeners for this instance.
*/
registerEventListeners() {
document.addEventListener('click', function(e) {
const tableRoot = this.getTableRoot(e);
if (!tableRoot) {
return;
}
this.clickHandlers.forEach((handler) => handler(tableRoot, e));
}.bind(this));
}
/**
* Get the table root from an event.
*
* @param {Event} e
* @returns {HTMLElement|bool}
*/
getTableRoot(e) {
const tableRoot = e.target.closest(Selectors.main.region);
if (!tableRoot) {
return false;
}
return tableRoot;
}
/**
* Set the plugin state (enabled or disabled)
*
* @param {string} methodname The web service to call
* @param {string} plugin The name of the plugin to set the state for
* @param {number} state The state to set
* @returns {Promise}
*/
setPluginState(methodname, plugin, state) {
return fetchMany([{
methodname,
args: {
plugin,
state,
},
}])[0];
}
setPluginOrder(methodname, plugin, direction) {
return fetchMany([{
methodname,
args: {
plugin,
direction,
},
}])[0];
}
/**
* Handle state toggling.
*
* @param {HTMLElement} tableRoot
* @param {Event} e
*/
async handleStateToggle(tableRoot, e) {
const stateToggle = e.target.closest('[data-action="togglestate"][data-toggle-method]');
if (stateToggle) {
e.preventDefault();
const pendingPromise = new Pending('core_table/dynamic:togglestate');
await this.setPluginState(
stateToggle.dataset.toggleMethod,
stateToggle.dataset.plugin,
stateToggle.dataset.state === '1' ? 0 : 1
);
const [updatedRoot] = await Promise.all([
refreshTableContent(tableRoot),
fetchNotifications(),
]);
// Refocus on the link that as pressed in the first place.
updatedRoot.querySelector(`[data-action="togglestate"][data-plugin="${stateToggle.dataset.plugin}"]`).focus();
// When clicking the toggle and it remains focused, a new tooltip will be generated.
// Therefore, the old tooltip should be removed.
this.removeTooltips();
pendingPromise.resolve();
}
}
async handleMoveUpDown(tableRoot, e) {
const actionLink = e.target.closest('[data-action="move"][data-method][data-direction]');
if (!actionLink) {
return;
}
e.preventDefault();
const pendingPromise = new Pending('core_table/dynamic:processAction');
await this.setPluginOrder(
actionLink.dataset.method,
actionLink.dataset.plugin,
actionLink.dataset.direction === 'up' ? -1 : 1,
);
const [updatedRoot] = await Promise.all([
refreshTableContent(tableRoot),
fetchNotifications(),
]);
// Refocus on the link that as pressed in the first place.
const exactMatch = updatedRoot.querySelector(
`[data-action="move"][data-plugin="${actionLink.dataset.plugin}"][data-direction="${actionLink.dataset.direction}"]`
);
if (exactMatch) {
exactMatch.focus();
} else {
// The move link is not present anymore, so we need to focus on the other one.
updatedRoot.querySelector(`[data-action="move"][data-plugin="${actionLink.dataset.plugin}"]`)?.focus();
}
pendingPromise.resolve();
}
/**
* Remove tooltips.
*/
removeTooltips() {
const tooltips = document.querySelectorAll('[id*="tooltip"]');
if (tooltips.length > 0) {
tooltips.forEach(tooltip => {
tooltip.remove();
});
}
}
}
-82
View File
@@ -1,82 +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/>.
/**
* Allows to filter the plugin list on plugins overview page
*
* @module core_admin/plugins_overview
* @copyright 2024 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
const SELECTORS = {
PLUGIN_FILTERS: '#plugins-overview-panel [data-filterby]',
PLUGIN_ROWS: 'table#plugins-control-panel tbody tr:not(.plugintypeheader)',
PLUGIN_TYPE_ROWS: 'table#plugins-control-panel tbody tr.plugintypeheader',
};
/**
* Initialise filters for the "Plugins overview" page
*/
export function init() {
const filters = document.querySelectorAll(SELECTORS.PLUGIN_FILTERS);
const pluginRows = document.querySelectorAll(SELECTORS.PLUGIN_ROWS);
const pluginTypeRows = document.querySelectorAll(SELECTORS.PLUGIN_TYPE_ROWS);
const filterPlugins = (target) => {
const filterBy = target.getAttribute('data-filterby');
const headerVisibility = {};
// Hide all plugin rows in the plugin table that do not match the filter and show all others.
for (const row of pluginRows) {
const type = [...row.classList].find(s => s.startsWith('type-'));
const visible = filterBy === 'all' ? true : row.classList.contains(filterBy);
row.style.display = visible ? null : 'none';
if (visible && type) {
headerVisibility[type] = true;
}
}
// Hide all the plugin type headers that do not have any visible plugins and show all others.
for (const row of pluginTypeRows) {
const type = [...row.classList].find(s => s.startsWith('type-'));
if (type) {
const visible = filterBy === 'all' || headerVisibility[type];
row.style.display = visible ? null : 'none';
}
}
// Toggle 'active' class for the selected filter.
filters.forEach(el => el.classList.remove('active'));
target.classList.add('active');
};
// Add event listeners for the links changing plugins filters.
filters
.forEach(target => target.addEventListener('click', (e) => {
e.preventDefault();
window.history.replaceState({}, null, e.target.href);
filterPlugins(target);
}));
// Pre-filter plugins based on the current url anchor.
if (window.location.hash.length > 1) {
const anchor = window.location.hash.substring(1);
const target = [...filters].find(t => t.getAttribute('data-filterby') === anchor);
if (target) {
filterPlugins(target);
}
}
}
@@ -1,104 +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/>.
/**
* Modal for theme previews.
*
* @module core_admin/themeselector/preview_modal
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import ModalEvents from 'core/modal_events';
import ModalCancel from 'core/modal_cancel';
import ModalSaveCancel from 'core/modal_save_cancel';
import Notification from 'core/notification';
import Templates from 'core/templates';
import {getString} from 'core/str';
const SELECTORS = {
THEMES_CONTAINER: 'themelist',
PREVIEW: '[data-action="preview"]',
};
/**
* Entrypoint of the js.
*
* @method init
*/
export const init = () => {
registerListenerEvents();
};
/**
* Register theme related event listeners.
*
* @method registerListenerEvents
*/
const registerListenerEvents = () => {
document.addEventListener('click', (e) => {
const preview = e.target.closest(SELECTORS.PREVIEW);
if (preview) {
buildModal(preview).catch(Notification.exception);
}
});
};
/**
* Build the modal with the provided data.
*
* @method buildModal
* @param {object} element
*/
const buildModal = async(element) => {
// This string can be long. We will fetch it with JS as opposed to passing it as an attribute.
let description = await getString('choosereadme', 'theme_' + element.getAttribute('data-choose'));
const themesContainer = document.getElementById(SELECTORS.THEMES_CONTAINER);
const definedInConfig = parseInt(themesContainer.dataset.definedinconfig);
// Prepare data for modal.
const data = {
name: element.getAttribute('data-name'),
image: element.getAttribute('data-image'),
description: description.replace(/<[^>]+>/g, ' '), // Strip out HTML tags.
current: element.getAttribute('data-current'),
actionurl: element.getAttribute('data-actionurl'),
choose: element.getAttribute('data-choose'),
sesskey: element.getAttribute('data-sesskey'),
definedinconfig: definedInConfig,
};
// Determine which modal template we should use.
let modalTemplate = ModalSaveCancel;
if (data.current || data.definedinconfig) {
modalTemplate = ModalCancel;
}
const modal = await modalTemplate.create({
title: data.name,
body: Templates.render('core_admin/themeselector/theme_preview_modal', data),
large: true,
buttons: {
'save': getString('selecttheme', 'moodle'),
'cancel': getString('closebuttontitle', 'moodle'),
},
show: true,
});
modal.getRoot().on(ModalEvents.save, () => {
modal.getRoot().find('form').submit();
});
};
+210
View File
@@ -0,0 +1,210 @@
<?php
/**
* Edit configuration for an individual auth plugin
*/
require_once '../config.php';
require_once $CFG->libdir.'/adminlib.php';
$auth = required_param('auth', PARAM_PLUGIN);
$PAGE->set_pagetype('admin-auth-' . $auth);
admin_externalpage_setup('authsetting'.$auth);
$authplugin = get_auth_plugin($auth);
$err = array();
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=manageauths";
debugging("Use of config.html files in authentication plugins have been deprecated. " .
" Please migrate your plugin to use the admin settings API", DEBUG_DEVELOPER);
// save configuration changes
if ($frm = data_submitted() and confirm_sesskey()) {
$authplugin->validate_form($frm, $err);
if (count($err) == 0) {
// save plugin config
if ($authplugin->process_config($frm)) {
// save field lock configuration
foreach ($frm as $name => $value) {
if (preg_match('/^lockconfig_(.+?)$/', $name, $matches)) {
$plugin = "auth/$auth";
$name = $matches[1];
set_config($name, $value, $plugin);
}
}
redirect($returnurl);
exit;
}
} else {
foreach ($err as $key => $value) {
$focus = "form.$key";
}
}
} else {
$frmlegacystyle = get_config('auth/'.$auth);
$frmnewstyle = get_config('auth_'.$auth);
$frm = (object)array_merge((array)$frmlegacystyle, (array)$frmnewstyle);
}
$user_fields = $authplugin->userfields;
//$user_fields = array("firstname", "lastname", "email", "phone1", "phone2", "institution", "department", "address", "city", "country", "description", "idnumber", "lang");
/// Get the auth title (from core or own auth lang files)
$authtitle = $authplugin->get_title();
/// Get the auth descriptions (from core or own auth lang files)
$authdescription = $authplugin->get_description();
// output configuration form
echo $OUTPUT->header();
// choose an authentication method
echo "<form id=\"authmenu\" method=\"post\" action=\"auth_config.php\">\n";
echo "<div>\n";
echo "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />\n";
echo "<input type=\"hidden\" name=\"auth\" value=\"".$auth."\" />\n";
// auth plugin description
echo $OUTPUT->box_start();
echo $OUTPUT->heading($authtitle);
echo $OUTPUT->box_start('informationbox');
echo $authdescription;
echo $OUTPUT->box_end();
echo "<hr />\n";
$authplugin->config_form($frm, $err, $user_fields);
echo $OUTPUT->box_end();
echo '<p style="text-align: center"><input type="submit" value="' . get_string("savechanges") . "\" /></p>\n";
echo "</div>\n";
echo "</form>\n";
$PAGE->requires->string_for_js('unmaskpassword', 'core_form');
$PAGE->requires->yui_module('moodle-auth-passwordunmask', 'M.auth.passwordunmask');
echo $OUTPUT->footer();
exit;
/// Functions /////////////////////////////////////////////////////////////////
/**
* auth field locking
* Good enough for most auth plugins
* but some may want a custom one if they are offering
* other options
* Note: lockconfig_ fields have special handling.
*
* @param string $auth authentication plugin shortname
* @param array $user_fields user profile fields
* @param string $helptext help text to be displayed at top of form
* @param boolean $retrieveopts Map fields or lock only.
* @param boolean $updateopts Allow remote updates
* @param array $customfields list of custom profile fields
* @deprecated since Moodle 3.3
*/
function print_auth_lock_options($auth, $user_fields, $helptext, $retrieveopts, $updateopts, $customfields = array()) {
global $DB, $OUTPUT;
debugging("The function 'print_auth_lock_options' has been deprecated, " .
"Please migrate your code to use the admin settings API and use the function 'display_auth_lock_options' instead. ",
DEBUG_DEVELOPER);
echo '<tr><td colspan="3">';
if ($retrieveopts) {
echo $OUTPUT->heading(get_string('auth_data_mapping', 'auth'));
} else {
echo $OUTPUT->heading(get_string('auth_fieldlocks', 'auth'));
}
echo '</td></tr>';
$lockoptions = array ('unlocked' => get_string('unlocked', 'auth'),
'unlockedifempty' => get_string('unlockedifempty', 'auth'),
'locked' => get_string('locked', 'auth'));
$updatelocaloptions = array('oncreate' => get_string('update_oncreate', 'auth'),
'onlogin' => get_string('update_onlogin', 'auth'));
$updateextoptions = array('0' => get_string('update_never', 'auth'),
'1' => get_string('update_onupdate', 'auth'));
$pluginconfig = get_config("auth/$auth");
// Helptext is on a field with rowspan.
if (empty($helptext)) {
$helptext = '&nbsp;';
}
// If we have custom fields then merge them with user fields.
if (!empty($customfields)) {
$user_fields = array_merge($user_fields, $customfields);
}
if (!empty($customfields)) {
$customfieldname = $DB->get_records('user_info_field', null, '', 'shortname, name');
}
foreach ($user_fields as $field) {
// Define some vars we'll work with.
if (!isset($pluginconfig->{"field_map_$field"})) {
$pluginconfig->{"field_map_$field"} = '';
}
if (!isset($pluginconfig->{"field_updatelocal_$field"})) {
$pluginconfig->{"field_updatelocal_$field"} = '';
}
if (!isset($pluginconfig->{"field_updateremote_$field"})) {
$pluginconfig->{"field_updateremote_$field"} = '';
}
if (!isset($pluginconfig->{"field_lock_$field"})) {
$pluginconfig->{"field_lock_$field"} = '';
}
// Define the fieldname we display to the user.
$fieldname = $field;
if ($fieldname === 'lang') {
$fieldname = get_string('language');
} elseif (!empty($customfields) && in_array($field, $customfields)) {
// If custom field then pick name from database.
$fieldshortname = str_replace('profile_field_', '', $fieldname);
$fieldname = $customfieldname[$fieldshortname]->name;
if (core_text::strlen($fieldshortname) > 67) {
// If custom profile field name is longer than 67 characters we will not be able to store the setting
// such as 'field_updateremote_profile_field_NOTSOSHORTSHORTNAME' in the database because the character
// limit for the setting name is 100.
continue;
}
} else {
$fieldname = get_string($fieldname);
}
if ($retrieveopts) {
$varname = 'field_map_' . $field;
echo '<tr valign="top"><td align="right">';
echo '<label for="lockconfig_'.$varname.'">'.$fieldname.'</label>';
echo '</td><td>';
echo "<input id=\"lockconfig_{$varname}\" name=\"lockconfig_{$varname}\" type=\"text\" size=\"30\" value=\"{$pluginconfig->$varname}\" />";
echo '<div style="text-align: right">';
echo '<label for="menulockconfig_field_updatelocal_'.$field.'">'.get_string('auth_updatelocal', 'auth') . '</label>&nbsp;';
echo html_writer::select($updatelocaloptions, "lockconfig_field_updatelocal_{$field}", $pluginconfig->{"field_updatelocal_$field"}, false);
echo '<br />';
if ($updateopts) {
echo '<label for="menulockconfig_field_updateremote_'.$field.'">'.get_string('auth_updateremote', 'auth') . '</label>&nbsp;';
echo html_writer::select($updateextoptions, "lockconfig_field_updateremote_{$field}", $pluginconfig->{"field_updateremote_$field"}, false);
echo '<br />';
}
echo '<label for="menulockconfig_field_lock_'.$field.'">'.get_string('auth_fieldlock', 'auth') . '</label>&nbsp;';
echo html_writer::select($lockoptions, "lockconfig_field_lock_{$field}", $pluginconfig->{"field_lock_$field"}, false);
echo '</div>';
} else {
echo '<tr valign="top"><td align="right">';
echo '<label for="menulockconfig_field_lock_'.$field.'">'.$fieldname.'</label>';
echo '</td><td>';
echo html_writer::select($lockoptions, "lockconfig_field_lock_{$field}", $pluginconfig->{"field_lock_$field"}, false);
}
echo '</td>';
if (!empty($helptext)) {
echo '<td rowspan="' . count($user_fields) . '">' . $helptext . '</td>';
$helptext = '';
}
echo '</tr>';
}
}
+222 -77
View File
@@ -1,94 +1,239 @@
<?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/>.
/**
* Allows the admin to configure blocks (hide/show, uninstall and configure)
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// Allows the admin to configure blocks (hide/show, uninstall and configure)
require_once('../config.php');
require_once("{$CFG->libdir}/adminlib.php");
require_once("{$CFG->libdir}/blocklib.php");
require_once("{$CFG->libdir}/tablelib.php");
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/blocklib.php');
require_once($CFG->libdir.'/tablelib.php');
admin_externalpage_setup('manageblocks');
admin_externalpage_setup('manageblocks');
$plugin = optional_param('plugin', '', PARAM_PLUGIN);
$action = optional_param('action', '', PARAM_ALPHA);
$unprotect = optional_param('unprotect', 0, PARAM_PLUGIN);
$protect = optional_param('protect', 0, PARAM_PLUGIN);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$hide = optional_param('hide', 0, PARAM_INT);
$show = optional_param('show', 0, PARAM_INT);
$unprotect = optional_param('unprotect', 0, PARAM_INT);
$protect = optional_param('protect', 0, PARAM_INT);
$strmanageblocks = get_string('manageblocks');
/// Print headings
// If data submitted, then process and store.
if (!empty($plugin) && !empty($action) && confirm_sesskey()) {
$manager = \core_plugin_manager::resolve_plugininfo_class('block');
$pluginname = get_string('pluginname', "block_{$plugin}");
$strmanageblocks = get_string('manageblocks');
$struninstall = get_string('uninstallplugin', 'core_admin');
$strversion = get_string('version');
$strhide = get_string('hide');
$strshow = get_string('show');
$strsettings = get_string('settings');
$strcourses = get_string('blockinstances', 'admin');
$strname = get_string('name');
$strshowblockcourse = get_string('showblockcourse');
$strprotecthdr = get_string('blockprotect', 'admin'). $OUTPUT->help_icon('blockprotect','admin');
$strprotect = get_string('blockprotect', 'admin');
$strunprotect = get_string('blockunprotect', 'admin');
if ($action === 'disable' && $manager::enable_plugin($plugin, 0)) {
\core\notification::add(
get_string('plugin_disabled', 'core_admin', $pluginname),
\core\notification::SUCCESS
);
// Settings not required - only pages.
admin_get_root(true, false);
} else if ($action === 'enable' && $manager::enable_plugin($plugin, 1)) {
\core\notification::add(
get_string('plugin_enabled', 'core_admin', $pluginname),
\core\notification::SUCCESS
);
// If data submitted, then process and store.
if (!empty($hide) && confirm_sesskey()) {
if (!$block = $DB->get_record('block', ['id' => $hide])) {
throw new \moodle_exception('blockdoesnotexist', 'error');
}
$class = \core_plugin_manager::resolve_plugininfo_class('block');
$class::enable_plugin($block->name, false);
// Settings not required - only pages.
admin_get_root(true, false);
}
// Redirect back to the page with out any params.
redirect(new moodle_url('/admin/blocks.php'));
}
if (!empty($show) && confirm_sesskey() ) {
if (!$block = $DB->get_record('block', ['id' => $show])) {
throw new \moodle_exception('blockdoesnotexist', 'error');
}
if (!empty($protect) && confirm_sesskey()) {
block_manager::protect_block($protect);
$pluginname = get_string('pluginname', "block_{$protect}");
\core\notification::add(
get_string('blockprotected', 'core_admin', $pluginname),
\core\notification::SUCCESS
);
// Settings not required - only pages.
admin_get_root(true, false);
}
$class = \core_plugin_manager::resolve_plugininfo_class('block');
$class::enable_plugin($block->name, true);
// Settings not required - only pages.
admin_get_root(true, false);
}
if (!empty($unprotect) && confirm_sesskey()) {
block_manager::unprotect_block($unprotect);
$pluginname = get_string('pluginname', "block_{$unprotect}");
\core\notification::add(
get_string('blockunprotected', 'core_admin', $pluginname),
\core\notification::SUCCESS
);
// Settings not required - only pages.
admin_get_root(true, false);
}
if (!empty($protect) && confirm_sesskey()) {
block_manager::protect_block((int)$protect);
admin_get_root(true, false); // settings not required - only pages
}
echo $OUTPUT->header();
echo $OUTPUT->heading($strmanageblocks);
echo $OUTPUT->notification(get_string('noteunneededblocks', 'admin'), 'info', false);
if (!empty($unprotect) && confirm_sesskey()) {
block_manager::unprotect_block((int)$unprotect);
admin_get_root(true, false); // settings not required - only pages
}
// Print the table of all blocks.
$table = new \core_admin\table\block_management_table();
$table->out();
echo $OUTPUT->footer();
$undeletableblocktypes = block_manager::get_undeletable_block_types();
echo $OUTPUT->header();
echo $OUTPUT->heading($strmanageblocks);
echo $OUTPUT->notification(get_string('noteunneededblocks', 'admin'), 'info');
/// Main display starts here
/// Get and sort the existing blocks
if (!$blocks = $DB->get_records('block', array(), 'name ASC')) {
throw new \moodle_exception('noblocks', 'error'); // Should never happen.
}
$incompatible = array();
/// Print the table of all blocks
$table = new flexible_table('admin-blocks-compatible');
$table->define_columns(array('name', 'instances', 'version', 'hideshow', 'undeletable', 'settings', 'uninstall'));
$table->define_headers(array($strname, $strcourses, $strversion, $strhide.'/'.$strshow, $strprotecthdr, $strsettings, $struninstall));
$table->define_baseurl($CFG->wwwroot.'/'.$CFG->admin.'/blocks.php');
$table->set_attribute('class', 'admintable blockstable generaltable');
$table->set_attribute('id', 'compatibleblockstable');
$table->setup();
$tablerows = array();
// Sort blocks using current locale.
$blocknames = array();
foreach ($blocks as $blockid=>$block) {
$blockname = $block->name;
if (file_exists("$CFG->dirroot/blocks/$blockname/block_$blockname.php")) {
$blocknames[$blockid] = get_string('pluginname', 'block_'.$blockname);
} else {
$blocknames[$blockid] = $blockname;
}
}
core_collator::asort($blocknames);
foreach ($blocknames as $blockid=>$strblockname) {
$block = $blocks[$blockid];
$blockname = $block->name;
$dbversion = get_config('block_'.$block->name, 'version');
if (!file_exists("$CFG->dirroot/blocks/$blockname/block_$blockname.php")) {
$blockobject = false;
$strblockname = '<span class="notifyproblem">'.$strblockname.' ('.get_string('missingfromdisk').')</span>';
$plugin = new stdClass();
$plugin->version = $dbversion;
} else {
$plugin = new stdClass();
$plugin->version = '???';
if (file_exists("$CFG->dirroot/blocks/$blockname/version.php")) {
include("$CFG->dirroot/blocks/$blockname/version.php");
}
if (!$blockobject = block_instance($block->name)) {
$incompatible[] = $block;
continue;
}
}
if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('block_'.$blockname, 'manage')) {
$uninstall = html_writer::link($uninstallurl, $struninstall);
} else {
$uninstall = '';
}
$settings = ''; // By default, no configuration
if ($blockobject and $blockobject->has_config()) {
$blocksettings = admin_get_root()->locate('blocksetting' . $block->name);
if ($blocksettings instanceof admin_externalpage) {
$settings = '<a href="' . $blocksettings->url . '">' . get_string('settings') . '</a>';
} else if ($blocksettings instanceof admin_settingpage) {
$settings = '<a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section=blocksetting'.$block->name.'">'.$strsettings.'</a>';
} else if (!file_exists($CFG->dirroot.'/blocks/'.$block->name.'/settings.php')) {
// If the block's settings node was not found, we check that the block really provides the settings.php file.
// Note that blocks can inject their settings to other nodes in the admin tree without using the default locations.
// This can be done by assigning null to $setting in settings.php and it is a valid case.
debugging('Warning: block_'.$block->name.' returns true in has_config() but does not provide a settings.php file',
DEBUG_DEVELOPER);
}
}
// MDL-11167, blocks can be placed on mymoodle, or the blogs page
// and it should not show up on course search page
$totalcount = $DB->count_records('block_instances', array('blockname'=>$blockname));
$count = $DB->count_records('block_instances', array('blockname'=>$blockname, 'pagetypepattern'=>'course-view-*'));
if ($count>0) {
$blocklist = "<a href=\"{$CFG->wwwroot}/course/search.php?blocklist=$blockid&amp;sesskey=".sesskey()."\" ";
$blocklist .= "title=\"$strshowblockcourse\" >$totalcount</a>";
}
else {
$blocklist = "$totalcount";
}
$class = ''; // Nothing fancy, by default
if (!$blockobject) {
// ignore
$visible = '';
} else if ($blocks[$blockid]->visible) {
$visible = '<a href="blocks.php?hide='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strhide.'">'.
$OUTPUT->pix_icon('t/hide', $strhide) . '</a>';
} else {
$visible = '<a href="blocks.php?show='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strshow.'">'.
$OUTPUT->pix_icon('t/show', $strshow) . '</a>';
$class = 'dimmed_text';
}
if ($dbversion == $plugin->version) {
$version = $dbversion;
} else {
$version = "$dbversion ($plugin->version)";
}
if (!$blockobject) {
// ignore
$undeletable = '';
} else if (in_array($blockname, $undeletableblocktypes)) {
$undeletable = '<a href="blocks.php?unprotect='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strunprotect.'">'.
$OUTPUT->pix_icon('t/unlock', $strunprotect) . '</a>';
} else {
$undeletable = '<a href="blocks.php?protect='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strprotect.'">'.
$OUTPUT->pix_icon('t/lock', $strprotect) . '</a>';
}
$row = array(
$strblockname,
$blocklist,
$version,
$visible,
$undeletable,
$settings,
$uninstall,
);
$table->add_data($row, $class);
}
$table->print_html();
if (!empty($incompatible)) {
echo $OUTPUT->heading(get_string('incompatibleblocks', 'blockstable', 'admin'));
$table = new flexible_table('admin-blocks-incompatible');
$table->define_columns(array('block', 'uninstall'));
$table->define_headers(array($strname, $struninstall));
$table->define_baseurl($CFG->wwwroot.'/'.$CFG->admin.'/blocks.php');
$table->set_attribute('class', 'incompatibleblockstable generaltable');
$table->setup();
foreach ($incompatible as $block) {
if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('block_'.$block->name, 'manage')) {
$uninstall = html_writer::link($uninstallurl, $struninstall);
} else {
$uninstall = '';
}
$table->add_data(array(
$block->name,
$uninstall,
));
}
$table->print_html();
}
echo $OUTPUT->footer();
+2 -5
View File
@@ -118,10 +118,6 @@ foreach ($settingspage->children as $childpage) {
}
$outputhtml .= html_writer::tag('div', '<!-- -->', array('class' => 'clearer'));
$outputhtml .= $setting->output_html($data);
if ($childpage->has_dependencies()) {
$opts = ['dependencies' => $childpage->get_dependencies_for_javascript()];
$PAGE->requires->js_call_amd('core/showhidesettings', 'init', [$opts]);
}
}
$outputhtml .= html_writer::end_tag('fieldset');
}
@@ -135,7 +131,8 @@ if ($savebutton) {
$outputhtml .= html_writer::end_tag('div');
}
$PAGE->set_title(implode(moodle_page::TITLE_SEPARATOR, $settingspage->visiblepath));
$visiblepathtosection = array_reverse($settingspage->visiblepath);
$PAGE->set_title("$SITE->shortname: " . implode(": ",$visiblepathtosection));
$PAGE->set_heading($SITE->fullname);
if ($buttons) {
$PAGE->set_button($buttons);
@@ -1,127 +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/>.
namespace core_admin\admin;
use admin_setting;
use core_plugin_manager;
use core_text;
/**
* Admin setting plugin manager.
*
* @package core_admin
* @subpackage admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class admin_setting_plugin_manager extends admin_setting {
/** @var core_plugin_manager The plugin manager instance */
protected core_plugin_manager $pluginmanager;
/** @var string The plugintype that this manager covers */
protected string $plugintype;
/** @var string The class of the management table to use */
protected string $tableclass;
public function __construct(
string $plugintype,
string $tableclass,
string $name,
string $visiblename,
string $description = '',
string $defaultsetting = '',
) {
$this->nosave = true;
$this->pluginmanager = core_plugin_manager::instance();
$this->plugintype = $plugintype;
$this->tableclass = $tableclass;
parent::__construct($name, $visiblename, $description, $defaultsetting);
}
/**
* Always returns true, does nothing
*
* @return true
*/
public function get_setting(): bool {
return true;
}
/**
* Always returns true, does nothing
*
* @return true
*/
public function get_defaultsetting(): bool {
return true;
}
/**
* Always returns '', does not write anything
*
* @return string Always returns ''
*/
// phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
public function write_setting($data): string {
// Do not write any setting.
return '';
}
/**
* Checks if $query is one of the available editors
*
* @param string $query The string to search for
* @return bool Returns true if found, false if not
*/
public function is_related($query) {
if (parent::is_related($query)) {
return true;
}
$plugins = $this->pluginmanager->get_installed_plugins($this->plugintype);
foreach (array_keys($plugins) as $plugin) {
$plugin = "{$this->plugintype}_{$plugin}";
if (str_contains($plugin, $query)) {
return true;
}
$pluginname = get_string('pluginname', $plugin);
if (strpos(core_text::strtolower($pluginname), $query) !== false) {
return true;
}
}
return false;
}
/**
* Builds the XHTML to display the control
*
* @param string $data Unused
* @param string $query
* @return string
*/
public function output_html($data, $query = ''): string {
$table = new $this->tableclass();
if (!($table instanceof \core_admin\table\plugin_management_table)) {
throw new \coding_exception("{$this->tableclass} must be an instance of \\core_admin\\table\\plugin_management_table");
}
return highlight($query, $table->get_content());
}
}
-97
View File
@@ -1,97 +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/>.
namespace core_admin\external;
use block_manager;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
/**
* Web Service to control the state of a plugin.
*
* @package core_admin
* @category external
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class set_block_protection extends external_api {
/**
* Returns description of method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'plugin' => new external_value(PARAM_PLUGIN, 'The name of the plugin', VALUE_REQUIRED),
'state' => new external_value(PARAM_INT, 'The target state', VALUE_REQUIRED),
]);
}
/**
* Set the block protection state.
*
* @param string $plugin The name of the plugin
* @param int $state The target state
* @return null
*/
public static function execute(
string $plugin,
int $state,
): array {
[
'plugin' => $plugin,
'state' => $state,
] = self::validate_parameters(self::execute_parameters(), [
'plugin' => $plugin,
'state' => $state,
]);
$context = \context_system::instance();
self::validate_context($context);
require_capability('moodle/site:config', $context);
[, $pluginname] = explode('_', \core_component::normalize_componentname($plugin), 2);
$displayname = get_string('pluginname', $plugin);
if ($state) {
block_manager::protect_block($pluginname);
\core\notification::add(
get_string('blockprotected', 'core_admin', $displayname),
\core\notification::SUCCESS
);
} else {
block_manager::unprotect_block($pluginname);
\core\notification::add(
get_string('blockunprotected', 'core_admin', $displayname),
\core\notification::SUCCESS
);
}
return [];
}
/**
* Describe the return structure of the external service.
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([]);
}
}
-84
View File
@@ -1,84 +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/>.
namespace core_admin\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
/**
* Web Service to control the order of a plugin.
*
* @package core_admin
* @category external
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class set_plugin_order extends external_api {
/**
* Returns description of method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'plugin' => new external_value(PARAM_PLUGIN, 'The name of the plugin', VALUE_REQUIRED),
'direction' => new external_value(PARAM_INT, 'The direction to move', VALUE_REQUIRED),
]);
}
/**
* Set the plugin state.
*
* @param string $plugin The name of the plugin
* @param int $direction The direction to move the plugin
* @return array
*/
public static function execute(
string $plugin,
int $direction,
): array {
[
'plugin' => $plugin,
'direction' => $direction,
] = self::validate_parameters(self::execute_parameters(), [
'plugin' => $plugin,
'direction' => $direction,
]);
$context = \context_system::instance();
self::validate_context($context);
require_capability('moodle/site:config', $context);
[$plugintype, $pluginname] = explode('_', \core_component::normalize_componentname($plugin), 2);
$manager = \core_plugin_manager::resolve_plugininfo_class($plugintype);
$manager::change_plugin_order($pluginname, $direction);
return [];
}
/**
* Describe the return structure of the external service.
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([]);
}
}
-98
View File
@@ -1,98 +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/>.
namespace core_admin\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
/**
* Web Service to control the state of a plugin.
*
* @package core_admin
* @category external
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class set_plugin_state extends external_api {
/**
* Returns description of method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'plugin' => new external_value(PARAM_PLUGIN, 'The name of the plugin', VALUE_REQUIRED),
'state' => new external_value(PARAM_INT, 'The target state', VALUE_REQUIRED),
]);
}
/**
* Set the plugin state.
*
* @param string $plugin The name of the plugin
* @param int $state The target state
* @return null
*/
public static function execute(
string $plugin,
int $state,
): array {
[
'plugin' => $plugin,
'state' => $state,
] = self::validate_parameters(self::execute_parameters(), [
'plugin' => $plugin,
'state' => $state,
]);
$context = \context_system::instance();
self::validate_context($context);
require_capability('moodle/site:config', $context);
[$plugintype, $pluginname] = explode('_', \core_component::normalize_componentname($plugin), 2);
$manager = \core_plugin_manager::resolve_plugininfo_class($plugintype);
$displayname = get_string('pluginname', $plugin);
if ($manager::enable_plugin($pluginname, $state)) {
if (!empty($state)) {
\core\notification::add(
get_string('plugin_enabled', 'core_admin', $displayname),
\core\notification::SUCCESS
);
} else {
\core\notification::add(
get_string('plugin_disabled', 'core_admin', $displayname),
\core\notification::SUCCESS
);
}
}
return [];
}
/**
* Describe the return structure of the external service.
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([]);
}
}
+1 -1
View File
@@ -62,7 +62,7 @@ class filesize extends \admin_setting {
* @param int|null $defaultunit GB, MB, etc. (in bytes)
*/
public function __construct(string $name, string $visiblename, string $description,
?int $defaultvalue = null, ?int $defaultunit = null) {
int $defaultvalue = null, int $defaultunit = null) {
$defaultsetting = self::parse_bytes($defaultvalue);
-71
View File
@@ -1,71 +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/>.
namespace core_admin\output;
use moodle_url;
use renderable;
use renderer_base;
use stdClass;
use templatable;
/**
* Theme selector renderable.
*
* @package core_admin
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class theme_selector implements renderable, templatable {
/** @var array $themedata Theme data to pass to the template. */
private $themedata = null;
/** @var bool Whether $CFG->theme is defined in config.php. */
private $definedinconfig;
/**
* Constructor.
*
* @param array $themedata Theme data used for template.
* @param bool $definedinconfig Whether $CFG->theme is defined in config.php.
*/
public function __construct(array $themedata, bool $definedinconfig = false) {
$this->themedata = $themedata;
$this->definedinconfig = $definedinconfig;
}
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param renderer_base $output Renderer base.
* @return stdClass
*/
public function export_for_template(renderer_base $output): stdClass {
$data = new stdClass();
// Theme data used to populate cards and modal.
$data->themes = $this->themedata;
// Reset theme caches button.
$reseturl = new moodle_url('/admin/themeselector.php', ['sesskey' => sesskey(), 'reset' => 1]);
$resetbutton = new \single_button($reseturl, get_string('themeresetcaches', 'admin'), 'post',
\single_button::BUTTON_SECONDARY);
$data->resetbutton = $resetbutton->export_for_template($output);
$data->definedinconfig = $this->definedinconfig;
return $data;
}
}
+1 -1
View File
@@ -35,7 +35,7 @@ class provider implements \core_privacy\local\metadata\null_provider {
*
* @return string
*/
public static function get_reason(): string {
public static function get_reason() : string {
return 'privacy:metadata';
}
}
@@ -78,17 +78,6 @@ class task_logs extends datasource {
];
}
/**
* Return the column sorting that will be added to the report upon creation
*
* @return int[]
*/
public function get_default_column_sorting(): array {
return [
'task_log:starttime' => SORT_DESC,
];
}
/**
* Return the filters that will be added to the report upon creation
*
@@ -46,14 +46,12 @@ class task_log extends base {
protected const FAILED = 1;
/**
* Database tables that this entity uses
* Database tables that this entity uses and their default aliases
*
* @return string[]
* @return array
*/
protected function get_default_tables(): array {
return [
'task_log',
];
protected function get_default_table_aliases(): array {
return ['task_log' => 'tl'];
}
/**
@@ -105,7 +103,7 @@ class task_log extends base {
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$tablealias}.classname")
->add_field("$tablealias.classname")
->set_is_sortable(true)
->add_callback(static function(string $classname): string {
$output = '';
@@ -183,7 +181,15 @@ class task_log extends base {
->set_type(column::TYPE_FLOAT)
->add_field("{$tablealias}.timeend - {$tablealias}.timestart", 'duration')
->set_is_sortable(true)
->add_callback([format::class, 'format_time'], 2);
->add_callback(static function(float $value): string {
$duration = round($value, 2);
if (empty($duration)) {
// The format_time function returns 'now' when the difference is exactly 0.
// Note: format_time performs concatenation in exactly this fashion so we should do this for consistency.
return '0 ' . get_string('secs', 'moodle');
}
return format_time($duration);
});
// Hostname column.
$columns[] = (new column(
@@ -203,8 +209,11 @@ class task_log extends base {
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_field("{$tablealias}.pid")
->set_is_sortable(true);
->set_is_sortable(true)
// Although this is an integer column, it doesn't make sense to perform numeric aggregation on it.
->set_disabled_aggregation(['avg', 'count', 'countdistinct', 'max', 'min', 'sum']);
// Database column.
$columns[] = (new column(
@@ -213,14 +222,17 @@ class task_log extends base {
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_fields("{$tablealias}.dbreads, {$tablealias}.dbwrites")
->set_is_sortable(true, ["{$tablealias}.dbreads", "{$tablealias}.dbwrites"])
->add_callback(static function($value, stdClass $row): string {
->add_callback(static function(int $value, stdClass $row): string {
$output = '';
$output .= \html_writer::div(get_string('task_stats:dbreads', 'admin', $row->dbreads));
$output .= \html_writer::div(get_string('task_stats:dbwrites', 'admin', $row->dbwrites));
return $output;
});
})
// Although this is an integer column, it doesn't make sense to perform numeric aggregation on it.
->set_disabled_aggregation(['avg', 'count', 'countdistinct', 'max', 'min', 'sum']);
// Database reads column.
$columns[] = (new column(
@@ -1,108 +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/>.
declare(strict_types=1);
namespace core_admin\reportbuilder\local\filters;
use core\context\system;
use core_course_category;
use MoodleQuickForm;
use core_reportbuilder\local\filters\base;
use core_reportbuilder\local\helpers\database;
/**
* Course role report filter (by role, category, course)
*
* The provided filter field SQL must refer/return an expression for the user ID (e.g. "{$user}.id")
*
* @package core_admin
* @copyright 2023 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class courserole extends base {
/**
* Setup form
*
* @param MoodleQuickForm $mform
*/
public function setup_form(MoodleQuickForm $mform): void {
$elements = [];
// Role.
$elements['role'] = $mform->createElement('select', "{$this->name}_role", get_string('rolefullname', 'core_role'),
[0 => get_string('anyrole', 'core_filters')] + get_default_enrol_roles(system::instance()));
// Category.
$elements['category'] = $mform->createElement('select', "{$this->name}_category", get_string('category'),
[0 => get_string('anycategory', 'core_filters')] + core_course_category::make_categories_list());
// Course.
$elements['course'] = $mform->createElement('text', "{$this->name}_course", get_string('shortnamecourse'));
$mform->setType("{$this->name}_course", PARAM_RAW_TRIMMED);
$mform->addGroup($elements, "{$this->name}_group", $this->get_header(), '', false)
->setHiddenLabel(true);
}
/**
* Return filter SQL
*
* @param array $values
* @return array
*/
public function get_sql_filter(array $values): array {
[$fieldsql, $params] = $this->filter->get_field_sql_and_params();
[$contextalias, $rolealias, $coursealias] = database::generate_aliases(3);
[$roleparam, $categoryparam, $courseparam] = database::generate_param_names(3);
// Role.
$role = (int) ($values["{$this->name}_role"] ?? 0);
if ($role > 0) {
$selects[] = "{$rolealias}.roleid = :{$roleparam}";
$params[$roleparam] = $role;
}
// Category.
$category = (int) ($values["{$this->name}_category"] ?? 0);
if ($category > 0) {
$selects[] = "{$coursealias}.category = :{$categoryparam}";
$params[$categoryparam] = $category;
}
// Course.
$course = trim($values["{$this->name}_course"] ?? '');
if ($course !== '') {
$selects[] = "{$coursealias}.shortname = :{$courseparam}";
$params[$courseparam] = $course;
}
// Filter values are not set.
if (empty($selects)) {
return ['', []];
}
return ["{$fieldsql} IN (
SELECT {$rolealias}.userid
FROM {role_assignments} {$rolealias}
JOIN {context} {$contextalias} ON {$contextalias}.id = {$rolealias}.contextid AND {$contextalias}.contextlevel = 50
JOIN {course} {$coursealias} ON {$coursealias}.id = {$contextalias}.instanceid
WHERE " . implode(' AND ', $selects) . "
)", $params];
}
}
@@ -20,12 +20,10 @@ use context_system;
use core_admin\reportbuilder\local\entities\task_log;
use core_reportbuilder\local\entities\user;
use core_reportbuilder\local\report\action;
use core_reportbuilder\system_report;
use html_writer;
use lang_string;
use moodle_url;
use pix_icon;
use stdClass;
use core_reportbuilder\system_report;
/**
* Task logs system report class implementation
@@ -91,9 +89,7 @@ class task_logs extends system_report {
* unique identifier
*/
public function add_columns(): void {
$entitymainalias = $this->get_entity('task_log')->get_table_alias('task_log');
$this->add_columns_from_entities([
$columns = [
'task_log:name',
'task_log:type',
'user:fullname',
@@ -103,18 +99,14 @@ class task_logs extends system_report {
'task_log:pid',
'task_log:database',
'task_log:result',
]);
];
// Wrap the task name in a link.
$this->get_column('task_log:name')
->add_field("{$entitymainalias}.id")
->add_callback(static function(string $output, stdClass $row): string {
return html_writer::link(new moodle_url('/admin/tasklogs.php', ['logid' => $row->id]), $output);
});
$this->add_columns_from_entities($columns);
// Rename the user fullname column.
$this->get_column('user:fullname')
->set_title(new lang_string('user', 'admin'));
// It's possible to override the display name of a column, if you don't want to use the value provided by the entity.
if ($column = $this->get_column('user:fullname')) {
$column->set_title(new lang_string('user', 'admin'));
}
// It's possible to set a default initial sort direction for one column.
$this->set_initial_sort_column('task_log:starttime', SORT_DESC);
@@ -127,14 +119,16 @@ class task_logs extends system_report {
* unique identifier
*/
protected function add_filters(): void {
$this->add_filters_from_entities([
$filters = [
'task_log:name',
'task_log:type',
'task_log:output',
'task_log:result',
'task_log:timestart',
'task_log:duration',
]);
];
$this->add_filters_from_entities($filters);
}
/**
@@ -149,7 +143,7 @@ class task_logs extends system_report {
new moodle_url('/admin/tasklogs.php', ['logid' => ':id']),
new pix_icon('e/search', ''),
[],
false,
true,
new lang_string('view'),
)));
@@ -1,417 +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/>.
namespace core_admin\reportbuilder\local\systemreports;
use core_admin\reportbuilder\local\filters\courserole;
use core\context\system;
use core_cohort\reportbuilder\local\entities\cohort;
use core_cohort\reportbuilder\local\entities\cohort_member;
use core_reportbuilder\local\entities\user;
use core_reportbuilder\local\filters\boolean_select;
use core_reportbuilder\local\helpers\database;
use core_reportbuilder\local\helpers\user_profile_fields;
use core_reportbuilder\local\report\action;
use core_reportbuilder\local\report\filter;
use core_reportbuilder\system_report;
use core_role\reportbuilder\local\entities\role;
use core_user\fields;
use lang_string;
use moodle_url;
use pix_icon;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/authlib.php');
require_once($CFG->libdir.'/enrollib.php');
require_once($CFG->dirroot.'/user/lib.php');
/**
* Browse users system report class implementation
*
* @package core_admin
* @copyright 2023 David Carrillo <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class users extends system_report {
/**
* Initialise report, we need to set the main table, load our entities and set columns/filters
*/
protected function initialise(): void {
global $CFG;
// Our main entity, it contains all of the column definitions that we need.
$entityuser = new user();
$entityuseralias = $entityuser->get_table_alias('user');
$this->set_main_table('user', $entityuseralias);
$this->add_entity($entityuser);
// Any columns required by actions should be defined here to ensure they're always available.
$fullnamefields = array_map(fn($field) => "{$entityuseralias}.{$field}", fields::get_name_fields());
$this->add_base_fields("{$entityuseralias}.id, {$entityuseralias}.confirmed, {$entityuseralias}.mnethostid,
{$entityuseralias}.suspended, {$entityuseralias}.username, " . implode(', ', $fullnamefields));
if ($this->get_parameter('withcheckboxes', false, PARAM_BOOL)) {
$canviewfullnames = has_capability('moodle/site:viewfullnames', \context_system::instance());
$this->set_checkbox_toggleall(static function(\stdClass $row) use ($canviewfullnames): array {
return [$row->id, fullname($row, $canviewfullnames)];
});
}
$paramguest = database::generate_param_name();
$this->add_base_condition_sql("{$entityuseralias}.deleted <> 1 AND {$entityuseralias}.id <> :{$paramguest}",
[$paramguest => $CFG->siteguest]);
$entitycohortmember = new cohort_member();
$entitycohortmemberalias = $entitycohortmember->get_table_alias('cohort_members');
$this->add_entity($entitycohortmember
->add_joins($entitycohortmember->get_joins())
->add_join("LEFT JOIN {cohort_members} {$entitycohortmemberalias}
ON {$entityuseralias}.id = {$entitycohortmemberalias}.userid")
);
$entitycohort = new cohort();
$entitycohortalias = $entitycohort->get_table_alias('cohort');
$this->add_entity($entitycohort
->add_joins($entitycohort->get_joins())
->add_joins($entitycohortmember->get_joins())
->add_join("LEFT JOIN {cohort} {$entitycohortalias}
ON {$entitycohortalias}.id = {$entitycohortmemberalias}.cohortid")
);
// Join the role entity (Needed for the system role filter).
$roleentity = new role();
$role = $roleentity->get_table_alias('role');
$this->add_entity($roleentity
->add_join("LEFT JOIN (
SELECT DISTINCT r0.id, ras.userid
FROM {role} r0
JOIN {role_assignments} ras ON ras.roleid = r0.id
WHERE ras.contextid = ".SYSCONTEXTID."
) {$role} ON {$role}.userid = {$entityuseralias}.id")
);
// Now we can call our helper methods to add the content we want to include in the report.
$this->add_columns();
$this->add_filters();
$this->add_actions();
// Set if report can be downloaded.
$this->set_downloadable(true);
}
/**
* Validates access to view this report
*
* @return bool
*/
protected function can_view(): bool {
return has_any_capability(['moodle/user:update', 'moodle/user:delete'], system::instance());
}
/**
* Adds the columns we want to display in the report
*
* They are all provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier
*/
public function add_columns(): void {
$entityuser = $this->get_entity('user');
$entityuseralias = $entityuser->get_table_alias('user');
$this->add_column($entityuser->get_column('fullnamewithpicturelink'));
// Include identity field columns.
$identitycolumns = $entityuser->get_identity_columns($this->get_context());
foreach ($identitycolumns as $identitycolumn) {
$this->add_column($identitycolumn);
}
// Add "Last access" column.
$this->add_column(($entityuser->get_column('lastaccess'))
->set_callback(static function ($value, \stdClass $row): string {
if ($row->lastaccess) {
return format_time(time() - $row->lastaccess);
}
return get_string('never');
})
);
if ($column = $this->get_column('user:fullnamewithpicturelink')) {
$column
->add_fields("{$entityuseralias}.suspended, {$entityuseralias}.confirmed")
->add_callback(static function(string $fullname, \stdClass $row): string {
if ($row->suspended) {
$fullname .= ' ' . \html_writer::tag('span', get_string('suspended', 'moodle'),
['class' => 'badge badge-secondary ms-1']);
}
if (!$row->confirmed) {
$fullname .= ' ' . \html_writer::tag('span', get_string('confirmationpending', 'admin'),
['class' => 'badge badge-danger ms-1']);
}
return $fullname;
});
}
$this->set_initial_sort_column('user:fullnamewithpicturelink', SORT_ASC);
$this->set_default_no_results_notice(new lang_string('nousersfound', 'moodle'));
}
/**
* Adds the filters we want to display in the report
*
* They are all provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier
*/
protected function add_filters(): void {
$entityuser = $this->get_entity('user');
$entityuseralias = $entityuser->get_table_alias('user');
$filters = [
'user:fullname',
'user:firstname',
'user:lastname',
'user:username',
'user:idnumber',
'user:email',
'user:department',
'user:institution',
'user:city',
'user:country',
'user:confirmed',
'user:suspended',
'user:timecreated',
'user:lastaccess',
'user:timemodified',
'user:auth',
'user:lastip',
'cohort:idnumber',
'role:name',
];
$this->add_filters_from_entities($filters);
// Enrolled in any course filter.
$ue = database::generate_alias();
[$now1, $now2] = database::generate_param_names(2);
$now = time();
$sql = "CASE WHEN ({$entityuseralias}.id IN (
SELECT userid FROM {user_enrolments} {$ue}
WHERE {$ue}.status = " . ENROL_USER_ACTIVE . "
AND ({$ue}.timestart = 0 OR {$ue}.timestart < :{$now1})
AND ({$ue}.timeend = 0 OR {$ue}.timeend > :{$now2})
)) THEN 1 ELSE 0 END";
$this->add_filter((new filter(
boolean_select::class,
'enrolledinanycourse',
new lang_string('anycourses', 'filters'),
$this->get_entity('user')->get_entity_name(),
))
->set_field_sql($sql, [
$now1 => $now,
$now2 => $now,
])
);
// Course role filter.
$this->add_filter((new filter(
courserole::class,
'courserole',
new lang_string('courserole', 'filters'),
$this->get_entity('user')->get_entity_name(),
))
->set_field_sql("{$entityuseralias}.id")
);
// Add user profile fields filters.
$userprofilefields = new user_profile_fields($entityuseralias . '.id', $entityuser->get_entity_name());
foreach ($userprofilefields->get_filters() as $filter) {
$this->add_filter($filter);
}
// Set options for system role filter.
if ($filter = $this->get_filter('role:name')) {
$filter
->set_header(new lang_string('globalrole', 'role'))
->set_options(get_assignable_roles(system::instance()));
}
}
/**
* Add the system report actions. An extra column will be appended to each row, containing all actions added here
*
* Note the use of ":id" placeholder which will be substituted according to actual values in the row
*/
protected function add_actions(): void {
global $DB, $USER;
$contextsystem = system::instance();
// Action to edit users.
$this->add_action((new action(
new moodle_url('/user/editadvanced.php', ['id' => ':id', 'course' => get_site()->id]),
new pix_icon('t/edit', ''),
[],
false,
new lang_string('edit', 'moodle'),
))->add_callback(static function(\stdclass $row) use ($USER, $contextsystem): bool {
return has_capability('moodle/user:update', $contextsystem) && (is_siteadmin($USER) || !is_siteadmin($row));
}));
// Action to suspend users (non mnet remote users).
$this->add_action((new action(
new moodle_url('/admin/user.php', ['suspend' => ':id', 'sesskey' => sesskey()]),
new pix_icon('t/show', ''),
[],
false,
new lang_string('suspenduser', 'admin'),
))->add_callback(static function(\stdclass $row) use ($USER, $contextsystem): bool {
return has_capability('moodle/user:update', $contextsystem) && !$row->suspended && !is_mnet_remote_user($row) &&
!($row->id == $USER->id || is_siteadmin($row));
}));
// Action to unsuspend users (non mnet remote users).
$this->add_action((new action(
new moodle_url('/admin/user.php', ['unsuspend' => ':id', 'sesskey' => sesskey()]),
new pix_icon('t/hide', ''),
[],
false,
new lang_string('unsuspenduser', 'admin'),
))->add_callback(static function(\stdclass $row) use ($USER, $contextsystem): bool {
return has_capability('moodle/user:update', $contextsystem) && $row->suspended && !is_mnet_remote_user($row) &&
!($row->id == $USER->id || is_siteadmin($row));
}));
// Action to unlock users (non mnet remote users).
$this->add_action((new action(
new moodle_url('/admin/user.php', ['unlock' => ':id', 'sesskey' => sesskey()]),
new pix_icon('t/unlock', ''),
[],
false,
new lang_string('unlockaccount', 'admin'),
))->add_callback(static function(\stdclass $row) use ($contextsystem): bool {
return has_capability('moodle/user:update', $contextsystem) && !is_mnet_remote_user($row) &&
login_is_lockedout($row);
}));
// Action to suspend users (mnet remote users).
$this->add_action((new action(
new moodle_url('/admin/user.php', ['acl' => ':id', 'sesskey' => sesskey(), 'accessctrl' => 'deny']),
new pix_icon('t/show', ''),
[],
false,
new lang_string('denyaccess', 'mnet'),
))->add_callback(static function(\stdclass $row) use ($DB, $contextsystem): bool {
if (!$accessctrl = $DB->get_field(table: 'mnet_sso_access_control', return: 'accessctrl',
conditions: ['username' => $row->username, 'mnet_host_id' => $row->mnethostid]
)) {
$accessctrl = 'allow';
}
return has_capability('moodle/user:update', $contextsystem) && !$row->suspended &&
is_mnet_remote_user($row) && $accessctrl == 'allow';
}));
// Action to unsuspend users (mnet remote users).
$this->add_action((new action(
new moodle_url('/admin/user.php', ['acl' => ':id', 'sesskey' => sesskey(), 'accessctrl' => 'allow']),
new pix_icon('t/hide', ''),
[],
false,
new lang_string('allowaccess', 'mnet'),
))->add_callback(static function(\stdclass $row) use ($DB, $contextsystem): bool {
if (!$accessctrl = $DB->get_field(table: 'mnet_sso_access_control', return: 'accessctrl',
conditions: ['username' => $row->username, 'mnet_host_id' => $row->mnethostid]
)) {
$accessctrl = 'allow';
}
return has_capability('moodle/user:update', $contextsystem) && !$row->suspended &&
is_mnet_remote_user($row) && $accessctrl == 'deny';
}));
// Action to delete users.
$this->add_action((new action(
new moodle_url('/admin/user.php', ['delete' => ':id', 'sesskey' => sesskey()]),
new pix_icon('t/delete', ''),
[
'class' => 'text-danger',
'data-modal' => 'confirmation',
'data-modal-title-str' => json_encode(['deleteuser', 'admin']),
'data-modal-content-str' => ':deletestr',
'data-modal-yes-button-str' => json_encode(['delete', 'core']),
'data-modal-destination' => ':deleteurl',
],
false,
new lang_string('delete', 'moodle'),
))->add_callback(static function(\stdclass $row) use ($USER, $contextsystem): bool {
// Populate deletion modal attributes.
$row->deletestr = json_encode([
'deletecheckfull',
'moodle',
fullname($row, true),
]);
$row->deleteurl = (new moodle_url('/admin/user.php', [
'delete' => $row->id,
'confirm' => md5($row->id),
'sesskey' => sesskey(),
]))->out(false);
return has_capability('moodle/user:delete', $contextsystem) &&
!is_mnet_remote_user($row) && $row->id != $USER->id && !is_siteadmin($row);
}));
$this->add_action_divider();
// Action to confirm users.
$this->add_action((new action(
new moodle_url('/admin/user.php', ['confirmuser' => ':id', 'sesskey' => sesskey()]),
new pix_icon('t/check', ''),
[],
false,
new lang_string('confirmaccount', 'moodle'),
))->add_callback(static function(\stdclass $row) use ($contextsystem): bool {
return has_capability('moodle/user:update', $contextsystem) && !$row->confirmed;
}));
// Action to resend email.
$this->add_action((new action(
new moodle_url('/admin/user.php', ['resendemail' => ':id', 'sesskey' => sesskey()]),
new pix_icon('t/email', ''),
[],
false,
new lang_string('resendemail', 'moodle'),
))->add_callback(static function(\stdclass $row): bool {
return !$row->confirmed && !is_mnet_remote_user($row);
}));
}
/**
* Row class
*
* @param \stdClass $row
* @return string
*/
public function get_row_class(\stdClass $row): string {
return $row->suspended ? 'text-muted' : '';
}
}
@@ -1,118 +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/>.
namespace core_admin\table;
use core_plugin_manager;
use dml_exception;
use html_writer;
use moodle_url;
use stdClass;
/**
* Activity Module admin settings.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class activity_management_table extends plugin_management_table {
public function setup() {
$this->set_attribute('id', 'modules');
$this->set_attribute('class', 'admintable generaltable');
parent::setup();
}
protected function get_table_id(): string {
return 'module-administration-table';
}
protected function get_plugintype(): string {
return 'mod';
}
public function guess_base_url(): void {
$this->define_baseurl(
new moodle_url('/admin/modules.php')
);
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/modules.php', $params);
}
protected function get_column_list(): array {
$columns = parent::get_column_list();
return array_merge(
array_slice($columns, 0, 1, true),
['activities' => get_string('activities')],
array_slice($columns, 1, null, true),
);
}
protected function col_name(stdClass $row): string {
global $OUTPUT;
$status = $row->plugininfo->get_status();
if ($status === core_plugin_manager::PLUGIN_STATUS_MISSING) {
return html_writer::span(
get_string('pluginmissingfromdisk', 'core', $row->plugininfo),
'notifyproblem'
);
}
return html_writer::span(
html_writer::img(
$OUTPUT->image_url('monologo', $row->plugininfo->name),
'',
[
'class' => 'icon',
],
) . get_string('modulename', $row->plugininfo->name)
);
}
/**
* Show the number of activities present, with a link to courses containing activity if relevant.
*
* @param mixed $row
* @return string
*/
protected function col_activities(stdClass $row): string {
global $DB, $OUTPUT;
try {
$count = $DB->count_records_select($row->plugininfo->name, "course <> 0");
} catch (dml_exception $e) {
$count = -1;
}
if ($count > 0) {
return $OUTPUT->action_link(
new moodle_url('/course/search.php', [
'modulelist' => $row->plugininfo->name,
]),
$count,
null,
['title' => get_string('showmodulecourse')]
);
} else if ($count < 0) {
return get_string('error');
} else {
return $count;
}
}
}
@@ -1,85 +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/>.
namespace core_admin\table;
use moodle_url;
use stdClass;
use html_writer;
use get_string_manager;
/**
* Availability admin settings.
*
* @package core_admin
* @copyright 2024 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class availability_management_table extends plugin_management_table {
protected function get_table_id(): string {
return 'availabilityconditions_administration_table';
}
protected function get_plugintype(): string {
return 'availability';
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/tool/availabilityconditions/', $params);
}
public function guess_base_url(): void {
$this->define_baseurl(
new moodle_url('/admin/tool/availabilityconditions/')
);
}
protected function get_column_list(): array {
return [
'name' => get_string('plugin'),
'version' => get_string('version'),
'enabled' => get_string('enabled', 'admin'),
'defaultdisplaymode' => get_string('defaultdisplaymode', 'tool_availabilityconditions'),
];
}
public function setup(): void {
$this->set_attribute('id', 'availabilityconditions_administration_table');
$this->set_attribute('class', 'admintable generaltable');
parent::setup();
}
protected function col_name(stdClass $row): string {
return html_writer::span(
get_string('pluginname', 'availability_' . $row->plugininfo->name)
);
}
protected function col_defaultdisplaymode(stdClass $row): string {
global $OUTPUT, $CFG;
$displaymode = get_config('availability_' . $row->plugininfo->name, 'defaultdisplaymode') ? 'show' : 'hide';
$paramsdisplaymode = [
'sesskey' => sesskey(),
'plugin' => $row->plugininfo->name,
'displaymode' => $displaymode,
];
$urldisplaymode = new moodle_url('/' . $CFG->admin . '/tool/availabilityconditions/', $paramsdisplaymode);
return html_writer::link($urldisplaymode, $OUTPUT->pix_icon('t/' . $displaymode,
get_string($displaymode)), ['class' => 'display-mode-' . $row->plugininfo->name]);
}
}
@@ -1,153 +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/>.
namespace core_admin\table;
use html_writer;
use moodle_url;
use stdClass;
/**
* Tiny admin settings.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class block_management_table extends \core_admin\table\plugin_management_table {
/** @var plugininfo[] A list of blocks which cannot be deleted */
protected array $undeletableblocktypes;
/** @var stdClass[] A list of basic block data */
protected array $blockdata;
/** @var array<string,int> A list of course counts */
protected array $courseblocks;
public function __construct() {
global $DB;
parent::__construct();
$this->undeletableblocktypes = \block_manager::get_undeletable_block_types();
$sql = 'SELECT b.name,
b.id,
COUNT(DISTINCT binst.id) as totalcount
FROM {block} b
LEFT JOIN {block_instances} binst ON binst.blockname = b.name
GROUP BY b.id,
b.name
ORDER BY b.name ASC';
$this->blockdata = $DB->get_records_sql($sql);
$sql = "SELECT blockname
FROM {block_instances}
WHERE pagetypepattern = 'course-view-*'
GROUP BY blockname";
$this->courseblocks = $DB->get_records_sql($sql);
}
protected function get_plugintype(): string {
return 'block';
}
public function guess_base_url(): void {
$this->define_baseurl(
new moodle_url('/admin/blocks.php')
);
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/blocks.php', $params);
}
protected function get_table_js_module(): string {
return 'core_admin/block_management_table';
}
protected function get_column_list(): array {
$columns = parent::get_column_list();
return array_merge(
array_slice($columns, 0, 1, true),
['instances' => get_string('blockinstances', 'admin')],
array_slice($columns, 1, 2, true),
['protect' => get_string('blockprotect', 'admin')],
array_slice($columns, 3, null, true),
);
}
protected function get_columns_with_help(): array {
return [
'protect' => new \help_icon('blockprotect', 'admin'),
];
}
/**
* Render the instances column
* @param stdClass $row
* @return string
*/
protected function col_instances(stdClass $row): string {
$blockdata = $this->blockdata[$row->plugininfo->name];
if (array_key_exists($blockdata->name, $this->courseblocks)) {
return html_writer::link(
new moodle_url('/course/search.php', [
'blocklist' => $blockdata->id,
]),
$blockdata->totalcount,
);
}
return $blockdata->totalcount;
}
/**
* Render the protect column.
*
* @param stdClass $row
* @return string
*/
protected function col_protect(stdClass $row): string {
global $OUTPUT;
$params = [
'sesskey' => sesskey(),
];
$protected = in_array($row->plugininfo->name, $this->undeletableblocktypes);
$pluginname = $row->plugininfo->displayname;
if ($protected) {
$params['unprotect'] = $row->plugininfo->name;
$icon = $OUTPUT->pix_icon('t/unlock', get_string('blockunprotectblock', 'admin', $pluginname));
} else {
$params['protect'] = $row->plugininfo->name;
$icon = $OUTPUT->pix_icon('t/lock', get_string('blockprotectblock', 'admin', $pluginname));
}
return html_writer::link(
$this->get_action_url($params),
$icon,
[
'data-action' => 'toggleprotectstate',
'data-plugin' => $row->plugin,
'data-target-state' => $protected ? 0 : 1,
],
);
return '';
}
}
@@ -1,63 +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/>.
namespace core_admin\table;
use moodle_url;
/**
* Tiny admin settings.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class editor_management_table extends \core_admin\table\plugin_management_table {
protected function get_plugintype(): string {
return 'editor';
}
public function guess_base_url(): void {
$this->define_baseurl(
new moodle_url('/admin/settings.php', ['section' => 'manageeditors'])
);
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/editors.php', $params);
}
protected function order_plugins(array $plugins): array {
global $CFG;
// The Editor list is stored in an ordered string.
$activeeditors = explode(',', $CFG->texteditors);
$sortedplugins = [];
foreach ($activeeditors as $editor) {
if (isset($plugins[$editor])) {
$sortedplugins[$editor] = $plugins[$editor];
unset($plugins[$editor]);
}
}
$otherplugins = parent::order_plugins($plugins);
return array_merge(
$sortedplugins,
$otherplugins
);
}
}
-281
View File
@@ -1,281 +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/>.
namespace core_admin\table;
use core_plugin_manager;
use flexible_table;
use html_writer;
use stdClass;
defined('MOODLE_INTERNAL') || die();
require_once("{$CFG->libdir}/tablelib.php");
/**
* Plugin Management table.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class hook_list_table extends flexible_table {
/** @var \core\plugininfo\base[] The plugin list */
protected array $plugins = [];
/** @var int The number of enabled plugins of this type */
protected int $enabledplugincount = 0;
/** @var core_plugin_manager */
protected core_plugin_manager $pluginmanager;
/** @var string The plugininfo class for this plugintype */
protected string $plugininfoclass;
/** @var stdClass[] The list of emitted hooks with metadata */
protected array $emitters;
public function __construct() {
global $CFG;
$this->define_baseurl('/admin/hooks.php');
parent::__construct('core_admin-hook_list_table');
// Add emitted hooks.
$this->emitters = \core\hook\manager::discover_known_hooks();
$this->setup_column_configuration();
$this->setup();
}
/**
* Set up the column configuration for this table.
*/
protected function setup_column_configuration(): void {
$columnlist = [
'details' => get_string('hookname', 'core_admin'),
'callbacks' => get_string('hookcallbacks', 'core_admin'),
'deprecates' => get_string('hookdeprecates', 'core_admin'),
];
$this->define_columns(array_keys($columnlist));
$this->define_headers(array_values($columnlist));
$columnswithhelp = [
'callbacks' => new \help_icon('hookcallbacks', 'admin'),
];
$columnhelp = array_map(function (string $column) use ($columnswithhelp): ?\renderable {
if (array_key_exists($column, $columnswithhelp)) {
return $columnswithhelp[$column];
}
return null;
}, array_keys($columnlist));
$this->define_help_for_headers($columnhelp);
}
/**
* Print the table.
*/
public function out(): void {
// All hook consumers referenced from the db/hooks.php files.
$hookmanager = \core\di::get(\core\hook\manager::class);
$allhooks = (array)$hookmanager->get_all_callbacks();
// Add any unused hooks.
foreach (array_keys($this->emitters) as $classname) {
if (isset($allhooks[$classname])) {
continue;
}
$allhooks[$classname] = [];
}
// Order rows by hook name, putting core first.
\core_collator::ksort($allhooks);
$corehooks = [];
foreach ($allhooks as $classname => $consumers) {
if (str_starts_with($classname, 'core\\')) {
$corehooks[$classname] = $consumers;
unset($allhooks[$classname]);
}
}
$allhooks = array_merge($corehooks, $allhooks);
foreach ($allhooks as $classname => $consumers) {
$this->add_data_keyed(
$this->format_row((object) [
'classname' => $classname,
'callbacks' => $consumers,
]),
$this->get_row_class($classname),
);
}
$this->finish_output(false);
}
protected function col_details(stdClass $row): string {
return $row->classname .
$this->get_description($row) .
html_writer::div($this->get_tags_for_row($row));
}
/**
* Show the name column content.
*
* @param stdClass $row
* @return string
*/
protected function get_description(stdClass $row): string {
if (!array_key_exists($row->classname, $this->emitters)) {
return '';
}
return html_writer::tag(
'small',
clean_text(markdown_to_html($this->emitters[$row->classname]['description']), FORMAT_HTML),
);
}
protected function col_deprecates(stdClass $row): string {
if (!class_exists($row->classname)) {
return '';
}
$deprecates = \core\hook\manager::get_replaced_callbacks($row->classname);
if (count($deprecates) === 0) {
return '';
}
$content = html_writer::start_tag('ul');
foreach ($deprecates as $deprecatedmethod) {
$content .= html_writer::tag('li', $deprecatedmethod);
}
$content .= html_writer::end_tag('ul');
return $content;
}
protected function col_callbacks(stdClass $row): string {
global $CFG;
$hookclass = $row->classname;
$cbinfo = [];
foreach ($row->callbacks as $definition) {
$iscallable = is_callable($definition['callback'], false, $callbackname);
$isoverridden = isset($CFG->hooks_callback_overrides[$hookclass][$definition['callback']]);
$info = "{$callbackname}&nbsp;({$definition['priority']})";
if (!$iscallable) {
$info .= '&nbsp;';
$info .= $this->get_tag(
get_string('error'),
'danger',
get_string('hookcallbacknotcallable', 'core_admin', $callbackname),
);
}
if ($isoverridden) {
// The lang string meaning should be close enough here.
$info .= $this->get_tag(
get_string('hookconfigoverride', 'core_admin'),
'warning',
get_string('hookconfigoverride_help', 'core_admin'),
);
}
$cbinfo[] = $info;
}
if ($cbinfo) {
$output = html_writer::start_tag('ol');
foreach ($cbinfo as $callback) {
$class = '';
if ($definition['disabled']) {
$class = 'dimmed_text';
}
$output .= html_writer::tag('li', $callback, ['class' => $class]);
}
$output .= html_writer::end_tag('ol');
return $output;
} else {
return '';
}
}
/**
* Get the HTML to display the badge with tooltip.
*
* @param string $tag The main text to display
* @param null|string $type The pill type
* @param null|string $tooltip The content of the tooltip
* @return string
*/
protected function get_tag(
string $tag,
?string $type = null,
?string $tooltip = null,
): string {
$attributes = [];
if ($type === null) {
$type = 'info';
}
if ($tooltip) {
$attributes['data-toggle'] = 'tooltip';
$attributes['title'] = $tooltip;
}
return html_writer::span($tag, "badge badge-{$type}", $attributes);
}
/**
* Get the code to display a set of tags for this table row.
*
* @param stdClass $row
* @return string
*/
protected function get_tags_for_row(stdClass $row): string {
if (!array_key_exists($row->classname, $this->emitters)) {
// This hook has been defined in the db/hooks.php file
// but does not refer to a hook in this version of Moodle.
return $this->get_tag(
get_string('hookunknown', 'core_admin'),
'warning',
get_string('hookunknown_desc', 'core_admin'),
);
}
if (!class_exists($row->classname)) {
// This hook has been defined in a hook discovery agent, but the class it refers to could not be found.
return $this->get_tag(
get_string('hookclassmissing', 'core_admin'),
'warning',
get_string('hookclassmissing_desc', 'core_admin'),
);
}
$tags = $this->emitters[$row->classname]['tags'] ?? [];
$taglist = array_map(function($tag): string {
if (is_array($tag)) {
return $this->get_tag(...$tag);
}
return $this->get_tag($tag, 'badge bg-info text-white');
}, $tags);
return implode("\n", $taglist);
}
protected function get_row_class(string $classname): string {
return '';
}
}
@@ -1,71 +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/>.
namespace core_admin\table;
use moodle_url;
use stdClass;
/**
* Media plugin admin settings.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class media_management_table extends \core_admin\table\plugin_management_table {
/** @var array The list of used extensions */
protected array $usedextensions = [];
protected function get_plugintype(): string {
return 'media';
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/media.php', $params);
}
protected function get_column_list(): array {
$columns = parent::get_column_list();
return array_merge(
array_slice($columns, 0, 1, true),
['supports' => get_string('supports', 'core_media')],
array_slice($columns, 1, null, true),
);
}
protected function col_name(stdClass $row): string {
global $OUTPUT, $PAGE;
$name = $row->plugininfo->name;
if ($PAGE->theme->resolve_image_location('icon', 'media_' . $name, false)) {
$icon = $OUTPUT->pix_icon('icon', '', "media_{$name}", ['class' => 'icon pluginicon']);
} else {
$icon = $OUTPUT->pix_icon('spacer', '', 'moodle', ['class' => 'icon pluginicon noicon']);
}
$help = '';
if (get_string_manager()->string_exists('pluginname_help', 'media_' . $name)) {
$help = '&nbsp;' . $OUTPUT->help_icon('pluginname', 'media_' . $name);
}
return $icon . $row->plugininfo->displayname . $help;
}
protected function col_supports(stdClass $row): string {
return $row->plugininfo->supports($this->usedextensions);
}
}
@@ -1,515 +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/>.
namespace core_admin\table;
use context_system;
use core_plugin_manager;
use core_table\dynamic as dynamic_table;
use flexible_table;
use html_writer;
use moodle_url;
use stdClass;
defined('MOODLE_INTERNAL') || die();
require_once("{$CFG->libdir}/tablelib.php");
/**
* Plugin Management table.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class plugin_management_table extends flexible_table implements dynamic_table {
/** @var \core\plugininfo\base[] The plugin list */
protected array $plugins = [];
/** @var int The number of enabled plugins of this type */
protected int $enabledplugincount = 0;
/** @var core_plugin_manager */
protected core_plugin_manager $pluginmanager;
/** @var string The plugininfo class for this plugintype */
protected string $plugininfoclass;
public function __construct() {
global $CFG;
parent::__construct($this->get_table_id());
require_once($CFG->libdir . '/adminlib.php');
// Fetch the plugininfo class.
$this->pluginmanager = core_plugin_manager::instance();
$this->plugininfoclass = $this->pluginmanager::resolve_plugininfo_class($this->get_plugintype());
$this->guess_base_url();
$this->plugins = $this->get_sorted_plugins();
$this->enabledplugincount = count(array_filter($this->plugins, function ($plugin) {
return $plugin->is_enabled();
}));
$this->setup_column_configuration();
$this->set_filterset(new plugin_management_table_filterset());
$this->setup();
}
/**
* Get the list of sorted plugins.
*
* @return \core\plugininfo\base[]
*/
protected function get_sorted_plugins(): array {
if ($this->plugininfoclass::plugintype_supports_ordering()) {
return $this->plugininfoclass::get_sorted_plugins();
} else {
$plugins = $this->pluginmanager->get_plugins_of_type($this->get_plugintype());
return self::sort_plugins($plugins);
}
}
/**
* Sort the plugins list.
*
* Note: This only applies to plugins which do not support ordering.
*
* @param \core\plugininfo\base[] $plugins
* @return \core\plugininfo\base[]
*/
protected function sort_plugins(array $plugins): array {
// The asort functions work by reference.
\core_collator::asort_objects_by_property($plugins, 'displayname');
return $plugins;
}
/**
* Set up the column configuration for this table.
*/
protected function setup_column_configuration(): void {
$columnlist = $this->get_column_list();
$this->define_columns(array_keys($columnlist));
$this->define_headers(array_values($columnlist));
$columnswithhelp = $this->get_columns_with_help();
$columnhelp = array_map(function (string $column) use ($columnswithhelp): ?\renderable {
if (array_key_exists($column, $columnswithhelp)) {
return $columnswithhelp[$column];
}
return null;
}, array_keys($columnlist));
$this->define_help_for_headers($columnhelp);
}
/**
* Set the standard order of the plugins.
*
* @param array $plugins
* @return array
*/
protected function order_plugins(array $plugins): array {
uasort($plugins, function ($a, $b) {
if ($a->is_enabled() && !$b->is_enabled()) {
return -1;
} else if (!$a->is_enabled() && $b->is_enabled()) {
return 1;
}
return strnatcasecmp($a->name, $b->name);
});
return $plugins;
}
/**
* Get the plugintype for this table.
*
* @return string
*/
abstract protected function get_plugintype(): string;
/**
* Get the action URL for this table.
*
* The action URL is used to perform all actions when JS is not available.
*
* @param array $params
* @return moodle_url
*/
abstract protected function get_action_url(array $params = []): moodle_url;
/**
* Provide a default implementation for guessing the base URL from the action URL.
*/
public function guess_base_url(): void {
$this->define_baseurl($this->get_action_url());
}
/**
* Get the web service method used to toggle state.
*
* @return null|string
*/
protected function get_toggle_service(): ?string {
return 'core_admin_set_plugin_state';
}
/**
* Get the web service method used to order plugins.
*
* @return null|string
*/
protected function get_sortorder_service(): ?string {
return 'core_admin_set_plugin_order';
}
/**
* Get the ID of the table.
*
* @return string
*/
protected function get_table_id(): string {
return 'plugin_management_table-' . $this->get_plugintype();
}
/**
* Get a list of the column titles
* @return string[]
*/
protected function get_column_list(): array {
$columns = [
'name' => get_string('name', 'core'),
'version' => get_string('version', 'core'),
];
if ($this->supports_disabling()) {
$columns['enabled'] = get_string('pluginenabled', 'core_plugin');
}
if ($this->supports_ordering()) {
$columns['order'] = get_string('order', 'core');
}
$columns['settings'] = get_string('settings', 'core');
$columns['uninstall'] = get_string('uninstallplugin', 'core_admin');
return $columns;
}
protected function get_columns_with_help(): array {
return [];
}
/**
* Get the context for this table.
*
* @return context_system
*/
public function get_context(): context_system {
return context_system::instance();
}
/**
* Get the table content.
*/
public function get_content(): string {
ob_start();
$this->out();
$content = ob_get_contents();
ob_end_clean();
return $content;
}
/**
* Print the table.
*/
public function out(): void {
$plugintype = $this->get_plugintype();
foreach ($this->plugins as $plugininfo) {
$plugin = "{$plugintype}_{$plugininfo->name}";
$rowdata = (object) [
'plugin' => $plugin,
'plugininfo' => $plugininfo,
'name' => $plugininfo->displayname,
'version' => $plugininfo->versiondb,
];
$this->add_data_keyed(
$this->format_row($rowdata),
$this->get_row_class($rowdata)
);
}
$this->finish_output(false);
}
/**
* This table is not downloadable.
* @param bool $downloadable
* @return bool
*/
// phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
public function is_downloadable($downloadable = null): bool {
return false;
}
/**
* Show the name column content.
*
* @param stdClass $row
* @return string
*/
protected function col_name(stdClass $row): string {
$status = $row->plugininfo->get_status();
if ($status === core_plugin_manager::PLUGIN_STATUS_MISSING) {
return html_writer::span(
get_string('pluginmissingfromdisk', 'core', $row->plugininfo),
'notifyproblem'
);
}
if ($row->plugininfo->is_installed_and_upgraded()) {
return $row->plugininfo->displayname;
}
return html_writer::span(
$row->plugininfo->displayname,
'notifyproblem'
);
}
/**
* Show the enable/disable column content.
*
* @param stdClass $row
* @return string
*/
protected function col_enabled(stdClass $row): string {
global $OUTPUT;
$enabled = $row->plugininfo->is_enabled();
if ($enabled) {
$labelstr = get_string('disableplugin', 'core_admin', $row->plugininfo->displayname);
} else {
$labelstr = get_string('enableplugin', 'core_admin', $row->plugininfo->displayname);
}
$params = [
'id' => 'admin-toggle-' . $row->plugininfo->name,
'checked' => $enabled,
'dataattributes' => [
'name' => 'id',
'value' => $row->plugininfo->name,
'toggle-method' => $this->get_toggle_service(),
'action' => 'togglestate',
'plugin' => $row->plugin,
'state' => $enabled ? 1 : 0,
],
'title' => $labelstr,
'label' => $labelstr,
'labelclasses' => 'sr-only',
];
return $OUTPUT->render_from_template('core_admin/setting_configtoggle', $params);
}
protected function col_order(stdClass $row): string {
global $OUTPUT;
if (!$this->supports_ordering()) {
return '';
}
if (!$row->plugininfo->is_enabled()) {
return '';
}
if ($this->enabledplugincount <= 1) {
// There is only one row.
return '';
}
$hasup = true;
$hasdown = true;
if (empty($this->currentrow)) {
// This is the top row.
$hasup = false;
}
if ($this->currentrow === ($this->enabledplugincount - 1)) {
// This is the last row.
$hasdown = false;
}
if ($this->supports_ordering()) {
$dataattributes = [
'data-method' => $this->get_sortorder_service(),
'data-action' => 'move',
'data-plugin' => $row->plugin,
];
} else {
$dataattributes = [];
}
if ($hasup) {
$upicon = html_writer::link(
$this->get_action_url([
'sesskey' => sesskey(),
'action' => 'up',
'plugin' => $row->plugininfo->name,
]),
$OUTPUT->pix_icon('t/up', get_string('moveup')),
array_merge($dataattributes, ['data-direction' => 'up']),
);
} else {
$upicon = $OUTPUT->spacer();
}
if ($hasdown) {
$downicon = html_writer::link(
$this->get_action_url([
'sesskey' => sesskey(),
'action' => 'down',
'plugin' => $row->plugininfo->name,
]),
$OUTPUT->pix_icon('t/down', get_string('movedown')),
array_merge($dataattributes, ['data-direction' => 'down']),
);
} else {
$downicon = $OUTPUT->spacer();
}
// For now just add the up/down icons.
return html_writer::span($upicon . $downicon);
}
/**
* Show the settings column content.
*
* @param stdClass $row
* @return string
*/
protected function col_settings(stdClass $row): string {
if ($settingsurl = $row->plugininfo->get_settings_url()) {
return html_writer::link($settingsurl, get_string('settings'));
}
return '';
}
/**
* Show the Uninstall column content.
*
* @param stdClass $row
* @return string
*/
protected function col_uninstall(stdClass $row): string {
$status = $row->plugininfo->get_status();
if ($status === core_plugin_manager::PLUGIN_STATUS_NEW) {
return get_string('status_new', 'core_plugin');
}
if ($status === core_plugin_manager::PLUGIN_STATUS_MISSING) {
$uninstall = get_string('status_missing', 'core_plugin') . '<br/>';
} else {
$uninstall = '';
}
if ($uninstallurl = $this->pluginmanager->get_uninstall_url($row->plugin)) {
$uninstall .= html_writer::link($uninstallurl, get_string('uninstallplugin', 'core_admin'));
}
return $uninstall;
}
/**
* Get the JS module used to manage this table.
*
* This should be a class which extends 'core_admin/plugin_management_table'.
*
* @return string
*/
protected function get_table_js_module(): string {
return 'core_admin/plugin_management_table';
}
/**
* Add JS specific to this implementation.
*
* @return string
*/
protected function get_dynamic_table_html_end(): string {
global $PAGE;
$PAGE->requires->js_call_amd($this->get_table_js_module(), 'init');
return parent::get_dynamic_table_html_end();
}
/**
* Get any class to add to the row.
*
* @param mixed $row
* @return string
*/
protected function get_row_class($row): string {
$plugininfo = $row->plugininfo;
if ($plugininfo->get_status() === core_plugin_manager::PLUGIN_STATUS_MISSING) {
return '';
}
if (!$plugininfo->is_enabled()) {
return 'dimmed_text';
}
return '';
}
public static function get_filterset_class(): string {
return self::class . '_filterset';
}
/**
* Whether this plugin type supports the disabling of plugins.
*
* @return bool
*/
protected function supports_disabling(): bool {
return $this->plugininfoclass::plugintype_supports_disabling();
}
/**
* Whether this table should show ordering fields.
*
* @return bool
*/
protected function supports_ordering(): bool {
return $this->plugininfoclass::plugintype_supports_ordering();
}
/**
* Check if the user has the capability to access this table.
*
* Default implementation for plugin management tables is to require 'moodle/site:config' capability
*
* @return bool Return true if capability check passed.
*/
public function has_capability(): bool {
return has_capability('moodle/site:config', $this->get_context());
}
}
@@ -1,27 +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/>.
namespace core_admin\table;
/**
* This file contains the dynamic interface.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plugin_management_table_filterset extends \core_table\local\filter\filterset {
}
@@ -1,44 +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/>.
namespace core_admin\table;
use moodle_url;
/**
* Admin tool settings.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_plugin_management_table extends \core_admin\table\plugin_management_table {
protected function get_plugintype(): string {
return 'tool';
}
protected function get_column_list(): array {
$columns = parent::get_column_list();
unset($columns['settings']);
return $columns;
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/settings.php', array_merge(['section' => 'toolsmanagement'], $params));
}
}
+29 -72
View File
@@ -27,28 +27,23 @@ define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once("{$CFG->libdir}/clilib.php");
require_once("{$CFG->libdir}/cronlib.php");
list($options, $unrecognized) = cli_get_params(
[
'execute' => false,
'help' => false,
'keep-alive' => 0,
'showsql' => false,
'showdebugging' => false,
'execute' => false,
'keep-alive' => 0,
'ignorelimits' => false,
'force' => false,
'id' => null,
'classname' => null,
'taskslimit' => null,
'failed' => false,
], [
'h' => 'help',
'e' => 'execute',
'k' => 'keep-alive',
'i' => 'ignorelimits',
'f' => 'force',
'c' => 'classname',
'l' => 'taskslimit',
]
);
@@ -57,7 +52,8 @@ if ($unrecognized) {
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
$help = <<<EOT
if ($options['help'] or empty($options['execute'])) {
$help = <<<EOT
Ad hoc cron tasks.
Options:
@@ -68,32 +64,22 @@ Options:
-k, --keep-alive=N Keep this script alive for N seconds and poll for new adhoc tasks
-i --ignorelimits Ignore task_adhoc_concurrency_limit and task_adhoc_max_runtime limits
-f, --force Run even if cron is disabled
--id Run (failed) task with id
-c, --classname Run tasks with a certain classname (FQN)
-l, --taskslimit=N Run at most N tasks
--failed Run only tasks that failed, ie those with a fail delay
Run all queued tasks:
Example:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --execute
Run all queued tasks of specific class:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --classname=\\\\core_course\\\\task\\\\course_delete_modules
Double backslash for the shell escape reasons.
Run a specific task:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --id=123456
Run a specific task with debugging:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --id=123456 --showsql --showdebugging
To profile a long running task:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --taskslimit=1 --classname='\\some\\class\\name' --ignorelimits
EOT;
if ($options['help']) {
echo $help;
exit(0);
die;
}
if ($options['showdebugging']) {
set_debugging(DEBUG_DEVELOPER, true);
}
if ($options['showsql']) {
$DB->set_debug(true);
}
if (CLI_MAINTENANCE) {
@@ -106,18 +92,17 @@ if (moodle_needs_upgrading()) {
exit(1);
}
if (empty($options['execute'])) {
exit(0);
}
if (!get_config('core', 'cron_enabled') && !$options['force']) {
mtrace('Cron is disabled. Use --force to override.');
exit(1);
}
// Common debugging options.
if ($options['showdebugging']) {
set_debugging(DEBUG_DEVELOPER, true);
}
if ($options['showsql']) {
$DB->set_debug(true);
if (empty($options['keep-alive'])) {
$options['keep-alive'] = 0;
}
if (!empty($CFG->showcronsql)) {
@@ -127,48 +112,20 @@ if (!empty($CFG->showcrondebugging)) {
set_debugging(DEBUG_DEVELOPER, true);
}
// Process params.
$checklimits = empty($options['ignorelimits']);
core_php_time_limit::raise();
// Increase memory limit.
raise_memory_limit(MEMORY_EXTRA);
// Emulate normal session - we use admin account by default.
\core\cron::setup_user();
cron_setup_user();
$humantimenow = date('r', time());
$keepalive = (int)$options['keep-alive'];
\core\local\cli\shutdown::script_supports_graceful_exit();
$humantimenow = date('r', time());
mtrace("Server Time: {$humantimenow}\n");
$classname = $options['classname'];
// Run a single adhoc task only, if requested.
if (!empty($options['id'])) {
$taskid = (int) $options['id'];
\core\cron::run_adhoc_task($taskid);
exit(0);
}
// Run all failed tasks.
if (!empty($options['failed'])) {
\core\cron::run_failed_adhoc_tasks($classname);
exit(0);
}
// Examine params and determine if we should run.
$execute = (bool) $options['execute'];
$keepalive = empty($options['keep-alive']) ? 0 : (int) $options['keep-alive'];
$taskslimit = empty($options['taskslimit']) ? null : (int) $options['taskslimit'];
$checklimits = empty($options['ignorelimits']);
if ($classname || $keepalive || $taskslimit) {
$execute = true;
}
// Output the help text if no criteria for running the adhoc tasks are given.
if (!$execute) {
echo $help;
exit(0);
}
\core\cron::run_adhoc_tasks(time(), $keepalive, $checklimits, null, $taskslimit, $classname);
cron_run_adhoc_tasks(time(), $keepalive, $checklimits);
+5 -4
View File
@@ -30,6 +30,7 @@ define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php'); // cli only functions
require_once($CFG->libdir.'/cronlib.php');
// now get cli options
list($options, $unrecognized) = cli_get_params(array('help'=>false),
@@ -79,10 +80,10 @@ if (!empty($CFG->showcrondebugging)) {
$starttime = microtime();
// Emulate normal session.
\core\cron::setup_user();
/// emulate normal session
cron_setup_user();
// Start output log.
/// Start output log
$timenow = time();
mtrace("Server Time: ".date('r',$timenow)."\n\n");
@@ -95,4 +96,4 @@ backup_cron_automated_helper::run_automated_backup(backup_cron_automated_helper:
mtrace("Automated cron backups completed correctly");
$difftime = microtime_diff($starttime, microtime());
mtrace("Execution took ".$difftime." seconds");
mtrace("Execution took ".$difftime." seconds");
+7 -23
View File
@@ -33,7 +33,6 @@ require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
list($options, $unrecognized) = cli_get_params(array(
'courseid' => false,
'courseshortname' => '',
'cmid' => false,
'destination' => '',
'help' => false,
), array('h' => 'help'));
@@ -43,14 +42,13 @@ if ($unrecognized) {
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help'] || !($options['courseid'] || $options['courseshortname'] || $options['cmid'])) {
if ($options['help'] || !($options['courseid'] || $options['courseshortname'])) {
$help = <<<EOL
Perform backup of the given course or course module.
Perform backup of the given course.
Options:
--courseid=INTEGER Course ID for backup.
--courseshortname=STRING Course shortname for backup. This option is ignored if courseid is set.
--cmid=INTEGER Course module ID for backup. This option is ignored if courseid or courseshortname is set.
--courseshortname=STRING Course shortname for backup.
--destination=STRING Path where to store backup file. If not set the backup
will be stored within the course backup file area.
-h, --help Print out this help.
@@ -78,26 +76,16 @@ if (!empty($dir)) {
}
}
// Check that the course or course module exists.
// Check that the course exists.
if ($options['courseid']) {
$course = $DB->get_record('course', array('id' => $options['courseid']), '*', MUST_EXIST);
} else if ($options['courseshortname']) {
$course = $DB->get_record('course', array('shortname' => $options['courseshortname']), '*', MUST_EXIST);
} else if ($options['cmid']) {
$cm = $DB->get_record('course_modules', ['id' => $options['cmid']], '*', MUST_EXIST);
}
cli_heading('Performing backup...');
if (!empty($course)) {
$bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE,
backup::INTERACTIVE_YES, backup::MODE_GENERAL, $admin->id);
} else if (!empty($cm)) {
$bc = new backup_controller(backup::TYPE_1ACTIVITY, $cm->id, backup::FORMAT_MOODLE,
backup::INTERACTIVE_YES, backup::MODE_GENERAL, $admin->id);
} else {
throw new \moodle_exception('invalidoption');
}
$bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE,
backup::INTERACTIVE_YES, backup::MODE_GENERAL, $admin->id);
// Set the default filename.
$format = $bc->get_format();
$type = $bc->get_type();
@@ -125,11 +113,7 @@ if (!empty($dir)) {
}
}
} else {
if (!empty($course)) {
mtrace("Backup completed, the new file is listed in the backup area of the given course");
} else {
mtrace("Backup completed, the new file is listed in the backup area of the given module");
}
mtrace("Backup completed, the new file is listed in the backup area of the given course");
}
$bc->destroy();
exit(0);
+13 -21
View File
@@ -1,4 +1,5 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -29,11 +30,12 @@
define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/clilib.php');
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php'); // cli only functions
require_once($CFG->libdir.'/cronlib.php');
// Now get cli option.
[$options, $unrecognized] = cli_get_params(
// now get cli options
list($options, $unrecognized) = cli_get_params(
[
'help' => false,
'stop' => false,
@@ -42,9 +44,7 @@ require_once($CFG->libdir . '/clilib.php');
'enable' => false,
'disable' => false,
'disable-wait' => false,
'keep-alive' => null,
],
[
], [
'h' => 'help',
's' => 'stop',
'l' => 'list',
@@ -52,7 +52,6 @@ require_once($CFG->libdir . '/clilib.php');
'e' => 'enable',
'd' => 'disable',
'w' => 'disable-wait',
'k' => 'keep-alive',
]
);
@@ -63,7 +62,7 @@ if ($unrecognized) {
if ($options['help']) {
$help =
"Execute periodic cron actions.
"Execute periodic cron actions.
Options:
-h, --help Print out this help
@@ -73,9 +72,6 @@ Options:
-e, --enable Enable cron
-d, --disable Disable cron
-w, --disable-wait=600 Disable cron and wait until all tasks finished or fail after N seconds (optional param)
-k, --keep-alive=N Keep this script alive for N seconds and poll for new tasks
The default value can be set by administrators in:
Site administration > Server > Tasks > Task processing > Keep alive time
Example:
\$sudo -u www-data /usr/bin/php admin/cli/cron.php
@@ -109,8 +105,7 @@ if ($options['list']) {
$tasks = \core\task\manager::get_running_tasks();
mtrace('The list of currently running tasks:');
$format = "%7s %-12s %-9s %-20s %-52s\n";
printf(
$format,
printf ($format,
'PID',
'HOST',
'TYPE',
@@ -118,8 +113,7 @@ if ($options['list']) {
'CLASSNAME'
);
foreach ($tasks as $task) {
printf(
$format,
printf ($format,
$task->pid,
substr($task->hostname, 0, 12),
$task->type,
@@ -143,7 +137,7 @@ if ($wait = $options['disable-wait']) {
set_config('cron_enabled', 0);
\core\task\manager::clear_static_caches();
mtrace('Cron has been disabled for the site.');
mtrace('Allocating ' . format_time($waitsec) . ' for the tasks to finish.');
mtrace('Allocating '. format_time($waitsec) . ' for the tasks to finish.');
$lastcount = 0;
while ($wait) {
@@ -157,7 +151,7 @@ if ($wait = $options['disable-wait']) {
if (time() - $started >= $waitsec) {
mtrace('');
mtrace('Wait time (' . format_time($waitsec) . ') elapsed, but ' . count($tasks) . ' task(s) still running.');
mtrace('Wait time ('. format_time($waitsec) . ') elapsed, but ' . count($tasks) . ' task(s) still running.');
mtrace('Exiting with code 1.');
exit(1);
}
@@ -181,6 +175,4 @@ if (!get_config('core', 'cron_enabled') && !$options['force']) {
\core\local\cli\shutdown::script_supports_graceful_exit();
$keepalive = $options['keep-alive'];
\core\cron::run_main_process($keepalive);
cron_run();
+1
View File
@@ -28,6 +28,7 @@ define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/clilib.php');
require_once($CFG->libdir . '/cronlib.php');
list($options, $unrecognized) = cli_get_params(
[
-209
View File
@@ -1,209 +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/>.
/**
* This script allows you to view and change the emailstop flag of any user.
*
* @package core
* @subpackage cli
* @copyright 2023 Stephan Robotta (stephan.robotta@bfh.ch)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
// Define the input options.
$longparams = [
'email' => '',
'help' => false,
'id' => '',
'quiet' => false,
'stop' => '',
'username' => '',
];
$shortparams = [
'e' => 'email',
'h' => 'help',
'i' => 'id',
'q' => 'quiet',
's' => 'stop',
'u' => 'username',
];
// Define exit codes.
$exitsuccess = 0;
$exitunknownoption = 1;
$exitmissinguserarg = 2;
$exittoomanyuserarg = 3;
$exitnosearchargs = 4;
$exitnousersfound = 5;
$exitinvalidstopflag = 6;
$exiterrordb = 7;
// Now get cli options that are set by the caller.
list($options, $unrecognized) = cli_get_params($longparams, $shortparams);
$verbose = empty($options['quiet']);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
if ($verbose) {
cli_error(get_string('cliunknowoption', 'admin', $unrecognized), $exitunknownoption);
}
exit($exitunknownoption);
}
if ($options['help']) {
$help =
"Set/unset or show status of emailstop flag for a user, identified by username or email.
There are no security checks here because anybody who is able to
execute this file may execute any PHP too.
Options:
-h, --help Print out this help
-e, --email=email Specify user by email, separate many users by comma
-i, --id=id Specify user by id, separate many users by comma
-q, --quiet No output to stdout
-s, --stop=0|1|off|on Set new value for emailstop flag
-u, --username=username Specify user by username, separate many users by comma
Example:
\$sudo -u www-data /usr/bin/php admin/cli/emailstop.php --email=student1@example.com --stop=1
\$sudo -u www-data /usr/bin/php admin/cli/emailstop.php --email=student1@example.com,student2@example.com
\$sudo -u www-data /usr/bin/php admin/cli/emailstop.php --u=student1,student2 -s=on
";
echo $help;
exit($exitsuccess);
}
$cntempty = 0;
$cntfilled = 0;
$searchargs = [];
// Try to find out which option is used to fetch the users from. Also do sanitize etc.
foreach (['email', 'username', 'id'] as $option) {
if (empty($options[$option])) {
$cntempty++;
} else {
$cntfilled++;
$argname = $option;
// The search args must be: split by the comma, trimmed, and empty elements filtered out.
$searchargs = array_flip(array_filter(
array_map(
function ($item) {
return trim($item);
},
explode(',', $options[$option])
),
function ($item) {
return $item !== '';
}
));
}
}
if ($cntempty === 3) {
if ($verbose) {
cli_error('One of username, email, or id must be set.', $exitmissinguserarg);
}
exit($exitmissinguserarg);
}
if ($cntfilled > 1) {
if ($verbose) {
cli_error('Only one of email, username, or id can be set to identify a user.', $exittoomanyuserarg);
}
exit($exittoomanyuserarg);
}
if (empty($searchargs)) {
if ($verbose) {
cli_error('No values are provided for users.', $exitnosearchargs);
}
exit($exitnosearchargs);
}
try {
$users = $DB->get_records_list('user', $argname, array_keys($searchargs));
} catch (Exception $e) {
if ($verbose) {
cli_error("Could not fetch data from db by {$argname}: '{$options[$argname]}'.", $exiterrordb);
}
exit($exiterrordb);
}
if (empty($users)) {
if ($verbose) {
cli_error("Can not find any user by {$argname}: '{$options[$argname]}'.", $exitnousersfound);
}
exit($exitnousersfound);
}
// No stop flag set, then just print the user and the current emailstop flag state.
if ($options['stop'] === '') {
foreach ($users as $user) {
if ($verbose) {
echo 'user=' . $user->{$argname} . ' - emailstop=' . (int)$user->emailstop . PHP_EOL;
unset($searchargs[$user->{$argname}]);
}
}
if ($verbose) {
foreach (array_keys($searchargs) as $arg) {
echo 'user=' . $arg . ' - not found' . PHP_EOL;
}
}
exit($exitsuccess);
}
// Allowed values for the stop flag enabled are 1 and on, for disabled are 0 and off.
$validvalues = ['0', '1', 'off', 'on'];
$stopflag = strtolower($options['stop']);
if (!in_array($stopflag, $validvalues)) {
if ($verbose) {
cli_error('Value for the emailstop flag must be one of: ' . implode(', ', $validvalues) . '.', $exitinvalidstopflag);
}
exit($exitinvalidstopflag);
}
foreach ($validvalues as $value) {
if ($value === $stopflag) {
$stopflag = ($value === '1' || $value === 'on') ? 1 : 0;
break;
}
}
// Update each user with the stop flag to be set if it is necessary.
foreach ($users as $user) {
$line = 'Update user ' . $user->{$argname} . ($argname !== 'id' ? ' (' . $user->id . ')' : '') . ' - ';
if ((int)$user->emailstop !== $stopflag) {
$DB->set_field('user', 'emailstop', $stopflag, ['id' => $user->id]);
$line .= 'ok';
} else {
$line .= 'already done';
}
if ($verbose) {
echo $line . PHP_EOL;
unset($searchargs[$user->{$argname}]);
}
}
if ($verbose) {
foreach (array_keys($searchargs) as $arg) {
echo 'user=' . $arg . ' - not found' . PHP_EOL;
}
}
exit($exitsuccess);
+5 -1
View File
@@ -39,6 +39,8 @@ if ($unrecognized) {
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
// TODO: MDL-71421 - Remove the openssl alternative once sodium becomes a requirement in Moodle 4.2.
if ($options['help']) {
echo "Generate secure key
@@ -52,7 +54,9 @@ may be manually installed on multiple servers.
Options:
-h, --help Print out this help
--method <method> Generate key for specified encryption method instead of default (sodium)
--method <method> Generate key for specified encryption method instead of default.
* sodium
* openssl-aes-256-ctr
Example:
php admin/cli/generate_key.php
-132
View File
@@ -1,132 +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/>.
/**
* This script allows to import a course from CLI.
*
* @package core
* @subpackage cli
* @author Tomo Tsuyuki <tomotsuyuki@catalyst-au.net>
* @copyright 2023 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', 1);
require(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/clilib.php');
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
require_once($CFG->dirroot . "/backup/util/includes/restore_includes.php");
list($options, $unrecognized) = cli_get_params([
'srccourseid' => '',
'srccmid' => '',
'dstcourseid' => '',
'showdebugging' => false,
'help' => false,
], [
's' => 'showdebugging',
'h' => 'help',
]);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help'] ||
!(($options['srccourseid'] && $options['dstcourseid'])
|| ($options['srccmid'] && $options['dstcourseid']))) {
$help = <<<EOL
Import course or course module into provided course.
Options:
--srccourseid=INT Source course ID to backup.
--srccmid=INT Source course module ID to backup.
--dstcourseid=INT Destination course ID to restore.
-s, --showdebugging Show developer level debugging information
-h, --help Print out this help.
Example1: (Import from a course into another course)
\$sudo -u www-data /usr/bin/php admin/cli/import.php --srccourseid=12 --dstcourseid=13\n
Example2: (Import from a course module into a course)
\$sudo -u www-data /usr/bin/php admin/cli/import.php --srccmid=21 --dstcourseid=11\n
EOL;
echo $help;
exit(0);
}
if ($options['showdebugging']) {
set_debugging(DEBUG_DEVELOPER, true);
}
if (!$admin = get_admin()) {
throw new \moodle_exception('noadmins');
}
if (!empty($options['srccourseid']) && !empty($options['dstcourseid'])) {
// Import from course into course.
if (!$srccourse = $DB->get_record('course', ['id' => $options['srccourseid']], 'id')) {
throw new \moodle_exception('invalidcourseid');
}
if (!$dstcourse = $DB->get_record('course', ['id' => $options['dstcourseid']], 'id')) {
throw new \moodle_exception('invalidcourseid');
}
cli_heading(get_string('importfromcoursetocourse', 'backup', (object)$options));
$bc = new backup_controller(backup::TYPE_1COURSE, $srccourse->id, backup::FORMAT_MOODLE,
backup::INTERACTIVE_NO, backup::MODE_IMPORT, $admin->id);
$backupid = $bc->get_backupid();
$bc->execute_plan();
$bc->destroy();
cli_heading(get_string('backupthenrestore', 'backup'));
$rc = new restore_controller($backupid, $dstcourse->id, backup::INTERACTIVE_NO,
backup::MODE_SAMESITE, $admin->id, backup::TARGET_EXISTING_ADDING);
$rc->execute_precheck();
$rc->execute_plan();
$rc->destroy();
cli_heading(get_string('restoredcourseid', 'backup', $dstcourse->id));
} else if (!empty($options['srccmid']) && !empty($options['dstcourseid'])) {
// Import from course module into course.
if (!$cm = $DB->get_record('course_modules', ['id' => $options['srccmid']], 'id')) {
throw new \moodle_exception('invalidcoursemoduleid', 'error', '', $options['srccmid']);
}
if (!$course = $DB->get_record('course', ['id' => $options['dstcourseid']], 'id')) {
throw new \moodle_exception('invalidcourseid');
}
cli_heading(get_string('importfromccmidtocourse', 'backup', (object)$options));
$bc = new backup_controller(backup::TYPE_1ACTIVITY, $cm->id, backup::FORMAT_MOODLE,
backup::INTERACTIVE_NO, backup::MODE_IMPORT, $admin->id);
$backupid = $bc->get_backupid();
$bc->execute_plan();
$bc->destroy();
cli_heading(get_string('backupthenrestore', 'backup'));
$rc = new restore_controller($backupid, $course->id, backup::INTERACTIVE_NO,
backup::MODE_SAMESITE, $admin->id, backup::TARGET_EXISTING_ADDING);
$rc->execute_precheck();
$rc->execute_plan();
$rc->destroy();
cli_heading(get_string('restoredcourseid', 'backup', $course->id));
} else {
throw new \moodle_exception('invalidoption');
}
exit(0);
+11 -7
View File
@@ -172,16 +172,11 @@ $CFG->debugdeveloper = true;
$parts = explode('/', str_replace('\\', '/', dirname(__DIR__)));
$CFG->admin = array_pop($parts);
// Point pear include path to moodles lib/pear so that includes and requires will search there for files before anywhere else
// the problem is that we need specific version of quickforms and hacked excel files :-(.
//point pear include path to moodles lib/pear so that includes and requires will search there for files before anywhere else
//the problem is that we need specific version of quickforms and hacked excel files :-(
ini_set('include_path', $CFG->libdir.'/pear' . PATH_SEPARATOR . ini_get('include_path'));
// The core_component class can be used in any scripts, it does not need anything else.
require_once($CFG->libdir.'/classes/component.php');
// Register our classloader.
\core\component::register_autoloader();
require_once($CFG->libdir.'/classes/text.php');
require_once($CFG->libdir.'/classes/string_manager.php');
require_once($CFG->libdir.'/classes/string_manager_install.php');
@@ -195,6 +190,15 @@ require_once($CFG->libdir.'/moodlelib.php');
require_once($CFG->libdir.'/deprecatedlib.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/componentlib.class.php');
require_once($CFG->dirroot.'/cache/lib.php');
// Register our classloader, in theory somebody might want to replace it to load other hacked core classes.
// Required because the database checks below lead to session interaction which is going to lead us to requiring autoloaded classes.
if (defined('COMPONENT_CLASSLOADER')) {
spl_autoload_register(COMPONENT_CLASSLOADER);
} else {
spl_autoload_register('core_component::classloader');
}
require($CFG->dirroot.'/version.php');
$CFG->target_release = $release;
-11
View File
@@ -57,7 +57,6 @@ Options:
--fullname=STRING Name of the site
--shortname=STRING Name of the site
--summary=STRING The summary to be displayed on the front page
--supportemail=STRING Email address for support and help.
-h, --help Print out this help
Example:
@@ -99,7 +98,6 @@ list($options, $unrecognized) = cli_get_params(
'fullname' => '',
'shortname' => '',
'summary' => '',
'supportemail' => '',
'agree-license' => false,
'help' => false
),
@@ -138,15 +136,6 @@ if (!empty($options['adminemail']) && !validate_email($options['adminemail'])) {
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
// Validate that the supportemail provided was an e-mail address.
if (!empty($options['supportemail']) && !validate_email($options['supportemail'])) {
$a = (object) [
'option' => 'supportemail',
'value' => $options['supportemail']
];
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
$options['lang'] = clean_param($options['lang'], PARAM_SAFEDIR);
if (!file_exists($CFG->dirroot.'/install/lang/'.$options['lang'])) {
$options['lang'] = 'en';
+1 -1
View File
@@ -50,6 +50,6 @@ Example:
exit(0);
}
\core\session\manager::destroy_all();
\core\session\manager::kill_all_sessions();
exit(0);
+9 -18
View File
@@ -69,7 +69,7 @@ if ($options['enablelater']) {
}
$time = time() + ($options['enablelater']*60);
set_config('maintenance_later', $time, null, true);
set_config('maintenance_later', $time);
echo get_string('clistatusenabledlater', 'admin', userdate($time))."\n";
return 0;
@@ -77,32 +77,23 @@ if ($options['enablelater']) {
} else if ($options['enable']) {
if (file_exists("$CFG->dataroot/climaintenance.html")) {
// The maintenance is already enabled, nothing to do.
exit(0);
}
enable_cli_maintenance_mode();
set_config('maintenance_enabled', 'cli mode', null, true);
if (isset($CFG->maintenance_later)) {
unset_config('maintenance_later', null, true);
} else {
enable_cli_maintenance_mode();
}
set_config('maintenance_enabled', 0);
unset_config('maintenance_later');
echo get_string('sitemaintenanceoncli', 'admin')."\n";
exit(0);
} else if ($options['enableold']) {
set_config('maintenance_enabled', 1, null, true);
if (isset($CFG->maintenance_later)) {
unset_config('maintenance_later', null, true);
}
set_config('maintenance_enabled', 1);
unset_config('maintenance_later');
echo get_string('sitemaintenanceon', 'admin')."\n";
exit(0);
} else if ($options['disable']) {
if ($CFG->maintenance_enabled !== '0') {
set_config('maintenance_enabled', 0, null, true);
}
if (isset($CFG->maintenance_later)) {
unset_config('maintenance_later', null, true);
}
set_config('maintenance_enabled', 0);
unset_config('maintenance_later');
if (file_exists("$CFG->dataroot/climaintenance.html")) {
unlink("$CFG->dataroot/climaintenance.html");
}
-4
View File
@@ -24,7 +24,6 @@
*/
define('CLI_SCRIPT', true);
define('IGNORE_COMPONENT_CACHE', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
@@ -32,7 +31,6 @@ require_once($CFG->libdir.'/clilib.php');
$longoptions = [
'help' => false,
'muc' => false,
'courses' => false,
'theme' => false,
'lang' => false,
'js' => false,
@@ -57,8 +55,6 @@ all caches will be purged.
Options:
-h, --help Print out this help
--muc Purge all MUC caches (includes lang cache)
--courses Purge all course caches (or only those specified by a comma-separated list).
e.g. --courses=4,67,145
--theme Purge theme cache
--lang Purge language string cache
--js Purge JavaScript cache
+17 -68
View File
@@ -32,13 +32,11 @@ require_once($CFG->dirroot . "/backup/util/includes/restore_includes.php");
list($options, $unrecognized) = cli_get_params([
'file' => '',
'categoryid' => '',
'courseid' => '',
'showdebugging' => false,
'help' => false,
], [
'f' => 'file',
'c' => 'categoryid',
'C' => 'courseid',
's' => 'showdebugging',
'h' => 'help',
]);
@@ -48,21 +46,18 @@ if ($unrecognized) {
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help'] || !($options['file']) || !($options['categoryid'] || $options['courseid'])) {
if ($options['help'] || !($options['file']) || !($options['categoryid'])) {
$help = <<<EOL
Restore backup into provided category or course.
If courseid is set, course module/s will be added into the course.
Restore backup into provided category.
Options:
-f, --file=STRING Path to the backup file.
-c, --categoryid=INT ID of the course category to restore to. This option is ignored when restoring an activity and courseid is set.
-C, --courseid=INT ID of the course to restore to. This option is ignored when restoring a course and the categoryid is set.
-s, --showdebugging Show developer level debugging information
-h, --help Print out this help.
-f, --file=STRING Path to the backup file.
-c, --categoryid=INT ID of the category to restore too.
-s, --showdebugging Show developer level debugging information
-h, --help Print out this help.
Example:
\$sudo -u www-data /usr/bin/php admin/cli/restore_backup.php --file=/path/to/backup/coursebackup.mbz --categoryid=1\n
\$sudo -u www-data /usr/bin/php admin/cli/restore_backup.php --file=/path/to/backup/activitybackup.mbz --courseid=1\n
\$sudo -u www-data /usr/bin/php admin/cli/restore_backup.php --file=/path/to/backup/file.mbz --categoryid=1\n
EOL;
echo $help;
@@ -81,75 +76,29 @@ if (!file_exists($options['file'])) {
throw new \moodle_exception('filenotfound');
}
if ($options['categoryid']) {
if (!$category = $DB->get_record('course_categories', ['id' => $options['categoryid']], 'id')) {
throw new \moodle_exception('invalidcategoryid');
}
if (!$category = $DB->get_record('course_categories', ['id' => $options['categoryid']], 'id')) {
throw new \moodle_exception('invalidcategoryid');
}
if ($options['courseid']) {
if (!$course = $DB->get_record('course', ['id' => $options['courseid']], 'id')) {
throw new \moodle_exception('invalidcourseid');
}
}
if (empty($category) && empty($course)) {
throw new \moodle_exception('invalidoption');
}
$backupdir = restore_controller::get_tempdir_name(SITEID, $USER->id);
$path = make_backup_temp_directory($backupdir);
$backupdir = "restore_" . uniqid();
$path = $CFG->tempdir . DIRECTORY_SEPARATOR . "backup" . DIRECTORY_SEPARATOR . $backupdir;
cli_heading(get_string('extractingbackupfileto', 'backup', $path));
$fp = get_file_packer('application/vnd.moodle.backup');
$fp->extract_to_pathname($options['file'], $path);
cli_heading(get_string('preprocessingbackupfile'));
try {
// Create a temporary restore controller to determine the restore type.
$tmprc = new restore_controller($backupdir, SITEID, backup::INTERACTIVE_NO,
backup::MODE_GENERAL, $admin->id, backup::TARGET_EXISTING_ADDING);
// Restore the backup into a new course if:
// - It is a course backup and the category is set.
// - It is an activity backup and the course is not set.
$restoreasnewcourse = ($tmprc->get_type() === backup::TYPE_1COURSE && !empty($category)) ||
($tmprc->get_type() !== backup::TYPE_1COURSE && empty($course));
// Make sure to clean up the temporary restore controller.
$tmprc->destroy();
list($fullname, $shortname) = restore_dbops::calculate_course_names(0, get_string('restoringcourse', 'backup'),
get_string('restoringcourseshortname', 'backup'));
if ($restoreasnewcourse) {
list($fullname, $shortname) = restore_dbops::calculate_course_names(0, get_string('restoringcourse', 'backup'),
get_string('restoringcourseshortname', 'backup'));
$courseid = restore_dbops::create_new_course($fullname, $shortname, $category->id);
$rc = new restore_controller($backupdir, $courseid, backup::INTERACTIVE_NO,
backup::MODE_GENERAL, $admin->id, backup::TARGET_NEW_COURSE);
} else {
$courseid = $course->id;
$rc = new restore_controller($backupdir, $courseid, backup::INTERACTIVE_NO,
backup::MODE_GENERAL, $admin->id, backup::TARGET_EXISTING_ADDING);
}
$courseid = restore_dbops::create_new_course($fullname, $shortname, $category->id);
$rc = new restore_controller($backupdir, $courseid, backup::INTERACTIVE_NO,
backup::MODE_GENERAL, $admin->id, backup::TARGET_NEW_COURSE);
$rc->execute_precheck();
$rc->execute_plan();
$rc->destroy();
// Rename the course's full and short names with the backup file's original names if the backup file is an activity backup
// that is restored to a new course.
if ($restoreasnewcourse && $rc->get_type() !== backup::TYPE_1COURSE) {
$course = get_course($courseid);
$backupinfo = $rc->get_info();
$tmpfullname = $backupinfo->original_course_fullname ?? get_string('restoretonewcourse', 'backup');
$tmpshortname = $backupinfo->original_course_shortname ?? get_string('newcourse');
list($fullname, $shortname) = restore_dbops::calculate_course_names(
courseid: 0,
fullname: $tmpfullname,
shortname: $tmpshortname,
);
$course->fullname = $fullname;
$course->shortname = $shortname;
$course->visible = 1;
$DB->update_record('course', $course);
}
} catch (Exception $e) {
cli_heading(get_string('cleaningtempdata'));
fulldelete($path);
+15 -42
View File
@@ -27,6 +27,7 @@ define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once("$CFG->libdir/clilib.php");
require_once("$CFG->libdir/cronlib.php");
list($options, $unrecognized) = cli_get_params(
[
@@ -36,8 +37,6 @@ list($options, $unrecognized) = cli_get_params(
'showsql' => false,
'showdebugging' => false,
'force' => false,
'disable' => false,
'enable' => false,
], [
'h' => 'help',
'f' => 'force',
@@ -49,15 +48,11 @@ if ($unrecognized) {
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
$commands = ['list', 'execute', 'disable', 'enable'];
$hascommand = count(array_filter($commands, fn($command) => $options[$command])) > 0;
if ($options['help'] || !$hascommand) {
if ($options['help'] or (!$options['list'] and !$options['execute'])) {
$help =
"Scheduled cron tasks.
Options:
--disable=\\some\\task Disable scheduled task
--enable=\\some\\task Enable scheduled task
--execute=\\some\\task Execute scheduled task manually
--list List all scheduled tasks
--showsql Show sql queries before they are executed
@@ -125,43 +120,17 @@ if ($options['list']) {
exit(0);
}
if (moodle_needs_upgrading()) {
mtrace("Moodle upgrade pending, cannot manage tasks.");
exit(1);
}
if ($disable = $options['disable']) {
if (!$task = \core\task\manager::get_scheduled_task($disable)) {
mtrace("Task '$disable' not found");
exit(1);
}
try {
$task->disable();
mtrace("Disabled '$disable'");
} catch (Exception $e) {
mtrace("$e->getMessage()");
exit(1);
}
} else if ($enable = $options['enable']) {
if (!$task = \core\task\manager::get_scheduled_task($enable)) {
mtrace("Task '$enable' not found");
exit(1);
}
try {
$task->enable();
mtrace("Enabled '$enable'");
} catch (Exception $e) {
mtrace("$e->getMessage()");
exit(1);
}
} else if ($execute = $options['execute']) {
if ($execute = $options['execute']) {
if (!$task = \core\task\manager::get_scheduled_task($execute)) {
mtrace("Task '$execute' not found");
exit(1);
}
if (moodle_needs_upgrading()) {
mtrace("Moodle upgrade pending, cannot execute tasks.");
exit(1);
}
if (!get_config('core', 'cron_enabled') && !$options['force']) {
mtrace('Cron is disabled. Use --force to override.');
exit(1);
@@ -173,7 +142,7 @@ if ($disable = $options['disable']) {
raise_memory_limit(MEMORY_EXTRA);
// Emulate normal session - we use admin account by default.
\core\cron::setup_user();
cron_setup_user();
// Execute the task.
\core\local\cli\shutdown::script_supports_graceful_exit();
@@ -189,7 +158,11 @@ if ($disable = $options['disable']) {
}
$task->set_lock($lock);
$cronlock->release();
if (!$task->is_blocking()) {
$cronlock->release();
} else {
$task->set_cron_lock($cronlock);
}
\core\cron::run_inner_scheduled_task($task);
cron_run_inner_scheduled_task($task);
}
+3 -3
View File
@@ -158,13 +158,13 @@ if ($options['plugins']) {
if (is_null($plugin)) {
cli_writeln('Unknown plugin: ' . $component);
} else {
$pluginstring = $component . "\t" . $plugin->displayname;
$pluginstring = $plugin->component . "\t" . $plugin->displayname;
if ($pluginman->can_uninstall_plugin($component)) {
if ($pluginman->can_uninstall_plugin($plugin->component)) {
if ($options['run']) {
cli_writeln('Uninstalling: ' . $pluginstring);
$progress = new progress_trace_buffer(new text_progress_trace(), true);
$pluginman->uninstall_plugin($component, $progress);
$pluginman->uninstall_plugin($plugin->component, $progress);
$progress->finished();
cli_write($progress->get_buffer());
} else {

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