Compare commits

...

1641 Commits

Author SHA1 Message Date
Huong Nguyen eb47eff071 Moodle release 5.1 2025-10-04 09:06:25 +07:00
Huong Nguyen 97bc3e3bde NOBUG: Add upgrade notes 2025-10-04 09:06:25 +07:00
AMOS bot fcad94c75d Automatically generated installer lang files 2025-10-04 00:08:09 +00:00
Shamim Rezaie 80a00e5fa5 Moodle release 5.1rc2 2025-10-03 20:03:45 +10:00
Shamim Rezaie 7d639b284f NOBUG: Add upgrade notes 2025-10-03 20:03:45 +10:00
Mihail Geshoski 05c3ba3087 MDL-75087 mod_assign: Fix failing behat tests in classic 2025-10-03 14:21:36 +07:00
Huong Nguyen 9034a16c0f MDL-86353 libraries: Moodle customization 2025-10-03 08:26:09 +07:00
Huong Nguyen 27fbf3a733 MDL-86782 block_activity_modules: Bump version 2025-10-02 19:56:56 +07:00
Mihail Geshoski 32b9566e3c Merge branch 'MDL-86782-main' of https://github.com/HuongNV13/moodle 2025-10-02 20:35:58 +08:00
Huong Nguyen d7de92b5a9 MDL-86782 block: Revert "MDL-83887: Remove activity_modules block"
This reverts commit 4885314a19.
2025-10-02 19:32:02 +07:00
Mihail Geshoski 5fdef6b986 MDL-75087 mod_assign: Fix failing unit test 2025-10-02 18:08:29 +07:00
Mihail Geshoski e99a3bde89 Merge branch 'MDL-86792-main' of https://github.com/HuongNV13/moodle 2025-10-02 17:13:39 +08:00
Huong Nguyen ff21ed3e55 MDL-86792 versions: Main version bump 2025-10-02 10:19:33 +07:00
Rajneel Totaram 78a3fe6c61 MDL-75087 mod_assign: Respect assignment timer
This patch has better handling of timed assignments.
Users cannot directly access the submission page without
confirming to begin a timed assignment.
2025-10-02 11:05:23 +08:00
Huong Nguyen 3ee8eaf1c5 MDL-86792 versions: Bump all versions and requires near release 2025-10-02 09:32:41 +07:00
raortegar c896740f1b MDL-86253 mod_assign: Respect enrollment status in notifications 2025-10-02 08:14:46 +07:00
raortegar b7a2e28e52 MDL-86253 mod_quiz: Respect enrollment status in notifications 2025-10-02 08:14:46 +07:00
Mihail Geshoski 2b5108f4f3 Merge branch 'MDL-86791-main' of https://github.com/Jayce0808/moodle 2025-10-02 00:26:14 +08:00
Mihail Geshoski 5615f2aeff Merge branch 'MDL-86760' of https://github.com/paulholden/moodle 2025-10-01 16:11:30 +08:00
Jake Dallimore c231451003 Merge branch 'MDL-86364-main' of https://github.com/mihailges/moodle 2025-10-01 15:51:21 +08:00
Mihail Geshoski 975eb78b40 MDL-86364 calendar: Fix calendar table styles 2025-10-01 14:26:28 +08:00
David Woloszyn 5d4910509e MDL-86494 router: Display error details only when debugging is on 2025-10-01 06:24:16 +00:00
David Woloszyn 5e7d5abc48 MDL-86335 router: Hide detailed payload data for non-admins 2025-10-01 06:24:16 +00:00
yusufwib01 e23160017c MDL-86353 libraries: Upgrade FPDI to 2.6.4 2025-10-01 06:24:16 +00:00
Paul Holden 05c7e1357c MDL-85421 cohort: limit requests for all cohorts to system context. 2025-10-01 06:24:16 +00:00
Paul Holden fc69b4744b MDL-86426 course: access checks in course overview fragment callback. 2025-10-01 06:24:16 +00:00
David Woloszyn e4d02567c9 MDL-86327 auth_webservice: Stricter check on login 2025-10-01 06:24:16 +00:00
Paul Holden 17e84d95f1 MDL-86709 report_progress: escape identity fields in report export. 2025-10-01 06:24:16 +00:00
yusufwib01 0c70d67059 MDL-86261 calendar: Improve event form to show accessible groups 2025-10-01 06:24:16 +00:00
raortegar a2078f781a MDL-86334 tool_mfa: Improve multi-factor authentication validation. 2025-10-01 06:24:16 +00:00
Jake Dallimore 50b9aba599 Merge branch 'MDL-86800-main' of https://github.com/mihailges/moodle 2025-10-01 14:17:55 +08:00
Mihail Geshoski f4700ae791 MDL-86392 theme_boost: Prevent bootstrap style reset on YUI DataTable 2025-10-01 13:56:27 +08:00
Mihail Geshoski b10671d5d5 Merge branch 'MDL-86162' of https://github.com/paulholden/moodle 2025-10-01 13:44:07 +08:00
Mihail Geshoski e23cca9390 MDL-86800 report_outline: Fix incorrect table borders 2025-10-01 11:26:20 +08:00
Mihail Geshoski 8975a09f23 MDL-86800 rating: Fix incorrect table borders 2025-10-01 11:26:20 +08:00
Mihail Geshoski 9320a66752 MDL-86800 mod_workshop: Fix incorrect table borders 2025-10-01 11:26:20 +08:00
Mihail Geshoski 5149bc2ec2 MDL-86800 mod_scorm: Fix incorrect table borders 2025-10-01 11:26:20 +08:00
Mihail Geshoski a6c128b1a8 MDL-86800 mod_forum: Fix incorrect table borders 2025-10-01 11:26:20 +08:00
Mihail Geshoski 93256b0bb1 MDL-86800 mod_folder: Fix incorrect table borders 2025-10-01 11:26:20 +08:00
Mihail Geshoski e7aef8276a MDL-86800 mod_data: Fix incorrect table borders 2025-10-01 11:26:20 +08:00
Mihail Geshoski 55d918c37d MDL-86800 profiling: Fix incorrect table borders 2025-10-01 11:26:20 +08:00
Mihail Geshoski 834691f39e MDL-86800 grade: Fix incorrect table borders 2025-10-01 11:26:20 +08:00
Mihail Geshoski 8c590b477e MDL-86800 block_rss_client: Fix incorrect table borders 2025-10-01 11:26:20 +08:00
Mihail Geshoski 8efbb21030 MDL-86800 block_completionstatus: Fix incorrect table borders 2025-10-01 11:26:20 +08:00
Mihail Geshoski a5bc9f715a MDL-86800 block_activity_results: Fix incorrect table borders 2025-10-01 11:08:30 +08:00
Mihail Geshoski 8447d3b5eb MDL-86800 badges: Fix incorrect table borders 2025-10-01 11:08:30 +08:00
Mihail Geshoski e5fc010f84 MDL-86800 tool_xmldb: Fix incorrect table borders 2025-10-01 11:08:30 +08:00
Huong Nguyen fc64b1170f Merge branch 'MDL-85546-main' of https://github.com/raortegar/moodle 2025-10-01 08:21:40 +07:00
Huong Nguyen a3d9adb952 Merge branch 'MDL-86725-main' of https://github.com/stevandoMoodle/moodle 2025-10-01 08:14:18 +07:00
Mihail Geshoski 52d00a1752 Merge branch 'MDL-86417_main' of https://github.com/andrewhancox/moodle 2025-10-01 01:27:29 +08:00
Mihail Geshoski a623714cdf MDL-86800 tool_capability: Fix incorrect table borders 2025-09-30 22:02:41 +08:00
Mihail Geshoski cb477a1160 MDL-86800 mnet: Fix incorrect table borders 2025-09-30 22:01:55 +08:00
raortegar 67005f8b20 MDL-85546 tool_mfa: Improve handling of require MFA conditions 2025-09-30 11:12:35 +02:00
Jayce Birrell 40c946af40 MDL-86791 core_analytics: include filelib in processor 2025-09-30 16:55:06 +09:30
Shamim Rezaie aab2e9f96f Merge branch 'MDL-86752-main' of https://github.com/muhammadarnaldo/moodle 2025-09-30 17:05:00 +10:00
Mihail Geshoski 193f453ea2 Merge branch 'MDL-86688-main' of https://github.com/Jayce0808/moodle 2025-09-30 11:20:20 +08:00
Paul Holden 2e8f42ee28 MDL-86760 course: observe maximum size of activity name with renaming. 2025-09-29 20:30:12 +01:00
Huong Nguyen 4019daa7af Merge branch 'MDL-86667-main' of https://github.com/stevandoMoodle/moodle 2025-09-29 13:36:29 +07:00
Stevani Andolo 206f146ae7 MDL-86667 registration: Unset fields after site being unregistered 2025-09-29 10:30:41 +08:00
Stevani Andolo d561fa10d6 MDL-86725 grade_report: Fixed invisible search box on mobile view 2025-09-29 10:29:00 +08:00
cescobedo a828ba12c1 Moodle release 5.1rc1 2025-09-26 13:45:44 +02:00
cescobedo a6ca5eeb71 NOBUG: Add upgrade notes 2025-09-26 13:45:44 +02:00
cescobedo cafc52e5fe Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-09-26 13:45:32 +02:00
Sara Arjona 37f5795045 Merge branch 'MDL-86488-fix' of https://github.com/sarjona/moodle 2025-09-26 13:19:20 +02:00
Sara Arjona 9d55f9aa6c MDL-86488 core: Fix to remove whitespaces 2025-09-26 13:18:03 +02:00
Muhammad Arnaldo 0cc7eba7ea MDL-86752 mod_assign: hide resizer on mobile devices 2025-09-26 16:26:14 +07:00
Jayce Birrell 671495c81c MDL-86688 tool_brickfield: Include cmid in url to edit qbank 2025-09-26 17:37:03 +09:30
Huong Nguyen b84d93d9b1 Merge branch 'MDL-86511-main' of https://github.com/andimendunia/moodle 2025-09-26 11:15:34 +07:00
Andi Permana 2f1b8044ae MDL-86511 tiny_link: TinyMCE fails to insert a link using enter key 2025-09-26 11:11:08 +07:00
Mihail Geshoski 71e54825cf Merge branch 'MDL-86177' of https://github.com/paulholden/moodle 2025-09-26 12:03:29 +08:00
Jun Pataleta 847c9b4030 Merge branch 'MDL-85684' of https://github.com/paulholden/moodle 2025-09-26 11:31:12 +08:00
Huong Nguyen 9a6b9a0b2c Merge branch 'mdl-84491_redis_connection_main' of https://github.com/ngandrass/moodle 2025-09-26 10:20:32 +07:00
Mihail Geshoski c2d59d46dc Merge branch 'MDL-85803' of https://github.com/paulholden/moodle 2025-09-26 11:19:18 +08:00
Jun Pataleta 97d3e1c472 Merge branch 'MDL-86703' of https://github.com/paulholden/moodle 2025-09-26 11:11:21 +08:00
Jun Pataleta 3d8fb5350f Merge branch 'MDL-86363' of https://github.com/paulholden/moodle 2025-09-26 11:08:04 +08:00
Mihail Geshoski 2e98ab89de Merge branch 'MDL-86259_transfer_question_categories-task-resilience' of https://github.com/ziegenberg/moodle 2025-09-26 10:35:04 +08:00
Jun Pataleta 75e8d9e5c8 Merge branch 'MDL-86605' of https://github.com/paulholden/moodle 2025-09-26 10:28:31 +08:00
Jun Pataleta aa0fbcd114 Merge branch 'MDL-86383-main-enfix' of https://github.com/mudrd8mz/moodle 2025-09-26 09:48:29 +08:00
Huong Nguyen 21e346de0f Merge branch 'MDL-85419-main' of https://github.com/sharpchi/moodle 2025-09-26 08:46:41 +07:00
Huong Nguyen b06759a052 Merge branch 'MDL-80447-main-4' of https://github.com/raortegar/moodle 2025-09-26 08:24:49 +07:00
Paul Holden 698e8fe848 MDL-85803 mod_scorm: re-define language string for deleting attempts.
The previous version was re-purposed in 22cc9757 so lost meaning and
context elsewhere. Define new string for course reset elements.
2025-09-25 16:03:22 +01:00
Andrew Hancox f9cdb2ff7c MDL-86417 quiz: Fix for legacy question_set_references on backup 2025-09-25 15:57:23 +01:00
Sara Arjona a6b0ed628f Merge branch 'MDL-86744-main' of https://github.com/junpataleta/moodle 2025-09-25 12:34:31 +02:00
Sara Arjona a2c663e1f4 Merge branch 'MDL-58001-main' of https://github.com/lucisgit/moodle 2025-09-25 12:02:50 +02:00
Mihail Geshoski e01db74b46 Merge branch 'MDL-86432-main' of https://github.com/timhunt/moodle 2025-09-25 14:13:46 +08:00
Mihail Geshoski e8de05d3bf Merge branch 'MDL-86424-main' of https://github.com/lucaboesch/moodle 2025-09-25 13:11:09 +08:00
Jun Pataleta 40369e9ba0 Merge branch 'MDL-86599' of https://github.com/timhunt/moodle 2025-09-25 12:08:52 +08:00
Mihail Geshoski 12759e5a06 Merge branch 'MDL-85675-main' of https://github.com/lameze/moodle 2025-09-25 11:55:11 +08:00
Mihail Geshoski fb1d1f06d5 Merge branch 'MDL-84085' of https://github.com/paulholden/moodle 2025-09-25 09:59:24 +08:00
AMOS bot aab5b7b48e Automatically generated installer lang files 2025-09-25 00:08:03 +00:00
Jun Pataleta 33275d6ec4 MDL-86744 customfield: Pass toggle data only when necessary 2025-09-25 07:19:01 +08:00
Andrew Nicols 3964418199 MDL-86432 qtype_ordering: Fix broken data provider 2025-09-24 17:50:44 +01:00
Andrew Nicols 19e965480f MDL-86432 phpunit: Ensure that data providers do not modify state 2025-09-24 16:47:40 +01:00
Amaia Anabitarte 8eed9cc2f9 Merge branch 'MDL-86488-main-2' of https://github.com/junpataleta/moodle 2025-09-24 17:18:55 +02:00
Huong Nguyen 91587690eb MDL-80447 repository_googledocs: Add missing fields 2025-09-24 11:18:31 +02:00
Huong Nguyen 962300597f MDL-80447 repository_googledocs: Switch to use core/pubsub 2025-09-24 11:17:24 +02:00
raortegar 7fbfa812b4 MDL-80447 repository_googledocs: Update Google Drive OAuth2 scope tests 2025-09-24 11:17:11 +02:00
raortegar d8a1187d11 MDL-80447 repository_googledocs: Update Google Drive OAuth2 scope
Updated the Google Drive integration to use the drive.file scope instead
of the broader drive scope. This change removes support for shared drives,
which rely on full access. As a result, unit tests were updated to reflect
this behavior by bypassing shared drive checks and expectations.
2025-09-24 11:17:04 +02:00
raortegar 17f87f6b93 MDL-80447 core_repository: Add upload button to filepicker repository 2025-09-24 11:16:41 +02:00
Mihail Geshoski b9ac0457d2 Merge branch 'MDL-83462' of https://github.com/paulholden/moodle 2025-09-24 16:17:00 +08:00
Sara Arjona ecdd7f18de Merge branch 'MDL-86727-main' of https://github.com/aanabit/moodle 2025-09-24 08:46:36 +02:00
Mihail Geshoski f3952c0280 Merge branch 'MDL-86297-main' of https://github.com/PhMemmel/moodle 2025-09-24 11:51:20 +08:00
Mihail Geshoski 7decf5af6d Merge branch 'MDL-85682' of https://github.com/paulholden/moodle 2025-09-24 10:21:38 +08:00
David Mudrák 3fbbf8b78b MDL-86383 lang: Use the fixed strings in tests, too 2025-09-23 20:07:22 +02:00
Sara Arjona ffe71d0f0f Moodle release 5.1beta 2025-09-23 17:22:38 +02:00
Sara Arjona 570f6924d6 NOBUG: Add upgrade notes 2025-09-23 17:22:38 +02:00
Sara Arjona 79b72e36ef NOBUG: Fix error generating upgrade notes 2025-09-23 17:17:54 +02:00
Sara Arjona d4f428b857 Merge branch 'MDL-86716-main' of https://github.com/aanabit/moodle 2025-09-23 18:35:56 +08:00
Jun Pataleta 1c764bf90d Merge branch 'MDL-86023' of https://github.com/catalyst/moodle 2025-09-23 18:35:56 +08:00
Jun Pataleta f8245b4457 Merge branch 'MDL-86664-main' of https://github.com/junpataleta/moodle 2025-09-23 18:35:55 +08:00
Jun Pataleta d3887bf9cc Merge branch 'MDL-84763' of https://github.com/paulholden/moodle 2025-09-23 18:35:51 +08:00
Jun Pataleta 36c2944fc1 Merge branch 'MDL-84948' of https://github.com/paulholden/moodle 2025-09-23 18:35:16 +08:00
Jun Pataleta c5da66c428 Merge branch 'MDL-84634' of https://github.com/paulholden/moodle 2025-09-23 18:35:16 +08:00
Huong Nguyen 4dbaddffcc Merge branch 'MDL-84504-maintenance-log' of https://github.com/bwalkerl/moodle 2025-09-23 18:35:15 +08:00
Jun Pataleta 0ade5ccf8d Merge branch 'MDL-85162' of https://github.com/paulholden/moodle 2025-09-23 18:35:15 +08:00
Jun Pataleta a10ce63be7 Merge branch 'MDL-85263' of https://github.com/paulholden/moodle 2025-09-23 18:35:14 +08:00
Amaia Anabitarte 96b90b4d96 MDL-86727 report_progress: Use filters when downloading 2025-09-23 10:44:12 +02:00
Andrew Nicols 04686a085e MDL-86664 install: Correct display value of Moodle root 2025-09-23 12:23:37 +08:00
Huong Nguyen 3c2473f65f Merge branch 'MDL-86586-main-choice-dropdown' of https://github.com/sharpchi/moodle 2025-09-23 08:43:15 +07:00
Mihail Geshoski cc5e6c24f5 Merge branch 'MDL-83014-main_list_downloaded_content_types' of https://github.com/sharpchi/moodle 2025-09-23 09:42:04 +08:00
Helen Foster a707bb0697 MDL-86383 lang: Import fixed English strings (en_fix) 2025-09-22 20:52:21 +02:00
Amaia Anabitarte 9fe035a107 MDL-86716 courseformat: Remove separator on Activity chooser 2025-09-22 16:22:01 +02:00
Jun Pataleta 625765534e Merge branch 'MDL-86215-main' of https://github.com/dpalou/moodle 2025-09-22 19:57:01 +08:00
Paul Holden ae7f3dfde5 MDL-84948 core: require plugin types always define lang strings.
This is consistent with subplugin behaviour since 36d842e0.

Co-authored-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-09-22 09:17:16 +01:00
Paul Holden 627bfa5d1a MDL-84763 customfield: increase size of category/field name fields.
Allows for more flexibility for multi-lingual sites using filtered
text.
2025-09-22 09:13:53 +01:00
Sara Arjona b8b17e6804 Merge branch 'MDL-86596-integration-main' of https://github.com/mihailges/moodle 2025-09-22 10:12:20 +02:00
Paul Holden 2cc0c93e75 MDL-84634 enrol: add course start placeholder to welcome message.
Update profile URL generation to use API rather than copy it.
2025-09-22 09:11:03 +01:00
Paul Holden 699520a1a2 MDL-85162 mod_assign: enable sorting of grading table by identifier. 2025-09-22 09:10:49 +01:00
Paul Holden ab6bf76fdc MDL-85263 core: use complete PHP binary path in CLI process title. 2025-09-22 09:10:33 +01:00
Mihail Geshoski 9dcda8c3a4 Merge branch 'MDL-86512-main' of https://github.com/junpataleta/moodle 2025-09-22 15:08:43 +08:00
Jun Pataleta a474a2e08a Merge branch 'MDL-85772-main' of https://github.com/mackensen/moodle 2025-09-22 14:49:47 +08:00
Mihail Geshoski f6f3f15b7f MDL-86596 tool_profiling: Deprecate unused string 'lastrun' 2025-09-22 13:16:37 +08:00
Mihail Geshoski 996738ab7f MDL-86596 tool_profiling: Revert string removal without deprecation 2025-09-22 13:00:22 +08:00
Mihail Geshoski e53ea08d99 Merge branch 'MDL-85766' of https://github.com/paulholden/moodle 2025-09-22 10:57:53 +08:00
Huong Nguyen 4087830649 Merge branch 'MDL-84870-main' of https://github.com/andimendunia/moodle 2025-09-22 08:28:21 +07:00
Huong Nguyen 64cf5a8669 Merge branch 'MDL-83066' of https://github.com/paulholden/moodle 2025-09-22 08:24:02 +07:00
Brendan Heywood f63aed7459 MDL-84504 cli: Add config logging for cli maintenance mode 2025-09-22 10:18:29 +10:00
Brendan Heywood 1d3f14d26a MDL-84504 core: Allow setting config and logging with one call 2025-09-22 10:16:19 +10:00
Mihail Geshoski b425629eb3 Merge branch 'MDL-83080' of https://github.com/paulholden/moodle 2025-09-21 22:48:54 +08:00
Mihail Geshoski 2d5ac91811 Merge branch 'MDL-86596' of https://github.com/yerairogo/moodle 2025-09-21 22:30:43 +08:00
Sara Arjona c2ba13aac8 Merge branch 'MDL-86704-main' of https://github.com/roland04/moodle 2025-09-19 21:20:09 +02:00
Laurent David 3816a39867 MDL-86520 mod_h5pactivity: Round number of attempts to decimal
* Add tests to check average and decimal point display
2025-09-19 16:39:16 +02:00
Laurent David 487cc7125d MDL-86520 mod_lesson: Average attempt rounded to decimal point
* Add test to check average and decimal point display
2025-09-19 16:39:16 +02:00
Laurent David 97a031f5bb MDL-86520 mod_quiz: Fix the average attempt count
* Average attempts for student is the number of attempts / number
of students who attempted
* Fix the count for total number of attempts (it was including teachers
by default and not including them in the number of attempts)
* Round this value to one decimal point
2025-09-19 16:39:16 +02:00
Laurent David e86dfcd285 MDL-86520 mod_scorm: Change the average attempts computation
* Make the average calculation uniform with other modules
(it is the students who attempted who are counted, not all
participants)
* Add a decimal point to the rounded value
2025-09-19 16:39:16 +02:00
Amaia Anabitarte 38a6a4210d Merge branch 'MDL-86174-main' of https://github.com/sarjona/moodle 2025-09-19 16:12:02 +02:00
Sara Arjona 2df87bfd26 MDL-86174 badges: Add Canvas Credentials paid plan alert 2025-09-19 15:21:19 +02:00
Mikel Martín bf0ee36713 MDL-86704 theme_boost: Fix modchooser height on small screens 2025-09-19 11:43:12 +02:00
Luca Bösch b5b25f3446 MDL-86424 quiz: Question type icon square within add question in quiz. 2025-09-19 10:28:22 +01:00
Paul Holden 275f2f8b65 MDL-86703 enrol_manual: format group names in enrolment form. 2025-09-19 10:26:01 +01:00
Mark Sharp 3eb9c87516 MDL-86586 core_form: Fixed dropdown JS error if no element found 2025-09-19 10:09:59 +01:00
Yerai Rodríguez e6f2cfb2db MDL-86596 Profiling: add breadcrumb node to profiling detail page
Boost theme removes the last item action.
This adds an extra node so the profile run details page breadcrumb is clickable in both Classic and Boost themes.
2025-09-19 10:51:55 +02:00
Huong Nguyen 74ee977521 on-demand release 5.1dev+ 2025-09-19 15:35:15 +07:00
Huong Nguyen 7cd3250d4d NOBUG: Fixed file access permissions 2025-09-19 15:35:03 +07:00
Huong Nguyen ef27a369de MDL-80053 core_grade: Fix illegal whitespaces 2025-09-19 15:13:33 +07:00
Huong Nguyen d69b7ca756 Merge branch 'MDL-83991_master' of https://github.com/panchalrohit/moodle 2025-09-19 08:56:48 +07:00
Mihail Geshoski e46a8a6399 Merge branch 'mdl-83857_main' of https://github.com/james-cnz/moodle 2025-09-19 09:54:41 +08:00
Huong Nguyen 9f46b8ec1d Merge branch 'MDL-86592-main' of https://github.com/davewoloszyn/moodle 2025-09-19 08:21:44 +07:00
Shamim Rezaie 041bf1108f Merge branch 'MDL-86021-main' of https://github.com/laurentdavid/moodle 2025-09-19 10:48:44 +10:00
James C e15b371ec9 MDL-83857 course: Use set_sectionid not num 2025-09-19 11:43:54 +12:00
Paul Holden e423cb8a7b Merge branch 'MDL-85679-main' of https://github.com/sammarshallou/moodle into main 2025-09-18 19:31:15 +01:00
Paul Holden 06c293ebb4 Merge branch 'MDL-85616-main_glossary_undefined_variable' of https://github.com/davidherney/moodle into main 2025-09-18 19:23:20 +01:00
Sara Arjona 747717b820 Merge branch 'MDL-86173-main' of https://github.com/aanabit/moodle 2025-09-18 17:55:51 +02:00
Jun Pataleta 2fdaddbab7 MDL-86488 componentlibrary: Improved documentation for the action menu 2025-09-18 19:28:07 +08:00
Jun Pataleta 320eb96304 MDL-86488 mod_subsection: Click on the menu button itself, not the icon 2025-09-18 19:28:07 +08:00
Jun Pataleta 838cf06c14 MDL-86488 behat: Click on the menu button itself, not the icon 2025-09-18 19:28:07 +08:00
Jun Pataleta f6a1a0cc1c MDL-86488 qbank_columnsortorder: Use action menu Behat steps 2025-09-18 19:28:07 +08:00
Jun Pataleta f97f5f40a0 MDL-86488 behat: Update xpath for action menu trigger's label 2025-09-18 19:28:07 +08:00
Jun Pataleta f1d0405fa3 MDL-86488 mod_data: Fix Behat tests for checking action menu items 2025-09-18 19:28:07 +08:00
Jun Pataleta f099b785bd MDL-86488 mod_feedback: Move menu trigger label outside the pix icon
* The pix icons must be decorative, and the label be put within
the menu trigger itself as a visually hidden text.
* Also make the pix icons beside the action menu items as decorative.
2025-09-18 19:28:06 +08:00
Jun Pataleta e4b264b5be MDL-86488 grade: Move menu trigger label outside the pix icon
* The pix icons must be decorative, and the label be put within
the menu trigger itself as a visually hidden text.
2025-09-18 19:28:06 +08:00
Jun Pataleta 7605aa8ce9 MDL-86488 course: Set action menu icon for category actions menu 2025-09-18 19:28:06 +08:00
Jun Pataleta 33973302de MDL-86488 mod_lti: Move menu trigger label outside the pix icon 2025-09-18 19:28:05 +08:00
Laurent David 10f497e2df MDL-86021 core_course: Sort modules in the course listing order
* When sections contains submodules, the list of course modules should appear
in the right order (the order displayed in the course page)
2025-09-18 11:46:18 +02:00
Jun Pataleta 588489e985 MDL-86512 mod_assign: Make the select column header name more accessible 2025-09-18 13:56:37 +08:00
Shamim Rezaie dbc5f2bacb Merge branch 'MDL-83838-master' of https://github.com/NashTechOpenUniversity/moodle 2025-09-18 07:08:02 +10:00
David Herney 841d847d58 MDL-85616 mod_glossary: The existence of the variable is controlled 2025-09-17 13:04:08 -05:00
Mihail Geshoski 2e580f5621 Merge branch 'MDL-80053-main' of https://github.com/Jayce0808/moodle 2025-09-17 23:34:28 +08:00
Paul Holden 212bba0782 Merge branch 'MDL-86454-main' of https://github.com/sh-csg/moodle into main 2025-09-17 16:04:33 +01:00
Amaia Anabitarte a9c2c4c099 MDL-86173 grade: Checking the grade item is gradable 2025-09-17 16:15:56 +02:00
Jun Pataleta adee8f29ec Merge branch 'MDL-86065' of https://github.com/dravek/moodle 2025-09-17 20:04:41 +08:00
Paul Holden 9ff896c1bf Merge branch 'MDL-86431-main' of https://github.com/andrewnicols/moodle into main 2025-09-17 12:39:04 +01:00
Paul Holden 3e36ff48ec Merge branch 'MDL-86541' of https://github.com/dfelipemonroy/moodle into main 2025-09-17 11:52:53 +01:00
hieuvu f378ebdc24 MDL-83838 report_progress: Add download widget 2025-09-17 17:36:29 +07:00
Amaia Anabitarte e20745801f Merge branch 'MDL-86208-main' of https://github.com/roland04/moodle 2025-09-17 12:32:22 +02:00
Amaia Anabitarte 725672521b Merge branch 'MDL-86490-main-2' of https://github.com/junpataleta/moodle 2025-09-17 11:53:20 +02:00
Amaia Anabitarte 05e80885b4 Merge branch 'MDL-86564-main' of https://github.com/aanabit/moodle 2025-09-17 11:45:20 +02:00
David Carrillo d50b1ed470 MDL-86065 customfield: Add privacy provider metadata for 'shared' table 2025-09-17 10:24:56 +02:00
Jun Pataleta 029a55c18b MDL-86488 output: Make the icon in action menu triggers decorative
* Set the action label properly.
* Set the kebab icon as a decorative icon.
* Move the title attribute to the menu button itself instead of the
kebab icon.
2025-09-17 14:54:14 +08:00
Andrew Nicols 4203d95152 MDL-86431 phpunit: Rename test teardown method 2025-09-17 13:57:35 +08:00
Jun Pataleta 29f69a4538 Merge branch 'MDL-86065' of https://github.com/dravek/moodle 2025-09-17 12:09:39 +08:00
Jun Pataleta fb93cd90d2 Merge branch 'MDL-85836-main' of https://github.com/junpataleta/moodle 2025-09-17 11:17:10 +08:00
Tim Hunt 1743de2718 MDL-85836 assign: refactor submit code, so the back-end is reusable
Previously, the code in mod_assign that handled submission had a
single method which took the submitted form data and verified all
the normal logic for 'can the this user submit this now' with the
acutal processing to update the state of the submission in the database
and send notifications, update completion, etc.

This was problematic, for example if you were trying to write a custom
scheduled_task which automatically turned draft submissions into final
submissions in certain circumstances. Hence this re-factor.
2025-09-17 11:16:15 +08:00
Tim Hunt 4e10ae6c74 MDL-85836 assign: document a useless submit_for_grading argument
This never worked, so was potentially misleading, so I have cleaned this up.

However, I now notice that this pattern is common in other methods in this
class. I am not going to attempt a full clean-up now. I will leave that
for the mod_assign maintainer. However, I do want to clean up this one
method before I change it in the next commit.
2025-09-17 11:11:58 +08:00
Huong Nguyen 9cdb8ef4c4 Merge branch 'MDL-76022-main' of https://github.com/stevandoMoodle/moodle 2025-09-17 08:40:39 +07:00
Tony Butler e495958b7c MDL-58001 mod_assign: Return early if no grade items are available 2025-09-16 17:48:25 +01:00
David Carrillo a0001c8776 MDL-86065 customfield: Allow to select shared categories on each entity 2025-09-16 18:07:39 +02:00
David Carrillo 78dc974150 MDL-86065 customfield: Add shared custom fields
- Now we can create shared custom field categories and use the
fields created in these categories in any other entity in Moodle.
2025-09-16 18:02:48 +02:00
Jun Pataleta 281ffb9020 MDL-86512 core: Ensure bulk action selection count announcement
When the bulk actions are first rendered, the item count in the
aria-live region will not be announced by screen readers as aria-live
regions need to be present in the DOM and changed before screen readers
can announce their content.

This commit ensures that the item selection count will be announced
when the bulk actions get added to the DOM by calling
`updateBulkItemSelection()` after rendering the bulk actions HTML. This
removes the non-breaking space in the template, effectively causing a
change in DOM without affecting the visuals, and allowing screen readers
to announce the contents of the item count.
2025-09-16 22:38:36 +08:00
Jun Pataleta e10c31ce2b MDL-86512 core: Assign status role for the number of selected items
Add a status role for the container containing the number of selected
items for bulk actions so that screen readers will announce this
number when an item gets selected for bulk action.
2025-09-16 22:38:36 +08:00
Jun Pataleta 6d12056bb2 MDL-86490 tool: Click on the action link itself and not on its icon 2025-09-16 22:35:21 +08:00
Jun Pataleta df486967e4 MDL-86490 output: Mark icon in action_icon as decorative 2025-09-16 22:35:21 +08:00
Huong Nguyen 0ec57fc3f2 on-demand release 5.1dev+ 2025-09-16 20:59:42 +07:00
Huong Nguyen bbf640c3bc NOBUG: Add upgrade notes 2025-09-16 20:59:42 +07:00
Mikel Martín 11d5d44a5d MDL-86208 output: Add load_fontawesome_map to mobile service 2025-09-16 15:43:22 +02:00
Huong Nguyen f47ec57bad Merge branch 'MDL-78437-main-fix' of https://github.com/bwalkerl/moodle 2025-09-16 12:42:40 +07:00
David Woloszyn c795eb11d4 MDL-86592 analytics: Modify processor checking in admin setting
Remove processor checks when calling write_setting. This prevents
configuration errors displaying when processors are not yet configured
when admin defaults are applied.
2025-09-16 14:56:55 +10:00
Jun Pataleta ee0e56251d Merge branch 'MDL-86495-main-patch' of https://github.com/HuongNV13/moodle 2025-09-16 10:15:25 +08:00
Benjamin Walker ec578c2e53 MDL-78437 core_task: Add expected clean up output to tests 2025-09-16 12:02:57 +10:00
Mihail Geshoski 6a725a9ab1 Merge branch 'MDL-86558-main' of https://github.com/rjnl/moodle 2025-09-16 09:56:27 +08:00
Huong Nguyen 2d0b3a0dde MDL-86495 core: Improve PHPUnit for IPLookup 2025-09-16 08:42:05 +07:00
Jayce 50b61a3ee6 MDL-80053 core_grade: fixed exception message appearing
- Fixing the exceptions shows an incorrectly formatted table
- The filler cell is only used to take space on the left rows but when the right rows are empty, it is not needed.
2025-09-16 11:06:49 +09:30
Amaia Anabitarte 13df8afd1e MDL-86564 mod_choice: Export a pix_icon in overview external 2025-09-15 15:23:39 +02:00
Amaia Anabitarte e7aac3341b Merge branch 'MDL-85541' of https://github.com/paulholden/moodle 2025-09-15 14:57:12 +02:00
Amaia Anabitarte 9758db46e0 Merge branch 'MDL-85990-main' of https://github.com/roland04/moodle 2025-09-15 14:53:12 +02:00
Amaia Anabitarte 626214aab1 Merge branch 'MDL-86157' of https://github.com/paulholden/moodle 2025-09-15 14:49:50 +02:00
Paul Holden 1ff1f7e1ea MDL-86157 mod_glossary: correctly format entry page title. 2025-09-15 12:00:06 +01:00
Paul Holden 9fd7163d43 MDL-83080 message: handle core\url instance data as contexturl. 2025-09-15 10:40:19 +01:00
Tim Hunt e7d76334a4 MDL-86599 assignment: add hidden captions to the table in the assign UI
This helps screen-reader users trying to navigate quickly to the right table.
2025-09-15 09:56:01 +01:00
Amaia Anabitarte d39140befc Merge branch 'MDL-86283-main-v02' of https://github.com/ferranrecio/moodle 2025-09-15 10:30:02 +02:00
Mikel Martín 360645cabb MDL-85990 mod_forum: Fix toggle accessibility in overview page
- Add aria-label to toggle buttons
- Add SRLogger to toggle button interactions
2025-09-15 10:27:40 +02:00
Mikel Martín e4c5c64087 MDL-85990 core: Improve core/toggle to accept any attribute
Improve the core/toggle template, so it can accept any attribute
and not only starting with "data-". This will allow to add attributes
like "aria-label", for example.
2025-09-15 10:27:40 +02:00
Shamim Rezaie e25438cda2 Merge branch 'MDL-86604-main' of https://github.com/mihailges/moodle 2025-09-15 18:23:47 +10:00
Andi Permana 0c084f065c MDL-84870 core: Update security.txt expiry 2025-09-15 12:11:32 +07:00
Huong Nguyen 85d69ffd52 Merge branch 'MDL-79362-main' of https://github.com/abias/moodle 2025-09-15 11:40:43 +07:00
Jun Pataleta 99de723da4 Merge branch 'MDL-86495-main' of https://github.com/HuongNV13/moodle 2025-09-15 10:25:42 +08:00
Huong Nguyen 9c4bbd2ae5 Merge branch 'MDL-78437-cleanup-metadata' of https://github.com/bwalkerl/moodle 2025-09-15 09:03:33 +07:00
Paul Holden 01902fc681 MDL-84085 mod_h5pactivity: account for missing ra table join alias. 2025-09-12 11:38:13 +01:00
Shamim Rezaie bbf404a1bc on-demand release 5.1dev+ 2025-09-12 18:36:02 +10:00
Shamim Rezaie f514ce30cd NOBUG: Add upgrade notes 2025-09-12 18:36:02 +10:00
CORDEL Yannick 0496d985ad MDL-76022 enrol_manual: Manual user enrolment includes group 2025-09-12 10:48:08 +08:00
Huong Nguyen cba48cdfcc Merge branch 'MDL-86584' of https://github.com/paulholden/moodle 2025-09-12 09:05:02 +07:00
Huong Nguyen 5bffa8b245 Merge branch 'MDL-85984' of https://github.com/paulholden/moodle 2025-09-12 09:03:43 +07:00
Huong Nguyen fb66b7b055 Merge branch 'MDL-80942-main_link_meta_enrolments_to_meta_page' of https://github.com/sharpchi/moodle 2025-09-12 09:01:43 +07:00
Jun Pataleta 7bfec4359b Merge branch 'MDL-86308-main' of https://github.com/sammarshallou/moodle 2025-09-12 09:45:46 +08:00
Mihail Geshoski 41ef2808e0 MDL-86604 mod_feedback: Remove unwanted table borders 2025-09-11 23:42:01 +08:00
Jun Pataleta 1f83dfd6e9 Merge branch 'MDL-86294_document-db-options' of https://github.com/ziegenberg/moodle 2025-09-11 17:12:43 +08:00
Paul Holden 6248b6b99c MDL-86605 core: update list of stale files for 5.1 release. 2025-09-11 09:52:13 +01:00
Jake Dallimore a9a0dd0e30 Merge branch 'MDL-86548-main' of https://github.com/mihailges/moodle 2025-09-11 16:22:47 +08:00
Mihail Geshoski 75ec49b083 MDL-86548 mod_glossary: Remove unwanted table borders 2025-09-11 13:51:16 +08:00
Mihail Geshoski d8334584d4 MDL-86548 theme_boost: Option to avoid the _reboot.scss reset for tables
MDL-85659 introduced a reset of the Bootstrap _reboot.scss table styles.
This reset is applied to most tables (except those using the .table
class) and in some cases resulted in regressions such as unwanted
borders.
To address this, the .table-reboot class has been introduced as an
option to bypass the reset applied by MDL-85659 in undo.scss. Tables
affected by this regression can include this class, which is
intentionally styleless and preserves the original _reboot.scss styles
while preventing the addition of unwanted styling (borders).
2025-09-11 12:05:00 +08:00
Huong Nguyen 73dec09faa Merge branch 'MDL-85672-main' of https://github.com/davewoloszyn/moodle 2025-09-11 09:07:17 +07:00
Huong Nguyen 2a50388fe4 Merge branch 'MDL-86573' of https://github.com/paulholden/moodle 2025-09-11 09:00:10 +07:00
Paul Holden a6e7af8bd9 Merge branch 'MDL-86330' of https://github.com/yerairogo/moodle into main 2025-09-10 16:26:42 +01:00
Mihail Geshoski b67d50de7e Merge branch 'MDL-82694' of https://github.com/paulholden/moodle 2025-09-10 23:22:40 +08:00
Jun Pataleta 03bcd85bee MDL-86501 form: Fix unit tests
The change in the calendar button from an `<a>` tag to a native
`<button>` tag means the `\HTML_QuickForm_group::getValue()` will have
a different result and the `test_onquickformevent()` tests must be
adjusted accordingly.
2025-09-10 16:14:31 +01:00
Paul Holden 4aa92a69e0 Merge branch 'MDL-86447_main' of https://github.com/dcmexy/moodle into main 2025-09-10 15:49:55 +01:00
Mihail Geshoski 91ca1aa211 Merge branch 'MDL-86479-main' of https://github.com/junpataleta/moodle 2025-09-10 22:18:57 +08:00
Paul Holden 6dd2b631f4 Merge branch 'MDL-86489-main' of https://github.com/junpataleta/moodle into main 2025-09-10 15:04:04 +01:00
ferran b0a08098ca MDL-86283 core_courseformat: improve overview data providers 2025-09-10 15:39:38 +02:00
ferran 6ee48e3d9b MDL-86283 mod: improve overview data providers 2025-09-10 15:39:33 +02:00
Andrew Nicols ba0ed2f3ab MDL-86283 mod: Fix coding style on courseformat unit tests 2025-09-10 15:39:28 +02:00
ferran ce76b122e7 MDL-86283 courseformat: Correct overview erroneous coverage
Co-Authored-By: Andrew Nicols <andrew@nicols.co.uk>
2025-09-10 15:31:45 +02:00
Andrew Nicols 7bd4392959 MDL-86283 mod: Correct erroneous coverage 2025-09-10 15:30:07 +02:00
Mark Sharp 57ef6e471f MDL-80942 enrol_meta: Let course meta link be clickable 2025-09-10 13:05:05 +01:00
Paul Holden 8cf9b22116 MDL-82694 availability_grade: link to grade items linked to activities. 2025-09-10 12:14:39 +01:00
Mihail Geshoski 4ed7c173ee Merge branch 'MDL-86498-main' of https://github.com/junpataleta/moodle 2025-09-10 17:45:09 +08:00
Amaia Anabitarte b139278257 Merge branch 'MDL-86390' of https://github.com/paulholden/moodle 2025-09-10 10:46:06 +02:00
Amaia Anabitarte cdfa0d3d65 Merge branch 'MDL-86531-main' of https://github.com/roland04/moodle 2025-09-10 10:37:41 +02:00
Huong Nguyen 60d026095c Merge branch 'MDL-86405' of https://github.com/paulholden/moodle 2025-09-10 09:11:58 +07:00
Huong Nguyen 68b3c32f80 Merge branch 'MDL-84076-main' of https://github.com/PhMemmel/moodle 2025-09-10 09:09:58 +07:00
Huong Nguyen 3852a3ae62 Merge branch 'MDL-85270-main' of https://github.com/micaherne/moodle 2025-09-10 09:08:11 +07:00
Huong Nguyen 6ab3ac1994 Merge branch 'MDL-85266' of https://github.com/paulholden/moodle 2025-09-10 09:05:34 +07:00
Paul Holden 9a0f006339 Merge branch 'MDL-86521-main' of https://github.com/abias/moodle into main 2025-09-09 14:24:59 +01:00
Paul Holden bab4535bdf Merge branch 'MDL-86499-main' of https://github.com/junpataleta/moodle into main 2025-09-09 14:15:29 +01:00
Amaia Anabitarte 1bb85af169 Merge branch 'MDL-86273-main' of https://github.com/ferranrecio/moodle 2025-09-09 15:12:42 +02:00
Paul Holden 431204d379 Merge branch 'MDL-86501-main' of https://github.com/junpataleta/moodle into main 2025-09-09 14:01:00 +01:00
Diego Monroy 4be66b0dfb MDL-86541 blocks: validate allowing block title to be '0' (zero). 2025-09-09 13:34:58 +02:00
Jun Pataleta 5bd674a313 MDL-86498 badges: Empty string for empty links 2025-09-09 18:16:28 +08:00
Jun Pataleta 161c465ed6 MDL-86498 badges: Add label for badge navigation url_select 2025-09-09 18:16:28 +08:00
Jun Pataleta ec9e02d0bf MDL-86498 badges: Accessibility coverage for badge details and overview 2025-09-09 18:16:28 +08:00
Paul Holden 75cfcb9ed8 MDL-86584 aiprovider_deepseek: add to standard plugin list. 2025-09-09 09:45:24 +01:00
Jake Dallimore 0582c77a33 on-demand release 5.1dev+ 2025-09-09 15:07:16 +08:00
Jake Dallimore e090b3df9a Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-09-09 15:07:09 +08:00
Paul Holden 695c83bf3c MDL-86405 libraries: upgrade to version 4.10.3 of axe-core. 2025-09-09 07:26:32 +01:00
Huong Nguyen 01d85801b8 Merge branch 'MDL-83003_INFO-command-not-compatible-with-envoy-proxy-redis' of https://github.com/ziegenberg/moodle 2025-09-09 09:28:37 +07:00
Huong Nguyen b358455bd1 Merge branch 'MDL-85706' of https://github.com/paulholden/moodle 2025-09-09 08:52:48 +07:00
Rajneel Totaram b7ade6be49 MDL-86558 mod_quiz: Fix styles for sticky columns
Also remove the duplicate '.table' class applied on the table.
2025-09-09 11:50:22 +12:00
ferran d0e0f746bc Merge branch 'MDL-84903' of https://github.com/jfederico/moodle 2025-09-08 17:12:45 +02:00
Huong Nguyen 750e45ba99 MDL-86495 core: Better errors handling for IP Lookup
- Since `Geoplugin` is not free anymore, a new admin setting called `GeoPlugin API key` has been added for user to input
  their API key if they still want to use `Geoplugin` service.
- The `iplookup_find_location()` method has been improved to handle error responses more effectively.
2025-09-08 16:20:52 +07:00
Michael Aherne 7e164e957d MDL-85270 output: Export url_select for template. 2025-09-08 10:13:33 +01:00
Mark Sharp 6ddf7796d2 MDL-85419 core_courseformat: Move event trigger to after cm cache purge 2025-09-08 09:44:43 +01:00
Huong Nguyen c7dbaec56b Merge branch 'MDL-84345-main' of https://github.com/yusufwib01/moodle 2025-09-08 08:36:30 +07:00
Huong Nguyen f1f794bc2c Merge branch 'MDL-86459-main' of https://github.com/yusufwib01/moodle 2025-09-08 08:33:01 +07:00
Mihail Geshoski fedbabb881 Merge branch 'MDL-86375' of https://github.com/paulholden/moodle 2025-09-08 09:32:07 +08:00
Huong Nguyen 94800998fc Merge branch 'MDL-85335-main' of https://github.com/gbarat87/moodle 2025-09-08 08:30:10 +07:00
Mihail Geshoski 2db34f7246 Merge branch 'MDL-86374' of https://github.com/paulholden/moodle 2025-09-08 09:24:21 +08:00
Mihail Geshoski 53f1bdb52b Merge branch 'MDL-86317-main' of https://github.com/rjnl/moodle 2025-09-08 09:18:11 +08:00
Benjamin Walker 6960ab1755 MDL-78437 core_task: Extend clean up ad hoc task metadata logging 2025-09-08 09:02:31 +10:00
Benjamin Walker fe9f7a053f MDL-78437 core_task: Run clean up ad hoc task metadata more frequently 2025-09-08 09:02:31 +10:00
Paul Holden d12b99aed9 MDL-86573 reportbuilder: correct 'classname' field type definition. 2025-09-07 18:09:57 +02:00
Paul Holden c42b5ddd18 MDL-86390 course: cancel link click events only when required.
Otherwise we prevent activity choose "More help" links working.
2025-09-07 10:37:49 +02:00
AMOS bot 21fe4af043 Automatically generated installer lang files 2025-09-06 00:08:09 +00:00
jfederico 8657c6fde8 MDL-84903 mdl_bigbluebuttonbn: overrides view through bbbext plugins 2025-09-05 18:31:50 +00:00
Huong Nguyen 70de23e219 on-demand release 5.1dev+ 2025-09-05 23:54:58 +07:00
Huong Nguyen 492b63b554 NOBUG: Add upgrade notes 2025-09-05 23:54:58 +07:00
Huong Nguyen b5ea6745ae Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-09-05 23:54:46 +07:00
ferran 3023a2b1fd MDL-86273 core_courseformat: fix overview phpunit test 2025-09-05 15:39:38 +02:00
Philipp Memmel a30c61ba2c MDL-84076 core_templates: Avoid manipulation of template context object 2025-09-05 09:58:59 +02:00
Huong Nguyen 7d910ee246 Merge branch 'MDL-83628-main' of https://github.com/sammarshallou/moodle 2025-09-05 09:21:41 +07:00
Huong Nguyen 3013325775 Merge branch 'MDL-85816-main' of https://github.com/andrewnicols/moodle 2025-09-05 09:19:54 +07:00
Simey Lameze 1579fdec8c MDL-85675 behat: add timefinish to quiz attempt generator
Adds support for the timefinish attribute to the quiz attempt
generator allowing Behat scenarios to specify the exact completion
time of an attempt.

This is necessary to simulate a scenario where the student finished
the attempt few minutes ago for example.

This commit also adds two scenarios that automates MDLQA-307.
2025-09-05 10:08:49 +08:00
Mihail Geshoski 1be5883bc4 Merge branch 'MDL-85922' of https://github.com/paulholden/moodle 2025-09-05 09:55:58 +08:00
Huong Nguyen 90b0d009c6 Merge branch 'MDL-86160' of https://github.com/paulholden/moodle 2025-09-05 08:43:33 +07:00
Huong Nguyen a930bb44ef Merge branch 'MDL-86066' of https://github.com/paulholden/moodle 2025-09-05 08:41:04 +07:00
Huong Nguyen 8c75d28cf1 Merge branch 'MDL-85707' of https://github.com/paulholden/moodle 2025-09-05 08:36:30 +07:00
Huong Nguyen a79cb21cfd Merge branch 'MDL-86142' of https://github.com/paulholden/moodle 2025-09-05 08:28:20 +07:00
Mihail Geshoski 04d5ab5638 Merge branch 'MDL-85346' of https://github.com/paulholden/moodle 2025-09-05 09:25:48 +08:00
Paul Holden 0b8b0732fb MDL-85346 course: correctly retrieve course request email content. 2025-09-04 18:49:09 +02:00
Mihail Geshoski 00d54ef308 Merge branch 'MDL-85869-main' of https://github.com/ziegenberg/moodle 2025-09-04 23:56:18 +08:00
Mihail Geshoski 82dcf1d2e3 Merge branch 'MDL-74046-main' of https://github.com/muhammadarnaldo/moodle 2025-09-04 23:47:56 +08:00
Yerai Rodríguez 13a32ba37d MDL-86330 enrol: remove time rounding to avoid missing active enrolments
Rounding time could lead to newest enrolments being excluded, resulting in
these courses not appearing under the "My courses" tab in the Dashboard until the rounded time aligned with the actual time.

enrol_get_all_users_courses() now uses the PSR-20 clock to provide stable
and testable time values.
2025-09-04 16:47:23 +02:00
ferran 1dec6e14d3 Merge branch 'MDL-82464' of https://github.com/paulholden/moodle 2025-09-04 16:41:25 +02:00
ferran 90af508b1a Merge branch 'MDL-85416' of https://github.com/timhunt/moodle 2025-09-04 16:31:17 +02:00
ferran 4222a58d09 Merge branch 'MDL-72956' of https://github.com/paulholden/moodle 2025-09-04 16:10:15 +02:00
Huong Nguyen b8b45ec683 Merge branch 'MDL-84799' of https://github.com/jfederico/moodle 2025-09-04 15:52:37 +07:00
Huong Nguyen d92470e9fd MDL-85738 course: Remove stray $PAGE variable 2025-09-04 15:48:33 +07:00
Huong Nguyen d02c06fcab Merge branch 'MDL-85738-main' of https://github.com/stevandoMoodle/moodle 2025-09-04 15:46:20 +07:00
Huong Nguyen f62b17d2c8 Merge branch 'MDL-86230' of https://github.com/paulholden/moodle 2025-09-04 15:44:11 +07:00
Huong Nguyen 0eab421dff Merge branch 'MDL-72511-main' of https://github.com/junpataleta/moodle 2025-09-04 15:41:46 +07:00
ferran 06eee5de8d Merge branch 'MDL-85641-main' of https://github.com/rjnl/moodle 2025-09-04 10:11:10 +02:00
ferran 19ec5ce24c Merge branch 'MDL-86248' of https://github.com/paulholden/moodle 2025-09-04 10:01:06 +02:00
Matt Porritt 6cd030ec82 MDL-84345 AI: Provider Plugin - Deepseek
Add a AI provider that supports the DeepSeek API.
Allows AI Subsystem to use DeepSeek models via
their API. Does not support DeepSeek models running
locally.

Co-authored by: Yusuf Wibisono <yusuf.wibisono@moodle.com>
2025-09-04 14:31:24 +07:00
Muhammad Arnaldo 764a67d2b2 MDL-74046 tool_lp: new-tab for competency frameworks repo link 2025-09-04 12:49:43 +07:00
Rajneel Totaram 3423dda97b MDL-86317 core: Replace deprecated bootstrap class 2025-09-04 10:19:57 +12:00
Rajneel Totaram 4f3958805c MDL-85641 mod_feedback: Use full width for reponses page 2025-09-04 09:49:37 +12:00
Alexander Bias 5ba0372bfd MDL-86521 block_myoverview: Fix overflow of filter bar 2025-09-03 14:45:30 +02:00
Mikel Martín 5304445907 MDL-86531 course: Fix overview table overflow 2025-09-03 13:14:09 +02:00
Paul Holden a79bd37ed6 Merge branch 'MDL-85619-main' of https://github.com/mihailges/moodle into main 2025-09-03 12:38:30 +02:00
Stevani Andolo 057919fbd9 MDL-85738 mod: Update unit tests with AI access control fields 2025-09-03 18:30:27 +08:00
Stevani Andolo 5906a94e29 MDL-85738 course: Add support for AI access controls 2025-09-03 18:30:24 +08:00
Paul Holden 426d9febe5 Merge branch 'MDL-84982-master' of https://github.com/NashTechOpenUniversity/moodle into main 2025-09-03 12:29:55 +02:00
Paul Holden 5d8ba68835 Merge branch 'MDL-86187-main' of https://github.com/phmemmel/moodle into main 2025-09-03 12:16:15 +02:00
Paul Holden 7c70df81f9 Merge branch 'MDL-85378-master' of https://github.com/danghieu1407/moodle into main 2025-09-03 11:52:24 +02:00
Daniel Ziegenberg 6836365f20 MDL-85869 qbank: Fix duplicate category stamps and idnumbers
Migrating from Moodle 4.5 to Moodle 5.0 the adhoc task
\mod_qbank\task\transfer_question_categories should transfer question
categories into new question bank instances.

The code for rescuing 'lost' categories where the linked contextid
no longer exists was failing. It moved all these categories to the
system context, which could lead to unique key violations.

To fix this, we check for duplicates, and if neccessary change the
stamp, or remove the idnumber. Since these questions were formerly
'lost', this is OK.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
Co-authored-by: Tim Hunt <T.J.Hunt@open.ac.uk>
2025-09-03 10:49:36 +02:00
ferran f8375a0559 Merge branch 'MDL-86514-main' of https://github.com/andrewnicols/moodle 2025-09-03 10:46:02 +02:00
Daniel Ziegenberg 5f00bcdd57 MDL-86259 qbank: Make transfer_question_categories more resilient
Migrating from Moodle 4.5 to Moodle 5.0 queues an adhoc task
`\mod_qbank\task\transfer_question_categories` which is supposed to
spawn a lot of adhoc tasks `\mod_qbank\task\transfer_questions`.

However, the task `\mod_qbank\task\transfer_question_categories` is
built in a way that the adhoc tasks to spawn are stored in memory in an
array. So if the task at some point crashes which is not as unlikely as
one would think (temporary database connection loss, leftover rubbish in
question table, all kinds of possible errors, see MDL-86226 or
MDL-85869) all these `\mod_qbank\task\transfer_questions` tasks WILL NOT
BE SPAWNED ANYMORE leaving the whole platform in a mess from which you
will not be able to recover from: Question categories have been migrated
to new contexts, but the questions have not, because the adhoc tasks
never have been created.

We fix this by moving the creation of the adhoc tasks
`\mod_qbank\task\transfer_questions` inside the delegated database
transaction where the question categories are being moved. So after a
category is moved but before it get's deleted, we create the
corresponding `\mod_qbank\task\transfer_questions` task and queue it for
execution.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-09-03 10:06:23 +02:00
Stevani Andolo 29ef751472 MDL-85738 ai: Add base support for AI access controls 2025-09-03 13:19:54 +08:00
Mihail Geshoski 52c564f9ac Merge branch 'MDL-82244' of https://github.com/paulholden/moodle 2025-09-03 12:22:18 +08:00
Mihail Geshoski 8f9b64129c Merge branch 'MDL-73671' of https://github.com/paulholden/moodle 2025-09-03 12:16:32 +08:00
Mihail Geshoski d23f1ce015 Merge branch 'MDL-83474' of https://github.com/paulholden/moodle 2025-09-03 12:08:36 +08:00
Mihail Geshoski 1e5cb529cd Merge branch 'MDL-85153-main' of https://github.com/snake/moodle 2025-09-03 11:57:34 +08:00
Mihail Geshoski 990aa21ed7 Merge branch 'MDL-84965' of https://github.com/timhunt/moodle 2025-09-03 11:49:49 +08:00
AMOS bot 2ae1af36c0 Automatically generated installer lang files 2025-09-03 00:08:04 +00:00
jfederico a863e03e8d MDL-84799 mdl_bigbluebuttonbn: Extend settings_navigation via extension 2025-09-02 18:30:47 +00:00
Tim Hunt 634bf20945 MDL-85416 assignment: fix date format in messages
For no very obvious reason, the date in the 'You have just
submitted your assignemnt' message was formatted differently
from the default display used on-screen.

This commit makes it consistent.
2025-09-02 17:17:04 +02:00
ferran c71dcf8f4f Merge branch 'MDL-71786' of https://github.com/paulholden/moodle 2025-09-02 17:02:59 +02:00
Michael Hawkins 8e37adaddf on-demand release 5.1dev+ 2025-09-02 20:34:14 +08:00
Michael Hawkins 23537b2f9a NOBUG: Add upgrade notes 2025-09-02 20:34:13 +08:00
Michael Hawkins 1456863e2b NOBUG: Fixed file access permissions 2025-09-02 20:33:53 +08:00
Michael Hawkins 89f6c90192 Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-09-02 20:33:45 +08:00
Michael Hawkins eb8d2ef302 MDL-86337 core_courseformat: Fix upgrade notes duplicate key 2025-09-02 19:52:12 +08:00
Mihail Geshoski 2b87b3137f Merge branch 'mdl-84975_main' of https://github.com/james-cnz/moodle 2025-09-02 09:45:18 +08:00
Mihail Geshoski 208e7a042b Merge branch 'MDL-85551_main' of https://github.com/marxjohnson/moodle 2025-09-02 09:31:55 +08:00
Mihail Geshoski 80358a9327 Merge branch 'MDL-86339-main' of https://github.com/rjnl/moodle 2025-09-02 09:17:40 +08:00
Mihail Geshoski 588005e509 Merge branch 'MDL-86366-main' of https://github.com/lucaboesch/moodle 2025-09-01 23:22:00 +08:00
Paul Holden 887b5a3d37 MDL-71786 mod_assign: shift activity grade reminder dates during reset.
Co-authored-by: aneno-m-e <43393997+aneno-m-e@users.noreply.github.com>
2025-09-01 17:06:59 +02:00
ferran 3a4a1e0f0e Merge branch 'MDL-86337-main' of https://github.com/ferranrecio/moodle 2025-09-01 17:01:02 +02:00
Paul Holden 1deea0cfba MDL-73671 mod_forum: shift activity due/cutoff dates during reset. 2025-09-01 16:55:03 +02:00
ferran 8402cdaa91 MDL-86337 core_courseformat: move activity chooser UI to course format 2025-09-01 16:48:45 +02:00
Mihail Geshoski 040f2a87f0 Merge branch 'MDL-85018_main' of https://github.com/marxjohnson/moodle 2025-09-01 22:29:27 +08:00
ferran e5f0ae0eea Merge branch 'MDL-82159-main' of https://github.com/andrewnicols/moodle 2025-09-01 16:25:28 +02:00
Mihail Geshoski b8723d53db Merge branch 'MDL-73417-main' of https://github.com/rjnl/moodle 2025-09-01 22:19:39 +08:00
Paul Holden bddbe33c9c MDL-85984 admin: verbose CLI info if trying to set hardcoded config. 2025-09-01 16:17:47 +02:00
Andrew Nicols 3fe065bdf4 MDL-82159 core: Deprecate lib/navigationlib.php 2025-09-01 15:09:26 +02:00
Andrew Nicols 090926c281 MDL-82159 core: Coding style fixes for navigation 2025-09-01 15:09:26 +02:00
Andrew Nicols 1b7682d536 MDL-82159 core: Update namespace of core navigation 2025-09-01 15:09:26 +02:00
Andrew Nicols afc3ef7bb4 MDL-82159 core: Migrate navigation classes to new dirs 2025-09-01 15:09:23 +02:00
ferran 8d17d46b4d Merge branch 'MDL-86223-main' of https://github.com/laurentdavid/moodle 2025-09-01 11:58:48 +02:00
Laurent David d976368a08 MDL-86223 mod_quiz: Implement group based permissions 2025-09-01 11:40:26 +02:00
ferran 74b3ae3631 Merge branch 'MDL-86192-main' of https://github.com/laurentdavid/moodle 2025-09-01 11:33:17 +02:00
ferran 9ab357dcfd Merge branch 'MDL-86216-main' of https://github.com/laurentdavid/moodle 2025-09-01 11:31:26 +02:00
Andrew Nicols 4911eb27f6 MDL-86514 core_course: Load the repository libraries 2025-09-01 10:52:08 +02:00
Jun Pataleta 9fb251930f MDL-86501 form: Fix date selector calendar button mark up
* Make the calendar icon decorative.
* Mark up the calendar button accordingly:
  - Render it as a `<button type="button">`
  - Add label using `aria-label`.
  - Use a more suitable label of "Date picker" rather than "Calendar"
  - Add a `title` attribute to show a tooltip for sighted users.
  - Disable/enable it accordingly by setting/removing the `disabled`
    attribute.
2025-09-01 16:07:46 +08:00
Philipp Memmel 5027b19ac6 MDL-86297 core_question: Fix limit when retrieving qbank instances 2025-09-01 07:10:55 +02:00
Laurent David 05e19e3d46 MDL-86192 mod_bigbluebuttonbn: Remove @covers from test methods 2025-09-01 07:07:52 +02:00
Laurent David dc71b344fd MDL-86192 mod_bigbluebuttonbn: Implement group in overview page 2025-09-01 07:07:52 +02:00
Laurent David b6882b73a2 MDL-86192 mod_bigbluebuttonbn: Make sure we can return all recordings
When we fetch recordings from an instance we filter out by groups automatically
depending on the group set in the instance.
This is not compatible with the approach of the overview page where we
filter by all groups of a user.
2025-09-01 06:20:27 +02:00
Laurent David d6182fad58 MDL-86216 mod_scorm: Add support for groups in overview page 2025-09-01 06:08:15 +02:00
AMOS bot a621f235c4 Automatically generated installer lang files 2025-09-01 00:07:58 +00:00
Luca Bösch b80ac52d54 MDL-86366 quiz: Description shouldn't show each secure page, but title. 2025-08-31 17:31:38 +02:00
Paul Holden 513a32f94a MDL-86066 reportbuilder: hook up front end elements to new schedules. 2025-08-29 16:02:18 +01:00
Paul Holden ce09276d3e MDL-86066 reportbuilder: establish base schedule class implementation.
Move previous functionality from, and deprecate, the schedule helper
class method for creation.

Switch task to support new API, and fix privacy provider for the same.
2025-08-29 16:02:18 +01:00
Paul Holden fc61185514 MDL-86066 reportbuilder: schedule schema update to support class types.
In order to support upcoming changes that allow for multiple types of
report schedule to be configured, update the table/persistent schema to
be more generic.

Audience data is retained as a first-class property, in order to more
easily and consistently support schedules that make use of audience data
and API, although the field itself is now nullable.
2025-08-29 16:00:06 +01:00
Paul Holden 75b4383b11 MDL-86177 task: ensure tasks are runnable in indicator output.
Also fix case where task indicator progress data no longer exists,
which lead to exceptions when encountered, breaking the gradebook.
2025-08-29 15:51:20 +01:00
Paul Holden 8502831121 MDL-85266 tool_uploaduser: correctly key bulk users session array. 2025-08-29 15:50:01 +01:00
Jun Pataleta 1e9eccc1f1 MDL-86479 course: Add accessibility coverage for course index options 2025-08-29 21:11:21 +08:00
Jun Pataleta 501f792893 MDL-86479 theme_boost: Fix a11y issues on the course index options
* Add aria-label for the options menu button.
* Add proper menu and menuitem roles for the options menu.
2025-08-29 21:11:20 +08:00
cescobedo a1a8af4ca0 on-demand release 5.1dev+ 2025-08-29 15:02:26 +02:00
cescobedo ff12c8306b NOBUG: Add upgrade notes 2025-08-29 15:02:26 +02:00
Jun Pataleta 63741143c2 MDL-86489 mod_feedback: Add accessibility coverage for Questions tab
* Also fix the heading level issue found by the test.
2025-08-29 20:50:24 +08:00
Jun Pataleta 734294277d MDL-86489 mod_feedback: Mark required icon as decorative
* Set `alt` param as empty, but add `title` attribute for the sake of
sighted users.
* Add a visually hidden string that indicates the element is required.
2025-08-29 20:50:23 +08:00
Sara Arjona 3d4b09b254 Merge branch 'MDL-80295-main' of https://github.com/ferranrecio/moodle 2025-08-29 06:29:59 +02:00
Jun Pataleta 00dd1986bb MDL-86499 core: Make table sort icons decorative 2025-08-29 12:24:45 +08:00
Huong Nguyen 5f616c49d8 Merge branch 'MDL-86343' of https://github.com/paulholden/moodle 2025-08-29 11:03:47 +07:00
Huong Nguyen 411647dd46 Merge branch 'MDL-85743' of https://github.com/paulholden/moodle 2025-08-29 11:00:32 +07:00
yusufwib01 fea351a39d MDL-86459 libraries: Upgrade libphonenumber-for-php-lite to 9.0.12 2025-08-29 10:56:04 +07:00
Michael Hawkins 72074466ae Merge branch 'MDL-85727-main' of https://github.com/HuongNV13/moodle 2025-08-29 11:52:52 +08:00
Mihail Geshoski 6eea9a5445 Merge branch 'MDL-83256' of https://github.com/paulholden/moodle 2025-08-29 11:34:13 +08:00
Huong Nguyen 16dd2607a9 Merge branch 'MDL-86452-main' of https://github.com/andrewnicols/moodle 2025-08-29 08:46:03 +07:00
Huong Nguyen 68fb7ea4b2 Merge branch 'MDL-86301-main' of https://github.com/andrewnicols/moodle 2025-08-29 08:41:10 +07:00
Huong Nguyen 07b7a281e6 Merge branch 'MDL-71147' of https://github.com/paulholden/moodle 2025-08-29 08:38:30 +07:00
Huong Nguyen 8d89a80b10 Merge branch 'MDL-77593_improve-performance-of-adding-members-to-communication-room' of https://github.com/ziegenberg/moodle 2025-08-29 08:36:04 +07:00
Paul Holden bd55b1668b MDL-82244 course: use site default course visibility in external call. 2025-08-28 17:39:58 +01:00
Paul Holden 0faeff2e1f MDL-86248 theme_boost: consistently apply dropdown item spacing.
Replace previous ad-hoc fixes for active item spacing in dropdown
menu items.

Changes to Javascript are due to the following bug in our SCSS
compiler, preventing a simpler `&:has([...])` selector:

https://github.com/scssphp/scssphp/issues/606

Co-authored-by: Mikel Martín <mikel@moodle.com>
2025-08-28 16:51:25 +01:00
ferran a02b601835 MDL-80295 core_courseformat: render cm controls using new rendering 2025-08-28 16:30:45 +02:00
ferran f0e2495ffd MDL-80295 core_courseformat: actvity chooser JS with section ID 2025-08-28 16:30:45 +02:00
ferran 801d046d21 MDL-80295 core_courseformat: activity chooser rendering using section ID 2025-08-28 16:30:45 +02:00
ferran 28421208b7 MDL-80295 core_courseformat: replace content items old webservice 2025-08-28 16:30:40 +02:00
Amaia Anabitarte 50fafca3c6 Merge branch 'MDL-86210-main' of https://github.com/ferranrecio/moodle 2025-08-28 16:03:36 +02:00
ferran 707aa5416c MDL-86210 core_courseformat: add permalink to activities 2025-08-28 15:57:10 +02:00
Amaia Anabitarte c8c6761cc4 Merge branch 'MDL-86280-main' of https://github.com/lucaboesch/moodle 2025-08-28 11:19:28 +02:00
Andrew Nicols f47311d0e3 MDL-86301 phpunit: Move fixture loading to base_testcase 2025-08-28 17:15:40 +08:00
Andrew Nicols d377b11ed6 MDL-86301 core: Switch to autoloaded externallib_testcase 2025-08-28 17:15:40 +08:00
Sara Arjona 3bcdb7b195 Merge branch 'MDL-86445-main' of https://github.com/roland04/moodle 2025-08-28 10:28:27 +02:00
Andrew Nicols 39765bece6 MDL-86452 core: Update coding style from previous commit
- phpunit_util
- tests for the basic_testcase
2025-08-28 13:53:26 +08:00
Andrew Nicols dc936abf1c MDL-86452 core: Reset navigation data between tests 2025-08-28 13:53:25 +08:00
Huong Nguyen b2b195cfff MDL-85727 tiny_premium: Support On-Premise version
Users can now select whether to use the Cloud-hosted version
or the On-Premise version of Premium plugins, providing
flexibility ased on their deployment preferences
2025-08-28 11:07:22 +07:00
Huong Nguyen 5ed43130d6 MDL-85727 editor_tiny: Support standalone package
Users can now choose to use either the bundled version or the
standalone package version of the TinyMCE editor, allowing more
flexibility in deployment and maintenance.
2025-08-28 11:07:22 +07:00
Huong Nguyen 2b9cf522a5 Merge branch 'MDL-86348-main' of https://github.com/yusufwib01/moodle 2025-08-28 10:34:55 +07:00
Huong Nguyen 029bf809d4 Merge branch 'MDL-86345-main' of https://github.com/yusufwib01/moodle 2025-08-28 10:31:53 +07:00
Andrew Nicols 1a8ba37e2b MDL-86301 core: Fix externallib_testcase style 2025-08-28 09:16:08 +08:00
Andrew Nicols f4eed1f6b2 MDL-86301 core: Create autoloadable externallib_testcase 2025-08-28 09:16:08 +08:00
ferran 8613052659 Merge branch 'MDL-79918-main' of https://github.com/sarjona/moodle 2025-08-27 18:19:13 +02:00
ferran f553947bd5 MDL-80295 core_course: mod and modedit compatible with section id 2025-08-27 16:55:50 +02:00
ferran ea0e555182 MDL-86245 core_course: improve activity chooser search 2025-08-27 16:53:27 +02:00
ferran 7f03847291 MDL-86195 course: clean activity chooser behat 2025-08-27 16:53:27 +02:00
ferran ac3453c9a9 MDL-85598 course: review activities purposes values 2025-08-27 16:53:27 +02:00
ferran f84136e9f7 MDL-85598 course: review activities purposes values 2025-08-27 16:53:27 +02:00
ferran 0682e00cab MDL-85598 course: add other purpose to modchooser 2025-08-27 16:53:27 +02:00
ferran d176fe36c9 MDL-85598 course: new other purpose feature 2025-08-27 16:53:27 +02:00
ferran a6ff943f84 MDL-86245 core_course: improve activity chooser search 2025-08-27 16:08:24 +02:00
Amaia Anabitarte 99bce86b18 Merge branch 'MDL-83898-main' of https://github.com/laurentdavid/moodle 2025-08-27 15:43:03 +02:00
Amaia Anabitarte 356f23a486 Merge branch 'MDL-86195-main' of https://github.com/ferranrecio/moodle 2025-08-27 15:28:54 +02:00
Amaia Anabitarte e882b75de1 Merge branch 'MDL-85598-main' of https://github.com/ferranrecio/moodle 2025-08-27 15:19:06 +02:00
Sara Arjona 501693927c Merge branch 'MDL-86146-main' of https://github.com/ferranrecio/moodle 2025-08-27 12:22:25 +02:00
Laurent David 00fc1a5bdb MDL-83898 mod_quiz: Adapt quiz overview index page 2025-08-27 11:50:13 +02:00
Laurent David 907feb1498 MDL-83898 mod_quiz: Add overview page for quiz 2025-08-27 11:50:13 +02:00
Sara Arjona 4f835c4bf1 MDL-85660 format: Move format_social install to public 2025-08-27 11:43:08 +02:00
Stefan Hanauska 7e09bfd82f MDL-86454 badges: Hide revoke button if not available 2025-08-27 10:09:30 +02:00
ferran 73b9ab545c Merge branch 'MDL-85660-main' of https://github.com/sarjona/moodle 2025-08-27 08:47:50 +02:00
Sara Arjona bed76ba8c1 Merge branch 'MDL-84632-main' of https://github.com/ferranrecio/moodle 2025-08-27 07:17:25 +02:00
Sara Arjona 3e76f8eba8 Merge branch 'MDL-85284-main' of https://github.com/ferranrecio/moodle 2025-08-27 07:16:46 +02:00
Sara Arjona c5f4a3143b Merge branch 'MDL-84809-main' of https://github.com/roland04/moodle 2025-08-27 07:15:32 +02:00
Sara Arjona 61da87857a Merge branch 'MDL-85850-main' of https://github.com/sarjona/moodle 2025-08-27 07:14:13 +02:00
Sara Arjona 56b4536a32 Merge branch 'MDL-85851-main' of https://github.com/sarjona/moodle 2025-08-27 07:11:41 +02:00
Sara Arjona 9969166b3e Merge branch 'MDL-85854-main' of https://github.com/aanabit/moodle 2025-08-27 07:05:11 +02:00
Sara Arjona 60f858b937 Merge branch 'MDL-85925-main' of https://github.com/roland04/moodle 2025-08-27 06:43:59 +02:00
Sara Arjona bd2135411f Merge branch 'MDL-85957-main' of https://github.com/sarjona/moodle 2025-08-27 06:42:14 +02:00
Rajneel Totaram f0a47b1f70 MDL-86339 qtype_numeric: Coding style improvements 2025-08-27 16:19:39 +12:00
Rajneel Totaram 3b4cd1e166 MDL-86339 qtype_numeric: Display units dropdown on the same line 2025-08-27 16:15:53 +12:00
Dean Chimezie 92eff4d1e8 MDL-86447 tool_mfa: Restore setup lang string 2025-08-26 12:47:27 -04:00
Luca Bösch e44d80a28d MDL-86280 mod: Do not filter help text in activity chooser.
Co-authored-by: Ferran Recio <ferran@moodle.com>
2025-08-26 18:19:30 +02:00
Sara Arjona 4c2f378a05 MDL-85660 format: Fix tests after disabling Social 2025-08-26 18:03:55 +02:00
Sara Arjona 9c4e1d7706 MDL-85660 format: Disable social course format
The social course format is now disabled by default for all new and
upgraded installations.
Existing courses using this format will continue to function, but
administrators must re-enable it to create new social courses.
2025-08-26 18:03:54 +02:00
ferran 2fd8e3b80d Merge branch 'MDL-85981-main' of https://github.com/sarjona/moodle 2025-08-26 17:09:02 +02:00
Mikel Martín eab69f2609 MDL-86445 theme_boost: Fix notifications date margin 2025-08-26 16:46:34 +02:00
cescobedo e3e51a0613 on-demand release 5.1dev+ 2025-08-26 15:56:13 +02:00
cescobedo f2e0c296c2 NOBUG: Add upgrade notes 2025-08-26 15:56:13 +02:00
cescobedo 0ca8758d8c Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-08-26 15:56:01 +02:00
Sara Arjona 5f299ff246 MDL-85981 courseformat: Add overviewaction output 2025-08-26 15:05:30 +02:00
ferran 224c4a73d0 MDL-86195 course: clean activity chooser behat 2025-08-26 12:26:43 +02:00
ferran 2d11b3e140 MDL-85598 course: review activities purposes values 2025-08-26 12:18:20 +02:00
ferran 7d1ff73a90 MDL-85598 course: add other purpose to modchooser 2025-08-26 12:18:20 +02:00
ferran ac7e3ed521 MDL-85598 course: new other purpose feature 2025-08-26 12:18:20 +02:00
Amaia Anabitarte 768ede6416 MDL-85854 mod_data: Implement group based information in overview page 2025-08-26 11:40:17 +02:00
Amaia Anabitarte 550963f369 MDL-85854 mod_data: Remove string manager dependency 2025-08-26 11:26:15 +02:00
Mikel Martín 4eabc4020b MDL-85925 mod_lesson: Implement group based information in overview page 2025-08-26 10:40:23 +02:00
Mihail Geshoski a242032ff1 Merge branch 'MDL-85677-main' of https://github.com/lameze/moodle 2025-08-26 11:58:05 +08:00
Mihail Geshoski 70184f09ba Merge branch 'MDL-85229' of https://github.com/paulholden/moodle 2025-08-26 11:49:47 +08:00
Mihail Geshoski 2ff8a303f6 Merge branch '76318-gradebook-improve-csv-import-error-message-main' of https://github.com/DSI-Universite-Rennes2/moodle 2025-08-26 11:28:12 +08:00
Mihail Geshoski b021a0414f Merge branch 'MDL-80283-main' of https://github.com/lucaboesch/moodle 2025-08-26 10:45:40 +08:00
Huong Nguyen 309bb2af82 Merge branch 'MDL-86315-main' of https://github.com/davewoloszyn/moodle 2025-08-26 09:23:13 +07:00
Adrian Greeve cd0bc9a3ac MDL-86204 core: Removed ending custom check tag
This was stopping further checks from showing.
2025-08-26 10:01:11 +08:00
Adrian Greeve 04d76ebae7 Merge branch 'MDL-86204-main' of https://github.com/andrewnicols/moodle 2025-08-26 10:00:08 +08:00
Huong Nguyen c60b931c29 Merge branch 'MDL-85518-main' of https://github.com/davewoloszyn/moodle 2025-08-26 08:21:55 +07:00
Simey Lameze a95cd67b5b MDL-85677 behat: test to verify SEB download link visibility 2025-08-26 09:12:28 +08:00
Luca Bösch 791df89032 MDL-80283 url: url page less wide. 2025-08-25 18:45:32 +02:00
Mihail Geshoski e0e85be743 Merge branch 'MDL-85676-main' of https://github.com/lameze/moodle 2025-08-26 00:44:35 +08:00
Sara Arjona a317e43ac6 MDL-85957 choice: Implement group based information in overview page 2025-08-25 17:20:32 +02:00
Daniel Ziegenberg 8d5b597b69 MDL-77593 communication: improve performance adding or removing members
Before this change, the communication room gets all the users when
enrolled or from the course when a new communication instance is added.
It happens using an ad-hoc task but there is no efficiency to handle the
number of users should be added in one go. This might have scaling
issues in terms of courses with massive number of enrolment or users.

This commit implements a logic to chunk the data and queue them so these
can happen in smaller chunks without keeping the servers busy for a long
time.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-08-25 17:14:47 +02:00
Sara Arjona 1cd8adcd2a MDL-85850 feedback: Implement group based information in overview page 2025-08-25 16:53:19 +02:00
ferran 05e07c3b14 Merge branch 'MDL-85853-main' of https://github.com/aanabit/moodle 2025-08-25 15:09:58 +02:00
ferran ce140c7619 MDL-84632 mod_url: deprecate index.php related event 2025-08-25 15:03:50 +02:00
ferran df82be756e MDL-84632 mod_resource: deprecate index.php related event 2025-08-25 15:03:24 +02:00
ferran b82b297954 MDL-84632 mod_page: deprecate index.php related event 2025-08-25 15:02:53 +02:00
ferran 925a46562f MDL-84632 mod_imscp: deprecate index.php related event 2025-08-25 15:02:33 +02:00
ferran 5db10f3a32 MDL-84632 mod_folder: deprecate index.php related event 2025-08-25 15:02:08 +02:00
ferran 47a323af46 MDL-84632 mod_book: deprecate index.php related event 2025-08-25 15:01:43 +02:00
Amaia Anabitarte 677b1cff40 Merge branch 'MDL-86179-main' of https://github.com/sarjona/moodle 2025-08-25 13:27:39 +02:00
Amaia Anabitarte c482b45b5c MDL-85853 mod_hp5activity: Implement group based information in overview 2025-08-25 13:23:03 +02:00
Sara Arjona 3e21697780 MDL-85851 assign: Implement group based information in overview page 2025-08-25 13:02:33 +02:00
Sara Arjona 670fb056e5 MDL-85981 data: Remove stringmanager from overview page 2025-08-25 12:52:47 +02:00
Sara Arjona e5191f1dd4 MDL-85981 forum: Remove stringmanager from overview page 2025-08-25 12:52:47 +02:00
ferran d241755acc Merge branch 'MDL-86338-main' of https://github.com/laurentdavid/moodle 2025-08-25 12:30:54 +02:00
Andrew Nicols cc7ab4ce22 MDL-85816 core: Warn on /public URLs 2025-08-25 17:05:56 +08:00
Dani Palou a12790ee5d MDL-86215 course: Add WebService to log module instance viewed 2025-08-25 10:57:37 +02:00
Andrew Nicols be8c96761f MDL-86204 core: Coding style updates 2025-08-25 16:57:00 +08:00
Shamim Rezaie 9212869e71 Merge branch 'MDL-71749-main' of https://github.com/ScottVerbeek/moodle 2025-08-25 18:26:43 +10:00
Adrian Greeve c62f97cd67 Merge branch 'MDL-82322-main' of https://github.com/andrewnicols/moodle 2025-08-25 16:00:31 +08:00
Sara Arjona 464447c883 MDL-79918 format: Improve the Hidden sections setting 2025-08-25 09:17:46 +02:00
Andrew Nicols bb78066b8f MDL-82322 course: Coding style fixes 2025-08-25 15:09:50 +08:00
Andrew Nicols 5b98b99c59 MDL-82322 course: Re-namespace dndupload classes 2025-08-25 15:09:28 +08:00
Andrew Nicols 4c77e6ba49 MDL-82322 course: Autoload course dndupload classes 2025-08-25 15:09:28 +08:00
Andrew Nicols 49d9b0a688 MDL-82322 course: Update request form namespaces 2025-08-25 15:09:06 +08:00
Andrew Nicols cb24f09b32 MDL-82322 course: Autoload course request classes 2025-08-25 14:49:59 +08:00
Andrew Nicols bc79083506 MDL-82322 core_course: Update namespace of \course_request 2025-08-25 14:49:58 +08:00
Andrew Nicols 9da5af5c5f MDL-82322 course: Migrate course_request class to autoloading 2025-08-25 14:49:56 +08:00
Andrew Nicols a4744bc5fe MDL-86204 core: Add environment tests for dev dependencies 2025-08-25 14:33:19 +08:00
Andrew Nicols dbc8a08e68 MDL-86204 test: Rename environmentlib test correctly 2025-08-25 14:33:19 +08:00
Andrew Nicols 9ffa11d11b MDL-86204 admin: Stop warning about non-dev composer dir 2025-08-25 14:33:18 +08:00
David Woloszyn 234ea10c03 MDL-85672 registration: Agreement privacy notice URL updated 2025-08-25 16:22:45 +10:00
Simey Lameze 9dc05e31db MDL-85676 behat: validate SEB attempt message 2025-08-25 13:58:13 +08:00
David Woloszyn 399aaeca1f MDL-85518 admin: Assign search match types to improve result sorting 2025-08-25 12:01:29 +10:00
David Woloszyn ac9dfd7f85 MDL-85672 registration: Fix Cibot format errors 2025-08-25 10:15:41 +10:00
David Woloszyn 861ae42967 MDL-85672 registration: Remove unused methods from form class 2025-08-25 10:15:41 +10:00
David Woloszyn be8adf1373 MDL-85672 registration: Added new fields to registration form 2025-08-25 10:15:41 +10:00
AMOS bot 47e90b473b Automatically generated installer lang files 2025-08-24 00:10:09 +00:00
Paul Holden 6519e8b09a MDL-85707 mod_forum: implement forum datasource for custom reporting.
Create new entities for exposing report data on forums, discussions
and posts; join to the course and user entities to provide data for
the reportbuilder editor.
2025-08-22 15:34:59 +01:00
Paul Holden 5094bb2f1f MDL-85706 message: implement messages datasource for custom reporting.
Create new entities for report data on messages/conversations, joined
to the user entity, providing data for the reportbuilder editor.
2025-08-22 15:20:30 +01:00
Paul Holden e6ca00993a MDL-85706 message: switch time-sensitive code to new Clock API.
Where current implementation relies on the current time then replace
that with the PSR-20 Clock from 298c13ac3b. This allows for better
and more accurate testing of such code.
2025-08-22 15:20:30 +01:00
Mihail Geshoski 6509b43b4c on-demand release 5.1dev+ 2025-08-22 20:45:26 +08:00
Mihail Geshoski a6383c5d9b NOBUG: Add upgrade notes 2025-08-22 20:45:26 +08:00
Mikel Martín 3e246694aa MDL-84809 mod_workshop: Implement group based information in overview 2025-08-22 12:58:53 +02:00
Julien Boulen ead32c158e MDL-76318 gradebook: Improve csv import error message 2025-08-22 09:57:01 +02:00
Huong Nguyen ddee87dbcc MDL-73845 enrol_database: Fix MySQL issue 2025-08-22 13:01:41 +08:00
Adrian Greeve fa2676cf86 Merge branch 'MDL-86256' of https://github.com/paulholden/moodle 2025-08-22 11:27:00 +08:00
Huong Nguyen cebaeffbeb MDL-83519 core: Fix Database schema 2025-08-22 09:37:22 +07:00
Adrian Greeve db055310a8 Merge branch 'main' of git.in.moodle.com:moodle/integration into MDL-86254 2025-08-22 10:06:28 +08:00
ferran 0fd34211df MDL-86254 core_comment: deprecate locallib classes 2025-08-22 09:48:03 +08:00
ferran a462603ea5 MDL-86254 core: remove comment/lib.php inclusions 2025-08-22 09:48:03 +08:00
ferran c7af4b4e94 MDL-86254 core_comment: Update coding style for updated classes 2025-08-22 09:48:03 +08:00
ferran 94fdbc5279 MDL-86254 core_comment: Move course internals to autoloading 2025-08-22 09:48:00 +08:00
Huong Nguyen 9755236837 Merge branch 'MDL-86231-main' of https://github.com/andrewnicols/moodle 2025-08-22 08:46:36 +07:00
Huong Nguyen 43be0bf691 Merge branch 'MDL-83519-main' of https://github.com/HuongNV13/moodle 2025-08-22 08:37:13 +07:00
Huong Nguyen 5a25d876c7 MDL-83519 core: Add shortlink privacy provider 2025-08-22 08:35:18 +07:00
David Woloszyn e385176ffa MDL-83519 router: Checks to routerconfigured are less strict 2025-08-22 08:34:24 +07:00
David Woloszyn 0eaf3b13b7 MDL-83519 core_sms: Remove URLs from long messages 2025-08-22 08:34:16 +07:00
David Woloszyn ba54e467b5 MDL-83519 mod_assign: Use shortlinks in SMS notifications 2025-08-22 08:34:08 +07:00
David Woloszyn 2e114a04f9 MDL-83519 mod_assign: Add shortlink handler
Co-authored-by: Andrew Lyons <andrew@nicols.co.uk>
2025-08-22 08:34:00 +07:00
David Woloszyn 253a38486d MDL-83519 core_sms: Add shortlinks to SMS manager
Co-authored-by: Andrew Lyons <andrew@nicols.co.uk>
2025-08-22 08:33:53 +07:00
David Woloszyn 681b15b9f0 MDL-83519 core: Support for short links
Co-authored-by: Andrew Lyons <andrew@nicols.co.uk>
2025-08-22 08:33:42 +07:00
yusufwib01 42b8deeb63 MDL-86348 libraries: Upgrade GeoIP2 and Maxmind DB Reader
- GeoIP2 PHP API 3.2.0
- MaxMind DB Reader API 1.12.1
2025-08-22 00:44:18 +07:00
yusufwib01 034fec6b7a MDL-86345 libraries: upgrade to version 1.3.75 of Minify. 2025-08-22 00:09:00 +07:00
ferran 4eb288bf41 Merge branch 'MDL-83889-main' of https://github.com/laurentdavid/moodle 2025-08-21 17:22:31 +02:00
Paul Holden 951ab8d704 MDL-71147 enrol_manual: allow start date selection in enrolment form. 2025-08-21 14:55:06 +01:00
Laurent David f4b12bf936 MDL-86338 course_format: Resources overview page redirection 2025-08-21 12:35:18 +02:00
Jun Pataleta 661740ae5c MDL-81455 behat: Add accessibility coverage to default start page tests 2025-08-21 17:50:22 +08:00
Jun Pataleta 39ad410585 Merge branch 'MDL-81455-main' of https://github.com/rajutm25/moodle 2025-08-21 17:48:20 +08:00
ferran 50160d3601 MDL-85284 core_course: deprecate changenumsections.php 2025-08-21 10:13:19 +02:00
Jun Pataleta c8e4164222 Merge branch 'MDL-86202-main' of https://github.com/rjnl/moodle 2025-08-21 15:21:03 +08:00
Rajneel Totaram 6ca7da74ca MDL-86202 mod_lesson: Use correct heading level 2025-08-21 18:26:02 +12:00
Mihail Geshoski 79bab8203a Merge branch 'MDL-84850' of https://github.com/paulholden/moodle 2025-08-21 11:47:17 +08:00
Huong Nguyen 59ae95b5dd Merge branch 'MDL-86311' of https://github.com/paulholden/moodle 2025-08-21 09:29:49 +07:00
Huong Nguyen fd2a861554 Merge branch 'MDL-82943-main' of https://github.com/stevandoMoodle/moodle 2025-08-21 09:13:41 +07:00
Huong Nguyen 0827e16aee Merge branch 'MDL-80611' of https://github.com/marinaglancy/moodle 2025-08-21 08:54:38 +07:00
ferran 22aed3f732 Merge branch 'MDL-85146-main' of https://github.com/sarjona/moodle 2025-08-20 17:09:30 +02:00
ferran 652ef4d6f0 Merge branch 'MDL-80556-main' of https://github.com/sarjona/moodle 2025-08-20 16:55:41 +02:00
ferran b27b994013 Merge branch 'MDL-83887-main' of https://github.com/sarjona/moodle 2025-08-20 16:13:09 +02:00
Mihail Geshoski 334bec4f27 Merge branch 'MDL-84739' of https://github.com/paulholden/moodle 2025-08-20 17:24:36 +08:00
Paul Holden a6ab780daa MDL-85684 mod_assign: format course/assignment notification content. 2025-08-20 09:14:46 +01:00
Paul Holden 3842b3ea28 MDL-83474 webservice: fix empty/zero $itemid handling in text format. 2025-08-20 09:08:20 +01:00
Mihail Geshoski b6b4c638f9 Merge branch 'MDL-86015' of https://github.com/paulholden/moodle 2025-08-20 09:55:21 +08:00
Huong Nguyen d143d1d665 Merge branch 'matrix-user-prefix' of https://github.com/geichelberger/moodle 2025-08-20 08:44:41 +07:00
Huong Nguyen 7846d3fe64 Merge branch 'MDL-73845-main' of https://github.com/HuongNV13/moodle 2025-08-20 08:41:25 +07:00
Paul Holden 27c4ec6bc7 MDL-86375 report_outline: consistent icon sizing/alignment.
Tighten selector for actual table so we don't break others on the
page (e.g. debug footer cache table).
2025-08-20 00:26:32 +01:00
Paul Holden 05c4e6888f MDL-86374 report_outline: use formatted activity name in report. 2025-08-20 00:18:34 +01:00
Scott Verbeek 88f5150548 MDL-71749 assign: Add resize function to grader 2025-08-20 08:07:20 +10:00
Russell England 48c2190af9 MDL-86142 reportbuilder: Add course url columns
Co-authored-by: Paul Holden <paulh@moodle.com>
2025-08-19 17:38:06 +01:00
Paul Holden 5da427267e MDL-85743 user: correct debugging for missing user picture fields. 2025-08-19 17:12:29 +01:00
Paul Holden 186b44d490 MDL-84850 tag: ensure course tags enabled before adding to navigation. 2025-08-19 17:10:49 +01:00
Stevani Andolo ef942cb2e7 MDL-82943 behat: Fix behat failures 2025-08-19 23:17:21 +08:00
Stevani Andolo 0609759f8e MDL-82943 editor_tiny: Embed styling uplift 2025-08-19 23:17:21 +08:00
Stevani Andolo b55afd06f7 MDL-82943 editor_tiny: Image styling uplift 2025-08-19 23:17:21 +08:00
Stevani Andolo 4e15e61fd5 MDL-82943 editor_tiny: Refactored embed path 2025-08-19 23:17:21 +08:00
Stevani Andolo 0970d7406a MDL-82943 editor_tiny: Refactored image path 2025-08-19 23:17:15 +08:00
Shamim Rezaie c1311feeb1 weekly release 5.1dev 2025-08-20 00:45:15 +10:00
Shamim Rezaie db839bf509 NOBUG: Add upgrade notes 2025-08-20 00:45:15 +10:00
Shamim Rezaie 2dc91f3c83 Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-08-20 00:44:59 +10:00
rajutm25 e0a03795f5 MDL-81455 core: Fix welcome message heading in dashboard
The welcome message on login was incorrectly replacing the dashboard
page header.The change ensures the welcome message appears as a
paragraph while maintaining the dashboard page heading.
2025-08-19 19:42:35 +05:30
Paul Holden bfcb13574e MDL-86363 completion: ensure module viewed completion data is cleaned.
The privacy provider should ensure it removes said data consistently.
2025-08-19 11:12:29 +01:00
Huong Nguyen 5065583b8c Merge branch 'MDL-85286' of https://github.com/paulholden/moodle 2025-08-19 16:06:03 +07:00
Huong Nguyen 365c58415b Merge branch 'MDL-84794' of https://github.com/paulholden/moodle 2025-08-19 16:06:03 +07:00
Mi Jia Looi e59c575d11 MDL-73845 enrol_database: Add lock to prevent race condition 2025-08-19 15:28:20 +07:00
Paul Holden 76e481b9ce MDL-86311 core: ensure component is normalised prior to comparison. 2025-08-19 09:13:36 +01:00
Paul Holden 4c844801bb MDL-86311 question: fixes for PHPUnit related warnings/notices.
* Correct component generator name;
* Add missing required object properties;
* Assert expected debugging messages
2025-08-19 09:13:36 +01:00
Paul Holden d011564222 MDL-86311 phpunit: update default configuration to fail on warnings.
This restores pre-PHPUnit 10 behaviour, and ensures that warnings
emitted by PHP during test execution will cause the test to fail.
2025-08-19 09:13:20 +01:00
Jun Pataleta 0cf827bfa5 MDL-72511 calendar: Better calendar navigation labelling
* Make the accessible labels of the previous and next month links more
informative by indicating the name of the previous/next months.
* Make titles on the previous and next month links reflect the actual
month and show titles only when the calendar is rendered within a block.
This is because the title attribute is only used for the sake for
sighted users who may need to know the meaning of the previous/next
month links, especially when the calendar is displayed in compact form
where the previous/next month name is not shown.
2025-08-19 11:22:17 +08:00
Jun Pataleta 1d971e0a82 MDL-72511 calendar: Fix month_mini navigation
* Hide arrow icons from assistive technologies.
* Add a more sensible aria-label for the previous/next
month links.
2025-08-19 11:17:46 +08:00
Huong Nguyen 7923355aa1 Merge branch 'MDL-86109-main' of https://github.com/stevandoMoodle/moodle 2025-08-19 09:53:25 +07:00
Mihail Geshoski 041f43b9e9 Merge branch 'MDL-83772-main' of https://github.com/srobotta/moodle 2025-08-19 10:28:34 +08:00
Paul Holden dddf86c05d MDL-86343 reportbuilder: fix course groupmode column type value.
Per a3c386af, this column does not produce numeric output. Also cleanup
redundancy in the default branch of corresponding switch statement.
2025-08-18 17:03:00 +01:00
Gregor Eichelberger 1466784fc7 MDL-85520 communication_matrix: Configurable user prefix
Allow the configuration of the matrix user prefix for numerical user
names for greater flexibility when integrating with existing matrix
installations.

Co-authored-by: David Woloszyn <david.woloszyn@moodle.com>
Signed-off-by: Gregor Eichelberger <gregor.eichelberger@tuwien.ac.at>
2025-08-18 13:09:48 +02:00
ferran b96fa1ceb7 Merge branch 'MDL-86036-main' of https://github.com/roland04/moodle 2025-08-18 12:13:51 +02:00
Paul Holden 606bb89188 MDL-85286 reportbuilder: schedule report filter by enabled state. 2025-08-18 10:59:44 +01:00
Paul Holden bb049f199e MDL-84739 gradingform_rubric: consistently style rubric table icons. 2025-08-18 08:57:50 +01:00
Paul Holden 1bcfb780bb MDL-83256 user: account for course context instances of teacher fields. 2025-08-18 08:56:56 +01:00
Paul Holden 47622a83cc MDL-85229 mod_url: observe description appearance setting on display.
Correctly determine whether said description is in fact "empty".
2025-08-18 08:55:39 +01:00
Paul Holden b206404a39 MDL-83066 blocks: restore deletion warning for "sticky" blocks.
It was lost when switching to modal delete configuration in 529c5c2e.
2025-08-18 08:49:20 +01:00
Mikel Martín 1b339cd6d8 MDL-86036 course: Add gradable info to activity chooser 2025-08-18 08:52:14 +02:00
Laurent David d48a8e03f1 MDL-83889 mod_bigbluebuttonbn: Add overview index page 2025-08-18 08:05:16 +02:00
Laurent David bf2ccb6592 MDL-83889 mod_bigbluebuttonbn: Add overview page 2025-08-18 08:05:16 +02:00
Laurent David f6da0c1ff0 MDL-83889 mod_bigbluebuttonbn: Add date classes and tests 2025-08-18 08:05:16 +02:00
Daniel Ziegenberg 89111fffa7 MDL-86294 core: Document missing dboptions in config-dist.php
For the full list of database config settings, the config-dist.php file
referred to https://docs.moodle.org/en/Database_settings, which in turn
pointed back to
https://github.com/moodle/moodle/blob/master/config-dist.php. We should
not play hide and seek with our configuration options, so let's document
them.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-08-17 17:04:30 +02:00
AMOS bot 0d1b4ca44d Automatically generated installer lang files 2025-08-16 00:08:05 +00:00
sam marshall 76dbebef1a MDL-86308 assignfeedback_file: Log download of feedback files 2025-08-15 15:59:01 +01:00
Philipp Memmel 2b511dd42f MDL-86187 core_ddl: Add reserved keywords for MySQL 8.4 2025-08-15 11:17:35 +00:00
Paul Holden f42ee02f82 MDL-86015 mod_assign: preserve advanced grading modal dropdown state.
Don't autoclose it when clicking inside the dropdown element. Fixes
change of behaviour during the Bootstrap 5 upgrade.
2025-08-15 11:04:10 +01:00
Paul Holden c479d30b06 MDL-86015 output: support autoclose behaviour in dropdown dialog. 2025-08-15 11:04:07 +01:00
Paul Holden 6f9fff031a MDL-85682 mod_assign: account for absence of workflow select filter. 2025-08-15 10:48:10 +01:00
David Woloszyn 6606a9c6dc MDL-86315 registration: Unset emails in hub when dependant value not set 2025-08-15 12:32:17 +10:00
Huong Nguyen 2b96047622 weekly release 5.1dev 2025-08-15 09:26:19 +07:00
Huong Nguyen e9f5a990a0 NOBUG: Add upgrade notes 2025-08-15 09:26:19 +07:00
Huong Nguyen bb4d7be5ef Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-08-15 09:25:56 +07:00
Stevani Andolo 50c2601fd2 MDL-86109 tiny_media: Fix selected subtitles and captions language
Ensures the selected subtitle or caption language is correctly retained
and displayed.
2025-08-15 09:48:02 +08:00
Mark Sharp c041644fed MDL-83014 core_h5p: List downloaded content types in task output 2025-08-14 17:28:14 +01:00
Sara Arjona a58900a94e MDL-86179 choice: Improve behat tests for overview page 2025-08-14 13:01:03 +02:00
Sara Arjona 2faf01af93 MDL-86179 courseformat: Add behat tests for resources overview 2025-08-14 13:01:03 +02:00
Paul Holden 2150850f76 MDL-72956 mod_feedback: remove session access for started activities. 2025-08-14 11:27:30 +01:00
Sara Arjona dfbd95c986 MDL-85146 output: Deprecated core:e/text_highlight(_picker) icons
The `core:e/text_highlight` and `core:e/text_highlight_picker` icons are
deprecated and will be removed in Moodle 6.0.
The UX team recommended this change to reduce visual clutter and improve
readability. The icons were removed because they didn't indicate status
changes, were repetitive across all notifications, and took up space that
could be used for more content.
2025-08-14 07:10:45 +02:00
Huong Nguyen 8b25d7788d Merge branch 'MDL-85505-main' of https://github.com/catalyst/moodle 2025-08-14 09:47:51 +07:00
Rajneel Totaram 3b40e5cbf3 MDL-73417 mod_assign: Remove duplicate array key 2025-08-14 12:45:37 +12:00
AMOS bot b2cf961265 Automatically generated installer lang files 2025-08-14 00:08:13 +00:00
Sara Arjona a042633966 Merge branch 'MDL-86196' of https://github.com/paulholden/moodle 2025-08-13 17:34:50 +02:00
Sara Arjona d81c2e3b37 Merge branch 'MDL-85593-main' of https://github.com/roland04/moodle 2025-08-13 17:31:46 +02:00
ferran ecfb2558c1 Merge branch 'MDL-83899-main' of https://github.com/laurentdavid/moodle 2025-08-13 17:17:05 +02:00
Sara Arjona 655d0162ca Merge branch 'MDL-85937-main' of https://github.com/ferranrecio/moodle 2025-08-13 16:59:42 +02:00
ferran a3cb690d42 MDL-85937 course: log overview from APP 2025-08-13 16:31:04 +02:00
AMOS bot 75afedfa90 Automatically generated installer lang files 2025-08-13 00:08:12 +00:00
Paul Holden ba7f0b5e44 MDL-84794 reportbuilder: add entity theme data "do not force" options.
For both column & filter, as was done in acc654e8.
2025-08-12 22:56:21 +01:00
Paul Holden 132ac18880 MDL-86160 reportbuilder: consistently refer to aggregation types.
Use existing API rather than hardcoded/non-discoverable strings.
Improve test coverage of related functionality.
2025-08-12 22:55:29 +01:00
Sara Arjona 7f23f89fa4 Merge branch 'MDL-85652-main-behat-fix' of https://github.com/ferranrecio/moodle 2025-08-12 17:01:51 +02:00
ferran f34435105d MDL-85652 block_site_main_menu: fix behat 2025-08-12 16:27:58 +02:00
Mark Johnson ad277fbd8b MDL-85551 questions: Increase category name field size
This increases the maximum length of category names in line with the
increased activity names from MDL-83985, avoiding issues when generating
a default category.
2025-08-12 14:03:26 +01:00
Mark Johnson 6abed1ad66 MDL-85551 questions: Creating a default category with a questions mod
When a new module that publishes questions is created, it does not have
a default question category created until it is viewed. This means that
other parts of the system that want to use the bank while its empty
(such as bulk moving questions) cannot see it.

This adds a step to the common edit_module_post_actions() function so
that any module supporting the FEATURE_PUBLISHES_QUESTIONS feature will
have its default category created with the module instance.

This can be overridden by setting skipdefaultcategory to true
in the $moduleinfo argument to edit_post_module_actions().
2025-08-12 14:03:26 +01:00
Paul Holden 0a41dacbec MDL-86256 core: coding style cleanup for XML parsing classes. 2025-08-12 13:08:03 +01:00
Paul Holden 25bf66cf01 MDL-86256 core: deprecate xmlize() method in favour of new class.
Update all current uses of said method.
2025-08-12 13:08:03 +01:00
ferran 206b082dd8 Merge branch 'MDL-86133-main' of https://github.com/roland04/moodle 2025-08-12 13:23:12 +02:00
Paul Holden 83c3cd34ae MDL-86256 core: move XML parsing classes into autoload namespaces. 2025-08-12 12:16:53 +01:00
Ilya Tregubov e189c19e1a Merge branch 'MDL-86268' of https://github.com/paulholden/moodle 2025-08-12 11:24:20 +03:00
Mihail Geshoski 5ca9029ba8 Merge branch 'MDL-85652' of https://github.com/paulholden/moodle 2025-08-12 13:57:26 +08:00
Ilya Tregubov 3f91d3d718 Merge branch 'MDL-86269' of https://github.com/paulholden/moodle 2025-08-12 08:18:45 +03:00
guillaumebarat e28c9c12ae MDL-85335 cli: Allow uninstall of sub-plugin when parent missing 2025-08-12 15:06:23 +10:00
Adrian Greeve 165dc7c94b Merge branch 'MDL-86155-main' of https://github.com/andrewnicols/moodle 2025-08-12 10:02:55 +08:00
James C bc86139697 MDL-84975 course: Handle tags in section and activity move dialogues 2025-08-12 13:24:26 +12:00
Paul Holden 959e4512a0 Merge branch 'MDL-82996' of https://github.com/pedrojordao/moodle into main 2025-08-11 16:36:35 +01:00
Paul Holden bc041be6c5 MDL-86269 assignfeedback_editpdf: update TCPDF related test assertion. 2025-08-11 14:21:12 +01:00
Paul Holden ff37bbbc2a MDL-86269 libraries: upgrade to version 6.10.0 of TCPDF. 2025-08-11 12:04:07 +01:00
Laurent David 8fadb5ac3c MDL-83899 mod_scorm: Redirect index page to overview 2025-08-11 12:56:53 +02:00
Laurent David cf97babf9d MDL-83899 mod_scorm: Add course overview page 2025-08-11 12:56:53 +02:00
Paul Holden 209b261389 MDL-86268 libraries: upgrade to version 4.5.0 of ChartJS. 2025-08-11 11:40:58 +01:00
Mark Johnson 7b89752b49 MDL-85018 questionlib: Update broken question test
A multianswer question with a missing database record no longer throws
an exception, so doesn't work for the "broken question" test, so switch
to ddwtos.
2025-08-11 10:07:39 +01:00
Mark Johnson 6f2353206f MDL-85018 qtype_multianswer: Prevent errors on backup/restore
If a multianswer question has its question_multianswer record missing
for some reason, attempting to backup and restore a bank containing the
question will result a dml_missing_record exception.

The qtype_multianswer::get_question_options() method already copes with
the sequence from this record being empty, so we can just remove the
MUST_EXIST check and let it fall back to that.
2025-08-11 10:07:39 +01:00
Paul Holden 5937dd57e0 MDL-85541 gradereport_history: show user country value correctly. 2025-08-11 09:18:16 +01:00
Laurent David 242b782fcb MDL-83899 mod_scorm: Add manager class for course overview 2025-08-11 08:21:59 +02:00
Mikel Martín 5f34fbae13 MDL-86133 theme_boost: Improve course overview styles 2025-08-08 13:02:13 +02:00
Mikel Martín 64f3673ae8 MDL-86133 courseformat: Standarise activity overview alignments 2025-08-08 13:02:11 +02:00
Mikel Martín 715e0fd80d MDL-86133 courseformat: Update overview buttons style 2025-08-08 13:00:50 +02:00
ferran a9c09e2768 MDL-86146 core_courseformat: fix keys in overview table 2025-08-08 12:37:04 +02:00
Paul Holden d004beb5cd MDL-86196 forms: style choice dropdown/list element as form control.
We then get consistent borders, text, colour, etc as other elements
(and carrots).

Co-authored-by: Mikel Martín <mikel@moodle.com>
2025-08-08 08:58:19 +01:00
Stephan Robotta 246f847a2c MDL-83772 mod_data: Fixed autosave bug in text areas with same name 2025-08-08 09:16:53 +02:00
Sara Arjona 4885314a19 MDL-83887 blocks: Remove activity_modules block 2025-08-08 08:00:54 +02:00
Sara Arjona e624c30a98 MDL-80556 blocks: Remove section_links block 2025-08-08 07:57:39 +02:00
Andrew Nicols f3158b3fcf MDL-86231 behat: Coding style fixes 2025-08-08 08:44:48 +08:00
Andrew Nicols f50da71a49 MDL-86231 behat: Support array callable syntax in execute method 2025-08-08 08:44:47 +08:00
Sara Arjona 621c6e1048 weekly release 5.1dev 2025-08-07 16:44:49 +02:00
Sara Arjona 4d8691fa38 NOBUG: Add upgrade notes 2025-08-07 16:44:49 +02:00
Sara Arjona ca64b394ff Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-08-07 16:44:42 +02:00
Huong Nguyen 8f533abf4a Merge branch 'MDL-86004-main' of https://github.com/rajutm25/moodle 2025-08-07 14:08:39 +07:00
Ilya Tregubov f0e9eb7051 Merge branch 'MDL-85260' of https://github.com/tasiobg/moodle 2025-08-07 09:11:58 +03:00
rajutm25 5d1bf0de87 MDL-86004 core: Modify upgrade step for Microsoft endpoints
The upgrade step for Microsoft OAuth2 issuers has been modified
to address an oversight in MDL-84432. The upgrade now only updates
service base urls for multi-tenant issuers.
2025-08-07 11:26:01 +05:30
Huong Nguyen 4c29ab7729 Merge branch 'MDL-85718-main' of https://github.com/yusufwib01/moodle 2025-08-07 12:21:25 +07:00
Huong Nguyen 62d858daa6 Merge branch 'MDL-86205-main' of https://github.com/junpataleta/moodle 2025-08-07 12:14:43 +07:00
Huong Nguyen de0cd5523d Merge branch 'MDL-84792' of https://github.com/paulholden/moodle 2025-08-07 11:40:22 +07:00
Huong Nguyen b8f4b47f2f Merge branch 'MDL-85794-main' of https://github.com/junpataleta/moodle 2025-08-07 11:37:13 +07:00
Huong Nguyen 1eb5e2cd67 Merge branch 'MDL-85795-main-2' of https://github.com/junpataleta/moodle 2025-08-07 11:25:53 +07:00
Huong Nguyen 0fedf84db7 Merge branch 'MDL-84217-main' of https://github.com/stevandoMoodle/moodle 2025-08-07 10:56:15 +07:00
Ilya Tregubov 47c4e54e49 MDL-63395 user: Fix profile visibility check. 2025-08-07 10:35:12 +07:00
Jun Pataleta 875cc74289 MDL-86205 message: Close drawer when activating elements outside of it 2025-08-07 11:23:00 +08:00
Andrew Nicols 7f7117d63e MDL-86155 core: Stop accessing deprecated ->extra
This was deprecated in Moodle 2.0.

Because this is just a stdClass we have no way of warning that the value
is deprecated.
2025-08-07 10:44:38 +08:00
Jun Pataleta 5d130b7072 Merge branch 'MDL-85674-main' of https://github.com/lameze/moodle 2025-08-07 10:44:21 +08:00
Jun Pataleta d02f130b14 Merge branch 'MDL-85701-master' of https://github.com/NashTechOpenUniversity/moodle 2025-08-07 10:39:11 +08:00
Jun Pataleta 33ddc9450c Merge branch 'MDL-78233-main' of https://github.com/Tasiobg/moodle 2025-08-07 10:35:21 +08:00
Jun Pataleta 14b1a7b7e4 Merge branch 'MDL-85802-main' of https://github.com/mihailges/moodle 2025-08-07 10:33:49 +08:00
Jun Pataleta 0ad72e5646 Merge branch 'MDL-86151' of https://github.com/paulholden/moodle 2025-08-07 10:32:07 +08:00
Mihail Geshoski 180460d40e Merge branch 'MDL-79540_main' of https://github.com/marxjohnson/moodle 2025-08-07 10:20:03 +08:00
Huong Nguyen 3bd1862ab7 Merge branch 'MDL-84010-main' of https://github.com/sammarshallou/moodle 2025-08-07 09:17:30 +07:00
AMOS bot 203d6c602c Automatically generated installer lang files 2025-08-07 00:08:08 +00:00
Amaia Anabitarte 5c77482a92 Merge branch 'MDL-85840-main' of https://github.com/sarjona/moodle 2025-08-06 16:28:07 +02:00
ferran 2632df1194 Merge branch 'MDL-86176-main' of https://github.com/sarjona/moodle 2025-08-06 16:21:08 +02:00
Amaia Anabitarte e8ae9f1d83 Merge branch 'MDL-85841-main' of https://github.com/sarjona/moodle 2025-08-06 16:14:11 +02:00
Sara Arjona 04678891f2 MDL-85841 courseformat: Apply last changes for resources in overview
- Add 'Actions' column with a 'View' link to a filtered by each resource type.
2025-08-06 15:39:10 +02:00
Sara Arjona 7af3d2fd76 MDL-86176 badges: Adjust badges due to Canvas Credentials changes
This change addresses necessary adjustments to how OBV2.0 badges are
sent to backpacks, specifically to ensure compatibility and correct
functionality following recent updates to Canvas Credentials' conditions.

It ensures our badge integration continues to operate smoothly despite
these external changes.
2025-08-06 15:04:39 +02:00
Jun Pataleta a468a46328 MDL-85795 behat: Update button text used in search steps 2025-08-06 20:46:53 +08:00
Andrew Nicols 3b115c138c MDL-86155 course: Emit debugging for deprecated cm_info properties 2025-08-06 20:03:38 +08:00
Andrew Nicols e2fadb5379 MDL-86155 course: Remove fictitious __empty() magic method 2025-08-06 20:03:38 +08:00
Andrew Nicols 0fe51a4878 MDL-86155 course: Update coding style for updated classes 2025-08-06 20:03:38 +08:00
Andrew Nicols 811a2f9fff MDL-86155 core_course: Move constant to \core_course\modinfo 2025-08-06 20:03:37 +08:00
Andrew Nicols 70a4e2a3ba MDL-86155 course: Move course internals to autoloading
| Old class name    | New class name           |
| ---               | ---                      |
| `\cm_info`        | `\course\cm_info
| `\cached_cm_info` | `\course\cached_cm_info` |
| `\section_info`   | `\course\section_info`   |
| `\course_modinfo` | `\course\modinfo`        |
2025-08-06 20:03:37 +08:00
Sara Arjona ec7446b6a1 MDL-85840 glossary: Apply last changes in the overview page
- Add comments column for teacher and student.
- Entries and Total entries columns should be text only (remove the link).
- View when all entries are approved.
- Standardise alignment.
2025-08-06 13:20:20 +02:00
Simey Lameze 92e9ed1995 MDL-85674 behat: replace multiple steps by a single table step 2025-08-06 18:19:12 +08:00
Jun Pataleta 7a31c18809 Merge branch 'MDL-86095-main' of https://github.com/rjnl/moodle 2025-08-06 15:41:25 +08:00
yusufwib01 0163a248eb MDL-85718 tiny_link: Improve image link behavior in TinyMCE 2025-08-06 14:30:44 +07:00
Rajneel Totaram 99581b195d MDL-86095 mod_book: Let screenreader know print book opens in new window 2025-08-06 18:13:10 +12:00
Huong Nguyen 68a3783968 Merge branch 'MDL-85132_main' of https://github.com/vladaskidanovas/moodle 2025-08-06 10:54:00 +07:00
Huong Nguyen 41f15dda0b MDL-84464 report_log: Fix EOF 2025-08-06 10:37:01 +07:00
Laurent David 0afd6e07b4 MDL-84464 report_loglive: Hide report for teacher without groups 2025-08-06 10:14:49 +07:00
Laurent David f28d48e5a7 MDL-84464 report_log: Hide report for teachers without groups
* Teachers without groups in SEPARATEGROUP mode should not see the report log page nor access it
2025-08-06 10:14:49 +07:00
hieuvu bca0b3cca1 MDL-85701 mod_quiz: Move delete activities before questions.
Make sure the question is not used when activities has been deleted.
2025-08-06 10:11:24 +07:00
Laurent David bd092870db MDL-84463 mod_feedback: Fix typo in behat test description 2025-08-06 02:14:19 +00:00
Laurent David 64e3264e79 MDL-84463 mod_feedback: Fix users in no group and email
* Non editing teachers in no group should not receive feedback emails
from students in no group
2025-08-06 02:14:19 +00:00
Laurent David 84cd368afc MDL-84463 mod_feedback: Fix show entries and nonrespondents
* Non editing teachers not in a groups should not see entries
from other users
2025-08-06 02:14:19 +00:00
raortegar 2bf960df6e MDL-85704 mod_bigbluebuttonbn: Update sesskey handling for compatibility 2025-08-06 02:14:19 +00:00
Adrian Greeve c478e477fd Merge branch 'MDL-86168-main' of https://github.com/andrewnicols/moodle 2025-08-06 10:02:18 +08:00
Huong Nguyen 7ea2e0bfd0 Merge branch 'MDL-85510-master' of https://github.com/NashTechOpenUniversity/moodle 2025-08-06 08:29:46 +07:00
Paul Holden 91eba52481 MDL-86230 admin: fix site registration link to Moodle app.
Broken by 5d316201.
2025-08-06 00:34:17 +01:00
Paul Holden 5e6cc7604b MDL-86151 reportbuilder: column method to get effective return type. 2025-08-05 20:20:00 +01:00
Amaia Anabitarte d60bd85afa Merge branch 'MDL-85888-main' of https://github.com/ssj365/moodle 2025-08-05 17:04:20 +02:00
andelacruz 1b5ff5fb93 MDL-85674 mod_grade: Behat test for multiple questions manual grading 2025-08-05 17:39:23 +08:00
Khoa Nguyen Dang e3b4be30e7 MDL-85510 Questions: clearfix from MDL-84708 affects spacing
Co-authored-by: Mikel Martín Corrales <mikel@moodle.com>
2025-08-05 15:56:16 +07:00
sam marshall ee233a6ad7 MDL-84010 core_files: sync_external_file can cause infinite recursion 2025-08-05 07:46:49 +01:00
Andrew Nicols 39760aa9b0 MDL-86168 core: Migrate ajaxlib to namespace class methods 2025-08-05 14:29:16 +08:00
Stevani Andolo 066c3582aa MDL-84217 editor_tiny: Added 'img-fluid' class to dropped image files 2025-08-05 14:06:40 +08:00
Mihail Geshoski 80acd5f9eb Merge branch 'MDL-86001' of https://github.com/paulholden/moodle 2025-08-05 11:44:05 +08:00
Mihail Geshoski e8cbafdc51 Merge branch 'MDL-85565_main' of https://github.com/PhilippImhof/moodle 2025-08-05 11:37:06 +08:00
Mihail Geshoski f977ba6000 Merge branch 'MDL-85492' of https://github.com/krisbax/moodle 2025-08-05 11:22:19 +08:00
Huong Nguyen 8135066427 Merge branch 'MDL-85338' of https://github.com/paulholden/moodle 2025-08-05 09:10:48 +07:00
Huong Nguyen c54dc29a5a Merge branch 'MDL-85231-main' of https://github.com/junpataleta/moodle 2025-08-05 08:50:11 +07:00
Huong Nguyen c83d50662f Merge branch 'MDL-86080-main' of https://github.com/roland04/moodle 2025-08-05 08:40:13 +07:00
Huong Nguyen 22830fe432 Merge branch 'MDL-86125_remove-duplicate-components-json' of https://github.com/ziegenberg/moodle 2025-08-05 08:35:56 +07:00
Huong Nguyen c19eabae5e Merge branch 'MDL-86043-main' of https://github.com/tasiobg/moodle 2025-08-05 08:31:54 +07:00
Paul Holden efd28fe3e7 MDL-82464 badges: re-use native aggregation for the overview report.
As was previously accomplished in 78f56cff but had to be rolled back
during de4e2a54, due to lack of explicit callback support during
column 'count' aggregation.
2025-08-04 14:30:47 +01:00
Paul Holden 81834c5b55 MDL-82464 reportbuilder: use column callbacks in count aggregation.
This is a fairly niche requirements, but valid use cases do exist
for system reports using "count" aggregation on a column, that also
wish to format the resulting output.
2025-08-04 13:20:14 +01:00
Paul Holden 22b96fdf15 MDL-82464 reportbuilder: standardize aggregation implementation/tests.
For all current methods, establish consistency in their implementation
as well as ensuring, for those that execute column callbacks, they are
each tested consistently.
2025-08-04 13:20:12 +01:00
Mikel Martín a1c0d41982 MDL-85593 theme_boost: Move modshooser styles to a new file
Move all the modchooser related styles from core.scss to a new
modchooser.scss file.
2025-08-04 13:09:03 +02:00
Mikel Martín a7ceae66dc MDL-85593 theme_boost: Update modchooser styles
Update activity chooser UI:
- Update related templates
- Update related styles in core.scss
- Fix related JS modules affected by the changes
- Clean and improve existing styles
2025-08-04 13:08:57 +02:00
Jun Pataleta 7ac14abcdd MDL-85795 message: Enclose the search widget in a group 2025-08-04 18:33:53 +08:00
Jun Pataleta 62d77f53e5 MDL-85795 search: Enclose the search widget in a group 2025-08-04 18:33:52 +08:00
Nathan Nguyen f7339869ee MDL-85505 core: consider iframe as actual content 2025-08-04 11:40:32 +10:00
Shamim Rezaie fa290b1bb8 Merge branch 'MDL-85787-main-2' of https://github.com/junpataleta/moodle 2025-08-04 09:52:13 +10:00
Paul Holden 904a2b7d9d MDL-83462 mod_page: observe page description display in popup. 2025-08-01 17:03:00 +01:00
Pedro Jordao e8da3af3f4 MDL-82996 customfield_number: Show 'Display format' label as header
Display format now has its own section and we maintain the conditional
display of fields depending on the value selected in the Field type of
the Number field settings section.
2025-08-01 09:40:07 -03:00
Mihail Geshoski 603524af90 MDL-85802 mod_quiz: Fix double-escaping in notification content
Avoids double-escaping when filtering notification content. Adds
a unit test to validate the content filtering logic.
2025-08-01 18:31:31 +08:00
Jun Pataleta b7e9ae8f16 MDL-85794 message: Set notification preferences controls within a group 2025-08-01 16:51:32 +08:00
Iñigo Zendegi 0b94ee3e05 MDL-85802 mod_quiz: format course/quiz notification content. 2025-08-01 15:43:50 +08:00
Mikel Martín 3344a90aa2 MDL-86080 theme_boost: Fix YUI tables styles
MDL-85659 generated a regression on YUI tables that are displayed
without borders. This patch improves the fix including YUI tables
as an exception too.
2025-08-01 08:48:06 +02:00
Jun Pataleta cc27cd2eaf Merge branch 'MDL-85945-main-enfix' of https://github.com/mudrd8mz/moodle 2025-08-01 14:34:55 +08:00
Jun Pataleta 2bf9750b69 MDL-85231 message: Style the notification buttons consistently 2025-08-01 13:07:52 +08:00
Jun Pataleta 02c578f226 MDL-85231 message_popup: Add a close button on the notification popover
This follows the recommendation on the ARIA Authoring Practices Guide
(APG) for modal dialogues:
> It is strongly recommended that the tab sequence of all dialogs
> include a visible element with role button that closes the dialog,
such as a close icon or cancel button.

https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/
2025-08-01 13:07:52 +08:00
Laurent David 7faa1247e5 MDL-85231 message_popup: Add focustrap in message popup 2025-08-01 13:07:52 +08:00
Huong Nguyen f854a2bf64 Merge branch 'MDL-86137-main' of https://github.com/roland04/moodle 2025-08-01 09:14:55 +07:00
Huong Nguyen 3b92a395f3 Merge branch 'MDL-86135' of https://github.com/paulholden/moodle 2025-08-01 09:12:04 +07:00
Sara Arjona 20bb0b2429 weekly release 5.1dev 2025-07-31 16:07:17 +02:00
Sara Arjona c9e1d37e20 NOBUG: Add upgrade notes 2025-07-31 16:07:17 +02:00
Sara Arjona 34a4cd05e0 Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-07-31 16:07:10 +02:00
Michael Hawkins 64c8f0d205 Merge branch 'MDL-85362-main' of https://github.com/HuongNV13/moodle 2025-07-31 14:33:51 +08:00
Huong Nguyen 863ea6bf8a Merge branch 'MDL-85967-main' of https://github.com/davewoloszyn/moodle 2025-07-31 10:49:30 +07:00
Huong Nguyen 8faceef8d5 Merge branch 'MDL-84486-Add-sortby-while-getting-list-of-webservices' of https://github.com/farhan6318/moodle 2025-07-31 10:38:01 +07:00
Huong Nguyen 900621a9b2 Merge branch 'MDL-86062-main' of https://github.com/andrewnicols/moodle 2025-07-31 10:20:47 +07:00
Huong Nguyen eb21d69241 Merge branch 'MDL-84485-Select-webservice-in-wstoken-behat-breadcrumb-main' of https://github.com/farhan6318/moodle 2025-07-31 10:17:37 +07:00
David Woloszyn cf978b145d MDL-85967 aiprovider_openai: Modify action config on upgrade 2025-07-31 13:08:42 +10:00
David Woloszyn c4cafb7eb1 MDL-85967 aiprovider_openai: O1 model settings updated 2025-07-31 13:08:42 +10:00
David Woloszyn 56b146f379 MDL-85967 aiprovider_openai: Update param max_completion_tokens
AMOS BEGIN
  MOV [settings_max_tokens_help,aiprovider_openai],[settings_max_completion_tokens_help,aiprovider_openai]
AMOS END
2025-07-31 13:08:42 +10:00
David Woloszyn f1b9808c40 MDL-85967 aiprovider_openai: Cast types to stored model settings 2025-07-31 13:08:42 +10:00
Huong Nguyen 62af279430 Merge branch 'MDL-85897-main' of https://github.com/andrewnicols/moodle 2025-07-31 08:58:14 +07:00
AMOS bot 3e1142cac4 Automatically generated installer lang files 2025-07-31 00:08:15 +00:00
David Mudrák 70b5610364 MDL-85945 lang: Use fixed strings in the tests, too 2025-07-30 23:59:26 +02:00
Helen Foster 5beb3cf86c MDL-85945 lang: Import fixed English strings (en_fix) 2025-07-30 21:28:14 +02:00
Shamim Rezaie 36a65fb9e2 Merge branch 'MDL-85295-main' of https://github.com/rjnl/moodle 2025-07-31 02:43:00 +10:00
Shamim Rezaie fc4d1dc116 Merge branch 'MDL-72133-filter-deleted-logs' of https://github.com/bwalkerl/moodle 2025-07-31 02:25:49 +10:00
Mihail Geshoski 6c4bb2a324 Merge branch 'MDL-86113-main' of https://github.com/snake/moodle 2025-07-30 23:30:09 +08:00
Mihail Geshoski fa31be85cc Merge branch 'MDL-85470-main' of https://github.com/junpataleta/moodle 2025-07-30 23:12:18 +08:00
Paul Holden db7adceb4c MDL-86162 h5p: fix content type/library page table layout. 2025-07-30 15:35:06 +01:00
Tasio da92cfbeee MDL-86043 core: keep SQL consistent with other Moodle versions.
This change resolves issues with Oracle in Moodle 4.5. It has been ported to newer Moodle versions as it improves
the existing SQL and helps maintain consistency across different Moodle versions.
2025-07-30 16:34:58 +02:00
Paul Holden 187dffe21e MDL-86135 core: move security.txt back into public webroot.
Originally missed as part of f747c15c.
2025-07-30 14:45:13 +01:00
Tasio 8d0b7a8674 MDL-86043 core: test for the task sending new users an email 2025-07-30 15:19:14 +02:00
Paul Holden cccae0184c MDL-85338 message: make messaging drawer responsive to sticky footer.
Co-authored-by: David Woloszyn <david.woloszyn@moodle.com>
2025-07-30 13:58:35 +01:00
Paul Holden b16a328281 MDL-85766 block_glossary_random: reset keys of retrieved entries. 2025-07-30 13:05:00 +01:00
Jun Pataleta 42b7c91a47 Merge branch 'MDL-85995-main' of https://github.com/rjnl/moodle 2025-07-30 17:10:22 +08:00
Mikel Martín d9d739991a MDL-86137 core_role: Fix role tables styles 2025-07-30 10:42:07 +02:00
Farhan Karmali 6966108bdd MDL-84485 webservice: Select webservice in Behat test to avoid errors 2025-07-30 11:35:31 +05:30
Andrew Nicols 0aa88aaf1a MDL-86062 mod_choice: Coding style fixes 2025-07-30 13:58:40 +08:00
Andrew Nicols 47764f6d82 MDL-85897 core: Move all deprecations to emit_deprecation 2025-07-30 13:56:04 +08:00
Andrew Nicols 76e67451c3 MDL-85897 core: Add emit_deprecation() method
This changeset adds a new `\core\deprecation::emit_deprecation` method
with the same signature as the `emit_deprecation_if_found()` method.

It is intended to be used in places where something is guaranteed to
have been deprecated, and will throw appropriate debugging if the
deprecated attribute is not found.

The `emit_deprecation_if_found()` method should still be used where the
item being checked is not known to be deprecated or not, for example in
calling code.
2025-07-30 13:53:21 +08:00
Huong Nguyen 8317da2d6a Merge branch 'MDL-85777-main' of https://github.com/yusufwib01/moodle 2025-07-30 09:10:35 +07:00
Huong Nguyen 2a316b9a2c Merge branch 'MDL-85590_fix_modal_backdrop_attachment_point_main' of https://github.com/MariaMozgunova/moodle 2025-07-30 08:37:26 +07:00
Andrew Nicols 8cb71f5f52 MDL-86062 mod_choice: Remove unused globals 2025-07-29 20:38:55 +08:00
Andrew Nicols 2d0d18ed98 MDL-86062 mod_choice: Stop calling get_string from lib.php 2025-07-29 20:38:53 +08:00
Paul Holden e0660ac1d6 MDL-84792 course: category report entity filter for course count. 2025-07-29 12:58:12 +01:00
Farhan Karmali 75399dcd9c MDL-84486 webservice: Add sorting to services on token form 2025-07-29 15:47:24 +05:30
Huong Nguyen 7564f3d790 Merge branch 'MDL-85855' of https://github.com/paulholden/moodle 2025-07-29 16:49:36 +07:00
Huong Nguyen 87eaa5774b Merge branch 'MDL-31071_deprecate-file_encode_url-function' of https://github.com/ziegenberg/moodle 2025-07-29 15:49:44 +07:00
Jun Pataleta a7f809b545 MDL-85470 badges: Add a11y Behat test for the manage badges page 2025-07-29 15:15:51 +08:00
Jun Pataleta 24a9680bef MDL-85470 badges: Use badge:namewithimagelink column in badges table 2025-07-29 15:15:50 +08:00
Jun Pataleta 22595b1e58 MDL-85470 reportbuilder: New column containing badge image, name, link 2025-07-29 15:15:50 +08:00
Jun Pataleta 984175b3d8 MDL-85787 course: Limit course index drag and drop to certain pages only
Only allow the drag and drop functionality in the course index on pages
that provide alternatives to move course items such as the course
homepage and the course section view pages.

This is to meet the WCAG 2.2 Level AA Success Criterion 2.5.7 for
dragging movements.
See: https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements
2025-07-29 11:46:45 +08:00
Jun Pataleta 966203b7bf Merge branch 'MDL-85698-main' of https://github.com/Jayce0808/moodle 2025-07-29 11:09:36 +08:00
yusufwib01 bdd055b8ed MDL-85777 message: Disable message input when sending isn’t allowed 2025-07-29 10:51:15 +08:00
Jayce Birrell 1fdf65454d MDL-85698 core: combo box informs screen reader users 2025-07-29 11:25:22 +09:30
Sara Arjona acc4c90802 Merge branch 'MDL-85638-main' of https://github.com/sarjona/moodle 2025-07-28 16:22:54 +02:00
ferran 970f206939 Merge branch 'MDL-85651-main-v02' of https://github.com/ferranrecio/moodle 2025-07-28 16:18:33 +02:00
Sara Arjona eba9f38df8 Merge branch 'MDL-85842-main' of https://github.com/sarjona/moodle 2025-07-28 16:15:54 +02:00
Sara Arjona 715a822661 Merge branch 'MDL-86020-main' of https://github.com/sarjona/moodle 2025-07-28 16:10:20 +02:00
Sara Arjona d47eeff7d9 Merge branch 'MDL-85839-main' of https://github.com/sarjona/moodle 2025-07-28 16:08:55 +02:00
Sara Arjona 875b58ceec Merge branch 'MDL-86014-main' of https://github.com/sarjona/moodle 2025-07-28 16:05:44 +02:00
ferran 1f7a8ee03c Merge branch 'MDL-85597-main-v02' of https://github.com/ferranrecio/moodle 2025-07-28 15:43:34 +02:00
AMOS bot e5936977d2 Automatically generated installer lang files 2025-07-28 13:17:29 +00:00
Maria Mozgunova f9a6fe2361 MDL-85590 core: Fix modal backdrop attachment point for full screen 2025-07-28 10:21:49 +01:00
Sara Arjona 98555dba41 Merge branch 'MDL-85509-main-v03' of https://github.com/ferranrecio/moodle 2025-07-28 08:55:25 +02:00
Sara Arjona 145f74e21e MDL-86020 wiki: Display View button in the overview page 2025-07-28 08:52:23 +02:00
Benjamin Walker a3708fc974 MDL-72133 report_log: Add fallback context display 2025-07-28 09:06:35 +10:00
Benjamin Walker 72271bace2 MDL-72133 report_loglive: Display logs filtered by deleted course ids 2025-07-28 09:06:35 +10:00
Benjamin Walker 9cbfe3687a MDL-72133 report_log: Display logs filtered by deleted course ids 2025-07-28 09:06:35 +10:00
Daniel Ziegenberg f66c2c9b09 MDL-86125 core: Remove duplicated components.json
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-07-25 15:52:06 +02:00
Philipp Imhof 0e3ae707e0 MDL-85565 phpunit: check for <select> before <option>
Make sure that assert_select_options() will fail when the output does
not contain a <select> and therefore does not have the given options.
2025-07-25 13:12:40 +02:00
ferran 84b1beae12 MDL-85509 core: adding exporters to overview outputs 2025-07-25 13:04:27 +02:00
ferran 6a0134caef MDL-85509 core_courseformat: new overview information webservice 2025-07-25 12:52:39 +02:00
ferran c29f8bad13 MDL-85509 core_courseformat: add check method to overview factory 2025-07-25 12:52:39 +02:00
Amaia Anabitarte e2e946e1b9 MDL-85852 course: Get groups to filter by in overview 2025-07-25 12:52:39 +02:00
Daniel Ziegenberg dd75e69d49 MDL-31071 question: replace deprecated file_encode_url
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-07-25 12:03:46 +02:00
Daniel Ziegenberg 6e298809e3 MDL-31071 core: replace deprecated file_encode_url
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-07-25 12:03:43 +02:00
Daniel Ziegenberg 66fe5efdc3 MDL-31071 blocks: replace deprecated file_encode_url
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-07-25 12:03:38 +02:00
Daniel Ziegenberg e06ddff2cd MDL-31071 blog: replace deprecated file_encode_url
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-07-25 12:03:35 +02:00
Daniel Ziegenberg f9f94f64ad MDL-31071 core: initial deprecation of file_encode_url
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-07-25 12:03:32 +02:00
ferran d0f804d2a2 Merge branch 'MDL-85852-main' of https://github.com/aanabit/moodle 2025-07-25 11:21:00 +02:00
Jake Dallimore 8a30246613 MDL-86113 mod_lti: skip slow network calls during tests
This check exists to determine whether a given tool URL is a cartridge,
specifically when the URL does not end in .xml. It hits the URL to
determine this. In tests, we have many mock tool URLs, which won't
resolve, and running this code causes large hangs and random failures.
Any tests covering cartridge support still work fine, provided they
continue to use URLs ending in .xml; this change only skips the check
during tests for other non-xml URLs.
2025-07-25 16:55:27 +08:00
Sara Arjona 2ebd6e6e9a MDL-86014 h5pactivity: Apply last changes in the overview page
- Change 'View results' column name to 'View'.
- Display 0 dropdown in the 'Total attemps' column (instead of '-').
- Remove stringmanager.
- Move logic from get_extra_overview_items() to each particular method.
2025-07-25 10:41:03 +02:00
Sara Arjona ebc0ddece6 MDL-85839 feedback: Apply last changes in the feedback overview page
- Change 'Allow answers until' colum name to 'Due date'.
- Responses column should be text only (remove the link).
- Add a new Actions column with the 'View' option linking to the feedback responses page.
2025-07-25 10:31:13 +02:00
Sara Arjona ee1aa205dd MDL-85638 mod_choice: Apply last changes in the overview page
- Add the overview dialog.
2025-07-25 10:28:41 +02:00
Sara Arjona 937dd204d1 MDL-85842 workshop: Apply last changes in the overview page
- Change 'Deadline' column name to 'Phase deadline'.
- Submissions and Assessments columns should always be text only (remove the links).
- Add Actions column with a 'View' link to Workshop tab (current phase selected).
2025-07-25 10:04:36 +02:00
Michael Hawkins a1e5573ee8 weekly release 5.1dev 2025-07-25 12:13:42 +08:00
Michael Hawkins 2dfac3fc78 NOBUG: Add upgrade notes 2025-07-25 12:13:42 +08:00
Michael Hawkins da67f9ddad Merge branch 'MDL-83111-main' of https://github.com/sh-csg/moodle 2025-07-24 12:00:41 +08:00
Huong Nguyen 2e1ca0fdbd Merge branch 'MDL-86049-main' of https://github.com/andrewnicols/moodle 2025-07-24 09:47:37 +07:00
Huong Nguyen 9854e6b646 Merge branch 'MDL-85504-main' of https://github.com/junpataleta/moodle 2025-07-24 09:43:45 +07:00
Huong Nguyen 5f4317da06 Merge branch 'MDL-85759' of https://github.com/paulholden/moodle 2025-07-24 09:30:22 +07:00
Rajneel Totaram a1678f5679 MDL-85995 mod_book: Make previous/next buttons accessible 2025-07-24 10:06:19 +12:00
Amaia Anabitarte 2ae4ee1442 MDL-85852 course: Get groups to filter by in overview 2025-07-23 16:57:00 +02:00
Jun Pataleta 26c41abea9 MDL-85504 mod_feedback: Enhance the question edit form via JS
The drag handle and actions menu should not be within the accessible
labels of the question items. In order to enhance the question edit
form with these, they need to be rendered via JS outside of container
of the questions' accessible name.
2025-07-23 16:16:10 +08:00
Amaia Anabitarte 8f2292d410 Merge branch 'MDL-85989-main' of https://github.com/sarjona/moodle 2025-07-23 10:11:14 +02:00
Jun Pataleta 2b4057c403 MDL-85504 form: Legend's label template data should not be escaped
The label context data in the fieldset's legend tag should not be
escaped and allow raw HTML given that legend tags can contain
phrasing content and headings.

See developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/legend.
2025-07-23 15:02:25 +08:00
Sara Arjona 108be0d8b9 Merge branch 'MDL-84762-main' of https://github.com/roland04/moodle 2025-07-23 08:02:08 +02:00
Huong Nguyen 175c6df93d Merge branch 'MDL-60799' of https://github.com/jonof/moodle 2025-07-23 09:03:24 +07:00
Huong Nguyen 7b1ecf6b41 Merge branch 'MDL-83996-readonly-false-positive' of https://github.com/bwalkerl/moodle 2025-07-23 08:59:58 +07:00
Huong Nguyen 139f5197ee Merge branch 'MDL-84787' of https://github.com/paulholden/moodle 2025-07-23 08:51:22 +07:00
Huong Nguyen 701031c321 Merge branch 'MDL-85573-tool-brickfield-uninstall' of https://github.com/szymonk1101/moodle 2025-07-23 08:33:25 +07:00
Shamim Rezaie d3db464475 Merge branch 'MDL-85307-main' of https://github.com/Jayce0808/moodle 2025-07-23 09:22:29 +10:00
Shamiso Jaravaza f0242eea23 MDL-85888 mod_bigbluebuttonbn: Fix setting logic 2025-07-22 16:11:36 -06:00
Rohit Panchal 25d5a9cea2 MDL-83991 tag: Optimized tag sql query 2025-07-23 00:56:11 +05:30
Mihail Geshoski a071011489 Merge branch 'MDL-86073' of https://github.com/paulholden/moodle 2025-07-22 23:54:03 +08:00
Mihail Geshoski 1de15ab76f Merge branch 'MDL-85997' of https://github.com/paulholden/moodle 2025-07-22 23:40:07 +08:00
Mihail Geshoski 6b7224ffed Merge branch 'MDL-85038_dml_missing_record_exception-when-running-mod_assign-task-send_assignment_due_soon_notification_to_user' of https://github.com/ziegenberg/moodle 2025-07-22 23:30:27 +08:00
Mikel Martín 03b77e002f MDL-84762 courseformat: Improve overview page styles
- Add BODY_OUTLINE to button property enum
- Improve overviewdialog buttonclasses generation
- Replace button classes in activities overviews
- Add new courseoverview SCSS
2025-07-22 16:30:50 +02:00
Mihail Geshoski f7e6f3e9e8 Merge branch 'MDL-83558-main' of https://github.com/andrewgos/moodle 2025-07-22 13:56:00 +08:00
Huong Nguyen 519b3930cc MDL-85362 core: Bump versions in moodle_minimum_php_version_is_met() 2025-07-22 09:56:23 +07:00
Huong Nguyen 3da349676f MDL-85362 GHA: Bump versions to the required values
For 5.1:
 - Minimum PostgreSQL version is bumped to 15
2025-07-22 09:53:28 +07:00
Huong Nguyen 7be5d00b87 MDL-85362 core: Define environment requirements for Moodle 5.1 2025-07-22 09:51:43 +07:00
Rajneel Totaram 4ef2a316d7 MDL-85295 qtype_ordering: render feedback properly
'answertext' is already passed through format_text(), so no need to escape it in the template.
2025-07-22 11:34:35 +12:00
ferran 6225133aa4 MDL-85651 course: add activity details to modchooser 2025-07-21 17:14:33 +02:00
ferran 96c1f995ef MDL-85597 behat: adapt tests to new activity chooser 2025-07-21 16:59:12 +02:00
ferran f54d7eefcd MDL-85597 course: add selection to activity chooser 2025-07-21 16:58:43 +02:00
Sara Arjona 5ebeb0e516 MDL-85989 output: Fix choicelist when selected 0 is not first
Previously, when the selected value in a choicelist was 0 but not in
the first position, the behavior was incorrect.
This commit fixes that issue, ensuring the choicelist behaves as expected
regardless of the position of the 0 value.
2025-07-21 12:22:42 +02:00
Andrew Nicols a99dd29975 MDL-86049 core: Do not use the component cache before purge
When trying to resolve a corrupt cache where it is not possible to
complete the Moodle setup/bootstrap, it is necessary to ignore the
current cache to load the cache purging infrastructure.
2025-07-21 12:24:37 +08:00
Benjamin Walker 93adecb0b8 MDL-83996 sessions: Fix false positive read only sessions errors 2025-07-21 10:26:21 +10:00
Paul Holden 130f7c48c9 MDL-86073 reportbuilder: fix external assertions of button property.
The tests from c439e2d3 tried to assert they were empty, when in fact
they didn't exist at all. Caused PHPUnit warnings.
2025-07-18 18:49:16 +01:00
Daniel Ziegenberg 63b96e255b MDL-83003 core: Add error check for envoy proxy
Checking the redis server version is also simplified; once ought to be
enough :)

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-07-18 16:33:40 +02:00
Daniel Ziegenberg 6effa046aa MDL-85038 assignment: fix exception on sending assignment notification
When the assignment gets deleted between the creation of the ad-hoc task
mod_assign\task\send_assignment_due_soon_notification_to_user or
mod_assign\task\send_assignment_overdue_notification_to_user and its
execution, the ad-hoc task fails with a dml_missing_record_exception and
the task gets stuck.

In this case we do not want the task to fail and just return with an
appropriate mtrace.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-07-18 12:29:27 +02:00
Mihail Geshoski ef6df9e70e weekly release 5.1dev 2025-07-18 14:52:14 +08:00
Mihail Geshoski 29c899c86e NOBUG: Add upgrade notes 2025-07-18 14:52:13 +08:00
Mihail Geshoski cf49c69e9f Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-07-18 14:51:56 +08:00
Andrew Nicols 19094fcc7e MDL-83424 upgradenotes: Correct path to version file 2025-07-17 16:43:18 +07:00
Andrew Nicols ee3368dd88 MDL-83424 js: Add back accidentally removed line 2025-07-17 16:43:13 +07:00
Paul Holden e5fecffb94 MDL-85944 block_myoverview: fix previously badly nested SCSS. 2025-07-17 15:23:49 +07:00
Mihail Geshoski 968a185203 Merge branch 'MDL-85846-main' of https://github.com/HuongNV13/moodle 2025-07-17 12:22:32 +08:00
Mihail Geshoski 0842f9e53b Merge branch 'MDL-85055-main' of https://github.com/lameze/moodle 2025-07-17 12:16:01 +08:00
Huong Nguyen bdd15d43eb Merge branch 'MDL-85050-master' of https://github.com/NashTechOpenUniversity/moodle 2025-07-17 10:23:52 +07:00
Huong Nguyen 50666700c7 Merge branch 'MDL-65027-main' of https://github.com/meirzamoodle/moodle 2025-07-17 09:59:53 +07:00
Andrew Nicols c7ebc31fdd MDL-83424 tool_task: Correct path to CLI task runners 2025-07-17 09:36:58 +07:00
Huong Nguyen 252e971758 Merge branch 'MDL-85944' of https://github.com/paulholden/moodle 2025-07-17 08:52:45 +07:00
Huong Nguyen 6fbe81d61e Merge branch 'MDL-81384' of https://github.com/paulholden/moodle 2025-07-17 08:43:47 +07:00
Shamim Rezaie ac712db5d3 Merge branch 'MDL-73003-main' of https://github.com/Jayce0808/moodle 2025-07-17 07:30:16 +10:00
Paul Holden c196a03781 MDL-85055 task: correct use of DI provided frozen Clock API.
Fixes some of the usage introduced in tests as part of a35335a9.
2025-07-16 19:40:07 +01:00
Mihail Geshoski 5fd440c201 Merge branch 'MDL-77237-main' of https://github.com/meirzamoodle/moodle 2025-07-16 23:54:38 +08:00
Mihail Geshoski 7aaa7b6442 Merge branch 'MDL-85726-main' of https://github.com/HuongNV13/moodle 2025-07-16 23:38:48 +08:00
Mihail Geshoski e35b741681 Merge branch 'MDL-85996' of https://github.com/paulholden/moodle 2025-07-16 23:27:34 +08:00
Amaia Anabitarte 8f7d70622c Merge branch 'MDL-83893-main-int' of https://github.com/sarjona/moodle 2025-07-16 12:53:59 +02:00
Huong Nguyen cbc12c6ee3 MDL-85726 tiny_premium: Support on-premise via Service URL
Some Tiny Premium features require server-side components.
It was done by Tiny Cloud. Alternatively, if you are using
a Self-hosted solution, you can use the on-premise version

On-premise version can be installed and run on an in-house
server an computing infrastructure, including a private cloud
2025-07-16 13:46:23 +07:00
Sara Arjona a2a3c4df8d MDL-83893 mod_forum: Redirect index.php to course overview 2025-07-16 07:42:34 +02:00
Sara Arjona 9e92e17949 MDL-83893 mod_forum: Add course overview integration 2025-07-16 07:42:26 +02:00
Sara Arjona ee7dbad82f MDL-83893 mod_forum: Add WS calls to support toggle 2025-07-16 07:42:20 +02:00
Mihail Geshoski 3ec78bc079 Merge branch 'MDL-84466_main' of https://github.com/marxjohnson/moodle 2025-07-16 13:19:23 +08:00
Huong Nguyen f4b1cf272a Merge branch 'MDL-85825-main' of https://github.com/Jayce0808/moodle 2025-07-16 10:13:00 +07:00
Huong Nguyen a4cb3e35be Merge branch 'MDL-85609' of https://github.com/paulholden/moodle 2025-07-16 09:52:28 +07:00
Andrew Gosali 9f68226804 MDL-83558 mod_forum: fix incorrect message on edge case scenario
(when student tries to see all participants on a forum with visible groups mode)
2025-07-15 22:47:45 +07:00
Alexander Van der Bellen 3f45006d3a MDL-86023 core_task: Task failures always log a stack trace 2025-07-15 21:00:19 +08:00
Mark Johnson 939e57219c MDL-84466 question/qbank: Update pending transfer notification
This updates the logic and text of the notification that is shown while
the question transfer task is still pending, to include instances of the
new transfer_questions task. It also ensures the notification is shown
if a user tries to access the question editing screen from outside the
question bank.
2025-07-15 12:03:54 +01:00
Mark Johnson 804b2c1c3f MDL-84466 qbank: Transfer question files and tags in separate tasks
On a large site, the task to transfer question categories to the new
mod_qbanks contexts could take a very long time, as of any transferred
categories contain questions using files, each file has to be updated
individually.

This change splits up the transfer into 2 stages. The first stage
(transfer_question_categories) updates the context IDs on each question
category and moves them to their new top category, then spawns an
instance of transfer_questions for each category that was moved.
transfer_questions then handles moving the files and tags for questions
in a single category at a time. This allows the transfer process to be
parallelised by using multi cron or ad-hoc task runners, so should speed
things up on larger sites.
2025-07-15 12:03:54 +01:00
meirzamoodle 300d233199 MDL-77237 core: Suppress debugging during capabilities cleanup
To prevent the debugging messages from appearing during the upgrade,
I set a flag to hide them.

For the test file, I adjusted the parameters in
the unassign_capability() function, which seemed to be using
the parameter intended for assign_capability().
2025-07-15 14:32:35 +07:00
Paul Holden 6415776da9 MDL-85944 block_myoverview: specific styling for "My courses" page. 2025-07-15 08:02:11 +01:00
Huong Nguyen 085fb7c644 Merge branch 'MDL-84795' of https://github.com/paulholden/moodle 2025-07-15 10:42:05 +07:00
Mihail Geshoski 5e735ecaa5 Merge branch 'MDL-85257_main' of https://github.com/marxjohnson/moodle 2025-07-15 11:27:00 +08:00
Mihail Geshoski 6434163f54 Merge branch 'MDL-85246-main' of https://github.com/rjnl/moodle 2025-07-15 11:13:04 +08:00
Huong Nguyen 42715e0e82 Merge branch 'MDL-72582-main' of https://github.com/tsmilan/moodle 2025-07-15 10:07:34 +07:00
Huong Nguyen 457d7fc8f4 Merge branch 'MDL-86016-main' of https://github.com/andrewnicols/moodle 2025-07-15 09:55:55 +07:00
Huong Nguyen a0ab3e9e11 Merge branch 'MDL-85040-main-new' of https://github.com/meirzamoodle/moodle 2025-07-15 09:42:10 +07:00
Mihail Geshoski a954ad1d27 Merge branch 'MDL-85754_main' of https://github.com/marxjohnson/moodle 2025-07-15 10:32:16 +08:00
Mihail Geshoski 843cb55770 Merge branch 'MDL-84385-requireonce' of https://github.com/leonstr/moodle into main 2025-07-15 09:42:47 +08:00
Andrew Nicols 41ead749cf MDL-86016 core: Remove xmldb test in favour of unit test 2025-07-15 09:31:51 +08:00
Andrew Nicols 7a300a09f5 MDL-86016 tests: Make install.xml test less restrictive 2025-07-15 09:29:41 +08:00
Paul Holden 1814857c24 MDL-85922 completion: correct/re-use new activity icon style classes. 2025-07-15 01:24:29 +01:00
Paul Holden af4453aa04 MDL-81384 theme_boost: centre help icon margin/padding. 2025-07-14 21:32:21 +01:00
Sara Arjona bc14a8f722 Merge branch 'MDL-83900-main-patch' of https://github.com/laurentdavid/moodle 2025-07-14 16:26:36 +02:00
Sara Arjona f07fbacb4b Merge branch 'MDL-85837-main' of https://github.com/aanabit/moodle 2025-07-14 16:13:11 +02:00
Laurent David 8ace342b6d MDL-83900 core_course: Fix behat test using wiki overview 2025-07-14 16:05:49 +02:00
meirzamoodle e1060d230d MDL-65027 core_auth: Implement reCaptcha on forgot password page 2025-07-14 16:40:02 +07:00
Huong Nguyen 30bbbe7191 MDL-85846 media: Use jsrev as the cache key when getting languages 2025-07-14 15:41:25 +07:00
Amaia Anabitarte 337479bb28 MDL-85837 core_grades: New is_gradable() function in gradelib 2025-07-14 10:30:29 +02:00
Amaia Anabitarte 2f701db247 MDL-85837 mod_assign: Apply last UX changes in overview page 2025-07-14 10:30:29 +02:00
cescobedo 5b81731491 Merge branch 'MDL-83900-main' of https://github.com/laurentdavid/moodle 2025-07-14 10:19:24 +02:00
meirzamoodle e5aac04e24 MDL-85040 forms: Make required form icons decorative
The required icon in mforms is not necessary. The div containing it
already has a title attribute that enables mouse users to hover on the
icon and see its meaning.

Screen reader users will know whether a field is required or not via
the `aria-required` attribute.

Labelling the required icon via `aria-label` does not pass the
a11y audit.

Given these, it only makes sense to make the required icon decorative
for mforms.

Co-authored-by: Jun Pataleta <jun@moodle.com>
2025-07-14 14:23:31 +07:00
Huong Nguyen 5a25595b65 Merge branch 'MDL-85817-main' of https://github.com/davewoloszyn/moodle 2025-07-14 13:52:19 +07:00
Andrew Nicols f6ec6f9dc4 MDL-83424 core: Guess dataroot correctly 2025-07-14 11:05:00 +07:00
Andrew Nicols ba80ee68fb MDL-83424 core: Move admin/cli scripts to root directory
Note: Plugin-specific CLI directories cannot be moved.
2025-07-14 09:16:32 +07:00
Andrew Nicols 5eb64075f4 MDL-83424 core: Make \core\component more resilient outside of install 2025-07-14 09:16:26 +07:00
Huong Nguyen b1b5f26359 Merge branch 'MDL-83424-main' of https://github.com/andrewnicols/moodle 2025-07-14 07:43:52 +07:00
Andrew Nicols 9c8fddfd21 MDL-83424 core: Version bump to clear caches 2025-07-12 17:52:12 +08:00
Andrew Nicols ce67db2a1e MDL-83424 message: Add missing MOODLE_INTERNAL checks 2025-07-12 17:51:41 +08:00
Michael Aherne 546de30fde MDL-83424 install: Fix install scripts 2025-07-12 17:51:41 +08:00
Andrew Nicols 3133520615 MDL-83424 core: Update component/plugin resolution to include new paths 2025-07-12 17:51:40 +08:00
Andrew Nicols efe3582d4a MDL-83424 core: Fix failing unit test 2025-07-12 17:51:40 +08:00
Andrew Nicols 0e961688e7 MDL-83424 core: Fix things after restructure 2025-07-12 17:51:40 +08:00
Andrew Nicols f747c15cbf MDL-83424 core: Restructure Moodle codebase 2025-07-12 17:51:38 +08:00
AMOS bot aeb177ab7a Automatically generated installer lang files 2025-07-12 00:08:03 +00:00
Paul Holden a2c9217a0b MDL-85996 reportbuilder: default "Any value" category filter operator. 2025-07-11 17:09:56 +01:00
Paul Holden 4c023c2c3d MDL-86001 qbank_columnsortorder: populate preview data question text. 2025-07-11 15:23:17 +01:00
Paul Holden 36654fd2a7 MDL-85997 output: require CLI library from corresponding renderer. 2025-07-11 11:58:10 +01:00
Mark Johnson bea32ccfa0 MDL-79540 qbank_managecategories: Don't allow own child as parent
When we build the options for a question category selector, the
"nochildrenof" option isn't correctly compared to the category ID. This
means we can select a category's own children as its new parent.
2025-07-11 10:07:29 +01:00
Michael Hawkins 9addea9f0a weekly release 5.1dev 2025-07-11 12:48:28 +08:00
Michael Hawkins 627eb435bd NOBUG: Add upgrade notes 2025-07-11 12:48:27 +08:00
Leon Stringer a50ff0efbe MDL-84385 mod_assign: Remove unneeded require_once 2025-07-10 09:24:56 +01:00
Mark Johnson 6d31566a3e MDL-85257 mod_quiz: Dont show edit links when you dont have permission
The quiz editing page includes an edit link for each question, and a
badge for questions in a shared bank that links to that bank.

It is possible that the user viewing the quiz does not have access to
edit the question or view the question bank, which means these links are
broken.

This change only adds the links if the user has permission for the pages
they link to.
2025-07-10 09:15:54 +01:00
Laurent David c45ec3f2b2 MDL-83900 mod_wiki: Refactor the course index page 2025-07-10 09:00:24 +02:00
Laurent David 6a7963faad MDL-83900 mod_wiki: Add course overview page for wiki 2025-07-10 09:00:24 +02:00
Laurent David da2b765125 MDL-83900 mod_wiki: Implement a manager class
* Add a manager class and a set of methods that will be
used in the overview page.
* Add a wiki_mode that will store the wiki mode types
2025-07-10 09:00:24 +02:00
Huong Nguyen b9fcb36062 Merge branch 'MDL-85863-main' of https://github.com/yusufwib01/moodle 2025-07-10 10:46:33 +07:00
Huong Nguyen deb8cafb5f Merge branch 'MDL-84399-main' of https://github.com/dpfahl-ms/moodle 2025-07-10 10:41:55 +07:00
Mihail Geshoski bf2d06d7c8 Merge branch 'MDL-85689-main' of https://github.com/andelacruz/moodle into main 2025-07-10 11:39:24 +08:00
Mark Johnson 9289f1e178 MDL-85721 qtype_multianswer: Update find_duplicated_subquestions for Oracle compatibility 2025-07-10 10:28:37 +07:00
Mihail Geshoski 5494fd13c6 MDL-84695 mod_qbank: Fix illegal whitespace 2025-07-10 11:09:27 +08:00
Mark Johnson 6c7a99e059 MDL-84695 mod_qbank: Fix unit tests for MS SQL server 2025-07-10 10:31:36 +08:00
Huong Nguyen d07f9905e5 Merge branch 'MDL-85262' of https://github.com/paulholden/moodle 2025-07-10 08:33:24 +07:00
Huong Nguyen 07f8a52dfa Merge branch 'MDL-84901' of https://github.com/paulholden/moodle 2025-07-10 08:25:31 +07:00
Mihail Geshoski b8126a9ada Merge branch 'MDL-85939' of https://github.com/paulholden/moodle into main 2025-07-09 23:26:29 +08:00
Mihail Geshoski 4d02ab1f44 Merge branch 'MDL-84255-main' of https://github.com/lucaboesch/moodle into main 2025-07-09 23:18:45 +08:00
Mihail Geshoski 23741e86c2 Merge branch 'MDL-80327_remove-deprecated-class-callbacks-from-mod_quiz' of https://github.com/ziegenberg/moodle into main 2025-07-09 23:12:19 +08:00
Daniel Ziegenberg 11a4622bce MDL-80327 mod_quiz: Remove deprecated class callbacks from mod_quiz
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-07-09 13:26:39 +02:00
Rajneel Totaram f99677e996 MDL-85246 mod_quiz: Fix quiz grade feedback
Using $CFG->recovergradesdefault and/or $gradeitem->refresh_grades()
are problematic when viewing a quiz. When reenrolling a user with
previous attempts, a teacher can choose not to recover the user's grades,
even when recovergradesdefault=true. This must be respected when
the user views the quiz. For site with recovergradesdefault=false,
the users always see a grade of 0, which is wrong.

This change shows the correct grade score and feedback to users and
avoids unintentionally recovering the grades.
2025-07-09 20:30:48 +12:00
Amaia Anabitarte 8fa40d6e93 Merge branch 'MDL-83890-main' of https://github.com/laurentdavid/moodle 2025-07-09 10:09:33 +02:00
cescobedo c6072eb768 Merge branch 'MDL-85880' of https://github.com/paulholden/moodle 2025-07-09 09:43:36 +02:00
Huong Nguyen 96b6f265f2 Merge branch 'MDL-83147-main' of https://github.com/meirzamoodle/moodle 2025-07-09 13:18:05 +07:00
Mihail Geshoski 21d4052bb6 Merge branch 'MDL-85721_main' of https://github.com/marxjohnson/moodle into main 2025-07-09 10:21:01 +08:00
andelacruz e331393822 MDL-85689 mod_quiz: Behat for adding and deleting page from quiz 2025-07-09 10:15:13 +08:00
Huong Nguyen a3c71c9010 Merge branch 'MDL-85697-main' of https://github.com/andelacruz/moodle 2025-07-09 09:10:31 +07:00
Huong Nguyen 9197345024 Merge branch 'MDL-85779' of https://github.com/paulholden/moodle 2025-07-09 09:05:56 +07:00
Paul Holden e6c72183a6 MDL-85759 qbank_history: define core t/log fontawesome icon mapping.
Its lack of existence caused question action menu misalignment.
2025-07-08 18:05:39 +01:00
Paul Holden d09bdd609a MDL-85939 qbank_columnsortorder: improve preview page table alignment. 2025-07-08 17:58:28 +01:00
Kristiina.Bax ebfc7ac005 MDL-85492 report_questioninstances: sort qtypes in alphabetical order 2025-07-08 17:00:56 +01:00
Mihail Geshoski 24895dede8 Merge branch 'MDL-85196' of https://github.com/paulholden/moodle into main 2025-07-08 22:45:20 +08:00
Laurent David 65faec66e1 MDL-83890 mod_choice: Migrate index to course overview
* Index page for mod_choice should be consistent with
the overview page
2025-07-08 16:45:11 +02:00
Laurent David 00cfa586c5 MDL-83890 mod_choice: Migrate to course overview page
* Add overview page renderer
* Add phpunit and behat test for new classes
2025-07-08 16:45:11 +02:00
Laurent David b72a7aa577 MDL-83890 mod_choice: Add manager class
* Add manager class to the mod_choice to avoid using
queries in output classes
2025-07-08 16:45:11 +02:00
Mihail Geshoski 36c6b71a6b Merge branch 'MDL-85069_main' of https://github.com/marxjohnson/moodle into main 2025-07-08 22:39:50 +08:00
Mihail Geshoski 5485e508e9 Merge branch 'MDL-84695-main' of https://github.com/lucaboesch/moodle into main 2025-07-08 22:21:54 +08:00
Mihail Geshoski 3cb07cf853 Merge branch 'MDL-85881_main' of https://github.com/marxjohnson/moodle into main 2025-07-08 22:16:12 +08:00
Amaia Anabitarte 33c1c059af Merge branch 'MDL-85659-main' of https://github.com/roland04/moodle 2025-07-08 15:05:02 +02:00
Paul Holden 1501f6644b MDL-84901 auth: specific session start error language string. 2025-07-08 12:33:02 +01:00
Huong Nguyen e085781437 Merge branch 'MDL-84976-main' of https://github.com/rjnl/moodle 2025-07-08 18:13:31 +07:00
Huong Nguyen 3e16767a42 Merge branch 'MDL-85037' of https://github.com/paulholden/moodle 2025-07-08 18:08:33 +07:00
Mark Johnson 013a2b78ae MDL-85754 quiz: Test for permission checks in "Add from question bank" 2025-07-08 11:52:25 +01:00
Mark Johnson 55e184caf5 MDL-85754 question: Don't show banks where user has no permission
The Switch Banks UI was listing all question banks on the course where
the use had the managecategory permission, plus the other banks they had
used recently.

This conflicted with the check when it tried to load a selected bank,
which checked the useall/usemine permissions. This could lead to errors
if this permission had been removed.

This applies consistent checks to both lists with the useall/usermine
permissions instead.
2025-07-08 11:52:25 +01:00
Mark Johnson 45e3284a3d MDL-85754 question: Only use current context in question_edit_contexts
Due to the changes in question sharing, it no longer makes sense to look
at parent contexts when establishing permissions in the question bank.

Questions now belong to a single activity module, and we should be able
to inherit and override permisions at that level like we do with any
other.

In the longer term, we probably want to replace question_edit_contexts
with something simpler, but for the time being this should apply the
correct permission checks where it's used without requiring a big
refactor of existing code.
2025-07-08 11:52:24 +01:00
Huong Nguyen 9c329c88b6 Merge branch 'MDL-85947_bump-GHA-ubuntu-24-04' of https://github.com/ziegenberg/moodle 2025-07-08 17:35:01 +07:00
cescobedo 0a6c94e30d Merge branch 'MDL-85654-main' of https://github.com/ferranrecio/moodle 2025-07-08 11:19:54 +02:00
Mihail Geshoski 7ee4a727f1 Merge branch 'MDL-41924_main' of https://github.com/marxjohnson/moodle into main 2025-07-08 17:07:53 +08:00
Huong Nguyen 7563f5e4d2 Merge branch 'MDL-84779-main' of https://github.com/davewoloszyn/moodle 2025-07-08 15:19:12 +07:00
Luca Bösch 261623858a MDL-84255 quiz: Show quiz title in heading in accessrule_seb layout. 2025-07-08 07:52:24 +02:00
David Woloszyn 2ef05e1e60 MDL-84779 core_ai: Convert model settings on upgrade 2025-07-08 15:20:52 +10:00
andelacruz 3a5bc92abf MDL-85697 mod_lesson: Behat for lesson group and user overrides 2025-07-08 12:32:49 +08:00
andelacruz 9b0063aa79 MDL-85697 mod_assign: Behat for assignment group and user overrides 2025-07-08 12:32:24 +08:00
andelacruz 6532126e7e MDL-85697 mod_quiz: Behat for quiz group and user overrides 2025-07-08 12:28:17 +08:00
meirzamoodle c35da28325 MDL-83147 AI: Implement detailed AI error messaging logic 2025-07-08 09:24:44 +07:00
meirzamoodle 0c0e3b7774 MDL-83147 AI: Introduce error message handler 2025-07-08 09:24:06 +07:00
Paul Holden 0d086be0d0 MDL-85652 block_site_main_menu: correct page context retrieval.
Ensure we retrieve the context for the current page, rather than
the context in which the block was originally added (to account
for it being on site homepage, and being displayed throughout the
entire site).
2025-07-07 17:04:15 +01:00
Amaia Anabitarte 3471a29b17 Merge branch 'MDL-83896-main' of https://github.com/roland04/moodle 2025-07-07 16:31:05 +02:00
yusufwib01 a697891f28 MDL-85863 user: Defer new-password email until after transaction commit 2025-07-07 20:59:41 +07:00
Daniel Ziegenberg f262bd66e2 MDL-85947 ci: Bump GHA to Ubuntu 24.04
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-07-07 15:57:39 +02:00
Dennis Pfahl 22d7f46deb MDL-84399 repository_nextcloud: Add search support using WebDAV
Co-authored-by: Lucas Gehrlein <lgehrlein@ssystems.de>
2025-07-07 13:48:42 +02:00
Dennis Pfahl 5246702a11 MDL-84399 core: add WebDAV SEARCH support to webdavlib
Co-authored-by: Lucas Gehrlein <lgehrlein@ssystems.de>
2025-07-07 13:39:23 +02:00
ferran 582eefc2e5 MDL-85654 course: purpose categories in activity chooser 2025-07-07 11:54:48 +02:00
Mikel Martín cdd4fb844e MDL-85659 theme_boost: Fix editor generated tables styles 2025-07-07 10:51:55 +02:00
Trisha Milan 464212f111 MDL-72582 core_files: Add unit test for readfile_accel debugging output
Adds a unit test for the debugging message triggered when readfile_accel() detects
a non-empty output buffer. The readfile_accel() function directly manipulates the
output buffers, so calling it from within PHPUnit triggers an error like "Test code
or tested code closed output buffers other than its own".

As a workaround, the test runs a CLI script in a separate process, allowing buffer
behaviour to be isolated and debugging output to be captured for assertions.
2025-07-07 18:47:27 +10:00
Matt Rice 5f38019f3c MDL-72582 core_files: Update readfile_accel error handling
Correct the error handling in readfile_accel to properly log errors when
working on a stored_file, rather than hiding the true error behind the
incorrect "Object of class stored_file could not be converted to
string."

Co-authored-by: Simey Lameze <simey@moodle.com>
Co-authored-by: Trisha Milan <trishamilan@catalyst-au.net>
2025-07-07 18:40:15 +10:00
David Woloszyn 84e21fe3e9 MDL-84779 core_ai: Store individual model settings 2025-07-07 17:41:41 +10:00
David Woloszyn ae62aa12b1 MDL-84779 aiprovider_ollama: Configure individual model settings 2025-07-07 17:41:41 +10:00
David Woloszyn d317f02a53 MDL-84779 aiprovider_openai: Configure individual model settings 2025-07-07 17:41:41 +10:00
David Woloszyn fbb6eeac32 MDL-84779 core_ai: Add method for getting model settings keys 2025-07-07 17:41:41 +10:00
Laurent David 95611b65b5 MDL-81702 core_message: Add focustrap and backdrop
* Add focustrap and backdrop to message drawer.
2025-07-07 07:08:18 +02:00
Laurent David d97239d9f3 MDL-81702 theme_boost: Add focus lock to drawers
* Add focus lock to drawers for small screens
2025-07-07 07:08:18 +02:00
Laurent David f1f9ef42ee MDL-81702 theme_boost: Remove site home link from drawers
* The site-home-link was added to all menu drawers and should
only be added to the main menu drawer (mobile version)
2025-07-07 07:08:18 +02:00
David Woloszyn e3835cae26 MDL-85817 mod_assign: Update assignment SMS strings 2025-07-07 11:29:40 +10:00
Luca Bösch d4f89cd803 MDL-84695 mod_qbank: More precise get_qbank_ids_of_type_in_course query. 2025-07-06 12:14:39 +02:00
Mihail Geshoski a6b17d8f6b weekly release 5.1dev 2025-07-06 09:25:26 +08:00
Mihail Geshoski 00d81a965a NOBUG: Add upgrade notes 2025-07-06 09:25:25 +08:00
Mihail Geshoski a3e560bbae Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install into main 2025-07-06 09:25:02 +08:00
Mihail Geshoski 95b3ef6834 Merge branch 'MDL-85350_main' of https://github.com/PhilippImhof/moodle into main 2025-07-05 20:16:39 +08:00
Mihail Geshoski 189be2d9c6 Merge branch 'MDL-84487_main' of https://github.com/marxjohnson/moodle into main 2025-07-05 20:16:39 +08:00
Mihail Geshoski 05d2e80087 Merge branch 'MDL-85200_main' of https://github.com/marxjohnson/moodle into main 2025-07-05 20:16:38 +08:00
Mihail Geshoski 536c2f7d7c Merge branch 'MDL-85563' of https://github.com/NeillM/moodle into main 2025-07-05 20:16:38 +08:00
Mihail Geshoski 87d21579d0 Merge branch 'MDL-85210_main' of https://github.com/marxjohnson/moodle into main 2025-07-05 20:16:38 +08:00
Mihail Geshoski cc3ac973ce Merge branch 'MDL-85432-main' of https://github.com/sh-csg/moodle into main 2025-07-05 20:16:38 +08:00
Paul Holden 4c93f5b795 MDL-85037 block_html: correct access checks for plugin file serving. 2025-07-04 08:55:45 +08:00
Mark Johnson f98f1e977b MDL-41924 quiz: Annotate questions for backups
Find question bank entries for all questions referenced by a question
slot, and for all questions matching a question bank referenced used for
a random question, and record their IDs so they can be included in
backups.
2025-07-03 14:50:24 +01:00
Mark Johnson 9cd623b508 MDL-41924 backup: Reduce questions included in backups
Historically, backups of an activity using questions would include all
questions for the entire context, where any question had been used. This
could lead to very large backup files, and exacerbated problems with
question duplication.

This changes the process for annotating categories to include in the
backup to find specific categories, rather than whole contexts. It
includes 3 groups of categories:
1. Those that belong to the backed up activity's context.
2. Those that contain a question used directly in a question_reference
belonging to the activity.
3. Those that contain a question used via a question_set_reference
belonging to the activity.
It also adds in any parent categories that are not included by the
above, so we have a complete hierarchy.

For group 1, the backup will include all questions belonging to these
categories, as before. For groups 2 and 3, it will only include
questions for question bank entries that have been annotated by the
activity.
2025-07-03 14:50:24 +01:00
Mikel Martín ce3eb175af MDL-83896 mod_lesson: Add course overview integration
- Implement course overview integration
- Redirect index.php to course overview
2025-07-03 15:05:21 +02:00
Mikel Martín 15f8c92d9e MDL-83896 mod_lesson: Add new methods to lesson class
Add new methods to the lesson class that will be needed by
the overview page.
2025-07-03 15:05:21 +02:00
Huong Nguyen eec4fac190 Merge branch 'MDL-76342-main' of https://github.com/yusufwib01/moodle 2025-07-03 09:07:20 +07:00
Huong Nguyen 99deb9d0f6 Merge branch 'MDL-85769-main' of https://github.com/meirzamoodle/moodle 2025-07-03 09:05:06 +07:00
Mihail Geshoski e37956b5d1 Merge branch 'patch/MDL-85666-main' of https://github.com/skodak/moodle into main 2025-07-03 09:56:06 +08:00
Mihail Geshoski 22c43f5714 Merge branch 'MDL-85725' of https://github.com/paulholden/moodle into main 2025-07-03 09:42:53 +08:00
Mikel Martín d8dbfe4dfd MDL-83896 mod_lesson: Add generators for lesson submissions 2025-07-02 16:06:53 +02:00
Mikel Martín bb5f837416 MDL-83896 mod_lesson: Update strings to improve consistency
Update how the word ‘attempts’ is used to  make the terminology more consistent
within Lesson and better aligned with how ‘attempts’ is used in other activities.
2025-07-02 16:06:53 +02:00
Mark Johnson a02dd5741d MDL-85069 qbank_bulkmove: Load banks and categories dynamically
The bulk move question dialogue presents 2 autocomplete fields for
selection of the target bank and category to move questions to. This was
loading all banks and categories the user could access, and filtering
categories based on the selected bank.

On large sites, this was not usable as there were too many banks and
categories to load leading to timeouts.

This refactors the dialogue to load just the current bank and cagtegory
initially, then load other options on demand via AJAX.
2025-07-02 10:58:34 +01:00
Mark Johnson f4e8942755 MDL-85069 question: Services for question bank and category search
This updates the core_question_search_shared_banks external function
with additional parameters to make it applicable outside of the "Switch
bank" dialogue in the quiz, with the corresponding changes to the
question_banks_datasource Javascript module, and unit test coverage.

It also adds a new \core_question\output\question_category_selector
class for rendering a select list of question categories, migrating
the logic used in qbank_managecategories to a core namespace. There
is a fragment callback for rendering this via AJAX.
2025-07-02 10:58:33 +01:00
Amaia Anabitarte 4fb29528b8 Merge branch 'MDL-83891-main' of https://github.com/aanabit/moodle 2025-07-02 08:56:44 +02:00
AMOS bot cb932437e2 Automatically generated installer lang files 2025-07-02 00:10:02 +00:00
Mark Johnson d3e0a93d9a MDL-85721 qtype_numerical: Prevent duplication on restore
If question_numerical record for a question has been deleted, when its
options are loaded its answers will not have a tolerance property. This
can lead to duplication.

Also, older questions may not have a question_numerical_options record.

To avoid this, we use 0 as a default tolerance for all answers if there
is no matching record, and do the same when reading the question
structure from backups. We also generate default values for the rest of
the options.
2025-07-01 11:59:17 +01:00
Mark Johnson ca51acb3e5 MDL-85721 qtype: Cope with missing options records
If we restore a question (or any other) which has had its
qtype_xxx_options record deleted, we get a notification output when we
try to build the options.

This may be called from an AJAX request (such as when we duplicate a
quiz), and outputting the notification breaks the AJAX response.
Returning false also means we don't get the answers attached to the
questiondata options, so the structure doesn't match the restored data,
and we get duplication.

This emits the errors via debugging instead, which allows it to be
supressed or logged, and allows get_question_options() to continue
running.
2025-07-01 11:59:17 +01:00
Mark Johnson e8002198f3 MDL-85721 qtype_multianswer: Clean up duplicate subquestions
This adds an ad-hoc task to clean up duplicate subquestions created by
the bug.

When the upgrade is run, it will run a query to check if any
subquestions have been duplicated (if there are multiple questions with
the same parent, text and stamp), and queue the cleanup task if there
are.

For each stamp identified, the task will find instances of the question
that are not referred to in their parent's sequence field, confirm that
they have 0 usages, and delete them.
2025-07-01 11:59:16 +01:00
Mark Johnson 201f1ea665 MDL-85721 qtype_multichoice: Generate default options on restore
qtype_multichoice::get_question_options() will create a default options
object if no qtype_multichoice_options record exists. This means if we
restore a backup containing a multichoice question without any options
(see previous commit), it will always create a duplicate.

This change generates a default set of options for the backupdata if
none exists, so the identity hash will match if the same question exists
in the database without options, and we dont get duplicates.
2025-07-01 11:39:22 +01:00
Mark Johnson 36e141bd1f MDL-85721 qtype_multianswer: Don't delete qtype data for subquestions
Historically, multianswer would re-use question IDs from subquestions,
so it was necessary to delete qtype-specific data if the qtype changed.
Since versioning was introduced, editing creates new versions of the
qtype and subquestions. Deleting the data means the original versions of
the subquestions cannot function correctly, so we shouldn't do that
anymore.
2025-07-01 11:39:22 +01:00
Andrew Nicols 3a57c6f6cd Merge branch 'MDL-84531' of https://github.com/paulholden/moodle 2025-07-01 17:33:38 +08:00
Petr Skoda 52520cc993 MDL-85666 phpunit: add general plugin tests
This defines new group which can be used
to limit execution of these tests to one plugin only.

For example to execute all tests for Label module use:

phpunit --testsuite=mod_label_testsuite
phpunit --group=plugin_checks --filter=mod_label

or

phpunit --filter=mod_label
2025-07-01 09:56:59 +02:00
Paul Holden bcd4923ae0 MDL-84795 reportbuilder: consistent/performant loading of context data.
Ensure we select only context related fields as provided by the helper,
and avoid empty joins by loading instances with the helper-specified ID
field `{$tablealias}.ctxid`.
2025-07-01 12:24:34 +08:00
Mark Johnson 082a5f7a96 MDL-85069 question: Fix return URL parameters after moving questions
When calling the core_question_move_questions external function, the
returned $returnurl paramater kept the original `cat`, `category` and
`lastchanged` parameters.

If the question was moved to another question bank, this meant the user
would be redirected to that bank, but the URL would still refer to the
category in the original bank. Opening the bulk move dialogue again
would then show the original bank and category selected by default, not
the current one.

This change ensures the cat parameter is updated to match the new
category, unsets the `category` parameter as it is redundant. If a single
question is moved, "lastchanged" is updated to that question, otherwise
it is unset.
2025-06-30 15:11:08 +01:00
Mark Johnson 5224fa5c60 MDL-85069 qbank: Add tool_generator callback
This adds a callback for tool_generator and the required lang strings to
allow qbanks to be generated as part of test courses, by passing the
--additionalmodules=qbank argument to maketestcourse.php.
2025-06-30 15:11:07 +01:00
Neill Magill 05977c9f6a MDL-85563 phpunit: Clock API should always use Moodle system time
When using `clock::now()` the frozen cloxk and incrementing clock will now
always return a `DateTimeImmutable` that uses the configured Moodle system
time. In unit tests this will be Australia/Perth.

Before this change, it would sometimes be UCT.
2025-06-30 11:38:00 +01:00
Mark Johnson 585c8d6b48 MDL-85881 questions: Handle multi-byte names during migration
We were using strlen() instead of core_text::strlen() when checking the
length of a question bank name created during the migration. This meant
that multibyte strings were counted as being too long, even though they
were within the character limit.
2025-06-30 11:08:54 +01:00
Paul Holden b69228a258 MDL-85880 reportbuilder: replace jQuery usage for parsing Javascript. 2025-06-30 17:26:26 +08:00
cescobedo c85a9f27e8 Merge branch 'MDL-85533-main-v03' of https://github.com/ferranrecio/moodle 2025-06-30 09:12:54 +02:00
ferran a8d43ea067 MDL-85533 course: activity chooser full refactor 2025-06-30 09:10:28 +02:00
ferran 1eb4671f1a MDL-85533 course: remove activitychoosertabmode setting 2025-06-30 09:10:26 +02:00
cescobedo 76b36b11ee Merge branch 'MDL-79319-main' of https://github.com/laurentdavid/moodle 2025-06-30 08:24:55 +02:00
Paul Holden 2424374a81 MDL-85779 block_timeline: fix/restore sort toggle dropdown behaviour.
Changes during Bootstrap upgrade, in conjunction with both 8a8c8ab2 and
0c586b41, caused the layout to deviate from that expected elsewhere for
managing of Bootstrap dropdown elements. Thus the dynamically chosen
item was no longer being shown as selected. Fix that here.
2025-06-29 23:12:47 +08:00
Huong Nguyen aa4a364d1d weekly release 5.1dev 2025-06-29 16:18:19 +07:00
Huong Nguyen 0e709fe184 NOBUG: Add upgrade notes 2025-06-29 16:18:19 +07:00
meirzamoodle 6225c8ca45 MDL-85769 AI: Trap focus within AI drawer on smaller screens
Co-authored-by: Laurent David <laurent.david@moodle.com>
2025-06-28 10:51:12 +07:00
Paul Holden 06157ee54b MDL-85855 calendar: format course shortname attribute correctly. 2025-06-26 21:45:34 +08:00
Mark Johnson e99d22692f MDL-84487 mod_quiz: Use modal form for editing random questions
Creating and editing random questions were using 2 different forms - one
dynamic form in a modal, and the other a regular form on a standalone
page. The "Switch bank" UI only works in a modal, so while it was
displayed on the edit page, it didn't function.

This combines the editing functionality with the existing modal form, so
the same UI can be used for both operations, and the "Switch bank"
functionality works.
2025-06-26 14:27:09 +01:00
Amaia Anabitarte 5d44690c27 MDL-83891 mod_data: Redirect index.php to activities overview page 2025-06-26 14:10:56 +02:00
Amaia Anabitarte 9d0c655576 MDL-83891 mod_data: Add overview page 2025-06-26 14:10:56 +02:00
Jayce Birrell 889a9b6af0 MDL-85825 behat: Exclude fieldsets
Fieldsets were getting incorrectly picked up from the 'form_row' selector
which was causing the i_expand_the_autocomplete() function to target the wrong element
2025-06-26 15:26:30 +09:30
Mihail Geshoski f4fefe6fc2 Merge branch 'MDL-85665-main' of https://github.com/andelacruz/moodle into main 2025-06-26 10:46:54 +08:00
Huong Nguyen 437069bab9 Merge branch 'MDL-83752' of https://github.com/ziegenberg/moodle 2025-06-26 09:19:27 +07:00
Huong Nguyen 4f86bf6e6d Merge branch 'MDL-83365-main' of https://github.com/andrewnicols/moodle 2025-06-26 09:06:28 +07:00
Andrew Nicols 08f4369245 MDL-83365 upgradenotes: Add release notes link generator 2025-06-26 09:54:23 +08:00
Huong Nguyen 0b873802e8 Merge branch 'MDL-76414-main' of https://github.com/yusufwib01/moodle 2025-06-26 08:29:32 +07:00
Huong Nguyen 80d25ccfcd Merge branch 'MDL-85734-main' of https://github.com/lucaboesch/moodle 2025-06-26 08:25:41 +07:00
Huong Nguyen f66dad28a8 Merge branch 'MDL-85466-main' of https://github.com/lucaboesch/moodle 2025-06-26 08:22:13 +07:00
Huong Nguyen 5e178fa428 Merge branch 'MDL-82109' of https://github.com/paulholden/moodle 2025-06-26 08:19:38 +07:00
Amaia Anabitarte a3c08430df MDL-83895 mod_h5pactivity: Fix Overview column name 2025-06-25 06:29:02 +02:00
Jonathon Fowler d955962786 MDL-60799 enrol: update_instance() needs separate objects passed
Passing the same object means enrol_cohort does not recognise a change
in role when an edit or batch course upload operation is done.

 * enrol/editinstance.php was modifying $instance before passing it to
   enrol_plugin::update_instance() so the latter never sees a difference
   versus $data. This is redundant since update_instance() is doing the
   same thing a second time.
 * admin/tool/uploadcourse/classes/course.php is passing the same object
   as both arguments to enrol_plugin::update_instance().

There is an expectation that update_enrol_plugin_data() is to mutate its
$instance argument and then return it based on how derived classes in
enrol_guest and enrol_self behave, so cloning $instance within
update_enrol_plugin_data() before mutating it isn't an option.
2025-06-25 09:42:57 +10:00
andelacruz 145922822e MDL-85665 mod_quiz: Behat to build quiz in single activity format course 2025-06-24 18:43:59 +08:00
Daniel Ziegenberg 815c051cd0 MDL-83752 workshop: Handle empty feedbackreviewer
Causes PHP warnings when null on PHP 8.1.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-06-24 12:40:53 +02:00
Huong Nguyen 69e1928a67 Merge branch 'MDL-85683' of https://github.com/paulholden/moodle 2025-06-24 09:21:06 +07:00
Huong Nguyen 89a38ddb80 Merge branch 'MDL-85644' of https://github.com/paulholden/moodle 2025-06-24 09:18:59 +07:00
Huong Nguyen 33cfd9f5cf Merge branch 'MDL-85407' of https://github.com/durenadev/moodle 2025-06-24 09:16:42 +07:00
cescobedo 0da299f874 Merge branch 'MDL-83895-main' of https://github.com/aanabit/moodle 2025-06-23 15:14:31 +02:00
cescobedo 1f17857520 Merge branch 'MDL-85436-main' of https://github.com/sarjona/moodle 2025-06-23 10:20:31 +02:00
Amaia Anabitarte 82a1547ccd MDL-83891 mod_data: Add approved option to entries generator 2025-06-20 17:01:48 +02:00
Luca Bösch 169a356ecf MDL-85734 calendar: support multilang group names. 2025-06-20 16:47:38 +02:00
Luca Bösch d44aebdba9 MDL-85466 course: space between number and course icon. 2025-06-20 16:47:11 +02:00
Sara Arjona edb9a0540a MDL-85436 lib: Deprecate unused icons 2025-06-20 15:33:16 +02:00
Andrew Gosali 80d68d4e4e MDL-85825 core_form: enable hideIf() on header element 2025-06-20 16:14:28 +07:00
Huong Nguyen 7d9030acd6 weekly release 5.1dev 2025-06-20 15:14:03 +07:00
Huong Nguyen af3b69b560 NOBUG: Add upgrade notes 2025-06-20 15:14:03 +07:00
Huong Nguyen 39a85af4e6 Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-06-20 15:13:45 +07:00
Sara Arjona 52b0b77eef Merge branch 'MDL-75947-integration-main-fix' of https://github.com/mihailges/moodle 2025-06-19 17:21:57 +02:00
Mark Johnson 31a524feb4 MDL-85210 mod_qbank: Update question set references during upgrade
When moving question categories during the migration to mod_qbank, set
references using questions in those categories were not updated with the
new context.

Furthermore, since top categories from system, category and course
contexts are deleted and not moved, and set references that filtered
based on a top category were left pointing to a non-existant category.

This change updates set references using the top category to point to
the new top category where its subcategories are moved, and updates set
references for all subcategories to set the new context.
2025-06-19 12:43:11 +01:00
Mark Johnson 78a1454b95 MDL-85210 question: Update move_question_set_references
move_question_set_references expected the set reference to use the old
filter format.

This change converts the filter to the new format if required, before
updating the category and context ids.
2025-06-19 12:43:10 +01:00
Mihail Geshoski c073e77cd4 MDL-75947 ltiservice_gradebookservices: Fix unit test
Fixes the test_sequential_score_posts() unit test in lineitem_test
by removing dynamic class property assignments, which were triggering
deprecation notices.
2025-06-19 16:26:19 +08:00
yusufwib01 2ae5a92733 MDL-76414 navigation: Show 'Calendar' link in primary nav to guests 2025-06-19 13:12:47 +07:00
Jayce Birrell e41d3c635c MDL-85307 filter_glossary: Do not filter concept
Filtering the concept here causes a recursive loop, disabling it here will prevent this.
2025-06-19 14:08:21 +09:30
Huong Nguyen 262ab112dd Merge branch 'MDL-85399' of https://github.com/paulholden/moodle 2025-06-19 11:33:31 +07:00
Huong Nguyen bf41e2b2f6 Merge branch 'MDL-85120' of https://github.com/paulholden/moodle 2025-06-19 11:29:35 +07:00
Huong Nguyen a8956f6dd5 Merge branch 'MDL-85223' of https://github.com/paulholden/moodle 2025-06-19 11:25:58 +07:00
Mihail Geshoski 17f340a968 Merge branch 'MDL-75947-main' of https://github.com/Jayce0808/moodle into main 2025-06-19 12:19:50 +08:00
Huong Nguyen 51774b2176 Merge branch 'MDL-79052_final-deprecation-of-removing-the-legacy-theme-settings' of https://github.com/ziegenberg/moodle 2025-06-19 11:15:45 +07:00
Huong Nguyen daf0a938e1 Merge branch 'MDL-78375_final-deprecation-of-device-related-theme-functions' of https://github.com/ziegenberg/moodle 2025-06-19 11:13:19 +07:00
Huong Nguyen b397dac469 Merge branch 'MDL-85678-main' of https://github.com/junpataleta/moodle 2025-06-19 11:07:23 +07:00
Mihail Geshoski c5b35b3bf4 Merge branch 'MDL-83487-main' of https://github.com/muhammadarnaldo/moodle into main 2025-06-19 11:33:17 +08:00
Huong Nguyen e0a1f66824 Merge branch 'MDL-85159-main' of https://github.com/stevandoMoodle/moodle 2025-06-19 10:03:25 +07:00
Mihail Geshoski aa659485d4 Merge branch 'MDL-85514-main' of https://github.com/snake/moodle into main 2025-06-19 11:01:07 +08:00
yusufwib01 16bed704d8 MDL-76342 core_output: Wrap buttons below heading on small screens 2025-06-19 10:00:40 +07:00
Jake Dallimore 14c75ddcc1 MDL-85514 core_form: support 'in' rule for multiselects via subset of
The 'in' rule currently behaves the same way that 'eq' does when used
with multi-selects, which is not correct. It should be modelled by
checking whether the selected values are a subset of the rule values
(i.e. selected values are 'in' the rule values). This patch implements
that for core form rules as well as for the admin settings show/hide.
Several behat features are updated as well, because these were verifying
the incorrect behaviour for multi-select in rules.
2025-06-19 09:51:11 +08:00
Sara Arjona 235940e424 Merge branch 'MDL-83904-master' of https://github.com/ngtrdai/moodle 2025-06-18 17:19:05 +02:00
Sara Arjona e2a5a88931 Merge branch 'MDL-85463-main' of https://github.com/sarjona/moodle 2025-06-18 13:18:07 +02:00
Daniel Ziegenberg a462df7eb7 MDL-79052 core: Final deprecation of removing the legacy theme settings 2025-06-18 12:23:06 +02:00
Daniel Ziegenberg 678c949d3f MDL-78375 core: Final deprecation of device related theme functions
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-06-18 12:16:56 +02:00
Paul Holden c77a2e49ae Merge branch 'MDL-85158' of https://github.com/pedrojordao/moodle into main 2025-06-18 10:01:45 +01:00
Mihail Geshoski 430a2488fc Merge branch 'MDL-42263-main' of https://github.com/Jayce0808/moodle into main 2025-06-18 16:19:24 +08:00
Jayce Birrell b5405a03ac MDL-73003 core_grades: Don't use 'scale' to determine grading method.
When a forum activity used a rubrics with a scale for grading, it was not treated as an advanced grading method, causing
the code to mishandle the grading object and not return any grades.
2025-06-18 16:47:04 +09:30
Dai Nguyen Trong 2a077d88b9 MDL-83904 badges: Add namespace to badges/classes/observer.php 2025-06-18 13:04:29 +07:00
Huong Nguyen ee98b24da2 Merge branch 'MDL-85742-main' of https://github.com/lucaboesch/moodle 2025-06-18 10:10:39 +07:00
Huong Nguyen ee060688fd Merge branch 'MDL-84832-main' of https://github.com/junpataleta/moodle 2025-06-18 09:50:11 +07:00
Amaia Anabitarte 0d1e36015c MDL-83895 mod_h5pactivity: Redirect index.php to overview page 2025-06-17 18:09:07 +02:00
Amaia Anabitarte 673a247b0d MDL-83895 mod_h5pactivity: New overview page 2025-06-17 18:09:07 +02:00
Mikel Martín 7920905430 MDL-83895 courseformat: Add new overviewdialog for overview page
Added new core_courseformat\output\local\overview\overviewdialog class to display
dialog elemetns in the course overview table. It will show a combination of
title, description and a list of items (label: value).
2025-06-17 18:09:07 +02:00
Amaia Anabitarte fff4fc9fd8 Merge branch 'MDL-85433-main' of https://github.com/sarjona/moodle 2025-06-17 16:05:30 +02:00
Paul Holden 1487084675 Merge branch 'MDL-85773-main' of https://github.com/sebastsg/moodle into main 2025-06-17 11:08:45 +01:00
Sebastian Gundersen cae63df759 MDL-85773 forms: Read-only selects must have static labels
This is to prevent labels with an invalid for attribute, referencing non-existing elements.
2025-06-17 11:25:22 +02:00
Mihail Geshoski 636bd2bed4 Merge branch 'MDL-84978-main' of https://github.com/olivabigyo/moodle into main 2025-06-17 15:17:10 +08:00
Mihail Geshoski 707ac6fb37 Merge branch 'MDL-82797_main' of https://github.com/cwarwicker/moodle into main 2025-06-17 15:02:41 +08:00
Luca Bösch 8cdf82687f MDL-85742 block_timeline: Fix active item indicator spacing 2025-06-17 07:05:07 +02:00
Marina Glancy 7e8210d8fd MDL-80611 general: do not translate url in help links 2025-06-16 18:08:04 +01:00
Paul Holden 471ab3215a MDL-85609 tool_mfa: fix user counting for factors in use table. 2025-06-16 13:03:31 +01:00
Sara Arjona be6c48511f Merge branch 'MDL-85553-main' of https://github.com/aanabit/moodle 2025-06-16 13:12:32 +02:00
Amaia Anabitarte 31ad09f72f MDL-85553 course: Change Status column name in Overview 2025-06-16 10:51:22 +02:00
Jun Pataleta 6d45a96984 MDL-85678 mod_feedback: a11y Behat coverage for Manage templates page 2025-06-16 13:56:49 +08:00
Jun Pataleta f26e66c002 MDL-85678 mod_feedback: Fix a11y issues in the Manage templates page
- Fix the heading hierarchy.
- Add a visually-hidden column header for the actions column.
2025-06-16 13:56:48 +08:00
Jake Dallimore 91f84ba4f1 MDL-75947 ltiservice_gradebookservices: score->timestamp as dategraded
If this is not passed in to grade_update(), then it's not passed on to
update_raw_grade(), resulting in time() being used instead, which isn't
correct. The grade timemodified value should be set to the timestamp
provided by the tool in the score post JSON, not the time of the score
post itself.

Co-authored-by: Jayce Birrell <jayce.birrell@moodle.com>
2025-06-16 14:38:46 +09:30
Jake Dallimore 3ecf81fcf4 MDL-75947 ltiservice_gradebookservices: test sequential score posting
This tests highlights a problem with the score handling logic and
will currently fail. On score post, the current time is used for
grade->timemodified instead of the score->timestamp provided by the
tool in the POST JSON.
2025-06-16 14:38:24 +09:30
aya-saad1 e46f1bd74e MDL-42263 assign: Force language of email sent to graders
Co-authored-by: Jayce Birrell <jayce.birrell@moodle.com>
2025-06-16 09:42:49 +09:30
AMOS bot bd6526b80d Automatically generated installer lang files 2025-06-15 00:09:57 +00:00
Sara Arjona 457b438bb4 MDL-85463 pix: Replace custom icons
When working on MDL-85084, it was decided to replace as many custom
icons as possible with their FontAwesome equivalents.
2025-06-13 16:06:02 +02:00
Sara Arjona c5d66da007 MDL-85433 singleactivity: Support multiple activities 2025-06-13 15:26:08 +02:00
Sara Arjona 6939cebb29 MDL-85433 site_main_menu: Add support to subsections
Co-authored-by: Ferran Recio <ferran@moodle.com>
2025-06-13 15:26:08 +02:00
Sara Arjona 2513bca047 MDL-85433 navigation: Generalise secondary navigation for single format
Introduce flexibility by allowing course formats to define custom logic
for retrieving activity modules.
2025-06-13 15:26:08 +02:00
Sara Arjona badade3137 MDL-85433 block: Update behaviour for default course blocks
To improve block handling in courses without a view page, subcontext
visibility is now enabled when a block needs to be added by default.
2025-06-13 15:26:08 +02:00
Sara Arjona 047bc9ec26 MDL-85433 course: Remove restriction to display course description
The "Show description" checkbox now appears even in course formats
without a dedicated view page, as this information can now be
displayed via the Additional activities block (formerly the Main
menu block), if added to the course.
2025-06-13 15:26:08 +02:00
Tasio 8ab7c798c8 MDL-78233 accesslib: remove unreliable test
Co-authored-by: Marina Glancy <marina.glancy@gmail.com>
2025-06-13 10:26:25 +02:00
Mihail Geshoski c42efe971f weekly release 5.1dev 2025-06-13 14:43:12 +08:00
Mihail Geshoski 3b6c42fd8d NOBUG: Add upgrade notes 2025-06-13 14:43:12 +08:00
Paul Holden 1a3888135f MDL-84531 core: default deprecated attribute $replacement to null. 2025-06-12 14:39:51 +01:00
Charles Fulton e8e365db74 MDL-85772 forum: added maxbytes default for announcement forums 2025-06-12 07:31:04 -04:00
Jun Pataleta 46208a0a25 Merge branch 'MDL-84752' of https://github.com/paulholden/moodle 2025-06-12 17:15:37 +08:00
Paul Holden fe7ec33f04 MDL-84752 qtype_essay: create accessible min/max words form elements.
Because of historical requirements involving fieldsets in question
type forms (see 958e7671), we should use ARIA label attribute on
grouped elements rather than normal labels in order to make them
accessible.

Co-authored-by: Jun Pataleta <jun@moodle.com>
2025-06-12 10:11:35 +01:00
Jun Pataleta 66aa45131a Merge branch 'MDL-85700-main' of https://github.com/roland04/moodle 2025-06-12 17:04:08 +08:00
Jun Pataleta d96ae2306d Merge branch 'MDL-85462' of https://github.com/paulholden/moodle 2025-06-12 17:04:08 +08:00
Jun Pataleta cb8e6d38bb Merge branch 'MDL-85344' of https://github.com/paulholden/moodle 2025-06-12 17:04:08 +08:00
Huong Nguyen 4d176ece30 MDL-72123 message: Add upgrade note 2025-06-12 17:04:08 +08:00
Huong Nguyen cc9b3ca238 Merge branch 'MDL-72123-main' of https://github.com/yusufwib01/moodle 2025-06-12 17:04:06 +08:00
Huong Nguyen 669bddbf52 Merge branch 'MDL-84611-main' of https://github.com/sh-csg/moodle 2025-06-12 08:37:11 +07:00
Paul Holden 9893ed9024 MDL-85725 qtype_ddimageortext: deprecate unused dropzone string. 2025-06-11 21:25:57 +01:00
Laurent David 27060eaac5 MDL-79319 core: Layout can inherit parent themes
* Layout should will be inherited from parent themes in the order
of precedence
2025-06-11 16:51:44 +02:00
Justin Hunt 38c9cb8bea MDL-82797 question engine: gift import fix 2025-06-11 12:04:12 +01:00
Stefan Hanauska 7ba49cbc0a MDL-84611 blocks: Respect instance_allow_multiple() 2025-06-11 11:17:43 +02:00
Stefan Hanauska dcdca4f88c MDL-84611 block_html: Change tests to respect capabilities 2025-06-11 11:13:12 +02:00
Huong Nguyen f7ca154b62 Merge branch 'MDL-77964' of https://github.com/paulholden/moodle 2025-06-11 14:08:30 +07:00
Huong Nguyen 53117827a7 Merge branch 'MDL-85316-main-mysql-version' of https://github.com/meirzamoodle/moodle 2025-06-11 13:33:28 +07:00
Huong Nguyen 0d5e0b2b28 Merge branch 'MDL-85274-main' of https://github.com/davewoloszyn/moodle 2025-06-11 13:29:47 +07:00
David Woloszyn 5f7525677e MDL-85274 calendar: Duration limits added to forms 2025-06-11 14:29:01 +10:00
meirzamoodle 04e848da25 MDL-85316 admin: Add environment check for AWS Aurora database 2025-06-11 10:41:43 +07:00
sam marshall 5bbf568c2f MDL-85679 mod_assign: Use core DI clock to make testing easier 2025-06-09 11:58:34 +01:00
Philipp Imhof 8520187d0e MDL-85350 questions: skip restore test for certain 3rd party plugins
The test_restore_course_with_same_stamp_questions() test assumes
that all question types using answers will also use the table
"question_answers" to store said answers. However, some 3rd party
qtypes might use custom tables and for those, the test would fail.
2025-06-06 15:57:19 +02:00
Mikel Martín cdd6da1efd MDL-85700 theme_boost: Fix group selector spacing
- Fix single_select template adding gap between elements.
- Improve groupselector definitions.
- Clean groupselector unneeded styles.
2025-06-06 10:19:47 +02:00
Rajneel Totaram 12948c8bac MDL-84976 tool_policy: noclean param was not set 2025-06-06 15:16:30 +12:00
yusufwib01 7adadac155 MDL-72123 message: Hide add to contacts button if user not allowed 2025-06-06 08:28:09 +07:00
Paul Holden 1b714008ab MDL-85683 enrol: use formatted course name for notification context. 2025-06-06 00:19:44 +01:00
Sara Arjona 9223e346c3 weekly release 5.1dev 2025-06-05 16:43:21 +02:00
Sara Arjona 645942388a NOBUG: Add upgrade notes 2025-06-05 16:43:21 +02:00
Sumaiya Javed 0ca08ce158 MDL-85344 reportbuilder: Add filter component plugin.
Co-authored-by: Paul Holden <paulh@moodle.com>
2025-06-05 15:08:52 +01:00
Niels Gandraß aaa24fc1a3 MDL-84491 core_session: Fix redis connection in CLI / scheduled task 2025-06-05 10:25:48 +02:00
Michael Hawkins 819a423093 MDL-83762 core_files: Bind resolve IPs and ports to cURL calls 2025-06-05 12:09:16 +07:00
Michael Hawkins 1a3ea766f4 Merge branch 'MDL-85571-main' of https://github.com/HuongNV13/moodle 2025-06-05 12:32:59 +08:00
Mihail Geshoski c6c3fc02c2 Merge branch 'MDL-85645-main' of https://github.com/lameze/moodle into main 2025-06-05 12:31:10 +08:00
Mihail Geshoski 84e2cf49f4 Merge branch 'MDL-85556_main' of https://github.com/marxjohnson/moodle into main 2025-06-05 12:25:11 +08:00
Vincent Schneider d6f3034716 MDL-84518 course: improved course visibility state handling 2025-06-05 11:21:50 +07:00
Michael Hawkins 349b7216b0 Merge branch 'MDL-80380-main' of https://github.com/HuongNV13/moodle 2025-06-05 12:19:05 +08:00
Jun Pataleta a7160a61bb Merge branch 'MDL-85450-main' of https://github.com/rjnl/moodle 2025-06-05 12:15:45 +08:00
Huong Nguyen 9647c3fd1b MDL-80380 core_auth: Add upgrade note 2025-06-05 11:10:30 +07:00
Huong Nguyen 41e516eac1 MDL-80380 admin: Support Microsoft XOAUTH2 for outgoing email 2025-06-05 11:10:29 +07:00
Mihail Geshoski 4cd77ec90a Merge branch 'MDL-69765-main' of https://github.com/lucaboesch/moodle into main 2025-06-05 12:10:24 +08:00
Jun Pataleta f068c3cf8d Merge branch 'MDL-84941' of https://github.com/paulholden/moodle 2025-06-05 12:08:36 +08:00
Mihail Geshoski 0565438932 Merge branch 'MDL-85072-main' of https://github.com/olivabigyo/moodle into main 2025-06-05 10:59:14 +07:00
Mihail Geshoski 2f2ce1f4c4 Merge branch 'MDL-83654-main-5' of https://github.com/junpataleta/moodle into main 2025-06-05 10:59:14 +07:00
Mihail Geshoski 8ec70a7a14 Merge branch 'MDL-85369_main' of https://github.com/agaranin/moodle into main 2025-06-05 10:59:14 +07:00
Martin Gauk 84338a4746 MDL-85488 mathjax: refactor loader to enhance configuration and loading 2025-06-05 10:59:14 +07:00
Mark Johnson 15e58709c8 MDL-85323 core: Don't cache the login page 2025-06-05 10:58:49 +07:00
meirzamoodle cf9f6b8e80 MDL-85375 libraries: Upgrade to version 5.22.9 of ADOdb 2025-06-05 01:34:17 +00:00
Vincent Schneider 8169e32764 MDL-84706 bigbluebuttonbn: improved authorization and mitigate CSRF risks 2025-06-05 01:34:17 +00:00
Huong Nguyen 2a97fdf215 MDL-79993 course: Fix PHPUnit failure 2025-06-05 01:34:17 +00:00
raortegar 4f0fb5f020 MDL-79993 course: Improve user access to recent courses service 2025-06-05 01:34:17 +00:00
Vincent Schneider 4efea4e7b4 MDL-84497 badges: fix missing action sesskey checks. 2025-06-05 01:34:17 +00:00
Jun Pataleta 78e82ea057 MDL-85239 mod_quiz: Use visually-hidden instead of deprecated sr-only 2025-06-05 09:25:34 +08:00
Jun Pataleta 3af1656932 Merge branch 'MDL-85239-master' of https://github.com/NashTechOpenUniversity/moodle 2025-06-05 09:22:47 +08:00
Jun Pataleta 5bf2a80de9 Merge branch 'MDL-84804' of https://github.com/paulholden/moodle 2025-06-05 08:12:37 +08:00
Sara Arjona b5f5bb30d0 Merge branch 'MDL-82069-main' of https://github.com/aanabit/moodle 2025-06-04 15:36:55 +02:00
Paul Holden 3fa4c62ae8 MDL-84804 output: amend page title when navigating dynamic tabs.
Prepend the current tab name to the page title, to ensure we can
easily identify the current page/tab and that it is both unique
and accessible.
2025-06-04 14:06:21 +01:00
Paul Holden 21074e3e6e MDL-84804 javascript: new module for manipulating the page title. 2025-06-04 14:06:20 +01:00
cescobedo 182691034c Merge branch 'MDL-85273' of https://github.com/paulholden/moodle 2025-06-04 12:58:53 +02:00
Jun Pataleta 8e09133213 Merge branch 'MDL-85041-main' of https://github.com/junpataleta/moodle 2025-06-04 17:48:16 +08:00
andelacruz 52edf23532 MDL-85645 mod_quiz: Behat to display questionbank name of quiz question. 2025-06-04 17:38:54 +08:00
Mihail Geshoski c770e91774 MDL-85619 mod_assign: Preserve default modal behaviour on save
Removes the preventDefault() call that previously prevented the
save/cancel modal from automatically closing when the 'Save' action
is applied for a specific bulk action on the assignment submissions
page.
2025-06-04 17:18:51 +08:00
Jun Pataleta 67aedf2505 MDL-85041 core: Make methods calling announceChanges async as well 2025-06-04 16:17:44 +08:00
Huong Nguyen f681462458 MDL-85571 mod_assign: Improve PHPUnit tests 2025-06-04 12:49:54 +07:00
raortegar 742dc355e6 MDL-85571 mod_assign: Add visibility check to due digest notification 2025-06-04 12:49:20 +07:00
Jun Pataleta 8a429d703d Merge branch 'MDL-85507-main-enfix' of https://github.com/mudrd8mz/moodle 2025-06-04 11:57:13 +08:00
Huong Nguyen da8c48ded1 Merge branch 'MDL-84732-main' of https://github.com/sammarshallou/moodle 2025-06-04 10:53:09 +07:00
Mihail Geshoski 84be6bdc08 Merge branch 'MDL-84432-main' of https://github.com/HuongNV13/moodle into main 2025-06-04 10:42:11 +08:00
Huong Nguyen 61d944be9d MDL-84432 core: Use discovery endpoint for Microsoft OAuth2 service
- Instead of creating the endpoints manually, use the OpenId
configuration endpoint to auto-configure endpoints
- Updates user field mappings so they map the new OpenId userinfo fields
2025-06-04 08:34:12 +07:00
Mark Johnson 47c54d06a6 MDL-85200 mod_quiz: Improve efficience of populate_question_sources
This uses the contexts from the categories of questions in the quiz to
narrow down the list of course modules we are querying to just those we
will need.
2025-06-03 16:34:12 +01:00
Mark Johnson 20d694efa5 MDL-85200 mod_quiz: Expand behat test to cover shared bank display
This extends the existing behat test for adding a question from a shared
bank to confirm that the source bank is displayed with the question on
the Questions page.

The bank name is already passed through format_string() before being
passed to the template, so additional encoding by the template is not
necessary, hence the template has been changed to use triple braces.
2025-06-03 16:32:49 +01:00
Sara Arjona 8a0fa3848e Merge branch 'MDL-84291-main-v03' of https://github.com/ferranrecio/moodle 2025-06-03 17:12:24 +02:00
Amaia Anabitarte 84f98d6a30 Merge branch 'MDL-85471-main' of https://github.com/junpataleta/moodle 2025-06-03 16:18:27 +02:00
cescobedo 960c90c151 Merge branch 'MDL-85398' of https://github.com/paulholden/moodle 2025-06-03 15:50:57 +02:00
cescobedo 96f171d9e6 Merge branch 'MDL-85216' of https://github.com/paulholden/moodle 2025-06-03 14:24:35 +02:00
Amaia Anabitarte 9a3c1fdf73 Merge branch 'MDL-85327' of https://github.com/paulholden/moodle 2025-06-03 13:37:02 +02:00
Amaia Anabitarte 0df97fb7ca Merge branch 'MDL-85250-main' of https://github.com/laurentdavid/moodle 2025-06-03 13:32:47 +02:00
Amaia Anabitarte 97cc40a544 Merge branch 'MDL-85281-main' of https://github.com/roland04/moodle 2025-06-03 13:29:12 +02:00
cescobedo a617addb84 Merge branch 'MDL-85326' of https://github.com/paulholden/moodle 2025-06-03 13:09:35 +02:00
ferran c960a9c5b8 MDL-84291 format_weeks: max initial sections setting 2025-06-03 12:58:52 +02:00
ferran b3cb1eb18a MDL-84291 format_topics: create courses with default number of sections 2025-06-03 12:58:52 +02:00
ferran 56b0e93d7c MDL-84291 course: deprecate maxsections setting 2025-06-03 12:58:51 +02:00
ferran 3bc7ca5513 MDL-84291 course: remove max section behat tests 2025-06-03 12:58:51 +02:00
ferran 4d9e0aa137 MDL-84291 course: remove max sections UI elements 2025-06-03 12:58:51 +02:00
Jun Pataleta 193eec2a1f Merge branch 'MDL-85467-main' of https://github.com/yusufwib01/moodle 2025-06-03 17:28:33 +08:00
Paul Holden 83e6469fbb MDL-85326 theme_boost: hide footer popover icon on small screens.
Fixes regression from add6f71d which forced `.btn-icon` display.

Co-authored-by: Mikel Martín <mikel@moodle.com>
2025-06-03 09:16:45 +01:00
Mikel Martín 7338d18084 MDL-83894 mod_glossary: Fix overview behat scenario 2025-06-03 08:29:25 +02:00
Paul Holden cdc4acb43a MDL-85644 course: bottom margin for course category listing actions. 2025-06-02 23:02:19 +01:00
Rajneel Totaram dcaa3f831c MDL-85450 block_calendar_upcoming: Fix heading level 2025-06-03 09:37:07 +12:00
cescobedo 3fba46abf9 Merge branch 'MDL-85632-main' of https://github.com/sarjona/moodle 2025-06-02 16:56:23 +02:00
Mark Johnson fa4223fa95 MDL-85556 backup: Only update question refs in restored course
The previous query updated all question references matching the original
question bank entry, regardless of whether they were part of the restore
or not. When we are dealing with duplicated questions, this means we
could accidentally change question references in the backed-up course as
well as the restored one.

This change filters the references to ensure they exist in a context
within the restored course, before updating them.
2025-06-02 15:54:10 +01:00
Mark Johnson 4d4ff4c28b MDL-85556 questions: Fix repeated_restore unit test
This unit test is meant to test restoring duplicated questions that
exist in a shared question bank. However, due to improvements in the
restore process from the introduction of mod_qbank, having the questions
in a bank that is not in the restored course means the questions don't
get restored at all, and we can't test that the process is working.

This changes the test to use a bank in the target course instead.
2025-06-02 15:04:38 +01:00
Amaia Anabitarte c85ac61b4b Merge branch 'MDL-85412-main' of https://github.com/aanabit/moodle 2025-06-02 13:23:26 +02:00
yusufwib01 922dfc3877 MDL-85467 core: Replace orphaned label with span for accessibility
This commit replaces orphaned labels with spans for improved
accessibility. It also updates the XPATH partial named selector
for select_menu fields to target span elements.
2025-06-02 13:42:31 +07:00
hieuvu 3a72810347 MDL-85239 mod_quiz: Add caption for Attempt tables. 2025-06-02 13:37:46 +07:00
meirzamoodle ba8cf5af44 MDL-85041 core: Improve autocomplete/tag a11y for assistive tech
- Updated autocomplete behavior to announce dynamic changes
via ARIA live regions
- Fixed focus management for keyboard and screen reader navigation
- Added proper role/aria tags for interactive tag components
2025-06-02 10:24:13 +07:00
Luca Bösch 4d06e2ae43 MDL-69765 qtype_essay: Create temporary draft file area only one time. 2025-05-31 12:56:14 +02:00
Jun Pataleta 9dec1f2e64 MDL-83654 qtype_match: Code style improvements for the renderer 2025-05-31 09:23:42 +08:00
Jun Pataleta 30a5e0a6dd MDL-83654 qtype_match: Only add the question text to the first field
In order to avoid repetition of the question text as the user navigates
to each answer field in a matching question (e.g. by tabbing).
2025-05-31 09:16:18 +08:00
Jun Pataleta bf9b8ebe0b MDL-83654 qtype_match: Add presentation role to table-related elements
The question and answer are displayed on a layout table and
does not really help with accessibility. We need to set a
presentation role for the table-related elements.
2025-05-31 09:07:02 +08:00
Jun Pataleta 36fad7be28 MDL-83654 qtype_match: Provide better information to answer fields
* In order to provide better context for screen reader users about the
answer fields in matching questions, the question text and the
corresponding item to be matched are included to the answer fields via
the aria-describedby attribute.
2025-05-31 09:07:01 +08:00
Amaia Anabitarte ac30877546 MDL-85412 course: adding and removing elements feedback message 2025-05-30 16:40:15 +02:00
Sara Arjona 4f73d6f57e MDL-85632 block_site_main_menu: Fix behat warning during init 2025-05-30 16:17:43 +02:00
ferran 18c6b9c0da MDL-84291 course: remove max section limits on user actions 2025-05-30 16:10:50 +02:00
ferran 0fba2d9b9f Merge branch 'MDL-83894-main' of https://github.com/roland04/moodle 2025-05-30 13:19:07 +02:00
Sara Arjona bbe9f1df33 Merge branch 'MDL-85315-main' of https://github.com/lucaboesch/moodle 2025-05-30 12:33:01 +02:00
Luca Bösch 797c1cd875 MDL-85315 themes: align modal closing button. 2025-05-30 11:38:57 +02:00
vlad.kidanov 2352c5a84b MDL-85132 mod_glossary: Add missing end div for entrybox element. 2025-05-30 10:28:40 +01:00
Jun Pataleta c31dae4eef MDL-84832 tiny_media: Announce when alt text maxlength is reached
Co-authored-by: Meirza <meirza.arson@moodle.com>
2025-05-30 17:08:54 +08:00
Michael Hawkins c39b737063 weekly release 5.1dev 2025-05-30 16:28:21 +08:00
Michael Hawkins 09a5c114b7 NOBUG: Add upgrade notes 2025-05-30 16:28:20 +08:00
Michael Hawkins 336cf9f6ed Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-05-30 16:27:54 +08:00
Katalin Lukacs Toth d2b0e2256f MDL-85072 qtype_ordering: Fix XML export
Option fields should not be left empty.
2025-05-30 07:37:24 +02:00
Artem Garanin 18f7b44510 MDL-85369 question: fix tag collection ID in legacy‑filter upgrade.
Use the actual tag collection for the 'question' tag area instead of
the default collection.
2025-05-29 14:11:14 -04:00
Mikel Martín 68b5f7b24a MDL-83894 mod_glossary: Add course overview integration
- Implement course overview integration
- Redirect index.php to course overview
2025-05-29 16:59:23 +02:00
Paul Holden 5577808482 MDL-85223 reportbuilder: initialize user entity filters just once. 2025-05-29 15:31:57 +01:00
Paul Holden f2078ed166 MDL-85399 reportbuilder: allow for hourly report scheduling. 2025-05-29 15:29:07 +01:00
Paul Holden bc7eee42ed MDL-85120 reportbuilder: allow selection of time in date range filter. 2025-05-29 15:27:55 +01:00
Paul Holden 6a26479909 MDL-85462 reportbuilder: improve user entity last access reporting.
Include filter/condition for "never accessed".
2025-05-29 15:26:25 +01:00
Paul Holden d34d630ef6 MDL-77964 availability: avoid JS console errors when closing modal. 2025-05-29 10:15:20 +01:00
Michael Hawkins a5c3e7c723 Merge branch 'MDL-84824-main' of https://github.com/stevandoMoodle/moodle 2025-05-29 12:21:26 +08:00
Michael Hawkins 4de0189cae Merge branch 'MDL-83448-main' of https://github.com/stevandoMoodle/moodle 2025-05-29 12:18:17 +08:00
Michael Hawkins 287ce62559 Merge branch 'MDL-84996' of https://github.com/paulholden/moodle 2025-05-29 12:09:26 +08:00
Michael Hawkins ed8b18e336 Merge branch 'MDL-85513' of https://github.com/paulholden/moodle 2025-05-29 12:03:47 +08:00
Michael Hawkins f99f32b3e9 Merge branch 'MDL-85552-main' of https://github.com/yusufwib01/moodle 2025-05-29 11:59:20 +08:00
Stevani Andolo f2f32c6964 MDL-84824 core_message: Fixed popup accessibility issue 2025-05-29 11:54:01 +08:00
Michael Hawkins d780c6bb58 Merge branch 'MDL-85437-main' of https://github.com/meirzamoodle/moodle 2025-05-29 11:50:40 +08:00
Huong Nguyen d9f5676426 Merge branch 'MDL-83044' of https://github.com/catalyst/moodle 2025-05-29 10:26:49 +07:00
Huong Nguyen 0e4617bbe5 Merge branch 'MDL-84548-main' of https://github.com/lucaboesch/moodle 2025-05-29 10:00:07 +07:00
Huong Nguyen d03d9a3719 Merge branch 'MDL-85177-main' of https://github.com/lucaboesch/moodle 2025-05-29 09:53:34 +07:00
Huong Nguyen 7d9722c84c Merge branch 'MDL-85525-main' of https://github.com/andelacruz/moodle 2025-05-29 09:51:37 +07:00
Huong Nguyen ba879425f6 Merge branch 'MDL-85400-main' of https://github.com/lameze/moodle 2025-05-29 08:59:33 +07:00
Huong Nguyen e6177ca370 Merge branch 'MDL-85389-main' of https://github.com/andelacruz/moodle 2025-05-29 08:52:22 +07:00
AMOS bot c571285818 Automatically generated installer lang files 2025-05-29 00:08:03 +00:00
Szymon Karolczuk 1ce83fee97 MDL-85573 tool_brickfield: fix uninstall code 2025-05-28 11:10:56 +02:00
Amaia Anabitarte 11c9f9c7c9 Merge branch 'MDL-85392-main-fix2' of https://github.com/sarjona/moodle 2025-05-28 08:37:45 +02:00
andelacruz f43ca5aba3 MDL-85389 mod_lesson: Behat for filtering lesson reports/essays by group 2025-05-28 14:03:48 +08:00
sam marshall 20480c7dc6 MDL-85400 PHPunit: Hard to test code that uses encryption
This change stops the encryption code setting created key files to
read-only during PHPunit runs, which means they will be safely
deleted when the system resets after a test.
2025-05-28 12:52:45 +08:00
meirzamoodle 48fcb8556a MDL-85437 AI: Move focus to the AI drawer 2025-05-28 11:30:00 +07:00
andelacruz 282c35f7da MDL-85525 mod_quiz: Behat test for quiz attempt page block display 2025-05-28 09:19:21 +08:00
Sara Arjona c158c3ef21 MDL-85392 block_site_main_menu: Add required library 2025-05-27 09:51:34 +02:00
Jun Pataleta a8bf72e643 Merge branch 'MDL-84806-main' of https://github.com/davewoloszyn/moodle 2025-05-27 15:37:06 +08:00
Laurent David d21a5035f2 MDL-85250 mod_book: Replace hardcoded separator in page titles
* Replace hard-coded ': ' by the usual separator constant in Book
2025-05-27 06:42:20 +02:00
Huong Nguyen a0279e9e25 Merge branch 'MDL-85169' of https://github.com/paulholden/moodle 2025-05-27 09:15:49 +07:00
Alexander Van der Bellen 7142b17b04 MDL-83044 core_block: Add return value check on form submission 2025-05-26 23:03:05 +08:00
ferran 88e987d781 Merge branch 'MDL-85354-main' of https://github.com/roland04/moodle 2025-05-26 16:13:02 +02:00
ferran 22d04237f9 Merge branch 'MDL-85247-main' of https://github.com/aanabit/moodle 2025-05-26 15:39:31 +02:00
Amaia Anabitarte b0e9c25476 Merge branch 'MDL-85392-main-fix' of https://github.com/sarjona/moodle 2025-05-26 15:22:04 +02:00
Sara Arjona c7dc23d1b9 MDL-85392 behat: Fix behat failures with Additional activities 2025-05-26 15:20:24 +02:00
ferran 7d80062e4f Merge branch 'MDL-84304-main' of https://github.com/laurentdavid/moodle 2025-05-26 13:49:45 +02:00
Sara Arjona 9e9eecd033 Merge branch 'MDL-85404-main' of https://github.com/ferranrecio/moodle 2025-05-26 11:27:33 +02:00
Amaia Anabitarte 9d82c8bef0 Merge branch 'MDL-84216-main' of https://github.com/ferranrecio/moodle 2025-05-26 11:21:45 +02:00
Mikel Martín 88dbf8a0d9 MDL-85281 theme_boost: Improve 'Add block' buttons styling
- Homogenize the styles for adding content buttons (add section, add button, ...)
  creating a new class 'btn-add-content' and add the SCSS in a single place.
- Fix the 'i_add_the_block' behat step to stop using css class and use a data
  attribute.
2025-05-26 10:47:40 +02:00
Mikel Martín fd0c7abaad MDL-85354 course: Improve course management tertiary navigation
Course search input in course management page can be missleading because it
is directly placed after the tertiary navigation dropdown.
Move the Search input to the right.
2025-05-26 10:47:04 +02:00
Amaia Anabitarte 7b62b80490 Merge branch 'MDL-85392-main' of https://github.com/sarjona/moodle 2025-05-26 10:19:13 +02:00
cescobedo 0487245446 Merge branch 'MDL-85435-main' of https://github.com/aanabit/moodle 2025-05-26 09:58:15 +02:00
sam marshall 2e874f8133 MDL-84732 Accessibility: Focus issue after closing nested modal 2025-05-23 15:47:23 +01:00
Luca Bösch 3c3918c414 MDL-84548 mod_qbank: Let delete bulk action set text-danger class. 2025-05-23 06:48:06 +02:00
Luca Bösch c414ae9a3c MDL-85177 quiz: style the question version pulldown nicely. 2025-05-23 06:43:20 +02:00
Huong Nguyen d65e24a62c weekly release 5.1dev 2025-05-23 11:03:36 +07:00
Huong Nguyen 7d0da9c3d0 NOBUG: Add upgrade notes 2025-05-23 11:03:36 +07:00
Huong Nguyen 6b5795ce86 Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-05-23 11:03:24 +07:00
David Woloszyn 155a647c64 MDL-84806 tiny_aiplacement: Remove unused div and css 2025-05-23 12:30:50 +10:00
David Woloszyn 636cacdcc6 MDL-84806 tiny_aiplacement: Announce action results for accessibility
The generatetext.js and associated templates have been adjusted to
match more closely with the generate image files. The generate image
way of displaying content was better suited to aria.
2025-05-23 12:30:50 +10:00
David Mudrák c6dd080532 MDL-85507 lang: Use fixed strings in tests, too 2025-05-22 21:10:00 +02:00
Helen Foster c2e7dc8e1e MDL-85507 lang: Import fixed English strings (en_fix) 2025-05-22 19:07:25 +02:00
Sara Arjona 4fe2e858b5 MDL-85392 block_site_main_menu: Add course support
To make the Main site menu block more versatile for use in various courses,
the following improvements have been made:

- Customizable title: Users can give a title to the block, that's relevant to
its context within a specific course.
- Expanded course compatibility: The block now functions correctly even in
course formats that don't have a dedicated course view page, such as Single
activity courses.
- Renamed for clarity: The block has been renamed to better reflect its broader
applicability.
2025-05-22 18:33:37 +02:00
ferran bcbc7f3fea MDL-84216 core_courseformat: fix state actions phpdocs 2025-05-22 15:27:46 +02:00
ferran 892931b757 MDL-84216 core_courseformat: new section_duplicate update 2025-05-22 15:27:46 +02:00
yusufwib01 da2d4521c8 MDL-85552 core: Make group selector label use normal font weight 2025-05-22 16:23:32 +07:00
Stevani Andolo 531c526b4e MDL-83448 core_hub: Fixed registration check 2025-05-22 13:41:42 +08:00
Huong Nguyen 5b7799ed6f Merge branch 'MDL-84899-main' of https://github.com/laurentdavid/moodle 2025-05-22 11:00:06 +07:00
Huong Nguyen 1c8c62ade5 Merge branch 'MDL-85240_main' of https://github.com/PhilippImhof/moodle 2025-05-22 10:58:28 +07:00
Huong Nguyen f354086c91 Merge branch 'MDL-84793-main' of https://github.com/sammarshallou/moodle 2025-05-22 10:48:02 +07:00
Huong Nguyen 766ba0bd8d Merge branch 'MDL-84918-main' of https://github.com/HuongNV13/moodle 2025-05-22 10:34:12 +07:00
David Woloszyn d6b955be71 MDL-84918 core: Add zend.exception_ignore_args environment check 2025-05-22 10:03:36 +07:00
Huong Nguyen d289ea56b4 MDL-84918 core: Add initial environment requirements for Moodle 5.1 2025-05-22 09:58:26 +07:00
Huong Nguyen bce7d058d7 Merge branch 'MDL-74900-main' of https://github.com/raortegar/moodle 2025-05-22 09:37:04 +07:00
Huong Nguyen d8cf8e53c1 Merge branch 'MDL-85193-main' of https://github.com/junpataleta/moodle 2025-05-22 09:23:03 +07:00
Huong Nguyen b822be68ad Merge branch 'MDL-85497' of https://github.com/paulholden/moodle 2025-05-22 09:21:47 +07:00
Amaia Anabitarte 7976fa47cd MDL-85435 course: Render HTML in activity overview name mustache 2025-05-21 17:35:41 +02:00
Katalin Lukacs Toth 3a3008ca1a MDL-84978 mod_forum: Fix latest/earliest post id lookup in a discussion
This properly fixes the problems that commit 0f5a96f in MDL-80848 tried
to address.
2025-05-21 11:01:49 +02:00
Huong Nguyen 97bbdb795b Merge branch 'MDL-84274-main' of https://github.com/davewoloszyn/moodle 2025-05-21 13:35:29 +07:00
raortegar e132aa26d5 MDL-74900 core_course: Exception in module deletion if missing instance 2025-05-21 08:25:58 +02:00
Huong Nguyen 67bca7b025 Merge branch 'MDL-83985-int-fix' of https://github.com/HuongNV13/moodle 2025-05-21 10:27:53 +07:00
Huong Nguyen 5cc37c0868 Merge branch 'MDL-85311-main' of https://github.com/rjnl/moodle 2025-05-21 10:22:54 +07:00
Huong Nguyen 9c368c8c1d Merge branch 'MDL-84296-main' of https://github.com/stevandoMoodle/moodle 2025-05-21 09:59:44 +07:00
Huong Nguyen 7dfe22758e Merge branch 'MDL-85374-main' of https://github.com/andrewnicols/moodle 2025-05-21 09:55:43 +07:00
Huong Nguyen e980a9de9f MDL-83985 grade_items_history: change itemname to 1333 chars 2025-05-21 09:22:45 +07:00
AMOS bot 2dd91e3f3d Automatically generated installer lang files 2025-05-21 00:07:59 +00:00
Paul Holden 8393a4ff0e MDL-82109 notes: include link to add site note if user has capability. 2025-05-20 13:18:25 +01:00
Huong Nguyen bd36c6495e Merge branch 'MDL-83985-main' of https://github.com/HuongNV13/moodle 2025-05-20 17:09:08 +07:00
Luca Bösch 9aa3599bc5 MDL-83985 grade_items: change itemname to 1333 chars 2025-05-20 17:06:50 +07:00
Luca Bösch 4716d73808 MDL-83985 course_sections: change name to 1333 chars 2025-05-20 17:06:50 +07:00
Luca Bösch 45cb49d216 MDL-83985 badges: change name and issuername to 1333 chars 2025-05-20 17:06:48 +07:00
Andrew Nicols 595d89b1be MDL-85374 report_competency: Create custom step for setting autocomplete
The autocompletes used in the competency report have been bastardised to
redirect on selection. Unfortunately this also applies when when making
null-op changes like deleting the initial "Please select a value"
option.

The autocomplete code removes all current options before creating an
option, and because of this redirect the browser is redirecting before
the new value can be entered, but we retain a reference to the field as
`$this->field`, which is now stale.
2025-05-20 12:41:51 +08:00
Amaia Anabitarte 3cb141de19 Merge branch 'MDL-85252-main' of https://github.com/laurentdavid/moodle 2025-05-19 15:15:03 +02:00
Amaia Anabitarte 900c7e67a8 Merge branch 'MDL-85397' of https://github.com/tasiobg/moodle 2025-05-19 12:43:07 +02:00
Amaia Anabitarte 145e88f866 Merge branch 'MDL-85264' of https://github.com/paulholden/moodle 2025-05-19 12:38:03 +02:00
Laurent David c21ce21b98 MDL-84304 core_courseformat: Remove COMPLETION_COMPLETE_FAIL test
* Because we removed this status in mod_scorm, we cannot test it
anymore against any module as no module has custom_rules that leads
to COMPLETION_COMPLETE_FAIL
2025-05-19 11:54:46 +02:00
Laurent David 3a5ca14b24 MDL-84304 mod_scorm: Remove completion failed from behat test
* Now that we removed the COMPLETION_COMPLETE_FAIL status for scorm
behat tests needs to be updated
2025-05-19 11:54:46 +02:00
Magnus Samuelsson 487de05d13 MDL-84304 mod_scorm: Remove the COMPLETION_COMPLETE_FAIL status 2025-05-19 11:54:45 +02:00
Stevani Andolo 461a069a0a MDL-85159 editory_tiny: Fix language list and track srclang a11y issue 2025-05-19 16:48:03 +08:00
Amaia Anabitarte 6c167f36d3 MDL-85247 report_log: Remove course filter for course log report 2025-05-19 09:34:52 +02:00
Amaia Anabitarte e2aaf58ed3 MDL-82069 core_completion: Improve errors for multiple grading items 2025-05-19 09:32:20 +02:00
Luca Bösch 553861cbcd MDL-83985 tool_recyclebin: change module names to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch 19cc7dc5df MDL-83985 mod_workshop: change name to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch 410f07f5c9 MDL-83985 mod_wiki: change name to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch 656d6bbef3 MDL-83985 mod_url: change name to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch 1f0d8c3481 MDL-83985 mod_subsection: change name to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch 070fac98ea MDL-83985 mod_scorm: change name to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch 79268654e2 MDL-83985 mod_resource: change name to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch 61632fcd43 MDL-83985 mod_quiz: change name to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch 5dc1d235ca MDL-83985 mod_qbank: change name to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch 2d55d71852 MDL-83985 mod_page: change name to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch 3a8421233b MDL-83985 mod_lti: change name to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch a5236207bb MDL-83985 mod_lesson: change name to 1333 chars 2025-05-16 13:53:19 +02:00
Luca Bösch a4ac449be8 MDL-83985 mod_label: change name to 1333 chars 2025-05-16 13:53:16 +02:00
Luca Bösch 4626347d77 MDL-83985 mod_imscp: change name to 1333 chars 2025-05-16 13:49:50 +02:00
Luca Bösch 02d5ece867 MDL-83985 mod_h5pactivity: change name to 1333 chars 2025-05-16 13:49:50 +02:00
Luca Bösch e834cb7fbe MDL-83985 mod_glossary: change name to 1333 chars 2025-05-16 13:49:50 +02:00
Luca Bösch 9dcc98c7f3 MDL-83985 mod_forum: change name to 1333 chars 2025-05-16 13:49:50 +02:00
Luca Bösch c3af150e1f MDL-83985 mod_folder: change name to 1333 chars 2025-05-16 13:49:50 +02:00
Luca Bösch 7f7cde56d5 MDL-83985 mod_feedback: change name, item name to 1333 chars 2025-05-16 13:49:50 +02:00
Luca Bösch 622570fae9 MDL-83985 mod_data: change name to 1333 chars 2025-05-16 13:49:50 +02:00
Luca Bösch d81e8c6b4a MDL-83985 mod_choice: change name to 1333 chars 2025-05-16 13:49:50 +02:00
Luca Bösch c00b022c29 MDL-83985 mod_book: change name, chapter title to 1333 chars 2025-05-16 13:49:50 +02:00
Luca Bösch 5a3b6b9965 MDL-83985 mod_bigbluebuttonbn: change name to 1333 chars 2025-05-16 13:49:50 +02:00
Luca Bösch 9bd31b286b MDL-83985 mod_assign: change name to 1333 chars 2025-05-16 13:49:50 +02:00
Jun Pataleta ff6025d330 MDL-85471 theme_boost: Dismiss tooltips on escape 2025-05-16 14:23:16 +08:00
Mihail Geshoski b4a8c83ea3 weekly release 5.1dev 2025-05-16 12:57:23 +08:00
Mihail Geshoski bd204dde96 NOBUG: Add upgrade notes 2025-05-16 12:57:23 +08:00
Mihail Geshoski bed90de010 Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install into main 2025-05-16 12:56:20 +08:00
Muhammad Arnaldo 8700e48051 MDL-83487 mod_forum: retain upcoming posts in user digests 2025-05-16 11:18:48 +07:00
Paul Holden 4cc406a323 MDL-85513 output: centre chevron icons within collapsible section. 2025-05-15 23:18:34 +01:00
Jun Pataleta 3478eba03e MDL-79756 core: Add missing p-0 class in toggler container 2025-05-15 23:50:44 +08:00
Paul Holden ea840539a4 MDL-85497 user: ask for confirmation before page is reset. 2025-05-15 11:04:37 +01:00
sam marshall 9a1c919f32 MDL-84793 Behat: Allow CLI scripts to run on Behat instance 2025-05-15 08:48:40 +01:00
toanlamt 14d38bdaaa MDL-85050 Javascript: core/dropzone Fix link & box click event conflict 2025-05-15 14:31:41 +07:00
Huong Nguyen eb41781353 Merge branch 'MDL-80056-main' of https://github.com/Jayce0808/moodle 2025-05-15 12:06:47 +07:00
Huong Nguyen 1aae73d052 Merge branch 'MDL-83350-main' of https://github.com/meirzamoodle/moodle 2025-05-15 12:00:41 +07:00
Huong Nguyen e34f141b96 Merge branch 'MDL-84073-main' of https://github.com/sh-csg/moodle 2025-05-15 11:57:10 +07:00
Huong Nguyen b5a2f0536f Merge branch 'MDL-83943-main' of https://github.com/meirzamoodle/moodle 2025-05-15 11:45:16 +07:00
Huong Nguyen 0f6395deab Merge branch 'MDL-85279-main' of https://github.com/andelacruz/moodle 2025-05-15 11:42:10 +07:00
Huong Nguyen 795d94e117 MDL-79756 core: Fix deprecated version 2025-05-14 22:56:45 +07:00
Huong Nguyen 381b2cc8f3 Merge branch 'MDL-79756-main' of https://github.com/junpataleta/moodle 2025-05-14 22:54:49 +07:00
Huong Nguyen 0285e0abe2 Merge branch 'MDL-84009-main' of https://github.com/raortegar/moodle 2025-05-14 21:51:29 +07:00
Amaia Anabitarte fc404a1360 Merge branch 'MDL-85253-main' of https://github.com/laurentdavid/moodle 2025-05-14 21:35:54 +07:00
Huong Nguyen 7aa47bbf6a Merge branch 'MDL-84751-main' of https://github.com/davewoloszyn/moodle 2025-05-14 21:35:54 +07:00
Amaia Anabitarte 85078d24e9 Merge branch 'MDL-85167-main' of https://github.com/roland04/moodle 2025-05-14 21:35:54 +07:00
Amaia Anabitarte 3d436ba822 Merge branch 'MDL-85205-main' of https://github.com/roland04/moodle 2025-05-14 21:35:54 +07:00
Amaia Anabitarte 030d6f26d0 Merge branch 'MDL-83081-main' of https://github.com/ferranrecio/moodle 2025-05-14 21:35:54 +07:00
Amaia Anabitarte ece204cafd Merge branch 'MDL-85360-main' of https://github.com/sarjona/moodle 2025-05-14 21:35:54 +07:00
Sara Arjona 8be4a4643b Merge branch 'MDL-85449' of https://github.com/paulholden/moodle 2025-05-14 21:35:54 +07:00
Sara Arjona 1b40a9a7eb Merge branch 'MDL-85157-main' of https://github.com/roland04/moodle 2025-05-14 21:35:54 +07:00
Sara Arjona 29ad067c10 Merge branch 'MDL-84954-main' of https://github.com/ferranrecio/moodle 2025-05-14 21:35:54 +07:00
Sara Arjona d813277d27 Merge branch 'MDL-81436-main' of https://github.com/rjnl/moodle 2025-05-14 21:35:54 +07:00
Sara Arjona 6b29ff1835 Merge branch 'MDL-81842-main' of https://github.com/laurentdavid/moodle 2025-05-14 21:35:53 +07:00
Huong Nguyen 8f6eabefc1 Merge branch 'MDL-84128-main' of https://github.com/meirzamoodle/moodle 2025-05-14 21:35:53 +07:00
Huong Nguyen 12f1cc1f8b MDL-78091 core: Fix deprecated version 2025-05-14 21:35:53 +07:00
Huong Nguyen 8c51114865 Merge branch 'MDL-78091_final-deprecations-for-quiz' of https://github.com/ziegenberg/moodle 2025-05-14 21:35:53 +07:00
Huong Nguyen 6bb4cad5ee Merge branch 'MDL-76612_final-quiz-deprecations' of https://github.com/ziegenberg/moodle 2025-05-14 21:35:53 +07:00
Huong Nguyen d77b3abe6d Merge branch 'MDL-85294-main' of https://github.com/lucaboesch/moodle 2025-05-14 21:35:53 +07:00
Huong Nguyen bc608416b1 Merge branch 'MDL-85224_main' of https://github.com/PhilippImhof/moodle 2025-05-14 21:35:53 +07:00
Huong Nguyen 512b595034 Merge branch 'MDL-85363-main' of https://github.com/lucaboesch/moodle 2025-05-14 21:35:53 +07:00
Huong Nguyen 2649de786f Merge branch 'MDL-84964-main' of https://github.com/Jayce0808/moodle 2025-05-14 21:35:53 +07:00
ferran b50c2ba71d Merge branch 'MDL-85364-main' of https://github.com/sarjona/moodle 2025-05-14 21:35:53 +07:00
Amaia Anabitarte 49d9dd6161 Merge branch 'MDL-85249-main' of https://github.com/laurentdavid/moodle 2025-05-14 21:35:53 +07:00
ferran e98f398f67 Merge branch 'mdl-84520_main' of https://github.com/james-cnz/moodle 2025-05-14 21:35:53 +07:00
Tasio d5afc6e9cd MDL-85397 theme: update reports to use container queries
With container queries, responsive design is no longer limited to the full browser width. For example, we can now display the report in a compact side panel, and it will automatically adapt its styling to suit smaller spaces.
2025-05-14 15:51:40 +02:00
Tasio 8bb40916f3 MDL-85260 core: prevent background scrolling
After upgrading to Bootstrap 5 (Moodle v5), opening a modal no longer prevents the background content from scrolling.
This fix restores the intended behavior by mimicking Bootstrap 5's JavaScript logic that disables background scrolling
when a modal is open.
2025-05-14 15:39:06 +02:00
Pedro Jordao 4a1bf4304b MDL-85158 libraries: Configure responsive options for ChartJS
Currently, the attributes to configure the responsiveness of a chart
are being set statically. With this change it will be possible to
update these static attributes in order to change the aspectRatio and
resizeDelay of the chart.
2025-05-14 09:34:33 -03:00
raortegar dab86dd04a MDL-84009 factor_webauthn: Add additional security keys 2025-05-14 11:16:04 +02:00
raortegar 315abd55ac MDL-84009 tool_mfa: Additional factor instances support 2025-05-14 11:16:04 +02:00
Paul Holden 318388af70 MDL-84996 enrol_manual: ensure externally supplied users are valid. 2025-05-14 09:55:39 +01:00
ferran f200f51b4c MDL-85404 format_social: allow subsections in social activities 2025-05-14 09:58:33 +02:00
andelacruz 7c0370e737 MDL-85279 mod_assign: Renamed behat test to a more specific name 2025-05-14 15:06:22 +08:00
andelacruz 45c2c63e62 MDL-85279 mod_page: Fix behat to match the expected behaviour 2025-05-14 11:29:40 +08:00
Jayce b2fc9bc6cf MDL-80056 mod_assign: Hide/show different bulk action buttons 2025-05-14 12:15:41 +09:30
Paul Holden 4e1dd1d51f MDL-85262 tool_task: switch next run time comparison in renderer.
If a task is "due", then next run time should be considered "ASAP".
2025-05-13 22:13:12 +01:00
ferran ecadc40c0d MDL-83081 mod_label: remove dndmedia setting 2025-05-13 16:29:29 +02:00
Stefan Hanauska d7debc7ad5 MDL-85432 mod_qbank: Don't support completion 2025-05-13 10:30:56 +02:00
Rajneel Totaram 9cb53a98e0 MDL-81436 theme: Fix scope of showmore button selector
Co-authored-by: Mikel Martín <mikel@moodle.com>
2025-05-13 17:28:05 +12:00
David Woloszyn 1ac70050e7 MDL-84751 aiprovider_ollama: Fix settings help spacing 2025-05-13 13:46:01 +10:00
David Woloszyn b7d5895d6e MDL-84751 aiprovider_openai: Fix settings help spacing 2025-05-13 13:36:49 +10:00
meirzamoodle 27ed3a0644 MDL-83350 files: Avoid cacheing user and file repo files
Set the lifetime to zero for files referenced in
the local/internal repository (private files and file system),
because they should not be cached.

Add `no-store` to the cache-control to ensure resources are
never cached, always fetching the latest version.
2025-05-13 09:34:16 +07:00
Stevani Andolo 86fa56fd3f MDL-84296 core_hub: Added detailed AI usage data to registration page 2025-05-13 07:21:51 +08:00
Mikel Martín e44195b5eb MDL-84954 theme_boost: Fix activity icons sizing styles 2025-05-12 15:21:08 +02:00
ferran 68dc80bd74 MDL-84954 calendar: add color to activity icons 2025-05-12 15:21:08 +02:00
Jun Pataleta a0766c10b8 Merge branch 'MDL-84817-main' of https://github.com/davewoloszyn/moodle 2025-05-12 12:44:35 +08:00
Laurent David 643b720878 MDL-81842 formlibs: Change display in sticky footer
* Make sure that form elements that are inserted in the
sticky footer are not wrapped
2025-05-12 06:15:51 +02:00
Paul Holden 5a3d329286 MDL-85449 block_myoverview: preserve documentation language params.
Fixes the link to Moodle docs from zero state.
2025-05-11 19:24:18 +01:00
Philipp Imhof ac5ee7f0ae MDL-85240 questions: restrict style override to qtype multichoice
As a consequence, the same style has been added to the calculatedmulti
qtype, because it uses similar structure and benefited from the more
general override.
2025-05-11 13:25:30 +02:00
Philipp Imhof 1d1a105f79 MDL-85224 quiz: consider submitted state when filtering
In function quiz_report_grade_method_sql(), also consider the new state 'submitted' when filtering for FIRSTATTEMPT or LASTATTEMPT.
2025-05-10 17:40:29 +02:00
AMOS bot fd1c2f4b16 Automatically generated installer lang files 2025-05-10 00:08:03 +00:00
Mikel Martín 2ee37467ba MDL-85205 theme_boost: Fix incorrect uses of 'btn-link' class
Because btn-link relies on $link-hover-decoration variable, some incorrect
btn-link usages need to be fixed.
2025-05-09 13:57:37 +02:00
Mikel Martín de611785a6 MDL-85205 theme_boost: Add link hover underline 2025-05-09 13:57:37 +02:00
Paul Holden 93cadaba95 MDL-85398 blocks: constrain width of block controls dropdown menu. 2025-05-09 12:50:35 +01:00
Mikel Martín a861a4687e MDL-85157 theme_boost: Clean table SCSS styles
- Simplify .generaltable styles
- Add Bootstrap .table class to every use of .generaltable
- Remove unneded classes from tables (.generalbox, .boxaligncenter, ...)
2025-05-09 13:46:51 +02:00
Mikel Martín 0dfb3002e5 MDL-85167 theme_boost: Fix tertiary navigation key listeners 2025-05-09 13:42:02 +02:00
Laurent David 2973956872 MDL-85252 mod_folder: Replace hardcoded separator in pages titles
* Replace the ': ' hardcoded separator by the page title separator
constant
2025-05-09 11:09:18 +02:00
Sara Arjona 8fbbc5e00f MDL-85364 block_social_activities: Move activities in mod pages too 2025-05-09 09:42:04 +02:00
Sara Arjona f8db24b44a MDL-85360 theme_boost: Fix active item indicator spacing
The fix in MDL-85017 covered the More menu; however, the secondary
navigation within the Single activity course format was not updated.
2025-05-09 09:02:45 +02:00
Laurent David 9864ec2bff MDL-84899 mod_forum: Fix summary report form change checker
* The forum summary report was not removing the right form
from the list of forms to check for changes.
2025-05-09 08:43:29 +02:00
Laurent David f44b292df8 MDL-84899 core_form: Fix unWatchForm in FormChangeChecker
* The unWatchForm as it stood was not removing the form from the list.
2025-05-09 08:43:29 +02:00
Luca Bösch 689f7c7571 MDL-85363 quiz: style the question number inplace editable nicely. 2025-05-09 08:13:08 +02:00
Luca Bösch 33fc27b6d7 MDL-85294 qbank: Align header, buttons and switch in "Edit categories". 2025-05-09 08:13:02 +02:00
meirzamoodle dc88f544f1 MDL-83943 core_tag: Fix the broken user tag pagination 2025-05-09 12:48:48 +07:00
meirzamoodle 4311608cb3 MDL-84128 core: Flip the image according to its orientation in PHP GD 2025-05-09 11:16:59 +07:00
Huong Nguyen 9242f9619a weekly release 5.1dev 2025-05-09 09:50:02 +07:00
Huong Nguyen b69d8407ce NOBUG: Add upgrade notes 2025-05-09 09:50:02 +07:00
Huong Nguyen e41082f869 Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-05-09 09:49:50 +07:00
Stefan Hanauska 325c1e1d98 MDL-84073 blocks: Load invisible blocks 2025-05-08 14:36:09 +02:00
Daniel Ureña 70209d2bc0 MDL-85407 mod_data: Fix unclosed HTML in list view 2025-05-08 09:25:43 +02:00
David Woloszyn e8a0b9d91c MDL-84817 core_message: Fix display issues in drawer at 400% 2025-05-08 17:06:12 +10:00
Laurent David 93fd168819 MDL-85249 mod_feedback: Replace hardcoded separator in page titles
* Replace the ': ' hardcoded separator in all pages titles
2025-05-08 07:32:04 +02:00
Huong Nguyen bbd92f9de6 Merge branch 'MDL-85341-main' of https://github.com/snake/moodle 2025-05-08 10:52:19 +07:00
Huong Nguyen f52364f894 Merge branch 'MDL-85280-main' of https://github.com/abias/moodle 2025-05-08 10:38:15 +07:00
Huong Nguyen 9ccc8d2f75 Merge branch 'MDL-84708-master' of https://github.com/danghieu1407/moodle 2025-05-08 09:46:53 +07:00
Huong Nguyen e9cd4e14c9 Merge branch 'MDL-84677-main' of https://github.com/lucaboesch/moodle 2025-05-08 09:28:02 +07:00
Huong Nguyen 3ada2becc8 Merge branch 'MDL-84597' of https://github.com/paulholden/moodle 2025-05-08 09:04:18 +07:00
Huong Nguyen 4ceef67de8 Merge branch 'MDL-85220-main' of https://github.com/rjnl/moodle 2025-05-08 08:58:51 +07:00
Huong Nguyen e3dc616055 Merge branch 'MDL-84654-main' of https://github.com/andelacruz/moodle 2025-05-08 08:43:58 +07:00
Amaia Anabitarte 13f7dad23b Merge branch 'MDL-85361-main' of https://github.com/sarjona/moodle 2025-05-07 14:01:24 +02:00
Sara Arjona f644575e73 Merge branch 'MDL-83422-main' of https://github.com/meirzamoodle/moodle 2025-05-07 13:50:13 +02:00
ferran f840450a62 Merge branch 'MDL-80455_remove-render_badge_collection-and-render_badge_recipients' of https://github.com/ziegenberg/moodle 2025-05-07 13:26:54 +02:00
Amaia Anabitarte 491cc0018a Merge branch 'MDL-84641-main' of https://github.com/ferranrecio/moodle 2025-05-07 13:04:15 +02:00
Jun Pataleta 51364617f0 MDL-85193 course: Fix restore of backups with missing activity plugins
Show debugging instead of throwing an error when fetching an activity
icon from a missing activity plugin.
2025-05-07 18:08:36 +08:00
Laurent David 05cd7ca936 MDL-85253 core_course: Fix edit module page title
* Following up MDL-80418, we should have New Database | Course name
as a title for the module edit page
2025-05-07 07:40:44 +02:00
AMOS bot cbbb7da455 Automatically generated installer lang files 2025-05-07 00:07:55 +00:00
Laurent David 6c2852ff08 MDL-85253 mod_data: Replace hardcoded separator for page titles 2025-05-06 17:33:30 +02:00
danghieu1407 30fae489fb MDL-85378 Badges: Add option to export recipients list 2025-05-06 15:22:52 +07:00
Huong Nguyen 98565de944 Merge branch 'MDL-85310-main' of https://github.com/andelacruz/moodle 2025-05-06 10:31:48 +07:00
Angelia Dela Cruz f285235be5 MDL-84654 mod_assign: Assignment additional files can be hidden 2025-05-06 11:21:37 +08:00
Jake Dallimore 8178f7c039 MDL-85153 mod_assign: add support for gradebook grade analysis
Implementing grade.php allows teachers to link directly from the
gradebook's grader report to the assignment grader view, both for
specific students (using the "Grade analysis" cell action) or for
the activity in general (using the "View Assignment results" link
in the column actions). Also includes a small fix for grade report
since the report cell content is now HTML.
2025-05-05 14:12:43 +08:00
Sara Arjona e618c03ce7 MDL-85361 block_social_activity: Fix inline editing text field 2025-05-04 19:35:14 +02:00
Paul Holden 3d8cdd8ea5 MDL-85264 javascript: reject promise when hiding saveCancel modal. 2025-05-02 17:24:01 +01:00
Tim Hunt d07575ecc5 MDL-84965 assign: improve the HTML in messages 2025-05-02 14:22:36 +01:00
Mikel Martín 23ba34ec99 MDL-83422 tiny_media: Fix modal footer layout 2025-05-02 19:35:29 +07:00
Paul Holden 1fe0dee805 MDL-85169 forms: focus grouped fields element based on parent data.
This fixes the previous attempt at focusing the first field within
grouped elements (aec60788) which inadvertently introduced duplicate
IDs.
2025-05-02 13:34:29 +01:00
Luca Bösch cbdc5292c8 MDL-84677 backup: Filter course shortnames in copy progress viewer. 2025-05-02 08:51:33 +02:00
Huong Nguyen 15b534da3e weekly release 5.1dev 2025-05-02 09:16:04 +07:00
Huong Nguyen ec4c393397 NOBUG: Add upgrade notes 2025-05-02 09:16:04 +07:00
Huong Nguyen aa90a4d41c Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-05-02 09:15:49 +07:00
Jake Dallimore 96eda0ed84 MDL-85341 core: remove unnecessary sesskey from module controlmenu items
This impacts those items using basemodurl:
- edit item
- move item
neither of which need sesskey at this stage as changes aren't being made
yet.
2025-05-02 09:51:32 +08:00
Paul Holden f44f29586c MDL-85273 output: fix custom menu dropdowns within "More" sub-menu.
Since move to BS5 data-* attributes in 0c586b41 trying to open custom
menu dropdowns that had been moved to the "More" sub-menu was broken.

It appears that Bootstrap now handles open/close for us automatically
(so we were effectively closing the menu immediately after Bootstrap
opened it).
2025-05-01 22:02:28 +01:00
Paul Holden 566c9670a3 MDL-85327 admin: observe show/hide settings on category page.
Co-authored-by: Carlos Castillo <carlos.castillo@moodle.com>
2025-05-01 10:54:09 +01:00
Huong Nguyen 9301575d49 Merge branch 'MDL-85178-main' of https://github.com/lucaboesch/moodle 2025-05-01 11:02:24 +07:00
Huong Nguyen 138097ee5b Merge branch 'MDL-84071-master' of https://github.com/danghieu1407/moodle 2025-05-01 10:52:39 +07:00
Huong Nguyen 5f4c28dbf0 Merge branch 'MDL-85003-main-add-more-info-to-course-request-mail' of https://github.com/melanietreitinger/moodle 2025-05-01 10:45:01 +07:00
Huong Nguyen 4a7ad40b88 Merge branch 'MDL-82381-main' of https://github.com/sh-csg/moodle 2025-05-01 10:42:18 +07:00
Huong Nguyen 7412d06775 Merge branch 'MDL-85225-main' of https://github.com/ferranrecio/moodle 2025-05-01 09:54:20 +07:00
Huong Nguyen 7dcd1d93f1 Merge branch 'MDL-85107-main' of https://github.com/ferranrecio/moodle 2025-05-01 09:50:34 +07:00
Daniel Ziegenberg 0635cad96c MDL-77307 core_grades: Fix missing language string 2025-05-01 09:48:19 +07:00
Rajneel Totaram 01be8b6b84 MDL-85311 mod_forum: Fix broken unread posts styles 2025-05-01 13:03:01 +12:00
AMOS bot fe8420a2f8 Automatically generated installer lang files 2025-05-01 00:08:02 +00:00
Angelia Dela Cruz e278eac36c MDL-85310 qtype: Renamed duplicate scenario names to fix warning 2025-04-30 11:37:51 +08:00
Huong Nguyen ab6c1e5384 Merge branch 'MDL-84781-main' of https://github.com/sh-csg/moodle 2025-04-30 10:31:24 +07:00
Huong Nguyen b85c809b43 Merge branch 'MDL-85141-main' of https://github.com/roland04/moodle 2025-04-30 10:14:31 +07:00
Huong Nguyen 84e2557c88 MDL-77307 core_grades: Fix version number 2025-04-30 10:12:09 +07:00
Huong Nguyen 0daee32632 Merge branch 'MDL-77307_final-deprecation-grader-report-and-grade-functions' of https://github.com/ziegenberg/moodle 2025-04-30 10:10:46 +07:00
Huong Nguyen 8a9712237d Merge branch 'MDL-85222' of https://github.com/tasiobg/moodle 2025-04-30 10:05:28 +07:00
Huong Nguyen 816b97906a Merge branch 'MDL-85208' of https://github.com/paulholden/moodle 2025-04-30 10:03:31 +07:00
Sara Arjona 8344c6b99a Merge branch 'MDL-84805-main' of https://github.com/aanabit/moodle 2025-04-29 15:31:46 +02:00
Amaia Anabitarte 188f7cd852 MDL-84805 badges: Titles must be unique 2025-04-29 11:15:02 +02:00
Rajneel Totaram 91e670b14e MDL-85220 block_recentlyaccesseditems: Fix heading level 2025-04-29 10:12:27 +12:00
Sara Arjona f0c5492544 Merge branch 'MDL-84192' of https://github.com/paulholden/moodle 2025-04-28 11:24:47 +02:00
Alexander Bias 34ba203c4d MDL-79362 auth_ldap: Close transaction when user fails to create 2025-04-28 10:46:51 +02:00
Huong Nguyen 3c929c6964 Merge branch 'MDL-84983' of https://github.com/paulholden/moodle 2025-04-28 10:54:55 +07:00
Huong Nguyen a3ce17f6df Merge branch 'MDL-84539-main' of https://github.com/andrewgos/moodle 2025-04-28 08:59:15 +07:00
Luca Bösch 9578c1a942 MDL-85178 quiz: style the question number inplace editable nicely. 2025-04-25 08:39:12 +02:00
Alexander Bias 3da85b5e76 MDL-85280 communication: Adapt communication button style 2025-04-25 08:17:34 +02:00
Huong Nguyen 5c4a7567ae Merge branch 'MDL-84421-main' of https://github.com/andrewnicols/moodle 2025-04-25 09:09:32 +07:00
Huong Nguyen 4d4369e073 weekly release 5.1dev 2025-04-24 22:05:18 +07:00
Huong Nguyen b700988f74 NOBUG: Add upgrade notes 2025-04-24 22:05:17 +07:00
Huong Nguyen 7575cd14e0 Merge branch 'install_main' of https://git.in.moodle.com/amosbot/moodle-install 2025-04-24 22:04:55 +07:00
sam marshall f6c1e82a52 MDL-83628 message: message_provider_uninstall slow
This function was slow because using case-insensitive LIKE on the large
user_preferences table means that Postgres does not use its index and
has to sequential-scan the table.
2025-04-24 13:04:53 +01:00
Paul Holden 2373f73a90 MDL-84192 course: update course information page language string.
The previous version used an incorrectly deprecated summary string.
2025-04-24 11:53:33 +01:00
danghieu1407 216b5230be MDL-84071 gradereport_singleview: Rewrite singleview to native JS 2025-04-24 15:26:14 +07:00
Huong Nguyen bcdb8f90d8 Merge branch 'MDL-84480' of https://github.com/paulholden/moodle 2025-04-24 07:26:16 +02:00
Sara Arjona b425f88ec1 Merge branch 'MDL-84233_main' of https://github.com/catalyst/moodle 2025-04-24 07:26:16 +02:00
Huong Nguyen 7deb91a7b7 Merge branch 'MDL-83563' of https://github.com/larsbonczek/moodle 2025-04-24 07:26:15 +02:00
Huong Nguyen e19acad10a Merge branch 'MDL-84442-metadata-task-logs' of https://github.com/bwalkerl/moodle 2025-04-24 07:25:18 +02:00
Huong Nguyen d0af3ec6eb Merge branch 'MDL-85202' of https://github.com/paulholden/moodle 2025-04-24 07:25:18 +02:00
David Woloszyn 74d8cb51a6 MDL-84274 tool_policy: Policy acceptance pages use secure layout 2025-04-24 11:54:42 +10:00
David Woloszyn 017209e1eb MDL-84274 tool_mfa: Prevent tool_policy pages from redirecting 2025-04-24 10:55:19 +10:00
AMOS bot 7d290f3006 Automatically generated installer lang files 2025-04-24 00:07:58 +00:00
Paul Holden e395fe3a9a MDL-85264 output: fix form change checker when switching tabs.
During the Bootstrap 5.0 upgrade the event handling within dynamic
tabs appears to have changed such that the "click" event happens
too late for the form change checker module to determine whether
there were any "dirty" forms on the tab being switched from.

This is related to, although not specifically caused by, changes
made in 0c586b41.
2025-04-23 18:03:30 +01:00
Jayce 6a9d93754c MDL-84964 mod_glossary: min width only apply for large device 2025-04-23 09:56:34 +09:30
Sara Arjona c03f9897ea Merge branch 'MDL-82658' of https://github.com/paulholden/moodle 2025-04-22 16:46:22 +02:00
Sara Arjona 4459de5cfb Merge branch 'MDL-84807-main' of https://github.com/davewoloszyn/moodle 2025-04-22 16:43:26 +02:00
Daniel Ziegenberg 19a53d8a09 MDL-77307 gradereport_grader: Final removal of grade report functions
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-04-22 16:32:27 +02:00
Daniel Ziegenberg fb5a609b4c MDL-77307 core_grades: Final removal of grade functions
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-04-22 16:32:21 +02:00
ferran 7f76a2b626 MDL-84641 mod_workshop: add human date to overview 2025-04-22 16:03:22 +02:00
ferran 10d2d31536 MDL-84641 mod_feedback: add human date to overview 2025-04-22 16:03:22 +02:00
ferran 7a4210c6f1 MDL-84641 mod_assign: add human date to overview 2025-04-22 16:03:22 +02:00
ferran 983bd7e69c MDL-85107 calendar: fix humandate year display 2025-04-22 10:20:36 +02:00
Huong Nguyen be5cfe2a65 Merge branch 'MDL-85182-main' of https://github.com/lucaboesch/moodle 2025-04-22 10:08:57 +07:00
Huong Nguyen 4142c1a0ca Merge branch 'MDL-84070-user-pref-race-bug-v2' of https://github.com/brendanheywood/moodle 2025-04-22 08:37:48 +07:00
Benjamin Walker 3690e8c770 MDL-84442 core_task: Add finalise log param to task failers 2025-04-22 09:28:29 +10:00
Brendan Heywood b80724abf3 MDL-84070 core: Fix race conditions setting user preferences 2025-04-21 21:41:09 +10:00
Huong Nguyen 1347e088bc Merge branch 'mdl-83262_main' of https://github.com/james-cnz/moodle 2025-04-21 09:12:23 +07:00
Stefan Hanauska 2cc6e875b7 MDL-83111 tool_recyclebin: Avoid null value 2025-04-18 07:15:22 +02:00
Stefan Hanauska ee6fcd3953 MDL-82381 report: Show group select in all courses 2025-04-18 07:05:50 +02:00
Stefan Hanauska c5f3af8ccd MDL-84781 format_singleactivity: Sort activity types by name 2025-04-18 07:03:58 +02:00
Luca Bösch 3b7760b93d MDL-85182 block_myoverview: Fix choice active item indicator spacing 2025-04-17 17:09:11 +02:00
Tasio aacdf63823 MDL-85222 themes: Remove grey zebra-striping background on reports
Only removing the grey background in small sceens when
the table is displayed as an accordion

Co-authored-by: Mikel Martín Corrales <mikel@moodle.com>
2025-04-17 15:44:53 +02:00
Sara Arjona c576443111 weekly on-sync release 5.1dev 2025-04-17 14:30:27 +02:00
Sara Arjona d7cd69df64 NOBUG: Add upgrade notes 2025-04-17 14:30:27 +02:00
Huong Nguyen ee06d98bb5 Merge branch 'MDL-84298' of https://github.com/paulholden/moodle 2025-04-17 10:50:59 +07:00
Huong Nguyen 36e652f7b8 Merge branch 'MDL-84625_close-recordset-in-core_analytics-model-add_prediction_ids' of https://github.com/ziegenberg/moodle 2025-04-17 10:27:39 +07:00
Huong Nguyen 6ba620a442 Merge branch '83713-javascript-error-xml-grades-import-main' of https://github.com/DSI-Universite-Rennes2/moodle 2025-04-17 10:11:31 +07:00
Huong Nguyen 00940881bb Merge branch 'MDL-84232-avoid_recover_quiz_grades' of https://github.com/drobayo/moodle 2025-04-17 08:38:27 +07:00
James C e53370ceb9 MDL-83262 course: Refresh all-sections toggler on section delete 2025-04-17 12:53:32 +12:00
Paul Holden f526ad153c MDL-85208 core: switch to ARIA attribute to label table headings.
Since ad14d58d visually hidden text within tables was displayed as
block elements, which introduced artificial line breaks in headings
for column names and sorting icons.

Co-authored-by: Mikel Martín <mikel@moodle.com>
2025-04-16 21:25:00 +01:00
Paul Holden 23c8c0657e MDL-85216 reportbuilder: allow pixicon to be passed to report actions. 2025-04-16 20:16:49 +01:00
Daniel Ziegenberg e70c3c3d4a MDL-80455 core_badges: Final removal of core_badges_renderer functions
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-04-16 20:48:13 +02:00
Julien Boulen cac0184d64 MDL-83713 form: Fix javascript selector on file picker
Co-authored-by: Meirza <meirza.arson@moodle.com>
2025-04-16 16:46:38 +02:00
Daniel Ziegenberg 5b404a92ae MDL-78091 core_quiz: initial deprecation add_random_form and associates
The just removed mod_quiz\form\add_random_form was the only place in
core where the mod_quiz/add_random_form javascript was called, so we can
deprecate this now. This also enables us to deprecate the
mod_quiz/random_question_form_preview javascript and the
mod_quiz/random_question_form_preview_question_list template as they are
direct dependends.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-04-16 15:44:58 +02:00
Daniel Ziegenberg e927dc51ad MDL-78091 core_question: initial deprecation render_question_pagination
Rendering the question pagination is now done via ajax based pagination.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-04-16 15:44:56 +02:00
Daniel Ziegenberg 0dc5c2e14c MDL-78091 core_question: final deprecations
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-04-16 15:44:54 +02:00
Daniel Ziegenberg b784342fa8 MDL-78091 core_quiz: final deprecations
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-04-16 15:44:50 +02:00
Sara Arjona f9dc4b051d Merge branch 'MDL-84820' of https://github.com/paulholden/moodle 2025-04-16 15:24:31 +02:00
Sara Arjona 7c8b02b34c Merge branch 'MDL-85170-main' of https://github.com/aanabit/moodle 2025-04-16 15:11:59 +02:00
ferran 6bee8fa821 MDL-85225 core: fix messaging emoji picker
The emoji picker fails when show template information is enabled. This
patch replaces the template loading to ignore the template comments.
2025-04-16 15:08:13 +02:00
Sara Arjona 1b4ac3a58c Merge branch 'MDL-82132' of https://github.com/paulholden/moodle 2025-04-16 14:54:49 +02:00
Huong Nguyen ff60e9e7b6 Merge branch 'MDL-83195-releaseanongradev2' of https://github.com/leonstr/moodle 2025-04-16 09:39:03 +07:00
Paul Holden 88a3f90e89 MDL-82132 user: less restrictive returning first/lastname details.
The `viewfullnames` capability check was overeager in restricting
the inclusion of user first and lastname properties in the returned
structure. Especially given that the same data was almost always
present in the fullname property of the same structure.
2025-04-15 16:00:46 +01:00
Paul Holden 9300828cee MDL-82132 user: re-factor code for generating dummy user fullname. 2025-04-15 16:00:46 +01:00
Sara Arjona 8661fe8d8b Merge branch 'MDL-84149' of https://github.com/paulholden/moodle 2025-04-15 16:44:54 +02:00
Sara Arjona 3e1024dd06 Merge branch 'MDL-84140' of https://github.com/paulholden/moodle 2025-04-15 16:30:54 +02:00
Sara Arjona db63c6faa2 Merge branch 'MDL-83990' of https://github.com/paulholden/moodle 2025-04-15 16:18:00 +02:00
Sara Arjona fb2a5bb129 Merge branch 'MDL-83537' of https://github.com/paulholden/moodle 2025-04-15 16:08:59 +02:00
Jun Pataleta 69e207daa3 Merge branch 'MDL-83979-url-always-proxy' of https://github.com/brendanheywood/moodle 2025-04-15 20:38:30 +08:00
Daniel Ziegenberg fe96f303b4 MDL-76612 mod_quiz: Final deprecations 2025-04-15 14:33:10 +02:00
Sara Arjona 792a272d8a Merge branch 'MDL-55034' of https://github.com/paulholden/moodle 2025-04-15 13:36:16 +02:00
Huong Nguyen dfc07d34cb Merge branch 'MDL-85207-main' of https://github.com/sarjona/moodle 2025-04-15 18:30:21 +07:00
Sara Arjona 095d4c6539 Merge branch 'MDL-78381' of https://github.com/paulholden/moodle 2025-04-15 11:36:31 +02:00
Sara Arjona 77a3d9496b Merge branch 'MDL-80337' of https://github.com/paulholden/moodle 2025-04-15 11:30:09 +02:00
Melanie Treitinger d8ce093322 MDL-85003 course: Provide more data for the course request mail 2025-04-15 11:25:40 +02:00
Sara Arjona 16afcb7936 MDL-85207 glossary: Add missing step for autolink behat test 2025-04-15 10:34:00 +02:00
Huong Nguyen 3cbbd0d3af Merge branch 'MDL-85179-main' of https://github.com/lucaboesch/moodle 2025-04-15 08:57:00 +07:00
Huong Nguyen accfde5bac Merge branch 'MDL-85195-main' of https://github.com/lucaboesch/moodle 2025-04-15 08:54:35 +07:00
Sara Arjona 161e98c244 Merge branch 'MDL-62230' of https://github.com/paulholden/moodle 2025-04-14 18:56:54 +02:00
Sara Arjona ce1f80aca3 Merge branch 'MDL-81454-main' of https://github.com/daniil-berg/moodle 2025-04-14 18:45:58 +02:00
Paul Holden a2016d0d1a MDL-55034 blog: update external blog deletion to not leak sesskey. 2025-04-14 17:38:52 +01:00
Paul Holden 6eeadc5eff MDL-85202 core: update list of stale files for 5.0 release. 2025-04-14 17:06:12 +01:00
Sara Arjona cecf53b937 Merge branch 'MDL-83550-main' of https://github.com/andrewgos/moodle 2025-04-14 17:54:16 +02:00
Sara Arjona cfcef9f2f6 Merge branch 'MDL-78886-main' of https://github.com/mwehr/moodle 2025-04-14 17:49:57 +02:00
Sara Arjona f808b2e622 Merge branch 'MDL-66584-master' of https://github.com/danghieu1407/moodle 2025-04-14 17:47:29 +02:00
Wehr Mario a63c87b689 MDL-78886 assignfeedback_editpdf: Fix broken next page button in PDFView
Credits go to Cédric Gerbault cdgerbault@gmail.com for providing the fix.
2025-04-14 17:32:28 +02:00
Sara Arjona 7b940d6cfc Merge branch 'MDL-84833-main' of https://github.com/ferranrecio/moodle 2025-04-14 17:10:53 +02:00
Sara Arjona a2ddc972c5 Merge branch 'MDL-79464-main' of https://github.com/mihailges/moodle 2025-04-14 17:08:19 +02:00
Sara Arjona f17ab58482 Merge branch 'MDL-84937' of https://github.com/jfederico/moodle 2025-04-14 17:01:14 +02:00
Paul Holden caddb3c628 MDL-85196 badges: report entity filter for badge language. 2025-04-14 12:12:07 +01:00
Luca Bösch b79ce1ea00 MDL-85195 block_myoverview: colour the button as in Bootstrap 4. 2025-04-14 12:01:18 +02:00
Mikel Martín 59504bb79b MDL-85141 theme_boost: Move print styles to print.scss 2025-04-14 11:30:44 +02:00
ferran d92e7a32c8 MDL-84833 course: completion feedback messages 2025-04-14 10:56:09 +02:00
Daniel Ziegenberg f2fc029bf1 MDL-84625 analytics: close recordset when it's not needed anymore
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2025-04-14 10:01:40 +02:00
Huong Nguyen 06d09a857f Merge branch 'MDL-85187-main' of https://github.com/junpataleta/moodle 2025-04-14 09:31:20 +07:00
Huong Nguyen fabd3ead87 Merge branch 'MDL-85186-main' of https://github.com/junpataleta/moodle 2025-04-14 08:58:07 +07:00
James C ea35e54203 MDL-84520 course: CM anchor scrolls to specified CM 2025-04-14 12:21:56 +12:00
Jun Pataleta 245cce7f85 MDL-85187 upgrade: Add the 5.0.0 separation line to all upgrade scripts 2025-04-13 18:42:19 +08:00
Jun Pataleta f679e7d07a MDL-85186 backup: Bump release to 5.1 2025-04-13 18:31:09 +08:00
Jun Pataleta bf164840d9 weekly back-to-dev release 5.1dev 2025-04-13 10:04:21 +08:00
Luca Bösch 9660fd7cc9 MDL-85179 mod_data: colour the buttons upon creation as in Bootstrap 4. 2025-04-12 09:06:56 +02:00
Amaia Anabitarte f4e0bf6b50 MDL-85170 mod_choice: Remove the unnecessary ul closing tag 2025-04-11 17:15:18 +02:00
Alec Gullon 7f708eaff9 MDL-79464 mod_assign: Limit user navigation if grading fails validation 2025-04-10 16:27:24 +08:00
Daniil Fajnberg b41bf2f579 MDL-81454 core: Remove incorrect @property-read annotation 2025-04-09 08:59:59 +02:00
jfederico dba1bdaceb MDL-84937 mdl_bigbluebuttonbn: Hide Settings for RecordingsOnly 2025-04-08 18:28:44 +00:00
Paul Holden a7a91723fc MDL-82658 mod_forum: calculate maxbytes correctly in reply handler. 2025-04-07 09:38:28 +01:00
Paul Holden 52b33e8759 MDL-84149 gradereport_grader: better support for collapse preferences.
The privacy provider is now resilient against missing courses, and also
supports retrieving preferences from multiple courses for the user.
2025-04-07 09:37:33 +01:00
David Woloszyn 10708c7c93 MDL-84807 AI: Remove records on provider uninstall 2025-03-31 11:17:48 +11:00
Paul Holden 90e06e0851 MDL-84140 course: more resilient check for activity footer component. 2025-03-27 08:32:50 +00:00
toanlamt b4a35b50d4 MDL-84982 tiny_media: Fix excessive data passed to the usedfiles JS file 2025-03-26 13:42:36 +07:00
danghieu1407 d792c4916a MDL-66584 qtype_ddimageortext: Move JSON data to data-attribute 2025-03-25 16:48:52 +07:00
Paul Holden 5de6165783 MDL-84983 core: account for invalid locales in intl extension.
Recent PHP versions are now stricter on the `$locale` value passed
to `IntlDateFormatter` class and will throw exceptions for invalid
values (some of which may be present in our language packs).

See: https://github.com/php/php-src/issues/12912
2025-03-24 15:29:42 +00:00
Paul Holden 3152af3513 MDL-84941 course: fix activity button label on end of section.
Where the button is rendered after all section content, we should
fix the ARIA label attribute to refer to the current section rather
than non-existing subsequent activity.
2025-03-19 19:16:52 +00:00
Paul Holden 1b2ffbab58 MDL-84820 moodlenet: correct activity modal icon size/alignment. 2025-03-19 10:05:14 +00:00
Andrew Gosali 6183549b77 MDL-84539 report_participation: use capability viewanonymousevents 2025-03-18 11:32:02 +07:00
Andrew Gosali f846c47ecf MDL-83550 gradingform_rubric: fix submit no grade when remark disabled 2025-03-17 14:49:35 +07:00
Paul Holden f08bcbe003 MDL-80337 availability: more robust checking for plugin class presence.
Co-authored-by: Dustin Brisebois <dustin.brisebois@lambdasolutions.net>
2025-03-16 19:27:22 +00:00
Paul Holden 5a0f4527d8 MDL-83990 course: ensure course start/end dates set in external call. 2025-03-13 17:53:40 +00:00
Paul Holden 09c191aefd MDL-83537 check: confirm presence of instance action link. 2025-03-13 17:52:36 +00:00
danghieu1407 dd7113a212 MDL-84708 question: Fixing layout answer box issue causing images 2025-03-13 10:30:02 +07:00
Jun Pataleta 25e481a6f9 MDL-79756 mod_scorm: Deprecate SCORM report generate_master_checkbox() 2025-03-12 13:32:29 +08:00
Jun Pataleta 6bae5f0f36 MDL-79756 core: Update usages of core/checkbox_toggleall
* Use appropriate selectors, variable names for target and
  toggler checkboxes and renamed method.

# Conflicts:
#	grade/edit/tree/lib.php
2025-03-12 13:32:22 +08:00
Jun Pataleta 7b726d6c46 MDL-79756 core: Make core/checkbox-toggleall more inclusive
* Refer to `master` checkboxes as `toggler` checkboxes.
* Refer to `slave` checkboxes as `target` checkboxes.
* Deprecate `master` and `slave` core/checkbox-toggleall templates and
  replace them with `toggler` and `target` templates.
* Deprecate usage of `data-toggle=master` and `data-toggle=slave`,
  replacing them with `data-toggle=toggler` and `data-toggle=target`
  while providing backwards compatibility to prevent breaking current
  usages.
* Deprecate `updateSlavesFromMasterState()` and replace with
  `updateTargetsFromTogglerState()`.
2025-03-12 13:31:27 +08:00
Paul Holden c7620b00a1 MDL-78381 course: observe default "showactivitydates" in external call. 2025-03-11 17:13:16 +00:00
Paul Holden bdac9acd10 MDL-84787 calendar: restore course-specific management page parameter. 2025-03-11 13:31:45 +00:00
Lars Bonczek 0b917eeac4 MDL-83563 form: Fix hideIf and disabledIf dependent on multiselects 2025-03-11 12:19:10 +01:00
Paul Holden 705d8e3471 MDL-84480 files: correct text formatting params when filtering files. 2025-03-11 10:29:58 +00:00
Nathan Nguyen 02c53f0afa MDL-84233 core_user: fix unit test 2025-03-07 16:48:02 +11:00
Dagoberto Robayo b62efe64fa MDL-84232 mod_quiz: Avoid recover grades in quiz view page
- If Recover grades default is not enabled, quiz grades should not be recover.
2025-03-05 15:24:18 -05:00
Paul Holden 0d487fd8de MDL-62230 mod_feedback: define exporter format for name/presentation. 2025-03-04 14:12:56 +00:00
Paul Holden 2a260b33d9 MDL-84298 mod_assign: target only first label for grade popout button. 2025-02-24 22:21:00 +00:00
Paul Holden a3bc1008e8 MDL-84597 blog: confirm blogs enabled prior to settings nav access. 2025-02-24 12:51:47 +00:00
Leon Stringer bec8c1a664 MDL-83195 mod_assign: Individual grade release
Fix pushing individual grades into the gradebook (as opposed to the
batch release of grades) when "Allow partial release of grades while
marking anonymously" is enabled.

This change reworks MDL-73626's fix for the same issue for releasing
multiple grades in a batch operation.
2025-02-14 12:16:26 +00:00
Andrew Nicols 9fce489ccf MDL-84421 tool_uploadcourse: Stop MUC caching enrol instances
We should not normally cache instances of a class. This can lead to poor
design to work around the limitations of PHP Serialization, and could
theoretically cause issues with PHP versions changing within a Moodle
version.
2025-02-04 22:12:34 +08:00
Brendan Heywood edea4a41af MDL-83979 repository_url: Always use the proxy for url downloads 2024-12-11 13:35:01 +11:00
31931 changed files with 691658 additions and 653878 deletions
+1 -1
View File
@@ -113,7 +113,7 @@ jobs:
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
php public/admin/tool/phpunit/cli/init.php --no-composer-self-update
- name: Run PHPUnit test (one by one)
env:
+5 -5
View File
@@ -19,7 +19,7 @@ env:
jobs:
Grunt:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Checking out code
@@ -61,12 +61,12 @@ jobs:
matrix:
include:
# MySQL builds always run with the lowest PHP supported version.
- os: ubuntu-22.04
- os: ubuntu-24.04
php: 8.2
extensions:
db: mysqli
# PostgreSQL builds always run with the highest PHP supported version.
- os: ubuntu-22.04
- os: ubuntu-24.04
php: 8.4
db: pgsql
@@ -88,7 +88,7 @@ jobs:
if: ${{ matrix.db == 'pgsql' }}
uses: m4nu56/postgresql-action@v1
with:
postgresql version: 14
postgresql version: 15
postgresql db: test
postgresql user: test
postgresql password: test
@@ -115,7 +115,7 @@ jobs:
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
php public/admin/tool/phpunit/cli/init.php --no-composer-self-update
- name: Running PHPUnit tests
env:
+1 -1
View File
@@ -140,7 +140,7 @@ jobs:
echo "pathtophp=$(which php)" >> $GITHUB_ENV # Inject installed pathtophp to env. The template config needs it.
cp .github/workflows/config-template.php config.php
mkdir ../moodledata
php admin/tool/phpunit/cli/init.php --no-composer-self-update
php public/admin/tool/phpunit/cli/init.php --no-composer-self-update
- name: Running PHPUnit tests
env:
+4 -4
View File
@@ -43,9 +43,9 @@ composer.phar
/vendor/
/behat.yml
*/yui/build/*/*-coverage.js
/lib/yuilib/*/build/*/*-coverage.js
/public/lib/yuilib/*/build/*/*-coverage.js
# lib/yuilib/version/module/module-coverage.js
/lib/yuilib/*/*/*-coverage.js
/public/lib/yuilib/*/*/*-coverage.js
atlassian-ide-plugin.xml
/node_modules/
/.vscode/
@@ -53,8 +53,8 @@ moodle-plugin-ci.phar
.eslintignore
.stylelintignore
/jsdoc
/admin/tool/componentlibrary/docs
/admin/tool/componentlibrary/hugo/site/data/my-index.json
/public/admin/tool/componentlibrary/docs
/public/admin/tool/componentlibrary/hugo/site/data/my-index.json
.hugo_build.lock
phpcs.xml
jsconfig.json
+9 -6
View File
@@ -47,7 +47,7 @@ const fetchComponentData = () => {
const components = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/components.json`));
const pluginData = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/plugins.json`));
componentData.pluginTypes = components.plugintypes;
componentData.pluginTypes = components.plugintypes
const standardPlugins = Object.entries(pluginData.standard).map(
([pluginType, pluginNames]) => {
@@ -56,18 +56,21 @@ const fetchComponentData = () => {
).reduce((acc, val) => acc.concat(val), []);
// Build the list of moodle subsystems.
componentData.subsystems.lib = 'core';
componentData.pathList.push(process.cwd() + path.sep + 'lib');
componentData.subsystems['public/lib'] = 'core';
componentData.pathList.push(`${process.cwd()}/public/lib`);
for (const [component, thisPath] of Object.entries(components.subsystems)) {
if (thisPath) {
// Prefix "core_" to the front of the subsystems.
componentData.subsystems[thisPath] = `core_${component}`;
componentData.pathList.push(process.cwd() + path.sep + thisPath);
componentData.pathList.push(`${process.cwd()}/${thisPath}`);
}
}
// The list of components includes the list of subsystems.
componentData.components = {...componentData.subsystems};
componentData.components = Object.fromEntries(
Object.entries(componentData.subsystems)
.map(([path, name]) => ([path, name]))
);
const subpluginAdder = (subpluginType, subpluginTypePath) => {
glob.sync(`${subpluginTypePath}/*/version.php`).forEach(versionPath => {
@@ -104,7 +107,7 @@ const fetchComponentData = () => {
});
} else if (subpluginList.plugintypes) {
Object.entries(subpluginList.plugintypes).forEach(([subpluginType, subpluginTypePath]) => {
subpluginAdder(subpluginType, subpluginTypePath);
subpluginAdder(subpluginType, `public/${subpluginTypePath}`);
});
}
}
+1 -1
View File
@@ -217,7 +217,7 @@ const getInitialMessageValue = (options) => {
export const getCurrentVersion = async () => {
const versionRegex = new RegExp(/^ *\$release *= *['\"](?<release>[^ \+]+\+?) *\(Build:.*/m);
try {
const versionFile = await readFile('version.php', 'utf8');
const versionFile = await readFile('public/version.php', 'utf8');
const match = versionFile.match(versionRegex);
if (match) {
return match.groups.release;
+58
View File
@@ -0,0 +1,58 @@
#!/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 { getAllComponents } from './components.mjs';
import { getCombinedNotesByComponent } from './note.mjs';
import logger from './logger.mjs';
import { existsSync } from 'fs';
/**
* Generate links to component-specific upgrade notes for each component.
*
* @param {string|undefined} tag The git tag to link to
* @returns {Promise<void>}
*/
export default async (tag) => {
const notes = await getCombinedNotesByComponent();
if (Object.keys(notes).length === 0) {
logger.warn('No notes to generate');
return;
}
if (!tag) {
logger.error('No tag provided');
return;
}
// Generate the links for the components which have upgrade notes in this release.
let upgradeNotes = `### Component API updates\n<!--cspell: disable -->\n\n`;
const componentList = Object.fromEntries(
Object.values(getAllComponents()).map(({path, value}) => [value, path]),
);
Object.entries(notes)
.map(([component]) => ({
component,
componentPath: componentList[component],
}))
.filter(({ componentPath }) => existsSync(`./${componentPath}/UPGRADING.md`))
.forEach(({component, componentPath}) => {
upgradeNotes += `- [${component}](https://github.com/moodle/moodle/blob/${tag}/${componentPath}/UPGRADING.md)\n`;
});
console.log(upgradeNotes);
};
+2 -2
View File
@@ -30,7 +30,7 @@ module.exports = grunt => {
* @param {string} path
* @returns {string}
*/
const getCLPath = path => `admin/tool/componentlibrary/${path}`;
const getCLPath = path => `public/admin/tool/componentlibrary/${path}`;
/**
* Get a spawn handler.
@@ -97,7 +97,7 @@ module.exports = grunt => {
'--source-map',
'--embed-sources',
'--precision', 6,
'--load-path', process.cwd(),
'--load-path', `${process.cwd()}/public`,
getCLPath('hugo/scss/docs.scss'),
getCLPath('hugo/dist/css/docs.css'),
]);
+3 -3
View File
@@ -84,10 +84,10 @@ module.exports = grunt => {
const stylelintIgnores = [
'# Generated by "grunt ignorefiles"',
'**/yui/build/*',
'theme/boost/style/moodle.css',
'theme/classic/style/moodle.css',
'public/theme/boost/style/moodle.css',
'public/theme/classic/style/moodle.css',
'jsdoc/styles/*.css',
'admin/tool/componentlibrary/hugo/dist/css/docs.css',
'public/admin/tool/componentlibrary/hugo/dist/css/docs.css',
].concat(thirdPartyPaths);
grunt.file.write('.stylelintignore', stylelintIgnores.join('\n') + '\n');
+2 -2
View File
@@ -43,8 +43,8 @@ module.exports = (grunt) => {
const componentData = fetchComponentData().components;
for (const [thisPath, component] of Object.entries(componentData)) {
jsconfigData.compilerOptions.paths[`${component}/*`] = [`${thisPath}/amd/src/*`];
jsconfigData.include.push(`${thisPath}/amd/src/**/*`);
jsconfigData.compilerOptions.paths[`${component}/*`] = [`public/${thisPath}/amd/src/*`];
jsconfigData.include.push(`public/${thisPath}/amd/src/**/*`);
}
grunt.file.write('jsconfig.json', JSON.stringify(jsconfigData, null, " ") + "\n");
+6 -3
View File
@@ -27,13 +27,16 @@ module.exports = grunt => {
sass: {
dist: {
files: {
"theme/boost/style/moodle.css": "theme/boost/scss/preset/default.scss",
"theme/classic/style/moodle.css": "theme/classic/scss/classicgrunt.scss"
"public/theme/boost/style/moodle.css": "public/theme/boost/scss/preset/default.scss",
"public/theme/classic/style/moodle.css": "public/theme/classic/scss/classicgrunt.scss"
}
},
options: {
implementation: require('sass'),
includePaths: ["theme/boost/scss/", "theme/classic/scss/"]
includePaths: [
"public/theme/boost/scss/",
"public/theme/classic/scss/",
]
}
},
});
+8
View File
@@ -20,6 +20,7 @@ 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 generateReleaseNotesLinks from './notes/src/releasenotes.mjs';
import logger from './notes/src/logger.mjs';
console.log(`
@@ -74,6 +75,13 @@ program
new Argument('[version]', 'The Moodle version to create the summary notes for')
)
.action((version) => generateAction(version));
program
.command('releasenotes')
.summary('Generate a list of upgrade notes for individual components in markdown format for the release notes')
.addArgument(
new Argument('[tag]', 'The Moodle tag')
)
.action((tag) => generateReleaseNotesLinks(tag));
program
.command('release')
+2 -2
View File
@@ -81,7 +81,7 @@ const setupMoodleEnvironment = grunt => {
let scssSrc = [];
const checkComponentDirectory = componentDirectory => {
const isTheme = componentDirectory.startsWith('theme/');
const isTheme = componentDirectory.startsWith('public/theme/');
if (isTheme) {
const scssDirectory = `${componentDirectory}/scss`;
@@ -153,7 +153,7 @@ const setupMoodleEnvironment = grunt => {
const relativeCwd = path.relative(gruntFilePath, cwd);
const componentDirectory = ComponentList.getOwningComponentDirectory(relativeCwd);
const inComponent = !!componentDirectory;
const inTheme = !!componentDirectory && componentDirectory.startsWith('theme/');
const inTheme = !!componentDirectory && componentDirectory.startsWith('public/theme/');
const runDir = inComponent ? componentDirectory : relativeCwd;
const fullRunDir = fs.realpathSync(gruntFilePath + path.sep + runDir);
const {inAMD, amdSrc} = getAmdConfiguration();
+913
View File
@@ -6,6 +6,919 @@ More detailed information on key changes can be found in the [Developer update n
The format of this change log follows the advice given at [Keep a CHANGELOG](https://keepachangelog.com).
## 5.1
### core
#### Added
- The following classes have been renamed and now support autoloading.
Existing classes are currently unaffected.
| Old class name | New class name |
| --- | --- |
| `\breadcrumb_navigation_node` | `\core\navigation\breadcrumb_navigation_node` |
| `\flat_navigation_node` | `\core\navigation\flat_navigation_node` |
| `\flat_navigation` | `\core\navigation\flat_navigation_node` |
| `\global_navigation_for_ajax` | `\core\navigation\global_navigation_for_ajax` |
| `\global_navigation` | `\core\navigation\global_navigation` |
| `\navbar` | `\core\navigation\navbar` |
| `\navigation_cache` | `\core\navigation\navigation_cache` |
| `\navigation_json` | `\core\navigation\navigation_json` |
| `\navigation_node_collection` | `\core\navigation\navigation_node_collection` |
| `\navigation_node` | `\core\navigation\navigation_node` |
| `\settings_navigation_for_ajax` | `\core\navigation\settings_navigation_for_ajax` |
| `\settings_navigation` | `\core\navigation\settings_navigation` |
For more information see [MDL-82159](https://tracker.moodle.org/browse/MDL-82159)
- - Added is_site_registered_in_hub method in lib/classes/hub/api.php to
check if the site is registered or not.
- Added get_secret method in lib/classes/hub/registration.php to get site's secret.
For more information see [MDL-83448](https://tracker.moodle.org/browse/MDL-83448)
- Added a new optional param to adhoc_task_failed and scheduled_task_failed to allow skipping log finalisation when called from a separate task.
For more information see [MDL-84442](https://tracker.moodle.org/browse/MDL-84442)
- Add a new method has_valid_group in \core\report_helper that will return true or false depending if the user has a valid group. This is mainly false in case the user is not in any group in SEPARATEGROUPS. Used in report_log and report_loglive
For more information see [MDL-84464](https://tracker.moodle.org/browse/MDL-84464)
- There is a new `core/page_title` Javascript module for manipulating the current page title
For more information see [MDL-84804](https://tracker.moodle.org/browse/MDL-84804)
- Added support for configurable `aspectRatio` in charts rendered using Chart.js. This enables developers to control chart sizing more precisely via the `chart_base` API and the frontend renderer.
For more information see [MDL-85158](https://tracker.moodle.org/browse/MDL-85158)
- Output classes can now implement the core\output\externable interface. This allows these classes to define methods for exporting their data in a format suitable for use in web services.
For more information see [MDL-85509](https://tracker.moodle.org/browse/MDL-85509)
- The following functions have been replaced with class methods.
| Old function name | New method name |
| --- | --- |
| `\ajax_capture_output()` | `\core\ajax::capture_output()` |
| `\ajax_check_captured_output()` | `\core\ajax::check_captured_output()` |
It is no longer necessary to include `lib/ajax/ajaxlib.php` in any code.
For more information see [MDL-86168](https://tracker.moodle.org/browse/MDL-86168)
- The Behat `::execute()` method now accepts an array-style callable in addition to the string `classname::method` format.
The following formats are now accepted:
```php
// String format:
$this->execute('behat_general::i_click_on', [...]);
// Array format:
$this->execute([behat_general::class,' i_click_on'], [...]);
```
For more information see [MDL-86231](https://tracker.moodle.org/browse/MDL-86231)
- The following classes have been moved into namespaces and now support autoloading:
| Old class name | New class name |
| --- | --- |
| `\core_xml_parser` | `\core\xml_parser` |
| `\xml_format_exception` | `\core\exception\xml_format_exception` |
For more information see [MDL-86256](https://tracker.moodle.org/browse/MDL-86256)
- The `\externallib_advanced_testcase` has been replaced by `\core_external\tests\externallib_testcase` and is now autoloadable.
For more information see [MDL-86283](https://tracker.moodle.org/browse/MDL-86283)
#### Changed
- Changes were implemented to make `checkbox-toggleall` output component more inclusive:
* Replace the references to `master` checkboxes with `toggler`.
* Replace the references to `slave` checkboxes with `target`.
For more information see [MDL-79756](https://tracker.moodle.org/browse/MDL-79756)
- The `\core\attribute\deprecated` attribute constructor `$replacement` parameter now defaults to null, and can be omitted
For more information see [MDL-84531](https://tracker.moodle.org/browse/MDL-84531)
- The `core_plugin_manager::plugintype_name[_plural]` methods now require language strings for plugin types always be defined via `type_<type>` and `type_<type>_plural` language strings
For more information see [MDL-84948](https://tracker.moodle.org/browse/MDL-84948)
- Added a new `\core\deprecation::emit_deprecation()` method which should be used in places where a deprecation is known to occur. This method will throw debugging if no deprecation notice was found, for example:
```php
public function deprecated_method(): void {
\core\deprecation::emit_deprecation([self::class, __FUNCTION__]);
}
```
For more information see [MDL-85897](https://tracker.moodle.org/browse/MDL-85897)
- The `\core\output\local\dropdown\dialog` class constructor now accepts a `$definition['autoclose']` parameter to define autoclose behaviour of the element
For more information see [MDL-86015](https://tracker.moodle.org/browse/MDL-86015)
- The default PHPUnit configuration now enables the following properties, ensuring PHP warnings will cause test failures (restoring pre-PHPUnit version 10 behaviour):
* `failOnDeprecation`
* `failOnWarning`
For more information see [MDL-86311](https://tracker.moodle.org/browse/MDL-86311)
#### Deprecated
- The following function has been deprecated and should no longer be used: `file_encode_url`. Please consider using the `core\url` factory methods instead.
For more information see [MDL-31071](https://tracker.moodle.org/browse/MDL-31071)
- The following `core/checkbox-toggleall` templates have been deprecated:
- `core/checkbox-toggleall-master-button` - This is replaced with `core/checkbox-toggleall-toggler-button`
- `core/checkbox-toggleall-master` - This is replaced with `core/checkbox-toggleall-toggler`
- `core/checkbox-toggleall-slave` - This is replaced with `core/checkbox-toggleall-target`
The following items in the `core/checkbox-toggleall` JS module have been deprecated:
- Method:
- `updateSlavesFromMasterState()` - This is replaced with `updateTargetsFromTogglerState()`.
- Usage of the following selectors:
- `data-toggle=master` - This is replaced with `data-toggle=toggler`.
- `data-toggle=slave` - This is replaced with `data-toggle=target`.
The usage of these selectors will continue to be supported until they are removed by final deprecation. In the meantime, a deprecation warning in the JavaScript console will be shown if usage of these selectors is detected.
For more information see [MDL-79756](https://tracker.moodle.org/browse/MDL-79756)
- The following global constants have been deprecated in favour of class
constants:
| Old constant | New constant |
| --- | --- |
| `NAVIGATION_CACHE_NAME` | `\core\navigation\navigation_node::CACHE_NAME` |
| `NAVIGATION_SITE_ADMIN_CACHE_NAME` | `\core\navigation\navigation_node::SITE_ADMIN_CACHE_NAME` |
For more information see [MDL-82159](https://tracker.moodle.org/browse/MDL-82159)
- The `user_preference_allow_ajax_update()` has been removed. It was deprecated without replacement in Moodle 4.3.
For more information see [MDL-86168](https://tracker.moodle.org/browse/MDL-86168)
- The `xmlize()` method from `lib/xmlize.php` has been deprecated, please instead use the `\core\xml_parser` class
For more information see [MDL-86256](https://tracker.moodle.org/browse/MDL-86256)
- In toggle.mustache `dataattributes` parameter is deprecated. Use `extraattributes` instead
For more information see [MDL-86990](https://tracker.moodle.org/browse/MDL-86990)
#### Removed
- Final deprecation of device related theme methods. The following two methods have been removed from the core_useragent class:
- core_useragent::get_device_type_theme
- core_useragent::get_device_type_cfg_var_name
For more information see [MDL-78375](https://tracker.moodle.org/browse/MDL-78375)
- Final deprecation of removing the legacy theme settings. The following method has been removed:
- core_useragent::get_device_type_list()
The following classes have been removed:
- core_adminpresets\local\setting\adminpresets_admin_setting_devicedetectregex
- admin_setting_devicedetectregex
For more information see [MDL-79052](https://tracker.moodle.org/browse/MDL-79052)
- Removed `core\hook\manager::is_deprecated_plugin_callback()` in favor of `core\hook\manager::get_hooks_deprecating_plugin_callback()`.
For more information see [MDL-80327](https://tracker.moodle.org/browse/MDL-80327)
### core_admin
#### Added
- - Added `searchmatchtype` property to `admin_settings`
to track search match type.
- Plugins that extend either `admin_settings` or `admin_externalpage`
are encouraged to specify a search match type from the available
types in `admin_search`.
For more information see [MDL-85518](https://tracker.moodle.org/browse/MDL-85518)
### core_ai
#### Added
- Error message handler for AI subsystem.
- Object creation
Use `core_ai\error\factory::create($errorcode, $reason, $errorsource)` to generate the appropriate error object.
- Extensibility
Add new error types by extending `core_ai\error\base` and registering them in the factory.
Please see `core_ai\error\ratelimit` as an example.
For more information see [MDL-83147](https://tracker.moodle.org/browse/MDL-83147)
- - Added `get_enabled_actions_in_course_module` method in public/ai/classes/manager.php to get enabled AI actions in course module. - Added `is_ai_tools_enabled_in_course` method in public/ai/classes/manager.php to check if AI tools is enabled in course. - Added `is_action_enabled_in_context` method in public/ai/classes/manager.php to check if an action is enabled in a particular context. - Added `get_ai_fields_from_course_module` method in public/ai/classes/manager.php to get the AI related fields from the course module. - Added `is_html_editor_placement_available` method in public/ai/placement/editor/classes/utils.php to check if editor placement is enabled. - Added `get_actions_available` method in public/ai/placement/editor/classes/utils.php to get available actions for editor placement.
For more information see [MDL-85738](https://tracker.moodle.org/browse/MDL-85738)
#### Changed
- The method `has_model_settings` inside `core_ai\aimodel\base` is now determined by values returned from a new method called `get_model_settings`.
For more information see [MDL-84779](https://tracker.moodle.org/browse/MDL-84779)
### core_auth
#### Added
- A new method called `get_additional_upgrade_token_parameters` has been added to `oauth2_client` class. This will allow custom clients to override this one and add their extra parameters for upgrade token request.
For more information see [MDL-80380](https://tracker.moodle.org/browse/MDL-80380)
### core_badges
#### Added
- The class core_badges_observer in badges/classes/observer.php has been moved to core_badges\event\observer in badges/classes/event/observer.php. A compatibility layer has been added to maintain backward compatibility, but direct use of the old class name is now deprecated. If you've extended or directly used the old class, you should update your code to use the new namespaced class.
For more information see [MDL-83904](https://tracker.moodle.org/browse/MDL-83904)
- A number of new static methods have been added to `core_badges\backpack_api` to support the new Canvas Credentials backpack provider. These methods allow you to retrieve lists of providers and regions, check if Canvas Credentials fields should be displayed, and get a region URL or API URL based on a given region ID. The new methods include `get_providers`, `get_regions`, `display_canvas_credentials_fields`, `get_region_url`, `get_region_api_url`, `get_regionid_from_url`, and `is_canvas_credentials_region`.
For more information see [MDL-86174](https://tracker.moodle.org/browse/MDL-86174)
#### Removed
- Final removal of core_badges_renderer::render_badge_collection() and core_badges_renderer::render_badge_recipients()
For more information see [MDL-80455](https://tracker.moodle.org/browse/MDL-80455)
### core_block
#### Changed
- Subcontext visibility is now turned on by default when adding blocks. This change makes it much easier to manage blocks, for example, in courses that lack a view page.
For more information see [MDL-85433](https://tracker.moodle.org/browse/MDL-85433)
#### Removed
- Removed block_section_links from Moodle 5.1.
For more information see [MDL-80556](https://tracker.moodle.org/browse/MDL-80556)
### core_comment
#### Added
- The following classes have been renamed and now support autoloading.
Existing classes are currently unaffected.
| Old class name | New class name |
| --- | --- |
| `\comment` | `\core_comment\manager` |
| `\comment_exception` | `\core_comment\comment_exception` |
For more information see [MDL-86254](https://tracker.moodle.org/browse/MDL-86254)
#### Deprecated
- The `public/comment/locallib.php` file and the `comment_manager` class have been deprecated. All related functionality should now be accessed via the `\core_comment\manager` class.
For more information see [MDL-86254](https://tracker.moodle.org/browse/MDL-86254)
- The `public/comment/lib.php` file is now empty and will be removed in Moodle 6.0. Please, do not include in your code anymore.
For more information see [MDL-86254](https://tracker.moodle.org/browse/MDL-86254)
### core_course
#### Added
- The following classes have been renamed and now support autoloading.
Existing classes are currently unaffected.
| Old class name | New class name |
| --- | --- |
| `\course_request` | `\core_course\course_request` |
For more information see [MDL-82322](https://tracker.moodle.org/browse/MDL-82322)
- Activities can now specify an additional purpose in their PLUGINNAME_supports function by using the new FEATURE_MOD_OTHERPURPOSE feature.
For more information see [MDL-85598](https://tracker.moodle.org/browse/MDL-85598)
- Added new `gradable` property to `core_course\local\entity\content_item`
For more information see [MDL-86036](https://tracker.moodle.org/browse/MDL-86036)
- - The following classes have been renamed and now support autoloading.
Existing classes are currently unaffected.
| Old class name | New class name |
| --- | --- |
| `\cm_info` | `\course\cm_info
| `\cached_cm_info` | `\course\cached_cm_info` |
| `\section_info` | `\course\section_info` |
| `\course_modinfo` | `\course\modinfo` |
For more information see [MDL-86155](https://tracker.moodle.org/browse/MDL-86155)
- Removed fictitious `__empty()` magic method.
The `empty()` method does not make use of any `__empty()` method. It is not a
defined magic method.
For more information see [MDL-86155](https://tracker.moodle.org/browse/MDL-86155)
#### Changed
- The 'Show description' checkbox is now present in all course formats. Activity descriptions can be displayed via the Additional activities block (formerly the Main menu block), regardless of whether the course format's has_view_page() function returns false.
For more information see [MDL-85433](https://tracker.moodle.org/browse/MDL-85433)
#### Deprecated
- The core_course_get_course_content_items is now deprecated. Use core_courseformat_get_section_content_items instead.
For more information see [MDL-80295](https://tracker.moodle.org/browse/MDL-80295)
- The course_section_add_cm_control course renderer method is deprecated. Use section_add_cm_controls instead.
For more information see [MDL-80295](https://tracker.moodle.org/browse/MDL-80295)
- Passing the section number (integer) to the core_course\output\activitychooserbutton is deprecated. You must use a core_course\section_info instead.
For more information see [MDL-80295](https://tracker.moodle.org/browse/MDL-80295)
- The getModulesData and activityModules methods from core_course/local/activitychooser/repository are deprecated. Use getSectionModulesData and sectionActivityModules instead
For more information see [MDL-80295](https://tracker.moodle.org/browse/MDL-80295)
- The duplicatesection param in course/view.php is deprecated. Use course/format/update.php with action section_duplicate instead.
For more information see [MDL-84216](https://tracker.moodle.org/browse/MDL-84216)
- The changenumsections.php script is deprecated. Please use course/format/update.php instead.
For more information see [MDL-85284](https://tracker.moodle.org/browse/MDL-85284)
- The `\course\cm_info::$extra` and `\course\cm_info::$score` properties will now
emit appropriate debugging.
These have been deprecated for a long time, but did not emit any debugging.
For more information see [MDL-86155](https://tracker.moodle.org/browse/MDL-86155)
- The `MAX_MODINFO_CACHE_SIZE` constant has been deprecated and replaced with a class constant.
For more information see [MDL-86155](https://tracker.moodle.org/browse/MDL-86155)
- The course renderer method course_activitychooser is now deprecated. Its logic is not part of the new section_renderer::add_cm_controls method.
For more information see [MDL-86337](https://tracker.moodle.org/browse/MDL-86337)
#### Removed
- The activitychoosertabmode setting has been removed. Consider implementing your own setting in your theme if needed.
For more information see [MDL-85533](https://tracker.moodle.org/browse/MDL-85533)
### core_courseformat
#### Added
- From now on, the activity chooser will use core_courseformat_get_section_content_items to get the available modules for a specific section
For more information see [MDL-80295](https://tracker.moodle.org/browse/MDL-80295)
- Added new core_courseformat\output\local\overview\overviewdialog output class to create dialog elements in the course overview page. Overview dialog will display a combination of title, description and a list of items (label: value).
For more information see [MDL-83896](https://tracker.moodle.org/browse/MDL-83896)
- A new interface, `main_activity_interface`, is now available. Course format plugins should implement it if they intend to display only a single activity in the course page.
For more information see [MDL-85433](https://tracker.moodle.org/browse/MDL-85433)
- The core_courseformat\local\overview\overviewfactory now includes a new method, activity_has_overview_integration, which determines if a module supports overview integration.
For more information see [MDL-85509](https://tracker.moodle.org/browse/MDL-85509)
- New needs_filtering_by_groups() and get_groups_for_filtering() had been created in activityoverviewbase class for a better management of groups filtering in Activities overview page by activities. needs_filtering_by_groups() returns whether the user needs to filter by groups in the current module, and get_groups_for_filtering() returns which is the filter the user should use with groups API.
For more information see [MDL-85852](https://tracker.moodle.org/browse/MDL-85852)
- A new has_error() function has been created in activityoverviewbase class to raise when a user is trying to check information about a module set as SEPARATE_GROUPS but the user is not in any group.
For more information see [MDL-85852](https://tracker.moodle.org/browse/MDL-85852)
- New optional $nogroupserror parameter has been added to activityname class constructor. A set_nogroupserror() setter to change the value after the constructor has been also added.
For more information see [MDL-85852](https://tracker.moodle.org/browse/MDL-85852)
- Added new `core_courseformat\output\local\overview\overviewaction` output class to create action buttons that now include a badge right next to the button text. It essentially extends the existing action_link class to add a badge, making important actions stand out more on the course overview. Plus, this new structure also makes these badged action links easier to export this information for web services.
For more information see [MDL-85981](https://tracker.moodle.org/browse/MDL-85981)
- Add a new modinfo::get_instance_of() to retrieve an instance of a cm via its name and instance id. Add a new modinfo::sort_cm_array() to sort an array of cms in their order of appearance in the course page. Replaces calls to get_course_and_cm_from_instance() and get_instances_of() whenever it was just used to retrieve a single instance of a cm.
For more information see [MDL-86021](https://tracker.moodle.org/browse/MDL-86021)
- The `core_course\output\activitychooserbutton` has been moved to `core_courseformat\output\local\activitychooserbutton` . From now on, format plugins can provide alternative outputs for this element. Also, all the javascript and templates related to the activity chooser are now located inside the core_courseformat subsystem.
For more information see [MDL-86337](https://tracker.moodle.org/browse/MDL-86337)
- All activity chooser related code has been moved to the `core_courseformat` subsystem. This includes all templates, javascript, and the main output class. If your theme overrides any of these, you will need to update your code accordingly.
For more information see [MDL-86337](https://tracker.moodle.org/browse/MDL-86337)
#### Changed
- The param $maxsections of get_num_sections_data in addsection output is not used anymore. If your format overrides this method, you should add a default value 0 to be consistent with the new implementation.
For more information see [MDL-84291](https://tracker.moodle.org/browse/MDL-84291)
#### Deprecated
- The maxsections setting is now considered deprecated and will be removed in Moodle 6.0. Consider implementing your own setting in your format plugin if needed.
For more information see [MDL-84291](https://tracker.moodle.org/browse/MDL-84291)
- The format base method get_max_sections has been deprecated, as the maxsections setting is also deprecated and no longer in use.
For more information see [MDL-84291](https://tracker.moodle.org/browse/MDL-84291)
- The course format "numsections" option to increment and decrement the number of sections of the course one by one is now deprecated and will be removed in Moodle 6.0.
For more information see [MDL-85284](https://tracker.moodle.org/browse/MDL-85284)
### core_customfield
#### Changed
- Added parameters 'component', 'area' and 'itemid' to the `api::get_instance_fields_data()` and `api::get_instances_fields_data()` methods. Added a new field 'shared' to the customfield_category DB table. Added 'component', 'area' and 'itemid' fields to the customfield_data DB table. Modified the customfield_data DB table unique index to include the new fields.
For more information see [MDL-86065](https://tracker.moodle.org/browse/MDL-86065)
### core_grades
#### Added
- New 'is_gradable()' function has been created to return whether the item has any gradeitem that is GRADE_TYPE_VALUE or GRADE_TYPE_SCALE.
For more information see [MDL-85837](https://tracker.moodle.org/browse/MDL-85837)
- - New grade_item::is_gradable function has been created to return whether the grade item is GRADE_TYPE_VALUE or GRADE_TYPE_SCALE.
For more information see [MDL-86173](https://tracker.moodle.org/browse/MDL-86173)
#### Removed
- The previously deprecate methods have been removed:
- grade_structure::get_grade_analysis_icon
- grade_structure::get_reset_icon
- grade_structure::get_edit_icon
- grade_structure::get_hiding_icon
- grade_structure::get_locking_icon
- grade_structure::get_calculation_icon
For more information see [MDL-77307](https://tracker.moodle.org/browse/MDL-77307)
### core_message
#### Added
- The web service `core_message_get_member_info` additionally returns `cancreatecontact` which is a boolean value for a user's permission to add a contact.
For more information see [MDL-72123](https://tracker.moodle.org/browse/MDL-72123)
- The `contexturl` property to `\core\message\message` instances can now contain `\core\url` values in addition to plain strings
For more information see [MDL-83080](https://tracker.moodle.org/browse/MDL-83080)
### core_question
#### Added
- The question backup API has been improved to only include questions that are actually used or owned by backed up activities.
Any activities that use question references should be supported automatically. Activities that use *question set references* (for example, random quiz questions) need to add a call to `backup_question_set_reference_trait::annotate_set_reference_bank_entries()` alongside the call to `backup_question_set_reference_trait::add_question_set_references()` in their backup step. See `backup_quiz_activity_structure_step::define_structure()` for an example.
For more information see [MDL-41924](https://tracker.moodle.org/browse/MDL-41924)
#### Changed
- `core_question_search_shared_banks` will now search all question banks, not just those outside the current course.
This makes the service usable in cases outside of the current "Switch banks" UI, which require searching all banks on the site.
It also makes the autocomplete in the "Switch banks" UI more consistent, as it was previously excluding some of the banks listed in the UI (Question banks in this course), but not others (Recently viewed question banks).
This change has also adds a 'requiredcapabilties' parameter to the function, which accepts an list of abbreviated capabilities for checking access against question banks before they are returned.
For more information see [MDL-85069](https://tracker.moodle.org/browse/MDL-85069)
- `question_edit_contexts` now only considers the provided context when checking permissions, rather than all parent contexts as well. As questions now exist only at the activity module context level, permissions can be inherited or overridden as normal for each question bank. The previous pattern of checking for a permission in any parent context circumvented the override system, and no longer makes sense.
For more information see [MDL-85754](https://tracker.moodle.org/browse/MDL-85754)
#### Deprecated
- Intial deprecation of core_question_bank_renderer::render_question_pagination() and the associated template file. Rendering the question pagination is now done via ajax based pagination.
For more information see [MDL-78091](https://tracker.moodle.org/browse/MDL-78091)
#### Removed
- Final deprecation of:
- core_question\local\bank\random_question_loader::get_next_question_id()
- core_question\local\bank\random_question_loader::get_category_key()
- core_question\local\bank\random_question_loader::ensure_questions_for_category_loaded()
- core_question\local\bank\random_question_loader::get_question_ids()
- core_question\local\bank\random_question_loader::is_question_available()
- core_question\local\bank\random_question_loader::get_questions()
- core_question\local\bank\random_question_loader::count_questions()
- core_question\local\bank\view::display_top_pagnation()
- core_question\local\bank\view::display_bottom_pagination()
- question_finder::get_questions_from_categories_with_usage_counts()
- question_finder::get_questions_from_categories_and_tags_with_usage_counts()
For more information see [MDL-78091](https://tracker.moodle.org/browse/MDL-78091)
#### Fixed
- The unit test repeated\_restore\_test::test\_restore\_course\_with\_same\_stamp\_questions was passing incorrectly on 5.x for question types that use answers.
Maintainers of third-party question types may want to re-run the test with the fix in place, or if they have copied parts of this test as the basis of a test in their own plugin, review the changes and see if they should be reflected in their own test.
For more information see [MDL-85556](https://tracker.moodle.org/browse/MDL-85556)
### core_reportbuilder
#### Added
- The `count[distinct]` aggregation types support optional `'callback'` value to customise the formatted output when applied to columns
For more information see [MDL-82464](https://tracker.moodle.org/browse/MDL-82464)
- The `report_action` class now accepts a `pix_icon` to include inside the rendered action element
For more information see [MDL-85216](https://tracker.moodle.org/browse/MDL-85216)
- Report schedule types are now extendable by third-party plugins by extending the `core_reportbuilder\local\schedules\base` class in your component namespace: `<component>\reportbuilder\schedule\<type>`
For more information see [MDL-86066](https://tracker.moodle.org/browse/MDL-86066)
- The report column class has a new `get_effective_type()` method to determine the returned column type, taking into account applied aggregation method
For more information see [MDL-86151](https://tracker.moodle.org/browse/MDL-86151)
#### Deprecated
- The following methods from the `schedule` helper class have been deprecated, in favour of usage of the new schedule type system:
* `create_schedule`
* `get_report_empty_options`
* `send_schedule_message`
For more information see [MDL-86066](https://tracker.moodle.org/browse/MDL-86066)
### core_user
#### Added
- New method `\core_user::get_dummy_fullname(...)` for returning dummy user fullname comprised of configured name fields only
For more information see [MDL-82132](https://tracker.moodle.org/browse/MDL-82132)
### block_site_main_menu
#### Added
- The "Main menu" block has been renamed to "Additional activities." Its title is now customizable, and it can be used in course formats without a dedicated view page (for instance, Single activity). On the Home page, this block has also been renamed; administrators will need to manually revert the name if they wish to retain "Main menu" after upgrading.
For more information see [MDL-85392](https://tracker.moodle.org/browse/MDL-85392)
### format_social
#### Deprecated
- The social course format is now disabled by default for all new and upgraded installations. Existing courses using this format will continue to function, but administrators must re-enable it to create new social courses.
For more information see [MDL-85660](https://tracker.moodle.org/browse/MDL-85660)
### format_topics
#### Added
- Now the custom sections format won't ask for initial sections on the creation form. Instead it will use the system number of sections settings directly.
For more information see [MDL-84291](https://tracker.moodle.org/browse/MDL-84291)
### format_weeks
#### Added
- The weekly sections format now has a system setting called Maximum initial number of weeks that replaced the old "Max sections" when creating a new course
For more information see [MDL-84291](https://tracker.moodle.org/browse/MDL-84291)
### gradereport_grader
#### Removed
- The previously deprecated methods have been removed:
- grade_report_grader::get_left_icons_row
- grade_report_grader::get_right_icons_row
- grade_report_grader::get_icons
For more information see [MDL-77307](https://tracker.moodle.org/browse/MDL-77307)
### gradereport_singleview
#### Added
- The `grade/report/singleview/js/singleview.js` file has been removed. And the `grade/report/singleview/amd/src/singleview.js` file has been added. The new file is converted from YUI to native JS.
For more information see [MDL-84071](https://tracker.moodle.org/browse/MDL-84071)
### mod_assign
#### Added
- Within mod_assign, time() calls have been changed to use the core clock class; this means Behat and PHPunit tests that mock the time will now work as expected in mod_assign.
For more information see [MDL-85679](https://tracker.moodle.org/browse/MDL-85679)
### mod_bigbluebuttonbn
#### Added
- Add activity_dates class to BigblueButton module.
For more information see [MDL-83889](https://tracker.moodle.org/browse/MDL-83889)
- Add a new parameter to the mod_bigbluebuttonbn\recording::get_recordings_for_instance so to ignore instance group settings and return all recordings. This is an optional argement and no change is expected from existing calls.
For more information see [MDL-86192](https://tracker.moodle.org/browse/MDL-86192)
### mod_book
#### Deprecated
- The \mod_book\event\course_module_instance_list_viewed event is now deprecated. Use \core\event\course_resources_list_viewed instead.
For more information see [MDL-84632](https://tracker.moodle.org/browse/MDL-84632)
### mod_choice
#### Added
- Add manager class to the mod_choice activity. For now this is only for the purpose of implementing the activity overview page but can be improved to be used elsewhere.
For more information see [MDL-83890](https://tracker.moodle.org/browse/MDL-83890)
- Add new generator for choice responses
For more information see [MDL-83890](https://tracker.moodle.org/browse/MDL-83890)
### mod_data
#### Added
- Database entries generator could create 'approved' entries.
For more information see [MDL-83891](https://tracker.moodle.org/browse/MDL-83891)
- New get_approval_requested(), get_all_entries(), filter_entries_by_user(), filter_entries_by_approval() and get_comments() functions have been added to mod_data manager class.
For more information see [MDL-83891](https://tracker.moodle.org/browse/MDL-83891)
### mod_feedback
#### Added
- Two new methods, `feedback_get_completeds` and `feedback_get_completeds_count`, have been added to the feedback API. These methods allow you to retrieve completed items based on multiple groups.
For more information see [MDL-85850](https://tracker.moodle.org/browse/MDL-85850)
### mod_folder
#### Deprecated
- The \mod_folder\event\course_module_instance_list_viewed event is now deprecated. Use \core\event\course_resources_list_viewed instead.
For more information see [MDL-84632](https://tracker.moodle.org/browse/MDL-84632)
### mod_forum
#### Deprecated
- The function forum_tp_get_untracked_forums() has been deprecated because it is no longer used.
For more information see [MDL-83893](https://tracker.moodle.org/browse/MDL-83893)
### mod_glossary
#### Added
- Added mod_glossary_get_comments(): a method for retrieving comments linked to a glossary.
For more information see [MDL-85840](https://tracker.moodle.org/browse/MDL-85840)
### mod_h5pactivity
#### Added
- count_attempts() and count_users_attempts() in manager class accept a new parameter to filter by groups.
For more information see [MDL-85853](https://tracker.moodle.org/browse/MDL-85853)
### mod_imscp
#### Deprecated
- The \mod_imscp\event\course_module_instance_list_viewed event is now deprecated. Use \core\event\course_resources_list_viewed instead.
For more information see [MDL-84632](https://tracker.moodle.org/browse/MDL-84632)
### mod_label
#### Removed
- The dndmedia setting has been removed. From now on dropping a media file into a course will always ask the user if they want to create a label.
For more information see [MDL-83081](https://tracker.moodle.org/browse/MDL-83081)
### mod_lesson
#### Added
- Added new 'count_all_submissions', 'count_submitted_participants' and 'count_all_participants' functions needed by the overview page.
For more information see [MDL-83896](https://tracker.moodle.org/browse/MDL-83896)
### mod_page
#### Deprecated
- The \mod_page\event\course_module_instance_list_viewed event is now deprecated. Use \core\event\course_resources_list_viewed instead.
For more information see [MDL-84632](https://tracker.moodle.org/browse/MDL-84632)
### mod_qbank
#### Changed
- The bulk_action_base class has gotten a get_bulk_action_classes function to let bulk actions specify additional classes to add to the bulk action menu entry. If none is defined in the child, '' is returned.
For more information see [MDL-84548](https://tracker.moodle.org/browse/MDL-84548)
### mod_quiz
#### Added
- Add helper methods in the mod/quiz/lib.php to count the number of attempts (quiz_num_attempts), the number of users who attempted a quiz (quiz_num_users_who_attempted) and users who can attempt (quiz_num_users_who_can_attempt)
For more information see [MDL-83898](https://tracker.moodle.org/browse/MDL-83898)
- Add a groupidlist option to quiz_num_attempt_summary, quiz_num_attempts and quiz_num_users_who_can_attempt to filter those number by groups (the new argument is a list of ids for groups)
For more information see [MDL-86223](https://tracker.moodle.org/browse/MDL-86223)
- Additional parameter for quiz_num_attempts so we only count users with specified capabilities
For more information see [MDL-86520](https://tracker.moodle.org/browse/MDL-86520)
#### Deprecated
- Final deprecations for the quiz. The following functions have been removed:
- quiz_has_question_use
- quiz_update_sumgrades
- quiz_update_all_attempt_sumgrades
- quiz_update_all_final_grades
- quiz_set_grade
- quiz_save_best_grade
- quiz_calculate_best_grade
- quiz_calculate_best_attempt
For more information see [MDL-76612](https://tracker.moodle.org/browse/MDL-76612)
- Initial deprecation add_random_form and associates.
The just removed mod_quiz\form\add_random_form was the only place in core where the mod_quiz/add_random_form javascript was called, so we can deprecate this now. This also enables us to deprecate the mod_quiz/random_question_form_preview javascript and the mod_quiz/random_question_form_preview_question_list template as they are direct dependends.
For more information see [MDL-78091](https://tracker.moodle.org/browse/MDL-78091)
#### Removed
- Final deprecations for the quiz. The following files have been removed:
- mod/quiz/accessmanager_form.php
- mod/quiz/accessmanager.php
- mod/quiz/accessrule/accessrulebase.php
- mod/quiz/attemptlib.php
- mod/quiz/cronlib.php
- mod/quiz/override_form.php
- mod/quiz/renderer.php
- mod/quiz/report/attemptsreport_form.php
- mod/quiz/report/attemptsreport_options.php
- mod/quiz/report/attemptsreport_table.php
- mod/quiz/report/attemptsreport.php
- mod/quiz/report/default.php
For more information see [MDL-76612](https://tracker.moodle.org/browse/MDL-76612)
- Final deprecations for the quiz. The following methods have been removed:
- mod_quiz\output\renderer::no_questions_message
- mod_quiz\output\renderer::render_mod_quiz_links_to_other_attempts
- mod_quiz\output\renderer::render_quiz_nav_question_button
- mod_quiz\output\renderer::render_quiz_nav_section_heading
- mod_quiz\structure::get_slot_tags_for_slot_id
- mod_quiz\structure::is_display_number_customised
For more information see [MDL-76612](https://tracker.moodle.org/browse/MDL-76612)
- Final deprecations for the quiz. The following classes have been removed:
- mod_quiz_overdue_attempt_updater
- moodle_quiz_exception
For more information see [MDL-76612](https://tracker.moodle.org/browse/MDL-76612)
- The const quiz_statistics\calculator::TIME_TO_CACHE has been removed.
For more information see [MDL-76612](https://tracker.moodle.org/browse/MDL-76612)
- Final deprecation of:
- mod_quiz\form\add_random_form::class
- mod_quiz\local\structure\slot_random::set_tags()
- mod_quiz\local\structure\slot_random::set_tags_by_id()
- const quiz_statistics\calculator::TIME_TO_CACHE
- quiz_add_random_questions()
For more information see [MDL-78091](https://tracker.moodle.org/browse/MDL-78091)
- Removed the deprecated class callbacks `quiz_structure_modified` and `quiz_attempt_deleted` from mod_quiz, use the `structure_modified` and `attempt_state_changed` hooks instead. These callbacks were deprecated in Moodle 4.4 and were outputting deprecation warnings since then.
For more information see [MDL-80327](https://tracker.moodle.org/browse/MDL-80327)
### mod_resource
#### Deprecated
- The \mod_resource\event\course_module_instance_list_viewed event is now deprecated. Use \core\event\course_resources_list_viewed instead.
For more information see [MDL-84632](https://tracker.moodle.org/browse/MDL-84632)
### mod_scorm
#### Added
- Create a manager class to regroup common functionalities for course overview page
For more information see [MDL-83899](https://tracker.moodle.org/browse/MDL-83899)
- Add a new generator for scorm attempts to simulate user's attempt.
For more information see [MDL-83899](https://tracker.moodle.org/browse/MDL-83899)
- Add group id list to \mod_scorm\manager::count_users_who_attempted and \mod_scorm\manager::count_participants so we can filter by groups. Empty array means no filtering.
For more information see [MDL-86216](https://tracker.moodle.org/browse/MDL-86216)
#### Deprecated
- The method `\mod_scorm\report::generate_master_checkbox()` has been deprecated and should no longer be used. SCORM report plugins calling this method should use `\mod_scorm\report::generate_toggler_checkbox()` instead.
For more information see [MDL-79756](https://tracker.moodle.org/browse/MDL-79756)
### mod_url
#### Deprecated
- The \mod_url\event\course_module_instance_list_viewed event is now deprecated. Use \core\event\course_resources_list_viewed instead.
For more information see [MDL-84632](https://tracker.moodle.org/browse/MDL-84632)
### mod_wiki
#### Added
- Create a manager class to regroup common functionalities and a wiki_mode enum related to the two different modes
For more information see [MDL-83900](https://tracker.moodle.org/browse/MDL-83900)
### mod_workshop
#### Deprecated
- The function `workshop::count_submissions` has been deprecated and should no longer be used, use `workshop::count_all_submissions` instead.
For more information see [MDL-84809](https://tracker.moodle.org/browse/MDL-84809)
- The function `workshop::count_assessments` has been deprecated and should no longer be used, use `workshop::count_all_assessments` instead.
For more information see [MDL-84809](https://tracker.moodle.org/browse/MDL-84809)
### qtype_multichoice
#### Changed
- Restrict override of margin-bottom for fitem_id_answer_* and fitem_id_fraction_* divs to own edit form. Question type plugins currently benefitting from the unlimited style override will need to change their styles.css accordingly. An example can be found in calculatedmulti's style sheet.
For more information see [MDL-85240](https://tracker.moodle.org/browse/MDL-85240)
### report_progress
#### Added
- Add download widget for report to download multiple formats.
For more information see [MDL-83838](https://tracker.moodle.org/browse/MDL-83838)
#### Changed
- Added a new optional parameter $activegroup to render_groups_select()
For more information see [MDL-82381](https://tracker.moodle.org/browse/MDL-82381)
#### Deprecated
- `report_progress\output\renderer::render_download_buttons` No replacement. We no longer need to render the download custom button links.
For more information see [MDL-83838](https://tracker.moodle.org/browse/MDL-83838)
### theme
#### Deprecated
- These icons are no longer in use and have been deprecated:
- core:e/insert_col_after
- core:e/insert_col_before
- core:e/split_cells
- core:e/text_color
- core:t/locktime
- tool_policy/level
For more information see [MDL-85436](https://tracker.moodle.org/browse/MDL-85436)
### theme_boost
#### Added
- Theme can now inherit from their grand-parent and parents. So if a child theme inherit from a parent theme that declares a new layout, the child theme can use it without redeclaring it. Also inheritance for layout uses the expected grandparent > parent > child with precedence to the child theme.
For more information see [MDL-79319](https://tracker.moodle.org/browse/MDL-79319)
- Tables affected by unwanted styling (e.g., borders) from the reset of Bootstrap _reboot.scss styles can now opt out and preserve the original behavior by adding the styleless .table-reboot class.
For more information see [MDL-86548](https://tracker.moodle.org/browse/MDL-86548)
#### Deprecated
- The `core:e/text_highlight` and `core:e/text_highlight_picker` icons are deprecated and will be removed in Moodle 6.0. The UX team recommended this change to reduce visual clutter and improve readability. The icons were removed because they didn't indicate status changes, were repetitive across all notifications, and took up space that could be used for more content.
For more information see [MDL-85146](https://tracker.moodle.org/browse/MDL-85146)
### tiny_premium
#### Added
- The `tiny_premium_get_api_key` web service now returns an additional field `usecloud` to indicate whether the cloud version or self-hosted version of Tiny Premium plugins should be used.
For more information see [MDL-85727](https://tracker.moodle.org/browse/MDL-85727)
## 5.0
### core
-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)
-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
-163
View File
@@ -1,163 +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 file is used to display a categories sub categories, external pages, and settings.
*
* @since Moodle 2.3
* @package admin
* @copyright 2011 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
$category = required_param('category', PARAM_SAFEDIR);
$return = optional_param('return','', PARAM_ALPHA);
$adminediting = optional_param('adminedit', -1, PARAM_BOOL);
require_login(0, false);
$PAGE->set_context(context_system::instance());
$PAGE->set_url('/admin/category.php', array('category' => $category));
$PAGE->set_pagetype('admin-setting-' . $category);
$PAGE->set_pagelayout('admin');
$PAGE->navigation->clear_cache();
$adminroot = admin_get_root(); // need all settings
$settingspage = $adminroot->locate($category, true);
if (empty($settingspage) or !($settingspage instanceof admin_category)) {
throw new \moodle_exception('categoryerror', 'error', "$CFG->wwwroot/$CFG->admin/");
}
if (!($settingspage->check_access())) {
throw new \moodle_exception('accessdenied', 'admin');
}
$hassiteconfig = has_capability('moodle/site:config', $PAGE->context);
if ($hassiteconfig) {
$PAGE->add_header_action($OUTPUT->render_from_template('core_admin/header_search_input', [
'action' => new moodle_url('/admin/search.php'),
]));
}
$statusmsg = '';
$errormsg = '';
if ($data = data_submitted() and confirm_sesskey()) {
$count = admin_write_settings($data);
if (empty($adminroot->errors)) {
// No errors. Did we change any setting? If so, then indicate success.
if ($count) {
$statusmsg = get_string('changessaved');
} else {
switch ($return) {
case 'site': redirect("$CFG->wwwroot/");
case 'admin': redirect("$CFG->wwwroot/$CFG->admin/");
}
}
} else {
$errormsg = get_string('errorwithsettings', 'admin');
$firsterror = reset($adminroot->errors);
}
$settingspage = $adminroot->locate($category, true);
}
if ($PAGE->user_allowed_editing() && $adminediting != -1) {
$USER->editing = $adminediting;
}
$buttons = null;
if ($PAGE->user_allowed_editing() && !$PAGE->theme->haseditswitch) {
$url = clone($PAGE->url);
if ($PAGE->user_is_editing()) {
$caption = get_string('blockseditoff');
$url->param('adminedit', 'off');
} else {
$caption = get_string('blocksediton');
$url->param('adminedit', 'on');
}
$buttons = $OUTPUT->single_button($url, $caption, 'get');
}
$savebutton = false;
$outputhtml = '';
foreach ($settingspage->children as $childpage) {
if ($childpage->is_hidden() || !$childpage->check_access()) {
continue;
}
if ($childpage instanceof admin_externalpage) {
$outputhtml .= $OUTPUT->heading(html_writer::link($childpage->url, $childpage->visiblename), 3);
} else if ($childpage instanceof admin_settingpage) {
$outputhtml .= $OUTPUT->heading(html_writer::link(new moodle_url('/'.$CFG->admin.'/settings.php', array('section' => $childpage->name)), $childpage->visiblename), 3);
// If its a settings page and has settings lets display them.
if (!empty($childpage->settings)) {
$outputhtml .= html_writer::start_tag('fieldset', array('class' => 'adminsettings'));
foreach ($childpage->settings as $setting) {
if (empty($setting->nosave)) {
$savebutton = true;
}
$fullname = $setting->get_full_name();
if (array_key_exists($fullname, $adminroot->errors)) {
$data = $adminroot->errors[$fullname]->data;
} else {
$data = $setting->get_setting();
}
$outputhtml .= html_writer::tag('div', '<!-- -->', array('class' => 'clearer'));
$outputhtml .= $setting->output_html($data);
}
$outputhtml .= html_writer::end_tag('fieldset');
}
} else if ($childpage instanceof admin_category) {
$outputhtml .= $OUTPUT->heading(html_writer::link(new moodle_url('/'.$CFG->admin.'/category.php', array('category' => $childpage->name)), get_string('admincategory', 'admin', $childpage->visiblename)), 3);
}
}
if ($savebutton) {
$outputhtml .= html_writer::start_tag('div', array('class' => 'form-buttons'));
$outputhtml .= html_writer::empty_tag('input', array('class' => 'btn btn-primary form-submit', 'type' => 'submit', 'value' => get_string('savechanges','admin')));
$outputhtml .= html_writer::end_tag('div');
}
$PAGE->set_title(implode(moodle_page::TITLE_SEPARATOR, $settingspage->visiblepath));
$PAGE->set_heading($SITE->fullname);
if ($buttons) {
$PAGE->set_button($buttons);
}
echo $OUTPUT->header();
if ($errormsg !== '') {
echo $OUTPUT->notification($errormsg);
} else if ($statusmsg !== '') {
echo $OUTPUT->notification($statusmsg, 'notifysuccess');
}
echo $OUTPUT->heading(get_string('admincategory', 'admin', $settingspage->visiblename), 2);
echo html_writer::start_tag('form', array('action' => '', 'method' => 'post', 'id' => 'adminsettings'));
echo html_writer::start_tag('div');
echo html_writer::input_hidden_params(new moodle_url($PAGE->url, array('sesskey' => sesskey(), 'return' => $return)));
echo html_writer::end_tag('div');
echo html_writer::start_tag('fieldset');
echo html_writer::tag('div', '<!-- -->', array('class' => 'clearer'));
echo $outputhtml;
echo html_writer::end_tag('fieldset');
echo html_writer::end_tag('form');
// Add the form change checker.
$PAGE->requires->js_call_amd('core_form/changechecker', 'watchFormById', ['adminsettings']);
echo $OUTPUT->footer();
+4 -1
View File
@@ -128,7 +128,10 @@ if ($options['unset'] || $options['set'] !== null) {
$settinginconfig = array_key_exists($options['name'], $CFG->config_php_settings);
}
if ($settinginconfig) {
cli_error('The configuration variable is hard-set in the config.php, unable to change.', 4);
$variablename = !empty($component)
? "\$CFG->forced_plugin_settings['{$component}']['{$options['name']}']"
: "\$CFG->{$options['name']}";
cli_error("The configuration variable {$variablename} is set in config.php, unable to change.", 4);
}
$new = $options['set'];
+4 -3
View File
@@ -103,7 +103,7 @@ if (file_exists($distrolibfile)) {
}
// Nothing to do if config.php exists
$configfile = __DIR__.'/../../config.php';
$configfile = dirname(__DIR__, 2).'/config.php';
if (file_exists($configfile)) {
require($configfile);
require_once($CFG->libdir.'/clilib.php');
@@ -150,14 +150,15 @@ define('PHPUNIT_TEST', false);
define('IGNORE_COMPONENT_CACHE', true);
// Check that PHP is of a sufficient version as soon as possible.
require_once(__DIR__.'/../../lib/phpminimumversionlib.php');
require_once(dirname(__DIR__, 2) . '/public/lib/phpminimumversionlib.php');
moodle_require_minimum_php_version();
// set up configuration
global $CFG;
$CFG = new stdClass();
$CFG->lang = 'en';
$CFG->dirroot = dirname(dirname(__DIR__));
$CFG->root = dirname(__DIR__, 2);
$CFG->dirroot = $CFG->root . '/public';
$CFG->libdir = "$CFG->dirroot/lib";
$CFG->wwwroot = "http://localhost";
$CFG->httpswwwroot = $CFG->wwwroot;
+1 -1
View File
@@ -65,7 +65,7 @@ Example:
";
// Check that PHP is of a sufficient version as soon as possible.
require_once(__DIR__.'/../../lib/phpminimumversionlib.php');
require_once(dirname(__DIR__, 2) . '/public/lib/phpminimumversionlib.php');
moodle_require_minimum_php_version();
// Nothing to do if config.php does not exist
+18 -9
View File
@@ -69,7 +69,7 @@ if ($options['enablelater']) {
}
$time = time() + ($options['enablelater']*60);
set_config('maintenance_later', $time);
set_config('maintenance_later', $time, null, true);
echo get_string('clistatusenabledlater', 'admin', userdate($time))."\n";
return 0;
@@ -77,23 +77,32 @@ if ($options['enablelater']) {
} else if ($options['enable']) {
if (file_exists("$CFG->dataroot/climaintenance.html")) {
// The maintenance is already enabled, nothing to do.
} else {
enable_cli_maintenance_mode();
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);
}
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);
unset_config('maintenance_later');
set_config('maintenance_enabled', 1, null, true);
if (isset($CFG->maintenance_later)) {
unset_config('maintenance_later', null, true);
}
echo get_string('sitemaintenanceon', 'admin')."\n";
exit(0);
} else if ($options['disable']) {
set_config('maintenance_enabled', 0);
unset_config('maintenance_later');
if ($CFG->maintenance_enabled !== '0') {
set_config('maintenance_enabled', 0, null, true);
}
if (isset($CFG->maintenance_later)) {
unset_config('maintenance_later', null, true);
}
if (file_exists("$CFG->dataroot/climaintenance.html")) {
unlink("$CFG->dataroot/climaintenance.html");
}
+1
View File
@@ -24,6 +24,7 @@
*/
define('CLI_SCRIPT', true);
define('IGNORE_COMPONENT_CACHE', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
+3 -3
View File
@@ -158,13 +158,13 @@ if ($options['plugins']) {
if (is_null($plugin)) {
cli_writeln('Unknown plugin: ' . $component);
} else {
$pluginstring = $plugin->component . "\t" . $plugin->displayname;
$pluginstring = $component . "\t" . $plugin->displayname;
if ($pluginman->can_uninstall_plugin($plugin->component)) {
if ($pluginman->can_uninstall_plugin($component)) {
if ($options['run']) {
cli_writeln('Uninstalling: ' . $pluginstring);
$progress = new progress_trace_buffer(new text_progress_trace(), true);
$pluginman->uninstall_plugin($plugin->component, $progress);
$pluginman->uninstall_plugin($component, $progress);
$progress->finished();
cli_write($progress->get_buffer());
} else {
-943
View File
@@ -1,943 +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/>.
/**
* Main administration script.
*
* @package core
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// Check that config.php exists, if not then call the install script
if (!file_exists('../config.php')) {
header('Location: ../install.php');
die();
}
// Check that PHP is of a sufficient version as soon as possible.
require_once(__DIR__.'/../lib/phpminimumversionlib.php');
moodle_require_minimum_php_version();
// make sure iconv is available and actually works
if (!function_exists('iconv')) {
// this should not happen, this must be very borked install
echo 'Moodle requires the iconv PHP extension. Please install or enable the iconv extension.';
die();
}
// Make sure xml extension is available.
if (!extension_loaded('xml')) {
echo 'Moodle requires the xml PHP extension. Please install or enable the xml extension.';
die();
}
// Make sure mbstring extension is available.
if (!extension_loaded('mbstring')) {
echo 'Moodle requires the mbstring PHP extension. Please install or enable the mbstring extension.';
die();
}
define('NO_OUTPUT_BUFFERING', true);
if (isset($_POST['upgradekey'])) {
// Before you start reporting issues about the collision attacks against
// SHA-1, you should understand that we are not actually attempting to do
// any cryptography here. This is hashed purely so that the key is not
// that apparent in the address bar itself. Anyone who catches the HTTP
// traffic can immediately use it as a valid admin key.
header('Location: index.php?cache=0&upgradekeyhash='.sha1($_POST['upgradekey']));
die();
}
if ((isset($_GET['cache']) and $_GET['cache'] === '0')
or (isset($_POST['cache']) and $_POST['cache'] === '0')
or (!isset($_POST['cache']) and !isset($_GET['cache']) and empty($_GET['sesskey']) and empty($_POST['sesskey']))) {
// Prevent caching at all cost when visiting this page directly,
// we redirect to self once we known no upgrades are necessary.
// Note: $_GET and $_POST are used here intentionally because our param cleaning is not loaded yet.
// Note2: the sesskey is present in all block editing hacks, we can not redirect there, so enable caching.
define('CACHE_DISABLE_ALL', true);
// Force OPcache reset if used, we do not want any stale caches
// when detecting if upgrade necessary or when running upgrade.
if (function_exists('opcache_reset')) {
opcache_reset();
}
$cache = 0;
} else {
$cache = 1;
}
require('../config.php');
// Invalidate the cache of version.php in any circumstances to help core_component
// detecting if the version has changed and component cache should be reset.
if (function_exists('opcache_invalidate')) {
opcache_invalidate($CFG->dirroot . '/version.php', true);
}
// Make sure the component cache gets rebuilt if necessary, any method that
// indirectly calls the protected init() method is good here.
core_component::get_core_subsystems();
if (is_major_upgrade_required() && isloggedin()) {
// A major upgrade is required.
// Terminate the session and redirect back here before anything DB-related happens.
redirect_if_major_upgrade_required();
}
require_once($CFG->libdir.'/adminlib.php'); // various admin-only functions
require_once($CFG->libdir.'/upgradelib.php'); // general upgrade/install related functions
$confirmupgrade = optional_param('confirmupgrade', 0, PARAM_BOOL); // Core upgrade confirmed?
$confirmrelease = optional_param('confirmrelease', 0, PARAM_BOOL); // Core release info and server checks confirmed?
$confirmplugins = optional_param('confirmplugincheck', 0, PARAM_BOOL); // Plugins check page confirmed?
$showallplugins = optional_param('showallplugins', 0, PARAM_BOOL); // Show all plugins on the plugins check page?
$agreelicense = optional_param('agreelicense', 0, PARAM_BOOL); // GPL license confirmed for installation?
$fetchupdates = optional_param('fetchupdates', 0, PARAM_BOOL); // Should check for available updates?
$newaddonreq = optional_param('installaddonrequest', null, PARAM_RAW); // Plugin installation requested at moodle.org/plugins.
$upgradekeyhash = optional_param('upgradekeyhash', null, PARAM_ALPHANUM); // Hash of provided upgrade key.
$installdep = optional_param('installdep', null, PARAM_COMPONENT); // Install given missing dependency (required plugin).
$installdepx = optional_param('installdepx', false, PARAM_BOOL); // Install all missing dependencies.
$confirminstalldep = optional_param('confirminstalldep', false, PARAM_BOOL); // Installing dependencies confirmed.
$abortinstall = optional_param('abortinstall', null, PARAM_COMPONENT); // Cancel installation of the given new plugin.
$abortinstallx = optional_param('abortinstallx', null, PARAM_BOOL); // Cancel installation of all new plugins.
$confirmabortinstall = optional_param('confirmabortinstall', false, PARAM_BOOL); // Installation cancel confirmed.
$abortupgrade = optional_param('abortupgrade', null, PARAM_COMPONENT); // Cancel upgrade of the given existing plugin.
$abortupgradex = optional_param('abortupgradex', null, PARAM_BOOL); // Cancel upgrade of all upgradable plugins.
$confirmabortupgrade = optional_param('confirmabortupgrade', false, PARAM_BOOL); // Upgrade cancel confirmed.
$installupdate = optional_param('installupdate', null, PARAM_COMPONENT); // Install given available update.
$installupdateversion = optional_param('installupdateversion', null, PARAM_INT); // Version of the available update to install.
$installupdatex = optional_param('installupdatex', false, PARAM_BOOL); // Install all available plugin updates.
$confirminstallupdate = optional_param('confirminstallupdate', false, PARAM_BOOL); // Available update(s) install confirmed?
if (!empty($CFG->disableupdateautodeploy)) {
// Invalidate all requests to install plugins via the admin UI.
$newaddonreq = null;
$installdep = null;
$installdepx = false;
$abortupgrade = null;
$abortupgradex = null;
$installupdate = null;
$installupdateversion = null;
$installupdatex = false;
}
// Set up PAGE.
$url = new moodle_url('/admin/index.php');
$url->param('cache', $cache);
if (isset($upgradekeyhash)) {
$url->param('upgradekeyhash', $upgradekeyhash);
}
$PAGE->set_url($url);
unset($url);
// Are we returning from an add-on installation request at moodle.org/plugins?
if ($newaddonreq and !$cache and empty($CFG->disableupdateautodeploy)) {
$target = new moodle_url('/admin/tool/installaddon/index.php', array(
'installaddonrequest' => $newaddonreq,
'confirm' => 0));
if (!isloggedin() or isguestuser()) {
// Login and go the the add-on tool page.
$SESSION->wantsurl = $target->out();
redirect(get_login_url());
}
redirect($target);
}
$PAGE->set_pagelayout('admin'); // Set a default pagelayout
$documentationlink = '<a href="http://docs.moodle.org/en/Installation">Installation docs</a>';
// Check some PHP server settings
if (ini_get_bool('session.auto_start')) {
throw new \moodle_exception('phpvaroff', 'debug', '',
(object)array('name' => 'session.auto_start', 'link' => $documentationlink));
}
if (!ini_get_bool('file_uploads')) {
throw new \moodle_exception('phpvaron', 'debug', '',
(object)array('name' => 'file_uploads', 'link' => $documentationlink));
}
if (is_float_problem()) {
throw new \moodle_exception('phpfloatproblem', 'admin', '', $documentationlink);
}
// Set some necessary variables during set-up to avoid PHP warnings later on this page
if (!isset($CFG->release)) {
$CFG->release = '';
}
if (!isset($CFG->version)) {
$CFG->version = '';
}
if (!isset($CFG->branch)) {
$CFG->branch = '';
}
$version = null;
$release = null;
$branch = null;
require("$CFG->dirroot/version.php"); // defines $version, $release, $branch and $maturity
$CFG->target_release = $release; // used during installation and upgrades
if (!$version or !$release) {
throw new \moodle_exception('withoutversion', 'debug'); // Without version, stop.
}
if (!core_tables_exist()) {
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
// fake some settings
$CFG->docroot = 'http://docs.moodle.org';
$strinstallation = get_string('installation', 'install');
// remove current session content completely
\core\session\manager::terminate_current();
if (empty($agreelicense)) {
$strlicense = get_string('license');
$PAGE->navbar->add($strlicense);
$PAGE->set_title($strinstallation . moodle_page::TITLE_SEPARATOR . 'Moodle ' . $CFG->target_release, false);
$PAGE->set_heading($strinstallation);
$PAGE->set_cacheable(false);
$output = $PAGE->get_renderer('core', 'admin');
echo $output->install_licence_page();
die();
}
if (empty($confirmrelease)) {
require_once($CFG->libdir.'/environmentlib.php');
list($envstatus, $environmentresults) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
$strcurrentrelease = get_string('currentrelease');
$PAGE->navbar->add($strcurrentrelease);
$PAGE->set_title($strinstallation);
$PAGE->set_heading($strinstallation . ' - Moodle ' . $CFG->target_release);
$PAGE->set_cacheable(false);
$output = $PAGE->get_renderer('core', 'admin');
echo $output->install_environment_page($maturity, $envstatus, $environmentresults, $release);
die();
}
// check plugin dependencies
$failed = array();
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed, $CFG->branch)) {
$PAGE->navbar->add(get_string('pluginscheck', 'admin'));
$PAGE->set_title($strinstallation);
$PAGE->set_heading($strinstallation . ' - Moodle ' . $CFG->target_release);
$output = $PAGE->get_renderer('core', 'admin');
$url = new moodle_url($PAGE->url, array('agreelicense' => 1, 'confirmrelease' => 1, 'lang' => $CFG->lang));
echo $output->unsatisfied_dependencies_page($version, $failed, $url);
die();
}
unset($failed);
//TODO: add a page with list of non-standard plugins here
$strdatabasesetup = get_string('databasesetup');
upgrade_init_javascript();
$PAGE->navbar->add($strdatabasesetup);
$PAGE->set_title($strinstallation . moodle_page::TITLE_SEPARATOR . $CFG->target_release, false);
$PAGE->set_heading($strinstallation);
$PAGE->set_cacheable(false);
$output = $PAGE->get_renderer('core', 'admin');
echo $output->header();
if (!$DB->setup_is_unicodedb()) {
if (!$DB->change_db_encoding()) {
// If could not convert successfully, throw error, and prevent installation
throw new \moodle_exception('unicoderequired', 'admin');
}
}
install_core($version, true);
}
// Check version of Moodle code on disk compared with database
// and upgrade if possible.
if (!$cache) {
// Do not try to do anything fancy in non-cached mode,
// this prevents themes from fetching data from non-existent tables.
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
}
$stradministration = get_string('administration');
$PAGE->set_context(context_system::instance());
if (empty($CFG->version)) {
throw new \moodle_exception('missingconfigversion', 'debug');
}
// If an upgrade is running, an admin page starting a frontend upgrade could corrupt the
// DB if the upgrade collided with an already running upgrade process at the wrong time.
// Pull the value direct from the DB, this needs to *always* be correct.
$outagelessupgrade = !empty($DB->get_field('config', 'value', ['name' => 'outagelessupgrade']));
if (!$outagelessupgrade) {
// Detect config cache inconsistency, this happens when you switch branches on dev servers.
if ($CFG->version != $DB->get_field('config', 'value', array('name' => 'version'))) {
purge_all_caches();
redirect(new moodle_url($PAGE->url), 'Config cache inconsistency detected, resetting caches...');
}
if (!$cache && $version > $CFG->version && !$outagelessupgrade) { // Upgrade.
$PAGE->set_url(new moodle_url($PAGE->url, array(
'confirmupgrade' => $confirmupgrade,
'confirmrelease' => $confirmrelease,
'confirmplugincheck' => $confirmplugins,
)));
check_upgrade_key($upgradekeyhash);
// Warning about upgrading a test site.
$testsite = false;
if (defined('BEHAT_SITE_RUNNING')) {
$testsite = 'behat';
}
if (isset($CFG->themerev)) {
// Store the themerev to restore after purging caches.
$themerev = $CFG->themerev;
}
// We purge all of MUC's caches here.
// Caches are disabled for upgrade by CACHE_DISABLE_ALL so we must set the first arg to true.
// This ensures a real config object is loaded and the stores will be purged.
// This is the only way we can purge custom caches such as memcache or APC.
// Note: all other calls to caches will still used the disabled API.
cache_helper::purge_all(true);
// We then purge the regular caches.
purge_all_caches();
if (isset($themerev)) {
// Restore the themerev.
set_config('themerev', $themerev);
}
$output = $PAGE->get_renderer('core', 'admin');
if (upgrade_stale_php_files_present()) {
$PAGE->set_title($stradministration);
$PAGE->set_cacheable(false);
echo $output->upgrade_stale_php_files_page();
die();
}
if (empty($confirmupgrade)) {
$a = new stdClass();
$a->oldversion = "$CFG->release (".sprintf('%.2f', $CFG->version).")";
$a->newversion = "$release (".sprintf('%.2f', $version).")";
$strdatabasechecking = get_string('databasechecking', '', $a);
$PAGE->set_title($stradministration);
$PAGE->set_heading($strdatabasechecking);
$PAGE->set_cacheable(false);
echo $output->upgrade_confirm_page($a->newversion, $maturity, $testsite);
die();
} else if (empty($confirmrelease)) {
require_once($CFG->libdir.'/environmentlib.php');
list($envstatus, $environmentresults) = check_moodle_environment($release, ENV_SELECT_RELEASE);
$strcurrentrelease = get_string('currentrelease');
$PAGE->navbar->add($strcurrentrelease);
$PAGE->set_title($strcurrentrelease);
$PAGE->set_heading($strcurrentrelease);
$PAGE->set_cacheable(false);
echo $output->upgrade_environment_page($release, $envstatus, $environmentresults);
die();
} else if (empty($confirmplugins)) {
$strplugincheck = get_string('plugincheck');
$PAGE->navbar->add($strplugincheck);
$PAGE->set_title($strplugincheck);
$PAGE->set_heading($strplugincheck);
$PAGE->set_cacheable(false);
$pluginman = core_plugin_manager::instance();
// Check for available updates.
if ($fetchupdates) {
// No sesskey support guaranteed here, because sessions might not work yet.
$updateschecker = \core\update\checker::instance();
if ($updateschecker->enabled()) {
$updateschecker->fetch();
}
redirect($PAGE->url);
}
// Cancel all plugin installations.
if ($abortinstallx) {
// No sesskey support guaranteed here, because sessions might not work yet.
$abortables = $pluginman->list_cancellable_installations();
if ($abortables) {
if ($confirmabortinstall) {
foreach ($abortables as $plugin) {
$pluginman->cancel_plugin_installation($plugin->component);
}
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, ['abortinstallx' => $abortinstallx, 'confirmabortinstall' => 1]);
echo $output->upgrade_confirm_abort_install_page($abortables, $continue);
die();
}
}
redirect($PAGE->url);
}
// Cancel single plugin installation.
if ($abortinstall) {
// No sesskey support guaranteed here, because sessions might not work yet.
if ($confirmabortinstall) {
$pluginman->cancel_plugin_installation($abortinstall);
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstall' => $abortinstall, 'confirmabortinstall' => 1));
$abortable = $pluginman->get_plugin_info($abortinstall);
if ($pluginman->can_cancel_plugin_installation($abortable)) {
echo $output->upgrade_confirm_abort_install_page(array($abortable), $continue);
die();
}
redirect($PAGE->url);
}
}
// Cancel all plugins upgrades (that is, restore archived versions).
if ($abortupgradex) {
// No sesskey support guaranteed here, because sessions might not work yet.
$restorable = $pluginman->list_restorable_archives();
if ($restorable) {
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgradex' => 1, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}
// Cancel single plugin upgrade (that is, install the archived version).
if ($abortupgrade) {
// No sesskey support guaranteed here, because sessions might not work yet.
$restorable = $pluginman->list_restorable_archives();
if (isset($restorable[$abortupgrade])) {
$restorable = array($restorable[$abortupgrade]);
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgrade' => $abortupgrade, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}
// Install all available missing dependencies.
if ($installdepx) {
// No sesskey support guaranteed here, because sessions might not work yet.
$installable = $pluginman->filter_installable($pluginman->missing_dependencies(true));
upgrade_install_plugins($installable, $confirminstalldep,
get_string('dependencyinstallhead', 'core_plugin'),
new moodle_url($PAGE->url, array('installdepx' => 1, 'confirminstalldep' => 1))
);
}
// Install single available missing dependency.
if ($installdep) {
// No sesskey support guaranteed here, because sessions might not work yet.
$installable = $pluginman->filter_installable($pluginman->missing_dependencies(true));
if (!empty($installable[$installdep])) {
$installable = array($installable[$installdep]);
upgrade_install_plugins($installable, $confirminstalldep,
get_string('dependencyinstallhead', 'core_plugin'),
new moodle_url($PAGE->url, array('installdep' => $installdep, 'confirminstalldep' => 1))
);
}
}
// Install all available updates.
if ($installupdatex) {
// No sesskey support guaranteed here, because sessions might not work yet.
$installable = $pluginman->filter_installable($pluginman->available_updates());
upgrade_install_plugins($installable, $confirminstallupdate,
get_string('updateavailableinstallallhead', 'core_admin'),
new moodle_url($PAGE->url, array('installupdatex' => 1, 'confirminstallupdate' => 1))
);
}
// Install single available update.
if ($installupdate and $installupdateversion) {
// No sesskey support guaranteed here, because sessions might not work yet.
if ($pluginman->is_remote_plugin_installable($installupdate, $installupdateversion)) {
$installable = array($pluginman->get_remote_plugin_info($installupdate, $installupdateversion, true));
upgrade_install_plugins($installable, $confirminstallupdate,
get_string('updateavailableinstallallhead', 'core_admin'),
new moodle_url($PAGE->url, array('installupdate' => $installupdate,
'installupdateversion' => $installupdateversion, 'confirminstallupdate' => 1)
)
);
}
}
echo $output->upgrade_plugin_check_page(core_plugin_manager::instance(), \core\update\checker::instance(),
$version, $showallplugins, $PAGE->url, new moodle_url($PAGE->url, array('confirmplugincheck' => 1)));
die();
} else {
// Always verify plugin dependencies!
$failed = array();
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed, $CFG->branch)) {
echo $output->unsatisfied_dependencies_page($version, $failed, new moodle_url($PAGE->url,
array('confirmplugincheck' => 0)));
die();
}
unset($failed);
// Launch main upgrade.
upgrade_core($version, true);
}
} else if ($version < $CFG->version) {
// Better stop here, we can not continue with plugin upgrades or anything else.
throw new moodle_exception('downgradedcore', 'error', new moodle_url('/admin/'));
}
// Updated human-readable release version if necessary.
if (!$cache && $release <> $CFG->release ) { // Update the release version.
set_config('release', $release);
}
if (!$cache && $branch <> $CFG->branch) { // Update the branch.
set_config('branch', $branch);
}
if (!$cache && moodle_needs_upgrading()) {
$PAGE->set_url(new moodle_url($PAGE->url, array(
'confirmrelease' => $confirmrelease,
'confirmplugincheck' => $confirmplugins,
)));
check_upgrade_key($upgradekeyhash);
if (!$PAGE->headerprinted) {
// Means core upgrade or installation was not already done.
$pluginman = core_plugin_manager::instance();
$output = $PAGE->get_renderer('core', 'admin');
if (empty($confirmrelease)) {
require_once($CFG->libdir . '/environmentlib.php');
list($envstatus, $environmentresults) = check_moodle_environment($release, ENV_SELECT_RELEASE);
$strcurrentrelease = get_string('currentrelease');
$PAGE->navbar->add($strcurrentrelease);
$PAGE->set_title($strcurrentrelease);
$PAGE->set_heading($strcurrentrelease);
$PAGE->set_cacheable(false);
echo $output->upgrade_environment_page($release, $envstatus, $environmentresults);
die();
} else if (!$confirmplugins) {
$strplugincheck = get_string('plugincheck');
$PAGE->navbar->add($strplugincheck);
$PAGE->set_title($strplugincheck);
$PAGE->set_heading($strplugincheck);
$PAGE->set_cacheable(false);
// Check for available updates.
if ($fetchupdates) {
require_sesskey();
$updateschecker = \core\update\checker::instance();
if ($updateschecker->enabled()) {
$updateschecker->fetch();
}
redirect($PAGE->url);
}
// Cancel all plugin installations.
if ($abortinstallx) {
require_sesskey();
$abortables = $pluginman->list_cancellable_installations();
if ($abortables) {
if ($confirmabortinstall) {
foreach ($abortables as $plugin) {
$pluginman->cancel_plugin_installation($plugin->component);
}
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstallx' => $abortinstallx,
'confirmabortinstall' => 1));
echo $output->upgrade_confirm_abort_install_page($abortables, $continue);
die();
}
}
redirect($PAGE->url);
}
// Cancel single plugin installation.
if ($abortinstall) {
require_sesskey();
if ($confirmabortinstall) {
$pluginman->cancel_plugin_installation($abortinstall);
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstall' => $abortinstall, 'confirmabortinstall' => 1));
$abortable = $pluginman->get_plugin_info($abortinstall);
if ($pluginman->can_cancel_plugin_installation($abortable)) {
echo $output->upgrade_confirm_abort_install_page(array($abortable), $continue);
die();
}
redirect($PAGE->url);
}
}
// Cancel all plugins upgrades (that is, restore archived versions).
if ($abortupgradex) {
require_sesskey();
$restorable = $pluginman->list_restorable_archives();
if ($restorable) {
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgradex' => 1, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}
// Cancel single plugin upgrade (that is, install the archived version).
if ($abortupgrade) {
require_sesskey();
$restorable = $pluginman->list_restorable_archives();
if (isset($restorable[$abortupgrade])) {
$restorable = array($restorable[$abortupgrade]);
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgrade' => $abortupgrade, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}
// Install all available missing dependencies.
if ($installdepx) {
require_sesskey();
$installable = $pluginman->filter_installable($pluginman->missing_dependencies(true));
upgrade_install_plugins($installable, $confirminstalldep,
get_string('dependencyinstallhead', 'core_plugin'),
new moodle_url($PAGE->url, array('installdepx' => 1, 'confirminstalldep' => 1))
);
}
// Install single available missing dependency.
if ($installdep) {
require_sesskey();
$installable = $pluginman->filter_installable($pluginman->missing_dependencies(true));
if (!empty($installable[$installdep])) {
$installable = array($installable[$installdep]);
upgrade_install_plugins($installable, $confirminstalldep,
get_string('dependencyinstallhead', 'core_plugin'),
new moodle_url($PAGE->url, array('installdep' => $installdep, 'confirminstalldep' => 1))
);
}
}
// Install all available updates.
if ($installupdatex) {
require_sesskey();
$installable = $pluginman->filter_installable($pluginman->available_updates());
upgrade_install_plugins($installable, $confirminstallupdate,
get_string('updateavailableinstallallhead', 'core_admin'),
new moodle_url($PAGE->url, array('installupdatex' => 1, 'confirminstallupdate' => 1))
);
}
// Install single available update.
if ($installupdate && $installupdateversion) {
require_sesskey();
if ($pluginman->is_remote_plugin_installable($installupdate, $installupdateversion)) {
$installable = array($pluginman->get_remote_plugin_info($installupdate, $installupdateversion, true));
upgrade_install_plugins($installable, $confirminstallupdate,
get_string('updateavailableinstallallhead', 'core_admin'),
new moodle_url($PAGE->url, array('installupdate' => $installupdate,
'installupdateversion' => $installupdateversion, 'confirminstallupdate' => 1)
)
);
}
}
// Show plugins info.
echo $output->upgrade_plugin_check_page($pluginman, \core\update\checker::instance(),
$version, $showallplugins,
new moodle_url($PAGE->url),
new moodle_url($PAGE->url, array('confirmplugincheck' => 1, 'cache' => 0)));
die();
}
// Make sure plugin dependencies are always checked.
$failed = array();
if (!$pluginman->all_plugins_ok($version, $failed, $CFG->branch)) {
$output = $PAGE->get_renderer('core', 'admin');
echo $output->unsatisfied_dependencies_page($version, $failed, new moodle_url($PAGE->url,
array('confirmplugincheck' => 0)));
die();
}
unset($failed);
}
// Install/upgrade all plugins and other parts.
upgrade_noncore(true);
}
// If this is the first install, indicate that this site is fully configured,
// Except the admin password.
if (during_initial_install()) {
set_config('rolesactive', 1); // After this, during_initial_install will return false.
set_config('adminsetuppending', 1);
set_config('registrationpending', 1); // Remind to register site after all other setup is finished.
// Apply default preset, if it is defined in $CFG and has a valid value.
if (!empty($CFG->setsitepresetduringinstall)) {
\core_adminpresets\helper::change_default_preset($CFG->setsitepresetduringinstall);
}
// We need this redirect to setup proper session.
upgrade_finished("index.php?sessionstarted=1&amp;lang=$CFG->lang");
}
// Make sure admin user is created - this is the last step,
// We need session to be working properly in order to edit admin account.
if (!empty($CFG->adminsetuppending)) {
$sessionstarted = optional_param('sessionstarted', 0, PARAM_BOOL);
if (!$sessionstarted) {
redirect("index.php?sessionstarted=1&lang=$CFG->lang");
} else {
$sessionverify = optional_param('sessionverify', 0, PARAM_BOOL);
if (!$sessionverify) {
$SESSION->sessionverify = 1;
redirect("index.php?sessionstarted=1&sessionverify=1&lang=$CFG->lang");
} else {
if (empty($SESSION->sessionverify)) {
throw new \moodle_exception('installsessionerror', 'admin', "index.php?sessionstarted=1&lang=$CFG->lang");
}
unset($SESSION->sessionverify);
}
}
// Cleanup SESSION to make sure other code does not complain in the future.
unset($SESSION->has_timed_out);
unset($SESSION->wantsurl);
// At this stage there can be only one admin unless more were added by install,
// Users may change username, so do not rely on that.
$adminids = explode(',', $CFG->siteadmins);
$adminuser = get_complete_user_data('id', reset($adminids));
if ($adminuser->password === 'adminsetuppending') {
// Prevent installation hijacking.
if ($adminuser->lastip !== getremoteaddr()) {
throw new \moodle_exception('installhijacked', 'admin');
}
// Login user and let him set password and admin details.
$adminuser->newadminuser = 1;
complete_user_login($adminuser);
redirect("$CFG->wwwroot/user/editadvanced.php?id=$adminuser->id"); // Edit thyself.
} else {
unset_config('adminsetuppending');
}
} else {
// Just make sure upgrade logging is properly terminated.
upgrade_finished('upgradesettings.php');
}
}
if (has_capability('moodle/site:config', context_system::instance())) {
if ($fetchupdates) {
require_sesskey();
$updateschecker = \core\update\checker::instance();
if ($updateschecker->enabled()) {
$updateschecker->fetch();
}
redirect(new moodle_url('/admin/index.php', array('cache' => 0)));
}
}
// Now we can be sure everything was upgraded and caches work fine,
// redirect if necessary to make sure caching is enabled.
if (!$cache) {
redirect(new moodle_url('/admin/index.php', array('cache' => 1)));
}
// Check for valid admin user - no guest autologin
require_login(0, false);
if (isguestuser()) {
// Login as real user!
$SESSION->wantsurl = (string)new moodle_url('/admin/index.php');
redirect(get_login_url());
}
$context = context_system::instance();
if (!has_capability('moodle/site:config', $context)) {
// Do not throw exception display an empty page with administration menu if visible for current user.
$PAGE->set_title(get_string('home'));
$PAGE->set_heading($SITE->fullname);
echo $OUTPUT->header();
echo $OUTPUT->footer();
exit;
}
// check that site is properly customized
$site = get_site();
if (empty($site->shortname)) {
// probably new installation - lets return to frontpage after this step
// remove settings that we want uninitialised
unset_config('registerauth');
unset_config('timezone'); // Force admin to select timezone!
redirect('upgradesettings.php?return=site');
}
// setup critical warnings before printing admin tree block
$insecuredataroot = is_dataroot_insecure(true);
$SESSION->admin_critical_warning = ($insecuredataroot==INSECURE_DATAROOT_ERROR);
$adminroot = admin_get_root();
$PAGE->set_primary_active_tab('siteadminnode');
// Check if there are any new admin settings which have still yet to be set
if (any_new_admin_settings($adminroot)) {
redirect('upgradesettings.php');
}
// Return to original page that started the plugin uninstallation if necessary.
if (isset($SESSION->pluginuninstallreturn)) {
$return = $SESSION->pluginuninstallreturn;
unset($SESSION->pluginuninstallreturn);
if ($return) {
redirect($return);
}
}
// If site registration needs updating, redirect.
\core\hub\registration::registration_reminder('/admin/index.php');
// Everything should now be set up, and the user is an admin
// Print default admin page with notifications.
$errorsdisplayed = defined('WARN_DISPLAY_ERRORS_ENABLED');
$lastcron = get_config('tool_task', 'lastcronstart');
$cronoverdue = ($lastcron < time() - 3600 * 24);
$lastcroninterval = get_config('tool_task', 'lastcroninterval');
$expectedfrequency = $CFG->expectedcronfrequency ?? MINSECS;
$croninfrequent = !$cronoverdue && ($lastcroninterval > ($expectedfrequency + MINSECS) || $lastcron < time() - $expectedfrequency);
$dbproblems = $DB->diagnose();
$maintenancemode = !empty($CFG->maintenance_enabled);
// Available updates for Moodle core.
$updateschecker = \core\update\checker::instance();
$availableupdates = array();
$availableupdatesfetch = null;
if ($updateschecker->enabled()) {
// Only compute the update information when it is going to be displayed to the user.
$availableupdates['core'] = $updateschecker->get_update_info('core',
array('minmaturity' => $CFG->updateminmaturity, 'notifybuilds' => $CFG->updatenotifybuilds));
// Available updates for contributed plugins
$pluginman = core_plugin_manager::instance();
foreach ($pluginman->get_plugins() as $plugintype => $plugintypeinstances) {
foreach ($plugintypeinstances as $pluginname => $plugininfo) {
$pluginavailableupdates = $plugininfo->available_updates();
if (!empty($pluginavailableupdates)) {
foreach ($pluginavailableupdates as $pluginavailableupdate) {
if (!isset($availableupdates[$plugintype.'_'.$pluginname])) {
$availableupdates[$plugintype.'_'.$pluginname] = array();
}
$availableupdates[$plugintype.'_'.$pluginname][] = $pluginavailableupdate;
}
}
}
}
// The timestamp of the most recent check for available updates
$availableupdatesfetch = $updateschecker->get_last_timefetched();
}
$buggyiconvnomb = (!function_exists('mb_convert_encoding') and @iconv('UTF-8', 'UTF-8//IGNORE', '100'.chr(130).'€') !== '100€');
//check if the site is registered on Moodle.org
$registered = \core\hub\registration::is_registered();
// Check if there are any cache warnings.
$cachewarnings = cache_helper::warnings();
// Check if there are events 1 API handlers.
$eventshandlers = $DB->get_records_sql('SELECT DISTINCT component FROM {events_handlers}');
$themedesignermode = !empty($CFG->themedesignermode);
$mobileconfigured = !empty($CFG->enablemobilewebservice);
$invalidforgottenpasswordurl = !empty($CFG->forgottenpasswordurl) && empty(clean_param($CFG->forgottenpasswordurl, PARAM_URL));
// Check if a directory with development libraries exists.
if (empty($CFG->disabledevlibdirscheck) && (is_dir($CFG->dirroot.'/vendor') || is_dir($CFG->dirroot.'/node_modules'))) {
$devlibdir = true;
} else {
$devlibdir = false;
}
// Check if the site is being foced onto ssl.
$overridetossl = !empty($CFG->overridetossl);
// Check if moodle campaign content setting is enabled or not.
$showcampaigncontent = !isset($CFG->showcampaigncontent) || $CFG->showcampaigncontent;
// Encourage admins to enable the user feedback feature if it is not enabled already.
$showfeedbackencouragement = empty($CFG->enableuserfeedback);
// Check if the service and support content setting is enabled or not.
$servicesandsupportcontent = !isset($CFG->showservicesandsupportcontent) || $CFG->showservicesandsupportcontent;
// Check whether the XML-RPC protocol is enabled or not.
require_once($CFG->libdir . '/environmentlib.php');
$result = new environment_results('custom_checks');
$result = check_xmlrpc_usage($result);
$xmlrpcwarning = !is_null($result) ? get_string($result->getFeedbackStr(), 'admin') : '';
admin_externalpage_setup('adminnotifications');
$output = $PAGE->get_renderer('core', 'admin');
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed, $cronoverdue, $dbproblems,
$maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
$registered, $cachewarnings, $eventshandlers, $themedesignermode, $devlibdir,
$mobileconfigured, $overridetossl, $invalidforgottenpasswordurl, $croninfrequent,
$showcampaigncontent, $showfeedbackencouragement, $servicesandsupportcontent,
$xmlrpcwarning);
-146
View File
@@ -1,146 +0,0 @@
<?php
// Allows the admin to configure mnet stuff
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/adminlib.php');
include_once($CFG->dirroot.'/mnet/lib.php');
admin_externalpage_setup('net');
$context = context_system::instance();
$site = get_site();
$mnet = get_mnet_environment();
if (!extension_loaded('openssl')) {
echo $OUTPUT->header();
set_config('mnet_dispatcher_mode', 'off');
throw new \moodle_exception('requiresopenssl', 'mnet');
}
if (!function_exists('curl_init') ) {
echo $OUTPUT->header();
set_config('mnet_dispatcher_mode', 'off');
throw new \moodle_exception('nocurl', 'mnet');
}
if (!isset($CFG->mnet_dispatcher_mode)) {
set_config('mnet_dispatcher_mode', 'off');
}
/// If data submitted, process and store
if (($form = data_submitted()) && confirm_sesskey()) {
if (!empty($form->submit) && $form->submit == get_string('savechanges')) {
if (in_array($form->mode, array("off", "strict", "dangerous"))) {
if (set_config('mnet_dispatcher_mode', $form->mode)) {
redirect('index.php', get_string('changessaved'));
} else {
throw new \moodle_exception('invalidaction', '', 'index.php');
}
}
} elseif (!empty($form->submit) && $form->submit == get_string('delete')) {
$mnet->get_private_key();
$SESSION->mnet_confirm_delete_key = md5(sha1($mnet->keypair['keypair_PEM'])).':'.time();
$formcontinue = new single_button(new moodle_url('index.php', array('confirm' => md5($mnet->public_key))), get_string('yes'));
$formcancel = new single_button(new moodle_url('index.php', array()), get_string('no'));
echo $OUTPUT->header();
echo $OUTPUT->confirm(get_string("deletekeycheck", "mnet"), $formcontinue, $formcancel);
echo $OUTPUT->footer();
exit;
} else {
// We're deleting
// If no/cancel then redirect back to the network setting page.
if (!isset($form->confirm)) {
redirect(
new moodle_url('/admin/mnet/index.php'),
get_string('keydeletedcancelled', 'mnet'),
null,
\core\output\notification::NOTIFY_SUCCESS
);
}
if (!isset($SESSION->mnet_confirm_delete_key)) {
// fail - you're being attacked?
}
$key = '';
$time = '';
@list($key, $time) = explode(':',$SESSION->mnet_confirm_delete_key);
$mnet->get_private_key();
if($time < time() - 60) {
// fail - you're out of time.
redirect(
new moodle_url('/admin/mnet/index.php'),
get_string('deleteoutoftime', 'mnet'),
null,
\core\output\notification::NOTIFY_WARNING
);
}
if ($key != md5(sha1($mnet->keypair['keypair_PEM']))) {
// fail - you're being attacked?
throw new \moodle_exception ('deletewrongkeyvalue', 'mnet', 'index.php');
exit;
}
$mnet->replace_keys();
redirect('index.php', get_string('keydeleted','mnet'));
}
}
$hosts = $DB->get_records_select('mnet_host', "id <> ? AND deleted = 0", array($CFG->mnet_localhost_id), 'wwwroot ASC');
echo $OUTPUT->header();
?>
<form method="post" action="index.php">
<table align="center" width="635" class="generaltable" border="0" cellpadding="5" cellspacing="0">
<tr>
<td class="generalboxcontent">
<table cellpadding="9" cellspacing="0" >
<tr valign="top">
<td colspan="2" class="header"><?php print_string('aboutyourhost', 'mnet'); ?></td>
</tr>
<tr valign="top">
<td align="right"><?php print_string('publickey', 'mnet'); ?>:</td>
<td><pre><?php echo $mnet->public_key; ?></pre></td>
</tr>
<tr valign="top">
<td align="right"><?php print_string('expires', 'mnet'); ?>:</td>
<td><?php echo userdate($mnet->public_key_expires); ?></td>
</tr>
</table>
</td>
</tr>
</table>
</form>
<form method="post" action="index.php">
<table align="center" width="635" class="generaltable" border="0" cellpadding="5" cellspacing="0">
<tr>
<td class="generalboxcontent">
<table cellpadding="9" cellspacing="0" >
<tr valign="top">
<td colspan="2" class="header"><?php print_string('expireyourkey', 'mnet'); ?></td>
</tr>
<tr valign="top">
<td colspan="2"><?php print_string('expireyourkeyexplain', 'mnet'); ?></td>
</tr>
<tr valign="top">
<td align="left" width="10" nowrap="nowrap"><?php print_string('expireyourkey', 'mnet'); ?></td>
<td align="left"><input type="hidden" name="sesskey" value="<?php echo sesskey() ?>" />
<input type="hidden" name="deleteKey" value="" />
<input type="submit" name="submit" value="<?php print_string('delete'); ?>" />
</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
<?php
echo $OUTPUT->footer();
-378
View File
@@ -1,378 +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_adminpresets;
/**
* Admin presets helper class.
*
* @package core_adminpresets
* @copyright 2021 Sara Arjona (sara@moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class helper {
/**
* Create an empty preset.
*
* @param array $data Preset data. Supported values:
* - name. To define the preset name.
* - comments. To change the comments field.
* - author. To update the author field.
* - iscore. Whether the preset is a core preset or not. Valid values on \core_adminpresets\manager class.
* @return int The identifier of the preset created.
*/
public static function create_preset(array $data): int {
global $CFG, $USER, $DB;
$name = array_key_exists('name', $data) ? $data['name'] : '';
$comments = array_key_exists('comments', $data) ? $data['comments'] : '';
$author = array_key_exists('author', $data) ? $data['author'] : fullname($USER);
$iscore = array_key_exists('iscore', $data) ? $data['iscore'] : manager::NONCORE_PRESET;
// Validate iscore value.
$allowed = [manager::NONCORE_PRESET, manager::STARTER_PRESET, manager::FULL_PRESET];
if (!in_array($iscore, $allowed)) {
$iscore = manager::NONCORE_PRESET;
}
$preset = [
'userid' => $USER->id,
'name' => $name,
'comments' => $comments,
'site' => $CFG->wwwroot,
'author' => $author,
'moodleversion' => $CFG->version,
'moodlerelease' => $CFG->release,
'iscore' => $iscore,
'timecreated' => time(),
'timeimported' => 0,
];
$presetid = $DB->insert_record('adminpresets', $preset);
return $presetid;
}
/**
* Helper method to add a setting item to a preset.
*
* @param int $presetid Preset identifier where the item will belong.
* @param string $name Item name.
* @param string $value Item value.
* @param string|null $plugin Item plugin.
* @param string|null $advname If the item is an advanced setting, the name of the advanced setting should be specified here.
* @param string|null $advvalue If the item is an advanced setting, the value of the advanced setting should be specified here.
* @return int The item identificator.
*/
public static function add_item(int $presetid, string $name, string $value, ?string $plugin = 'none',
?string $advname = null, ?string $advvalue = null): int {
global $DB;
$presetitem = [
'adminpresetid' => $presetid,
'plugin' => $plugin,
'name' => $name,
'value' => $value,
];
$itemid = $DB->insert_record('adminpresets_it', $presetitem);
if (!empty($advname)) {
$presetadv = [
'itemid' => $itemid,
'name' => $advname,
'value' => $advvalue,
];
$DB->insert_record('adminpresets_it_a', $presetadv);
}
return $itemid;
}
/**
* Helper method to add a plugin to a preset.
*
* @param int $presetid Preset identifier where the item will belong.
* @param string $plugin Plugin type.
* @param string $name Plugin name.
* @param int $enabled Whether the plugin will be enabled or not.
* @return int The plugin identificator.
*/
public static function add_plugin(int $presetid, string $plugin, string $name, int $enabled): int {
global $DB;
$pluginentry = [
'adminpresetid' => $presetid,
'plugin' => $plugin,
'name' => $name,
'enabled' => $enabled,
];
$pluginid = $DB->insert_record('adminpresets_plug', $pluginentry);
return $pluginid;
}
/**
* Apply the given preset. If it's a filename, the preset will be imported and then applied.
*
* @param string $presetnameorfile The preset name to be applied or a valid preset file to be imported and applied.
* @return int|null The preset identifier that has been applied or null if the given value was not valid.
*/
public static function change_default_preset(string $presetnameorfile): ?int {
global $DB;
$presetid = null;
// Check if the given variable points to a valid preset file to be imported and applied.
if (is_readable($presetnameorfile)) {
$xmlcontent = file_get_contents($presetnameorfile);
$manager = new manager();
list($xmlnotused, $preset) = $manager->import_preset($xmlcontent);
if (!is_null($preset)) {
list($applied) = $manager->apply_preset($preset->id);
if (!empty($applied)) {
$presetid = $preset->id;
}
}
} else {
// Check if the given preset exists; if that's the case, it will be applied.
$stringmanager = get_string_manager();
if ($stringmanager->string_exists($presetnameorfile . 'preset', 'core_adminpresets')) {
$params = ['name' => get_string($presetnameorfile . 'preset', 'core_adminpresets')];
} else {
$params = ['name' => $presetnameorfile];
}
if ($preset = $DB->get_record('adminpresets', $params)) {
$manager = new manager();
list($applied) = $manager->apply_preset($preset->id);
if (!empty($applied)) {
$presetid = $preset->id;
}
}
}
return $presetid;
}
/**
* Helper method to create default site admin presets and initialize them.
*/
public static function create_default_presets(): void {
// Create the "Starter" site admin preset.
$data = [
'name' => get_string('starterpreset', 'core_adminpresets'),
'comments' => get_string('starterpresetdescription', 'core_adminpresets'),
'iscore' => manager::STARTER_PRESET,
];
$presetid = static::create_preset($data);
// Add settings to the "Starter" site admin preset.
static::add_item($presetid, 'usecomments', '0');
static::add_item($presetid, 'usetags', '0');
static::add_item($presetid, 'enablenotes', '0');
static::add_item($presetid, 'enableblogs', '0');
static::add_item($presetid, 'enablebadges', '0');
static::add_item($presetid, 'enableanalytics', '0');
static::add_item($presetid, 'enabled', '0', 'core_competency');
static::add_item($presetid, 'pushcourseratingstouserplans', '0', 'core_competency');
static::add_item($presetid, 'showdataretentionsummary', '0', 'tool_dataprivacy');
static::add_item($presetid, 'forum_maxattachments', '3');
static::add_item($presetid, 'guestloginbutton', '0');
// Set Activity chooser tabs to "Starred, Recommended, All".
static::add_item($presetid, 'activitychoosertabmode', '4');
// Modules: Hide database, external tool (lti), IMS content package (imscp), lesson, SCORM, wiki, workshop.
static::add_plugin($presetid, 'mod', 'data', false);
static::add_plugin($presetid, 'mod', 'lti', false);
static::add_plugin($presetid, 'mod', 'imscp', false);
static::add_plugin($presetid, 'mod', 'lesson', false);
static::add_plugin($presetid, 'mod', 'scorm', false);
static::add_plugin($presetid, 'mod', 'wiki', false);
static::add_plugin($presetid, 'mod', 'workshop', false);
// Availability restrictions: Hide Grouping, User profile.
static::add_plugin($presetid, 'availability', 'grouping', false);
static::add_plugin($presetid, 'availability', 'profile', false);
// Blocks: Hide Activities, Blog menu, Blog tags, Comments, Course completion status, Courses, Flickr,
// Global search, Latest badges, Learning plans, Logged in user, Login, Main menu, Mentees, Online users,
// Private files, Recent blog entries, Recently accessed courses, Search forums, Section links, Social activities,
// Starred courses, Tags, YouTube.
// Hidden by default: Course/site summary, RSS feeds, Self completion, Feedback.
static::add_plugin($presetid, 'block', 'activity_modules', false);
static::add_plugin($presetid, 'block', 'blog_menu', false);
static::add_plugin($presetid, 'block', 'blog_tags', false);
static::add_plugin($presetid, 'block', 'comments', false);
static::add_plugin($presetid, 'block', 'completionstatus', false);
static::add_plugin($presetid, 'block', 'course_summary', false);
static::add_plugin($presetid, 'block', 'course_list', false);
static::add_plugin($presetid, 'block', 'tag_flickr', false);
static::add_plugin($presetid, 'block', 'globalsearch', false);
static::add_plugin($presetid, 'block', 'badges', false);
static::add_plugin($presetid, 'block', 'lp', false);
static::add_plugin($presetid, 'block', 'myprofile', false);
static::add_plugin($presetid, 'block', 'login', false);
static::add_plugin($presetid, 'block', 'site_main_menu', false);
static::add_plugin($presetid, 'block', 'mentees', false);
static::add_plugin($presetid, 'block', 'private_files', false);
static::add_plugin($presetid, 'block', 'blog_recent', false);
static::add_plugin($presetid, 'block', 'rss_client', false);
static::add_plugin($presetid, 'block', 'search_forums', false);
static::add_plugin($presetid, 'block', 'section_links', false);
static::add_plugin($presetid, 'block', 'selfcompletion', false);
static::add_plugin($presetid, 'block', 'social_activities', false);
static::add_plugin($presetid, 'block', 'tags', false);
static::add_plugin($presetid, 'block', 'tag_youtube', false);
static::add_plugin($presetid, 'block', 'feedback', false);
static::add_plugin($presetid, 'block', 'online_users', false);
static::add_plugin($presetid, 'block', 'recentlyaccessedcourses', false);
static::add_plugin($presetid, 'block', 'starredcourses', false);
// Course formats: Disable Social format.
static::add_plugin($presetid, 'format', 'social', false);
// Data formats: Disable Javascript Object Notation (.json).
static::add_plugin($presetid, 'dataformat', 'json', false);
// Enrolments: Disable Cohort sync, Guest access.
static::add_plugin($presetid, 'enrol', 'cohort', false);
static::add_plugin($presetid, 'enrol', 'guest', false);
// Filter: Disable MathJax, Activity names auto-linking.
static::add_plugin($presetid, 'filter', 'mathjaxloader', TEXTFILTER_DISABLED);
static::add_plugin($presetid, 'filter', 'activitynames', TEXTFILTER_DISABLED);
// Question behaviours: Disable Adaptive mode (no penalties), Deferred feedback with CBM, Immediate feedback with CBM.
static::add_plugin($presetid, 'qbehaviour', 'adaptivenopenalty', false);
static::add_plugin($presetid, 'qbehaviour', 'deferredcbm', false);
static::add_plugin($presetid, 'qbehaviour', 'immediatecbm', false);
// Question types: Disable Calculated, Calculated multichoice, Calculated simple, Drag and drop markers,
// Drag and drop onto image, Embedded answers (Cloze), Numerical, Random short-answer matching.
static::add_plugin($presetid, 'qtype', 'calculated', false);
static::add_plugin($presetid, 'qtype', 'calculatedmulti', false);
static::add_plugin($presetid, 'qtype', 'calculatedsimple', false);
static::add_plugin($presetid, 'qtype', 'ddmarker', false);
static::add_plugin($presetid, 'qtype', 'ddimageortext', false);
static::add_plugin($presetid, 'qtype', 'multianswer', false);
static::add_plugin($presetid, 'qtype', 'numerical', false);
static::add_plugin($presetid, 'qtype', 'randomsamatch', false);
// Repositories: Disable Server files, URL downloader, Wikimedia.
static::add_plugin($presetid, 'repository', 'local', false);
static::add_plugin($presetid, 'repository', 'url', false);
static::add_plugin($presetid, 'repository', 'wikimedia', false);
// Create the "Full" site admin preset.
$data = [
'name' => get_string('fullpreset', 'core_adminpresets'),
'comments' => get_string('fullpresetdescription', 'core_adminpresets'),
'iscore' => manager::FULL_PRESET,
];
$presetid = static::create_preset($data);
// Add settings to the "Full" site admin preset.
static::add_item($presetid, 'usecomments', '1');
static::add_item($presetid, 'usetags', '1');
static::add_item($presetid, 'enablenotes', '1');
static::add_item($presetid, 'enableblogs', '1');
static::add_item($presetid, 'enablebadges', '1');
static::add_item($presetid, 'enableanalytics', '0');
static::add_item($presetid, 'enabled', '1', 'core_competency');
static::add_item($presetid, 'pushcourseratingstouserplans', '1', 'core_competency');
static::add_item($presetid, 'showdataretentionsummary', '1', 'tool_dataprivacy');
static::add_item($presetid, 'forum_maxattachments', '9');
static::add_item($presetid, 'guestloginbutton', '1');
// Set Activity chooser tabs to the default value ("Starred, Recommended, All, Activities, Resources").
static::add_item($presetid, 'activitychoosertabmode', '3');
// Modules: Enable database, external tool (lti), IMS content package (imscp), lesson, SCORM, wiki, workshop.
static::add_plugin($presetid, 'mod', 'data', true);
static::add_plugin($presetid, 'mod', 'lti', true);
static::add_plugin($presetid, 'mod', 'imscp', true);
static::add_plugin($presetid, 'mod', 'lesson', true);
static::add_plugin($presetid, 'mod', 'scorm', true);
static::add_plugin($presetid, 'mod', 'wiki', true);
static::add_plugin($presetid, 'mod', 'workshop', true);
// Availability restrictions: Enable Grouping, User profile.
static::add_plugin($presetid, 'availability', 'grouping', true);
static::add_plugin($presetid, 'availability', 'profile', true);
// Blocks: Enable Activities, Blog menu, Blog tags, Comments, Course completion status, Courses, Flickr,
// Global search, Latest badges, Learning plans, Logged in user, Login, Main menu, Mentees, Online users,
// Private files, Recent blog entries, Recently accessed courses, Search forums, Section links, Social activities,
// Starred courses, Tags, YouTube.
// Hidden by default: Course/site summary, RSS feeds, Self completion, Feedback.
static::add_plugin($presetid, 'block', 'activity_modules', true);
static::add_plugin($presetid, 'block', 'blog_menu', true);
static::add_plugin($presetid, 'block', 'blog_tags', true);
static::add_plugin($presetid, 'block', 'comments', true);
static::add_plugin($presetid, 'block', 'completionstatus', true);
static::add_plugin($presetid, 'block', 'course_list', true);
static::add_plugin($presetid, 'block', 'tag_flickr', true);
static::add_plugin($presetid, 'block', 'globalsearch', true);
static::add_plugin($presetid, 'block', 'badges', true);
static::add_plugin($presetid, 'block', 'lp', true);
static::add_plugin($presetid, 'block', 'myprofile', true);
static::add_plugin($presetid, 'block', 'login', true);
static::add_plugin($presetid, 'block', 'site_main_menu', true);
static::add_plugin($presetid, 'block', 'mentees', true);
static::add_plugin($presetid, 'block', 'private_files', true);
static::add_plugin($presetid, 'block', 'blog_recent', true);
static::add_plugin($presetid, 'block', 'search_forums', true);
static::add_plugin($presetid, 'block', 'section_links', true);
static::add_plugin($presetid, 'block', 'social_activities', true);
static::add_plugin($presetid, 'block', 'tags', true);
static::add_plugin($presetid, 'block', 'online_users', true);
static::add_plugin($presetid, 'block', 'recentlyaccessedcourses', true);
static::add_plugin($presetid, 'block', 'starredcourses', true);
// Course formats: Enable Social format.
static::add_plugin($presetid, 'format', 'social', true);
// Data formats: Enable Javascript Object Notation (.json).
static::add_plugin($presetid, 'dataformat', 'json', true);
// Enrolments: Enable Cohort sync, Guest access.
static::add_plugin($presetid, 'enrol', 'cohort', true);
static::add_plugin($presetid, 'enrol', 'guest', true);
// Filter: Enable MathJax, Activity names auto-linking.
static::add_plugin($presetid, 'filter', 'mathjaxloader', TEXTFILTER_ON);
static::add_plugin($presetid, 'filter', 'activitynames', TEXTFILTER_ON);
// Question behaviours: Enable Adaptive mode (no penalties), Deferred feedback with CBM, Immediate feedback with CBM.
static::add_plugin($presetid, 'qbehaviour', 'adaptivenopenalty', true);
static::add_plugin($presetid, 'qbehaviour', 'deferredcbm', true);
static::add_plugin($presetid, 'qbehaviour', 'immediatecbm', true);
// Question types: Enable Calculated, Calculated multichoice, Calculated simple, Drag and drop markers,
// Drag and drop onto image, Embedded answers (Cloze), Numerical, Random short-answer matching.
static::add_plugin($presetid, 'qtype', 'calculated', true);
static::add_plugin($presetid, 'qtype', 'calculatedmulti', true);
static::add_plugin($presetid, 'qtype', 'calculatedsimple', true);
static::add_plugin($presetid, 'qtype', 'ddmarker', true);
static::add_plugin($presetid, 'qtype', 'ddimageortext', true);
static::add_plugin($presetid, 'qtype', 'multianswer', true);
static::add_plugin($presetid, 'qtype', 'numerical', true);
static::add_plugin($presetid, 'qtype', 'randomsamatch', true);
// Repositories: Enable Server files, URL downloader, Wikimedia.
static::add_plugin($presetid, 'repository', 'local', true);
static::add_plugin($presetid, 'repository', 'url', true);
static::add_plugin($presetid, 'repository', 'wikimedia', true);
}
}
@@ -1,54 +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_adminpresets\local\setting;
/**
* Reimplementation to allow human friendly view of the selected regexps.
*
* @deprecated Moodle 4.3 MDL-78468 - No longer used since the devicedetectregex was removed.
* @todo Final deprecation on Moodle 4.7 MDL-79052
* @package core_adminpresets
* @copyright 2021 Pimenko <support@pimenko.com><pimenko.com>
* @author Jordan Kesraoui | Sylvain Revenu | Pimenko based on David Monllaó <david.monllao@urv.cat> code
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class adminpresets_admin_setting_devicedetectregex extends adminpresets_admin_setting_configtext {
/**
* @deprecated Moodle 4.3 MDL-78468 - No longer used since the devicedetectregex was removed.
* @todo Final deprecation on Moodle 4.7 MDL-79052
*/
public function set_visiblevalue() {
debugging(
__FUNCTION__ . '() is deprecated.' .
'All functions associated with devicedetectregex theme setting are being removed.',
DEBUG_DEVELOPER
);
$values = json_decode($this->get_value());
if (!$values) {
parent::set_visiblevalue();
return;
}
$this->visiblevalue = '';
foreach ($values as $key => $value) {
$this->visiblevalue .= $key . ' = ' . $value . ', ';
}
$this->visiblevalue = rtrim($this->visiblevalue, ', ');
}
}
File diff suppressed because it is too large Load Diff
-131
View File
@@ -1,131 +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/>.
/**
* @package moodle
* @subpackage registration
* @author Jerome Mouneyrac <jerome@mouneyrac.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com
*
* This page displays the site registration form.
* It handles redirection to the hub to continue the registration workflow process.
* It also handles update operation by web service.
*/
require_once('../../config.php');
require_once($CFG->libdir . '/adminlib.php');
admin_externalpage_setup('registrationmoodleorg');
$unregistration = optional_param('unregistration', false, PARAM_BOOL);
$confirm = optional_param('confirm', false, PARAM_BOOL);
if ($unregistration && \core\hub\registration::is_registered()) {
if ($confirm) {
require_sesskey();
\core\hub\registration::unregister(false, false);
if (!\core\hub\registration::is_registered()) {
redirect(new moodle_url('/admin/registration/index.php'));
}
}
echo $OUTPUT->header();
echo $OUTPUT->confirm(
get_string('registerwithmoodleorgremove', 'core_hub'),
new moodle_url(new moodle_url('/admin/registration/index.php', ['unregistration' => 1, 'confirm' => 1])),
new moodle_url(new moodle_url('/admin/registration/index.php'))
);
echo $OUTPUT->footer();
exit;
}
$isinitialregistration = \core\hub\registration::show_after_install(true);
if (!$returnurl = optional_param('returnurl', null, PARAM_LOCALURL)) {
$returnurl = $isinitialregistration ? '/admin/index.php' : '/admin/registration/index.php';
}
$siteregistrationform = new \core\hub\site_registration_form();
$siteregistrationform->set_data(['returnurl' => $returnurl]);
if ($fromform = $siteregistrationform->get_data()) {
// Save the settings.
\core\hub\registration::save_site_info($fromform);
if (\core\hub\registration::is_registered()) {
if (\core\hub\registration::update_manual()) {
redirect(new moodle_url($returnurl));
}
redirect(new moodle_url('/admin/registration/index.php', ['returnurl' => $returnurl]));
} else {
\core\hub\registration::register($returnurl);
// This method will redirect away.
}
}
// OUTPUT SECTION.
echo $OUTPUT->header();
// Current status of registration.
$notificationtype = \core\output\notification::NOTIFY_ERROR;
if (\core\hub\registration::is_registered()) {
$lastupdated = \core\hub\registration::get_last_updated();
if ($lastupdated == 0) {
$registrationmessage = get_string('pleaserefreshregistrationunknown', 'admin');
} else if (\core\hub\registration::get_new_registration_fields()) {
$registrationmessage = get_string('pleaserefreshregistrationnewdata', 'admin');
} else {
$lastupdated = userdate($lastupdated, get_string('strftimedate', 'langconfig'));
$registrationmessage = get_string('pleaserefreshregistration', 'admin', $lastupdated);
$notificationtype = \core\output\notification::NOTIFY_INFO;
}
echo $OUTPUT->notification($registrationmessage, $notificationtype);
} else if (!$isinitialregistration) {
$registrationmessage = get_string('registrationwarning', 'admin');
echo $OUTPUT->notification($registrationmessage, $notificationtype);
}
// Heading.
if (\core\hub\registration::is_registered()) {
echo $OUTPUT->heading(get_string('registerwithmoodleorgupdate', 'core_hub'));
} else if ($isinitialregistration) {
echo $OUTPUT->heading(get_string('registerwithmoodleorgcomplete', 'core_hub'));
} else {
echo $OUTPUT->heading(get_string('registerwithmoodleorg', 'core_hub'));
}
$renderer = $PAGE->get_renderer('core', 'admin');
echo $renderer->moodleorg_registration_message();
$siteregistrationform->display();
if (\core\hub\registration::is_registered()) {
// Unregister link.
$unregisterhuburl = new moodle_url("/admin/registration/index.php", ['unregistration' => 1]);
echo html_writer::div(html_writer::link($unregisterhuburl, get_string('unregister', 'hub')), 'unregister mt-2');
} else if ($isinitialregistration) {
echo html_writer::div(html_writer::link(new moodle_url($returnurl), get_string('skipregistration', 'hub')),
'skipregistration mt-2');
}
$PAGE->requires->js_call_amd('core_admin/expand_hash', 'init');
echo $OUTPUT->footer();
-2338
View File
File diff suppressed because it is too large Load Diff
-413
View File
@@ -1,413 +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/>.
require_once(__DIR__ . '/../config.php');
require_once($CFG->dirroot . '/repository/lib.php');
require_once($CFG->libdir . '/adminlib.php');
$repository = optional_param('repos', '', PARAM_ALPHANUMEXT);
$action = optional_param('action', '', PARAM_ALPHANUMEXT);
$sure = optional_param('sure', '', PARAM_ALPHA);
$downloadcontents = optional_param('downloadcontents', false, PARAM_BOOL);
$display = true; // fall through to normal display
$pagename = 'managerepositories';
if ($action == 'edit') {
$pagename = 'repositorysettings' . $repository;
} else if ($action == 'delete') {
$pagename = 'repositorydelete';
} else if (($action == 'newon') || ($action == 'newoff')) {
$pagename = 'repositorynew';
}
// Need to remember this for form
$formaction = $action;
// Check what visibility to show the new repository
if ($action == 'newon') {
$action = 'new';
$visible = true;
} else if ($action == 'newoff') {
$action = 'new';
$visible = false;
}
admin_externalpage_setup($pagename);
// The URL used for redirection, and that all edit related URLs will be based off.
$baseurl = new moodle_url('/admin/repository.php');
$return = true;
if (($action == 'edit') || ($action == 'new')) {
$pluginname = '';
if ($action == 'edit') {
$repositorytype = repository::get_type_by_typename($repository);
$classname = 'repository_' . $repositorytype->get_typename();
$configs = call_user_func(array($classname, 'get_type_option_names'));
$plugin = $repositorytype->get_typename();
// looking for instance to edit plugin name
$instanceoptions = call_user_func(array($classname, 'get_instance_option_names'));
if (empty($instanceoptions)) {
$params = array();
$params['type'] = $plugin;
$instances = repository::get_instances($params);
if ($instance = array_pop($instances)) {
// use the one form db record
$pluginname = $instance->instance->name;
}
}
} else {
$repositorytype = null;
$plugin = $repository;
$typeid = $repository;
}
$PAGE->set_pagetype('admin-repository-' . $plugin);
// display the edit form for this instance
$mform = new repository_type_form('', array('pluginname'=>$pluginname, 'plugin' => $plugin, 'instance' => $repositorytype, 'action' => $formaction));
$fromform = $mform->get_data();
//detect if we create a new type without config (in this case if don't want to display a setting page during creation)
$nosettings = false;
if ($action == 'new') {
$adminconfignames = repository::static_function($repository, 'get_type_option_names');
$nosettings = empty($adminconfignames);
}
// end setup, begin output
if ($mform->is_cancelled()){
redirect($baseurl);
} else if (!empty($fromform) || $nosettings) {
require_sesskey();
if ($action == 'edit') {
$settings = array();
foreach($configs as $config) {
if (!empty($fromform->$config)) {
$settings[$config] = $fromform->$config;
} else {
// if the config name is not appear in $fromform
// empty this config value
$settings[$config] = '';
}
}
$instanceoptionnames = repository::static_function($repository, 'get_instance_option_names');
if (!empty($instanceoptionnames)) {
if (property_exists($fromform, 'enablecourseinstances')) {
$settings['enablecourseinstances'] = $fromform->enablecourseinstances;
}
else {
$settings['enablecourseinstances'] = 0;
}
if (property_exists($fromform, 'enableuserinstances')) {
$settings['enableuserinstances'] = $fromform->enableuserinstances;
}
else {
$settings['enableuserinstances'] = 0;
}
}
$success = $repositorytype->update_options($settings);
} else {
$type = new repository_type($plugin, (array)$fromform, $visible);
$success = true;
if (!$repoid = $type->create()) {
$success = false;
} else {
add_to_config_log('repository_visibility', '', (int)$visible, $plugin);
}
$data = data_submitted();
}
if ($success) {
// configs saved
core_plugin_manager::reset_caches();
redirect($baseurl);
} else {
throw new \moodle_exception('instancenotsaved', 'repository', $baseurl);
}
exit;
} else {
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('configplugin', 'repository_'.$plugin));
$displaysettingform = true;
if ($action == 'edit') {
$typeoptionnames = repository::static_function($repository, 'get_type_option_names');
$instanceoptionnames = repository::static_function($repository, 'get_instance_option_names');
if (empty($typeoptionnames) && empty($instanceoptionnames)) {
$displaysettingform = false;
}
}
if ($displaysettingform){
$OUTPUT->box_start();
$mform->display();
$OUTPUT->box_end();
}
$return = false;
// Display instances list and creation form
if ($action == 'edit') {
$instanceoptionnames = repository::static_function($repository, 'get_instance_option_names');
if (!empty($instanceoptionnames)) {
repository::display_instances_list(context_system::instance(), $repository);
}
}
}
} else if ($action == 'show') {
require_sesskey();
$class = \core_plugin_manager::resolve_plugininfo_class('repository');
$class::enable_plugin($repository, 1);
$return = true;
} else if ($action == 'hide') {
require_sesskey();
$class = \core_plugin_manager::resolve_plugininfo_class('repository');
$class::enable_plugin($repository, 0);
$return = true;
} else if ($action == 'delete') {
$repositorytype = repository::get_type_by_typename($repository);
if ($sure) {
$PAGE->set_pagetype('admin-repository-' . $repository);
require_sesskey();
if ($repositorytype->delete($downloadcontents)) {
// Include this information into config changes table.
add_to_config_log('repository_visibility', $repositorytype->get_visible(), '', $repository);
core_plugin_manager::reset_caches();
redirect($baseurl);
} else {
throw new \moodle_exception('instancenotdeleted', 'repository', $baseurl);
}
exit;
} else {
echo $OUTPUT->header();
$message = get_string('confirmremove', 'repository', $repositorytype->get_readablename());
$output = $OUTPUT->box_start('generalbox', 'notice');
$output .= html_writer::tag('p', $message);
$removeurl = new moodle_url($baseurl, [
'action' =>'delete',
'repos' => $repository,
'sure' => 'yes',
]);
$removeanddownloadurl = new moodle_url($removeurl, [
'downloadcontents' => 1,
]);
$output .= $OUTPUT->single_button($removeurl, get_string('continueuninstall', 'repository'));
$output .= $OUTPUT->single_button($removeanddownloadurl, get_string('continueuninstallanddownload', 'repository'));
$output .= $OUTPUT->single_button($baseurl, get_string('cancel'));
$output .= $OUTPUT->box_end();
echo $output;
$return = false;
}
} else if ($action == 'moveup') {
require_sesskey();
$repositorytype = repository::get_type_by_typename($repository);
$repositorytype->move_order('up');
} else if ($action == 'movedown') {
require_sesskey();
$repositorytype = repository::get_type_by_typename($repository);
$repositorytype->move_order('down');
} else {
// If page is loaded directly
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('manage', 'repository'));
// Get strings that are used
$strshow = get_string('on', 'repository');
$strhide = get_string('off', 'repository');
$strdelete = get_string('disabled', 'repository');
$struninstall = get_string('uninstallplugin', 'core_admin');
$actionchoicesforexisting = array(
'show' => $strshow,
'hide' => $strhide,
'delete' => $strdelete
);
$actionchoicesfornew = array(
'newon' => $strshow,
'newoff' => $strhide,
'delete' => $strdelete
);
$output = '';
$output .= $OUTPUT->box_start('generalbox');
// Set strings that are used multiple times
$settingsstr = get_string('settings');
$disablestr = get_string('disable');
// Table to list plug-ins
$table = new html_table();
$table->head = array(get_string('name'), get_string('isactive', 'repository'), get_string('order'), $settingsstr, $struninstall);
$table->colclasses = array('leftalign', 'centeralign', 'centeralign', 'centeralign', 'centeralign', 'centeralign');
$table->id = 'repositoriessetting';
$table->data = array();
$table->attributes['class'] = 'admintable generaltable';
// Get list of used plug-ins
$repositorytypes = repository::get_types();
// Array to store plugins being used
$alreadyplugins = array();
if (!empty($repositorytypes)) {
$totalrepositorytypes = count($repositorytypes);
$updowncount = 1;
foreach ($repositorytypes as $i) {
$settings = '';
$typename = $i->get_typename();
// Display edit link only if you can config the type or if it has multiple instances (e.g. has instance config)
$typeoptionnames = repository::static_function($typename, 'get_type_option_names');
$instanceoptionnames = repository::static_function($typename, 'get_instance_option_names');
if (!empty($typeoptionnames) || !empty($instanceoptionnames)) {
// Calculate number of instances in order to display them for the Moodle administrator
if (!empty($instanceoptionnames)) {
$params = array();
$params['context'] = array(context_system::instance());
$params['onlyvisible'] = false;
$params['type'] = $typename;
$admininstancenumber = count(repository::static_function($typename, 'get_instances', $params));
// site instances
$admininstancenumbertext = get_string('instancesforsite', 'repository', $admininstancenumber);
$params['context'] = array();
$instances = repository::static_function($typename, 'get_instances', $params);
$courseinstances = array();
$userinstances = array();
foreach ($instances as $instance) {
$repocontext = context::instance_by_id($instance->instance->contextid);
if ($repocontext->contextlevel == CONTEXT_COURSE) {
$courseinstances[] = $instance;
} else if ($repocontext->contextlevel == CONTEXT_USER) {
$userinstances[] = $instance;
}
}
// course instances
$instancenumber = count($courseinstances);
$courseinstancenumbertext = get_string('instancesforcourses', 'repository', $instancenumber);
// user private instances
$instancenumber = count($userinstances);
$userinstancenumbertext = get_string('instancesforusers', 'repository', $instancenumber);
} else {
$admininstancenumbertext = "";
$courseinstancenumbertext = "";
$userinstancenumbertext = "";
}
$settings = html_writer::link(new moodle_url($baseurl, ['action' => 'edit', 'repos' => $typename]), $settingsstr);
$settings .= $OUTPUT->container_start('mdl-left');
$settings .= '<br/>';
$settings .= $admininstancenumbertext;
$settings .= '<br/>';
$settings .= $courseinstancenumbertext;
$settings .= '<br/>';
$settings .= $userinstancenumbertext;
$settings .= $OUTPUT->container_end();
}
// Get the current visibility
if ($i->get_visible()) {
$currentaction = 'show';
} else {
$currentaction = 'hide';
}
// Active toggle.
$selectaction = new moodle_url($baseurl, ['sesskey' => sesskey(), 'repos' => $typename]);
$select = new single_select($selectaction, 'action', $actionchoicesforexisting, $currentaction, null,
'applyto' . basename($typename));
$select->set_label(get_string('action'), array('class' => 'accesshide'));
// Display up/down link
$updown = '';
$spacer = $OUTPUT->spacer(array('height'=>15, 'width'=>15)); // should be done with CSS instead
if ($updowncount > 1) {
$moveupaction = new moodle_url($baseurl, [
'sesskey' => sesskey(),
'action' => 'moveup',
'repos' => $typename,
]);
$updown .= html_writer::link($moveupaction, $OUTPUT->pix_icon('t/up', get_string('moveup'))) . '&nbsp;';
}
else {
$updown .= $spacer;
}
if ($updowncount < $totalrepositorytypes) {
$movedownaction = new moodle_url($baseurl, [
'sesskey' => sesskey(),
'action' => 'movedown',
'repos' => $typename,
]);
$updown .= html_writer::link($movedownaction, $OUTPUT->pix_icon('t/down', get_string('movedown'))) . '&nbsp;';
}
else {
$updown .= $spacer;
}
$updowncount++;
$uninstall = '';
if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('repository_' . $typename, 'manage')) {
$uninstall = html_writer::link($uninstallurl, $struninstall);
}
$table->data[] = array($i->get_readablename(), $OUTPUT->render($select), $updown, $settings, $uninstall);
$table->rowclasses[] = '';
if (!in_array($typename, $alreadyplugins)) {
$alreadyplugins[] = $typename;
}
}
}
// Get all the plugins that exist on disk
$plugins = core_component::get_plugin_list('repository');
if (!empty($plugins)) {
foreach ($plugins as $plugin => $dir) {
// Check that it has not already been listed
if (!in_array($plugin, $alreadyplugins)) {
$selectaction = new moodle_url($baseurl, ['sesskey' => sesskey(), 'repos' => $plugin]);
$select = new single_select($selectaction, 'action', $actionchoicesfornew, 'delete', null,
'applyto' . basename($plugin));
$select->set_label(get_string('action'), array('class' => 'accesshide'));
$uninstall = '';
if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('repository_' . $plugin, 'manage')) {
$uninstall = html_writer::link($uninstallurl, $struninstall);
}
$table->data[] = array(get_string('pluginname', 'repository_'.$plugin), $OUTPUT->render($select), '', '', $uninstall);
$table->rowclasses[] = 'dimmed_text';
}
}
}
$output .= html_writer::table($table);
$output .= $OUTPUT->box_end();
print $output;
$return = false;
}
if ($return) {
redirect($baseurl);
}
echo $OUTPUT->footer();
-354
View File
@@ -1,354 +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/>.
/**
* Assign roles to users.
*
* @package core_role
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../config.php');
require_once($CFG->dirroot . '/' . $CFG->admin . '/roles/lib.php');
define("MAX_USERS_TO_LIST_PER_ROLE", 10);
$contextid = required_param('contextid', PARAM_INT);
$roleid = optional_param('roleid', 0, PARAM_INT);
$returnurl = optional_param('returnurl', null, PARAM_LOCALURL);
list($context, $course, $cm) = get_context_info_array($contextid);
$url = new moodle_url('/admin/roles/assign.php', array('contextid' => $contextid));
if ($course) {
$isfrontpage = ($course->id == SITEID);
} else {
$isfrontpage = false;
if ($context->contextlevel == CONTEXT_USER) {
$course = $DB->get_record('course', array('id'=>optional_param('courseid', SITEID, PARAM_INT)), '*', MUST_EXIST);
$user = $DB->get_record('user', array('id'=>$context->instanceid), '*', MUST_EXIST);
$url->param('courseid', $course->id);
$url->param('userid', $user->id);
} else {
$course = $SITE;
}
}
// Security.
require_login($course, false, $cm);
require_capability('moodle/role:assign', $context);
navigation_node::override_active_url($url);
$pageurl = new moodle_url($url);
if ($returnurl) {
$pageurl->param('returnurl', $returnurl);
}
$PAGE->set_url($pageurl);
$PAGE->set_context($context);
$PAGE->activityheader->disable();
$contextname = $context->get_context_name();
$courseid = $course->id;
// These are needed early because of tabs.php.
list($assignableroles, $assigncounts, $nameswithcounts) = get_assignable_roles($context, ROLENAME_BOTH, true);
$overridableroles = get_overridable_roles($context, ROLENAME_BOTH);
// Make sure this user can assign this role.
if ($roleid && !isset($assignableroles[$roleid])) {
$a = new stdClass;
$a->roleid = $roleid;
$a->context = $contextname;
throw new \moodle_exception('cannotassignrolehere', '', $context->get_url(), $a);
}
// Work out an appropriate page title.
if ($roleid) {
$a = new stdClass;
$a->role = $assignableroles[$roleid];
$a->context = $contextname;
$title = get_string('assignrolenameincontext', 'core_role', $a);
} else {
if ($isfrontpage) {
$title = get_string('frontpageroles', 'admin');
} else {
$title = get_string('assignrolesin', 'core_role', $contextname);
}
}
// Process any incoming role assignments before printing the header.
if ($roleid) {
// Create the user selector objects.
$options = array('context' => $context, 'roleid' => $roleid);
$potentialuserselector = core_role_get_potential_user_selector($context, 'addselect', $options);
$currentuserselector = new core_role_existing_role_holders('removeselect', $options);
// Process incoming role assignments.
$errors = array();
if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) {
$userstoassign = $potentialuserselector->get_selected_users();
if (!empty($userstoassign)) {
foreach ($userstoassign as $adduser) {
$allow = true;
if ($allow) {
role_assign($roleid, $adduser->id, $context->id);
}
}
$potentialuserselector->invalidate_selected_users();
$currentuserselector->invalidate_selected_users();
// Counts have changed, so reload.
list($assignableroles, $assigncounts, $nameswithcounts) = get_assignable_roles($context, ROLENAME_BOTH, true);
}
}
// Process incoming role unassignments.
if (optional_param('remove', false, PARAM_BOOL) && confirm_sesskey()) {
$userstounassign = $currentuserselector->get_selected_users();
if (!empty($userstounassign)) {
foreach ($userstounassign as $removeuser) {
// Unassign only roles that are added manually, no messing with other components!!!
role_unassign($roleid, $removeuser->id, $context->id, '');
}
$potentialuserselector->invalidate_selected_users();
$currentuserselector->invalidate_selected_users();
// Counts have changed, so reload.
list($assignableroles, $assigncounts, $nameswithcounts) = get_assignable_roles($context, ROLENAME_BOTH, true);
}
}
}
if (!empty($user) && ($user->id != $USER->id)) {
$PAGE->navigation->extend_for_user($user);
$PAGE->navbar->includesettingsbase = true;
}
$PAGE->set_pagelayout('admin');
if ($context->contextlevel == CONTEXT_BLOCK) {
// Do not show blocks when changing block's settings, it is confusing.
$PAGE->blocks->show_only_fake_blocks(true);
}
$PAGE->set_title($title);
switch ($context->contextlevel) {
case CONTEXT_SYSTEM:
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('assignroles', '', array('contextid' => $contextid, 'roleid' => $roleid));
break;
case CONTEXT_USER:
$fullname = fullname($user, has_capability('moodle/site:viewfullnames', $context));
$PAGE->set_heading($fullname);
$showroles = 1;
break;
case CONTEXT_COURSECAT:
core_course_category::page_setup();
break;
case CONTEXT_COURSE:
if ($isfrontpage) {
$PAGE->set_heading(get_string('frontpage', 'admin'));
} else {
$PAGE->set_heading($course->fullname);
}
break;
case CONTEXT_MODULE:
$PAGE->set_heading($context->get_context_name(false));
$PAGE->set_cacheable(false);
break;
case CONTEXT_BLOCK:
$PAGE->set_heading($PAGE->course->fullname);
break;
}
$PAGE->set_navigation_overflow_state(false);
// Within a course context we need to explicitly set active tab as there isn't a reference in the nav tree.
if ($context->contextlevel == CONTEXT_COURSE) {
$PAGE->set_secondary_active_tab('participants');
}
echo $OUTPUT->header();
$backurl = null;
// We are looking at a particular role. The page URL has been set correctly.
if ($roleid) {
$backurl = $pageurl;
} else if ($context->contextlevel == CONTEXT_COURSE && !$isfrontpage) {
// Return to the intermediary page when within the course context.
$backurl = new moodle_url('/enrol/otherusers.php', ['id' => $course->id]);
} else if ($returnurl) {
// Factor in for $returnurl being passed.
$backurl = new moodle_url($returnurl);
}
if ($backurl) {
$backbutton = new single_button($backurl, get_string('back'), 'get');
$backbutton->class = 'singlebutton navitem';
echo html_writer::tag('div', $OUTPUT->render($backbutton), ['class' => 'tertiary-navigation']);
} else if (in_array($context->contextlevel, [CONTEXT_COURSE, CONTEXT_MODULE, CONTEXT_COURSECAT])) {
// The front page doesn't have an intermediate page 'other users' but needs similar tertiary nav like a standard course.
echo $OUTPUT->render_participants_tertiary_nav($course);
}
// Print heading.
echo $OUTPUT->heading_with_help($title, 'assignroles', 'core_role');
if ($roleid) {
// Show UI for assigning a particular role to users.
// Print a warning if we are assigning system roles.
if ($context->contextlevel == CONTEXT_SYSTEM) {
echo $OUTPUT->notification(get_string('globalroleswarning', 'core_role'));
}
// Print the form.
$assignurl = new moodle_url($PAGE->url, array('roleid'=>$roleid));
?>
<form id="assignform" method="post" action="<?php echo $assignurl ?>"><div>
<input type="hidden" name="sesskey" value="<?php echo sesskey() ?>" />
<table id="assigningrole" summary="" class="admintable roleassigntable generaltable" cellspacing="0">
<tr>
<td id="existingcell">
<p><label for="removeselect"><?php print_string('extusers', 'core_role'); ?></label></p>
<?php $currentuserselector->display() ?>
</td>
<td id="buttonscell">
<div id="addcontrols">
<input name="add" id="add" type="submit" value="<?php echo $OUTPUT->larrow().'&nbsp;'.get_string('add'); ?>"
title="<?php print_string('add'); ?>" class="btn btn-secondary"/><br />
</div>
<div id="removecontrols">
<input name="remove" id="remove" type="submit" value="<?php echo get_string('remove').'&nbsp;'.$OUTPUT->rarrow(); ?>"
title="<?php print_string('remove'); ?>" class="btn btn-secondary"/>
</div>
</td>
<td id="potentialcell">
<p><label for="addselect"><?php print_string('potusers', 'core_role'); ?></label></p>
<?php $potentialuserselector->display() ?>
</td>
</tr>
</table>
</div></form>
<?php
$PAGE->requires->js_init_call('M.core_role.init_add_assign_page');
if (!empty($errors)) {
$msg = '<p>';
foreach ($errors as $e) {
$msg .= $e.'<br />';
}
$msg .= '</p>';
echo $OUTPUT->box_start();
echo $OUTPUT->notification($msg);
echo $OUTPUT->box_end();
}
// Print a form to swap roles, and a link back to the all roles list.
echo '<div class="backlink">';
$select = new single_select($PAGE->url, 'roleid', $nameswithcounts, $roleid, null);
$select->label = get_string('assignanotherrole', 'core_role');
echo $OUTPUT->render($select);
echo '</div>';
} else if (empty($assignableroles)) {
// Print a message that there are no roles that can me assigned here.
echo $OUTPUT->heading(get_string('notabletoassignroleshere', 'core_role'), 3);
} else {
// Show UI for choosing a role to assign.
// Print a warning if we are assigning system roles.
if ($context->contextlevel == CONTEXT_SYSTEM) {
echo $OUTPUT->notification(get_string('globalroleswarning', 'core_role'));
}
// Print instruction.
echo $OUTPUT->heading(get_string('chooseroletoassign', 'core_role'), 3);
// Get the names of role holders for roles with between 1 and MAX_USERS_TO_LIST_PER_ROLE users,
// and so determine whether to show the extra column.
$roleholdernames = array();
$strmorethanmax = get_string('morethan', 'core_role', MAX_USERS_TO_LIST_PER_ROLE);
$showroleholders = false;
foreach ($assignableroles as $roleid => $notused) {
$roleusers = '';
if (0 < $assigncounts[$roleid] && $assigncounts[$roleid] <= MAX_USERS_TO_LIST_PER_ROLE) {
$userfieldsapi = \core_user\fields::for_name();
$userfields = 'u.id, u.username' . $userfieldsapi->get_sql('u')->selects;
$roleusers = get_role_users($roleid, $context, false, $userfields);
if (!empty($roleusers)) {
$strroleusers = array();
foreach ($roleusers as $user) {
$strroleusers[] = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $user->id . '" >' . fullname($user) . '</a>';
}
$roleholdernames[$roleid] = implode('<br />', $strroleusers);
$showroleholders = true;
}
} else if ($assigncounts[$roleid] > MAX_USERS_TO_LIST_PER_ROLE) {
$assignurl = new moodle_url($PAGE->url, array('roleid'=>$roleid));
$roleholdernames[$roleid] = '<a href="'.$assignurl.'">'.$strmorethanmax.'</a>';
} else {
$roleholdernames[$roleid] = '';
}
}
// Print overview table.
$table = new html_table();
$table->id = 'assignrole';
$table->head = array(get_string('role'), get_string('description'), get_string('userswiththisrole', 'core_role'));
$table->colclasses = array('leftalign role', 'leftalign', 'centeralign userrole');
$table->attributes['class'] = 'admintable generaltable';
if ($showroleholders) {
$table->headspan = array(1, 1, 2);
$table->colclasses[] = 'leftalign roleholder';
}
foreach ($assignableroles as $roleid => $rolename) {
$description = format_string($DB->get_field('role', 'description', array('id'=>$roleid)));
$assignurl = new moodle_url($PAGE->url, array('roleid'=>$roleid));
$row = array('<a href="'.$assignurl.'">'.$rolename.'</a>',
$description, $assigncounts[$roleid]);
if ($showroleholders) {
$row[] = $roleholdernames[$roleid];
}
$table->data[] = $row;
}
echo html_writer::table($table);
if (!$PAGE->has_secondary_navigation() && $context->contextlevel > CONTEXT_USER) {
if (!$returnurl) {
$url = $context->get_url();
echo html_writer::start_tag('div', array('class' => 'backlink'));
echo html_writer::tag('a', get_string('backto', '', $contextname), array('href' => $url));
echo html_writer::end_tag('div');
}
}
}
echo $OUTPUT->footer();
@@ -1,218 +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_role\reportbuilder\local\entities;
use core\{context, context_helper};
use core\lang_string;
use core_reportbuilder\local\entities\base;
use core_reportbuilder\local\filters\select;
use core_reportbuilder\local\report\{column, filter};
use stdClass;
/**
* Role entity
*
* @package core_role
* @copyright 2023 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class role extends base {
/**
* Database tables that this entity uses
*
* @return string[]
*/
protected function get_default_tables(): array {
return [
'context',
'role',
];
}
/**
* The default title for this entity
*
* @return lang_string
*/
protected function get_default_entity_title(): lang_string {
return new lang_string('role');
}
/**
* Initialise the entity
*
* @return base
*/
public function initialise(): base {
$columns = $this->get_all_columns();
foreach ($columns as $column) {
$this->add_column($column);
}
// All the filters defined by the entity can also be used as conditions.
$filters = $this->get_all_filters();
foreach ($filters as $filter) {
$this
->add_filter($filter)
->add_condition($filter);
}
return $this;
}
/**
* Returns list of all available columns
*
* @return column[]
*/
protected function get_all_columns(): array {
$contextalias = $this->get_table_alias('context');
$rolealias = $this->get_table_alias('role');
// Name column.
$columns[] = (new column(
'name',
new lang_string('rolefullname', 'core_role'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->add_fields("{$rolealias}.name, {$rolealias}.shortname, {$rolealias}.id, {$contextalias}.id AS contextid")
->add_fields(context_helper::get_preload_record_columns_sql($contextalias))
// The sorting is on name, unless empty then we use shortname.
->set_is_sortable(true, [
"CASE WHEN COALESCE({$rolealias}.name, '') = ''
THEN {$rolealias}.shortname
ELSE {$rolealias}.name
END",
])
->add_callback(static function(?string $name, stdClass $role): string {
if ($name === null) {
return '';
}
context_helper::preload_from_record($role);
$context = context::instance_by_id($role->contextid);
return role_get_name($role, $context, ROLENAME_BOTH);
});
// Original name column.
$columns[] = (new column(
'originalname',
new lang_string('roleoriginalname', 'core_role'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->add_fields("{$rolealias}.name, {$rolealias}.shortname")
// The sorting is on name, unless empty then we use shortname.
->set_is_sortable(true, [
"CASE WHEN COALESCE({$rolealias}.name, '') = ''
THEN {$rolealias}.shortname
ELSE {$rolealias}.name
END",
])
->add_callback(fn(?string $name, stdClass $role) => match ($name) {
null => '',
default => role_get_name($role, null, ROLENAME_ORIGINAL),
});
// Short name column.
$columns[] = (new column(
'shortname',
new lang_string('roleshortname', 'core_role'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->add_field("{$rolealias}.shortname")
->set_is_sortable(true);
// Archetype column.
$columns[] = (new column(
'archetype',
new lang_string('archetype', 'core_role'),
$this->get_entity_name(),
))
->add_joins($this->get_joins())
->add_field("{$rolealias}.archetype")
->add_callback(fn(?string $archetype) => match ($archetype) {
null => '',
'' => get_string('none'),
default => get_string("archetype{$archetype}", 'core_role'),
})
->set_is_sortable(true);
// Description column.
$columns[] = (new column(
'description',
new lang_string('description'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_LONGTEXT)
->add_fields("{$rolealias}.description, {$rolealias}.shortname")
->set_is_sortable(true)
->add_callback(fn(?string $description, stdClass $role) => match ($description) {
null => '',
default => role_get_description($role),
});
return $columns;
}
/**
* Return list of all available filters
*
* @return filter[]
*/
protected function get_all_filters(): array {
$rolealias = $this->get_table_alias('role');
// Name filter.
$filters[] = (new filter(
select::class,
'name',
new lang_string('rolefullname', 'core_role'),
$this->get_entity_name(),
"{$rolealias}.id"
))
->add_joins($this->get_joins())
->set_options_callback(static function(): array {
return role_get_names(null, ROLENAME_ORIGINAL, true);
});
// Archetype filter.
$filters[] = (new filter(
select::class,
'archetype',
new lang_string('archetype', 'core_role'),
$this->get_entity_name(),
"{$rolealias}.archetype",
))
->add_joins($this->get_joins())
->set_options_callback(static function(): array {
return array_map(
fn(string $archetype) => get_string("archetype{$archetype}", 'core_role'),
get_role_archetypes(),
);
});
return $filters;
}
}
-225
View File
@@ -1,225 +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/>.
/**
* Lets the user define and edit roles.
*
* Responds to actions:
* [blank] - list roles.
* delete - delete a role (with are-you-sure)
* moveup - change the sort order
* movedown - change the sort order
*
* For all but the first two of those, you also need a roleid parameter, and
* possibly some other data.
*
* @package core_role
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->dirroot . '/' . $CFG->admin . '/roles/lib.php');
$action = optional_param('action', '', PARAM_ALPHA);
if ($action) {
$roleid = required_param('roleid', PARAM_INT);
} else {
$roleid = 0;
}
// Get the base URL for this and related pages into a convenient variable.
$baseurl = $CFG->wwwroot . '/' . $CFG->admin . '/roles/manage.php';
$defineurl = $CFG->wwwroot . '/' . $CFG->admin . '/roles/define.php';
admin_externalpage_setup('defineroles');
// Check access permissions.
$systemcontext = context_system::instance();
require_capability('moodle/role:manage', $systemcontext);
// Get some basic data we are going to need.
$roles = role_fix_names(get_all_roles(), $systemcontext, ROLENAME_ORIGINAL);
$undeletableroles = array();
$undeletableroles[$CFG->notloggedinroleid] = 1;
$undeletableroles[$CFG->guestroleid] = 1;
$undeletableroles[$CFG->defaultuserroleid] = 1;
$PAGE->set_primary_active_tab('siteadminnode');
$PAGE->navbar->add(get_string('defineroles', 'role'), $PAGE->url);
// Process submitted data.
$confirmed = (optional_param('confirm', false, PARAM_BOOL) && data_submitted() && confirm_sesskey());
switch ($action) {
case 'delete':
if (isset($undeletableroles[$roleid])) {
throw new \moodle_exception('cannotdeletethisrole', '', $baseurl);
}
if (!$confirmed) {
// Show confirmation.
echo $OUTPUT->header();
$optionsyes = array('action'=>'delete', 'roleid'=>$roleid, 'sesskey'=>sesskey(), 'confirm'=>1);
$a = new stdClass();
$a->id = $roleid;
$a->name = $roles[$roleid]->localname;
$a->shortname = $roles[$roleid]->shortname;
$a->count = $DB->count_records_select('role_assignments',
'roleid = ?', array($roleid), 'COUNT(DISTINCT userid)');
$formcontinue = new single_button(new moodle_url($baseurl, $optionsyes), get_string('yes'));
$formcancel = new single_button(new moodle_url($baseurl), get_string('no'), 'get');
echo $OUTPUT->confirm(get_string('deleterolesure', 'core_role', $a), $formcontinue, $formcancel);
echo $OUTPUT->footer();
die;
}
if (!delete_role($roleid)) {
// The delete failed.
throw new \moodle_exception('cannotdeleterolewithid', 'error', $baseurl, $roleid);
}
// Deleted a role sitewide...
redirect($baseurl);
break;
case 'moveup':
if (confirm_sesskey()) {
$prevrole = null;
$thisrole = null;
foreach ($roles as $role) {
if ($role->id == $roleid) {
$thisrole = $role;
break;
} else {
$prevrole = $role;
}
}
if (is_null($thisrole) || is_null($prevrole)) {
throw new \moodle_exception('cannotmoverolewithid', 'error', '', $roleid);
}
if (!switch_roles($thisrole, $prevrole)) {
throw new \moodle_exception('cannotmoverolewithid', 'error', '', $roleid);
}
}
redirect($baseurl);
break;
case 'movedown':
if (confirm_sesskey()) {
$thisrole = null;
$nextrole = null;
foreach ($roles as $role) {
if ($role->id == $roleid) {
$thisrole = $role;
} else if (!is_null($thisrole)) {
$nextrole = $role;
break;
}
}
if (is_null($nextrole)) {
throw new \moodle_exception('cannotmoverolewithid', 'error', '', $roleid);
}
if (!switch_roles($thisrole, $nextrole)) {
throw new \moodle_exception('cannotmoverolewithid', 'error', '', $roleid);
}
}
redirect($baseurl);
break;
}
// Print the page header and tabs.
echo $OUTPUT->header();
$currenttab = 'manage';
require('managetabs.php');
// Initialise table.
$table = new html_table();
$table->colclasses = array('leftalign', 'leftalign', 'leftalign', 'leftalign');
$table->id = 'roles';
$table->attributes['class'] = 'admintable generaltable';
$table->head = array(
get_string('role') . ' ' . $OUTPUT->help_icon('roles', 'core_role'),
get_string('description'),
get_string('roleshortname', 'core_role'),
get_string('edit')
);
// Get some strings outside the loop.
$stredit = get_string('edit');
$strdelete = get_string('delete');
$strmoveup = get_string('moveup');
$strmovedown = get_string('movedown');
// Print a list of roles with edit/copy/delete/reorder icons.
$table->data = array();
$firstrole = reset($roles);
$lastrole = end($roles);
foreach ($roles as $role) {
// Basic data.
$row = array(
'<a href="' . $defineurl . '?action=view&amp;roleid=' . $role->id . '">' . $role->localname . '</a>',
role_get_description($role),
s($role->shortname),
'',
);
// Move up.
if ($role->sortorder != $firstrole->sortorder) {
$row[3] .= get_action_icon($baseurl . '?action=moveup&amp;roleid=' . $role->id . '&amp;sesskey=' . sesskey(), 'up', $strmoveup, $strmoveup);
} else {
$row[3] .= get_spacer();
}
// Move down.
if ($role->sortorder != $lastrole->sortorder) {
$row[3] .= get_action_icon($baseurl . '?action=movedown&amp;roleid=' . $role->id . '&amp;sesskey=' . sesskey(), 'down', $strmovedown, $strmovedown);
} else {
$row[3] .= get_spacer();
}
// Edit.
$row[3] .= get_action_icon($defineurl . '?action=edit&amp;roleid=' . $role->id,
'edit', $stredit, get_string('editxrole', 'core_role', $role->localname));
// Delete.
if (isset($undeletableroles[$role->id])) {
$row[3] .= get_spacer();
} else {
$row[3] .= get_action_icon($baseurl . '?action=delete&amp;roleid=' . $role->id,
'delete', $strdelete, get_string('deletexrole', 'core_role', $role->localname));
}
$table->data[] = $row;
}
echo html_writer::table($table);
echo $OUTPUT->container_start('buttons');
echo $OUTPUT->single_button(new moodle_url($defineurl, array('action' => 'add')), get_string('addrole', 'core_role'), 'get');
echo $OUTPUT->container_end();
echo $OUTPUT->footer();
die;
function get_action_icon($url, $icon, $alt, $tooltip) {
global $OUTPUT;
return '<a title="' . $tooltip . '" href="'. $url . '">' .
$OUTPUT->pix_icon('t/' . $icon, $alt) . '</a> ';
}
function get_spacer() {
global $OUTPUT;
return $OUTPUT->spacer();
}
-102
View File
@@ -1,102 +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 file defines settingpages and externalpages under the "badges" section
*
* @package core
* @subpackage badges
* @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Yuliya Bozhko <yuliya.bozhko@totaralms.com>
*/
global $SITE;
if (($hassiteconfig || has_any_capability(array(
'moodle/badges:viewawarded',
'moodle/badges:createbadge',
'moodle/badges:manageglobalsettings',
'moodle/badges:awardbadge',
'moodle/badges:configurecriteria',
'moodle/badges:configuremessages',
'moodle/badges:configuredetails',
'moodle/badges:deletebadge'), $systemcontext))) {
require_once($CFG->libdir . '/badgeslib.php');
$globalsettings = new admin_settingpage('badgesettings', new lang_string('badgesettings', 'badges'),
array('moodle/badges:manageglobalsettings'), empty($CFG->enablebadges));
$globalsettings->add(new admin_setting_configtext('badges_defaultissuername',
new lang_string('defaultissuername', 'badges'),
new lang_string('defaultissuername_desc', 'badges'),
$SITE->fullname ? $SITE->fullname : $SITE->shortname, PARAM_TEXT));
$globalsettings->add(new admin_setting_configtext('badges_defaultissuercontact',
new lang_string('defaultissuercontact', 'badges'),
new lang_string('defaultissuercontact_desc', 'badges'),
get_config('moodle','supportemail'), PARAM_EMAIL));
$globalsettings->add(new admin_setting_configtext('badges_badgesalt',
new lang_string('badgesalt', 'badges'),
new lang_string('badgesalt_desc', 'badges'),
'badges' . $SITE->timecreated, PARAM_ALPHANUM));
$globalsettings->add(new admin_setting_configcheckbox('badges_allowcoursebadges',
new lang_string('allowcoursebadges', 'badges'),
new lang_string('allowcoursebadges_desc', 'badges'), 1));
$globalsettings->add(new admin_setting_configcheckbox('badges_allowexternalbackpack',
new lang_string('allowexternalbackpack', 'badges'),
new lang_string('allowexternalbackpack_desc', 'badges'), 1));
$ADMIN->add('badges', $globalsettings);
$ADMIN->add('badges',
new admin_externalpage('managebadges',
new lang_string('managebadges', 'badges'),
new moodle_url('/badges/index.php', array('type' => BADGE_TYPE_SITE)),
array(
'moodle/badges:viewawarded',
'moodle/badges:createbadge',
'moodle/badges:awardbadge',
'moodle/badges:configurecriteria',
'moodle/badges:configuremessages',
'moodle/badges:configuredetails',
'moodle/badges:deletebadge'
),
empty($CFG->enablebadges)
)
);
$ADMIN->add('badges',
new admin_externalpage('newbadge',
new lang_string('newbadge', 'badges'),
new moodle_url('/badges/edit.php', ['action' => 'new']),
array('moodle/badges:createbadge'), empty($CFG->enablebadges)
)
);
$ADMIN->add('badges',
new admin_externalpage('managebackpacks',
new lang_string('managebackpacks', 'badges'),
new moodle_url('/badges/backpacks.php'),
array('moodle/badges:manageglobalsettings'), empty($CFG->enablebadges) || empty($CFG->badges_allowexternalbackpack)
)
);
}
@@ -1,56 +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/>.
}}
{{!
@deprecated since Moodle 4.3
@todo Final deprecation on Moodle 4.7 MDL-79052
@template core_admin/setting_devicedetectregex
Admin devicedetectregex setting template.
Context variables required for this template:
* expressions - List of expressions containing index, name, expression and value
Example context (json):
{
"expressions": [
{ "index": "i1", "name": "Name", "expression": "/bird|yellow/", "value": "Canary" }
]
}
}}
{{!
Setting devicedetectregex.
}}
<table class="table table-striped">
<thead>
<tr>
<th>{{#str}}devicedetectregexexpression, admin{{/str}}</th>
<th>{{#str}}devicedetectregexvalue, admin{{/str}}</th>
</tr>
</thead>
<tbody>
{{#expressions}}
<tr>
<td class="c{{index}}">
<input type="text" name="{{name}}[expression{{index}}]" class="form-control" value="{{expression}}">
</td>
<td class="c{{index}}">
<input type="text" name="{{name}}[value{{index}}]" class="form-control" value="{{value}}">
</td>
</tr>
{{/expressions}}
</tbody>
</table>
-30
View File
@@ -1,30 +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/>.
/**
* Admin tool presets plugin to load some settings.
*
* @package tool_admin_presets
* @copyright 2021 Pimenko <support@pimenko.com><pimenko.com>
* @author Jordan Kesraoui | Sylvain Revenu | Pimenko based on David Monllaó <david.monllao@urv.cat> code
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'tool_admin_presets';
$plugin->version = 2025041400;
$plugin->requires = 2025040800;
-83
View File
@@ -1,83 +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/>.
/**
* Tool analytics external functions tests.
*
* @package tool_analytics
* @category external
* @copyright 2019 David Monllaó {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.8
*/
namespace tool_analytics\external;
use externallib_advanced_testcase;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
require_once($CFG->dirroot . '/analytics/tests/fixtures/test_indicator_max.php');
require_once($CFG->dirroot . '/analytics/tests/fixtures/test_target_course_level_shortname.php');
/**
* Tool analytics external functions tests
*
* @package tool_analytics
* @category external
* @copyright 2019 David Monllaó {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.8
*/
final class external_test extends externallib_advanced_testcase {
/**
* test_potential_contexts description
*/
public function test_potential_contexts(): void {
$this->resetAfterTest();
$this->setAdminUser();
// Include the all context levels so the misc. category get included.
$this->assertCount(1, \tool_analytics\external::potential_contexts());
// The frontpage is not included.
$this->assertCount(0, \tool_analytics\external::potential_contexts('PHPUnit'));
$target = \core_analytics\manager::get_target('test_target_course_level_shortname');
$indicators = ['test_indicator_max' => \core_analytics\manager::get_indicator('test_indicator_max')];
$model = \core_analytics\model::create($target, $indicators);
$this->assertCount(1, \tool_analytics\external::potential_contexts(null, $model->get_id()));
}
/**
* test_potential_contexts description
*/
public function test_potential_contexts_no_manager(): void {
$this->resetAfterTest();
$user = $this->getDataGenerator()->create_user();
$this->setUser($user);
$this->expectException(\required_capability_exception::class);
$this->assertCount(2, \tool_analytics\external::potential_contexts());
}
}
-29
View File
@@ -1,29 +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/>.
/**
* Version details.
*
* @package tool_analytics
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_analytics'; // Full name of the plugin (used for diagnostics).
@@ -1,29 +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/>.
/**
* Version
*
* @package tool_availabilityconditions
* @copyright 2014 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400;
$plugin->requires = 2025040800;
$plugin->component = 'tool_availabilityconditions';
-210
View File
@@ -1,210 +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/>.
/**
* CLI script to set up all the behat test environment.
*
* @package tool_behat
* @copyright 2013 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (isset($_SERVER['REMOTE_ADDR'])) {
die(); // No access from web!
}
// Force OPcache reset if used, we do not want any stale caches
// when preparing test environment.
if (function_exists('opcache_reset')) {
opcache_reset();
}
// Is not really necessary but adding it as is a CLI_SCRIPT.
define('CLI_SCRIPT', true);
define('CACHE_DISABLE_ALL', true);
// Basic functions.
require_once(__DIR__ . '/../../../../lib/clilib.php');
require_once(__DIR__ . '/../../../../lib/behat/lib.php');
list($options, $unrecognized) = cli_get_params(
array(
'parallel' => 0,
'maxruns' => false,
'help' => false,
'fromrun' => 1,
'torun' => 0,
'optimize-runs' => '',
'add-core-features-to-theme' => false,
'axe' => null,
'disable-composer' => false,
'composer-upgrade' => true,
'composer-self-update' => true,
'scss-deprecations' => false,
'no-icon-deprecations' => false,
),
array(
'j' => 'parallel',
'm' => 'maxruns',
'h' => 'help',
'o' => 'optimize-runs',
'a' => 'add-core-features-to-theme',
)
);
// Checking run.php CLI script usage.
$help = "
Behat utilities to initialise behat tests
Usage:
php init.php [--parallel=value [--maxruns=value] [--fromrun=value --torun=value]]
[--no-axe] [--scss-deprecations] [--no-icon-deprecations] [-o | --optimize-runs]
[-a | --add-core-features-to-theme]
[--no-composer-self-update] [--no-composer-upgrade]
[--disable-composer]
[--help]
Options:
-j, --parallel Number of parallel behat run to initialise
-m, --maxruns Max parallel processes to be executed at one time
--fromrun Execute run starting from (Used for parallel runs on different vms)
--torun Execute run till (Used for parallel runs on different vms)
--no-axe Disable axe accessibility tests.
--scss-deprecations Enable SCSS deprecation checks.
--no-icon-deprecations Disable icon deprecation checks.
-o, --optimize-runs
Split features with specified tags in all parallel runs.
-a, --add-core-features-to-theme
Add all core features to specified theme's
--no-composer-self-update
Prevent upgrade of the composer utility using its self-update command
--no-composer-upgrade
Prevent update development dependencies using composer
--disable-composer
A shortcut to disable composer self-update and dependency update
Note: Installation of composer and/or dependencies will still happen as required
-h, --help Print out this help
Example from Moodle root directory:
\$ php admin/tool/behat/cli/init.php --parallel=2
More info in https://moodledev.io/general/development/tools/behat/running
";
if (!empty($options['help'])) {
echo $help;
exit(0);
}
if ($options['axe']) {
echo "Axe accessibility tests are enabled by default, to disable them, use the --no-axe option.\n";
} else if ($options['axe'] === false) {
echo "Axe accessibility tests have been disabled.\n";
}
// Check which util file to call.
$utilfile = 'util_single_run.php';
$commandoptions = "";
// If parallel run then use utilparallel.
if ($options['parallel'] && $options['parallel'] > 1) {
$utilfile = 'util.php';
// Sanitize all input options, so they can be passed to util.
foreach ($options as $option => $value) {
$commandoptions .= behat_get_command_flags($option, $value);
}
} else {
// Only sanitize options for single run.
$cmdoptionsforsinglerun = [
'add-core-features-to-theme',
'axe',
'scss-deprecations',
'no-icon-deprecations',
];
foreach ($cmdoptionsforsinglerun as $option) {
$commandoptions .= behat_get_command_flags($option, $options[$option]);
}
}
// Changing the cwd to admin/tool/behat/cli.
$cwd = getcwd();
$output = null;
if ($options['disable-composer']) {
// Disable self-update and upgrade easily.
// Note: Installation will still occur regardless of this setting.
$options['composer-self-update'] = false;
$options['composer-upgrade'] = false;
}
// Install and update composer and dependencies as required.
testing_update_composer_dependencies($options['composer-self-update'], $options['composer-upgrade']);
// Check whether the behat test environment needs to be updated.
chdir(__DIR__);
exec("php $utilfile --diag $commandoptions", $output, $code);
if ($code == 0) {
echo "Behat test environment already installed\n";
} else if ($code == BEHAT_EXITCODE_INSTALL) {
// Behat and dependencies are installed and we need to install the test site.
chdir(__DIR__);
passthru("php $utilfile --install $commandoptions", $code);
if ($code != 0) {
chdir($cwd);
exit($code);
}
} else if ($code == BEHAT_EXITCODE_REINSTALL) {
// Test site data is outdated.
chdir(__DIR__);
passthru("php $utilfile --drop $commandoptions", $code);
if ($code != 0) {
chdir($cwd);
exit($code);
}
chdir(__DIR__);
passthru("php $utilfile --install $commandoptions", $code);
if ($code != 0) {
chdir($cwd);
exit($code);
}
} else {
// Generic error, we just output it.
echo implode("\n", $output)."\n";
chdir($cwd);
exit($code);
}
// Enable editing mode according to config.php vars.
chdir(__DIR__);
passthru("php $utilfile --enable $commandoptions", $code);
if ($code != 0) {
echo "Error enabling site" . PHP_EOL;
chdir($cwd);
exit($code);
}
exit(0);
-504
View File
@@ -1,504 +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/>.
/**
* CLI tool with utilities to manage parallel Behat integration in Moodle
*
* All CLI utilities uses $CFG->behat_dataroot and $CFG->prefix_dataroot as
* $CFG->dataroot and $CFG->prefix
* Same applies for $CFG->behat_dbname, $CFG->behat_dbuser, $CFG->behat_dbpass
* and $CFG->behat_dbhost. But if any of those is not defined $CFG->dbname,
* $CFG->dbuser, $CFG->dbpass and/or $CFG->dbhost will be used.
*
* @package tool_behat
* @copyright 2012 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (isset($_SERVER['REMOTE_ADDR'])) {
die(); // No access from web!.
}
define('BEHAT_UTIL', true);
define('CLI_SCRIPT', true);
define('NO_OUTPUT_BUFFERING', true);
define('IGNORE_COMPONENT_CACHE', true);
define('ABORT_AFTER_CONFIG', true);
require_once(__DIR__ . '/../../../../lib/clilib.php');
// CLI options.
list($options, $unrecognized) = cli_get_params(
array(
'help' => false,
'install' => false,
'drop' => false,
'enable' => false,
'disable' => false,
'diag' => false,
'parallel' => 0,
'maxruns' => false,
'updatesteps' => false,
'fromrun' => 1,
'torun' => 0,
'optimize-runs' => '',
'add-core-features-to-theme' => false,
'axe' => true,
'scss-deprecations' => false,
'no-icon-deprecations' => false,
),
array(
'h' => 'help',
'j' => 'parallel',
'm' => 'maxruns',
'o' => 'optimize-runs',
'a' => 'add-core-features-to-theme',
)
);
// Checking util.php CLI script usage.
$help = "
Behat utilities to manage the test environment
Usage:
php util.php [--install|--drop|--enable|--disable|--diag|--updatesteps]
[--no-axe|--scss-deprecations|--no-icon-deprecations|--help]
[--parallel=value [--maxruns=value]]
Options:
--install Installs the test environment for acceptance tests
--drop Drops the database tables and the dataroot contents
--enable Enables test environment and updates tests list
--disable Disables test environment
--diag Get behat test environment status code
--updatesteps Update feature step file.
--no-axe Disable axe accessibility tests.
--scss-deprecations Enable SCSS deprecation checks.
--no-icon-deprecations Disable icon deprecation checks.
-j, --parallel Number of parallel behat run operation
-m, --maxruns Max parallel processes to be executed at one time.
-o, --optimize-runs Split features with specified tags in all parallel runs.
-a, --add-core-features-to-theme Add all core features to specified theme's
-h, --help Print out this help
Example from Moodle root directory:
\$ php admin/tool/behat/cli/util.php --enable --parallel=4
More info in https://moodledev.io/general/development/tools/behat/running
";
if (!empty($options['help'])) {
echo $help;
exit(0);
}
$cwd = getcwd();
// If Behat parallel site is being initiliased, then define a param to be used to ignore single run install.
if (!empty($options['parallel'])) {
define('BEHAT_PARALLEL_UTIL', true);
}
require_once(__DIR__ . '/../../../../config.php');
require_once(__DIR__ . '/../../../../lib/behat/lib.php');
require_once(__DIR__ . '/../../../../lib/behat/classes/behat_command.php');
require_once(__DIR__ . '/../../../../lib/behat/classes/behat_config_manager.php');
// Remove error handling overrides done in config.php. This is consistent with admin/tool/behat/cli/util_single_run.php.
$CFG->debug = (E_ALL);
$CFG->debugdisplay = 1;
error_reporting($CFG->debug);
ini_set('display_errors', '1');
ini_set('log_errors', '1');
// Import the necessary libraries.
require_once($CFG->libdir . '/setuplib.php');
require_once($CFG->libdir . '/behat/classes/util.php');
// For drop option check if parallel site.
if ((empty($options['parallel'])) && ($options['drop']) || $options['updatesteps']) {
$options['parallel'] = behat_config_manager::get_behat_run_config_value('parallel');
}
// If not a parallel site then open single run.
if (empty($options['parallel'])) {
// Set run config value for single run.
behat_config_manager::set_behat_run_config_value('singlerun', 1);
chdir(__DIR__);
// Check if behat is initialised, if not exit.
passthru("php util_single_run.php --diag", $status);
if ($status) {
exit ($status);
}
$cmd = commands_to_execute($options);
$processes = cli_execute_parallel(array($cmd), __DIR__);
$status = print_sequential_output($processes, false);
chdir($cwd);
exit((int) $status);
}
// Default torun is maximum parallel runs.
if (empty($options['torun'])) {
$options['torun'] = $options['parallel'];
}
$status = false;
$cmds = commands_to_execute($options);
// Start executing commands either sequential/parallel for options provided.
if ($options['diag'] || $options['enable'] || $options['disable']) {
// Do it sequentially as it's fast and need to be displayed nicely.
foreach (array_chunk($cmds, 1, true) as $cmd) {
$processes = cli_execute_parallel($cmd, __DIR__);
print_sequential_output($processes);
}
} else if ($options['drop']) {
$processes = cli_execute_parallel($cmds, __DIR__);
$exitcodes = print_combined_drop_output($processes);
foreach ($exitcodes as $exitcode) {
$status = (bool)$status || (bool)$exitcode;
}
// Remove run config file.
$behatrunconfigfile = behat_config_manager::get_behat_run_config_file_path();
if (file_exists($behatrunconfigfile)) {
if (!unlink($behatrunconfigfile)) {
behat_error(BEHAT_EXITCODE_PERMISSIONS, 'Can not delete behat run config file');
}
}
// Remove test file path.
if (file_exists(behat_util::get_test_file_path())) {
if (!unlink(behat_util::get_test_file_path())) {
behat_error(BEHAT_EXITCODE_PERMISSIONS, 'Can not delete test file enable info');
}
}
} else if ($options['install']) {
// This is intensive compared to behat itself so run them in chunk if option maxruns not set.
if ($options['maxruns']) {
foreach (array_chunk($cmds, $options['maxruns'], true) as $chunk) {
$processes = cli_execute_parallel($chunk, __DIR__);
$exitcodes = print_combined_install_output($processes);
foreach ($exitcodes as $name => $exitcode) {
if ($exitcode != 0) {
echo "Failed process [[$name]]" . PHP_EOL;
echo $processes[$name]->getOutput();
echo PHP_EOL;
echo $processes[$name]->getErrorOutput();
echo PHP_EOL . PHP_EOL;
}
$status = (bool)$status || (bool)$exitcode;
}
}
} else {
$processes = cli_execute_parallel($cmds, __DIR__);
$exitcodes = print_combined_install_output($processes);
foreach ($exitcodes as $name => $exitcode) {
if ($exitcode != 0) {
echo "Failed process [[$name]]" . PHP_EOL;
echo $processes[$name]->getOutput();
echo PHP_EOL;
echo $processes[$name]->getErrorOutput();
echo PHP_EOL . PHP_EOL;
}
$status = (bool)$status || (bool)$exitcode;
}
}
} else if ($options['updatesteps']) {
// Rewrite config file to ensure we have all the features covered.
if (empty($options['parallel'])) {
behat_config_manager::update_config_file('', true, '', $options['add-core-features-to-theme'], false, false);
} else {
// Update config file, ensuring we have up-to-date behat.yml.
for ($i = $options['fromrun']; $i <= $options['torun']; $i++) {
$CFG->behatrunprocess = $i;
// Update config file for each run.
behat_config_manager::update_config_file('', true, $options['optimize-runs'], $options['add-core-features-to-theme'],
$options['parallel'], $i);
}
unset($CFG->behatrunprocess);
}
// Do it sequentially as it's fast and need to be displayed nicely.
foreach (array_chunk($cmds, 1, true) as $cmd) {
$processes = cli_execute_parallel($cmd, __DIR__);
print_sequential_output($processes);
}
exit(0);
} else {
// We should never reach here.
echo $help;
exit(1);
}
// Ensure we have success status to show following information.
if ($status) {
echo "Unknown failure $status" . PHP_EOL;
exit((int)$status);
}
// Show command o/p (only one per time).
if ($options['install']) {
echo "Acceptance tests site installed for sites:".PHP_EOL;
// Display all sites which are installed/drop/diabled.
for ($i = $options['fromrun']; $i <= $options['torun']; $i++) {
if (empty($CFG->behat_parallel_run[$i - 1]['behat_wwwroot'])) {
echo $CFG->behat_wwwroot . "/" . BEHAT_PARALLEL_SITE_NAME . $i . PHP_EOL;
} else {
echo $CFG->behat_parallel_run[$i - 1]['behat_wwwroot'] . PHP_EOL;
}
}
} else if ($options['drop']) {
echo "Acceptance tests site dropped for " . $options['parallel'] . " parallel sites" . PHP_EOL;
} else if ($options['enable']) {
echo "Acceptance tests environment enabled on $CFG->behat_wwwroot, to run the tests use:" . PHP_EOL;
echo behat_command::get_behat_command(true, true);
// Save fromrun and to run information.
if (isset($options['fromrun'])) {
behat_config_manager::set_behat_run_config_value('fromrun', $options['fromrun']);
}
if (isset($options['torun'])) {
behat_config_manager::set_behat_run_config_value('torun', $options['torun']);
}
if (isset($options['parallel'])) {
behat_config_manager::set_behat_run_config_value('parallel', $options['parallel']);
}
echo PHP_EOL;
} else if ($options['disable']) {
echo "Acceptance tests environment disabled for " . $options['parallel'] . " parallel sites" . PHP_EOL;
} else if ($options['diag']) {
// Valid option, so nothing to do.
} else {
echo $help;
chdir($cwd);
exit(1);
}
chdir($cwd);
exit(0);
/**
* Create commands to be executed for parallel run.
*
* @param array $options options provided by user.
* @return array commands to be executed.
*/
function commands_to_execute($options) {
$removeoptions = array('maxruns', 'fromrun', 'torun');
$cmds = array();
$extraoptions = $options;
$extra = "";
// Remove extra options not in util_single_run.php.
foreach ($removeoptions as $ro) {
$extraoptions[$ro] = null;
unset($extraoptions[$ro]);
}
foreach ($extraoptions as $option => $value) {
$extra .= behat_get_command_flags($option, $value);
}
if (empty($options['parallel'])) {
$cmds = "php util_single_run.php " . $extra;
} else {
// Create commands which has to be executed for parallel site.
for ($i = $options['fromrun']; $i <= $options['torun']; $i++) {
$prefix = BEHAT_PARALLEL_SITE_NAME . $i;
$cmds[$prefix] = "php util_single_run.php " . $extra . " --run=" . $i . " 2>&1";
}
}
return $cmds;
}
/**
* Print drop output merging each run.
*
* @param array $processes list of processes.
* @return array exit codes of each process.
*/
function print_combined_drop_output($processes) {
$exitcodes = array();
$maxdotsonline = 70;
$remainingprintlen = $maxdotsonline;
$progresscount = 0;
echo "Dropping tables:" . PHP_EOL;
while (count($exitcodes) != count($processes)) {
usleep(10000);
foreach ($processes as $name => $process) {
if ($process->isRunning()) {
$op = $process->getIncrementalOutput();
if (trim($op)) {
$update = preg_filter('#^\s*([FS\.\-]+)(?:\s+\d+)?\s*$#', '$1', $op);
$strlentoprint = $update ? strlen($update) : 0;
// If not enough dots printed on line then just print.
if ($strlentoprint < $remainingprintlen) {
echo $update;
$remainingprintlen = $remainingprintlen - $strlentoprint;
} else if ($strlentoprint == $remainingprintlen) {
$progresscount += $maxdotsonline;
echo $update . " " . $progresscount . PHP_EOL;
$remainingprintlen = $maxdotsonline;
} else {
while ($part = substr($update, 0, $remainingprintlen) > 0) {
$progresscount += $maxdotsonline;
echo $part . " " . $progresscount . PHP_EOL;
$update = substr($update, $remainingprintlen);
$remainingprintlen = $maxdotsonline;
}
}
}
} else {
// Process exited.
$process->clearOutput();
$exitcodes[$name] = $process->getExitCode();
}
}
}
echo PHP_EOL;
return $exitcodes;
}
/**
* Print install output merging each run.
*
* @param array $processes list of processes.
* @return array exit codes of each process.
*/
function print_combined_install_output($processes) {
$exitcodes = array();
$line = array();
// Check what best we can do to accommodate all parallel run o/p on single line.
// Windows command line has length of 80 chars, so default we will try fit o/p in 80 chars.
if (defined('BEHAT_MAX_CMD_LINE_OUTPUT') && BEHAT_MAX_CMD_LINE_OUTPUT) {
$lengthofprocessline = (int)max(10, BEHAT_MAX_CMD_LINE_OUTPUT / count($processes));
} else {
$lengthofprocessline = (int)max(10, 80 / count($processes));
}
echo "Installing behat site for " . count($processes) . " parallel behat run" . PHP_EOL;
// Show process name in first row.
foreach ($processes as $name => $process) {
// If we don't have enough space to show full run name then show runX.
if ($lengthofprocessline < strlen($name) + 2) {
$name = substr($name, -5);
}
// One extra padding as we are adding | separator for rest of the data.
$line[$name] = str_pad('[' . $name . '] ', $lengthofprocessline + 1);
}
ksort($line);
$tableheader = array_keys($line);
echo implode("", $line) . PHP_EOL;
// Now print o/p from each process.
while (count($exitcodes) != count($processes)) {
usleep(50000);
$poutput = array();
// Create child process.
foreach ($processes as $name => $process) {
if ($process->isRunning()) {
$output = $process->getIncrementalOutput();
if (trim($output)) {
$poutput[$name] = explode(PHP_EOL, $output);
}
} else {
// Process exited.
$exitcodes[$name] = $process->getExitCode();
}
}
ksort($poutput);
// Get max depth of o/p before displaying.
$maxdepth = 0;
foreach ($poutput as $pout) {
$pdepth = count($pout);
$maxdepth = $pdepth >= $maxdepth ? $pdepth : $maxdepth;
}
// Iterate over each process to get line to print.
for ($i = 0; $i <= $maxdepth; $i++) {
$pline = "";
foreach ($tableheader as $name) {
$po = empty($poutput[$name][$i]) ? "" : substr($poutput[$name][$i], 0, $lengthofprocessline - 1);
$po = str_pad($po, $lengthofprocessline);
$pline .= "|". $po;
}
if (trim(str_replace("|", "", $pline))) {
echo $pline . PHP_EOL;
}
}
unset($poutput);
$poutput = null;
}
echo PHP_EOL;
return $exitcodes;
}
/**
* Print install output merging showing one run at a time.
* If any process fail then exit.
*
* @param array $processes list of processes.
* @param bool $showprefix show prefix.
* @return bool exitcode.
*/
function print_sequential_output($processes, $showprefix = true) {
$status = false;
foreach ($processes as $name => $process) {
$shownname = false;
while ($process->isRunning()) {
$op = $process->getIncrementalOutput();
if (trim($op)) {
// Show name of the run once for sequential.
if ($showprefix && !$shownname) {
echo '[' . $name . '] ';
$shownname = true;
}
echo $op;
}
}
// If any error then exit.
$exitcode = $process->getExitCode();
if ($exitcode != 0) {
exit($exitcode);
}
$status = $status || (bool)$exitcode;
}
return $status;
}
-29
View File
@@ -1,29 +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/>.
/**
* tool_behat version info
*
* @package tool_behat
* @copyright 2012 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_behat'; // Full name of the plugin (used for diagnostics)
@@ -1,222 +0,0 @@
<?php
// This file is part of the Query submission plugin
//
// 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 tool_brickfield\local\areas\core_question;
use core\event\question_created;
use core\event\question_updated;
use tool_brickfield\area_base;
/**
* Base class for various question-related areas.
*
* This is an abstract class so it will be skipped by manager when it finds all areas
*
* @package tool_brickfield
* @copyright 2020 onward: Brickfield Education Labs, www.brickfield.ie
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class base extends area_base {
/**
* Find recordset of the relevant areas.
*
* @param \core\event\base $event
* @return \moodle_recordset|null
*/
public function find_relevant_areas(\core\event\base $event): ?\moodle_recordset {
global $DB;
if (($event instanceof question_created) || ($event instanceof question_updated)) {
$sql = "SELECT {$this->get_type()} AS type,
ctx.id AS contextid,
{$this->get_standard_area_fields_sql()}
q.id AS itemid,
{$this->get_course_and_cat_sql($event)}
q.{$this->get_fieldname()} AS content
FROM {question} q
INNER JOIN {question_versions} qv
ON qv.questionid = q.id
INNER JOIN {question_bank_entries} qbe
ON qbe.id = qv.questionbankentryid
INNER JOIN {question_categories} qc
ON qc.id = qbe.questioncategoryid
INNER JOIN {context} ctx
ON ctx.id = qc.contextid
WHERE (q.id = :refid)
ORDER BY q.id";
$rs = $DB->get_recordset_sql($sql, ['refid' => $event->objectid]);
return $rs;
}
return null;
}
/**
* Find recordset of the course areas.
*
* @param int $courseid
* @return \moodle_recordset
*/
public function find_course_areas(int $courseid): ?\moodle_recordset {
global $DB;
$coursecontext = \context_course::instance($courseid);
$param = [
'module' => CONTEXT_MODULE,
'coursecontextpath' => $DB->sql_like_escape($coursecontext->path) . '/%',
];
$sql = "SELECT {$this->get_type()} AS type,
ctx.id AS contextid,
{$this->get_standard_area_fields_sql()}
q.id AS itemid,
{$courseid} AS courseid,
null AS categoryid,
q.{$this->get_fieldname()} AS content
FROM {question} q
INNER JOIN {question_versions} qv
ON qv.questionid = q.id
INNER JOIN {question_bank_entries} qbe
ON qbe.id = qv.questionbankentryid
INNER JOIN {question_categories} qc
ON qc.id = qbe.questioncategoryid
INNER JOIN {context} ctx
ON ctx.id = qc.contextid
WHERE ctx.contextlevel = :module
AND {$DB->sql_like('ctx.path', ':coursecontextpath')}
ORDER BY q.id ASC";
return $DB->get_recordset_sql($sql, $param);
}
/**
* Return an array of area objects that contain content at the site and system levels only. This would be question content from
* question categories at the system context only.
*
* @return \moodle_recordset
* @deprecated since Moodle 5.0.
* @todo MDL-82413 Final deprecation in Moodle 6.0.
*/
#[\core\attribute\deprecated(null, since: '5.0', reason: 'This method should not be used', mdl: 'MDL-71378')]
public function find_system_areas(): ?\moodle_recordset {
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
global $DB;
$params = [
'syscontext' => CONTEXT_SYSTEM,
'coursecat' => CONTEXT_COURSECAT,
'coursecat2' => CONTEXT_COURSECAT,
];
$sql = "SELECT {$this->get_type()} AS type,
qc.contextid AS contextid,
{$this->get_standard_area_fields_sql()}
q.id AS itemid,
" . SITEID . " as courseid,
cc.id as categoryid,
q.{$this->get_fieldname()} AS content
FROM {question} q
INNER JOIN {question_versions} qv
ON qv.questionid = q.id
INNER JOIN {question_bank_entries} qbe
ON qbe.id = qv.questionbankentryid
INNER JOIN {question_categories} qc
ON qc.id = qbe.questioncategoryid
INNER JOIN {context} ctx
ON ctx.id = qc.contextid
LEFT JOIN {course_categories} cc
ON cc.id = ctx.instanceid
AND ctx.contextlevel = :coursecat
WHERE (ctx.contextlevel = :syscontext)
OR (ctx.contextlevel = :coursecat2)
ORDER BY q.id";
return $DB->get_recordset_sql($sql, $params);
}
/**
* Returns the moodle_url of the page to edit the error.
*
* @param \stdClass $componentinfo
* @return \moodle_url
*/
public static function get_edit_url(\stdClass $componentinfo): \moodle_url {
$questionid = $componentinfo->itemid;
// Question answers are editable on main question page.
// Hence, use refid for these links.
if ($componentinfo->tablename === 'question_answers') {
$questionid = $componentinfo->refid;
}
// Default to SITEID if courseid is null, i.e. system or category level questions.
$thiscourseid = ($componentinfo->courseid !== null) ? $componentinfo->courseid : SITEID;
return new \moodle_url('/question/bank/editquestion/question.php', ['courseid' => $thiscourseid, 'id' => $questionid]);
}
/**
* Determine the course and category id SQL depending on the specific context associated with question data.
*
* @param \core\event\base $event
* @return string
*/
protected function get_course_and_cat_sql(\core\event\base $event): string {
$courseid = 'null';
$catid = 'null';
if ($record = self::get_course_and_category(CONTEXT_MODULE, $event->objectid)) {
$courseid = $record->courseid;
}
return "
{$courseid} AS courseid,
{$catid} AS categoryid,
";
}
/**
* Get the course and category data for the question.
*
* @param int $coursemodule
* @param int $refid
* @return \stdClass|false
*/
public static function get_course_and_category($coursemodule, $refid) {
global $DB;
if ($coursemodule !== CONTEXT_MODULE) {
debugging("Invalid contextlevel: ($coursemodule}", DEBUG_DEVELOPER);
}
$sql = 'SELECT ctx.instanceid,
cm.course as courseid,
ctx.contextlevel
FROM {question} q
INNER JOIN {question_versions} qv
ON qv.questionid = q.id
INNER JOIN {question_bank_entries} qbe
ON qbe.id = qv.questionbankentryid
INNER JOIN {question_categories} qc
ON qc.id = qbe.questioncategoryid
INNER JOIN {context} ctx
ON ctx.id = qc.contextid
INNER JOIN {course_modules} cm
ON cm.id = ctx.instanceid
AND ctx.contextlevel = :coursemodule
WHERE q.id = :refid';
$params = [
'coursemodule' => $coursemodule,
'refid' => $refid
];
return $DB->get_record_sql($sql, $params);
}
}
-29
View File
@@ -1,29 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package tool_brickfield
* @copyright 2020 Brickfield Education Labs, https://www.brickfield.ie - Author: Karen Holland
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'tool_brickfield';
$plugin->version = 2025041400;
$plugin->requires = 2025040800;
-169
View File
@@ -1,169 +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/>.
/**
* For a given capability, show what permission it has for every role, and everywhere that it is overridden.
*
* @package tool_capability
* @copyright 2008 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../config.php');
require_once($CFG->dirroot.'/'.$CFG->admin.'/tool/capability/locallib.php');
require_once($CFG->libdir.'/adminlib.php');
// Get URL parameters.
$systemcontext = context_system::instance();
$contextid = optional_param('context', $systemcontext->id, PARAM_INT);
// Check permissions.
list($context, $course, $cm) = get_context_info_array($contextid);
require_login($course, false, $cm);
require_capability('moodle/role:manage', $context);
// Print the header.
admin_externalpage_setup('toolcapability');
// Prepare the list of capabilities to choose from.
$capabilitychoices = array();
foreach ($context->get_capabilities('name') as $cap) {
$capabilitychoices[$cap->name] = $cap->name . ': ' . get_capability_string($cap->name);
}
$allroles = role_fix_names(get_all_roles($context));
// Prepare the list of roles to choose from.
$rolechoices = array('0' => get_string('all'));
foreach ($allroles as $role) {
$rolechoices[$role->id] = $role->localname;
}
$form = new tool_capability_settings_form(null, array(
'capabilities' => $capabilitychoices,
'roles' => $rolechoices
));
$PAGE->requires->js_call_amd('tool_capability/search', 'init');
// Log.
$capabilities = array();
$rolestoshow = array();
$roleids = array('0');
$cleanedroleids = array();
$onlydiff = false;
if ($data = $form->get_data()) {
$roleids = array();
if (!empty($data->roles)) {
$roleids = $data->roles;
}
$capabilities = array();
if (!empty($data->capability)) {
$capabilities = $data->capability;
}
if (in_array('0', $roleids)) {
$rolestoshow = $allroles;
} else {
$cleanedroleids = array_intersect(array_keys($allroles), $roleids);
if (count($cleanedroleids) === 0) {
$rolestoshow = $allroles;
} else {
foreach ($cleanedroleids as $id) {
$rolestoshow[$id] = $allroles[$id];
}
}
}
if (isset($data->onlydiff)) {
$onlydiff = $data->onlydiff;
}
}
\tool_capability\event\report_viewed::create()->trigger();
$renderer = $PAGE->get_renderer('tool_capability');
echo $OUTPUT->header();
$form->display();
// If we have a capability, generate the report.
if (count($capabilities) && count($rolestoshow)) {
/* @var tool_capability_renderer $renderer */
echo $renderer->capability_comparison_table($capabilities, $context->id, $rolestoshow, $onlydiff);
}
// Footer.
echo $OUTPUT->footer();
function print_report_tree($contextid, $contexts, $allroles) {
global $CFG;
// Array for holding lang strings.
static $strpermissions = null;
if (is_null($strpermissions)) {
$strpermissions = array(
CAP_INHERIT => get_string('notset','role'),
CAP_ALLOW => get_string('allow','role'),
CAP_PREVENT => get_string('prevent','role'),
CAP_PROHIBIT => get_string('prohibit','role')
);
}
// Start the list item, and print the context name as a link to the place to
// make changes.
if ($contextid == context_system::instance()->id) {
$url = "$CFG->wwwroot/$CFG->admin/roles/manage.php";
$title = get_string('changeroles', 'tool_capability');
} else {
$url = "$CFG->wwwroot/$CFG->admin/roles/override.php?contextid=$contextid";
$title = get_string('changeoverrides', 'tool_capability');
}
$context = context::instance_by_id($contextid);
echo '<h3><a href="' . $url . '" title="' . $title . '">', $context->get_context_name(), '</a></h3>';
// If there are any role overrides here, print them.
if (!empty($contexts[$contextid]->rolecapabilities)) {
$rowcounter = 0;
echo '<table class="generaltable table-striped"><tbody>';
foreach ($allroles as $role) {
if (isset($contexts[$contextid]->rolecapabilities[$role->id])) {
$permission = $contexts[$contextid]->rolecapabilities[$role->id];
echo '<tr class="r' . ($rowcounter % 2) . '"><th class="cell">', $role->localname,
'</th><td class="cell">' . $strpermissions[$permission] . '</td></tr>';
$rowcounter++;
}
}
echo '</tbody></table>';
}
// After we have done the site context, change the string for CAP_INHERIT
// from 'notset' to 'inherit'.
$strpermissions[CAP_INHERIT] = get_string('inherit','role');
// If there are any child contexts, print them recursively.
if (!empty($contexts[$contextid]->children)) {
echo '<ul>';
foreach ($contexts[$contextid]->children as $childcontextid) {
echo '<li>';
print_report_tree($childcontextid, $contexts, $allroles);
echo '</li>';
}
echo '</ul>';
}
}
-158
View File
@@ -1,158 +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/>.
/**
* Capability tool renderer.
*
* @package tool_capability
* @copyright 2013 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* The primary renderer for the capability tool.
*
* @copyright 2013 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_capability_renderer extends plugin_renderer_base {
/**
* Returns an array of permission strings.
*
* @return lang_string[]
*/
protected function get_permission_strings() {
static $strpermissions;
if (!$strpermissions) {
$strpermissions = array(
CAP_INHERIT => new lang_string('inherit', 'role'),
CAP_ALLOW => new lang_string('allow', 'role'),
CAP_PREVENT => new lang_string('prevent', 'role'),
CAP_PROHIBIT => new lang_string('prohibit', 'role')
);
}
return $strpermissions;
}
/**
* Returns an array of permission CSS classes.
*
* @return string[]
*/
protected function get_permission_classes() {
static $permissionclasses;
if (!$permissionclasses) {
$permissionclasses = array(
CAP_INHERIT => 'inherit',
CAP_ALLOW => 'allow',
CAP_PREVENT => 'prevent',
CAP_PROHIBIT => 'prohibit',
);
}
return $permissionclasses;
}
/**
* Produces a table to visually compare roles and capabilities.
*
* @param array $capabilities An array of capabilities to show comparison for.
* @param int $contextid The context we are displaying for.
* @param array $roles An array of roles to show comparison for.
* @param bool $onlydiff show only different permissions
* @return string
*/
public function capability_comparison_table(array $capabilities, $contextid, array $roles, $onlydiff=false) {
static $capabilitycontexts = array();
$strpermissions = $this->get_permission_strings();
$permissionclasses = $this->get_permission_classes();
if ($contextid === context_system::instance()->id) {
$strpermissions[CAP_INHERIT] = new lang_string('notset', 'role');
}
$table = new html_table();
$table->attributes['class'] = 'comparisontable';
$table->head = array('&nbsp;');
foreach ($roles as $role) {
$url = new moodle_url('/admin/roles/define.php', array('action' => 'view', 'roleid' => $role->id));
$table->head[] = html_writer::div(html_writer::link($url, $role->localname));
}
$table->data = array();
$childcontextsids = [];
foreach ($capabilities as $capability) {
if (empty($capabilitycontexts[$capability])) {
$capabilitycontexts[$capability] = tool_capability_calculate_role_data($capability, $roles);
}
$contexts = $capabilitycontexts[$capability];
$captitle = new html_table_cell(get_capability_string($capability) . html_writer::span($capability));
$captitle->header = true;
$row = new html_table_row(array($captitle));
$permissiontypes = array();
foreach ($roles as $role) {
if (isset($contexts[$contextid]->rolecapabilities[$role->id])) {
$permission = $contexts[$contextid]->rolecapabilities[$role->id];
} else {
$permission = CAP_INHERIT;
}
if (!in_array($permission, $permissiontypes)) {
$permissiontypes[] = $permission;
}
$cell = new html_table_cell($strpermissions[$permission]);
$cell->attributes['class'] = $permissionclasses[$permission];
$row->cells[] = $cell;
}
if (!$onlydiff || count($permissiontypes) > 1) {
$table->data[] = $row;
}
if (!empty($contexts[$contextid]->children)) {
$childcontextsids = array_merge($childcontextsids, $contexts[$contextid]->children);
$childcontextsids = array_unique($childcontextsids);
}
}
// Start the list item, and print the context name as a link to the place to make changes.
$context = context::instance_by_id($contextid);
if ($context instanceof context_system) {
$url = new moodle_url('/admin/roles/manage.php');
} else {
$url = new moodle_url('/admin/roles/permissions.php', ['contextid' => $contextid]);
}
$title = get_string('permissionsincontext', 'core_role', $context->get_context_name());
$html = $this->output->heading(html_writer::link($url, $title), 3);
if (!empty($table->data)) {
$html .= html_writer::table($table);
} else {
$html .= html_writer::tag('p', get_string('nodifferences', 'tool_capability'));
}
// If there are any child contexts, print them recursively.
if (!empty($childcontextsids)) {
foreach ($childcontextsids as $childcontextid) {
$html .= $this->capability_comparison_table($capabilities, $childcontextid, $roles, $onlydiff);
}
}
return $html;
}
}
-29
View File
@@ -1,29 +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/>.
/**
* Version details.
*
* @package tool_capability
* @copyright 2011 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_capability'; // Full name of the plugin (used for diagnostics).
-55
View File
@@ -1,55 +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/>.
/**
* Plugin upgrade code
*
* @package tool_cohortroles
* @copyright 2020 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Function to upgrade tool_cohortroles.
*
* @param int $oldversion the version we are upgrading from
* @return bool result
*/
function xmldb_tool_cohortroles_upgrade($oldversion) {
global $DB;
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2023042401) {
// Delete any tool_cohortroles mappings for users who no longer exist.
$DB->delete_records_select('tool_cohortroles', 'userid NOT IN (SELECT id FROM {user} WHERE deleted = 0)');
// Cohortroles savepoint reached.
upgrade_plugin_savepoint(true, 2023042401, 'tool', 'cohortroles');
}
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.5.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
-29
View File
@@ -1,29 +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/>.
/**
* Plugin version info
*
* @package tool_cohortroles
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_cohortroles'; // Full name of the plugin (used for diagnostics).
-73
View File
@@ -1,73 +0,0 @@
languageCode: "en"
title: "Moodle Component Library"
baseURL: "http://MOODLEROOT/"
enableInlineShortcodes: true
pygmentsUseClasses: true
markup:
goldmark:
renderer:
unsafe: true
markup:
goldmark:
extensions:
definitionList: true
footnote: true
linkify: true
strikethrough: true
table: true
taskList: true
typographer: true
parser:
attribute: true
autoHeadingID: true
autoHeadingIDType: github
renderer:
hardWraps: false
unsafe: true
xHTML: false
highlight:
codeFences: true
guessSyntax: true
hl_Lines: ""
lineNoStart: 1
lineNos: false
lineNumbersInTable: true
noClasses: true
style: monokailight
tabWidth: 4
buildDrafts: false
buildFuture: true
enableRobotsTXT: true
metaDataFormat: "yaml"
disableKinds: ["404", "taxonomy", "taxonomyTerm", "RSS"]
blackfriday:
fractions: false
relativeURLs: true
publishDir: "./admin/tool/componentlibrary/docs"
archetypeDir: "./admin/tool/componentlibrary/hugo/archetypes"
assetDir: "./admin/tool/componentlibrary/hugo/assets"
contentDir: "./admin/tool/componentlibrary/content"
dataDir: "./admin/tool/componentlibrary/hugo/site/data"
layoutDir: "./admin/tool/componentlibrary/hugo/site/layouts"
staticDir: "./admin/tool/componentlibrary/content/static"
params:
moodleroot: "MOODLEROOT"
current_version: "4.6.2"
current_ruby_version: "4.6.2"
docs_version: "4.6"
boostrap_docs: "https://getbootstrap.com/docs/4.6"
repo: "https://github.com/twbs/bootstrap"
cdn:
# See https://www.srihash.org for info on how to generate the hashes
popper: "https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
@@ -1,159 +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/>.
/**
* Moodle Component Library
*
* A sample of a default action menu.
*
* @package tool_componentlibrary
* @copyright 2023 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
declare(strict_types=1);
require_once(__DIR__ . '/../../../../config.php');
global $PAGE;
$PAGE->set_url(new moodle_url('/admin/tool/componentlibrary/examples/actionmenu.php'));
$PAGE->set_context(context_system::instance());
$PAGE->set_pagelayout('embedded');
$PAGE->set_heading('Moodle action menus');
$PAGE->set_title('Moodle action menus');
/** @var core_renderer $output*/
$output = $PAGE->get_renderer('core');
// Some menu items require as renderable element. This is just an
// example of a choice list but it can be any other renderable.
$choice = new core\output\choicelist('Choice example');
$choice->add_option("statusa", "Status A", [
'url' => $PAGE->url,
'description' => 'Status A description',
'icon' => new pix_icon('t/user', '', ''),
]);
$choice->add_option("statusb", "Status B", [
'url' => $PAGE->url,
'description' => 'Status B description',
'icon' => new pix_icon('t/groupv', '', ''),
]);
$choice->set_selected_value('statusb');
// Those are some examples of action items.
// Action menu links is the most used action item.
$basicactionlink = new action_menu_link(
new moodle_url($PAGE->url),
new pix_icon('t/emptystar', ''),
'Action link example',
false
);
// Subpanels display lateral panels on hovered or clicked.
$subpanel = new core\output\local\action_menu\subpanel(
'Subpanel example',
$choice
);
echo $output->header();
echo '<p><strong>Important note:</strong> actions menus are not prepared
to be displayed inside iframes. You may need to scroll to see the
action menu options.</p>';
echo $output->heading("Action menu default example", 4);
$menu = new action_menu();
$menu->add($basicactionlink);
$menu->add($basicactionlink);
$menu->add($subpanel);
$menu->add($basicactionlink);
echo '<div class="border m-3 p-3 d-flex flex-row">';
echo '<div class="flex-fill">Example of default an action menu</div><div>';
echo $OUTPUT->render($menu);
echo '</div></div>';
echo $output->heading("Kebab menu example", 4);
$menu = new action_menu();
$menu->set_kebab_trigger(get_string('edit'), $output);
$menu->set_additional_classes('fields-actions');
$menu->add($basicactionlink);
$menu->add($basicactionlink);
$menu->add(new core\output\local\action_menu\subpanel(
'Subpanel example',
$choice
));
$menu->add($basicactionlink);
echo '<div class="border m-3 p-3 d-flex flex-row">';
echo '<div class="flex-fill">Example of kebab menu</div><div>';
echo $OUTPUT->render($menu);
echo '</div></div>';
echo $output->heading("Custom trigger menu example", 4);
$menu = new action_menu();
$menu->set_menu_trigger(get_string('edit'));
$menu->add($basicactionlink);
$menu->add($basicactionlink);
$menu->add(new core\output\local\action_menu\subpanel(
'Subpanel example',
$choice
));
$menu->add($basicactionlink);
echo '<div class="border m-3 p-3 d-flex flex-row">';
echo '<div class="flex-fill">Example of kebab menu</div><div>';
echo $OUTPUT->render($menu);
echo '</div></div>';
echo $output->heading("Primary actions menu example", 4);
$menu = new action_menu();
$menu->set_menu_trigger(get_string('edit'));
$menu->add($basicactionlink);
$menu->add($basicactionlink);
$menu->add(new core\output\local\action_menu\subpanel(
'Subpanel example',
$choice
));
$menu->add($basicactionlink);
$menu->add(new action_menu_link_primary(
$PAGE->url,
new pix_icon('t/emptystar', ''),
'Action link example',
));
$menu->add(new action_menu_link_primary(
$PAGE->url,
new pix_icon('t/user', ''),
'Action link example',
));
echo '<div class="border m-3 p-3 d-flex flex-row">';
echo '<div class="flex-fill">Example of a menu with primary actions</div><div>';
echo $OUTPUT->render($menu);
echo '</div></div>';
echo $output->footer();
File diff suppressed because one or more lines are too long
-26
View File
@@ -1,26 +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/>.
/**
* Plugin version info
*
* @package tool_componentlibrary
* @copyright 2021 Bas Brands <bas@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_componentlibrary';
-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/>.
/**
* Language customization report upgrades
*
* @package tool
* @subpackage customlang
* @copyright 2010 David Mudrak <david.mudrak@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
function xmldb_tool_customlang_upgrade($oldversion) {
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.5.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
-30
View File
@@ -1,30 +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/>.
/**
* Version information
*
* @package tool
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400;
$plugin->requires = 2025040800;
$plugin->component = 'tool_customlang'; // Full name of the plugin (used for diagnostics)
-110
View File
@@ -1,110 +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/>.
/**
* tool_dataprivacy plugin upgrade code
*
* @package tool_dataprivacy
* @copyright 2018 Jun Pataleta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Function to upgrade tool_dataprivacy.
*
* @param int $oldversion the version we are upgrading from
* @return bool result
*/
function xmldb_tool_dataprivacy_upgrade($oldversion) {
global $CFG, $DB;
$dbman = $DB->get_manager();
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2023062700) {
// Define table tool_dataprivacy_contextlist to be created.
$table = new xmldb_table('tool_dataprivacy_contextlist');
// Adding fields to table tool_dataprivacy_contextlist.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('component', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
// Adding keys to table tool_dataprivacy_contextlist.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
// Conditionally launch create table for tool_dataprivacy_contextlist.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table tool_dataprivacy_ctxlst_ctx to be created.
$table = new xmldb_table('tool_dataprivacy_ctxlst_ctx');
// Adding fields to table tool_dataprivacy_ctxlst_ctx.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('contextlistid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('status', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0');
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
// Adding keys to table tool_dataprivacy_ctxlst_ctx.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
$table->add_key('contextlistid', XMLDB_KEY_FOREIGN, ['contextlistid'], 'tool_dataprivacy_contextlist', ['id']);
// Conditionally launch create table for tool_dataprivacy_ctxlst_ctx.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table tool_dataprivacy_rqst_ctxlst to be created.
$table = new xmldb_table('tool_dataprivacy_rqst_ctxlst');
// Adding fields to table tool_dataprivacy_rqst_ctxlst.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('requestid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('contextlistid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
// Adding keys to table tool_dataprivacy_rqst_ctxlst.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
$table->add_key('requestid', XMLDB_KEY_FOREIGN, ['requestid'], 'tool_dataprivacy_request', ['id']);
$table->add_key('contextlistid', XMLDB_KEY_FOREIGN, ['contextlistid'], 'tool_dataprivacy_contextlist', ['id']);
$table->add_key('requestidcontextlistid', XMLDB_KEY_UNIQUE, ['requestid', 'contextlistid']);
// Conditionally launch create table for tool_dataprivacy_rqst_ctxlst.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Dataprivacy savepoint reached.
upgrade_plugin_savepoint(true, 2023062700, 'tool', 'dataprivacy');
}
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.5.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
File diff suppressed because it is too large Load Diff
-29
View File
@@ -1,29 +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/>.
/**
* Data privacy plugin version information
*
* @package tool_dataprivacy
* @copyright 2018 onwards Jun Pataleta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
$plugin->version = 2025041400;
$plugin->requires = 2025040800;
$plugin->component = 'tool_dataprivacy';
-29
View File
@@ -1,29 +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/>.
/**
* Version details.
*
* @package tool_dbtransfer
* @copyright 2008 Petr Skoda {@link http://skodak.org/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_dbtransfer'; // Full name of the plugin (used for diagnostics).
-25
View File
@@ -1,25 +0,0 @@
/**
* Styles for admin tool page.
*/
/* Fix bad default table wrap (caused by the long mimetype field). */
.path-admin-tool-filetypes .generaltable .c0,
.path-admin-tool-filetypes .generaltable .c1,
.path-admin-tool-filetypes .generaltable .c2,
.path-admin-tool-filetypes .generaltable th {
white-space: nowrap;
}
/* Formatting for deleted lines. */
.path-admin-tool-filetypes .generaltable .deleted .c0 img {
opacity: 0.2;
}
.path-admin-tool-filetypes .generaltable .deleted .c0 span {
text-decoration: line-through;
}
/* Custom types show bold */
.path-admin-tool-filetypes .generaltable .nonstandard {
font-weight: bold;
}
-29
View File
@@ -1,29 +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/>.
/**
* Version details.
*
* @package tool_filetypes
* @copyright 2014 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400;
$plugin->requires = 2025040800;
$plugin->component = 'tool_filetypes';
-29
View File
@@ -1,29 +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/>.
/**
* Version details.
*
* @package tool_generator
* @copyright 2013 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400;
$plugin->requires = 2025040800;
$plugin->component = 'tool_generator';
-29
View File
@@ -1,29 +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/>.
/**
* Version details.
*
* @package tool_httpsreplace
* @copyright Copyright (c) 2016 Blackboard Inc. (http://www.blackboard.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_httpsreplace'; // Full name of the plugin (used for diagnostics).
-29
View File
@@ -1,29 +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/>.
/**
* @package tool_installaddon
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'tool_installaddon';
$plugin->version = 2025041400;
$plugin->requires = 2025040800;
$plugin->maturity = MATURITY_STABLE;
-30
View File
@@ -1,30 +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/>.
/**
* Version details.
*
* @package tool
* @subpackage langimport
* @copyright 2011 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_langimport'; // Full name of the plugin (used for diagnostics)
@@ -1,196 +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/>.
/**
* Renderable for display of license manager table.
*
* @package tool_licensemanager
* @copyright 2020 Tom Dickman <tomdickman@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_licensemanager\output;
use html_table;
use html_table_cell;
use html_table_row;
use html_writer;
use license_manager;
defined('MOODLE_INTERNAL') || die();
/**
* Renderable for display of license manager table.
*
* @package tool_licensemanager
* @copyright 2020 Tom Dickman <tomdickman@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class table implements \renderable {
/**
* 'Create License' link.
*
* @return string HTML string.
*/
public function create_license_link() {
$link = html_writer::link(\tool_licensemanager\helper::get_create_license_url(),
get_string('createlicensebuttontext', 'tool_licensemanager'),
['class' => 'btn btn-secondary mb-3']);
return $link;
}
/**
* Create the HTML table for license management.
*
* @param array $licenses
* @param \renderer_base $output
*
* @return string HTML for license manager table.
*/
public function create_license_manager_table(array $licenses, \renderer_base $output) {
$table = new html_table();
$table->head = [
get_string('enable'),
get_string('license', 'tool_licensemanager'),
get_string('version'),
get_string('order'),
get_string('edit'),
get_string('delete'),
];
$table->colclasses = [
'text-center',
'text-start',
'text-start',
'text-center',
'text-center',
'text-center',
];
$table->id = 'manage-licenses';
$table->attributes['class'] = 'admintable generaltable';
$table->data = [];
$rownumber = 0;
$rowcount = count($licenses);
foreach ($licenses as $key => $value) {
$canmoveup = $rownumber > 0;
$canmovedown = $rownumber < $rowcount - 1;
$table->data[] = $this->get_license_table_row_data($value, $canmoveup, $canmovedown, $output);
$rownumber++;
}
$html = html_writer::table($table);
return $html;
}
/**
* Get table row data for a license.
*
* @param object $license the license to populate row data for.
* @param bool $canmoveup can this row move up.
* @param bool $canmovedown can this row move down.
* @param \renderer_base $output the renderer
*
* @return \html_table_row of columns values for row.
*/
protected function get_license_table_row_data($license, bool $canmoveup, bool $canmovedown, \renderer_base $output) {
global $CFG;
$summary = $license->fullname . ' ('. $license->shortname . ')';
if (!empty($license->source)) {
$summary .= html_writer::empty_tag('br');
$summary .= html_writer::link($license->source, $license->source, ['target' => '_blank']);
}
$summarycell = new html_table_cell($summary);
$summarycell->attributes['class'] = 'license-summary';
$versioncell = new html_table_cell($license->version);
$versioncell->attributes['class'] = 'license-version';
$deletelicense = '';
if ($license->shortname == $CFG->sitedefaultlicense) {
$hideshow = $output->pix_icon('t/locked', get_string('sitedefaultlicenselock', 'tool_licensemanager'));
} else {
if ($license->enabled == license_manager::LICENSE_ENABLED) {
$hideshow = html_writer::link(\tool_licensemanager\helper::get_disable_license_url($license->shortname),
$output->pix_icon('t/hide', get_string('disablelicensename', 'tool_licensemanager', $license->fullname)));
} else {
$hideshow = html_writer::link(\tool_licensemanager\helper::get_enable_license_url($license->shortname),
$output->pix_icon('t/show', get_string('enablelicensename', 'tool_licensemanager', $license->fullname)));
}
if ($license->custom == license_manager::CUSTOM_LICENSE) {
$deletelink = new \moodle_url('/admin/tool/licensemanager/index.php', [
'action' => 'delete',
'license' => $license->shortname,
'sesskey' => sesskey(),
]);
$deletelicense = html_writer::link(
url: '#',
text: $output->pix_icon('i/trash', get_string('deletelicensename', 'tool_licensemanager', $license->fullname)),
attributes: [
'class' => 'delete-license',
'data-modal' => 'confirmation',
'data-modal-title-str' => json_encode(['deletelicense', 'tool_licensemanager']),
'data-modal-content-str' => json_encode(['deletelicenseconfirmmessage', 'tool_licensemanager']),
'data-modal-destination' => $deletelink->out(false),
],
);
}
}
$hideshowcell = new html_table_cell($hideshow);
$hideshowcell->attributes['class'] = 'license-status';
if ($license->custom == license_manager::CUSTOM_LICENSE) {
$editlicense = html_writer::link(\tool_licensemanager\helper::get_update_license_url($license->shortname),
$output->pix_icon('t/editinline', get_string('editlicensename', 'tool_licensemanager', $license->fullname)),
['class' => 'edit-license']);
} else {
$editlicense = '';
}
$editlicensecell = new html_table_cell($editlicense);
$editlicensecell->attributes['class'] = 'edit-license';
$spacer = $output->pix_icon('spacer', '', 'moodle', ['class' => 'iconsmall']);
$updown = '';
if ($canmoveup) {
$updown .= html_writer::link(\tool_licensemanager\helper::get_moveup_license_url($license->shortname),
$output->pix_icon('t/up', get_string('movelicenseupname', 'tool_licensemanager', $license->fullname),
'moodle', ['class' => 'iconsmall']),
['class' => 'move-up']) . '';
} else {
$updown .= $spacer;
}
if ($canmovedown) {
$updown .= '&nbsp;'.html_writer::link(\tool_licensemanager\helper::get_movedown_license_url($license->shortname),
$output->pix_icon('t/down', get_string('movelicensedownname', 'tool_licensemanager', $license->fullname),
'moodle', ['class' => 'iconsmall']),
['class' => 'move-down']);
} else {
$updown .= $spacer;
}
$updowncell = new html_table_cell($updown);
$updowncell->attributes['class'] = 'license-order';
$row = new html_table_row([$hideshowcell, $summarycell, $versioncell, $updowncell, $editlicensecell, $deletelicense]);
$row->attributes['data-license'] = $license->shortname;
$row->attributes['class'] = strtolower(get_string('license', 'tool_licensemanager'));
return $row;
}
}
-31
View File
@@ -1,31 +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/>.
/**
* Version details for component 'tool_licensemanager'.
*
* @package tool_licensemanager
* @copyright Tom Dickman <tomdickman@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400;
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_licensemanager';
$plugin->maturity = MATURITY_STABLE;
-45
View File
@@ -1,45 +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/>.
/**
* Logging support.
*
* @package tool_log
* @copyright 2014 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Upgrade the plugin.
*
* @param int $oldversion
* @return bool always true
*/
function xmldb_tool_log_upgrade($oldversion) {
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.5.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
@@ -1,39 +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/>.
/**
* Database log store upgrade.
*
* @package logstore_database
* @copyright 2014 onwards Ankit Agarwal <ankit.agrr@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
function xmldb_logstore_database_upgrade($oldversion) {
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.5.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
-29
View File
@@ -1,29 +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/>.
/**
* External database log store.
*
* @package logstore_database
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'logstore_database'; // Full name of the plugin (used for diagnostics).
@@ -1,39 +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/>.
/**
* Standard log store upgrade.
*
* @package logstore_standard
* @copyright 2014 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
function xmldb_logstore_standard_upgrade($oldversion) {
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.5.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
-29
View File
@@ -1,29 +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/>.
/**
* Standard log store.
*
* @package logstore_standard
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'logstore_standard'; // Full name of the plugin (used for diagnostics).
-29
View File
@@ -1,29 +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/>.
/**
* Default log manager.
*
* @package tool_log
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_log'; // Full name of the plugin (used for diagnostics).
-264
View File
@@ -1,264 +0,0 @@
.path-admin-tool-lp [data-region="managecompetencies"] ul li,
.path-admin-tool-lp [data-region="plans"] ul li,
.path-admin-tool-lp [data-region="competencymovetree"] ul li,
.path-admin-tool-lp [data-region="competencylinktree"] ul li,
.path-badges [data-region="competencylinktree"] ul li {
list-style-type: none;
}
.path-admin-tool-lp .progresstext {
display: inline-block;
vertical-align: top;
}
.path-admin-tool-lp .progress {
width: 100%;
display: inline-block;
}
.path-admin-tool-lp .progress .bar {
min-width: 3em;
}
.path-admin-tool-lp [data-region="managecompetencies"] ul[data-enhance="tree"],
.path-admin-tool-lp [data-region="plans"] ul[data-enhance="tree"],
.path-admin-tool-lp [data-region="competencylinktree"] ul[data-enhance="linktree"],
.path-badges [data-region="competencylinktree"] ul[data-enhance="linktree"],
.path-admin-tool-lp [data-region="competencymovetree"] ul[data-enhance="movetree"] {
border: 1px solid #ccc;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
transition: border linear .2s, box-shadow linear .2s;
border-radius: 4px;
padding-left: 20px;
padding-right: 20px;
margin-left: 10px;
margin-right: 10px;
}
.path-admin-tool-lp [data-region="managecompetencies"] ul,
.path-admin-tool-lp [data-region="plans"] ul,
.path-admin-tool-lp [data-region="competencylinktree"] ul,
.path-badges [data-region="competencylinktree"] ul,
.path-admin-tool-lp [data-region="competencymovetree"] ul {
cursor: pointer;
}
.path-admin-tool-lp [data-region="competencylinktree"] ul li > span,
.path-badges [data-region="competencylinktree"] ul li > span,
.path-admin-tool-lp [data-region="competencymovetree"] ul li > span,
.path-admin-tool-lp [data-region="plans"] ul li > span,
.path-admin-tool-lp [data-region="managecompetencies"] ul li > span {
padding-top: 2px;
padding-bottom: 2px;
padding-left: 4px;
padding-right: 4px;
border-radius: 4px;
}
.path-admin-tool-lp [data-region="competencylinktree"] ul [aria-selected="true"] > span,
.path-badges [data-region="competencylinktree"] ul [aria-selected="true"] > span,
.path-admin-tool-lp [data-region="competencymovetree"] ul [aria-selected="true"] > span,
.path-admin-tool-lp [data-region="plans"] ul [aria-selected="true"] > span,
.path-admin-tool-lp [data-region="managecompetencies"] ul [aria-selected="true"] > span {
background-color: #dfdfdf;
}
.path-admin-tool-lp [data-region="competencylinktree"] ul [tabindex="0"] > span,
.path-badges [data-region="competencylinktree"] ul [tabindex="0"] > span,
.path-admin-tool-lp [data-region="competencymovetree"] ul [tabindex="0"] > span,
.path-admin-tool-lp [data-region="plans"] ul [tabindex="0"] > span,
.path-admin-tool-lp [data-region="managecompetencies"] ul [tabindex="0"] > span {
border: 2px solid #0070a8;
}
.path-admin-tool-lp [data-region="filtercompetencies"] input {
margin-left: 10px;
}
.path-admin-tool-lp [data-region="link-buttons"],
.path-admin-tool-lp [data-region="move-buttons"] {
text-align: center;
}
.path-admin-tool-lp [data-region="competencylinktree"] > ul,
.path-badges [data-region="competencylinktree"] > ul {
overflow-y: auto;
height: 400px;
}
.path-admin-tool-lp span.currentdragtarget {
border: 1px dashed;
}
.path-admin-tool-lp .competencyactionsmenu {
display: inline-block;
vertical-align: text-top;
}
.path-admin-tool-lp [data-region="competencyruleconfig"] [data-region="rule-base"] {
display: table;
width: 100%;
}
.path-admin-tool-lp [data-region="competencyruleconfig"] [data-region="rule-outcome"],
.path-admin-tool-lp [data-region="competencyruleconfig"] [data-region="rule-type"] {
display: table-row;
}
.path-admin-tool-lp [data-region="competencyruleconfig"] [data-region="rule-outcome"] label,
.path-admin-tool-lp [data-region="competencyruleconfig"] [data-region="rule-type"] label {
padding-right: 10px;
}
.path-admin-tool-lp [data-region="competencyruleconfig"] [data-region="rule-outcome"] label,
.path-admin-tool-lp [data-region="competencyruleconfig"] [data-region="rule-outcome"] select,
.path-admin-tool-lp [data-region="competencyruleconfig"] [data-region="rule-type"] label,
.path-admin-tool-lp [data-region="competencyruleconfig"] [data-region="rule-type"] select {
display: table-cell;
}
.path-admin-tool-lp [data-region="competencyruleconfig"] [data-region="rule-outcome"] select,
.path-admin-tool-lp [data-region="competencyruleconfig"] [data-region="rule-type"] select,
.path-admin-tool-lp [data-region="competencylinktree"] select,
.path-badges [data-region="competencylinktree"] select {
width: 100%;
}
.path-admin-tool-lp [data-region] .generaltable.fullwidth {
clear: both;
}
.path-admin-tool-lp .competency-rule-points {
margin-top: 10px;
max-height: 300px;
overflow-y: auto;
}
.path-admin-tool-lp .competency-rule-points table input {
margin-bottom: 0;
}
.path-admin-tool-lp .competency-rule-points tr[data-competency] th {
font-weight: normal;
}
.path-admin-tool-lp .competency-rule-points input[type="number"] {
width: 50px;
}
.competency-heading {
margin-bottom: 15px;
}
.competency-heading h4 {
margin: 0;
}
/** Styles required for menubar js */
.tool-lp-menu {
margin: 0;
}
.tool-lp-menu li {
float: left;
position: relative;
list-style-type: none;
white-space: nowrap;
}
.tool-lp-sub-menu {
position: absolute;
list-style: none;
margin: 0;
top: -10px;
}
.tool-lp-sub-menu li {
float: none;
}
.tool-lp-menu .tool-lp-sub-menu[aria-hidden=false] {
display: block;
}
.tool-lp-menu ul[aria-hidden=true] {
display: none;
}
.tool-lp-menu .caret {
margin: 8px;
}
.tool-lp-menu.tool-lp-menu-open-left .tool-lp-sub-menu {
left: auto;
right: 0;
}
/** This highlighting is copied from bootstrap - but can be overridden by a theme */
.tool-lp-menu .tool-lp-sub-menu .menu-focus a {
color: #fff;
text-decoration: none;
background-color: #00699e;
background-image: linear-gradient(to bottom, #0070a8, #005f8f);
background-repeat: repeat-x;
}
/** check box and radio button on configure scale dialogue */
input[type="radio"].tool_lp_scale_default,
input[type="checkbox"].tool_lp_scale_proficient {
margin-top: 0;
}
/** User evidence */
.user-evidence-documents {
margin: 10px 20px;
list-style: none;
}
.user-evidence-competencies,
.user-evidence-documents li {
margin-bottom: 5px;
word-break: break-all;
}
[data-region="user-evidence-list"] .user-evidence-competencies,
[data-region="user-evidence-list"] .user-evidence-documents {
margin: 0;
list-style: none;
}
.user-competency-course-navigation select {
display: none;
}
.user-competency-course-navigation span {
max-width: 100%;
overflow: hidden;
}
/** Competency grader */
.competency-grader textarea {
width: 100%;
max-width: 100%;
box-sizing: border-box;
}
.path-admin-tool-lp #region-main {
overflow-x: visible;
}
ul.competency-tree img {
width: 16px;
height: 16px;
}
[data-region="managecompetencies"] a .icon,
[data-region="plan-page"] a .icon {
color: initial;
}
[data-region="managecompetencies"] h2 a .icon,
[data-region="plan-page"] h2 a .icon {
font-size: smaller;
}
-482
View File
@@ -1,482 +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 tool_lp;
use core_competency\api;
use core_external\external_api;
use externallib_advanced_testcase;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* External learning plans webservice API tests.
*
* @package tool_lp
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class externallib_test extends externallib_advanced_testcase {
/** @var \stdClass $creator User with enough permissions to create insystem context. */
protected $creator = null;
/** @var \stdClass $catcreator User with enough permissions to create incategory context. */
protected $catcreator = null;
/** @var \stdClass $category Category */
protected $category = null;
/** @var \stdClass $category Category */
protected $othercategory = null;
/** @var \stdClass $user User with enough permissions to view insystem context */
protected $user = null;
/** @var \stdClass $catuser User with enough permissions to view incategory context */
protected $catuser = null;
/** @var int Creator role id */
protected $creatorrole = null;
/** @var int User role id */
protected $userrole = null;
/**
* Setup function- we will create a course and add an assign instance to it.
*/
protected function setUp(): void {
global $DB, $CFG;
parent::setUp();
$this->resetAfterTest(true);
// Create some users.
$creator = $this->getDataGenerator()->create_user();
$user = $this->getDataGenerator()->create_user();
$catuser = $this->getDataGenerator()->create_user();
$catcreator = $this->getDataGenerator()->create_user();
$category = $this->getDataGenerator()->create_category();
$othercategory = $this->getDataGenerator()->create_category();
$syscontext = \context_system::instance();
$catcontext = \context_coursecat::instance($category->id);
// Fetching default authenticated user role.
$authrole = $DB->get_record('role', array('id' => $CFG->defaultuserroleid));
// Reset all default authenticated users permissions.
unassign_capability('moodle/competency:competencygrade', $authrole->id);
unassign_capability('moodle/competency:competencymanage', $authrole->id);
unassign_capability('moodle/competency:competencyview', $authrole->id);
unassign_capability('moodle/competency:planmanage', $authrole->id);
unassign_capability('moodle/competency:planmanagedraft', $authrole->id);
unassign_capability('moodle/competency:planmanageown', $authrole->id);
unassign_capability('moodle/competency:planview', $authrole->id);
unassign_capability('moodle/competency:planviewdraft', $authrole->id);
unassign_capability('moodle/competency:planviewown', $authrole->id);
unassign_capability('moodle/competency:planviewowndraft', $authrole->id);
unassign_capability('moodle/competency:templatemanage', $authrole->id);
unassign_capability('moodle/competency:templateview', $authrole->id);
unassign_capability('moodle/cohort:manage', $authrole->id);
unassign_capability('moodle/competency:coursecompetencyconfigure', $authrole->id);
// Creating specific roles.
$this->creatorrole = create_role('Creator role', 'lpcreatorrole', 'learning plan creator role description');
$this->userrole = create_role('User role', 'lpuserrole', 'learning plan user role description');
assign_capability('moodle/competency:competencymanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:coursecompetencyconfigure', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:planmanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:planmanagedraft', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:planview', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:templatemanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:competencygrade', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/cohort:manage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:competencyview', CAP_ALLOW, $this->userrole, $syscontext->id);
assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontext->id);
assign_capability('moodle/competency:planviewown', CAP_ALLOW, $this->userrole, $syscontext->id);
assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);
role_assign($this->creatorrole, $creator->id, $syscontext->id);
role_assign($this->creatorrole, $catcreator->id, $catcontext->id);
role_assign($this->userrole, $user->id, $syscontext->id);
role_assign($this->userrole, $catuser->id, $catcontext->id);
$this->creator = $creator;
$this->catcreator = $catcreator;
$this->user = $user;
$this->catuser = $catuser;
$this->category = $category;
$this->othercategory = $othercategory;
accesslib_clear_all_caches_for_unit_testing();
}
public function test_search_users_by_capability(): void {
global $CFG;
$this->resetAfterTest(true);
$dg = $this->getDataGenerator();
$ux = $dg->create_user();
$u1 = $dg->create_user(array('idnumber' => 'Cats', 'firstname' => 'Bob', 'lastname' => 'Dyyylan',
'email' => 'bobbyyy@dyyylan.com', 'phone1' => '123456', 'phone2' => '78910', 'department' => 'Marketing',
'institution' => 'HQ'));
// Assign capability required to perform the search.
$this->setUser($ux);
$systemcontext = \context_system::instance();
$customrole = $this->assignUserCapability('moodle/competency:templatemanage', $systemcontext->id);
// Now we assign a different capability.
$usercontext = \context_user::instance($u1->id);
$this->assignUserCapability('moodle/competency:templatemanage', $usercontext->id, $customrole);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(0, $result['users']);
$this->assertEquals(0, $result['count']);
// Now we assign a matching capability in the same role.
$usercontext = \context_user::instance($u1->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $customrole);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
// Now assign another role with the same capability (test duplicates).
role_assign($this->creatorrole, $ux->id, $usercontext->id);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
// Now lets try a different user with only the role at system level.
$ux2 = $dg->create_user();
role_assign($this->creatorrole, $ux2->id, $systemcontext->id);
$this->setUser($ux2);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
// Now lets try a different user with only the role at user level.
$ux3 = $dg->create_user();
role_assign($this->creatorrole, $ux3->id, $usercontext->id);
$this->setUser($ux3);
$systemcontext = \context_system::instance();
$customrole = $this->assignUserCapability('moodle/competency:templatemanage', $systemcontext->id, $customrole);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
// Switch back.
$this->setUser($ux);
// Now add a prevent override (will change nothing because we still have an ALLOW).
assign_capability('moodle/competency:planmanage', CAP_PREVENT, $customrole, $usercontext->id);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
// Now change to a prohibit override (should prevent access).
assign_capability('moodle/competency:planmanage', CAP_PROHIBIT, $customrole, $usercontext->id);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
}
/**
* Ensures that overrides, as well as system permissions, are respected.
*/
public function test_search_users_by_capability_the_comeback(): void {
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$master = $dg->create_user();
$manager = $dg->create_user();
$slave1 = $dg->create_user(array('lastname' => 'MOODLER'));
$slave2 = $dg->create_user(array('lastname' => 'MOODLER'));
$slave3 = $dg->create_user(array('lastname' => 'MOODLER'));
$syscontext = \context_system::instance();
$slave1context = \context_user::instance($slave1->id);
$slave2context = \context_user::instance($slave2->id);
$slave3context = \context_user::instance($slave3->id);
// Creating a role giving the site config.
$roleid = $dg->create_role();
assign_capability('moodle/site:config', CAP_ALLOW, $roleid, $syscontext->id, true);
// Create a role override for slave 2.
assign_capability('moodle/site:config', CAP_PROHIBIT, $roleid, $slave2context->id, true);
// Assigning the role.
// Master -> System context.
// Manager -> User context.
role_assign($roleid, $master->id, $syscontext);
role_assign($roleid, $manager->id, $slave1context);
// Flush accesslib.
accesslib_clear_all_caches_for_unit_testing();
// Confirm.
// Master has system permissions.
$this->setUser($master);
$this->assertTrue(has_capability('moodle/site:config', $syscontext));
$this->assertTrue(has_capability('moodle/site:config', $slave1context));
$this->assertFalse(has_capability('moodle/site:config', $slave2context));
$this->assertTrue(has_capability('moodle/site:config', $slave3context));
// Manager only has permissions in slave 1.
$this->setUser($manager);
$this->assertFalse(has_capability('moodle/site:config', $syscontext));
$this->assertTrue(has_capability('moodle/site:config', $slave1context));
$this->assertFalse(has_capability('moodle/site:config', $slave2context));
$this->assertFalse(has_capability('moodle/site:config', $slave3context));
// Now do the test.
$this->setUser($master);
$dummyrole = $this->assignUserCapability('moodle/competency:templatemanage', $syscontext->id);
$result = external::search_users('MOODLER', 'moodle/site:config');
$this->assertCount(2, $result['users']);
$this->assertEquals(2, $result['count']);
$this->assertArrayHasKey($slave1->id, $result['users']);
$this->assertArrayHasKey($slave3->id, $result['users']);
$this->setUser($manager);
$this->assignUserCapability('moodle/competency:templatemanage', $syscontext->id, $dummyrole);
$result = external::search_users('MOODLER', 'moodle/site:config');
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
$this->assertArrayHasKey($slave1->id, $result['users']);
}
public function test_search_users(): void {
global $CFG;
$this->resetAfterTest(true);
$dg = $this->getDataGenerator();
$ux = $dg->create_user();
$u1 = $dg->create_user(array('idnumber' => 'Cats', 'firstname' => 'Bob', 'lastname' => 'Dyyylan',
'email' => 'bobbyyy@dyyylan.com', 'phone1' => '123456', 'phone2' => '78910', 'department' => 'Marketing',
'institution' => 'HQ'));
$u2 = $dg->create_user(array('idnumber' => 'Dogs', 'firstname' => 'Alice', 'lastname' => 'Dyyylan',
'email' => 'alyyyson@dyyylan.com', 'phone1' => '33333', 'phone2' => '77777', 'department' => 'Development',
'institution' => 'O2'));
$u3 = $dg->create_user(array('idnumber' => 'Fish', 'firstname' => 'Thomas', 'lastname' => 'Xow',
'email' => 'fishyyy@moodle.com', 'phone1' => '77777', 'phone2' => '33333', 'department' => 'Research',
'institution' => 'Bob'));
// We need to give the user the capability we are searching for on each of the test users.
$this->setAdminUser();
$usercontext = \context_user::instance($u1->id);
$dummyrole = $this->assignUserCapability('moodle/competency:planmanage', $usercontext->id);
$usercontext = \context_user::instance($u2->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole);
$usercontext = \context_user::instance($u3->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole);
$this->setUser($ux);
$usercontext = \context_user::instance($u1->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole);
$usercontext = \context_user::instance($u2->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole);
$usercontext = \context_user::instance($u3->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole);
$this->setAdminUser();
// No identity fields.
$CFG->showuseridentity = '';
$result = external::search_users('cats', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(0, $result['users']);
$this->assertEquals(0, $result['count']);
// Filter by name.
$CFG->showuseridentity = '';
$result = external::search_users('dyyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(2, $result['users']);
$this->assertEquals(2, $result['count']);
$this->assertEquals($u2->id, $result['users'][0]['id']);
$this->assertEquals($u1->id, $result['users'][1]['id']);
// Filter by institution and name.
$CFG->showuseridentity = 'institution';
$result = external::search_users('bob', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(2, $result['users']);
$this->assertEquals(2, $result['count']);
$this->assertEquals($u1->id, $result['users'][0]['id']);
$this->assertEquals($u3->id, $result['users'][1]['id']);
// Filter by id number.
$CFG->showuseridentity = 'idnumber';
$result = external::search_users('cats', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
$this->assertEquals($u1->id, $result['users'][0]['id']);
$this->assertEquals($u1->idnumber, $result['users'][0]['idnumber']);
$this->assertEmpty($result['users'][0]['email']);
$this->assertEmpty($result['users'][0]['phone1']);
$this->assertEmpty($result['users'][0]['phone2']);
$this->assertEmpty($result['users'][0]['department']);
$this->assertEmpty($result['users'][0]['institution']);
// Filter by email.
$CFG->showuseridentity = 'email';
$result = external::search_users('yyy', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(3, $result['users']);
$this->assertEquals(3, $result['count']);
$this->assertEquals($u2->id, $result['users'][0]['id']);
$this->assertEquals($u2->email, $result['users'][0]['email']);
$this->assertEquals($u1->id, $result['users'][1]['id']);
$this->assertEquals($u1->email, $result['users'][1]['email']);
$this->assertEquals($u3->id, $result['users'][2]['id']);
$this->assertEquals($u3->email, $result['users'][2]['email']);
// Filter by any.
$CFG->showuseridentity = 'idnumber,email,phone1,phone2,department,institution';
$result = external::search_users('yyy', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(3, $result['users']);
$this->assertEquals(3, $result['count']);
$this->assertArrayHasKey('idnumber', $result['users'][0]);
$this->assertArrayHasKey('email', $result['users'][0]);
$this->assertArrayHasKey('phone1', $result['users'][0]);
$this->assertArrayHasKey('phone2', $result['users'][0]);
$this->assertArrayHasKey('department', $result['users'][0]);
$this->assertArrayHasKey('institution', $result['users'][0]);
// Switch to a user that cannot view identity fields.
$this->setUser($ux);
$systemcontext = \context_system::instance();
$this->assignUserCapability('moodle/competency:templatemanage', $systemcontext->id, $dummyrole);
$CFG->showuseridentity = 'idnumber,email,phone1,phone2,department,institution';
// Only names are included.
$result = external::search_users('fish');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(0, $result['users']);
$this->assertEquals(0, $result['count']);
$result = external::search_users('bob', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
$this->assertEquals($u1->id, $result['users'][0]['id']);
$this->assertEmpty($result['users'][0]['idnumber']);
$this->assertEmpty($result['users'][0]['email']);
$this->assertEmpty($result['users'][0]['phone1']);
$this->assertEmpty($result['users'][0]['phone2']);
$this->assertEmpty($result['users'][0]['department']);
$this->assertEmpty($result['users'][0]['institution']);
}
public function test_data_for_user_competency_summary_in_plan(): void {
global $CFG;
$this->setUser($this->creator);
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$f1 = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$tpl = $lpg->create_template();
$lpg->create_template_competency(array('templateid' => $tpl->get('id'), 'competencyid' => $c1->get('id')));
$plan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get('id'), 'name' => 'Evil'));
$uc = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1->get('id')));
$evidence = \core_competency\external::grade_competency_in_plan($plan->get('id'), $c1->get('id'), 1, true);
$evidence = \core_competency\external::grade_competency_in_plan($plan->get('id'), $c1->get('id'), 2, true);
$summary = external::data_for_user_competency_summary_in_plan($c1->get('id'), $plan->get('id'));
$this->assertTrue($summary->usercompetencysummary->cangrade);
$this->assertEquals('Evil', $summary->plan->name);
$this->assertEquals('B', $summary->usercompetencysummary->usercompetency->gradename);
$this->assertEquals('B', $summary->usercompetencysummary->evidence[0]->gradename);
$this->assertEquals('A', $summary->usercompetencysummary->evidence[1]->gradename);
}
public function test_data_for_user_competency_summary(): void {
$this->setUser($this->creator);
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$f1 = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 1, true);
$evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 2, true);
$summary = external::data_for_user_competency_summary($this->user->id, $c1->get('id'));
$this->assertTrue($summary->cangrade);
$this->assertEquals('B', $summary->usercompetency->gradename);
$this->assertEquals('B', $summary->evidence[0]->gradename);
$this->assertEquals('A', $summary->evidence[1]->gradename);
}
public function test_data_for_course_competency_page(): void {
$this->setAdminUser();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$f1 = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$course1 = $dg->create_course(array('category' => $this->category->id));
$cc = api::add_competency_to_course($course1->id, $c1->get('id'));
$evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 1, true);
$evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 2, true);
$pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page');
$page = $pagegenerator->create_instance(array('course' => $course1->id));
$page2 = $pagegenerator->create_instance(array('course' => $course1->id));
$cm = get_coursemodule_from_instance('page', $page->id);
$cm2 = get_coursemodule_from_instance('page', $page2->id);
// Add the competency to the course module.
$ccm = api::add_competency_to_course_module($cm, $c1->get('id'));
$summary = external::data_for_course_competencies_page($course1->id, 0);
$summary2 = external::data_for_course_competencies_page($course1->id, $cm->id);
$summary3 = external::data_for_course_competencies_page($course1->id, $cm2->id);
$this->assertEquals(count($summary->competencies), 1);
$this->assertEquals(count($summary->competencies), count($summary2->competencies));
$this->assertEquals(count($summary3->competencies), 0);
}
}
-30
View File
@@ -1,30 +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/>.
/**
* Plugin version info
*
* @package tool_lp
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_lp'; // Full name of the plugin (used for diagnostics).
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version info
*
* @package tool_lpimportcsv
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_lpimportcsv'; // Full name of the plugin (used for diagnostics).
$plugin->dependencies = ['tool_lp' => 2025040800];
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version info.
*
* @package tool_lpmigrate
* @copyright 2016 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'tool_lpmigrate'; // Full name of the plugin (used for diagnostics).
$plugin->dependencies = [
'tool_lp' => ANY_VERSION,
];
-108
View File
@@ -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/>.
/**
* Output rendering for the plugin.
*
* @package tool_messageinbound
* @copyright 2014 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Implements the plugin renderer
*
* @copyright 2014 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_messageinbound_renderer extends plugin_renderer_base {
/**
* Render a table listing all of the Inbound Message handlers.
*
* @param array $handlers - list of all messageinbound handlers.
* @return string HTML to output.
*/
public function messageinbound_handlers_table(array $handlers) {
global $CFG;
$table = new html_table();
$handlername = new html_table_cell(get_string('name', 'tool_messageinbound') . "\n" .
html_writer::tag('span', get_string('classname', 'tool_messageinbound'), array('class' => 'handler-function')));
// Prepare some of the rows with additional styling.
$enabled = new html_table_cell(get_string('enabled', 'tool_messageinbound'));
$enabled->attributes['class'] = 'state';
$edit = new html_table_cell(get_string('edit', 'tool_messageinbound'));
$edit->attributes['class'] = 'edit';
$table->head = array(
$handlername,
get_string('description', 'tool_messageinbound'),
$enabled,
$edit,
);
$table->attributes['class'] = 'admintable generaltable messageinboundhandlers';
$yes = get_string('yes');
$no = get_string('no');
$data = array();
// Options for description formatting.
$descriptionoptions = new stdClass();
$descriptionoptions->trusted = false;
$descriptionoptions->noclean = false;
$descriptionoptions->filter = false;
$descriptionoptions->para = true;
$descriptionoptions->newlines = false;
$descriptionoptions->overflowdiv = true;
$editurlbase = new moodle_url('/admin/tool/messageinbound/index.php');
foreach ($handlers as $handler) {
$handlername = new html_table_cell($handler->name . "\n" .
html_writer::tag('span', $handler->classname, array('class' => 'handler-function')));
$handlername->header = true;
$editurl = new moodle_url($editurlbase, array('classname' => $handler->classname));
$editlink = $this->action_icon($editurl, new pix_icon('t/edit',
get_string('edithandler', 'tool_messageinbound', $handler->classname)));
// Prepare some of the rows with additional styling.
$enabled = new html_table_cell($handler->enabled ? $yes : $no);
$enabled->attributes['class'] = 'state';
$edit = new html_table_cell($editlink);
$edit->attributes['class'] = 'edit';
// Add the row.
$row = new html_table_row(array(
$handlername,
format_text($handler->description, FORMAT_MARKDOWN, $descriptionoptions),
$enabled,
$edit,
));
if (!$handler->enabled) {
$row->attributes['class'] = 'disabled';
}
$data[] = $row;
}
$table->data = $data;
return html_writer::table($table);
}
}
-29
View File
@@ -1,29 +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/>.
/**
* Plugin version info
*
* @package tool_messageinbound
* @copyright 2014 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400;
$plugin->requires = 2025040800;
$plugin->component = 'tool_messageinbound';
-908
View File
@@ -1,908 +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 tool_mfa;
use dml_exception;
use tool_mfa\plugininfo\factor;
/**
* MFA management class.
*
* @package tool_mfa
* @author Peter Burnett <peterburnett@catalyst-au.net>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class manager {
/** @var int */
const REDIRECT = 1;
/** @var int */
const NO_REDIRECT = 0;
/** @var int */
const REDIRECT_EXCEPTION = -1;
/** @var int */
const REDIR_LOOP_THRESHOLD = 5;
/** @var array These components and related fileareas will not redirect. */
const ALLOWED_COMPONENTS = [
'core_admin' => [
'logocompact',
'logo',
'favicon',
],
'tool_mfa' => [
'guidance',
]
];
/**
* Displays a debug table with current factor information.
*
* @return void
*/
public static function display_debug_notification(): void {
global $OUTPUT, $PAGE;
if (!get_config('tool_mfa', 'debugmode')) {
return;
}
$html = $OUTPUT->heading(get_string('debugmode:heading', 'tool_mfa'), 3);
$table = new \html_table();
$table->head = [
get_string('weight', 'tool_mfa'),
get_string('factor', 'tool_mfa'),
get_string('setup', 'tool_mfa'),
get_string('achievedweight', 'tool_mfa'),
get_string('status'),
];
$table->attributes['class'] = 'admintable generaltable table table-bordered';
$table->colclasses = [
'text-end',
'',
'',
'text-end',
'text-center',
];
$factors = factor::get_enabled_factors();
$userfactors = factor::get_active_user_factor_types();
$runningtotal = 0;
$weighttoggle = false;
foreach ($factors as $factor) {
$namespace = 'factor_'.$factor->name;
$name = get_string('pluginname', $namespace);
// If factor is unknown, pending from here.
if ($factor->get_state() == factor::STATE_UNKNOWN) {
$weighttoggle = true;
}
// Stop adding weight if 100 achieved.
if (!$weighttoggle) {
$achieved = $factor->get_state() == factor::STATE_PASS ? $factor->get_weight() : 0;
$achieved = '+'.$achieved;
$runningtotal += $achieved;
} else {
$achieved = '';
}
// Setup.
if ($factor->has_setup()) {
$found = false;
foreach ($userfactors as $userfactor) {
if ($userfactor->name == $factor->name) {
$found = true;
}
}
$setup = $found ? get_string('yes') : get_string('no');
} else {
$setup = get_string('na', 'tool_mfa');
}
// Status.
$OUTPUT = $PAGE->get_renderer('tool_mfa');
// If toggle has been flipped, fall to default pending badge.
if ($weighttoggle) {
$state = $OUTPUT->get_state_badge('');
} else {
$state = $OUTPUT->get_state_badge($factor->get_state());
}
$table->data[] = [
$factor->get_weight(),
$name,
$setup,
$achieved,
$state,
];
// If we just hit 100, flip toggle.
if ($runningtotal >= 100) {
$weighttoggle = true;
}
}
$finalstate = self::get_status();
$table->data[] = [
'',
'',
'<b>' . get_string('overall', 'tool_mfa') . '</b>',
self::get_cumulative_weight(),
$OUTPUT->get_state_badge($finalstate),
];
$html .= \html_writer::table($table);
echo $html;
}
/**
* Returns the total weight from all factors currently enabled for user.
*
* @return int
*/
public static function get_total_weight(): int {
$totalweight = 0;
$factors = factor::get_active_user_factor_types();
foreach ($factors as $factor) {
if ($factor->get_state() == factor::STATE_PASS) {
$totalweight += $factor->get_weight();
}
}
return $totalweight;
}
/**
* Checks that provided factorid exists and belongs to current user.
*
* @param int $factorid
* @param object $user
* @return bool
* @throws \dml_exception
*/
public static function is_factorid_valid(int $factorid, object $user): bool {
global $DB;
return $DB->record_exists('tool_mfa', ['userid' => $user->id, 'id' => $factorid]);
}
/**
* Function to display to the user that they cannot login, then log them out.
*
* @return void
*/
public static function cannot_login(): void {
global $ME, $PAGE, $SESSION, $USER;
// Determine page URL without triggering warnings from $PAGE.
if (!preg_match("~(\/admin\/tool\/mfa\/auth.php)~", $ME)) {
// If URL isn't set, we need to redir to auth.php.
// This ensures URL and required info is correctly set.
// Then we arrive back here.
redirect(new \moodle_url('/admin/tool/mfa/auth.php'));
}
$renderer = $PAGE->get_renderer('tool_mfa');
echo $renderer->header();
if (get_config('tool_mfa', 'debugmode')) {
self::display_debug_notification();
}
echo $renderer->not_enough_factors();
echo $renderer->footer();
// Emit an event for failure, then logout.
$event = \tool_mfa\event\user_failed_mfa::user_failed_mfa_event($USER);
$event->trigger();
// We should set the redir flag, as this page is generated through auth.php.
$SESSION->tool_mfa_has_been_redirected = true;
die;
}
/**
* Logout user.
*
* @return void
*/
public static function mfa_logout(): void {
$authsequence = get_enabled_auth_plugins();
foreach ($authsequence as $authname) {
$authplugin = get_auth_plugin($authname);
$authplugin->logoutpage_hook();
}
require_logout();
}
/**
* Function to get the overall status of a user's authentication.
*
* @return string a STATE variable from plugininfo
*/
public static function get_status(): string {
global $SESSION;
// Check for any instant fail states.
$factors = factor::get_active_user_factor_types();
foreach ($factors as $factor) {
$factor->load_locked_state();
if ($factor->get_state() == factor::STATE_FAIL) {
return factor::STATE_FAIL;
}
}
$passcondition = ((isset($SESSION->tool_mfa_authenticated) && $SESSION->tool_mfa_authenticated) ||
self::passed_enough_factors());
// Check next factor for instant fail (fallback).
if (factor::get_next_user_login_factor()->get_state() == factor::STATE_FAIL) {
// We need to handle a special case here, where someone reached the fallback,
// If they were able to modify their state on the error page, such as passing iprange,
// We must return pass.
if ($passcondition) {
return factor::STATE_PASS;
}
return factor::STATE_FAIL;
}
// Now check for general passing state. If found, ensure that session var is set.
if ($passcondition) {
return factor::STATE_PASS;
}
// Else return neutral state.
return factor::STATE_NEUTRAL;
}
/**
* Function to check the overall status of a users authentication,
* and perform any required actions.
*
* @param bool $shouldreload whether the function should reload (used for auth.php).
* @return void
*/
public static function resolve_mfa_status(bool $shouldreload = false): void {
global $SESSION;
$state = self::get_status();
if ($state == factor::STATE_PASS) {
self::set_pass_state();
// Check if user even had to reach auth page.
if (isset($SESSION->tool_mfa_has_been_redirected)) {
if (empty($SESSION->wantsurl)) {
$wantsurl = '/';
} else {
$wantsurl = $SESSION->wantsurl;
}
unset($SESSION->wantsurl);
redirect(new \moodle_url($wantsurl));
} else {
// Don't touch anything, let user be on their way.
return;
}
} else if ($state == factor::STATE_FAIL) {
self::cannot_login();
} else if ($shouldreload) {
// Set a session variable to track whether user is where they want to be.
$SESSION->tool_mfa_has_been_redirected = true;
$authurl = new \moodle_url('/admin/tool/mfa/auth.php');
redirect($authurl);
}
}
/**
* Checks whether user has passed enough factors to be allowed in.
*
* @return bool true if user has passed enough factors.
*/
public static function passed_enough_factors(): bool {
// Check for any instant fail states.
$factors = factor::get_active_user_factor_types();
foreach ($factors as $factor) {
if ($factor->get_state() == factor::STATE_FAIL) {
self::mfa_logout();
}
}
$totalweight = self::get_cumulative_weight();
if ($totalweight >= 100) {
return true;
}
return false;
}
/**
* Sets the session variable for pass_state, if not already set.
*
* @return void
*/
public static function set_pass_state(): void {
global $DB, $SESSION, $USER;
if (!isset($SESSION->tool_mfa_authenticated)) {
$SESSION->tool_mfa_authenticated = true;
$event = \tool_mfa\event\user_passed_mfa::user_passed_mfa_event($USER);
$event->trigger();
// Allow plugins to callback as soon possible after user has passed MFA.
$hook = new \tool_mfa\hook\after_user_passed_mfa();
\core\di::get(\core\hook\manager::class)->dispatch($hook);
// Add/update record in DB for users last mfa auth.
self::update_pass_time();
// Unset session vars during mfa auth.
unset($SESSION->mfa_redir_referer);
unset($SESSION->mfa_redir_count);
// Unset user preferences during mfa auth.
unset_user_preference('mfa_sleep_duration', $USER);
try {
// Clear locked user factors, they may now reauth with anything.
@$DB->set_field('tool_mfa', 'lockcounter', 0, ['userid' => $USER->id]);
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
} catch (\Exception $e) {
// This occurs when upgrade.php hasn't been run. Nothing to do here.
}
// Fire post pass state factor actions.
$factors = factor::get_active_user_factor_types();
foreach ($factors as $factor) {
$factor->post_pass_state();
// Also set the states for this session to neutral if they were locked.
if ($factor->get_state() == factor::STATE_LOCKED) {
$factor->set_state(factor::STATE_NEUTRAL);
}
}
// Output notifications if any factors were reset for this user.
$enabledfactors = factor::get_enabled_factors();
foreach ($enabledfactors as $factor) {
$pref = 'tool_mfa_reset_' . $factor->name;
$factorpref = get_user_preferences($pref, false);
if ($factorpref) {
$url = new \moodle_url('/admin/tool/mfa/user_preferences.php');
$link = \html_writer::link($url, get_string('preferenceslink', 'tool_mfa'));
$data = ['factor' => $factor->get_display_name(), 'url' => $link];
\core\notification::warning(get_string('factorreset', 'tool_mfa', $data));
unset_user_preference($pref);
}
}
// Also check for a global reset.
// TODO: Delete this in a few months, the reset all preference is no longer set.
$allfactor = get_user_preferences('tool_mfa_reset_all', false);
if ($allfactor) {
$url = new \moodle_url('/admin/tool/mfa/user_preferences.php');
$link = \html_writer::link($url, get_string('preferenceslink', 'tool_mfa'));
\core\notification::warning(get_string('factorresetall', 'tool_mfa', $link));
unset_user_preference('tool_mfa_reset_all');
}
}
}
/**
* Inserts or updates user's last MFA pass time in DB.
* This should only be called from set_pass_state.
*
* @return void
*/
private static function update_pass_time(): void {
global $DB, $USER;
$exists = $DB->record_exists('tool_mfa_auth', ['userid' => $USER->id]);
if ($exists) {
$DB->set_field('tool_mfa_auth', 'lastverified', time(), ['userid' => $USER->id]);
} else {
$DB->insert_record('tool_mfa_auth', ['userid' => $USER->id, 'lastverified' => time()]);
}
}
/**
* Checks whether the user should be redirected from the provided url.
*
* @param string|\moodle_url $url
* @param bool|null $preventredirect
* @return int
*/
public static function should_require_mfa(string|\moodle_url $url, bool|null $preventredirect): int {
global $CFG, $USER, $SESSION;
// If no cookies then no session so cannot do MFA.
// Unit testing based on defines is not viable.
if (NO_MOODLE_COOKIES && !PHPUNIT_TEST) {
return self::NO_REDIRECT;
}
// Ensure we have a moodle_url object if a string is provided.
if (is_string($url)) {
$url = new \moodle_url($url);
}
// Check for pluginfile.php urls.
$pluginfileurl = new \moodle_url('/pluginfile.php');
if ($url->compare($pluginfileurl)) {
// Get the slash arguments.
$args = explode('/', ltrim($url->get_slashargument(), '/'));
// Remove the contextid because we do not need it for this check.
array_shift($args);
// Get the component and filearea.
$component = clean_param(array_shift($args), PARAM_COMPONENT);
$filearea = clean_param(array_shift($args), PARAM_AREA);
// Check allowed components.
if (!array_key_exists($component, static::ALLOWED_COMPONENTS)) {
return self::REDIRECT;
}
// Check allowed fileareas.
if (!in_array($filearea, static::ALLOWED_COMPONENTS[$component])) {
return self::REDIRECT;
}
return self::NO_REDIRECT;
}
// Remove all params before comparison.
$url->remove_all_params();
// Checks for upgrades pending.
if (is_siteadmin()) {
// We should only allow an upgrade from the frontend to complete.
// After that is completed, only the settings shouldn't redirect.
// Everything else should be safe to enforce MFA.
if (moodle_needs_upgrading()) {
return self::NO_REDIRECT;
}
// An upgrade isn't complete if there are settings that must be saved.
$upgradesettings = new \moodle_url('/admin/upgradesettings.php');
if ($url->compare($upgradesettings, URL_MATCH_BASE)) {
return self::NO_REDIRECT;
}
}
// Admin not setup.
if (!empty($CFG->adminsetuppending)) {
return self::NO_REDIRECT;
}
// Initial installation.
// We get this for free from get_plugins_with_function.
// Upgrade check.
// We get this for free from get_plugins_with_function.
// Honor prevent_redirect.
if ($preventredirect) {
return self::NO_REDIRECT;
}
// User not properly setup.
if (user_not_fully_set_up($USER)) {
return self::NO_REDIRECT;
}
// Guest access.
if (isguestuser()) {
return self::NO_REDIRECT;
}
// Forced password changes.
if (get_user_preferences('auth_forcepasswordchange')) {
return self::NO_REDIRECT;
}
// Login as.
if (\core\session\manager::is_loggedinas()) {
return self::NO_REDIRECT;
}
// Site policy.
if (isset($USER->policyagreed) && !$USER->policyagreed) {
$manager = new \core_privacy\local\sitepolicy\manager();
$policyurl = $manager->get_redirect_url(false);
if (!empty($policyurl) && $url->compare($policyurl, URL_MATCH_BASE)) {
return self::NO_REDIRECT;
}
}
// WS/AJAX check.
if (WS_SERVER || AJAX_SCRIPT) {
if (isset($SESSION->mfa_pending) && !empty($SESSION->mfa_pending)) {
// Allow AJAX and WS, but never from auth.php.
return self::NO_REDIRECT;
}
return self::REDIRECT_EXCEPTION;
}
// Check factor defined safe urls.
$factorurls = self::get_no_redirect_urls();
foreach ($factorurls as $factorurl) {
if ($factorurl->compare($url)) {
return self::NO_REDIRECT;
}
}
// Circular checks.
$authurl = new \moodle_url('/admin/tool/mfa/auth.php');
$authlocal = $authurl->out_as_local_url();
if (isset($SESSION->mfa_redir_referer)
&& $SESSION->mfa_redir_referer != $authlocal) {
if ($SESSION->mfa_redir_referer == get_local_referer(true)) {
// Possible redirect loop.
if (!isset($SESSION->mfa_redir_count)) {
$SESSION->mfa_redir_count = 1;
} else {
$SESSION->mfa_redir_count++;
}
if ($SESSION->mfa_redir_count > self::REDIR_LOOP_THRESHOLD) {
return self::REDIRECT_EXCEPTION;
}
} else {
// If not a match, reset counter.
$SESSION->mfa_redir_count = 0;
}
}
// Set referer after checks.
$SESSION->mfa_redir_referer = get_local_referer(true);
// Don't redirect if already on auth.php.
if ($url->compare($authurl, URL_MATCH_BASE)) {
return self::NO_REDIRECT;
}
return self::REDIRECT;
}
/**
* Clears the redirect counter for infinite redirect loops. Called from auth.php when a valid load is resolved.
*
* @return void
*/
public static function clear_redirect_counter(): void {
global $SESSION;
unset($SESSION->mfa_redir_referer);
unset($SESSION->mfa_redir_count);
}
/**
* Gets all defined factor urls that should not redirect.
*
* @return array
*/
public static function get_no_redirect_urls(): array {
$factors = factor::get_factors();
$urls = [
new \moodle_url('/login/logout.php'),
new \moodle_url('/admin/tool/mfa/guide.php'),
];
foreach ($factors as $factor) {
$urls = array_merge($urls, $factor->get_no_redirect_urls());
}
// Allow forced redirection exclusions.
if ($exclusions = get_config('tool_mfa', 'redir_exclusions')) {
foreach (explode("\n", $exclusions) as $exclusion) {
$urls[] = new \moodle_url($exclusion);
}
}
return $urls;
}
/**
* Sleeps for an increasing period of time.
*
* @return void
*/
public static function sleep_timer(): void {
global $USER;
$duration = get_user_preferences('mfa_sleep_duration', null, $USER);
if (!empty($duration)) {
// Double current time.
$duration *= 2;
$duration = min(2, $duration);
} else {
// No duration set.
$duration = 0.05;
}
set_user_preference('mfa_sleep_duration', $duration, $USER);
sleep((int)$duration);
}
/**
* If MFA Plugin is ready check tool_mfa_authenticated USER property and
* start MFA authentication if it's not set or false.
*
* @param mixed $courseorid
* @param mixed $autologinguest
* @param mixed $cm
* @param mixed $setwantsurltome
* @param mixed $preventredirect
* @return void
*/
public static function require_auth($courseorid = null, $autologinguest = null, $cm = null,
$setwantsurltome = null, $preventredirect = null): void {
global $PAGE, $SESSION, $FULLME;
// Guest user should never interact with MFA,
// And $SESSION->tool_mfa_authenticated should never be set in a guest session.
if (isguestuser()) {
return;
}
if (!self::is_ready()) {
// Set session var so if MFA becomes ready, you dont get locked from session.
$SESSION->tool_mfa_authenticated = true;
return;
}
if (empty($SESSION->tool_mfa_authenticated) || !$SESSION->tool_mfa_authenticated) {
if ($PAGE->has_set_url()) {
$cleanurl = $PAGE->url;
} else {
// Use $FULLME instead.
$cleanurl = new \moodle_url($FULLME);
}
$authurl = new \moodle_url('/admin/tool/mfa/auth.php');
$redir = self::should_require_mfa($cleanurl, $preventredirect);
if ($redir == self::NO_REDIRECT && !$cleanurl->compare($authurl, URL_MATCH_BASE)) {
// A non-MFA page that should take precedence.
// This check is for any pages, such as site policy, that must occur before MFA.
// This check allows AJAX and WS requests to fire on these pages without throwing an exception.
$SESSION->mfa_pending = true;
}
if ($redir == self::REDIRECT) {
if (empty($SESSION->wantsurl)) {
!empty($setwantsurltome)
? $SESSION->wantsurl = qualified_me()
: $SESSION->wantsurl = new \moodle_url('/');
$SESSION->tool_mfa_setwantsurl = true;
}
// Remove pending status.
// We must now auth with MFA, now that pending statuses are resolved.
unset($SESSION->mfa_pending);
// Call resolve_status to instantly pass if no redirect is required.
self::resolve_mfa_status(true);
} else if ($redir == self::REDIRECT_EXCEPTION) {
if (!empty($SESSION->mfa_redir_referer)) {
throw new \moodle_exception('redirecterrordetected', 'tool_mfa',
$SESSION->mfa_redir_referer, $SESSION->mfa_redir_referer);
} else {
throw new \moodle_exception('redirecterrordetected', 'error');
}
}
}
}
/**
* Sets config variable for given factor.
*
* @param array $data
* @param string $factor
*
* @return bool true or exception
* @throws dml_exception
*/
public static function set_factor_config(array $data, string $factor): bool|dml_exception {
$factorconf = get_config($factor);
foreach ($data as $key => $newvalue) {
if (empty($factorconf->$key)) {
add_to_config_log($key, null, $newvalue, $factor);
set_config($key, $newvalue, $factor);
} else if ($factorconf->$key != $newvalue) {
add_to_config_log($key, $factorconf->$key, $newvalue, $factor);
set_config($key, $newvalue, $factor);
}
}
return true;
}
/**
* Checks if MFA Plugin is enabled and has enabled factor.
* If plugin is disabled or there is no enabled factors,
* it means there is nothing to do from user side.
* Thus, login flow shouldn't be extended with MFA.
*
* @return bool
* @throws \dml_exception
*/
public static function is_ready(): bool {
global $CFG, $USER;
if (!empty($CFG->upgraderunning)) {
return false;
}
$pluginenabled = get_config('tool_mfa', 'enabled');
if (empty($pluginenabled)) {
return false;
}
// Check if user can interact with MFA.
$usercontext = \context_user::instance($USER->id);
if (!has_capability('tool/mfa:mfaaccess', $usercontext)) {
return false;
}
$enabledfactors = factor::get_enabled_factors();
if (count($enabledfactors) == 0) {
return false;
}
return true;
}
/**
* Performs factor actions for given factor.
* Change factor order and enable/disable.
*
* @param string $factorname
* @param string $action
*
* @return void
* @throws dml_exception
*/
public static function do_factor_action(string $factorname, string $action): void {
$order = explode(',', get_config('tool_mfa', 'factor_order'));
$key = array_search($factorname, $order);
switch ($action) {
case 'up':
if ($key >= 1) {
$fsave = $order[$key];
$order[$key] = $order[$key - 1];
$order[$key - 1] = $fsave;
}
break;
case 'down':
if ($key < (count($order) - 1)) {
$fsave = $order[$key];
$order[$key] = $order[$key + 1];
$order[$key + 1] = $fsave;
}
break;
case 'enable':
if (!$key) {
$order[] = $factorname;
}
break;
case 'disable':
if ($key) {
unset($order[$key]);
}
break;
default:
break;
}
self::set_factor_config(['factor_order' => implode(',', $order)], 'tool_mfa');
}
/**
* Checks if a factor that can make a user pass can be setup.
* It checks if a user will always pass regardless,
* then checks if there are factors that can be setup to let a user pass.
*
* @return bool
*/
public static function possible_factor_setup(): bool {
global $USER;
// Get all active factors.
$factors = factor::get_enabled_factors();
// Check if there are enough factors that a user can ONLY pass, if so, don't display the menu.
$weight = 0;
foreach ($factors as $factor) {
$states = $factor->possible_states($USER);
if (count($states) == 1 && reset($states) == factor::STATE_PASS) {
$weight += $factor->get_weight();
if ($weight >= 100) {
return false;
}
}
}
// Now if there is a factor that can be setup, that may return a pass state for the user, display menu.
foreach ($factors as $factor) {
if ($factor->has_setup()) {
if (in_array(factor::STATE_PASS, $factor->possible_states($USER))) {
return true;
}
}
}
return false;
}
/**
* Gets current user weight, up until first unknown factor.
*
* @return int $totalweight Total weight of all factors.
*/
public static function get_cumulative_weight(): int {
$factors = factor::get_active_user_factor_types();
// Factor order is important here, so sort the factors by state.
$sortedfactors = factor::sort_factors_by_state($factors, factor::STATE_PASS);
$totalweight = 0;
foreach ($sortedfactors as $factor) {
if ($factor->get_state() == factor::STATE_PASS) {
$totalweight += $factor->get_weight();
// If over 100, break. Don't care about >100.
if ($totalweight >= 100) {
break;
}
} else if ($factor->get_state() == factor::STATE_UNKNOWN) {
break;
}
}
return $totalweight;
}
/**
* Checks whether the factor was actually used in the login process.
*
* @param string $factorname the name of the factor.
* @return bool true if factor is pending.
*/
public static function check_factor_pending(string $factorname): bool {
$factors = factor::get_active_user_factor_types();
// Setup vars.
$pending = [];
$totalweight = 0;
$weighttoggle = false;
foreach ($factors as $factor) {
// If toggle is reached, put in pending and continue.
if ($weighttoggle) {
$pending[] = $factor->name;
continue;
}
if ($factor->get_state() == factor::STATE_PASS) {
$totalweight += $factor->get_weight();
if ($totalweight >= 100) {
$weighttoggle = true;
}
}
}
// Check whether factor falls into pending category.
return in_array($factorname, $pending);
}
}
-711
View File
@@ -1,711 +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 tool_mfa\output;
use core\context\system;
use tool_mfa\local\factor\object_factor;
use tool_mfa\local\form\login_form;
use \html_writer;
use tool_mfa\plugininfo\factor;
/**
* MFA renderer.
*
* @package tool_mfa
* @author Mikhail Golenkov <golenkovm@gmail.com>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class renderer extends \plugin_renderer_base {
/**
* Returns the state of the factor as a badge.
*
* @param string $state
* @return string
*/
public function get_state_badge(string $state): string {
switch ($state) {
case factor::STATE_PASS:
return html_writer::tag('span', get_string('state:pass', 'tool_mfa'), ['class' => 'badge bg-success text-white']);
case factor::STATE_FAIL:
return html_writer::tag('span', get_string('state:fail', 'tool_mfa'), ['class' => 'badge bg-danger text-white']);
case factor::STATE_NEUTRAL:
return html_writer::tag('span', get_string('state:neutral', 'tool_mfa'),
['class' => 'badge bg-warning text-dark']);
case factor::STATE_UNKNOWN:
return html_writer::tag('span', get_string('state:unknown', 'tool_mfa'),
['class' => 'badge bg-secondary text-dark']);
case factor::STATE_LOCKED:
return html_writer::tag('span', get_string('state:locked', 'tool_mfa'), ['class' => 'badge bg-danger text-white']);
default:
return html_writer::tag('span', get_string('pending', 'tool_mfa'), ['class' => 'badge bg-secondary text-dark']);
}
}
/**
* Returns a list of factors which a user can add.
*
* @return string
*/
public function available_factors(): string {
global $USER;
$factors = factor::get_enabled_factors();
$data = [];
foreach ($factors as $factor) {
// Allow all factors with setup and button.
// Make an exception for email factor as this is currently set up by admins only and required on this list.
if ((!$factor->has_setup() || !$factor->show_setup_buttons()) && !$factor instanceof \factor_email\factor) {
continue;
}
$userfactors = $factor->get_active_user_factors($USER);
$active = !empty($userfactors) ?? false;
$button = null;
$icon = $factor->get_icon();
$params = [
'action' => 'setup',
'factor' => $factor->name,
];
if (!$active) {
// Not active yet and requires set up.
$info = $factor->get_info();
if ($factor->show_setup_buttons()) {
$params['action'] = 'setup';
$button = new \single_button(
url: new \moodle_url('action.php', $params),
label: $factor->get_setup_string(),
method: 'post',
type: \single_button::BUTTON_PRIMARY,
attributes: [
'aria-label' => get_string('setupfactor', 'factor_' . $factor->name),
],
);
$button = $button->export_for_template($this->output);
}
} else {
// Active and can be managed.
$factorid = reset($userfactors)->id;
$info = $factor->get_manage_info($factorid);
if ($factor->show_setup_buttons()) {
$params['action'] = 'manage';
$button = new \single_button(
url: new \moodle_url('action.php', $params),
label: $factor->get_manage_string(),
method: 'post',
type: \single_button::BUTTON_PRIMARY,
attributes: [
'aria-label' => get_string('managefactor', 'factor_' . $factor->name),
],
);
$button = $button->export_for_template($this->output);
}
}
// Prepare data for template.
$data['factors'][] = [
'active' => $active,
'label' => $factor->get_display_name(),
'name' => $factor->name,
'info' => $info,
'icon' => $icon,
'button' => $button,
];
}
return $this->render_from_template('tool_mfa/mfa_selector', $data);
}
/**
* @deprecated since Moodle 4.4
*/
#[\core\attribute\deprecated(null, reason: 'It is no longer used', since: '4.4', mdl: 'MDL-79920', final: true)]
public function setup_factor(): void {
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
}
/**
* Show a table displaying a users active factors.
*
* @param string|null $filterfactor The factor name to filter on.
* @return string $html
* @throws \coding_exception
*/
public function active_factors(?string $filterfactor = null): string {
global $USER, $CFG;
require_once($CFG->dirroot . '/iplookup/lib.php');
$html = '';
$headers = get_strings([
'devicename',
'added',
'lastused',
'replace',
'remove',
], 'tool_mfa');
$table = new \html_table();
$table->id = 'active_factors';
$table->attributes['class'] = 'generaltable table table-bordered';
$table->head = [
$headers->devicename,
$headers->added,
$headers->lastused,
$headers->replace,
$headers->remove,
];
$table->colclasses = [
'text-start',
'text-start',
'text-start',
'text-center',
'text-center',
];
$table->data = [];
$factors = factor::get_enabled_factors();
$hasmorethanone = factor::user_has_more_than_one_active_factors();
foreach ($factors as $factor) {
// Filter results to match the specified factor.
if (!empty($filterfactor) && $factor->name !== $filterfactor) {
continue;
}
$userfactors = $factor->get_active_user_factors($USER);
if (!$factor->has_setup()) {
continue;
}
foreach ($userfactors as $userfactor) {
// Revoke option.
if ($factor->has_revoke() && $hasmorethanone) {
$content = $headers->remove;
$attributes = [
'data-action' => 'revoke',
'data-factor' => $factor->name,
'data-factorid' => $userfactor->id,
'data-factorname' => $factor->get_display_name(),
'data-devicename' => $userfactor->label,
'aria-label' => get_string('revokefactor', 'tool_mfa'),
'class' => 'btn btn-primary mfa-action-button',
];
$revokebutton = \html_writer::tag('button', $content, $attributes);
} else {
$revokebutton = get_string('statusna');
}
// Replace option.
if ($factor->has_replace()) {
$content = $headers->replace;
$attributes = [
'data-action' => 'replace',
'data-factor' => $factor->name,
'data-factorid' => $userfactor->id,
'data-factorname' => $factor->get_display_name(),
'data-devicename' => $userfactor->label,
'aria-label' => get_string('replacefactor', 'tool_mfa'),
'class' => 'btn btn-primary mfa-action-button',
];
$replacebutton = \html_writer::tag('button', $content, $attributes);
} else {
$replacebutton = get_string('statusna');
}
$timecreated = $userfactor->timecreated == '-' ? '-'
: userdate($userfactor->timecreated, get_string('strftimedatetime'));
$lastverified = $userfactor->lastverified;
if ($lastverified == 0) {
$lastverified = '-';
} else if ($lastverified != '-') {
$lastverified = userdate($userfactor->lastverified, get_string('strftimedatetime'));
$lastverified .= '<br>';
$lastverified .= get_string('ago', 'core_message', format_time(time() - $userfactor->lastverified));
}
$row = new \html_table_row([
$userfactor->label,
$timecreated,
$lastverified,
$replacebutton,
$revokebutton,
]);
$table->data[] = $row;
}
}
// If table has no data, don't output.
if (count($table->data) == 0) {
return '';
}
$html .= \html_writer::table($table);
$html .= '<br>';
return $html;
}
/**
* Generates notification text for display when user cannot login.
*
* @return string $notification
*/
public function not_enough_factors(): string {
global $CFG, $SITE;
$notification = \html_writer::tag('h4', get_string('error:notenoughfactors', 'tool_mfa'));
$notification .= \html_writer::tag('p', get_string('error:reauth', 'tool_mfa'));
// Support link.
$supportemail = $CFG->supportemail;
if (!empty($supportemail)) {
$subject = get_string('email:subject', 'tool_mfa',
format_string($SITE->fullname, true, ['context' => system::instance()]));
$maillink = \html_writer::link("mailto:$supportemail?Subject=$subject", $supportemail);
$notification .= get_string('error:support', 'tool_mfa');
$notification .= \html_writer::tag('p', $maillink);
}
// Support page link.
$supportpage = $CFG->supportpage;
if (!empty($supportpage)) {
$linktext = \html_writer::link($supportpage, $supportpage);
$notification .= $linktext;
}
$return = $this->output->notification($notification, 'notifyerror', false);
// Logout button.
$url = new \moodle_url('/admin/tool/mfa/auth.php', ['logout' => 1]);
$btn = new \single_button($url, get_string('logout'), 'post', \single_button::BUTTON_PRIMARY);
$return .= $this->render($btn);
$return .= $this->get_support_link();
return $return;
}
/**
* Displays a table of all factors in use currently.
*
* @param int $lookback the period to view.
* @return string the HTML for the table
*/
public function factors_in_use_table(int $lookback): string {
global $DB;
$factors = factor::get_factors();
// Setup 2 arrays, one with internal names, one pretty.
$columns = [''];
$displaynames = $columns;
$colclasses = ['center', 'center', 'center', 'center', 'center'];
// Force the first 4 columns to custom data.
$displaynames[] = get_string('totalusers', 'tool_mfa');
$displaynames[] = get_string('usersauthedinperiod', 'tool_mfa');
$displaynames[] = get_string('nonauthusers', 'tool_mfa');
$displaynames[] = get_string('nologinusers', 'tool_mfa');
foreach ($factors as $factor) {
$columns[] = $factor->name;
$displaynames[] = get_string('pluginname', 'factor_'.$factor->name);
$colclasses[] = 'right';
}
// Add total column to the end.
$displaynames[] = get_string('total');
$colclasses[] = 'center';
$table = new \html_table();
$table->head = $displaynames;
$table->align = $colclasses;
$table->attributes['class'] = 'generaltable table table-bordered w-auto';
$table->attributes['style'] = 'width: auto; min-width: 50%; margin-bottom: 0;';
// Manually handle Total users and MFA users.
$alluserssql = "SELECT auth,
COUNT(id)
FROM {user}
WHERE deleted = 0
AND suspended = 0
GROUP BY auth";
$allusersinfo = $DB->get_records_sql($alluserssql, []);
$noncompletesql = "SELECT u.auth, COUNT(u.id)
FROM {user} u
LEFT JOIN {tool_mfa_auth} mfaa ON u.id = mfaa.userid
WHERE u.lastlogin >= ?
AND (mfaa.lastverified < ?
OR mfaa.lastverified IS NULL)
GROUP BY u.auth";
$noncompleteinfo = $DB->get_records_sql($noncompletesql, [$lookback, $lookback]);
$nologinsql = "SELECT auth, COUNT(id)
FROM {user}
WHERE deleted = 0
AND suspended = 0
AND lastlogin < ?
GROUP BY auth";
$nologininfo = $DB->get_records_sql($nologinsql, [$lookback]);
$mfauserssql = "SELECT auth,
COUNT(DISTINCT tm.userid)
FROM {tool_mfa} tm
JOIN {user} u ON u.id = tm.userid
WHERE tm.lastverified >= ?
AND u.deleted = 0
AND u.suspended = 0
GROUP BY u.auth";
$mfausersinfo = $DB->get_records_sql($mfauserssql, [$lookback]);
$factorsusedsql = "SELECT CONCAT(u.auth, '_', tm.factor) as id,
COUNT(*)
FROM {tool_mfa} tm
JOIN {user} u ON u.id = tm.userid
WHERE tm.lastverified >= ?
AND u.deleted = 0
AND u.suspended = 0
AND (tm.revoked = 0 OR (tm.revoked = 1 AND tm.timemodified > ?))
GROUP BY CONCAT(u.auth, '_', tm.factor)";
$factorsusedinfo = $DB->get_records_sql($factorsusedsql, [$lookback, $lookback]);
// Auth rows.
$authtypes = get_enabled_auth_plugins(true);
foreach ($authtypes as $authtype) {
$row = [];
$row[] = \html_writer::tag('b', $authtype);
// Setup the overall totals columns.
$row[] = $allusersinfo[$authtype]->count ?? '-';
$row[] = $mfausersinfo[$authtype]->count ?? '-';
$row[] = $noncompleteinfo[$authtype]->count ?? '-';
$row[] = $nologininfo[$authtype]->count ?? '-';
// Create a running counter for the total.
$authtotal = 0;
// Now for each factor add the count from the factor query, and increment the running total.
foreach ($columns as $column) {
if (!empty($column)) {
// Get the information from the data key.
$key = $authtype . '_' . $column;
$count = $factorsusedinfo[$key]->count ?? 0;
$authtotal += $count;
$row[] = $count ? format_float($count, 0) : '-';
}
}
// Append the total of all factors to final column.
$row[] = $authtotal ? format_float($authtotal, 0) : '-';
$table->data[] = $row;
}
// Total row.
$totals = [0 => html_writer::tag('b', get_string('total'))];
for ($colcounter = 1; $colcounter < count($row); $colcounter++) {
$column = array_column($table->data, $colcounter);
// Transform string to int forcibly, remove -.
$column = array_map(function ($element) {
return $element === '-' ? 0 : (int) $element;
}, $column);
$columnsum = array_sum($column);
$colvalue = $columnsum === 0 ? '-' : $columnsum;
$totals[$colcounter] = $colvalue;
}
$table->data[] = $totals;
// Wrap in a div to cleanly scroll.
return \html_writer::div(\html_writer::table($table), '', ['style' => 'overflow:auto;']);
}
/**
* Displays a table of all factors in use currently.
*
* @return string the HTML for the table
*/
public function factors_locked_table(): string {
global $DB;
$factors = factor::get_factors();
$table = new \html_table();
$table->attributes['class'] = 'generaltable table table-bordered w-auto';
$table->attributes['style'] = 'width: auto; min-width: 50%';
$table->head = [
'factor' => get_string('factor', 'tool_mfa'),
'active' => get_string('active'),
'locked' => get_string('state:locked', 'tool_mfa'),
'actions' => get_string('actions'),
];
$table->align = [
'left',
'left',
'right',
'right',
];
$table->data = [];
$locklevel = (int) get_config('tool_mfa', 'lockout');
foreach ($factors as $factor) {
$sql = "SELECT COUNT(DISTINCT(userid))
FROM {tool_mfa}
WHERE factor = ?
AND lockcounter >= ?
AND revoked = 0";
$lockedusers = $DB->count_records_sql($sql, [$factor->name, $locklevel]);
$enabled = $factor->is_enabled() ? \html_writer::tag('b', get_string('yes')) : get_string('no');
$actions = \html_writer::link( new \moodle_url($this->page->url,
['reset' => $factor->name, 'sesskey' => sesskey()]), get_string('performbulk', 'tool_mfa'));
$lockedusers = \html_writer::link(new \moodle_url($this->page->url, ['view' => $factor->name]), $lockedusers);
$table->data[] = [
$factor->get_display_name(),
$enabled,
$lockedusers,
$actions,
];
}
return \html_writer::table($table);
}
/**
* Displays a table of all users with a locked instance of the given factor.
*
* @param object_factor $factor the factor class
* @return string the HTML for the table
*/
public function factor_locked_users_table(object_factor $factor): string {
global $DB;
$table = new \html_table();
$table->attributes['class'] = 'generaltable table table-bordered w-auto';
$table->attributes['style'] = 'width: auto; min-width: 50%';
$table->head = [
'userid' => get_string('userid', 'grades'),
'fullname' => get_string('fullname'),
'factorip' => get_string('ipatcreation', 'tool_mfa'),
'lastip' => get_string('lastip'),
'modified' => get_string('modified'),
'actions' => get_string('actions'),
];
$table->align = [
'left',
'left',
'left',
'left',
'left',
'right',
];
$table->data = [];
$locklevel = (int) get_config('tool_mfa', 'lockout');
$sql = "SELECT mfa.id as mfaid, u.*, mfa.createdfromip, mfa.timemodified
FROM {tool_mfa} mfa
JOIN {user} u ON mfa.userid = u.id
WHERE factor = ?
AND lockcounter >= ?
AND revoked = 0";
$records = $DB->get_records_sql($sql, [$factor->name, $locklevel]);
foreach ($records as $record) {
// Construct profile link.
$proflink = \html_writer::link(new \moodle_url('/user/profile.php',
['id' => $record->id]), fullname($record));
// IP link.
$creatediplink = \html_writer::link(new \moodle_url('/iplookup/index.php',
['ip' => $record->createdfromip]), $record->createdfromip);
$lastiplink = \html_writer::link(new \moodle_url('/iplookup/index.php',
['ip' => $record->lastip]), $record->lastip);
// Deep link to logs.
$logicon = $this->pix_icon('i/report', get_string('userlogs', 'tool_mfa'));
$actions = \html_writer::link(new \moodle_url('/report/log/index.php', [
'id' => 1, // Site.
'user' => $record->id,
]), $logicon);
$action = new \confirm_action(get_string('resetfactorconfirm', 'tool_mfa', fullname($record)));
$actions .= $this->action_link(
new \moodle_url($this->page->url, ['reset' => $factor->name, 'id' => $record->id, 'sesskey' => sesskey()]),
$this->pix_icon('t/delete', get_string('resetconfirm', 'tool_mfa')),
$action
);
$table->data[] = [
$record->id,
$proflink,
$creatediplink,
$lastiplink,
userdate($record->timemodified, get_string('strftimedatetime', 'langconfig')),
$actions,
];
}
return \html_writer::table($table);
}
/**
* Returns a rendered support link.
* If the MFA guidance page is enabled, this is returned.
* Otherwise, the site support link is returned.
* If neither support link is configured, an empty string is returned.
*
* @return string
*/
public function get_support_link(): string {
// Try the guidance page link first.
if (get_config('tool_mfa', 'guidance')) {
return $this->render_from_template('tool_mfa/guide_link', []);
} else {
return $this->output->supportemail([], true);
}
}
/**
* Renders an mform element from a template
*
* In certain situations, includes a script element which adds autosubmission behaviour.
*
* @param mixed $element element
* @param bool $required if input is required field
* @param bool $advanced if input is an advanced field
* @param string|null $error error message to display
* @param bool $ingroup True if this element is rendered as part of a group
* @return mixed string|bool
*/
public function mform_element(mixed $element, bool $required,
bool $advanced, string|null $error, bool $ingroup): string|bool {
$script = null;
if ($element instanceof \tool_mfa\local\form\verification_field) {
if ($this->page->pagelayout === 'secure') {
$script = $element->secure_js();
}
}
$result = parent::mform_element($element, $required, $advanced, $error, $ingroup);
if (!empty($script) && $result !== false) {
$result .= $script;
}
return $result;
}
/**
* Renders the verification form.
*
* @param object_factor $factor The factor to render the form for.
* @param login_form $form The login form object.
* @return string
* @throws \coding_exception
* @throws \dml_exception
* @throws \moodle_exception
*/
public function verification_form(object_factor $factor, login_form $form): string {
$allloginfactors = factor::get_all_user_login_factors();
$additionalfactors = [];
$disabledfactors = [];
$displaycount = 0;
$disablefactor = false;
foreach ($allloginfactors as $loginfactor) {
if ($loginfactor->name != $factor->name) {
$additionalfactor = [
'name' => $loginfactor->name,
'icon' => $loginfactor->get_icon(),
'loginoption' => get_string('loginoption', 'factor_' . $loginfactor->name),
];
// We mark the factor as disabled if it is locked.
// We store the disabled factors in a separate array so that they can be displayed at the bottom of the template.
if ($loginfactor->get_state() == factor::STATE_LOCKED) {
$additionalfactor['loginoption'] = get_string('locked', 'tool_mfa', $additionalfactor['loginoption']);
$additionalfactor['disable'] = true;
$disabledfactors[] = $additionalfactor;
} else {
$additionalfactors[] = $additionalfactor;
}
$displaycount++;
}
}
// We merge the additional factors placing the disabled ones last.
$alladitionalfactors = array_merge($additionalfactors, $disabledfactors);
$hasadditionalfactors = $displaycount > 0;
$authurl = new \moodle_url('/admin/tool/mfa/auth.php');
// Set the form to better display vertically.
$form->set_display_vertical();
// Check if we need to display a remaining attempts message.
$remattempts = $factor->get_remaining_attempts();
$verificationerror = $form->get_element_error('verificationcode');
if ($remattempts < get_config('tool_mfa', 'lockout') && !empty($verificationerror)) {
// Update the validation error for the code form field to include the remaining attempts.
$remattemptsstr = get_string('lockoutnotification', 'tool_mfa', $factor->get_remaining_attempts());
$updatederror = $verificationerror . '&nbsp;' . $remattemptsstr;
$form->set_element_error('verificationcode', $updatederror);
}
// If all attempts for this factor have been used, disable the form.
// This forces the user to choose another factor or cancel their login.
if ($remattempts <= 0) {
$disablefactor = true;
$form->freeze('verificationcode');
// Handle the trust factor if present.
if ($form->element_exists('factor_token_trust')) {
$form->freeze('factor_token_trust');
}
}
$context = [
'logintitle' => get_string('logintitle', 'factor_'.$factor->name),
'logindesc' => $factor->get_login_desc(),
'factoricon' => $factor->get_icon(),
'form' => $form->render(),
'hasadditionalfactors' => $hasadditionalfactors,
'additionalfactors' => $alladitionalfactors,
'authurl' => $authurl->out(),
'sesskey' => sesskey(),
'supportlink' => $this->get_support_link(),
'disablefactor' => $disablefactor
];
return $this->render_from_template('tool_mfa/verification_form', $context);
}
}
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_admin
* @subpackage tool_mfa
* @author Peter Burnett <peterburnett@catalyst-au.net>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_admin'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
-58
View File
@@ -1,58 +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/>.
/**
* factor_auth upgrade library.
*
* @package factor_auth
* @copyright 2021 Peter Burnett <peterburnett@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Factor auth upgrade helper function
*
* @param int $oldversion
*/
function xmldb_factor_auth_upgrade($oldversion) {
if ($oldversion < 2021020500) {
$authtypes = get_enabled_auth_plugins(true);
// Upgrade goodauth config from number to name.
$goodauth = explode(',', get_config('factor_auth', 'goodauth'));
$newauths = [];
foreach ($goodauth as $auth) {
// Check if index exists before access. If not, ignore, settings were out of sync.
if (array_key_exists($auth, $authtypes)) {
$newauths[] = $authtypes[$auth];
}
}
set_config('goodauth', implode(',', $newauths), 'factor_auth');
// MFA savepoint reached.
upgrade_plugin_savepoint(true, 2021020500, 'factor', 'auth');
}
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.5.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_auth
* @subpackage tool_mfa
* @author Mikhail Golenkov <golenkovm@gmail.com>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_auth'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
@@ -1,32 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_capability
* @subpackage tool_mfa
* @author Peter Burnett <peterburnett@catalyst-au.net>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_capability'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_cohort
* @subpackage tool_mfa
* @author Chris Pratt <tonyyeb@gmail.com>
* @copyright Chris Pratt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_cohort'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
@@ -1,57 +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/>.
/**
* factor_email upgrade library.
*
* @package factor_email
* @copyright 2024 David Woloszyn <david.woloszyn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* MFA upgrade helper function.
*
* @param int $oldversion
*/
function xmldb_factor_email_upgrade($oldversion): bool {
if ($oldversion < 2024122400) {
// Check for sites that don't have MFA enabled.
if (!get_config('tool_mfa', 'enabled')) {
// Enable email factor.
set_config('enabled', 1, 'factor_email');
// Check factor order config to ensure email is situated in there.
$factororderconfig = get_config('tool_mfa', 'factor_order');
if (!$factororderconfig) {
set_config('factor_order', 'email', 'tool_mfa');
} else {
$order = explode(',', $factororderconfig);
// Remove any empty entries (this happens with entries like ',sms,email').
$order = array_filter($order);
if (!in_array('email', $order)) {
array_unshift($order, 'email');
$orderstring = implode(',', $order);
set_config('factor_order', $orderstring, 'tool_mfa');
}
}
}
upgrade_plugin_savepoint(true, 2024122400, 'factor', 'email');
}
return true;
}
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_email
* @subpackage tool_mfa
* @author Mikhail Golenkov <golenkovm@gmail.com>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_email'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_grace
* @subpackage tool_mfa
* @author Peter Burnett <peterburnett@catalyst-au.net>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_grace'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
-31
View File
@@ -1,31 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_iprange
* @author Mikhail Golenkov <golenkovm@gmail.com>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_iprange'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_nosetup
* @subpackage tool_mfa
* @author Peter Burnett <peterburnett@catalyst-au.net>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_nosetup'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_role
* @subpackage tool_mfa
* @author Peter Burnett <peterburnett@catalyst-au.net>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_role'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
-100
View File
@@ -1,100 +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/>.
/**
* factor_sms upgrade library.
*
* @package factor_sms
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Factor sms upgrade helper.
*
* @param int $oldversion Previous version of the plugin.
* @return bool
*/
function xmldb_factor_sms_upgrade(int $oldversion): bool {
if ($oldversion < 2024082200) {
$config = get_config('factor_sms');
// If the sms factor is enabled, then do the migration to the sms subsystem.
if ((int)$config->enabled === 1) {
// SMS gateway configs.
$smsconfig = new stdClass();
$smsconfig->countrycode = $config->countrycode;
$smsconfig->gateway = $config->gateway;
$smsconfig->usecredchain = $config->usecredchain;
$smsconfig->api_key = $config->api_key;
$smsconfig->api_secret = $config->api_secret;
$smsconfig->api_region = $config->api_region;
// Now insert the record.
$manager = \core\di::get(\core_sms\manager::class);
$gateway = $manager->create_gateway_instance(
classname: \smsgateway_aws\gateway::class,
name: 'MFA AWS',
enabled: $config->enabled,
config: $smsconfig,
);
// Set the mfa config for the sms gateway.
set_config('smsgateway', $gateway->id, 'factor_sms');
// Now add the task to send notification to admins about this migration.
$task = new \factor_sms\task\sms_gateway_migration_notification();
\core\task\manager::queue_adhoc_task($task, true);
}
// MFA savepoint reached.
upgrade_plugin_savepoint(true, 2024082200, 'factor', 'sms');
}
if ($oldversion < 2024082201) {
// Unset the removed admin settings.
unset_config('countrycode', 'factor_sms');
unset_config('gateway', 'factor_sms');
unset_config('usecredchain', 'factor_sms');
unset_config('api_key', 'factor_sms');
unset_config('api_secret', 'factor_sms');
unset_config('api_region', 'factor_sms');
// MFA savepoint reached.
upgrade_plugin_savepoint(true, 2024082201, 'factor', 'sms');
}
// Automatically generated Moodle v4.5.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2025040700) {
// Ensure default values are applied for the MFA SMS factor when upgrading.
$config = get_config('factor_sms');
// Set the weight to the default value (100) if it is misconfigured (e.g. set to 0).
$weight = $config->weight ?? null;
if (isset($weight) && (int)$weight <= 0) {
set_config('weight', 100, 'factor_sms');
}
// Set the duration to the default value (30 minutes) if it is misconfigured (e.g. set to 0).
$duration = $config->duration ?? null;
if (isset($duration) && (int)$duration <= 0) {
set_config('duration', 30 * MINSECS, 'factor_sms');
}
// MFA savepoint reached.
upgrade_plugin_savepoint(true, 2025040700, 'factor', 'sms');
}
return true;
}
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_sms
* @subpackage tool_mfa
* @author Peter Burnett <peterburnett@catalyst-au.net>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_sms'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_token
* @subpackage tool_mfa
* @author Peter Burnett <peterburnett@catalyst-au.net>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_token'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;
-46
View File
@@ -1,46 +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/>.
/**
* factor_totp upgrade library.
*
* @package factor_totp
* @copyright 2024 Daniel Ziegenberg <daniel@ziegenberg.at>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Factor totp upgrade helper function
*
* @param int $oldversion
*/
function xmldb_factor_totp_upgrade($oldversion): bool {
if ($oldversion < 2024081600) {
$window = get_config('factor_totp', 'window');
if ($window && $window >= 30) {
set_config('window', 29, 'factor_totp');
}
// Savepoint reached.
upgrade_plugin_savepoint(true, 2024081600, 'factor', 'totp');
}
// Automatically generated Moodle v4.5.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
-32
View File
@@ -1,32 +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/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package factor_totp
* @subpackage tool_mfa
* @author Mikhail Golenkov <golenkovm@gmail.com>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2025040800; // Requires this Moodle version.
$plugin->component = 'factor_totp'; // Full name of the plugin (used for diagnostics).
$plugin->maturity = MATURITY_STABLE;

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