Compare commits

...

529 Commits

Author SHA1 Message Date
Eloy Lafuente (stronk7) de301d4237 Moodle release 3.9.4 2021-01-16 16:58:25 +01:00
Sara Arjona e2c8f4ad1b weekly release 3.9.3+ 2021-01-15 08:25:45 +01:00
Sara Arjona 8c1455d220 Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2021-01-15 08:25:44 +01:00
Sara Arjona 7b85e141da Merge branch 'MDL-69308_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2021-01-14 12:04:13 +01:00
Jake Dallimore cd744ba504 Merge branch 'MDL-69877-39' of git://github.com/mickhawkins/moodle into MOODLE_39_STABLE 2021-01-14 14:52:36 +08:00
Michael Hawkins 974c63505b MDL-69877 core: Added security.txt 2021-01-14 14:31:01 +08:00
AMOS bot 724210c4f7 Automatically generated installer lang files 2021-01-14 00:07:44 +00:00
Eloy Lafuente (stronk7) ae9d510288 MDL-69308 environment: Apply agreed changes
- PHP 7.3 required.
- Moodle 3.6 required.
- SQL*Server 2017 (aka, 14.0) required.
- Sodium PHP extension required.
2021-01-13 19:30:15 +01:00
Eloy Lafuente (stronk7) 981f750b81 MDL-69308 environment: 3.11 base information
This is a direct copy of the 3.10 branch to have
the changes under control in next commits.
2021-01-13 19:30:10 +01:00
Mihail Geshoski 721d57228f MDL-68486 auth_shibboleth: Reset convert_data if it uses dataroot file
Upgrade step that resets the 'Data modification API' (convert_data)
setting to its default value if this setting is currently configured
to use a file located within the $CFG->dataroot directory.
2021-01-13 12:35:42 +08:00
Mihail Geshoski 3c25c373d9 MDL-68486 auth_shibboleth: Prevent using dataroot files in convert_data
Prevents configuring the 'Data modification API' (convert_data) setting
to use files located within the $CFG->dataroot directory as it exposes
the site to security risks.
2021-01-13 12:35:42 +08:00
AMOS bot 17eb41c270 Automatically generated installer lang files 2021-01-13 00:07:45 +00:00
Michael Hawkins af6e65f221 MDL-69911 core: Clean content passed through TeX filter 2021-01-12 10:27:31 +01:00
Ferran Recio 8bbc064e29 MDL-67782 message: fix messages max length 2021-01-12 10:27:31 +01:00
Juan Segarra Montesinos 78b18c00bf MDL-69797 core_grades: Implement authorization into fetch method 2021-01-12 10:27:31 +01:00
Juan Segarra Montesinos 4b3b4b7d78 MDL-69797 core_grades: Implement authorization into fetch method 2021-01-12 10:27:31 +01:00
Juan Segarra Montesinos 557d1c8820 MDL-69797 gradingform_rubric: Implement authorization into fetch method 2021-01-12 10:27:31 +01:00
Juan Segarra Montesinos 698e1f7823 MDL-69797 gradingform_guide: Implement authorization into fetch method 2021-01-12 10:27:31 +01:00
Sara Arjona 5b4702a6b6 Merge branch 'MDL-70009-39' of git://github.com/ilyatregubov/moodle into MOODLE_39_STABLE 2021-01-12 10:21:20 +01:00
Jake Dallimore 77c0b16613 Merge branch 'MDL-69431_Validate_section_arg_modedit' of git://github.com/watson8/moodle into MOODLE_39_STABLE 2021-01-12 17:09:29 +08:00
Ilya Tregubov 9adef8af21 MDL-70009 h5pactivity: Split get_pluginfile_hash in two methods. 2021-01-12 09:11:04 +02:00
AMOS bot cc45df637f Automatically generated installer lang files 2021-01-12 00:07:54 +00:00
Sara Arjona 13655cd5ea Merge branch 'MDL-70034_39' of git://github.com/mdjnelson/moodle into MOODLE_39_STABLE 2021-01-11 15:19:39 +01:00
Sara Arjona ea3f1d19b9 Merge branch 'MDL-70567-MOODLE_39_STABLE' of https://github.com/dmitriim/moodle into MOODLE_39_STABLE 2021-01-11 13:09:56 +01:00
Sara Arjona 8256ebd431 Merge branch 'MDL-70578-39' of git://github.com/lucaboesch/moodle into MOODLE_39_STABLE 2021-01-11 12:58:28 +01:00
Sara Arjona 8ba97d0104 Merge branch 'MDL-70352-MOODLE_39_STABLE' of https://github.com/dmitriim/moodle into MOODLE_39_STABLE 2021-01-11 12:24:12 +01:00
AMOS bot 71ee378a69 Automatically generated installer lang files 2021-01-11 00:08:59 +00:00
David Watson 8208453a14 MDL-69431 course: validate section url param against maxsections 2021-01-10 17:11:50 +00:00
Eloy Lafuente (stronk7) 7c6e9b37b3 Merge branch 'MDL-70550-39-enfix' of git://github.com/mudrd8mz/moodle into MOODLE_39_STABLE 2021-01-09 13:18:02 +01:00
Mark Nelson 19dc872bca MDL-70034 gradingform_guide: use new API to retrieve grade item name 2021-01-09 14:31:18 +08:00
AMOS bot 0a51214fb3 Automatically generated installer lang files 2021-01-09 00:07:50 +00:00
Sara Arjona 6910afa56f Merge branch 'MDL-70558-39' of git://github.com/paulholden/moodle into MOODLE_39_STABLE 2021-01-08 17:07:29 +01:00
Sara Arjona 5e5e82621c Merge branch 'MDL-70102-m39' of https://github.com/sammarshallou/moodle into MOODLE_39_STABLE 2021-01-08 15:51:14 +01:00
David Mudrák 2edff57e63 MDL-70550 lang: Use the fixed strings in Behat tests, too 2021-01-08 09:17:03 +01:00
Helen Foster 3b8bb4d4c1 MDL-70550 lang: Import fixed English strings (en_fix) 2021-01-08 09:16:38 +01:00
Jun Pataleta 920763ad00 Merge branch 'MDL-70310-39' of git://github.com/ilyatregubov/moodle into MOODLE_39_STABLE 2021-01-08 14:47:05 +08:00
Luca Bösch 1acd3cac07 MDL-70578 cohorts: Add bootstrap classes to buttons 2021-01-08 07:28:02 +01:00
Jun Pataleta 7de4119fe2 weekly release 3.9.3+ 2021-01-08 12:14:52 +08:00
Jun Pataleta 6fb2fa9859 Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2021-01-08 12:14:51 +08:00
AMOS bot 1d54d21ec0 Automatically generated installer lang files 2021-01-08 00:07:44 +00:00
Eloy Lafuente (stronk7) c87ed01b17 Merge branch 'MDL-70245-MOODLE_39_STABLE' of https://github.com/TomoTsuyuki/moodle into MOODLE_39_STABLE 2021-01-07 23:50:05 +01:00
Eloy Lafuente (stronk7) 23541c936a Merge branch 'MDL-70584-39' of git://github.com/marinaglancy/moodle into MOODLE_39_STABLE 2021-01-07 23:30:53 +01:00
sam marshall b7490a205f MDL-70102 PHPunit: Core test fails with weird added modules
Specifically it fails if the modules have unusual default capabilities
so that editingteacher doesn't have addinstance.
2021-01-07 16:12:30 +00:00
Marina Glancy 8415e0461b MDL-70584 core_iplookup: increase tolerance in test 2021-01-07 14:23:33 +01:00
Ilya Tregubov 9ee41118b0 MDL-70310 user: Remove yahoo icon since domain no longer exists. 2021-01-07 09:15:35 +02:00
Jun Pataleta 137b10b378 Merge branch 'MDL-70374_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2021-01-07 12:23:34 +08:00
Eloy Lafuente (stronk7) bb9e3ec1ff Merge branch 'MDL-70476_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2021-01-07 00:28:16 +01:00
Eloy Lafuente (stronk7) 7152b05700 Merge branch 'MOODLE_39_MDL-70520' of https://github.com/golenkovm/moodle into MOODLE_39_STABLE 2021-01-07 00:19:23 +01:00
Dmitrii Metelkin 087ccaff4f MDL-70567 task: fix broken result filter on logs page 2021-01-06 14:28:38 +11:00
Dmitrii Metelkin 3fb245f481 MDL-70352 core: attach modal to a specific element 2021-01-06 11:09:01 +11:00
Paul Holden 8de31cf961 MDL-70558 tool_langimport: sort available language packs. 2021-01-04 23:56:05 +00:00
AMOS bot 88e7da61cd Automatically generated installer lang files 2020-12-27 00:07:46 +00:00
AMOS bot 3648b629ed Automatically generated installer lang files 2020-12-24 00:07:52 +00:00
Eloy Lafuente (stronk7) 0d833e248a weekly release 3.9.3+ 2020-12-23 20:24:49 +01:00
Eloy Lafuente (stronk7) 783fba428f Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-12-23 20:24:46 +01:00
Eloy Lafuente (stronk7) 514c7ee639 Merge branch 'MDL-56119-390' of https://github.com/inigozendegi/moodle into MOODLE_39_STABLE 2020-12-23 01:07:59 +01:00
Eloy Lafuente (stronk7) fa35b9506f Merge branch 'MDL-70279-39' of git://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-12-23 00:47:09 +01:00
Eloy Lafuente (stronk7) 29f7630b75 Merge branch 'MDL-70436-39' of git://github.com/bmbrands/moodle into MOODLE_39_STABLE 2020-12-22 18:30:03 +01:00
Eloy Lafuente (stronk7) 7a2a47d9e8 Merge branch 'MDL-70386-39' of git://github.com/bmbrands/moodle into MOODLE_39_STABLE 2020-12-22 18:22:10 +01:00
Jake Dallimore 17211224a1 Merge branch 'MDL-69422-39-2' of git://github.com/junpataleta/moodle into MOODLE_39_STABLE 2020-12-22 16:03:33 +08:00
Jake Dallimore 2394a675dd Merge branch 'MDL-70426-39' of https://github.com/HuongNV13/moodle into MOODLE_39_STABLE 2020-12-22 15:17:02 +08:00
Mikhail Golenkov 449c835fe2 MDL-70520 mod_assign: Use task API to get scheduled task lastruntime 2020-12-22 15:31:42 +11:00
Mikhail Golenkov 322afa9f4f MDL-70520 tasks: Keep lastruntime when a scheduled task is reset 2020-12-22 15:31:38 +11:00
AMOS bot 1d0777dbe4 Automatically generated installer lang files 2020-12-22 00:07:45 +00:00
Víctor Déniz cd94f2bc2e Merge branch 'MDL-70355-39' of git://github.com/lucaboesch/moodle into MOODLE_39_STABLE 2020-12-21 23:18:49 +00:00
Sara Arjona e899fd5c02 Merge branch 'MDL-69107-39-2' of git://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-12-18 15:22:41 +01:00
Tim Hunt 438b2ac8c2 MDL-70374 qtype_multichoice: improve alignment of choices 2020-12-18 13:09:41 +00:00
Tim Hunt f6ae03bf41 MDL-70476 permission overrides: role names double-escaped in tool tip 2020-12-18 13:09:02 +00:00
Luca Bösch fc52aaf319 MDL-70355 calendar: Filter popuptext for calendar entries. 2020-12-17 17:42:42 +01:00
Sara Arjona ef8eb8ef1a weekly release 3.9.3+ 2020-12-17 15:52:48 +01:00
Sara Arjona f1c6cf8b26 Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-12-17 15:52:46 +01:00
Víctor Déniz e68cea5747 Merge branch 'MDL-70261-39' of git://github.com/ilya-catalyst/moodle into MOODLE_39_STABLE 2020-12-16 12:36:13 +00:00
Sara Arjona 3f797704ea Merge branch 'MDL-70373_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2020-12-16 12:40:58 +01:00
Jun Pataleta aae57db8d2 Merge branch 'MDL-54907_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2020-12-16 10:01:04 +08:00
Andrew Nicols 8c3091e5f3 MDL-69107 user: Fix autocomplete usages 2020-12-16 07:50:56 +08:00
Sara Arjona b52ad05038 Merge branch 'MDL-70422-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-12-15 16:43:14 +01:00
Sara Arjona ec5d807139 Merge branch 'MDL-70409-39' of git://github.com/merrill-oakland/moodle into MOODLE_39_STABLE 2020-12-15 16:15:59 +01:00
Sara Arjona 1f00b5d9bb Merge branch 'MDL-70342-39' of git://github.com/abias/moodle into MOODLE_39_STABLE 2020-12-15 15:29:28 +01:00
Sara Arjona 0f53bd6b8e Merge branch 'MDL-70357-39-cronlibthrowables' of git://github.com/mudrd8mz/moodle into MOODLE_39_STABLE 2020-12-15 14:56:12 +01:00
Ilya Tregubov bf29fea4bb MDL-70261 course: Allow update locked course custom fields
on course upload.
2020-12-15 14:43:18 +02:00
Jake Dallimore 8a733bc85f Merge branch 'MDL-67623-39_blocks_myoverview_pagination_regression' of https://github.com/tomdickman/moodle into MOODLE_39_STABLE 2020-12-15 18:22:28 +08:00
Andrew Nicols 1b87f634a8 MDL-69107 form_autocomplete: Rewrite item selection
The form_autocomplete is essentially a custom element. Unfortunately the
`setValue()` function in Mink has undesired actions so it is necessary
to write our own handling for it.

The standard Mink `setValue()` function focuses the element, sets a
value, and then blurs the element. In the case of the autocomplete this
can cause the autocomplete suggestions list to be closed in some
situations. Instead of using the setValue we click, and type the value,
but do not immediately blur.
2020-12-15 09:08:05 +08:00
AMOS bot 9260dad3b3 Automatically generated installer lang files 2020-12-15 00:07:45 +00:00
Sara Arjona 6002a1454f Merge branch 'MDL-70397-39' of git://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-12-14 17:12:15 +01:00
Jake Dallimore cef3216f2a Merge branch 'MDL-70324-3.9' of https://github.com/JBThong/moodle into MOODLE_39_STABLE 2020-12-14 11:30:32 +08:00
Tom Dickman bed6bfe7d4 MDL-67623 block overview: fix pagination regression
Fixed a regression caused by MDL-64194 resulting in Dashboard - Course
overview pagination not working from second page of courses onwards.

Course overview block should now do the following:
- Display no pagination controls when user has no courses
- Display no pagination controls when less than 12 courses to display
- Only display pagination controls up to the number of courses user is
enrolled in
- Work correctly when on a page greater than the second page.
2020-12-14 13:34:38 +11:00
AMOS bot 1c39517553 Automatically generated installer lang files 2020-12-13 00:07:45 +00:00
AMOS bot e92846ce18 Automatically generated installer lang files 2020-12-12 00:07:55 +00:00
AMOS bot 31d0ccb078 Merge branch 'MOODLE_39_STABLE' into install_39_STABLE 2020-12-12 00:07:54 +00:00
AMOS bot fc7fa7f72c Automatically generated installer lang files 2020-12-11 00:07:53 +00:00
Víctor Déniz 6994f63eef weekly release 3.9.3+ 2020-12-10 21:10:36 +00:00
Víctor Déniz c28c0ed466 Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-12-10 21:10:30 +00:00
Huong Nguyen 479b0f0eaa MDL-70426 qtype_ddmarker: infinite markers keep duplicating 2020-12-10 15:55:24 +07:00
Shamim Rezaie 7b96e8a413 MDL-69301 theme_boost: Remove the special handling of Escape key 2020-12-10 14:56:46 +08:00
Tomo Tsuyuki 2321fe4da9 MDL-70245 core_grade: Fix grade_get_setting unit test failures
To fix the phpunit issue, change from static variable to use cache
2020-12-10 16:46:54 +11:00
Jake Dallimore 3aa05048cf Merge branch 'MDL-70320-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-12-10 12:02:53 +08:00
Andrew Nicols 17d6ecd26d MDL-70320 behat: User full path to page admin node 2020-12-10 07:56:58 +08:00
Bas Brands 7d5c5fad77 MDL-70386 theme_boost: quizes correctness badges 2020-12-09 18:09:27 +01:00
Bas Brands c1296560bf MDL-70436 theme_boost: closebutton styles in moodle-dialog-fullscreen 2020-12-09 14:59:50 +01:00
Víctor Déniz 93e25f8657 Merge branch 'MDL-63683-39' of https://github.com/dravek/moodle into MOODLE_39_STABLE 2020-12-09 12:46:18 +00:00
Jake Dallimore f43de821c6 Merge branch 'MDL-70151-39' of git://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-12-09 14:46:36 +08:00
Andrew Nicols 1b0690a7f1 Merge branch 'MDL-70320_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2020-12-09 12:07:32 +08:00
Andrew Nicols e003e8a6ff Merge branch 'MDL-62707-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-12-09 08:58:12 +08:00
Jake Dallimore 1e8f432437 Merge branch 'MDL-70285_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2020-12-08 16:34:10 +08:00
AMOS bot 51d7849f08 Automatically generated installer lang files 2020-12-08 00:07:43 +00:00
Paul Holden ede7d22dc7 MDL-70422 restore: fix for undefined question answer ordering in test. 2020-12-07 10:15:55 +00:00
Adrian Greeve 4355451e2f Merge branch 'MDL-69301-39' of git://github.com/rezaies/moodle into MOODLE_39_STABLE 2020-12-07 09:23:27 +08:00
AMOS bot 5e102fa8c3 Automatically generated installer lang files 2020-12-06 00:07:50 +00:00
Eric Merrill 1925b641e2 MDL-70409 chat: Use require_once to import lib.php 2020-12-04 10:46:16 -05:00
Paul Holden 377da86151 MDL-70279 tool_templatelibrary: preserve component search field value. 2020-12-04 14:55:28 +00:00
Paul Holden 9a2db9e2ec MDL-62707 search: account for no matching courses when listing areas.
When limiting the list of courses during retrieval of the search areas
the user can access, make sure we have some contexts before looking
for blocks.
2020-12-04 09:43:27 +00:00
inigozendegi 844637b880 MDL-56119 gradingform_rubric: Rubric display layout issue 2020-12-04 09:41:40 +01:00
David Matamoros 9e597d3658 MDL-63683 enrol: Fix plugin settings when no role has student archetype 2020-12-04 09:27:20 +01:00
Andrew Nicols 0e25936c0d MDL-70397 behat: Prevent browser restarting after initial start 2020-12-04 12:07:36 +08:00
Jake Dallimore 627e14727e weekly release 3.9.3+ 2020-12-04 08:42:43 +08:00
Jake Dallimore ffe84e977f Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-12-04 08:42:40 +08:00
Andrew Nicols 7bc67e92e2 Merge branch 'MDL-70080-39' of git://github.com/jleyva/moodle into MOODLE_39_STABLE 2020-12-03 11:55:54 +08:00
Andrew Nicols dd96341354 Merge branch 'MDL-70327-39' of git://github.com/cescobedo/moodle into MOODLE_39_STABLE 2020-12-03 11:52:06 +08:00
Andrew Nicols 1714cb74b3 Merge branch 'MDL-70321_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2020-12-03 11:40:24 +08:00
Jake Dallimore c94c579aa6 Merge branch 'MDL-69411-39' of git://github.com/dravek/moodle into MOODLE_39_STABLE 2020-12-03 11:37:17 +08:00
Jake Dallimore 16bcd8f057 Merge branch 'MDL-67460-39_profile_secure' of https://github.com/beenet-dev/moodle into MOODLE_39_STABLE 2020-12-03 11:16:52 +08:00
Andrew Nicols 5e65d02eab Merge branch 'MDL-70157_39' of https://github.com/rlorenzo/moodle into MOODLE_39_STABLE 2020-12-03 11:01:21 +08:00
Adrian Greeve 1b8bfedaa9 Merge branch 'wip_MDL-70267_m39' of git://github.com/gjb2048/moodle into MOODLE_39_STABLE 2020-12-03 10:55:54 +08:00
Adrian Greeve 7b920d2d7b Merge branch 'MDL-70167-39' of git://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-12-03 09:56:42 +08:00
AMOS bot 63b0a865dd Automatically generated installer lang files 2020-12-03 00:07:48 +00:00
Andrew Nicols 7766af18a5 Merge branch 'MDL-69868-39' of git://github.com/ilya-catalyst/moodle into MOODLE_39_STABLE 2020-12-03 07:48:59 +08:00
Tim Hunt 14d68d98b5 MDL-70373 qtype_essay: missing border on atto input 2020-12-02 20:10:15 +00:00
Shamim Rezaie 8676a67888 MDL-69301 course: Remove custom keyboard navigation code 2020-12-02 23:11:27 +11:00
Shamim Rezaie 8af16c5709 MDL-69301 core: Enhanced WAI-ARIA support for tab elements 2020-12-02 23:08:13 +11:00
Shamim Rezaie 7f74dc1c16 MDL-69301 theme_boost: convert aria.js to es6 module 2020-12-02 23:08:13 +11:00
Jake Dallimore 5bdc07a3b6 Merge branch 'MDL-67514-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-12-02 16:24:30 +08:00
AMOS bot bccfc48b94 Automatically generated installer lang files 2020-12-02 00:07:44 +00:00
Thong Bui 95c3de0877 MDL-70324 Question: get_all_response_file_areas() not work correctly 2020-12-01 16:16:45 +07:00
AMOS bot d833fc2131 Automatically generated installer lang files 2020-12-01 00:07:51 +00:00
David Mudrák 6e04f9f294 MDL-70357 cron: Catch Throwables not just Exceptions when running tasks
Starting from PHP 7, most language errors throw Error exceptions. We
want to deal with those equally as with any other exception so we need
to catch all Throwables here.
2020-11-30 17:37:39 +01:00
Alexander Bias 7f45f9ab3e MDL-70342 block_timeline: Get rid of double quotes
This commit gets rid of double quotes around the activity name and course name
which have sneaked into block_timeline's view in MDL-65183.
2020-11-30 13:18:40 +01:00
Gareth Barnard 547a6dcdde MDL-70267 ux, theme: Course user profile inconsistent page layout. 2020-11-29 23:52:32 +00:00
AMOS bot 28fff43d2b Automatically generated installer lang files 2020-11-29 00:07:54 +00:00
Tim Hunt 7565cda9c6 MDL-54907 quiz unit tests: clean up code style in attempts_test.php 2020-11-27 18:30:19 +00:00
Tim Hunt 90fa490de7 MDL-54907 quiz: better timefinish for attempts finished asynchronously
There are serveral ways a quiz attempt can be submitted:

1. The student click the Submit and finish button. In this case,
   no problem. We record the current time as the finish time
   for the quiz attempt.

2. The student is activly working away at the quiz, and the
   count-down timer reachers zero. In this case, we also record
   the current time. Note that, if the server is under high load,
   then this could well end up being a few seconds after the
   theoretical end time, so you could have a quiz with a 30 minute
   time limit, with an attempt that lasted 30:07. However, this
   is just an accurate reflection of what happened, so should
   be recorded like this.

3. If the student is offline when the time expires, then
   (depending on the quiz settings) the attempt may be
   automatically submitted by cron, but this will happen with
   at least some delay (to prevent race conditions between cron
   and a student working online) and if cron is running slow
   on the server, it could be a lot later. Previously, this led
   to, say, a 30 minute quiz where an attempt seemed to have
   lasted 67 minutes, which confused people.

   Now, in this situation, the finsh time for the quiz attempt is
   recorded as the time when the time limit ran out. This is not
   just less confusing for teachers looking at the quiz report,
   it is also more accurate. That is the latest time at which
   students could have made any changes to their responses.
2020-11-27 18:30:19 +00:00
Tim Hunt 5f9ddb348e MDL-54907 quiz generator: defaults should match a new Moodle install 2020-11-27 18:30:18 +00:00
Tim Hunt ff8da7e008 MDL-54907 dml: Correct incorrect PHPdoc 2020-11-27 18:30:18 +00:00
Jun Pataleta a6ab91786f MDL-69422 mod_data: Export form accessibility fixes
* Set appropriate heading element IDs
* Replace usages of deprecated HTML tag acronym with abbr instead.
* Add a label for the export fields fieldset.
* Move the CSV delimiter list outside the radio group.
* Fix div under a label element and duplicate labels
for the checkboxes of the fields to be exported by showing the field
name and type together.
* Group the fields to be exported as a fieldset.
* Move unsupported fields into a separate list.
* Move export options into its own section and group the options as a
fieldset.
2020-11-27 23:24:26 +08:00
Jun Pataleta 0a43bdcc6c MDL-69422 core: Convert required and help button container to div
* A span element cannot have a div as a child.
2020-11-27 23:24:26 +08:00
Juan Leyva b1a4bd579a MDL-70080 tool_mobile: Return support contact information via WS 2020-11-27 10:19:15 +01:00
Sara Arjona 4825c139ef weekly release 3.9.3+ 2020-11-27 07:50:43 +01:00
Sara Arjona d207a2ad02 Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-11-27 07:50:40 +01:00
AMOS bot ccc6b4d00b Automatically generated installer lang files 2020-11-27 06:21:32 +00:00
Tim Hunt cc3a909810 MDL-70320 permission overrides: role names were double-escaped 2020-11-26 20:37:18 +00:00
Sara Arjona c93de36436 Merge branch 'MDL-70276_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2020-11-26 15:04:48 +01:00
Ilya Tregubov da3ebf216e MDL-69868 h5pactivity: Prevent breaking $USER when seeing
attempt report.
2020-11-26 12:40:33 +02:00
Andrew Nicols 7c8fd0d417 Merge branch 'MDL-70242-39' of git://github.com/marinaglancy/moodle into MOODLE_39_STABLE 2020-11-26 10:49:32 +08:00
Andrew Nicols 558ace5997 Merge branch 'MDL-65852-39' of git://github.com/ilya-catalyst/moodle into MOODLE_39_STABLE 2020-11-26 10:04:23 +08:00
Eloy Lafuente (stronk7) 98254ccd1a MDL-70276 github actions: First cut, phpunit and grunt checks
First working version, supports phpunit (using build matrix):

- php72 (lowest), running mysql.
- php74 (highest), running postgres.

Also verifies that the branch has been "gruntified" and there
isn't any missing change (build js/css files).

TODO: Verify the remaining checks currently in .travis.yml, namely:
 - CITEST
 - Add caching
 - Better health-check for DB images.
 - Support from the tracker (satus badges and enable check).
 - Support from CiBoT (status and enable check).
 - Consider moving both the common setup (git, composer...)
   and the database (mysql, postgres) to own actions for
   easier tweaking.
2020-11-26 00:23:49 +01:00
cescobedo 5be02868af MDL-70327 core_h5p: Add preventredirect to the player 2020-11-25 16:30:50 +01:00
Sara Arjona a36b3ec48f Merge branch 'MDL-70248-39' of https://github.com/HuongNV13/moodle into MOODLE_39_STABLE 2020-11-25 16:23:07 +01:00
Sara Arjona ea4e0ae3cb Merge branch 'MDL-70265_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2020-11-25 15:47:01 +01:00
Ilya Tregubov 68c3eb8aa9 MDL-65852 user: Fix permission check to download course participants. 2020-11-25 11:27:31 +02:00
Tim Hunt 331b9947a3 MDL-70321 question backup: fix MDL-47178 unit tests
They were failing if you had CodeRunner installed
2020-11-24 15:29:55 +00:00
Simon Mok 4e8d58374e MDL-67460 profile: User profile link to use HTTPS 2020-11-24 20:49:35 +08:00
Tim Hunt 86669b0564 MDL-70285 completion upgrade: fix performance of the MDL-69687 code 2020-11-23 21:02:08 +00:00
David Matamoros e80e613f65 MDL-69411 core_message: Fix return structure for empty result set
Passing a timefrom higher than last message timecreated needs to
return a formatted response so it does not break ws.
2020-11-23 19:25:44 +01:00
Eloy Lafuente (stronk7) 81410615ed MDL-70265 travis: Completely remove the UPGRADE check
It was broken since ages ago, see MDL-64874, so no sense
to keep it eating minutes for nothing.
2020-11-23 13:43:15 +01:00
Adrian Greeve 1d0bd0cfdf Merge branch 'MDL-67668-39-2' of git://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-11-23 15:36:55 +08:00
Jake Dallimore b4f40ae78e Merge branch 'MDL-70160-function-cache-39' of https://github.com/Peterburnett/moodle into MOODLE_39_STABLE 2020-11-23 15:23:10 +08:00
Andrew Nicols 556611a864 MDL-70151 assign: Fix bulk change for behat
Behat does not play well with confirmation dialogues and in some
situations it does not wait for the page to reload before starting the
next step.

This change adds a pending_js call which is only resolved if the cancel
button was pressed, otherwise it remains in-progress until the page
reloads resetting the entire state of it.
2020-11-23 11:12:15 +08:00
Andrew Nicols 7ce8e4cde2 MDL-70167 behat: Rewrite attribute check steps
This commit updates the following steps to use the
`the_attribute_of_should_be_set` step under the hood:
- the [element] [type] should be disabled
- the [element] [type] should be enabled
- the [element] [type] should be readonly
- the [element] [type] should not be readonly

This reduces unnecssary code duplication.
2020-11-23 11:03:43 +08:00
Andrew Nicols bde7f5d734 MDL-70167 behat: Boolean attributes should either exist or not 2020-11-23 11:03:42 +08:00
Andrew Nicols e08f640061 MDL-67668 behat: Update tests for inplace editable field type 2020-11-23 09:00:46 +08:00
Andrew Nicols 4f01d454a7 MDL-67668 behat: Add inplace editable field type
This commit promotes the Inplace Editable field to a first-class form
element by introducing a new partial selector for inplace editable
fields, and teaching the field manager how to recognise these, then
introducing a new field type which can handle setting values for this
field.
2020-11-23 09:00:46 +08:00
Andrew Nicols 35cc7cad05 MDL-67668 behat: Share behat_behat functionality with forms
Behat form fields are implemented in a way completely isolated from the
rest of the Behat Context system. Whereas regular step definitions have
access to execute steps, to call `find`, check for JS running, and other
related functionality, the Moodle implementation of a field type does
not have any access to this.

By moving the core functionality of behat_base to a new trait, and the
constants to a new interface, the functionality can also be used in
behat form fields in the same way as elsewhere.
2020-11-23 09:00:46 +08:00
Andrew Nicols 7b5fa603dd MDL-67668 behat: Correct js pending check
Pending checks should only run when JS is running, but some uses were
not apply this check.
2020-11-23 09:00:46 +08:00
Andrew Nicols 4e72b72720 MDL-67668 behat: Support NodeElement when fetching node in container
This is similar to change made in MDL-69136 to allow an already-fetched
NodeElement to be provided to the get_node_in_container() function and
makes it easier to be deterministic when writing steps.
2020-11-23 09:00:46 +08:00
Eloy Lafuente (stronk7) eaf24d71f2 MDL-70265 travis: Only run highest phpunit if configured via env
By default only lowest php version will be executed, and only pgsql.

This default behavior can be changed with a new variable:

MOODLE_PHP = [all]
MOODLE_DATABASE = [pgsql | mysqli | all]
2020-11-21 11:28:27 +01:00
Charles Fulton ed46bff4ae MDL-70157 dml: add support for aurora mysql 2020-11-20 15:21:22 -08:00
Eloy Lafuente (stronk7) 87bcff8c6e weekly release 3.9.3+ 2020-11-20 23:17:02 +01:00
Huong Nguyen 81c2fe97a3 MDL-70248 qtype_ddimageortext: Drop zones have UI issue in Editing form 2020-11-19 17:16:23 +07:00
Adrian Greeve 8b53812c8f Merge branch 'MOODLE_39_STABLE-MDL-67636' of https://github.com/yao9394/moodle into MOODLE_39_STABLE 2020-11-19 11:56:28 +08:00
John Yao 78aeaf17e7 MDL-67636 gradebook: Prevent exposing hidden grade in locked category 2020-11-19 14:34:43 +11:00
Adrian Greeve 662d20869a Merge branch 'MDL-56653-39' of git://github.com/lameze/moodle into MOODLE_39_STABLE 2020-11-19 11:02:18 +08:00
Jun Pataleta f66c4fa42d Merge branch 'MDL-70094-39' of https://github.com/SangNguyen2601/moodle into MOODLE_39_STABLE 2020-11-19 09:35:43 +08:00
Eloy Lafuente (stronk7) 76a830b058 Merge branch 'MDL-69201-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-11-18 23:00:30 +01:00
sangnguyen 2f9582d754 MDL-70094 Question: Technical info section expands if click help icon 2020-11-18 17:30:49 +07:00
Vitaly 12d4c82f98 MDL-56653 enrol_meta: a single DB query in edit_instance_validation
The 'edit_instance_validation()' method checks for existing meta enrolment instances.
The fix replaces DB queries in a loop for each course with a single query for all courses.
Also, a new testing method 'test_edit_instance_validation_with_existing_courses()'
was added to /enrol/meta/tests/plugin_test.php to test if the new implementation
returns an error in case of trying to save the already linked courses in the 'customint1' field.
2020-11-18 15:05:31 +08:00
Andrew Nicols 3648ffdc8e Merge branch '39_MDL-68896' of git://github.com/danmarsden/moodle into MOODLE_39_STABLE 2020-11-18 10:06:41 +08:00
Eloy Lafuente (stronk7) 1194dde152 Merge branch 'MDL-70148-39' of git://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-11-17 23:13:27 +01:00
Paul Holden f727dad657 MDL-67514 customfield: correct external usescategories return type. 2020-11-17 22:13:19 +00:00
Marina Glancy 985d5a5824 MDL-70242 auth_oauth2: set page context and url 2020-11-17 16:48:06 +01:00
Andrew Nicols 0210ab0005 MDL-70148 gradereport_grader: Improve reliability of keyboard usage
In some browsers the ajax grade select does not properly update the
grade after setting values. The previous solution was to press the
[enter] key, but doing this with the new key type step opens the select
box again. This is what happens when a real user presses enter on the
select.

This is the last possible field in the report, so pressing the tab key
to move to the next gradable element does not work.

The solution uses a shift-tab to move the focus away to the previous
gradale element. In this case it must also be moved to an earlier step
because the previously selected value must be checked in the Then
section of the test and if it is selected then its value cannot be
checked.
2020-11-17 15:14:43 +08:00
Andrew Nicols 99cf35e681 MDL-70148 qtype: Update qtype steps to new key interaction
Note: The ddmarker question type was previously getting the number of
keypresses wrong. This was because it was using both keyDown/keyUp, and
also keyPress. As a result each keypress was essentially happening two
times.
2020-11-17 15:14:43 +08:00
Andrew Nicols 61d0134488 MDL-70148 behat: Update steps for keyboard 2020-11-17 15:14:43 +08:00
Andrew Nicols 2369ad7737 MDL-70148 behat: Add steps to send keys without an element 2020-11-17 15:14:43 +08:00
Andrew Nicols 71dcd85182 Merge branch 'MDL-69526-39' of git://github.com/lucaboesch/moodle into MOODLE_39_STABLE 2020-11-17 14:55:32 +08:00
Adrian Greeve f5d19447e0 Merge branch 'MDL-50955-39' of git://github.com/peterRd/moodle into MOODLE_39_STABLE 2020-11-17 13:10:08 +08:00
Andrew Nicols b276f33850 Merge branch 'MDL-69964-39' of git://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-11-17 10:23:01 +08:00
Paul Holden b932b798f1 MDL-69964 course: toggle participant checkboxes in root element.
For a given toggleGroup, the relevant action elements are not
necessarily descendants of the same tableRoot element, on the
course participants page.
2020-11-16 17:44:26 +00:00
Andrew Nicols 14cecfa4c0 MDL-67513 core: Only move modal to body if currently attached
A previous change as part of this commitset was intended to move the
modal to the document.body, but where the modal had been destroyed it
was instead added back to the body.
2020-11-16 09:40:43 +01:00
Peter Dias 9582b85c16 MDL-50955 core: Reset lessons completion criteria if grade type is none 2020-11-16 16:37:28 +08:00
Andrew Nicols f920fdced0 Merge branch 'MDL-67513-m39' of https://github.com/NeillM/moodle into MOODLE_39_STABLE 2020-11-16 08:39:21 +08:00
Luca Bösch 53836d2035 MDL-69526 block_myoverview: custom course fields natural sorting 2020-11-13 00:56:26 +01:00
Eloy Lafuente (stronk7) ff2b655928 weekly release 3.9.3+ 2020-11-12 22:11:37 +01:00
Eloy Lafuente (stronk7) 706f6c93ae Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-11-12 22:11:34 +01:00
Neill Magill 6028dc3924 MDL-67513 forum: View conversations while fullscreen grading
Before this change when a modal was shown and an element on the page
was fullscreen the modal would be created behind it.

This change ensures that the modal will be inside an element that is
fullscreen so that it will be correctly displayed.
2020-11-12 08:34:59 +00:00
Adrian Greeve fd34a36514 Merge branch 'MDL-69453-39' of git://github.com/bmbrands/moodle into MOODLE_39_STABLE 2020-11-12 12:00:36 +08:00
Andrew Nicols 27da8851f6 Merge branch 'MDL-70067-39_theme_classic' of https://github.com/alexmorrisnz/moodle into MOODLE_39_STABLE 2020-11-12 10:30:45 +08:00
Adrian Greeve 248ab7a4b3 Merge branch 'MOODLE_39_MDL-70117' of https://github.com/golenkovm/moodle into MOODLE_39_STABLE 2020-11-12 09:25:39 +08:00
Eloy Lafuente (stronk7) fcf07d64c8 Merge branch 'MDL-65941-39' of https://github.com/snake/moodle into MOODLE_39_STABLE 2020-11-12 00:18:51 +01:00
Eloy Lafuente (stronk7) 897cfd7c81 Merge branch 'MDL-70023-39' of git://github.com/marinaglancy/moodle into MOODLE_39_STABLE 2020-11-11 23:57:35 +01:00
Alex Morris 193aa32b88 MDL-70067 report_insights: Replace BS3 column naming
Bootstrap 4 removed col-xs- and replaced it with col-
2020-11-12 08:57:29 +13:00
Sara Arjona 78908d7757 Merge branch 'MDL-70063-39-1' of git://github.com/mihailges/moodle into MOODLE_39_STABLE 2020-11-11 16:30:34 +01:00
Jun Pataleta 896c962160 Merge branch 'MDL-68257-M39' of https://github.com/ised-isde-canada/moodle into MOODLE_39_STABLE 2020-11-11 22:12:53 +08:00
Jun Pataleta 1178406516 Merge branch 'MDL-70072-39' of git://github.com/rezaies/moodle into MOODLE_39_STABLE 2020-11-11 22:09:21 +08:00
Mihail Geshoski 409f92b75d MDL-70063 block_tag_youtube: Add behat tests 2020-11-11 21:49:38 +08:00
Mihail Geshoski 6ea0b003d7 MDL-70063 block_tag_youtube: Fix category config in existing instances
Upgrade step that fixes the category configuration of existing
tag_youtube block instances.
2020-11-11 21:49:38 +08:00
Mihail Geshoski 918b60d700 MDL-70063 block_tag_youtube: Update category config to use category ID
In YouTube Data API v3, the API call to fetch the videos related to a
certain category expects the category ID to be passed to the
videoCategoryId parameter, instead of the category name. Therefore, the
category config should store the category ID.
2020-11-11 21:49:37 +08:00
Bas Brands b997786180 MDL-69453 core_form: improve form UI icons and alignment 2020-11-11 14:05:00 +01:00
Sara Arjona 3e8447fe9a Merge branch 'MDL-70141-m39' of https://github.com/sammarshallou/moodle into MOODLE_39_STABLE 2020-11-11 08:39:37 +01:00
Michael Aherne 28a1f0943d MDL-65941 cache: Prevent cache config failure on redis problems. 2020-11-11 14:50:43 +08:00
Andrew Nicols 7a2d0fb5dc Merge branch 'MDL-70126-39' of git://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-11-11 10:26:14 +08:00
Andrew Nicols 28de3d7db9 Merge branch 'MDL-70065_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2020-11-11 10:10:45 +08:00
AMOS bot 9fa04e3f2e Automatically generated installer lang files 2020-11-11 00:07:45 +00:00
Mikhail Golenkov 1d41237ae8 MDL-70117 dataformat_pdf: Fix content overflow when headers are involved 2020-11-11 10:53:20 +11:00
Sara Arjona b0a9faf1c6 Merge branch 'MDL-70106-icon-cache-39' of https://github.com/Peterburnett/moodle into MOODLE_39_STABLE 2020-11-10 16:53:46 +01:00
Peter Burnett e9961085eb MDL-70160 cache: plugin_functions checks for function_exists() 2020-11-10 16:04:49 +10:00
Jun Pataleta 766376261a Merge branch 'MDL-69930-39' of https://github.com/HuongNV13/moodle into MOODLE_39_STABLE
# Conflicts:
#	question/type/ddimageortext/amd/build/question.min.js
#	question/type/ddimageortext/amd/build/question.min.js.map
#	question/type/ddimageortext/amd/src/question.js
2020-11-10 14:03:19 +08:00
Jun Pataleta 8e2e459daa Merge branch 'MDL-68349-39' of git://github.com/marinaglancy/moodle into MOODLE_39_STABLE 2020-11-10 10:14:28 +08:00
Jake Dallimore fedd703ce1 Merge branch 'MDL-69841-39' of https://github.com/HuongNV13/moodle into MOODLE_39_STABLE 2020-11-10 09:33:47 +08:00
Víctor Déniz a1216eb05b Merge branch 'MDL-69955-39' of https://github.com/HuongNV13/moodle into MOODLE_39_STABLE 2020-11-09 21:47:45 +00:00
Paul Holden e49e58a924 MDL-69201 core: consistent table primary sort column/order. 2020-11-09 19:45:28 +00:00
Paul Holden 97a03ba74d MDL-70126 tag: correct thrown exception class name. 2020-11-09 19:43:31 +00:00
Neill Magill ba43374d96 MDL-67513 forum: Test that discussions can be viewed while grading 2020-11-09 14:26:21 +00:00
AMOS bot 09d078c3b8 Automatically generated installer lang files 2020-11-09 00:07:54 +00:00
Eloy Lafuente (stronk7) a8e089a8c8 Moodle release 3.9.3 2020-11-07 16:48:07 +01:00
AMOS bot 3e8043f3f4 Automatically generated installer lang files 2020-11-07 00:07:48 +00:00
Eloy Lafuente (stronk7) 70f695d068 weekly release 3.9.2+ 2020-11-06 22:55:50 +01:00
Eloy Lafuente (stronk7) e83cad80b1 Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-11-06 22:55:47 +01:00
Víctor Déniz d727c1eafd Merge branch 'MDL-70137-39-2' of git://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-11-06 19:17:44 +00:00
Andrew Nicols 463b232453 MDL-70137 cache: Write config to temp file and move into place 2020-11-06 19:17:43 +00:00
Andrew Nicols 02a8be1f80 MDL-70137 cache: Use sensible default when reading MUC config
When we read the MUC configuration, a file which exists but is empty
will not error, but will cause all configuration to be empty.

We already perform an {{is_array()}} check on the {{$configuration}}
variable, but the default value for {{$configuration}} is an empty
array. In the case where the file exists, but is empty, no errors occur
when the file is loaded, and the initial {{$configuration}} value is
not overwritten, leading to the file being replaced with an empty copy.
2020-11-06 19:17:34 +00:00
Eloy Lafuente (stronk7) 7bc714ac09 Merge branch 'MDL-70139-39' of git://github.com/sarjona/moodle into MOODLE_39_STABLE 2020-11-06 19:24:40 +01:00
sam marshall 3accc543ec MDL-70141 core_block: Web service set $PAGE url to avoid warnings 2020-11-06 17:40:02 +00:00
Sara Arjona 481c57cabe MDL-70139 core_badges: fix invalid request when sending to backpack
Having mixed $data in badge exporters is causing some issues.
As all these exporters are using $data as an object, $data can be
converted to object in the constructor, to avoid errors and get
the expected behaviour always.
2020-11-06 16:21:34 +01:00
Shamim Rezaie c0256a7351 MDL-70072 core: Fix always displaying date in Gregorian 2020-11-06 19:23:22 +11:00
AMOS bot f8287cb170 Automatically generated installer lang files 2020-11-06 00:09:55 +00:00
Eloy Lafuente (stronk7) 621cd70b4c weekly release 3.9.2+ 2020-11-05 12:16:29 +01:00
Marina Glancy 7e2acbfb55 MDL-70023 core_course: improve performance of recently accessed courses 2020-11-05 09:54:54 +01:00
Jun Pataleta c87ccd3111 Merge branch 'MDL-70075-39-2' of git://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-11-05 12:45:24 +08:00
Andrew Nicols 06be826b2e Merge branch 'MDL-70066-39' of git://github.com/lameze/moodle into MOODLE_39_STABLE 2020-11-05 10:09:48 +08:00
Simey Lameze 06a4390060 MDL-70066 badges: change usages of array_key_exists to isset 2020-11-05 10:06:39 +08:00
Andrew Nicols 126cbbff7c MDL-70075 core: Autocomplete selection should always have an active item
Ensure that there is always one active element in the list of selected
autocomplete elements.

Without this we have issues beacuse clicking on the link makes the first
one active if one is not already active, and this turns a click event
into a drag event, which means that it is not deleted.
2020-11-05 09:05:40 +08:00
Sara Arjona f252b08433 Merge branch 'MDL-70114-39' of git://github.com/bmbrands/moodle into MOODLE_39_STABLE 2020-11-04 20:15:21 +01:00
Víctor Déniz fae048b402 Merge branch 'MDL-68749-39-2' of git://github.com/mickhawkins/moodle into MOODLE_39_STABLE 2020-11-04 15:24:23 +00:00
Sara Arjona 0408008fbe Merge branch 'MDL-70119-39' of git://github.com/ferranrecio/moodle into MOODLE_39_STABLE 2020-11-04 15:20:03 +01:00
Bas Brands 0ff5242a3c MDL-70114 mod_data: add border for to textarea 2020-11-04 13:30:19 +00:00
Ferran Recio 2488fe37ca MDL-70119 core_badges: fix tab names 2020-11-04 12:57:24 +01:00
Andrew Nicols 4edad07619 MDL-70075 core: Do not return a value in an event handler
Returning a value of `false` in an event handler has the effect of
calling event.preventDefault() and event.stopPropagation().

This is neither obvious, nor desirable in this situation.
2020-11-04 15:09:57 +08:00
Andrew Nicols 6cdcee7a65 MDL-70075 core: jQuery.attr() does not accept a bool value
The documented values that jQuery.attr() accepts are String, Number, or
null. For some reason, when we pass a Boolean value, the subsequent
click handler does not work in some situations.

Changing this to take a Number, and unsetting it when empty, resolves
this issue.
2020-11-04 15:09:49 +08:00
Andrew Nicols 28fbba8b3c MDL-70075 core: Listen for change in accessibleChange event
The accessibleChange custom interaction event was only listening for
blur and focus, however some OS/browser combinations do not emit these
events until the element is explicitly blurred. This is notably
different on Firefox on some Operating Systems.

Recent changes in MDL-68167 explicitly moved the user participants page
filter module to use the accessibleChange event, which means that the
selections are now only triggered on an explicit blur when using
Firefox. This highlight a bug whereby, when the mouse is used to make a
selection, the event is not triggered until the element is blurred.

This change modifies the accessibleChange event to ignore the `change`
event where it was triggered by the keyboard and where that keybaord
event was not a [return] or [escape] keypress, but to otherwise respect
the native change event.
2020-11-04 15:09:35 +08:00
Andrew Nicols 90fde2b40d MDL-70075 core: Listen for the focus and blur events again
The `blur` event does not bubble, but the `focusout` events are not
available in all supported versions of Firefox.

Rather than switching event, this patch using event capture to
effectively achieve the same result and bubble the event up through the
DOM to the delegated listener.

There should be no functional change with this patch, except to support
Firefox fully.
2020-11-04 15:09:35 +08:00
Peter Burnett d8bfd5b747 MDL-70106 cache: Set icon localstorage cache to use theme localisation 2020-11-04 13:36:14 +10:00
Huong Nguyen 0d9c49d8d6 MDL-69955 qtype_ddimageortext: drop zone disappear in special case 2020-11-04 09:53:23 +07:00
Jake Dallimore 4d9ffaae34 Merge branch 'MOODLE_39_MDL-70093' of https://github.com/golenkovm/moodle into MOODLE_39_STABLE 2020-11-04 09:00:49 +08:00
Mihail Geshoski 21cfc35074 MDL-67837 backup: Add unit tests 2020-11-03 12:27:34 +01:00
Mihail Geshoski 5d0b569ba1 MDL-67837 backup: Verify caps before unenrolling users on course restore 2020-11-03 12:27:34 +01:00
andreasschenkel fd7db38d8b MDL-69844 user: Fix no email in download_participants_table
Only include eMail in download_participants_table 
if selected in showuseridentity 
($identityfieldsselect)
2020-11-03 12:27:34 +01:00
Juan Leyva 2f9f0b0fcc MDL-67015 mod_data: Prevent users adding entries to other groups 2020-11-03 12:27:34 +01:00
Amaia Anabitarte 14aaba1b72 MDL-69046 core_contentbank: Escape quotes when showing name 2020-11-03 12:27:34 +01:00
Ferran Recio 629657363d MDL-69378 tool_uploadcourse: fix enrolment methods uploads 2020-11-03 12:27:34 +01:00
Peter Dias 498c54d1de MDL-56310 restore: Confirm user has permission to change capabilities 2020-11-03 12:27:34 +01:00
Eloy Lafuente (stronk7) a3f72b3972 weekly release 3.9.2+ 2020-11-03 12:21:21 +01:00
Michael Hawkins 098f09b638 MDL-68749 theme: Fix bootstrap toggle switches in RTL layout
Co-authored-by: Bas Brands <bas@moodle.com>
2020-11-03 15:24:48 +08:00
Eloy Lafuente (stronk7) 99732c4c3b Merge branch 'MDL-70081-39' of git://github.com/jleyva/moodle into MOODLE_39_STABLE 2020-11-03 01:26:11 +01:00
Sara Arjona 905d3939f5 Merge branch 'MDL-69973_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2020-11-02 15:45:09 +01:00
Mikhail Golenkov 051cad238b MDL-70093 dataformat_pdf: Fix row height calculation with high cells 2020-11-02 22:27:08 +11:00
Alexander 6a4bf785cc MDL-70067 theme_classic: Use col-12 as col-xs-12 was removed in BS4 2020-11-02 09:07:05 +13:00
Juan Leyva 223f7cc0b4 MDL-70081 airnotifier: Add missing device type in token registration 2020-10-31 13:08:05 +01:00
Eloy Lafuente (stronk7) 287ed73429 MDL-69973 xmldb: Ensure all reports use fresh metadata (not cached) 2020-10-30 19:27:18 +01:00
Eloy Lafuente (stronk7) db1368926a MDL-69973 xmldb: Fix problem with MariaDB >= 10.2.7 metadata defaults
With MariaDB 10.2.7 the driver was incorrectly returning '' (empty
string) as default for all the columns having null (meaning, no
default).

Also, cover the case in unit tests, it seems that we were already
testing other defaults but not the null case.
2020-10-30 19:27:18 +01:00
Marina Glancy ec19837b79 MDL-68349 auth_db: user_created event should be triggered later 2020-10-30 14:18:41 +01:00
Eloy Lafuente (stronk7) 3b0d958065 weekly release 3.9.2+ 2020-10-30 13:49:12 +01:00
Eloy Lafuente (stronk7) 6722a6b105 Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-10-30 13:49:09 +01:00
Jun Pataleta 920b4dd6ab Merge branch 'MDL-68167-39' of git://github.com/rezaies/moodle into MOODLE_39_STABLE 2020-10-30 13:16:48 +08:00
Shamim Rezaie 898bdfdd67 MDL-68167 lib: autocomplete focos should not be removed on blur
See https://www.w3.org/TR/wai-aria-practices-1.1/examples/listbox/listbox-rearrangeable.html
2020-10-30 16:11:16 +11:00
Shamim Rezaie ed7485277e MDL-68167 lib: Do not set aria-expanded if it should not be set 2020-10-30 16:11:16 +11:00
Shamim Rezaie eb238722da MDL-68167 user: Fix missing label for participants filter input fields 2020-10-30 16:11:16 +11:00
Shamim Rezaie da1f204a0a MDL-68167 lib: Clear single-select autocomplete elements with keyboard
Following MDL-57680, it should be possible to clear the selected option
using keyboard as well.
2020-10-30 16:11:16 +11:00
Shamim Rezaie 5dd385d522 MDL-68167 user: Fix a hardcoded string to be read from lang pack 2020-10-30 16:11:16 +11:00
Shamim Rezaie dca6513b8a MDL-68167 lib: Fix label for autocomplete selection/suggestion box
The content of the autocomplete selection div is purged by javascript
so we have to move its label outside of it. aria-labeledby is the way
to go.

Each time the suggestion box is expanded, autocomplete js renders the
autocomplete suggestions template. So the label cannot be outside the
suggestions ul.
2020-10-30 16:11:08 +11:00
Shamim Rezaie 6484e89188 MDL-68167 user: filter elements should listen to accessibleChange event 2020-10-30 14:58:54 +11:00
Shamim Rezaie 9312e7389a MDL-68167 lib: The accessibleChange custom event now supports bubbling
The change event bubbles so the accessibleChange shoud bubble as well.
2020-10-30 14:58:54 +11:00
Shamim Rezaie 0218859c3e MDL-68167 theme_boost: make focus outline accessible for autocompletes 2020-10-30 14:58:53 +11:00
Shamim Rezaie 18702b5869 MDL-68167 lib: Autocomplete selection to use listbox aria role
The aria-selected state cannot be used for the listitem role. The
autocomplete widget highly uses the aria-selected state internally.
2020-10-30 14:56:39 +11:00
Shamim Rezaie d0ab1d1540 MDL-68167 user: Improve keyboard navigation on autocomplete fields 2020-10-30 14:56:39 +11:00
Shamim Rezaie 7d25143979 Merge branch 'MDL-69390-39' of git://github.com/bmbrands/moodle into MDL-69390-39-test 2020-10-30 14:56:03 +11:00
Andrew Nicols a067cc5ada Merge branch 'MDL-69156_39' of https://github.com/ffhs/moodle into MOODLE_39_STABLE 2020-10-30 11:52:35 +08:00
Huong Nguyen ea68407895 MDL-69841 Quiz: Review options 'Help' icons do not work correctly 2020-10-30 10:28:59 +07:00
AMOS bot 03f5e32712 Automatically generated installer lang files 2020-10-30 00:09:48 +00:00
Víctor Déniz c0b0649582 Merge branch 'MDL-70032-39-2' of git://github.com/junpataleta/moodle into MOODLE_39_STABLE 2020-10-29 22:24:21 +00:00
Tim Hunt 72cd24d3c9 MDL-70065 quiz: fix paging when adding questions from the bank 2020-10-29 20:29:58 +00:00
Paul Holden d16aa74359 MDL-69156 backup: correct behaviour of course copy idnumber field.
When a given user doesn't have the capability to change the idnumber
field during course copy, freeze the field value.
2020-10-29 14:10:09 +01:00
Adrian Perez 7e52e95d8d MDL-69156 course_copy: set defaults for idnumber when not permitted 2020-10-29 13:52:48 +01:00
Jun Pataleta 42f3862b91 MDL-70032 qtype_multichoice: Use custom partial named selector
* With the removal of the label element, Behat now has to click on the
answer text. In order to achieve this, the custom partial named selector
"qtype_multichoice > Answer" was now added and have replaced the
instances where the label of the answer's checkbox/radio button is
being clicked.
2020-10-29 16:22:08 +08:00
Jun Pataleta 556648db0b MDL-70032 qtype_multichoice: Fix answer labelling
* Discard the use of the label element in order to be able to render
multiple choice answers as they are and have these act as the radio
button/checkbox' label through the aria-labelledby attribute.
* New JS module qtype_multichoice/answers that listens for click events
on the answer text container and selects the appropriate answer radio
button/checkbox.
2020-10-29 16:22:08 +08:00
Andrew Nicols 6026aa7b3c Merge branch 'MDL-68722-39' of https://github.com/matt-catalyst/moodle into MOODLE_39_STABLE 2020-10-29 14:03:29 +08:00
Jake Dallimore 8e5782b848 Merge branch 'MDL-69716-39' of git://github.com/aanabit/moodle into MOODLE_39_STABLE 2020-10-29 12:40:23 +08:00
Jake Dallimore f38e17f16f Merge branch 'MDL-70041-39' of git://github.com/mihailges/moodle into MOODLE_39_STABLE 2020-10-29 11:49:40 +08:00
Adrian Greeve 465cc9e91a Merge branch 'm39_MDL-70042_Progress_Bar_Upgrade_Message_Popup' of https://github.com/scara/moodle into MOODLE_39_STABLE 2020-10-29 08:32:16 +08:00
Matteo Scaramuccia faa76ee29a MDL-70042 message_popup: Trivial savepoint comment cleanup 2020-10-28 23:03:34 +01:00
Matteo Scaramuccia d6491a67c8 MDL-70042 message_popup: progress bar on upgrade only when necessary 2020-10-28 23:03:26 +01:00
Jun Pataleta 27db5c5024 Merge branch 'MDL-69390-39' of git://github.com/bmbrands/moodle into MOODLE_39_STABLE 2020-10-28 22:44:02 +08:00
Bas Brands e6b274a542 MDL-69390 theme_boost: dropdown menu accessibility
- display a dot before the active element
- use the active colour for the hover colour
2020-10-28 14:10:45 +01:00
Jun Pataleta 6f317a983e Merge branch 'MDL-69815-39' of git://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-10-28 14:19:09 +08:00
Andrew Nicols a5293c4ed8 Merge branch 'MDL-70004-39' of git://github.com/junpataleta/moodle into MOODLE_39_STABLE 2020-10-28 13:14:23 +08:00
Jake Dallimore 66e77f8173 Merge branch 'MDL-64723-39' of git://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-10-28 12:12:52 +08:00
Mihail Geshoski 4ba58ac02f MDL-70041 filepicker: Make sure the user has a recently used license 2020-10-28 12:06:43 +08:00
Jake Dallimore 21f5c148fc Merge branch 'MDL-65792-39' of git://github.com/bmbrands/moodle into MOODLE_39_STABLE 2020-10-28 12:00:34 +08:00
Andrew Nicols 2e026689c6 MDL-69815 core: Bump Node to v14.15.0 (LTS/Fermium) 2020-10-28 09:34:31 +08:00
Eloy Lafuente (stronk7) 3a718d620e Merge branch 'MDL-69998-39-enfix' of git://github.com/mudrd8mz/moodle into MOODLE_39_STABLE 2020-10-28 00:42:25 +01:00
Eloy Lafuente (stronk7) beff06190a weekly release 3.9.2+ 2020-10-27 23:47:40 +01:00
David Mudrák 975081c367 MDL-69998 lang: Fix reworded strings in Behat test scenarios 2020-10-27 11:29:12 +01:00
Helen Foster 9417cedd78 MDL-69998 lang: Import fixed English strings (en_fix) 2020-10-27 11:29:12 +01:00
Bas Brands 19343c7bd1 MDL-65792 mod_forum: show release time on timed posts 2020-10-27 08:41:38 +01:00
Jun Pataleta 64dd473559 MDL-70004 qtype_multichoice: Set appropriate clear my choice role 2020-10-27 09:57:48 +08:00
Paul Holden 9e4a19af6c MDL-64723 tool_mobile: workaround for invalid certificate parsing.
This is to account for specific server configuration that are affected
by one of the following issues, which results in certificate signature
algorithms being incorrectly parsed:

 * https://bugs.php.net/bug.php?id=77548
 * https://github.com/curl/curl/issues/3706
2020-10-26 23:06:14 +00:00
Matt Clarkson eeba9c1dc5 MDL-68722 atto_equation: fix for form elements with special characters
Element id's containing characters such as ':' would break the tab
selector in bootstrap.

This specifically affects the essay question type.
2020-10-27 11:08:47 +13:00
Eloy Lafuente (stronk7) 55a465c445 Merge branch 'MDL-69993-39' of git://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-10-26 10:43:02 +01:00
Andrew Nicols d1d52a3399 Merge branch 'MDL-69995-39' of git://github.com/lucaboesch/moodle into MOODLE_39_STABLE 2020-10-26 16:01:07 +08:00
Huong Nguyen ad7b38f3ff MDL-69930 qtype_ddimageortext: Duplication items in drag-onto-image question 2020-10-25 20:15:27 +07:00
Luca Bösch a22b74872c MDL-69995 backup: padding before activity icons. 2020-10-25 02:04:52 +02:00
Amaia Anabitarte 1af998d32c MDL-69716 mod_quiz: No timestamp for in progress attempts 2020-10-23 16:03:03 +02:00
Eloy Lafuente (stronk7) 4d9ab4ca48 weekly release 3.9.2+ 2020-10-23 14:40:50 +02:00
Eloy Lafuente (stronk7) 55189f02ee Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-10-23 14:40:45 +02:00
Paul Holden 115f703440 MDL-69993 output: correct navigation node type for user reports. 2020-10-23 08:25:47 +01:00
Adrian Greeve 5cd7b5cad0 Merge branch 'MDL-67650-forced-checkbox-textarea-MOODLE_39_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_39_STABLE 2020-10-23 09:01:07 +08:00
Eloy Lafuente (stronk7) fb81664dc3 Merge branch 'MDL-69729-39' of git://github.com/sarjona/moodle into MOODLE_39_STABLE 2020-10-22 19:05:22 +02:00
Víctor Déniz 8cbc470f2a Merge branch 'MDL-68664-39' of git://github.com/lameze/moodle into MOODLE_39_STABLE 2020-10-22 12:25:43 +01:00
Sara Arjona 1bc92d37f2 Merge branch 'MDL-69553-m39' of https://github.com/NeillM/moodle into MOODLE_39_STABLE 2020-10-22 08:56:19 +02:00
Brendan Heywood 348e338a21 MDL-67650 admin: Consistently show forced config settings 2020-10-22 13:17:17 +11:00
Jake Dallimore bf854f5f24 Merge branch 'MDL-68438_39' of https://github.com/t-schroeder/moodle into MOODLE_39_STABLE 2020-10-22 09:31:02 +08:00
Jun Pataleta b861165753 Merge branch 'MDL-69657-39' of git://github.com/merrill-oakland/moodle into MOODLE_39_STABLE 2020-10-22 09:24:08 +08:00
Adrian Greeve 3c2208cc24 Merge branch 'MDL-69788-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-10-22 09:06:53 +08:00
AMOS bot 2d1fcf6cce Automatically generated installer lang files 2020-10-22 00:08:01 +00:00
Eloy Lafuente (stronk7) 2f502066cb Merge branch 'MDL-66392-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-10-21 19:48:20 +02:00
Sara Arjona 41cd0c4d3a Merge branch 'm39_MDL-68536_Notice_Undefined_Property_CFG_branch' of https://github.com/scara/moodle into MOODLE_39_STABLE 2020-10-21 18:33:15 +02:00
Paul Holden 0efc7095e3 MDL-66392 analytics: make model output directory default to empty.
Falling back to path within $CFG->dataroot/models.
2020-10-21 17:32:29 +01:00
Víctor Déniz 6178388d94 Merge branch 'MDL-69392-39' of git://github.com/junpataleta/moodle into MOODLE_39_STABLE 2020-10-21 16:26:35 +01:00
Tim Schroeder f0e9fa2a7b MDL-68438 message: fixed email format change with messaging disabled 2020-10-21 12:47:53 +02:00
Paul Holden c651779095 MDL-69788 admin: validate language menu configuration. 2020-10-21 11:24:18 +01:00
Jun Pataleta ce5efbc1da Merge branch 'MDL-37226-39' of git://github.com/lucaboesch/moodle into MOODLE_39_STABLE 2020-10-21 17:46:38 +08:00
Neill Magill e9506c638b MDL-69553 output: Handle pre-loading multiline string defines
Before this patch strings that were declared over multiple lines in
a template would not be parsed correctly.

{{#str}}value,
mod_forum{{/str}}

would have been been parsed to get_string('value', 'core')

{{#str}}
value, mod_forum
{{/str}}

would have been been parsed to get_string('', 'core')
2020-10-21 10:08:23 +01:00
Neill Magill bb3f9ee492 MDL-69553 output: Unit tests for loading multiline string defines 2020-10-21 10:08:22 +01:00
Jun Pataleta 14017f40b9 Merge branch 'MDL-69945-39' of git://github.com/lucaboesch/moodle into MOODLE_39_STABLE 2020-10-21 16:03:04 +08:00
Jun Pataleta 413736095b MDL-69392 question: Fix Try again button styling 2020-10-21 14:57:58 +08:00
Jun Pataleta f78101f638 MDL-69392 theme_boost: Improve question colour contrast
* Lighten info container.
* Fix colour contrast for the question container by
  - Lightening the background a bit
  - Darkening the text colour a bit
  - Making sure the link colour has good colour contrast against the
  question text.
* Fix colour contrast for the comments container by
  - Lightening the text colour a bit
  - Darkening the link colour a bit for better colour contrast against
  the feedback text.
2020-10-21 14:57:57 +08:00
Jun Pataleta 105e40d377 MDL-69392 theme_classic: Darken red, blue and green colours
The current red, blue, and green colours achieve the minimum colour
contrast against a white background. However, when they're against
coloured background, text with these colours will easily fail the
4.5:1 contrast ratio requirement for Level AA.
The updated colours now have the following contrast ratio against a
white background:
* Blue  - #0f6fc5 (5.12:1, from 4.58:1)
* Green - #357a32 (5.27:1, from 4.63:1)
* Red   - #ca3120 (5.29:1, from 4.59:1)
2020-10-21 14:57:57 +08:00
Jun Pataleta ce2f6179cd MDL-69392 theme_boost: Darken red, blue and green colours
The current red, blue, and green colours achieve the minimum colour
contrast against a white background. However, when they're against
coloured background, text with these colours will easily fail the
4.5:1 contrast ratio requirement for Level AA.
The updated colours now have the following contrast ratio against a
white background:
* Blue  - #0f6fc5 (5.12:1, from 4.58:1)
* Green - #357a32 (5.27:1, from 4.63:1)
* Red   - #ca3120 (5.29:1, from 4.59:1)
2020-10-21 14:57:57 +08:00
Adrian Greeve 47ff67ec29 \Merge branch 'MDL-69807-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-10-21 14:22:19 +08:00
Adrian Greeve 3fb1660734 Merge branch 'MDL-68766-M39' of https://github.com/ised-isde-canada/moodle into MOODLE_39_STABLE 2020-10-21 12:49:18 +08:00
Jake Dallimore 6e7c392d84 Merge branch 'MDL-68983-recent-session-lock-ro-MOODLE_39_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_39_STABLE 2020-10-21 12:46:11 +08:00
Jake Dallimore 806e6bec59 Merge branch 'MDL-69902-39' of https://github.com/marinaglancy/moodle into MOODLE_39_STABLE 2020-10-21 10:57:53 +08:00
Jake Dallimore 8d7fe960a0 Merge branch 'MDL-69751-39' of git://github.com/mihailges/moodle into MOODLE_39_STABLE 2020-10-21 10:04:31 +08:00
Eloy Lafuente (stronk7) 8d1cbe3a35 weekly release 3.9.2+ 2020-10-21 00:50:42 +02:00
Sara Arjona 197ec7e822 MDL-69729 h5p: move temporary editor files to draft area
This is a backport of MDL-68909
2020-10-20 09:59:09 +02:00
Sara Arjona fbab65f86b MDL-69729 h5p: upgrade step to remove files in editor filearea
As temporary editor files have been moved from core_h5p/editor to
user/draft, they can be removed (to clean unused DB entries).

This is a backport of MDL-68909
2020-10-20 09:18:16 +02:00
Adrian Greeve cd054d77f1 MDL-68284 gradebook: Fix use of get_recordset in upgrade code. 2020-10-20 14:15:20 +08:00
Jake Dallimore 6168569323 Merge branch 'MDL-67695-MOODLE_39_STABLE_get_lti_proxies' of https://github.com/andrewmadden/moodle into MOODLE_39_STABLE 2020-10-20 11:09:11 +08:00
Mihail Geshoski 5da2fa002e MDL-69751 core: Restore deleted guest user and add missing context
This upgrade step fixes the cases where the current guest user is
labelled as 'deleted' and the related user context is missing.
2020-10-20 08:43:52 +08:00
Adrian Greeve 4b137eb20c Merge branch 'MOODLE_39_STABLE-MDL-68284' of https://github.com/yao9394/moodle into MOODLE_39_STABLE 2020-10-20 08:41:09 +08:00
Mihail Geshoski 34ffdc2c81 MDL-69751 course: Handle missing guest user context
Makes sure the guest user context exists when fetching
the recommended modules. If the context does not exist
an exception is being thrown describing the problem.
2020-10-20 08:39:24 +08:00
Simey Lameze 83d478ce93 MDL-68664 theme: remove right margin from form-inline class 2020-10-20 08:32:57 +08:00
Andrew Nicols 565bc965b1 Merge branch 'MDL-69687-m39' of https://github.com/sammarshallou/moodle into MOODLE_39_STABLE 2020-10-20 08:02:46 +08:00
Jake Dallimore e2cdcc563d Merge branch 'MDL-69726_39' of git://github.com/aolley/moodle into MOODLE_39_STABLE 2020-10-20 07:46:23 +08:00
Paul Holden ae61985191 MDL-69807 blocks: remove redundant sesskey loading edit/delete page. 2020-10-19 22:40:43 +01:00
Eloy Lafuente (stronk7) 2b169e9b31 Merge branch 'MDL-69906-39-searchsimpledb' of git://github.com/mudrd8mz/moodle into MOODLE_39_STABLE 2020-10-19 22:56:40 +02:00
Eloy Lafuente (stronk7) ccbd35915c Merge branch 'MDL-57756-text-customparams-39' of https://github.com/cengage/moodle into MOODLE_39_STABLE 2020-10-19 22:32:10 +02:00
Sara Arjona 114d1a051e Merge branch 'MDL-69897-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-10-19 18:15:07 +02:00
Sara Arjona 856c31cc32 Merge branch 'MDL-69900-39' of git://github.com/mihailges/moodle into MOODLE_39_STABLE 2020-10-19 13:42:13 +02:00
sam marshall 25049f4f19 MDL-69687 Course: remove_course_contents orphaned completion data
The remove_course_contents function did not delete data from
course_module_completion table in most cases, resulting in large
quantities of orphaned data.
2020-10-19 10:21:12 +01:00
Sara Arjona 00a46671fa Merge branch 'MOODLE_39_MDL-69791' of https://github.com/golenkovm/moodle into MOODLE_39_STABLE 2020-10-19 10:08:08 +02:00
Sara Arjona d008aa7c99 Merge branch 'MDL-69736-39' of git://github.com/ferranrecio/moodle into MOODLE_39_STABLE 2020-10-19 09:04:06 +02:00
Sagar Ghimire 2d462ee8bd MDL-68284 gradebook: Prevent exposing hidden quiz grade item 2020-10-19 16:22:37 +11:00
Andrew Nicols 3f50f83dc1 Merge branch 'MDL-69687-m39' of https://github.com/sammarshallou/moodle into MOODLE_39_STABLE 2020-10-19 13:20:25 +08:00
Andrew Madden 41121d705f MDL-67695 mod_lti: Use correct return structure for get_tool_proxies.
* Use tool_proxy_return_structure for each proxy.
* Added tests for getting all proxies and orphaned proxies.
2020-10-19 15:16:44 +11:00
sam marshall cc2faa2c90 MDL-69687 Course: Improve removal of completion data on MySQL 2020-10-16 18:23:41 +01:00
sam marshall ae4f9b31f7 MDL-69687 DB: Add API for deleting data based on subquery
The new API works on normal databases (by deleting data based on the
subquery) and also on MySQL (by deleting the data using a weird join
on the subquery).
2020-10-16 18:23:41 +01:00
Luca Bösch 01f3495a46 MDL-37226 assign: align select all header checkbox 2020-10-16 16:08:48 +02:00
Paul Holden c4c328565d MDL-69788 lang: fallback to all translations if misconfigured.
If given translation list contains only invalid entries, fallback
to returning the complete list of available language translations.
2020-10-16 14:38:07 +01:00
Luca Bösch 7961a36b76 MDL-69945 core_calendar: let circles appear as circles 2020-10-16 14:15:56 +02:00
Sara Arjona eda7eb44b3 weekly release 3.9.2+ 2020-10-16 13:18:43 +02:00
Jake Dallimore 6589c3cdd6 Merge branch 'MOODLE_39_MDL-47178' of https://github.com/golenkovm/moodle into MOODLE_39_STABLE 2020-10-16 11:52:58 +08:00
Jun Pataleta eeb76ddd3f Merge branch 'MDL-69266-39' of https://github.com/HuongNV13/moodle into MOODLE_39_STABLE 2020-10-16 10:09:30 +08:00
Huong Nguyen 14ea69c07c MDL-69266 qtype_ddwtos: 'unlimited' options fail in 3.9 2020-10-15 20:07:02 +07:00
Eloy Lafuente (stronk7) 9f0400b74d Merge branch 'MDL-69813-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-10-14 22:47:23 +02:00
Eloy Lafuente (stronk7) f68a64d50b MDL-68070 messaging: Ensure that error is shown on first messages
Before there is a conversation, messages between users are sent
using core_message_send_instant_messages instead of
core_message_send_messages_to_conversation.

That method had an undefined $errormessage variable, ultimately
causing the problem detected on message_post_message()/message_send()
to never been returned by the external.

This just adds the same error than already existing conversations do,
but returning it as warning, for BC, JS will show it.
2020-10-14 18:57:43 +02:00
Eloy Lafuente (stronk7) d82acd309b MDL-68070 messaging: Amend lang string to be clearer for any user.
Credit goes to Helen Foster for the improvement, thanks!
2020-10-14 16:54:48 +02:00
Víctor Déniz 22f34e807d Merge branch 'MDL-68900-m39' of https://github.com/sumitnegi933/moodle into MOODLE_39_STABLE 2020-10-14 12:22:49 +01:00
Jake Dallimore 31d3a656d6 Merge branch 'MOODLE_39_MDL-69848' of https://github.com/golenkovm/moodle into MOODLE_39_STABLE 2020-10-14 09:43:03 +08:00
Eloy Lafuente (stronk7) 3d41104fab Merge branch 'MDL-68070-39_messaging_fix' of https://github.com/beenet-dev/moodle into MOODLE_39_STABLE 2020-10-13 23:41:03 +02:00
Sara Arjona 523f308a9a weekly release 3.9.2+ 2020-10-13 13:24:20 +02:00
Sara Arjona e4d03a9257 Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-10-13 13:24:17 +02:00
Brendan Heywood cedf141cc3 MDL-68983 cache: Fix bug with readonly session combined with lock debug 2020-10-13 14:53:11 +11:00
Andrew Nicols b4d51d67a9 Merge branch 'MDL-67654-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-10-13 08:01:08 +08:00
Jenkins Automation 9763c99f87 MDL-69726 calendar: fix raw event fetcher under postgres
Without this, there's a code path that under the right circumstances is hit and
results in a query with `FROM (mdl_event) ev` in it - which is not valid syntax
under postgres.
2020-10-13 09:35:03 +10:30
Paul Holden 56be61d4f6 MDL-67654 mod_forum: formchangechecker for discussion inline replies. 2020-10-12 23:32:38 +01:00
Simon Mok 6de6fe9590 MDL-68070 messaging: Fix error when personal notification is disabled 2020-10-12 21:43:48 +08:00
Michael Milette 754440d796 MDL-68766 auth: Login form: 'Log in using...' should be h3, not h6 2020-10-12 09:32:25 -04:00
Michael Milette 1ddaad70ad MDL-68257 book: Fix display of table of contents in IE11. 2020-10-12 09:21:28 -04:00
Adrian Greeve c954e18a99 Merge branch 'MOODLE_39_MDL-69818' of https://github.com/golenkovm/moodle into MOODLE_39_STABLE 2020-10-12 14:47:52 +08:00
Jake Dallimore e0a366fa0a Merge branch 'MDL-68292-admin-sesskey-MOODLE_39_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_39_STABLE 2020-10-12 14:37:40 +08:00
Brendan Heywood 2e5daf9108 MDL-68292 core: Remove sesskey leakage on module pages 2020-10-12 17:11:48 +11:00
Adrian Greeve 5281e10e77 Merge branch 'MDL-69649-39' of git://github.com/rezaies/moodle into MOODLE_39_STABLE 2020-10-12 10:16:15 +08:00
Jake Dallimore aae7a2b206 Merge branch 'MDL-69910-calendar-protectusername-MOODLE_39_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_39_STABLE 2020-10-12 10:06:06 +08:00
AMOS bot 419ff44b78 Automatically generated installer lang files 2020-10-11 00:08:29 +00:00
Brendan Heywood c4a8787574 MDL-69910 calendar: Fix export exception when both params are sent 2020-10-11 09:20:21 +11:00
David Mudrák 834a1d64c5 MDL-69906 admin: Display Setup search engine as link only if it is valid
We use auto-generated admin section name here so we need to check that
the target section actually exists.
2020-10-09 14:04:55 +02:00
Sara Arjona 496e6ac804 weekly release 3.9.2+ 2020-10-09 11:11:56 +02:00
Sara Arjona 7eb0f97113 Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-10-09 11:11:53 +02:00
Marina Glancy 9f1df0f2e4 MDL-69902 core_search: fix error in the custom fields indexing 2020-10-09 08:47:28 +02:00
Adrian Greeve 8fc60dd25d Merge branch 'MDL-68384-fix-spec-violations-39' of https://github.com/cengage/moodle into MOODLE_39_STABLE 2020-10-09 12:04:22 +08:00
Jun Pataleta 558a30dc7d Merge branch 'MDL-69257-39' of git://github.com/mihailges/moodle into MOODLE_39_STABLE 2020-10-09 11:12:08 +08:00
Mihail Geshoski 9773b4b079 MDL-69257 core_h5p: Move $maxsize outside the foreach loop
There is no reason to repeatedly obtain the maximum size for uploading
files as a part of foreach loop.
2020-10-09 10:36:11 +08:00
Martin Gauk d686ee8faa MDL-69257 H5P: Check size of uploaded files and virus scan 2020-10-09 10:36:11 +08:00
Stephen Bourget 5cb1cf7695 MDL-69900 core_backup: Allow IMSCC v1.0 restore to finish 2020-10-09 09:06:37 +08:00
Paul Holden 465f3b477b MDL-69897 repository: add heading to delete file modal. 2020-10-08 20:29:51 +01:00
Amaia Anabitarte ad00d91851 MDL-69712 core_h5p: Remove 'whitelist' key uses 2020-10-08 16:27:57 +02:00
Sara Arjona 1eed96dec7 Merge branch 'MDL-64657-39' of git://github.com/jleyva/moodle into MOODLE_39_STABLE 2020-10-08 14:15:50 +02:00
Sumit Negi 2e21c78006 MDL-68900 mod_forum: permission check for user who is viewing timed post
Pass current user object to post builder as argument, so that the permission to view timed post
will check with current user, who is viewing the posts instead of user who made that post.
2020-10-08 12:45:33 +05:30
Adrian Greeve aba9644393 Merge branch 'MDL-69805-39' of https://github.com/dravek/moodle into MOODLE_39_STABLE 2020-10-08 14:59:28 +08:00
Adrian Greeve 4aa6b89ead Merge branch 'MDL-69798_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2020-10-08 13:32:23 +08:00
Víctor Déniz f8bce36ef2 Merge branch 'MDL-69759-m39' of https://github.com/sammarshallou/moodle into MOODLE_39_STABLE 2020-10-07 22:26:06 +01:00
Victor Deniz Falcon fce2b0008c MDL-52407 travis: use Travis default notifications(email) 2020-10-07 16:32:58 +08:00
Andrew Nicols c2bd0a7d31 Merge branch 'MDL-67275-39-post_noun_verb' of git://github.com/mudrd8mz/moodle into MOODLE_39_STABLE 2020-10-07 12:38:55 +08:00
AMOS bot 2d7a59d060 Automatically generated installer lang files 2020-10-07 00:07:45 +00:00
Eloy Lafuente (stronk7) 57e0a20dec Merge branch 'wip-MDL-68808-MOODLE_39_STABLE' of https://github.com/jason-platts/moodle into MOODLE_39_STABLE 2020-10-06 23:12:19 +02:00
Ferran Recio 3fe455fab4 MDL-69736 core_h5p: enable player reporting 2020-10-06 13:05:24 +02:00
Paul Holden ca743b6a95 MDL-69813 h5p: fix undefined addon ordering in framework test. 2020-10-06 10:48:10 +01:00
Eloy Lafuente (stronk7) 5ea37637b7 weekly release 3.9.2+ 2020-10-06 10:20:46 +02:00
Eloy Lafuente (stronk7) 75bae1a55b Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-10-06 10:20:43 +02:00
Mikhail Golenkov f3db3d30e0 MDL-47178 question: Retain question authors when restoring backups. 2020-10-06 09:36:42 +11:00
Eloy Lafuente (stronk7) 7714ea42ec Merge branch 'MDL-69772-39-allcountrycodes' of git://github.com/mudrd8mz/moodle into MOODLE_39_STABLE 2020-10-06 00:04:13 +02:00
Eloy Lafuente (stronk7) 12c103b21a Merge branch 'MDL-65074-39' of https://github.com/hitteshahuja/moodle into MOODLE_39_STABLE 2020-10-05 23:12:33 +02:00
Sara Arjona ec157a3052 Merge branch 'MDL-69355-39-filebuffer' of git://github.com/mudrd8mz/moodle into MOODLE_39_STABLE 2020-10-05 18:34:02 +02:00
Jun Pataleta 57bb2fdaac Merge branch 'MDL-69704-39' of git://github.com/sarjona/moodle into MOODLE_39_STABLE 2020-10-05 23:12:50 +08:00
Sara Arjona e437183098 Merge branch 'MDL-69641-MOODLE_39_STABLE' of https://github.com/dmitriim/moodle into MOODLE_39_STABLE 2020-10-05 13:38:06 +02:00
Eloy Lafuente (stronk7) 3af8f89e58 Merge branch 'MOODLE_39-MDL-69752' of https://github.com/golenkovm/moodle into MOODLE_39_STABLE 2020-10-05 10:55:10 +02:00
Mikhail Golenkov 52b1184468 MDL-69791 gradereport: Fix error message when invalid grade is entered 2020-10-05 15:00:20 +11:00
Mikhail Golenkov 99d0308e4b MDL-69848 upgrade: Delete notifications in chunks 2020-10-05 13:14:26 +11:00
Mikhail Golenkov 3ae46b2a93 MDL-69818 mod_feedback: Fix item dependency during activity restoration 2020-10-04 18:29:45 +11:00
Mikhail Golenkov 5fce0b3f5d MDL-69752 mod_data: Format module intro on Database activities page 2020-10-04 13:49:35 +11:00
AMOS bot b3ebbb61f4 Automatically generated installer lang files 2020-10-03 00:08:29 +00:00
Sara Arjona 16689245e8 weekly release 3.9.2+ 2020-10-02 13:43:27 +02:00
Eloy Lafuente (stronk7) 98280a4c8c Merge branch 'MDL-69758-m39' of https://github.com/sammarshallou/moodle into MOODLE_39_STABLE 2020-10-01 23:44:26 +02:00
Claude Vervoort 171e55f304 MDL-57756 mod_lti: params change to text type 2020-10-01 17:34:39 -04:00
Sara Arjona f1fed72bda MDL-69704 course: catch exception when calling get_course_content_items
When plugins are removed from disk, an exception is thrown when
calling component_callback_exists.
This exception should be catched here in order to load properly
the activity chooser (otherwise, the exception will be displayed
and no activity will appear).
2020-10-01 19:56:41 +02:00
Tim Hunt 07674eb12f MDL-69798 XML question export: excape special chars in idnumbers 2020-10-01 17:10:58 +01:00
Amaia Anabitarte 2308a02324 MDL-69672 core_contentbank: is_context_allowed unit tests 2020-10-01 17:56:38 +02:00
Eloy Lafuente (stronk7) 1da6703d6d Merge branch 'MDL-69672-39' of git://github.com/aanabit/moodle into MOODLE_39_STABLE 2020-10-01 17:49:23 +02:00
Eloy Lafuente (stronk7) 27a62292ad Merge branch 'MDL-69586-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-10-01 17:12:53 +02:00
David Mudrák 271b94ff4f MDL-69772 admin: Better validation for the allcountrycodes setting
The patch introduces a new admin_setting fiela type that can be used for
specifying comma separated list of countries. The field has inbuilt
validation so that only valid country codes can be inserted.
2020-10-01 13:37:51 +02:00
Jason Platts 315ec3bad6 MDL-68808 forms: autocomplete throwing error in IE11 2020-10-01 12:11:11 +01:00
Sara Arjona 4cb342ef34 Merge branch 'MDL-68098-39' of git://github.com/dpalou/moodle into MOODLE_39_STABLE 2020-10-01 12:56:31 +02:00
Dani Palou e7bb7aa9a2 MDL-68098 tests: Reset FILTERLIB_PRIVATE after tests 2020-10-01 12:50:00 +02:00
Dani Palou 7aca3ebb3c MDL-68098 ws: Add unit tests to test mathjax in WS 2020-10-01 12:50:00 +02:00
David Matamoros 61bb2c70c2 MDL-69805 mod_data: Freeze comment field if comments disabled 2020-09-30 15:53:29 +02:00
Matteo Scaramuccia d84da184c5 MDL-68536 core: Fix notice about undefined prop 'branch' in $CFG 2020-09-30 14:47:20 +02:00
Adrian Greeve f612465b53 Merge branch 'MDL-37802-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-09-30 13:50:03 +08:00
Dan Marsden 4727970abd MDL-69641 grade: fix slow query.
This is a backport of MDL-69190
2020-09-30 15:00:35 +10:00
Adrian Greeve 88c700bd2c Merge branch 'MDL-69359_39' of https://github.com/adpe/moodle into MOODLE_39_STABLE 2020-09-30 11:43:16 +08:00
Sara Arjona b354694012 Merge branch 'MDL-69342-39_profile_picture_deletion' of https://github.com/vtos/moodle into MOODLE_39_STABLE 2020-09-29 19:01:19 +02:00
Amaia Anabitarte a9bccc9dbc MDL-69672 core_contentbank: Check used context level 2020-09-29 12:44:48 +02:00
Eloy Lafuente (stronk7) 7c52a27375 weekly release 3.9.2+ 2020-09-29 10:48:33 +02:00
Eloy Lafuente (stronk7) 300d9ca23d Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-09-29 10:48:29 +02:00
Claude Vervoort 00b2219fd4 MDL-68384 mod_lti: fix spec violations bo claim name and dl value type 2020-09-28 17:04:07 -04:00
Víctor Déniz 8b9d73dad8 Merge branch 'MDL-69644-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-09-28 20:34:26 +01:00
Shamim Rezaie 9029eb0e71 MDL-69649 form: Fix labels for defaultcustom form elements 2020-09-28 23:21:50 +10:00
Shamim Rezaie d54b3447e6 MDL-69649 backup: Fix missing labels
- The backup details page uses a table to show a sumary of the backup
  content. Used role attribute to denote the tabular format of the
  summary.
- The backup details page displays activity name next to each activity
  icon. Therefore the icons are only decorative and do not need to have
  any title or even alt text.
- Form labels should be associated with form controls.  A div element is
  not a form control.
- The from attribute of the form labels should be equal to the id
  attribute of an element. Therefore, we first create a label and an
  input elements and associate them to each other, and then pass them to
  backup_detail_pair() when a label is needed.
2020-09-28 23:21:50 +10:00
sam marshall 39d542eeb4 MDL-69759 Web services: app checks to token.php cause log errors 2020-09-28 11:55:56 +01:00
AMOS bot 2cf6b7cc41 Automatically generated installer lang files 2020-09-26 00:07:59 +00:00
adpe 5651e88dc9 MDL-69359 admin_cli: show only contributed plugins in uninstall plugins 2020-09-25 17:03:31 +02:00
Hittesh Ahuja 5a90580646 MDL-65074 mod_quiz: Quiz navigation buttons shouldnt use btn-secondary
Removing .btn-secondary as plain.scss and default.scss in bootstrap hide the button from view.
2020-09-25 15:17:10 +01:00
Paul Holden c98428aab3 MDL-37802 repository: return error if unzipping files fails.
For instance, when a user tried to unzip a password protected zip
archive using the file manager.
2020-09-25 09:34:01 +01:00
Paul Holden dc780e3eb1 MDL-69586 tool_usertours: use specified user in privacy prefs export. 2020-09-25 09:13:39 +01:00
David Mudrák d75844ea12 MDL-69772 admin: Fix legacy coding style on Location settings admin page
No actual change here. Just polishing the coding style and adding
fulltree check.
2020-09-24 18:14:12 +02:00
David Mudrák 11e5003bd6 MDL-69772 lang: Ignore misconfigured allcountrycodes filter
If the allcountrycodes filter contains only invalid values, ignore the
whole filter setting and make get_list_of_countries() return the full
list of all known countries, rather than empty list.
2020-09-24 18:14:12 +02:00
Víctor Déniz a348c5f420 weekly release 3.9.2+ 2020-09-24 16:27:32 +01:00
Víctor Déniz 4b651226d5 Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-09-24 16:27:27 +01:00
Eloy Lafuente (stronk7) e33c554aaa Merge branch 'MDL-69698-39-licensecache' of git://github.com/mudrd8mz/moodle into MOODLE_39_STABLE 2020-09-24 16:50:47 +02:00
Paul Holden 31937c4b0e MDL-69644 tool_dataprivacy: fix focus outline of contact DPO link.
The link class attribute is a leftover from 7258bf0b, which was mostly
removed in 3b2f691f. It no longer serves a purpose and interferes with
the element focus outline.
2020-09-24 11:51:15 +01:00
Vitaly 141216f94c MDL-69342 core_user: fixed user picture updating
When editing a user and checking the 'Delete picture' checkbox to delete
the old picture and uploading a new one at a time, the new one didn't appear
in the user profile. This happened due to the 'if/else' statement
in the 'core_user::update_picture()' method which allowed either to delete
the old picture or to upload a new one.
The fix removes the 'else' part of the 'if/else' statement to force
checking for a new uploaded picture no matter if a user checked
the 'Delete picture' checkbox or not.
2020-09-24 10:55:29 +03:00
Dani Palou fba96f096b MDL-68098 ws: Fix WebServices broken by filters HTML 2020-09-23 16:23:19 +02:00
Eloy Lafuente (stronk7) 7148c9d35e Merge branch 'MDL-68229-39' of git://github.com/jleyva/moodle into MOODLE_39_STABLE 2020-09-23 11:51:30 +02:00
Eloy Lafuente (stronk7) 8193ba9da9 Merge branch 'MDL-69014-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-09-22 23:10:53 +02:00
Juan Leyva 6bf314500a MDL-64657 course: Return hidden section names when configured 2020-09-22 12:25:58 +02:00
AMOS bot ee034c39e5 Automatically generated installer lang files 2020-09-22 00:07:13 +00:00
Eloy Lafuente (stronk7) 46aea33b69 Merge branch 'MDL-66648-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-09-21 23:36:30 +02:00
Eloy Lafuente (stronk7) e0f9ca6787 Merge branch 'MDL-69667-MOODLE_39_STABLE' of https://github.com/comete-upn/moodle into MOODLE_39_STABLE 2020-09-21 23:20:35 +02:00
David Mudrák 976f8f0c52 MDL-67275 forum: Fix language and accessibility issues with buttons
There were inconsistencies with the text shown on the submit button,
depending on the where the button was shown.

* Inline reply forum displayed general "Submit".
* Experimental nested discussion view reply form displayed "Post"
  (post/core string) which acts as a noun in other contexts and cannot
  be used as such in many non-English languages.
* Advanced reply form displayed "Post to forum".

The patch fixes this and starts to show "Post to forum" in all three
places consistently.

While working on this, two more issues were noticed and fixed:

* Inline reply textarea's title was hard-coded English "post" text.
  Changed to "Message" to provide advisory information related to the
  element.
* Buttons contained title attribute with the same value as the explicit
  button text. This goes against accessibility guidelines.
2020-09-21 22:48:20 +02:00
sam marshall 767be5d8c1 MDL-69758 Web services: core_get_course_contents PHP warnings
Calls to core_get_course_contents can cause PHP warnings in the server
log if there are any URL instances in the course with sketchy URLs.
This is because url_export_contents incorrectly returns null instead
of an empty array if there is an error.
2020-09-21 15:28:47 +01:00
Juan Leyva 94140b11e8 MDL-68229 tool_mobile: Add missing option to disable tags in the app 2020-09-18 15:30:55 +02:00
Eloy Lafuente (stronk7) a45e6838ef weekly release 3.9.2+ 2020-09-17 19:04:23 +02:00
Eloy Lafuente (stronk7) ae17678a1c Merge branch 'install_39_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_39_STABLE 2020-09-17 19:04:20 +02:00
Eloy Lafuente (stronk7) 3ae39301b9 Merge branch 'MDL-69395_39' of github.com:stronk7/moodle into MOODLE_39_STABLE 2020-09-17 17:03:10 +02:00
Eloy Lafuente (stronk7) 422fcb70ca MDL-69395 theme_classic: remove superfluous selector already in boost 2020-09-17 13:06:06 +02:00
David Mudrák 29a396fe4e MDL-69355 file: Do not attempt to set headers after output started
It was found out that in certain situations there may be some content
in to output handlers buffers. Let's allow that to happen given that:

* default handler's buffer is not sent as a part of the file and an
  error is reported into the server log.
* other handlers' buffer is sent with the assumption that it is required
  for the correct serving of the file.
2020-09-17 11:42:33 +02:00
Eloy Lafuente (stronk7) af777f92a0 Merge branch 'MDL-62387-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-09-17 08:58:46 +02:00
Eloy Lafuente (stronk7) 6f35d6536d Merge branch 'MDL-69395-39' of git://github.com/bmbrands/moodle into MOODLE_39_STABLE 2020-09-17 08:58:46 +02:00
Jun Pataleta 36cde1e295 Merge branch 'MDL-69663-m39' of https://github.com/sammarshallou/moodle into MOODLE_39_STABLE 2020-09-17 08:58:46 +02:00
AMOS bot 05a1532e88 Automatically generated installer lang files 2020-09-16 00:07:11 +00:00
David Mudrák 91ae4ab5db MDL-69698 licenses: Improve the performance of the licenses cache
The cache uses a single simple key and there is no need to hash it.
2020-09-15 10:22:57 +02:00
David Mudrák 2cc3588b77 MDL-69698 licenses: Do not cache the localised licenses fullnames
The localisation must happen only after loading the list of licenses
from cache so that the name is displayed in the current user's preferred
language, not in the language of the user who initiated the cache
rebuild.
2020-09-15 10:19:46 +02:00
Paul Holden 222aefb456 MDL-62387 tool_lp: switch to core 'cohort' form element.
The autocomplete AJAX is identical to the version in tool_lp, but also
includes support for excluding suggestions (i.e. cohorts already
synced with the current learning plan).
2020-09-15 08:06:37 +01:00
comete-upn 94160c9ad0 MDL-69667 competencies: fix competencies count always 0 in frameworks. 2020-09-15 08:37:50 +02:00
Jun Pataleta 9c7ab777d9 Merge branch 'MDL-42012-39-alt' of git://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-09-15 11:52:50 +08:00
Andrew Nicols 7818990010 MDL-42012 cache: Fix missing return value 2020-09-15 11:46:31 +08:00
Eloy Lafuente (stronk7) 17a035ac59 Merge branch 'MDL-42012-39-alt' of git://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2020-09-14 23:29:04 +02:00
Eloy Lafuente (stronk7) abe11a9ace Merge branch 'MDL-69658-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2020-09-14 22:56:55 +02:00
Paul Holden bfab0d603c MDL-69014 tool_usertours: clean up user preferences of deleted tours. 2020-09-14 20:36:26 +01:00
Paul Holden 070454489f MDL-66648 user: consistent checks for linking to full profile.
The access checks for displaying a link to a users' full profile
now match the checks performed on the full profile page itself.
2020-09-14 20:22:03 +01:00
AMOS bot e32a114998 Automatically generated installer lang files 2020-09-13 00:07:51 +00:00
AMOS bot 3db28cdebd Automatically generated installer lang files 2020-09-12 00:07:33 +00:00
sam marshall 51b0a67bd2 MDL-69663 Web services: override_webservice_execution not honoured
If two different plugin types (e.g. theme, local) implement
override_webservice_execution callbacks, then all of them except
the 'last' plugin type do not work correctly.
2020-09-10 09:51:16 +01:00
Andrew Nicols 7156a01a0c MDL-42012 cache: Valid definitions are required even when disabled 2020-09-09 14:05:19 +08:00
Andrew Nicols db22846df6 MDL-42012 cache: Fully disable cache for disabled cache factory 2020-09-09 14:05:19 +08:00
Andrew Nicols ef6e3bfd77 MDL-42012 cache: Allow data sources to work when caching is disabled 2020-09-09 14:05:19 +08:00
Paul Holden 36ee886a12 MDL-69658 quizaccess_seb: progress bar on install only when necessary. 2020-09-08 19:32:36 +01:00
Sara Arjona 97e0452344 MDL-69657 mod_h5pactivity: component passed always
The $component = 'mod_h5pactivity' will be passed always to the H5P
player because it's required for being able to call these activities
from outside using embed code. The xAPI implementation checks whether
the information should be tracked or not.

Backport of MDL-69174
2020-09-08 13:08:44 -04:00
Sara Arjona 874bdf2035 MDL-69657 h5p: add component to the embed H5P code
When the Moodle component is passed to the player, xAPI tracking
is enabled so, if the component implements required xAPI API methods
(for instance, mod_h5pactivity does), grades and responses are sent.
Adding this component to the embed code will help to add
the embed code from a mod_h5pactivity to any other place (such as label,
page or book), and being able to track the responses to the original
mod_h5pactivity.

Backport from MDL-69174
2020-09-08 13:08:13 -04:00
Bas Brands 6c39b7890e MDL-69395 theme_boost: improve colour contrast for form input fields
- for this issue the atto styles.css was moved into theme boost so
we can use our preset variable for $gray-500
2020-09-03 11:09:02 +02:00
Sam Hemelryk 3e9dadc85e MDL-68896 mod_scorm: improved sendBeacon use when unloading 2020-08-19 20:30:49 +12:00
1088 changed files with 13875 additions and 6788 deletions
+71
View File
@@ -0,0 +1,71 @@
<?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/>.
/**
* Template configuraton file for github actions CI/CD.
*
* @package core
* @copyright 2020 onwards Eloy Lafuente (stronk7) {@link https://stronk7.com}
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// This cannot be used out from a github actions workflow, so just exit.
getenv('GITHUB_WORKFLOW') || die; // phpcs:ignore moodle.Files.MoodleInternal.MoodleInternalGlobalState
unset($CFG);
global $CFG;
$CFG = new stdClass();
$CFG->dbtype = getenv('dbtype');
$CFG->dblibrary = 'native';
$CFG->dbhost = '127.0.0.1';
$CFG->dbname = 'test';
$CFG->dbuser = 'test';
$CFG->dbpass = 'test';
$CFG->prefix = 'm_';
$CFG->dboptions = ['dbcollation' => 'utf8mb4_bin'];
$host = 'localhost';
$CFG->wwwroot = "http://{$host}";
$CFG->dataroot = realpath(dirname(__DIR__)) . '/moodledata';
$CFG->admin = 'admin';
$CFG->directorypermissions = 0777;
// Debug options - possible to be controlled by flag in future.
$CFG->debug = (E_ALL | E_STRICT); // DEBUG_DEVELOPER.
$CFG->debugdisplay = 1;
$CFG->debugstringids = 1; // Add strings=1 to url to get string ids.
$CFG->perfdebug = 15;
$CFG->debugpageinfo = 1;
$CFG->allowthemechangeonurl = 1;
$CFG->passwordpolicy = 0;
$CFG->cronclionly = 0;
$CFG->pathtophp = getenv('pathtophp');
$CFG->phpunit_dataroot = realpath(dirname(__DIR__)) . '/phpunitdata';
$CFG->phpunit_prefix = 't_';
define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://localhost:8080');
define('TEST_EXTERNAL_FILES_HTTPS_URL', 'http://localhost:8080');
define('TEST_SESSION_REDIS_HOST', 'localhost');
define('TEST_CACHESTORE_REDIS_TESTSERVERS', 'localhost');
// TODO: add others (solr, mongodb, memcached, ldap...).
// Too much for now: define('PHPUNIT_LONGTEST', true); // Only leaves a few tests out and they are run later by CI.
require_once(__DIR__ . '/lib/setup.php');
+103
View File
@@ -0,0 +1,103 @@
name: Core
on: [push]
env:
php: 7.4
jobs:
Grunt:
runs-on: ubuntu-18.04
steps:
- name: Checking out code
uses: actions/checkout@v2
- name: Configuring node & npm
shell: bash -l {0}
run: nvm install
- name: Installing node stuff
run: npm install
- name: Running grunt
run: npx grunt
- name: Looking for uncommitted changes
# Add all files to the git index and then run diff --cached to see all changes.
# This ensures that we get the status of all files, including new files.
# We ignore npm-shrinkwrap.json to make the tasks immune to npm changes.
run: |
git add .
git reset -- npm-shrinkwrap.json
git diff --cached --exit-code
PHPUnit:
runs-on: ${{ matrix.os }}
services:
exttests:
image: moodlehq/moodle-exttests
ports:
- 8080:80
redis:
image: redis
ports:
- 6379:6379
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
php: 7.2
db: mysqli
- os: ubuntu-18.04
php: 7.4
db: pgsql
steps:
- name: Setting up DB mysql
if: ${{ matrix.db == 'mysqli' }}
uses: johanmeiring/mysql-action@tmpfs-patch
with:
collation server: utf8mb4_bin
mysql version: 5.7
mysql database: test
mysql user: test
mysql password: test
use tmpfs: true
- name: Setting up DB pgsql
if: ${{ matrix.db == 'pgsql' }}
uses: m4nu56/postgresql-action@v1
with:
postgresql version: 9.6
postgresql db: test
postgresql user: test
postgresql password: test
- name: Configuring git vars
uses: rlespinasse/github-slug-action@v3.x
- name: Setting up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
uses: actions/checkout@v2
- name: Setting up PHPUnit
env:
dbtype: ${{ matrix.db }}
run: |
echo "pathtophp=$(which php)" >> $GITHUB_ENV # Inject installed pathtophp to env. The template config needs it.
cp .github/workflows/config-template.php config.php
mkdir ../moodledata
sudo locale-gen en_AU.UTF-8
php admin/tool/phpunit/cli/init.php --no-composer-self-update
- name: Running PHPUnit tests
env:
dbtype: ${{ matrix.db }}
run: vendor/bin/phpunit -v
+1 -1
View File
@@ -1 +1 @@
v14.0.0
v14.15.0
+31 -74
View File
@@ -2,10 +2,9 @@
# process (which uses our internal CI system) this file is here for the benefit
# of community developers git clones - see MDL-51458.
# We currently disable Travis notifications entirely until https://github.com/travis-ci/travis-ci/issues/4976
# is fixed.
notifications:
email: false
email:
if: env(MOODLE_EMAIL) != no
language: php
@@ -17,31 +16,9 @@ services:
- mysql
- docker
php:
# We only run the highest and lowest supported versions to reduce the load on travis-ci.org.
- 7.4
- 7.2
addons:
postgresql: "9.6"
env:
# Although we want to run these jobs and see failures as quickly as possible, we also want to get the slowest job to
# start first so that the total run time is not too high.
#
# We only run MySQL on PHP 7.2, so run that first.
# CI Tests should be second-highest in priority as these only take <= 60 seconds to run under normal circumstances.
# Postgres is significantly is pretty reasonable in its run-time.
# Run CI Tests without running PHPUnit.
- DB=none TASK=CITEST
# Run unit tests on Postgres
- DB=pgsql TASK=PHPUNIT
# Perform an upgrade test too.
- DB=pgsql TASK=UPGRADE
jobs:
# Enable fast finish.
# This will fail the build if a single job fails (except those in allow_failures).
@@ -49,12 +26,35 @@ jobs:
fast_finish: true
include:
# Run mysql only on highest - it's just too slow
- php: 7.4
# First all the lowest php ones (7.2)
- php: 7.2
env: DB=none TASK=CITEST
- php: 7.2
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
- if: env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present
php: 7.2
env: DB=pgsql TASK=PHPUNIT
- if: env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all"
php: 7.2
env: DB=mysqli TASK=PHPUNIT
# Then, conditionally, all the highest php ones (7.4)
- if: env(MOODLE_PHP) = "all"
php: 7.4
env: DB=none TASK=CITEST
- if: env(MOODLE_PHP) = "all"
php: 7.4
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present)
php: 7.4
env: DB=pgsql TASK=PHPUNIT
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all")
php: 7.4
env: DB=mysqli TASK=PHPUNIT
# Run grunt/npm install on highest version too ('node' is an alias for the latest node.js version.)
- php: 7.4
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
cache:
directories:
@@ -114,7 +114,7 @@ install:
before_script:
- phpenv config-rm xdebug.ini
- >
if [ "$TASK" = 'PHPUNIT' -o "$TASK" = 'UPGRADE' ];
if [ "$TASK" = 'PHPUNIT' ];
then
# Copy generic configuration in place.
cp config-dist.php config.php ;
@@ -225,32 +225,6 @@ before_script:
export phpcmd=`which php`;
fi
########################################################################
# Upgrade test
########################################################################
- >
if [ "$TASK" = 'UPGRADE' ];
then
# We need the official upstream.
git remote add upstream https://github.com/moodle/moodle.git;
# Checkout 30 STABLE branch (the first version compatible with PHP 7.x)
git fetch upstream MOODLE_30_STABLE;
git checkout MOODLE_30_STABLE;
# Perform the upgrade
php admin/cli/install_database.php --agree-license --adminpass=Password --adminemail=admin@example.com --fullname="Upgrade test" --shortname=Upgrade;
# Return to the previous commit
git checkout -;
# Perform the upgrade
php admin/cli/upgrade.php --non-interactive --allow-unstable ;
# The local_ci repository can be used to check upgrade savepoints.
git clone https://github.com/moodlehq/moodle-local_ci.git local/ci ;
fi
script:
- >
if [ "$TASK" = 'PHPUNIT' ];
@@ -276,23 +250,6 @@ script:
git diff --cached --exit-code ;
fi
########################################################################
# Upgrade test
########################################################################
- >
if [ "$TASK" = 'UPGRADE' ];
then
cp local/ci/check_upgrade_savepoints/check_upgrade_savepoints.php ./check_upgrade_savepoints.php
result=`php check_upgrade_savepoints.php`;
# Check if there are problems
count=`echo "$result" | grep -P "ERROR|WARN" | wc -l` ;
if (($count > 0));
then
echo "$result"
exit 1 ;
fi
fi
after_script:
- >
if [ "$TASK" = 'PHPUNIT' ];
@@ -178,6 +178,7 @@ class filesize extends \admin_setting {
'id' => $this->get_id(),
'name' => $this->get_full_name(),
'value' => $data['v'],
'readonly' => $this->is_readonly(),
'options' => array_map(function($unit, $title) use ($data, $defaultunit) {
return [
'value' => $unit,
+1
View File
@@ -215,6 +215,7 @@ define('SITEID', 1);
//Database types
$databases = array('mysqli' => moodle_database::get_driver_instance('mysqli', 'native'),
'auroramysql' => moodle_database::get_driver_instance('auroramysql', 'native'),
'mariadb'=> moodle_database::get_driver_instance('mariadb', 'native'),
'pgsql' => moodle_database::get_driver_instance('pgsql', 'native'),
'oci' => moodle_database::get_driver_instance('oci', 'native'),
+10 -2
View File
@@ -34,6 +34,7 @@ $help = "Command line tool to uninstall plugins.
Options:
-h --help Print this help.
--show-all Displays a list of all installed plugins.
--show-contrib Displays a list of all third-party installed plugins.
--show-missing Displays a list of plugins missing from disk.
--purge-missing Uninstall all missing from disk plugins.
--plugins=<plugin name> A comma separated list of plugins to be uninstalled. E.g. mod_assign,mod_forum
@@ -44,6 +45,9 @@ Examples:
# php uninstall_plugins.php --show-all
Prints tab-separated list of all installed plugins.
# php uninstall_plugins.php --show-contrib
Prints tab-separated list of all third-party installed plugins.
# php uninstall_plugins.php --show-missing
Prints tab-separated list of all missing from disk plugins.
@@ -63,6 +67,7 @@ Examples:
list($options, $unrecognised) = cli_get_params([
'help' => false,
'show-all' => false,
'show-contrib' => false,
'show-missing' => false,
'purge-missing' => false,
'plugins' => false,
@@ -84,12 +89,15 @@ if ($options['help']) {
$pluginman = core_plugin_manager::instance();
$plugininfo = $pluginman->get_plugins();
if ($options['show-all'] || $options['show-missing']) {
if ($options['show-all'] || $options['show-missing'] || $options['show-contrib']) {
foreach ($plugininfo as $type => $plugins) {
foreach ($plugins as $name => $plugin) {
if ($options['show-contrib'] && $plugin->is_standard()) {
continue;
}
$pluginstring = $plugin->component . "\t" . $plugin->displayname;
if ($options['show-all']) {
if ($options['show-all'] || $options['show-contrib']) {
cli_writeln($pluginstring);
} else {
if ($plugin->get_status() === core_plugin_manager::PLUGIN_STATUS_MISSING) {
+182
View File
@@ -3344,4 +3344,186 @@
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
<MOODLE version="3.11" requires="3.6">
<UNICODE level="required">
<FEEDBACK>
<ON_ERROR message="unicoderequired" />
</FEEDBACK>
</UNICODE>
<DATABASE level="required">
<VENDOR name="mariadb" version="10.2.29" />
<VENDOR name="mysql" version="5.7" />
<VENDOR name="postgres" version="9.6" />
<VENDOR name="mssql" version="14.0" />
<VENDOR name="oracle" version="11.2" />
</DATABASE>
<PHP version="7.3.0" level="required">
</PHP>
<PCREUNICODE level="optional">
<FEEDBACK>
<ON_CHECK message="pcreunicodewarning" />
</FEEDBACK>
</PCREUNICODE>
<PHP_EXTENSIONS>
<PHP_EXTENSION name="iconv" level="required">
<FEEDBACK>
<ON_ERROR message="iconvrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="mbstring" level="required">
<FEEDBACK>
<ON_ERROR message="mbstringrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="curl" level="required">
<FEEDBACK>
<ON_ERROR message="curlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="openssl" level="required">
<FEEDBACK>
<ON_ERROR message="opensslrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="tokenizer" level="optional">
<FEEDBACK>
<ON_CHECK message="tokenizerrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="xmlrpc" level="optional">
<FEEDBACK>
<ON_CHECK message="xmlrpcrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="soap" level="optional">
<FEEDBACK>
<ON_CHECK message="soaprecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="ctype" level="required">
<FEEDBACK>
<ON_ERROR message="ctyperequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zip" level="required">
<FEEDBACK>
<ON_ERROR message="ziprequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zlib" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="gd" level="required">
<FEEDBACK>
<ON_ERROR message="gdrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="simplexml" level="required">
<FEEDBACK>
<ON_ERROR message="simplexmlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="spl" level="required">
<FEEDBACK>
<ON_ERROR message="splrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="pcre" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="dom" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xml" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xmlreader" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="intl" level="required">
<FEEDBACK>
<ON_ERROR message="intlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="json" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="hash" level="required"/>
<PHP_EXTENSION name="fileinfo" level="required"/>
<PHP_EXTENSION name="sodium" level="required"/>
</PHP_EXTENSIONS>
<PHP_SETTINGS>
<PHP_SETTING name="memory_limit" value="96M" level="required">
<FEEDBACK>
<ON_ERROR message="settingmemorylimit" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="file_uploads" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="settingfileuploads" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="opcache.enable" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="opcacherecommended" />
</FEEDBACK>
</PHP_SETTING>
</PHP_SETTINGS>
<CUSTOM_CHECKS>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbstorageengine" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
<FEEDBACK>
<ON_ERROR message="quizattemptsupgradedmessage" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
<FEEDBACK>
<ON_CHECK message="slashargumentswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
<FEEDBACK>
<ON_CHECK message="unsupporteddbtablerowformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_unoconv_version" level="optional">
<FEEDBACK>
<ON_CHECK message="unoconvwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
<FEEDBACK>
<ON_CHECK message="libcurlwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfileformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfilepertable" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddblargeprefix" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_is_https" level="optional">
<FEEDBACK>
<ON_CHECK message="ishttpswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_incomplete_unicode_support" level="optional">
<FEEDBACK>
<ON_CHECK message="incompleteunicodesupport" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_sixtyfour_bits" level="optional">
<FEEDBACK>
<ON_CHECK message="sixtyfourbitswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
</COMPATIBILITY_MATRIX>
+4 -2
View File
@@ -49,6 +49,7 @@
array($module->id));
core_plugin_manager::reset_caches();
admin_get_root(true, false); // settings not required - only pages
redirect(new moodle_url('/admin/modules.php'));
}
if (!empty($show) and confirm_sesskey()) {
@@ -66,6 +67,7 @@
array($module->id));
core_plugin_manager::reset_caches();
admin_get_root(true, false); // settings not required - only pages
redirect(new moodle_url('/admin/modules.php'));
}
echo $OUTPUT->header();
@@ -121,8 +123,8 @@
$count = -1;
}
if ($count>0) {
$countlink = "<a href=\"{$CFG->wwwroot}/course/search.php?modulelist=$module->name" .
"&amp;sesskey=".sesskey()."\" title=\"$strshowmodulecourse\">$count</a>";
$countlink = $OUTPUT->action_link(new moodle_url('/course/search.php', ['modulelist' => $module->name]),
$count, null, ['title' => $strshowmodulecourse]);
} else if ($count < 0) {
$countlink = get_string('error');
} else {
+1 -1
View File
@@ -53,7 +53,6 @@ $pageurl = new moodle_url('/admin/plugins.php', $pageparams);
$pluginman = core_plugin_manager::instance();
if ($uninstall) {
require_sesskey();
if (!$confirmed) {
admin_externalpage_setup('pluginsoverview', '', $pageparams);
@@ -92,6 +91,7 @@ if ($uninstall) {
exit();
} else {
require_sesskey();
$SESSION->pluginuninstallreturn = $pluginfo->get_return_url_after_uninstall($return);
$progress = new progress_trace_buffer(new text_progress_trace(), false);
$pluginman->uninstall_plugin($pluginfo->component, $progress);
+3 -8
View File
@@ -131,15 +131,10 @@ if ($hassiteconfig && \core_analytics\manager::is_analytics_enabled()) {
$timesplittingdefaults, $timesplittingoptions)
);
// Predictions processor output dir.
$defaultmodeloutputdir = rtrim($CFG->dataroot, '/') . DIRECTORY_SEPARATOR . 'models';
if (empty(get_config('analytics', 'modeloutputdir')) && !file_exists($defaultmodeloutputdir) &&
is_writable($defaultmodeloutputdir)) {
// Automatically create the dir for them so users don't see the invalid value red cross.
mkdir($defaultmodeloutputdir, $CFG->directorypermissions, true);
}
// Predictions processor output dir - specify default in setting description (used if left blank).
$defaultmodeloutputdir = \core_analytics\model::default_output_dir();
$settings->add(new admin_setting_configdirectory('analytics/modeloutputdir', new lang_string('modeloutputdir', 'analytics'),
new lang_string('modeloutputdirinfo', 'analytics'), $defaultmodeloutputdir));
new lang_string('modeloutputdirwithdefaultinfo', 'analytics', $defaultmodeloutputdir), ''));
// Disable web interface evaluation and get predictions.
$settings->add(new admin_setting_configcheckbox('analytics/onlycli', new lang_string('onlycli', 'analytics'),
+50 -14
View File
@@ -1,21 +1,57 @@
<?php
// This file is part of Moodle - https://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/>.
if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
/**
* Define administration settings on the Location settings page.
*
* @package core
* @category admin
* @copyright 2006 Martin Dougiamas <martin@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// "locations" settingpage
$temp = new admin_settingpage('locationsettings', new lang_string('locationsettings', 'admin'));
$temp->add(new admin_setting_servertimezone());
$temp->add(new admin_setting_forcetimezone());
$temp->add(new admin_settings_country_select('country', new lang_string('country', 'admin'), new lang_string('configcountry', 'admin'), 0));
$temp->add(new admin_setting_configtext('defaultcity', new lang_string('defaultcity', 'admin'), new lang_string('defaultcity_help', 'admin'), ''));
defined('MOODLE_INTERNAL') || die();
$temp->add(new admin_setting_heading('iplookup', new lang_string('iplookup', 'admin'), new lang_string('iplookupinfo', 'admin')));
$temp->add(new admin_setting_configfile('geoip2file', new lang_string('geoipfile', 'admin'),
new lang_string('configgeoipfile', 'admin', $CFG->dataroot.'/geoip/'), $CFG->dataroot.'/geoip/GeoLite2-City.mmdb'));
$temp->add(new admin_setting_configtext('googlemapkey3', new lang_string('googlemapkey3', 'admin'), new lang_string('googlemapkey3_help', 'admin'), '', PARAM_RAW, 60));
if ($hassiteconfig) {
$temp = new admin_settingpage('locationsettings', new lang_string('locationsettings', 'core_admin'));
$temp->add(new admin_setting_configtext('allcountrycodes', new lang_string('allcountrycodes', 'admin'), new lang_string('configallcountrycodes', 'admin'), '', '/^(?:\w+(?:,\w+)*)?$/'));
if ($ADMIN->fulltree) {
$temp->add(new admin_setting_servertimezone());
$temp->add(new admin_setting_forcetimezone());
$temp->add(new admin_settings_country_select('country', new lang_string('country', 'core_admin'),
new lang_string('configcountry', 'core_admin'), 0));
$temp->add(new admin_setting_configtext('defaultcity', new lang_string('defaultcity', 'core_admin'),
new lang_string('defaultcity_help', 'core_admin'), ''));
$temp->add(new admin_setting_heading('iplookup', new lang_string('iplookup', 'core_admin'),
new lang_string('iplookupinfo', 'core_admin')));
$temp->add(new admin_setting_configfile('geoip2file', new lang_string('geoipfile', 'core_admin'),
new lang_string('configgeoipfile', 'core_admin', $CFG->dataroot . '/geoip/'),
$CFG->dataroot . '/geoip/GeoLite2-City.mmdb'));
$temp->add(new admin_setting_configtext('googlemapkey3', new lang_string('googlemapkey3', 'core_admin'),
new lang_string('googlemapkey3_help', 'core_admin'), '', PARAM_RAW, 60));
$temp->add(new admin_setting_countrycodes('allcountrycodes', new lang_string('allcountrycodes', 'core_admin'),
new lang_string('configallcountrycodes', 'core_admin')));
}
$ADMIN->add('location', $temp);
} // end of speedup
}
+1
View File
@@ -32,6 +32,7 @@ $result = optional_param('result', null, PARAM_INT);
$pageurl = new \moodle_url('/admin/tasklogs.php');
$pageurl->param('filter', $filter);
$pageurl->param('result', $result);
$PAGE->set_url($pageurl);
$PAGE->set_context(context_system::instance());
@@ -25,6 +25,7 @@
* value - yes value
* id - element id
* checked - boole
* readonly - bool
Example context (json):
{
@@ -32,10 +33,11 @@
"no": "False",
"value": "True",
"id": "test0",
"checked": "checked"
"checked": "checked",
"readonly": false
}
}}
<div class="form-checkbox defaultsnext">
<input type="hidden" name="{{name}}" value="{{no}}">
<input type="checkbox" name="{{name}}" value="{{value}}" id="{{id}}" {{#checked}}checked{{/checked}}>
<input {{#readonly}}disabled{{/readonly}} type="checkbox" name="{{name}}" value="{{value}}" id="{{id}}" {{#checked}}checked{{/checked}}>
</div>
@@ -25,6 +25,7 @@
* id - element id
* value - element value
* haspreviewconfig - show preview of selected color
* readonly - bool
Example context (json):
{
@@ -32,6 +33,7 @@
"name": "name0",
"id": "id0",
"value": "#555655",
"readonly": false,
"haspreviewconfig": false
}
}}
@@ -44,7 +46,7 @@
{{>core/pix_icon}}
{{/icon}}
</div>
<input type="text" name="{{name}}" id="{{id}}" value="{{value}}" size="12" class="form-control text-ltr">
<input type="text" name="{{name}}" id="{{id}}" value="{{value}}" size="12" class="form-control text-ltr" {{#readonly}}disabled{{/readonly}}>
{{#haspreviewconfig}}
<input type="button" id="{{id}}_preview" value={{#quote}}{{#str}}preview{{/str}}{{/quote}} class="admin_colourpicker_preview">
{{/haspreviewconfig}}
@@ -33,7 +33,7 @@
"name": "test",
"value": "/my-super-secret-path/",
"id": "test0",
"readonly": true,
"readonly": false,
"showvalidity": true,
"valid": false
}
@@ -23,6 +23,7 @@
* name - form element name
* options - list of options for units containing name, value, selected
* value - yes
* readonly - bool
* id - element id
Example context (json):
@@ -30,6 +31,7 @@
"name": "test",
"value": "5",
"id": "test0",
"readonly": false,
"options": [ { "name": "Minutes", "value": "mins", "selected": true } ]
}
}}
@@ -38,9 +40,9 @@
}}
<div class="form-duration defaultsnext">
<div class="form-inline">
<input type="text" size="5" id="{{id}}v" name="{{name}}[v]" value="{{value}}" class="form-control text-ltr">
<input type="text" size="5" id="{{id}}v" name="{{name}}[v]" value="{{value}}" class="form-control text-ltr" {{#readonly}}disabled{{/readonly}}>
<label class="sr-only" for="{{id}}u">{{#str}}durationunits, admin{{/str}}</label>
<select id="{{id}}u" name="{{name}}[u]" class="form-control custom-select">
<select id="{{id}}u" name="{{name}}[u]" class="form-control custom-select" {{#readonly}}disabled{{/readonly}}>
{{#options}}
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
{{/options}}
@@ -33,7 +33,7 @@
"name": "test",
"value": "/usr/bin/cowsay",
"id": "test0",
"readonly": true,
"readonly": false,
"showvalidity": true,
"valid": false
}
+3 -1
View File
@@ -26,6 +26,7 @@
* readonly - Make the field readonly
* value - value
* showvalidity - Show a green check if the path is readable
* readonly - bool
* valid - True if the path is readable
Example context (json):
@@ -33,8 +34,9 @@
"name": "test",
"value": "/my-super-secret-path/file",
"id": "test0",
"readonly": true,
"readonly": false,
"showvalidity": true,
"readonly": false,
"valid": false
}
}}
@@ -24,12 +24,14 @@
* options - list of options for units containing name, value, selected
* value - yes
* id - element id
* readonly - bool
Example context (json):
{
"name": "test",
"value": "5",
"id": "test0",
"readonly": false,
"options": [ { "name": "KB", "value": "1024", "selected": true } ]
}
}}
@@ -38,9 +40,9 @@
}}
<div class="form-filesize defaultsnext">
<div class="form-inline">
<input type="text" size="5" id="{{id}}v" name="{{name}}[v]" value="{{value}}" class="form-control text-ltr">
<input type="text" size="5" id="{{id}}v" name="{{name}}[v]" value="{{value}}" class="form-control text-ltr" {{#readonly}}disabled{{/readonly}}>
<label class="sr-only" for="{{id}}u">{{#str}}filesizeunits, admin{{/str}}</label>
<select id="{{id}}u" name="{{name}}[u]" class="form-control custom-select">
<select id="{{id}}u" name="{{name}}[u]" class="form-control custom-select" {{#readonly}}disabled{{/readonly}}>
{{#options}}
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
{{/options}}
@@ -24,11 +24,13 @@
* id - element id
* size - element size
* options - list of options containing name, value, selected
* readonly - bool
Example context (json):
{
"name": "test",
"id": "test0",
"readonly": false,
"size": "3",
"options": [ { "name": "Option 1", "value": "V", "selected": true },
{ "name": "Option 2", "value": "V", "selected": true } ]
@@ -39,7 +41,7 @@
}}
<div class="form-select">
<input type="hidden" name="{{name}}[xxxxx]" value="1">
<select id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
{{#options}}
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
{{/options}}
@@ -25,11 +25,13 @@
* size - element size
* options - list of options not grouped
* optgroups - list of options grouped containing the group label and for each option: name, value, selected
* readonly - bool
Example context (json):
{
"name": "test",
"id": "test0",
"readonly": false,
"size": "3",
"options": [
{ "name": "Option 1", "value": "V", "selected": false },
@@ -58,7 +60,7 @@
}}
<div class="form-select">
<input type="hidden" name="{{name}}[xxxxx]" value="1">
<select id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
{{#options}}
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
{{/options}}
@@ -24,7 +24,7 @@
* size - form element size
* value - form element value
* id - element id
* forced - has value been defined in config.php
* readonly - has value been defined in config.php
Example context (json):
{
@@ -32,10 +32,10 @@
"id": "test0",
"size": "8",
"value": "secret",
"forced": false
"readonly": false
}
}}
{{#forced}}
{{#readonly}}
<div class="form-password">
<input type="text"
name = "{{ name }}"
@@ -46,8 +46,8 @@
disabled
>
</div>
{{/forced}}
{{^forced}}
{{/readonly}}
{{^readonly}}
<div class="form-password">
<span data-passwordunmask="wrapper" data-passwordunmaskid="{{ id }}">
<span data-passwordunmask="editor">
@@ -76,4 +76,4 @@ require(['core_form/passwordunmask'], function(PasswordUnmask) {
new PasswordUnmask("{{ id }}");
});
{{/js}}
{{/forced}}
{{/readonly}}
@@ -23,11 +23,13 @@
* name - form element name
* id - element id
* options - list of options containing name, value, selected
* readonly - bool
Example context (json):
{
"name": "test",
"id": "test0",
"readonly": false,
"options": [
{ "name": "Option 1", "value": "V", "selected": true },
{ "name": "Option 2", "value": "V", "selected": true }
@@ -38,7 +40,7 @@
Setting configselect.
}}
<div class="form-select defaultsnext">
<select id="{{id}}" name="{{name}}" class="custom-select">
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}" class="custom-select">
{{#options}}
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
{{/options}}
@@ -22,6 +22,7 @@
Context variables required for this template:
* name - form element name
* id - element id
* readonly - bool
* options - list of options (not grouped)
* optgroups - list of options grouped containing the group label and for each option: name, value, selected
@@ -29,6 +30,7 @@
{
"name": "test",
"id": "test0",
"readonly": false,
"options": [
{ "name": "Option 1", "value": "V", "selected": false },
{ "name": "Option 2", "value": "V", "selected": false }
@@ -55,7 +57,7 @@
Setting configselect with optgroup support.
}}
<div class="form-select defaultsnext">
<select id="{{id}}" name="{{name}}" class="custom-select">
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}" class="custom-select">
{{#options}}
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
{{/options}}
+3 -1
View File
@@ -26,6 +26,7 @@
* size - element size
* forceltr - always display as ltr
* attributes - list of additional attributes containing name, value
* readonly - bool
Example context (json):
{
@@ -34,6 +35,7 @@
"value": "A tall, dark stranger will have more fun than you.",
"size": "21",
"forceltr": false,
"readonly": false,
"attributes": [ { "name": "readonly", "value": "readonly" } ]
}
}}
@@ -41,5 +43,5 @@
Setting configtext.
}}
<div class="form-text defaultsnext">
<input type="text" name="{{name}}" value="{{value}}" size="{{size}}" id="{{id}}" class="form-control {{#forceltr}}text-ltr{{/forceltr}}">
<input type="text" name="{{name}}" value="{{value}}" size="{{size}}" id="{{id}}" class="form-control {{#forceltr}}text-ltr{{/forceltr}}" {{#readonly}}disabled{{/readonly}}>
</div>
@@ -33,6 +33,7 @@
"cols": "30",
"rows": "3",
"value": "Excellent day for putting Slinkies on an escalator.",
"readonly": false,
"id": "test0"
}
}}
@@ -40,5 +41,5 @@
Setting configtextarea.
}}
<div class="form-textarea">
<textarea rows="{{rows}}" cols="{{cols}}" id="{{id}}" name="{{name}}" spellcheck="true" class="form-control {{#forceltr}}text-ltr{{/forceltr}}">{{value}}</textarea>
<textarea {{#readonly}}disabled{{/readonly}} rows="{{rows}}" cols="{{cols}}" id="{{id}}" name="{{name}}" spellcheck="true" class="form-control {{#forceltr}}text-ltr{{/forceltr}}">{{value}}</textarea>
</div>
+4 -2
View File
@@ -24,11 +24,13 @@
* id - element id
* hours - list of valid hour options containing name, value, selected
* minutes - list of valid minute options containing name, value, selected
* readonly - bool
Example context (json):
{
"name": "test",
"id": "test0",
"readonly": false,
"minutes": [
{ "name": "00", "value": "0", "selected": true },
{ "name": "01", "value": "1", "selected": false }
@@ -45,13 +47,13 @@
<div class="form-time defaultsnext">
<div class="form-inline text-ltr">
<label class="sr-only" for="{{id}}h">{{#str}}hours{{/str}}</label>
<select id="{{id}}h" name="{{name}}[h]" class="custom-select">
<select id="{{id}}h" name="{{name}}[h]" class="custom-select" {{#readonly}}disabled{{/readonly}}>
{{#hours}}
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
{{/hours}}
</select>:
<label class="sr-only" for="{{id}}m">{{#str}}minutes{{/str}}</label>
<select id="{{id}}m" name="{{name}}[m]" class="custom-select">
<select id="{{id}}m" name="{{name}}[m]" class="custom-select" {{#readonly}}disabled{{/readonly}}>
{{#minutes}}
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
{{/minutes}}
@@ -0,0 +1,29 @@
@core @core_admin
Feature: Administrator is warned and when trying to set invalid allcountrycodes value.
In order to avoid misconfiguration of the country selector fields
As an admin
I want to be warned when I try to set an invalid country code in the allcountrycodes field
Scenario: Attempting to set allcountrycodes field with valid country codes
Given I log in as "admin"
And I navigate to "Location > Location settings" in site administration
When I set the following administration settings values:
| All country codes | CZ,BE,GB,ES |
Then I should not see "Invalid country code"
Scenario: Attempting to set allcountrycodes field with invalid country code
Given I log in as "admin"
And I navigate to "Location > Location settings" in site administration
When I set the following administration settings values:
| All country codes | CZ,BE,FOOBAR,GB,ES |
Then I should see "Invalid country code: FOOBAR"
Scenario: Attempting to unset allcountrycodes field
Given I log in as "admin"
And I navigate to "Location > Location settings" in site administration
And I set the following administration settings values:
| All country codes | CZ,BE,GB,ES |
And I navigate to "Location > Location settings" in site administration
When I set the following administration settings values:
| All country codes | |
Then I should not see "Invalid country code"
@@ -0,0 +1,34 @@
@core @core_admin
Feature: Configure language settings for the site
In order to configure language settings for the site
As an admin
I want to set language settings relevant to my site users
Scenario: Set languages on language menu
Given I log in as "admin"
And I navigate to "Language > Language settings" in site administration
When I set the field "Languages on language menu" to "en"
And I press "Save changes"
Then I should not see "Invalid language code"
Scenario: Reset languages on language menu
Given I log in as "admin"
And I navigate to "Language > Language settings" in site administration
When I set the field "Languages on language menu" to ""
And I press "Save changes"
Then I should not see "Invalid language code"
Scenario Outline: Set languages on language menu with invalid language
Given I log in as "admin"
And I navigate to "Language > Language settings" in site administration
When I set the field "Languages on language menu" to "<fieldvalue>"
And I press "Save changes"
Then I should see "Invalid language code: <invalidlang>"
Examples:
| fieldvalue | invalidlang |
| xx | xx |
| xx\|Bad | xx |
| en,qq | qq |
| en,qq\|Bad | qq |
| en$$ | en$$ |
| en$$\|Bad | en$$ |
@@ -6,14 +6,18 @@ Feature: Edit capabilities
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| username | firstname | lastname |
| teacher1 | Teacher | 1 |
| tutor | Teaching | Assistant |
| student | Student | One |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| user | course | role |
| teacher1 | C1 | editingteacher |
| tutor | C1 | teacher |
| student | C1 | student |
Scenario: Default system capabilities modification
Given I log in as "admin"
@@ -60,3 +64,25 @@ Feature: Edit capabilities
Then "mod/forum:deleteanypost" capability has "Prohibit" permission
And "mod/forum:editanypost" capability has "Prevent" permission
And "mod/forum:addquestion" capability has "Allow" permission
@javascript
Scenario: Edit permissions escapes role names correctly
When I am on the "C1" "Course" page logged in as "admin"
And I navigate to "Edit settings" in current page administration
And I set the following fields to these values:
| Your word for 'Teacher' | Teacher >= editing |
| Your word for 'Non-editing teacher' | Teacher < "editing" |
| Your word for 'Student' | Studier & 'learner' |
And I press "Save and display"
And I navigate to course participants
Then I should see "Teacher >= editing" in the "Teacher 1" "table_row"
And I should see "Teacher < \"editing\"" in the "Teaching Assistant" "table_row"
And I should see "Studier & 'learner'" in the "Student One" "table_row"
And I navigate to "Users > Permissions" in current page administration
And I should see "Teacher >= editing" in the "mod/forum:replypost" "table_row"
And I should see "Teacher < \"editing\"" in the "mod/forum:replypost" "table_row"
And I should see "Studier & 'learner'" in the "mod/forum:replypost" "table_row"
And I follow "Prohibit"
And "Teacher >= editing" "button" in the "Prohibit role" "dialogue" should be visible
And "Teacher < \"editing\"" "button" in the "Prohibit role" "dialogue" should be visible
And "Studier & 'learner'" "button" in the "Prohibit role" "dialogue" should be visible
@@ -0,0 +1,30 @@
@tool_behat
Feature: Verify that the inplace editable field works as expected
In order to use behat step definitions
As a test write
I need to ensure that the inplace editable works in forms
Background:
Given the following "course" exists:
| fullname | Course 1 |
| shortname | C1 |
And the following "activities" exist:
| activity | course | name | idnumber |
| forum | C1 | My first forum | forum1 |
| assign | C1 | My first assignment | assign1 |
| quiz | C1 | My first quiz | quiz1 |
And I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
@javascript
Scenario: Using an inplace editable updates the name of an activity
When I set the field "Edit title" in the "My first assignment" "activity" to "Coursework submission"
Then I should see "Coursework submission"
And I should not see "My first assignment"
But I should see "My first forum"
And I should see "My first quiz"
And I set the field "Edit title" in the "Coursework submission" "activity" to "My first assignment"
And I should not see "Coursework submission"
But I should see "My first assignment"
And I should see "My first forum"
And I should see "My first quiz"
@@ -0,0 +1,52 @@
@tool_behat
Feature: Verify that keyboard steps work as expected
In order to use behat step definitions
As a test writer
I need to verify that the keyboard steps work as expected
@javascript
Scenario: Typing keys into a field causes them to be input
Given the following "users" exist:
| username | email | firstname | lastname | password |
| saffronr | saffron.rutledge@example.com | Saffron | Rutledge | flowerpower |
Given I click on "Log in" "link"
And I click on "Username" "field"
When I type "saffronr"
And I press the tab key
And I type "flowerpower"
And I press enter
Then I should see "You are logged in as Saffron Rutledge"
@javascript
Scenario: Using tab changes focus to the next or previous field
Given I click on "Log in" "link"
And I click on "Username" "field"
And the focused element is "Username" "field"
When I press the tab key
Then the focused element is "Password" "field"
And I press the shift tab key
And the focused element is "Username" "field"
@javascript
Scenario: Using the arrow keys allows me to navigate through menus
Given the following "users" exist:
| username | email | firstname | lastname |
| saffronr | saffron.rutledge@example.com | Saffron | Rutledge |
And I log in as "saffronr"
And I click on "Saffron Rutledge" "link" in the ".usermenu" "css_element"
When I press the up key
Then the focused element is "Log out" "link"
@javascript
Scenario: The escape key can be used to close a dialogue
Given the following "course" exists:
| fullname | C1|
| shortname | C1 |
And I log in as "admin"
And I am on "C1" course homepage
And I navigate to course participants
And I press "Enrol users"
And "Enrol users" "dialogue" should be visible
When I press the escape key
Then "Enrol users" "dialogue" should not be visible
+1 -1
View File
@@ -1613,7 +1613,7 @@ class external extends external_api {
*/
private static function get_tree_node_structure($allowchildbranches = true) {
$fields = [
'text' => new external_value(PARAM_TEXT, 'The node text', VALUE_REQUIRED),
'text' => new external_value(PARAM_RAW, 'The node text', VALUE_REQUIRED),
'expandcontextid' => new external_value(PARAM_INT, 'The contextid this node expands', VALUE_REQUIRED),
'expandelement' => new external_value(PARAM_ALPHA, 'What element is this node expanded to', VALUE_REQUIRED),
'contextid' => new external_value(PARAM_INT, 'The node contextid', VALUE_REQUIRED),
@@ -63,7 +63,6 @@ class renderer extends plugin_renderer_base {
$params = [
'data-action' => 'contactdpo',
'data-replytoemail' => $replytoemail,
'class' => 'contactdpo'
];
return html_writer::link('#', get_string('contactdataprotectionofficer', 'tool_dataprivacy'), $params);
}
@@ -46,7 +46,7 @@ Feature: Manage data requests
And I open the action menu in "John Doe" "table_row"
And I should see "View the request"
But I should not see "Mark as complete"
And I press key "27" in ".moodle-actionmenu" "css_element"
And I press the escape key
And I open the action menu in "Jane Doe" "table_row"
And I choose "Mark as complete" in the open action menu
And I should see "Do you really want to mark this user enquiry as complete?"
@@ -10,16 +10,12 @@ Feature: Manage data storage purposes
And I open the action menu in "region-main" "region"
And I choose "Purposes" in the open action menu
And I press "Add purpose"
And I set the field "Name" to "Purpose 1"
And I set the field "Description" to "Purpose 1 description"
And I click on ".form-autocomplete-downarrow" "css_element" in the "Lawful bases" "form_row"
And I click on "Contract (GDPR Art. 6.1(b))" "list_item"
And I click on "Legal obligation (GDPR Art 6.1(c))" "list_item"
And I press key "27" in the field "Lawful bases"
And I click on ".form-autocomplete-downarrow" "css_element" in the "Sensitive personal data processing reasons" "form_row"
And I click on "Explicit consent (GDPR Art. 9.2(a))" "list_item"
And I press key "27" in the field "Sensitive personal data processing reasons"
And I set the field "retentionperiodnumber" to "2"
And I set the following fields to these values:
| Name | Purpose 1 |
| Description | Purpose 1 description |
| Lawful bases | Contract (GDPR Art. 6.1(b)),Legal obligation (GDPR Art 6.1(c)) |
| Sensitive personal data processing reasons | Explicit consent (GDPR Art. 9.2(a)) |
| retentionperiodnumber | 2 |
When I press "Save"
Then I should see "Purpose 1" in the "List of data purposes" "table"
And I should see "Contract (GDPR Art. 6.1(b))" in the "Purpose 1" "table_row"
@@ -31,14 +27,13 @@ Feature: Manage data storage purposes
Scenario: Update a data storage purpose
Given I open the action menu in "Purpose 1" "table_row"
And I choose "Edit" in the open action menu
And I set the field "Name" to "Purpose 1 edited"
And I set the field "Description" to "Purpose 1 description edited"
And I click on "Legal obligation (GDPR Art 6.1(c))" "text" in the ".form-autocomplete-selection" "css_element"
And I click on ".form-autocomplete-downarrow" "css_element" in the "Lawful bases" "form_row"
And I click on "Vital interests (GDPR Art. 6.1(d))" "list_item"
And I press key "27" in the field "Lawful bases"
And I set the field "retentionperiodnumber" to "3"
And I click on "protected" "checkbox"
And I set the following fields to these values:
| Name | Purpose 1 edited |
| Description | Purpose 1 description edited |
| Lawful bases | Contract (GDPR Art. 6.1(b)), Vital interests (GDPR Art. 6.1(d)) |
| Sensitive personal data processing reasons | Explicit consent (GDPR Art. 9.2(a)) |
| retentionperiodnumber | 3 |
| protected | 1 |
When I press "Save changes"
Then I should see "Purpose 1 edited" in the "List of data purposes" "table"
And I should see "Purpose 1 description edited" in the "Purpose 1 edited" "table_row"
@@ -22,8 +22,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_langimport\output;
defined('MOODLE_INTERNAL') || die();
use core_collator;
use moodle_url;
use renderable;
use renderer_base;
@@ -95,6 +95,8 @@ class langimport_page implements renderable, templatable {
if (!empty($this->availablelanguages)) {
$data->toinstalloptions = [];
core_collator::asort($this->availablelanguages);
foreach ($this->availablelanguages as $code => $language) {
$option = new stdClass();
$option->value = $code;
@@ -26,7 +26,6 @@ namespace tool_lp\form;
defined('MOODLE_INTERNAL') || die();
use moodleform;
use core\form\persistent;
require_once($CFG->libdir . '/formslib.php');
@@ -39,17 +38,20 @@ require_once($CFG->libdir . '/formslib.php');
*/
class template_cohorts extends moodleform {
/**
* Form definition
*
* @return void
*/
public function definition() {
$mform = $this->_form;
$options = array(
'ajax' => 'tool_lp/form-cohort-selector',
'multiple' => true,
'data-contextid' => $this->_customdata['pagecontextid'],
'data-includes' => 'parents'
'exclude' => implode(',', $this->_customdata['excludecohorts']),
'contextid' => $this->_customdata['pagecontextid'],
);
$mform->addElement('autocomplete', 'cohorts', get_string('selectcohortstosync', 'tool_lp'), array(), $options);
$mform->addElement('cohort', 'cohorts', get_string('selectcohortstosync', 'tool_lp'), $options);
$mform->addElement('submit', 'submit', get_string('addcohorts', 'tool_lp'));
}
}
+13 -1
View File
@@ -54,7 +54,19 @@ if ($canmanagetemplate && ($removecohort = optional_param('removecohort', false,
}
// Capture the form submission.
$form = new \tool_lp\form\template_cohorts($url->out(false), array('pagecontextid' => $pagecontextid));
$existingcohortsql =
'SELECT c.id
FROM {' . \core_competency\template_cohort::TABLE . '} tc
JOIN {cohort} c ON c.id = tc.cohortid
WHERE tc.templateid = :templateid';
$existingcohorts = $DB->get_records_sql_menu($existingcohortsql, ['templateid' => $template->get('id')]);
$form = new \tool_lp\form\template_cohorts($url->out(false), [
'pagecontextid' => $pagecontextid,
'excludecohorts' => array_keys($existingcohorts),
]);
if ($canmanagetemplate && ($data = $form->get_data()) && !empty($data->cohorts)) {
$maxtocreate = 50;
$maxreached = false;
@@ -53,11 +53,11 @@ Feature: See the competencies for an activity on the course competencies page.
Then I should see "Test-Comp1"
And I should see "Test-Comp2"
And I set the field "Filter competencies by resource or activity" to "PageName1"
And I press key "13" in the field "Filter competencies by resource or activity"
And I press the enter key
And I should see "Test-Comp1"
And I should not see "Test-Comp2"
And I set the field "Filter competencies by resource or activity" to "PageName2"
And I press key "13" in the field "Filter competencies by resource or activity"
And I press the enter key
And I should not see "Test-Comp1"
And I should not see "Test-Comp2"
And I should see "No competencies have been linked to this activity or resource."
+2 -4
View File
@@ -30,7 +30,7 @@ Feature: Manage plearning plan
And I click on ".template-userplans" "css_element" in the "Science template" "table_row"
And I open the autocomplete suggestions list
And I click on "Admin User" item in the autocomplete list
And I press key "27" in the field "Select users to create learning plans for"
And I press the escape key
When I click on "Create learning plans" "button"
Then I should see "A learning plan was created"
And I should see "Admin User" in the "Science template" "table_row"
@@ -53,9 +53,7 @@ Feature: Manage plearning plan
And I follow "Home"
And I navigate to "Competencies > Learning plan templates" in site administration
And I click on ".template-cohorts" "css_element" in the "Science template cohort" "table_row"
And I click on ".form-autocomplete-downarrow" "css_element"
And I click on "cohort plan" item in the autocomplete list
And I press key "27" in the field "Select cohorts to sync"
And I set the field "Select cohorts to sync" to "cohort plan"
When I click on "Add cohorts" "button"
Then I should see "2 learning plans were created."
And I follow "Learning plan templates"
+21 -1
View File
@@ -322,6 +322,12 @@ class api {
}
}
if (empty($section) or $section == 'supportcontact') {
$settings->supportname = $CFG->supportname;
$settings->supportemail = $CFG->supportemail;
$settings->supportpage = $CFG->supportpage;
}
return $settings;
}
@@ -487,6 +493,7 @@ class api {
'$mmSideMenuDelegate_mmaCompetency' => new lang_string('myplans', 'tool_lp'),
'CoreMainMenuDelegate_AddonBlog' => new lang_string('blog', 'blog'),
'$mmSideMenuDelegate_mmaFiles' => new lang_string('files'),
'CoreMainMenuDelegate_CoreTag' => new lang_string('tags'),
'$mmSideMenuDelegate_website' => new lang_string('webpage'),
'$mmSideMenuDelegate_help' => new lang_string('help'),
'CoreMainMenuDelegate_QrReader' => new lang_string('scanqrcode', 'tool_mobile'),
@@ -595,8 +602,21 @@ class api {
$timenow = time();
$expectedissuer = null;
foreach ($info['certinfo'] as $cert) {
// Due to a bug in certain curl/openssl versions the signature algorithm isn't always correctly parsed.
// See https://github.com/curl/curl/issues/3706 for reference.
if (!array_key_exists('Signature Algorithm', $cert)) {
// The malformed field that does contain the algorithm we're looking for looks like the following:
// <WHITESPACE>Signature Algorithm: <ALGORITHM><CRLF><ALGORITHM>.
preg_match('/\s+Signature Algorithm: (?<algorithm>[^\s]+)/', $cert['Public Key Algorithm'], $matches);
$signaturealgorithm = $matches['algorithm'] ?? '';
} else {
$signaturealgorithm = $cert['Signature Algorithm'];
}
// Check if the signature algorithm is weak (Android won't work with SHA-1).
if ($cert['Signature Algorithm'] == 'sha1WithRSAEncryption' || $cert['Signature Algorithm'] == 'sha1WithRSA') {
if ($signaturealgorithm == 'sha1WithRSAEncryption' || $signaturealgorithm == 'sha1WithRSA') {
$warnings[] = ['insecurealgorithmwarning', 'tool_mobile'];
}
// Check certificate start date.
+1 -1
View File
@@ -139,7 +139,7 @@ class external extends external_api {
array(
'wwwroot' => new external_value(PARAM_RAW, 'Site URL.'),
'httpswwwroot' => new external_value(PARAM_RAW, 'Site https URL (if httpslogin is enabled).'),
'sitename' => new external_value(PARAM_TEXT, 'Site name.'),
'sitename' => new external_value(PARAM_RAW, 'Site name.'),
'guestlogin' => new external_value(PARAM_INT, 'Whether guest login is enabled.'),
'rememberusername' => new external_value(PARAM_INT, 'Values: 0 for No, 1 for Yes, 2 for optional.'),
'authloginviaemail' => new external_value(PARAM_INT, 'Whether log in via email is enabled.'),
@@ -229,6 +229,10 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
'value' => get_config('core_admin', 'coursecolor' . $number)
];
}
$expected[] = ['name' => 'supportname', 'value' => $CFG->supportname];
$expected[] = ['name' => 'supportemail', 'value' => $CFG->supportemail];
$expected[] = ['name' => 'supportpage', 'value' => $CFG->supportpage];
$this->assertCount(0, $result['warnings']);
$this->assertEquals($expected, $result['settings']);
+1 -1
View File
@@ -1,2 +1,2 @@
define ("tool_templatelibrary/search",["jquery","core/ajax","core/log","core/notification","core/templates","core/config"],function(a,b,c,d,e,f){var g=function(b){e.render("tool_templatelibrary/search_results",{templates:b}).done(function(b,c){e.replaceNode(a("[data-region=\"searchresults\"]"),b,c)}).fail(d.exception)},h=function(c){var e=a("[data-field=\"component\"]").val(),f=a("[data-field=\"search\"]").val();document.location.hash=f;b.call([{methodname:"tool_templatelibrary_list_templates",args:{component:e,search:f,themename:c},done:g,fail:d.exception}],!0,!1)},i=null,j=function(a,b){if(null!==i){window.clearTimeout(i)}i=window.setTimeout(function(){a();i=null},b)},k=function(){j(h.bind(this,f.theme),400)};a("[data-region=\"list-templates\"]").on("change","[data-field=\"component\"]",k);a("[data-region=\"list-templates\"]").on("input","[data-field=\"search\"]",k);a("[data-field=\"search\"]").val(document.location.hash.replace("#",""));h(f.theme);return{}});
define ("tool_templatelibrary/search",["jquery","core/ajax","core/log","core/notification","core/templates","core/config"],function(a,b,c,d,e,f){var g=function(b){e.render("tool_templatelibrary/search_results",{templates:b}).done(function(b,c){e.replaceNode(a("[data-region=\"searchresults\"]"),b,c)}).fail(d.exception)},h=function(c){var e=a("[data-field=\"component\"]").val(),f=a("[data-field=\"search\"]").val();b.call([{methodname:"tool_templatelibrary_list_templates",args:{component:e,search:f,themename:c},done:g,fail:d.exception}],!0,!1)},i=null,j=function(a,b){if(null!==i){window.clearTimeout(i)}i=window.setTimeout(function(){a();i=null},b)},k=function(){j(h.bind(this,f.theme),400)};a("[data-region=\"list-templates\"]").on("change","[data-field=\"component\"]",k);a("[data-region=\"list-templates\"]").on("input","[data-field=\"search\"]",k);h(f.theme);return{}});
//# sourceMappingURL=search.min.js.map
File diff suppressed because one or more lines are too long
@@ -48,8 +48,6 @@ define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates'
var searchStr = $('[data-field="search"]').val();
// Trigger the search.
document.location.hash = searchStr;
ajax.call([
{methodname: 'tool_templatelibrary_list_templates',
args: {component: componentStr, search: searchStr, themename: themename},
@@ -86,7 +84,6 @@ define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates'
$('[data-region="list-templates"]').on('change', '[data-field="component"]', changeHandler);
$('[data-region="list-templates"]').on('input', '[data-field="search"]', changeHandler);
$('[data-field="search"]').val(document.location.hash.replace('#', ''));
refreshSearch(config.theme);
return {};
});
@@ -38,6 +38,22 @@ use tool_templatelibrary\api;
*/
class list_templates_page implements renderable, templatable {
/** @var string $component The currently selected component */
protected $component;
/** @var string $search The current search */
protected $search;
/**
* Template page constructor
*
* @param string $component
* @param string $search
*/
public function __construct(string $component = '', string $search = '') {
$this->component = $component;
$this->search = $search;
}
/**
* Export this data so it can be used as the context for a mustache template.
*
@@ -46,6 +62,7 @@ class list_templates_page implements renderable, templatable {
public function export_for_template(renderer_base $output) {
$data = new stdClass();
$data->allcomponents = array();
$data->search = $this->search;
$fulltemplatenames = api::list_templates();
$pluginmanager = core_plugin_manager::instance();
$components = array();
@@ -59,6 +76,7 @@ class list_templates_page implements renderable, templatable {
foreach ($components as $component) {
$info = new stdClass();
$info->component = $component;
$info->selected = ($component === $this->component);
if (strpos($component, 'core') === 0) {
$info->name = get_string('coresubsystem', 'tool_templatelibrary', $component);
} else {
@@ -36,10 +36,10 @@
<div class="control-group">
<label for="selectcomponent" class="control-label">{{#str}}component, tool_templatelibrary{{/str}}</label>
<div class="controls">
<select id="selectcomponent" data-field="component">
<select id="selectcomponent" name="component" data-field="component">
<option value="">{{#str}}all, tool_templatelibrary{{/str}}</option>
{{#allcomponents}}
<option value="{{component}}">{{name}}</option>
<option value="{{component}}" {{#selected}}selected{{/selected}}>{{name}}</option>
{{/allcomponents}}
</select>
</div>
@@ -47,7 +47,7 @@
<div class="control-group">
<label for="search" class="control-label">{{#str}}search, tool_templatelibrary{{/str}}</label>
<div class="controls">
<input type="text" id="search" data-field="search"/>
<input type="text" id="search" name="search" value="{{ search }}" data-field="search"/>
</div>
</div>
</form>
+14 -19
View File
@@ -902,36 +902,31 @@ class tool_uploadcourse_course {
unset($method['delete']);
unset($method['disable']);
if (!empty($instance) && $todelete) {
if ($todelete) {
// Remove the enrolment method.
foreach ($instances as $instance) {
if ($instance->enrol == $enrolmethod) {
$plugin = $enrolmentplugins[$instance->enrol];
$plugin->delete_instance($instance);
break;
}
if ($instance) {
$plugin = $enrolmentplugins[$instance->enrol];
$plugin->delete_instance($instance);
}
} else if (!empty($instance) && $todisable) {
// Disable the enrolment.
foreach ($instances as $instance) {
if ($instance->enrol == $enrolmethod) {
$plugin = $enrolmentplugins[$instance->enrol];
$plugin->update_status($instance, ENROL_INSTANCE_DISABLED);
$enrol_updated = true;
break;
}
}
$plugin = $enrolmentplugins[$instance->enrol];
$plugin->update_status($instance, ENROL_INSTANCE_DISABLED);
$enrol_updated = true;
} else {
$plugin = null;
$status = ($todisable) ? ENROL_INSTANCE_DISABLED : ENROL_INSTANCE_ENABLED;
if (empty($instance)) {
$plugin = $enrolmentplugins[$enrolmethod];
$instance = new stdClass();
$instance->id = $plugin->add_default_instance($course);
$instanceid = $plugin->add_default_instance($course);
$instance = $DB->get_record('enrol', ['id' => $instanceid]);
$instance->roleid = $plugin->get_config('roleid');
$instance->status = ENROL_INSTANCE_ENABLED;
$plugin->update_status($instance, $status);
} else {
$plugin = $enrolmentplugins[$instance->enrol];
$plugin->update_status($instance, ENROL_INSTANCE_ENABLED);
$plugin->update_status($instance, $status);
}
// Now update values.
@@ -0,0 +1,114 @@
@tool @tool_uploadcourse @_file_upload
Feature: An admin can update courses enrolments using a CSV file
In order to update courses enrolments using a CSV file
As an admin
I need to be able to upload a CSV file with enrolment methods for the courses
Background:
Given the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And I log in as "admin"
@javascript
Scenario: Creating enrolment method by enable it
Given I am on "Course 1" course homepage
And I navigate to "Users > Enrolment methods" in current page administration
And I click on "Delete" "link" in the "Guest access" "table_row"
And I click on "Continue" "button"
And I should not see "Guest access" in the "generaltable" "table"
And I navigate to "Courses > Upload courses" in site administration
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_enable.csv" file to "File" filemanager
And I set the field "Upload mode" to "Only update existing courses"
And I set the field "Update mode" to "Update with CSV data only"
And I set the field "Allow deletes" to "Yes"
And I click on "Preview" "button"
When I click on "Upload courses" "button"
Then I should see "Course updated"
And I am on "Course 1" course homepage
And I navigate to "Users > Enrolment methods" in current page administration
And "Disable" "icon" should exist in the "Guest access" "table_row"
@javascript
Scenario: Creating enrolment method by disabling it
Given I am on "Course 1" course homepage
And I navigate to "Users > Enrolment methods" in current page administration
And I click on "Delete" "link" in the "Guest access" "table_row"
And I click on "Continue" "button"
And I should not see "Guest access" in the "generaltable" "table"
And I navigate to "Courses > Upload courses" in site administration
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_disable.csv" file to "File" filemanager
And I set the field "Upload mode" to "Only update existing courses"
And I set the field "Update mode" to "Update with CSV data only"
And I set the field "Allow deletes" to "Yes"
And I click on "Preview" "button"
When I click on "Upload courses" "button"
Then I should see "Course updated"
And I am on "Course 1" course homepage
And I navigate to "Users > Enrolment methods" in current page administration
And "Enable" "icon" should exist in the "Guest access" "table_row"
@javascript
Scenario: Enabling enrolment method
Given I navigate to "Courses > Upload courses" in site administration
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_enable.csv" file to "File" filemanager
And I set the field "Upload mode" to "Only update existing courses"
And I set the field "Update mode" to "Update with CSV data only"
And I set the field "Allow deletes" to "Yes"
And I click on "Preview" "button"
When I click on "Upload courses" "button"
Then I should see "Course updated"
And I am on "Course 1" course homepage
And I navigate to "Users > Enrolment methods" in current page administration
And "Disable" "icon" should exist in the "Guest access" "table_row"
@javascript
Scenario: Disable an enrolment method
Given I am on "Course 1" course homepage
And I navigate to "Users > Enrolment methods" in current page administration
And I click on "Enable" "link" in the "Guest access" "table_row"
And "Disable" "icon" should exist in the "Guest access" "table_row"
And I navigate to "Courses > Upload courses" in site administration
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_disable.csv" file to "File" filemanager
And I set the field "Upload mode" to "Only update existing courses"
And I set the field "Update mode" to "Update with CSV data only"
And I set the field "Allow deletes" to "Yes"
And I click on "Preview" "button"
When I click on "Upload courses" "button"
Then I should see "Course updated"
And I am on "Course 1" course homepage
And I navigate to "Users > Enrolment methods" in current page administration
And "Enable" "icon" should exist in the "Guest access" "table_row"
@javascript
Scenario: Delete an enrolment method
Given I navigate to "Courses > Upload courses" in site administration
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_delete.csv" file to "File" filemanager
And I set the field "Upload mode" to "Only update existing courses"
And I set the field "Update mode" to "Update with CSV data only"
And I set the field "Allow deletes" to "Yes"
And I click on "Preview" "button"
When I click on "Upload courses" "button"
Then I should see "Course updated"
And I am on "Course 1" course homepage
And I navigate to "Users > Enrolment methods" in current page administration
And I should not see "Guest access" in the "generaltable" "table"
@javascript
Scenario: Delete an unexistent enrolment method (nothing should change)
Given I am on "Course 1" course homepage
And I navigate to "Users > Enrolment methods" in current page administration
And I click on "Delete" "link" in the "Guest access" "table_row"
And I click on "Continue" "button"
And I should not see "Guest access" in the "generaltable" "table"
And I navigate to "Courses > Upload courses" in site administration
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_delete.csv" file to "File" filemanager
And I set the field "Upload mode" to "Only update existing courses"
And I set the field "Update mode" to "Update with CSV data only"
And I set the field "Allow deletes" to "Yes"
And I click on "Preview" "button"
When I click on "Upload courses" "button"
Then I should see "Course updated"
And I am on "Course 1" course homepage
And I navigate to "Users > Enrolment methods" in current page administration
And I should not see "Guest access" in the "generaltable" "table"
@@ -0,0 +1,2 @@
shortname,category,enrolment_1,enrolment_1_delete
C1,1,guest,1
1 shortname category enrolment_1 enrolment_1_delete
2 C1 1 guest 1
@@ -0,0 +1,2 @@
shortname,category,enrolment_1,enrolment_1_disable
C1,1,guest,1
1 shortname category enrolment_1 enrolment_1_disable
2 C1 1 guest 1
@@ -0,0 +1,2 @@
shortname,category,enrolment_1,enrolment_1_disable
C1,1,guest,0
1 shortname category enrolment_1 enrolment_1_disable
2 C1 1 guest 0
@@ -47,7 +47,7 @@ class provider implements
/**
* Returns meta data about this system.
*
* @param collection $itemcollection The initialised item collection to add items to.
* @param collection $items The initialised item collection to add items to.
* @return collection A listing of user data stored through this system.
*/
public static function get_metadata(collection $items) : collection {
@@ -64,7 +64,7 @@ class provider implements
* @param int $userid The userid of the user whose data is to be exported.
*/
public static function export_user_preferences(int $userid) {
$preferences = get_user_preferences();
$preferences = get_user_preferences(null, null, $userid);
foreach ($preferences as $name => $value) {
$descriptionidentifier = null;
$tourid = null;
+14 -5
View File
@@ -557,9 +557,10 @@ class tour {
// Remove the configuration for the tour.
$DB->delete_records('tool_usertours_tours', array('id' => $this->id));
helper::reset_tour_sortorder();
$this->remove_user_preferences();
return null;
}
@@ -585,6 +586,16 @@ class tour {
return $this;
}
/**
* Remove stored user preferences for the tour
*/
protected function remove_user_preferences(): void {
global $DB;
$DB->delete_records('user_preferences', ['name' => self::TOUR_LAST_COMPLETED_BY_USER . $this->get_id()]);
$DB->delete_records('user_preferences', ['name' => self::TOUR_REQUESTED_BY_USER . $this->get_id()]);
}
/**
* Whether this tour should be displayed to the user.
*
@@ -665,11 +676,9 @@ class tour {
* @return $this
*/
public function mark_major_change() {
global $DB;
// Clear old reset and completion notes.
$DB->delete_records('user_preferences', ['name' => self::TOUR_LAST_COMPLETED_BY_USER . $this->get_id()]);
$DB->delete_records('user_preferences', ['name' => self::TOUR_REQUESTED_BY_USER . $this->get_id()]);
$this->remove_user_preferences();
$this->set_config('majorupdatetime', time());
$this->persist();
+22
View File
@@ -25,6 +25,7 @@
defined('MOODLE_INTERNAL') || die();
use tool_usertours\manager;
use tool_usertours\tour;
/**
* Upgrade the user tours plugin.
@@ -57,5 +58,26 @@ function xmldb_tool_usertours_upgrade($oldversion) {
// Automatically generated Moodle v3.9.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2020061502) {
// Clean up user preferences of deleted tours.
$select = $DB->sql_like('name', ':lastcompleted') . ' OR ' . $DB->sql_like('name', ':requested');
$params = [
'lastcompleted' => tour::TOUR_LAST_COMPLETED_BY_USER . '%',
'requested' => tour::TOUR_REQUESTED_BY_USER . '%',
];
$preferences = $DB->get_records_select('user_preferences', $select, $params, '', 'DISTINCT name');
foreach ($preferences as $preference) {
// Match tour ID at the end of the preference name, remove all of that preference type if tour ID doesn't exist.
if (preg_match('/(?<tourid>\d+)$/', $preference->name, $matches) &&
!$DB->record_exists('tool_usertours_tours', ['id' => $matches['tourid']])) {
$DB->delete_records('user_preferences', ['name' => $preference->name]);
}
}
upgrade_plugin_savepoint(true, 2020061502, 'tool', 'usertours');
}
return true;
}
@@ -15,9 +15,9 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Unit tests for the block_html implementation of the privacy API.
* Unit tests for the tool_usertours implementation of the privacy API.
*
* @package block_html
* @package tool_usertours
* @category test
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -27,19 +27,22 @@ defined('MOODLE_INTERNAL') || die();
use \core_privacy\local\metadata\collection;
use \core_privacy\local\request\writer;
use \core_privacy\local\request\approved_contextlist;
use \core_privacy\local\request\deletion_criteria;
use \tool_usertours\tour;
use \tool_usertours\privacy\provider;
/**
* Unit tests for the block_html implementation of the privacy API.
* Unit tests for the tool_usertours implementation of the privacy API.
*
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_usertours_privacy_testcase extends \core_privacy\tests\provider_testcase {
class tool_usertours_privacy_provider_testcase extends \core_privacy\tests\provider_testcase {
/**
* Helper method for creating a tour
*
* @return tour
*/
protected function create_test_tour(): tour {
return (new tour())
->set_name('test_tour')
@@ -118,6 +121,37 @@ class tool_usertours_privacy_testcase extends \core_privacy\tests\provider_testc
$this->assertCount(2, (array) $prefs);
}
/**
* Make sure we are exporting preferences for the correct user
*/
public function test_export_user_preferences_correct_user(): void {
$this->resetAfterTest();
$tour = $this->create_test_tour();
// Create test user, mark them as having completed the tour.
$user = $this->getDataGenerator()->create_user();
$this->setUser($user);
$tour->mark_user_completed();
// Switch to admin user, mark them as having reset the tour.
$this->setAdminUser();
$tour->request_user_reset();
// Export test users preferences.
provider::export_user_preferences($user->id);
$writer = writer::with_context(\context_system::instance());
$this->assertTrue($writer->has_any_data());
$prefs = $writer->get_user_preferences('tool_usertours');
$this->assertCount(1, (array) $prefs);
// We should have received back the "completed tour" preference of the test user.
$this->assertStringStartsWith('You last marked the "' . $tour->get_name() . '" user tour as completed on',
reset($prefs)->description);
}
/**
* Ensure that export_user_preferences excludes deleted tours.
*/
+8 -3
View File
@@ -64,7 +64,7 @@ class tour_testcase extends advanced_testcase {
/**
* Helper to mock the database.
*
* @return moodle_database
* @return \PHPUnit\Framework\MockObject\MockObject
*/
public function mock_database() {
global $DB;
@@ -569,9 +569,14 @@ class tour_testcase extends advanced_testcase {
// Mock the database.
$DB = $this->mock_database();
$DB->expects($this->once())
$DB->expects($this->exactly(3))
->method('delete_records')
->with($this->equalTo('tool_usertours_tours'), $this->equalTo(['id' => $id]))
->withConsecutive(
[$this->equalTo('tool_usertours_tours'), $this->equalTo(['id' => $id])],
[$this->equalTo('user_preferences'), $this->equalTo(['name' => tour::TOUR_LAST_COMPLETED_BY_USER . $id])],
[$this->equalTo('user_preferences'), $this->equalTo(['name' => tour::TOUR_REQUESTED_BY_USER . $id])]
)
->willReturn(null)
;
+1 -1
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2020061501; // The current module version (Date: YYYYMMDDXX).
$plugin->version = 2020061502; // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2020060900; // Requires this Moodle version.
$plugin->component = 'tool_usertours'; // Full name of the plugin (used for diagnostics).
@@ -149,7 +149,7 @@ abstract class XMLDBCheckAction extends XMLDBAction {
continue;
}
// Fetch metadata from physical DB. All the columns info.
if (!$metacolumns = $DB->get_columns($xmldb_table->getName())) {
if (!$metacolumns = $DB->get_columns($xmldb_table->getName(), false)) {
// / Skip table if no metacolumns is available for it
continue;
}
+12 -3
View File
@@ -1492,6 +1492,17 @@ class model {
$prediction->get_prediction_data()->contextid, $prediction->get_sample_data());
}
/**
* Returns the default output directory for prediction processors
*
* @return string
*/
public static function default_output_dir(): string {
global $CFG;
return $CFG->dataroot . DIRECTORY_SEPARATOR . 'models';
}
/**
* Returns the output directory for prediction processors.
*
@@ -1506,8 +1517,6 @@ class model {
* @return string
*/
public function get_output_dir($subdirs = array(), $onlymodelid = false) {
global $CFG;
$subdirstr = '';
foreach ($subdirs as $subdir) {
$subdirstr .= DIRECTORY_SEPARATOR . $subdir;
@@ -1516,7 +1525,7 @@ class model {
$outputdir = get_config('analytics', 'modeloutputdir');
if (empty($outputdir)) {
// Apply default value.
$outputdir = rtrim($CFG->dataroot, '/') . DIRECTORY_SEPARATOR . 'models';
$outputdir = self::default_output_dir();
}
// Append model id.
+1 -4
View File
@@ -55,10 +55,7 @@ Feature: Manage analytics models
And I choose "Create model" in the open action menu
And I set the field "Enabled" to "Enable"
And I select "__core_course__analytics__target__course_completion" from the "target" singleselect
And I open the autocomplete suggestions list
And I click on "Read actions amount" item in the autocomplete list
And I open the autocomplete suggestions list
And I click on "Any write action in the course" item in the autocomplete list
And I set the field "Indicators" to "Read actions amount, Any write action in the course"
And I select "__core__analytics__time_splitting__single_range" from the "timesplitting" singleselect
And I press "Save changes"
Then I should see "No predictions available yet" in the "Students at risk of not meeting the course completion conditions" "table_row"
+3 -1
View File
@@ -462,7 +462,7 @@ class auth_plugin_db extends auth_plugin_base {
continue;
}
try {
$id = user_create_user($user, false); // It is truly a new user.
$id = user_create_user($user, false, false); // It is truly a new user.
$trace->output(get_string('auth_dbinsertuser', 'auth_db', array('name'=>$user->username, 'id'=>$id)), 1);
} catch (moodle_exception $e) {
$trace->output(get_string('auth_dbinsertusererror', 'auth_db', $user->username), 1);
@@ -481,6 +481,8 @@ class auth_plugin_db extends auth_plugin_base {
// Make sure user context is present.
context_user::instance($id);
\core\event\user_created::create_from_userid($id)->trigger();
}
unset($add_users);
}
+29 -2
View File
@@ -119,6 +119,7 @@ class auth_db_testcase extends advanced_testcase {
$table->add_field('email', XMLDB_TYPE_CHAR, '255', null, null, null);
$table->add_field('firstname', XMLDB_TYPE_CHAR, '255', null, null, null);
$table->add_field('lastname', XMLDB_TYPE_CHAR, '255', null, null, null);
$table->add_field('animal', XMLDB_TYPE_CHAR, '255', null, null, null);
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
if ($dbman->table_exists($table)) {
$dbman->drop_table($table);
@@ -137,6 +138,15 @@ class auth_db_testcase extends advanced_testcase {
set_config('field_updateremote_email', '0', 'auth_db');
set_config('field_lock_email', 'unlocked', 'auth_db');
// Create a user profile field and add mapping to it.
$DB->insert_record('user_info_field', ['shortname' => 'pet', 'name' => 'Pet', 'required' => 0,
'visible' => 1, 'locked' => 0, 'categoryid' => 1, 'datatype' => 'text']);
set_config('field_map_profile_field_pet', 'animal', 'auth_db');
set_config('field_updatelocal_profile_field_pet', 'oncreate', 'auth_db');
set_config('field_updateremote_profile_field_pet', '0', 'auth_db');
set_config('field_lock_profile_field_pet', 'unlocked', 'auth_db');
// Init the rest of settings.
set_config('passtype', 'plaintext', 'auth_db');
set_config('changepasswordurl', '', 'auth_db');
@@ -156,6 +166,7 @@ class auth_db_testcase extends advanced_testcase {
public function test_plugin() {
global $DB, $CFG;
require_once($CFG->dirroot . '/user/profile/lib.php');
$this->resetAfterTest(true);
@@ -193,7 +204,7 @@ class auth_db_testcase extends advanced_testcase {
// Test bulk user account creation.
$user2 = (object)array('name'=>'u2', 'pass'=>'heslo', 'email'=>'u2@example.com');
$user2 = (object)['name' => 'u2', 'pass' => 'heslo', 'email' => 'u2@example.com', 'animal' => 'cat'];
$user2->id = $DB->insert_record('auth_db_users', $user2);
$user3 = (object)array('name'=>'admin', 'pass'=>'heslo', 'email'=>'admin@example.com'); // Should be skipped.
@@ -202,13 +213,24 @@ class auth_db_testcase extends advanced_testcase {
$this->assertCount(2, $DB->get_records('user'));
$trace = new null_progress_trace();
$auth->sync_users($trace, false);
// Sync users and make sure that two events user_created werer triggered.
$sink = $this->redirectEvents();
$auth->sync_users($trace, false);
$events = $sink->get_events();
$sink->close();
$this->assertCount(2, $events);
$this->assertTrue($events[0] instanceof \core\event\user_created);
$this->assertTrue($events[1] instanceof \core\event\user_created);
// Assert the two users were created.
$this->assertEquals(4, $DB->count_records('user'));
$u1 = $DB->get_record('user', array('username'=>$user1->name, 'auth'=>'db'));
$this->assertSame($user1->email, $u1->email);
$this->assertEmpty(profile_user_record($u1->id)->pet);
$u2 = $DB->get_record('user', array('username'=>$user2->name, 'auth'=>'db'));
$this->assertSame($user2->email, $u2->email);
$this->assertSame($user2->animal, profile_user_record($u2->id)->pet);
$admin = $DB->get_record('user', array('username'=>'admin', 'auth'=>'manual'));
$this->assertNotEmpty($admin);
@@ -217,12 +239,14 @@ class auth_db_testcase extends advanced_testcase {
$user2b = clone($user2);
$user2b->email = 'u2b@example.com';
$user2b->animal = 'dog';
$DB->update_record('auth_db_users', $user2b);
$auth->sync_users($trace, false);
$this->assertEquals(4, $DB->count_records('user'));
$u2 = $DB->get_record('user', array('username'=>$user2->name));
$this->assertSame($user2->email, $u2->email);
$this->assertSame($user2->animal, profile_user_record($u2->id)->pet);
$auth->sync_users($trace, true);
$this->assertEquals(4, $DB->count_records('user'));
@@ -231,6 +255,8 @@ class auth_db_testcase extends advanced_testcase {
set_config('field_updatelocal_email', 'onlogin', 'auth_db');
$auth->config->field_updatelocal_email = 'onlogin';
set_config('field_updatelocal_profile_field_pet', 'onlogin', 'auth_db');
$auth->config->field_updatelocal_profile_field_pet = 'onlogin';
$auth->sync_users($trace, false);
$this->assertEquals(4, $DB->count_records('user'));
@@ -241,6 +267,7 @@ class auth_db_testcase extends advanced_testcase {
$this->assertEquals(4, $DB->count_records('user'));
$u2 = $DB->get_record('user', array('username'=>$user2->name));
$this->assertSame($user2b->email, $u2->email);
$this->assertSame($user2b->animal, profile_user_record($u2->id)->pet);
// Test sync deletes and suspends.
+2 -2
View File
@@ -147,12 +147,12 @@ class auth_email_external extends external_api {
array(
'id' => new external_value(PARAM_INT, 'Profile field id', VALUE_OPTIONAL),
'shortname' => new external_value(PARAM_ALPHANUMEXT, 'Profile field shortname', VALUE_OPTIONAL),
'name' => new external_value(PARAM_TEXT, 'Profield field name', VALUE_OPTIONAL),
'name' => new external_value(PARAM_RAW, 'Profield field name', VALUE_OPTIONAL),
'datatype' => new external_value(PARAM_ALPHANUMEXT, 'Profield field datatype', VALUE_OPTIONAL),
'description' => new external_value(PARAM_RAW, 'Profield field description', VALUE_OPTIONAL),
'descriptionformat' => new external_format_value('description'),
'categoryid' => new external_value(PARAM_INT, 'Profield field category id', VALUE_OPTIONAL),
'categoryname' => new external_value(PARAM_TEXT, 'Profield field category name', VALUE_OPTIONAL),
'categoryname' => new external_value(PARAM_RAW, 'Profield field category name', VALUE_OPTIONAL),
'sortorder' => new external_value(PARAM_INT, 'Profield field sort order', VALUE_OPTIONAL),
'required' => new external_value(PARAM_INT, 'Profield field required', VALUE_OPTIONAL),
'locked' => new external_value(PARAM_INT, 'Profield field locked', VALUE_OPTIONAL),
+45
View File
@@ -93,6 +93,51 @@ class auth_email_external_testcase extends externallib_advanced_testcase {
$this->assertEquals('textarea', $namedarray['sometext']['datatype']);
}
/**
* Test get_signup_settings with mathjax in a profile field.
*/
public function test_get_signup_settings_with_mathjax_in_profile_fields() {
global $CFG, $DB;
require_once($CFG->dirroot . '/lib/externallib.php');
// Enable MathJax filter in content and headings.
$this->configure_filters([
['name' => 'mathjaxloader', 'state' => TEXTFILTER_ON, 'move' => -1, 'applytostrings' => true],
]);
// Create category with MathJax and a new field with MathJax.
$categoryname = 'Cat $$(a+b)=2$$';
$fieldname = 'Some text $$(a+b)=2$$';
$categoryid = $DB->insert_record('user_info_category', array('name' => $categoryname, 'sortorder' => 1));
$field3 = $DB->insert_record('user_info_field', array(
'shortname' => 'mathjaxname', 'name' => $fieldname, 'categoryid' => $categoryid,
'datatype' => 'textarea', 'signup' => 1, 'visible' => 1, 'required' => 1, 'sortorder' => 2));
$result = auth_email_external::get_signup_settings();
$result = external_api::clean_returnvalue(auth_email_external::get_signup_settings_returns(), $result);
// Format the original data.
$sitecontext = context_system::instance();
$categoryname = external_format_string($categoryname, $sitecontext->id);
$fieldname = external_format_string($fieldname, $sitecontext->id);
// Whip up a array with named entries to easily check against.
$namedarray = array();
foreach ($result['profilefields'] as $key => $value) {
$namedarray[$value['shortname']] = $value;
}
// Check the new profile field.
$this->assertArrayHasKey('mathjaxname', $namedarray);
$this->assertStringContainsString('<span class="filter_mathjaxloader_equation">',
$namedarray['mathjaxname']['categoryname']);
$this->assertStringContainsString('<span class="filter_mathjaxloader_equation">',
$namedarray['mathjaxname']['name']);
$this->assertEquals($categoryname, $namedarray['mathjaxname']['categoryname']);
$this->assertEquals($fieldname, $namedarray['mathjaxname']['name']);
}
public function test_signup_user() {
global $DB;
+3
View File
@@ -27,6 +27,9 @@ require_once('../../config.php');
$issuerid = required_param('id', PARAM_INT);
$wantsurl = new moodle_url(optional_param('wantsurl', '', PARAM_URL));
$PAGE->set_context(context_system::instance());
$PAGE->set_url(new moodle_url('/auth/oauth2/login.php', ['id' => $issuerid]));
require_sesskey();
if (!\auth_oauth2\api::is_enabled()) {
+2 -1
View File
@@ -182,7 +182,8 @@ How to customize the way the Shibboleth user data is used in Moodle
Among the Shibboleth settings in Moodle there is a field that should contain a
path to a php file that can be used as data manipulation hook.
You can use this if you want to further process the way your Shibboleth
attributes are used in Moodle.
attributes are used in Moodle. Due to security reasons this file cannot be
located within the current site data directory ($CFG->dataroot).
Example 1: Your Shibboleth federation uses an attribute that specifies the
user's preferred language, but the content of this attribute is not
@@ -0,0 +1,75 @@
<?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/>.
/**
* Special setting for auth_shibboleth convert_data.
*
* @package auth_shibboleth
* @copyright 2020 Mihail Geshoski
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Admin settings class for the convert_data option.
*
* @package auth_shibboleth
* @copyright 2020 Mihail Geshoski
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class auth_shibboleth_admin_setting_convert_data extends admin_setting_configfile {
/**
* Constructor.
*
* @param string $name
* @param string $visiblename
* @param string $description
* @param mixed $defaultdirectory
*/
public function __construct($name, $visiblename, $description, $defaultdirectory) {
parent::__construct($name, $visiblename, $description, $defaultdirectory);
}
/**
* Validate the file path (location).
*
* This method ensures that the file defined as a data modification API exists and is not located in the site
* data directory ($CFG->dataroot). We should prohibit using files from the site data directory as this introduces
* security vulnerabilities.
*
* @param string $filepath The path to the file.
* @return mixed bool true for success or string:error on failure.
*/
public function validate($filepath) {
global $CFG;
if (empty($filepath)) {
return true;
}
// Fail if the file does not exist or it is not readable by the webserver process.
if (!is_readable($filepath)) {
return get_string('auth_shib_convert_data_warning', 'auth_shibboleth');
}
// Fail if the absolute file path matches the currently defined dataroot path.
if (preg_match('/' . preg_quote($CFG->dataroot, '/') . '/', realpath($filepath))) {
return get_string('auth_shib_convert_data_filepath_warning', 'auth_shibboleth');
}
return true;
}
}
+23 -1
View File
@@ -30,7 +30,7 @@ defined('MOODLE_INTERNAL') || die();
* @return bool result
*/
function xmldb_auth_shibboleth_upgrade($oldversion) {
global $CFG, $DB;
global $CFG, $DB, $OUTPUT;
// Automatically generated Moodle v3.5.0 release upgrade line.
// Put any upgrade step following this.
@@ -47,5 +47,27 @@ function xmldb_auth_shibboleth_upgrade($oldversion) {
// Automatically generated Moodle v3.9.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2020061501) {
// The 'Data modification API' setting in the Shibboleth authentication plugin can no longer be configured
// to use files located within the site data directory, as it exposes the site to security risks. Therefore,
// we need to find every existing case and reset the 'Data modification API' setting to its default value.
$convertdataconfig = get_config('auth_shibboleth', 'convert_data');
if (preg_match('/' . preg_quote($CFG->dataroot, '/') . '/', realpath($convertdataconfig))) {
set_config('convert_data', '', 'auth_shibboleth');
$warn = 'Your \'Data modification API\' setting in the Shibboleth authentication plugin is currently
configured to use a file located within the current site data directory ($CFG->dataroot). You are no
longer able to use files from within this directory for this purpose as it exposes your site to security
risks. This setting has been reset to its default value. Please reconfigure it by providing a path
to a file which is not located within the site data directory.';
echo $OUTPUT->notification($warn, 'notifyproblem');
}
upgrade_plugin_savepoint(true, 2020061501, 'auth', 'shibboleth');
}
return true;
}
@@ -38,6 +38,7 @@ $string['auth_shibboleth_select_organization'] = 'For authentication via Shibbol
$string['auth_shib_convert_data'] = 'Data modification API';
$string['auth_shib_convert_data_description'] = 'You can use this API to further modify the data provided by Shibboleth. Read the <a href="{$a}">README</a> for further instructions.';
$string['auth_shib_convert_data_warning'] = 'The file does not exist or is not readable by the webserver process!';
$string['auth_shib_convert_data_filepath_warning'] = 'You cannot use a file that is located within the current site data directory ($CFG->dataroot) as the data modification API.';
$string['auth_shib_changepasswordurl'] = 'Password-change URL';
$string['auth_shib_idp_list'] = 'Identity providers';
$string['auth_shib_idp_list_description'] = 'Provide a list of Identity Provider entityIDs to let the user choose from on the login page.<br />On each line there must be a comma-separated tuple for entityID of the IdP (see the Shibboleth metadata file) and Name of IdP as it shall be displayed in the drop-down list.<br />As an optional third parameter you can add the location of a Shibboleth session initiator that shall be used in case your Moodle installation is part of a multi federation setup.';
+3 -2
View File
@@ -28,6 +28,7 @@ if ($ADMIN->fulltree) {
// We use a couple of custom admin settings since we need to massage the data before it is inserted into the DB.
require_once($CFG->dirroot.'/auth/shibboleth/classes/admin_setting_special_wayf_select.php');
require_once($CFG->dirroot.'/auth/shibboleth/classes/admin_setting_special_idp_configtextarea.php');
require_once($CFG->dirroot.'/auth/shibboleth/classes/admin_setting_special_convert_data_configfile.php');
// Introductory explanation.
$readmeurl = (new moodle_url('/auth/shibboleth/README.txt'))->out();
@@ -38,8 +39,8 @@ if ($ADMIN->fulltree) {
$settings->add(new admin_setting_configtext('auth_shibboleth/user_attribute', get_string('username'),
get_string('auth_shib_username_description', 'auth_shibboleth'), '', PARAM_RAW));
// COnvert Data configuration file.
$settings->add(new admin_setting_configfile('auth_shibboleth/convert_data',
// Convert Data configuration file.
$settings->add(new auth_shibboleth_admin_setting_convert_data('auth_shibboleth/convert_data',
get_string('auth_shib_convert_data', 'auth_shibboleth'),
get_string('auth_shib_convert_data_description', 'auth_shibboleth', $readmeurl), ''));
+5
View File
@@ -1,6 +1,11 @@
This files describes API changes in /auth/shibboleth/*,
information provided here is intended especially for developers.
=== 3.9.4 ===
* The 'Data modification API' (convert_data) setting can no longer be configured to use files located within the
current site data directory ($CFG->dataroot), as it exposes the site to security risks.
=== 3.5.2 ===
* Moved the public function unserializesession in auth/shibboleth/logout.php to auth/shibboleth/classes/helper.php and
+1 -1
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->version = 2020061501; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2020060900; // Requires this Moodle version
$plugin->component = 'auth_shibboleth'; // Full name of the plugin (used for diagnostics)
+1 -1
View File
@@ -794,7 +794,7 @@ class cc2moodle {
}
}
protected function critical_error ($text) {
protected static function critical_error ($text) {
$path_to_log = static::log_file();
+1 -1
View File
@@ -76,7 +76,7 @@ class entities {
cc2moodle::log_action('Load the XML resource file: '.$path_to_file);
if (!$resource->load($path_to_file)) {
cc2moodle::log_action('Cannot load the XML resource file: ' . $path_to_file, true);
cc2moodle::log_action('Cannot load the XML resource file: ' . $path_to_file, false);
}
return $resource;
@@ -369,6 +369,7 @@ class restore_controller extends base_controller {
$options = array();
$options['keep_roles_and_enrolments'] = $this->get_setting_value('keep_roles_and_enrolments');
$options['keep_groups_and_groupings'] = $this->get_setting_value('keep_groups_and_groupings');
$options['userid'] = $this->userid;
restore_dbops::delete_course_content($this->get_courseid(), $options);
}
// If this is not a course restore or single activity restore (e.g. duplicate), inform the plan we are not
@@ -272,7 +272,7 @@ abstract class backup_activity_task extends backup_task {
$settingname = $settingprefix . 'included';
$activity_included = new backup_activity_generic_setting($settingname, base_setting::IS_BOOLEAN, true);
$activity_included->get_ui()->set_icon(new image_icon('icon', get_string('pluginname', $this->modulename),
$this->modulename, array('class' => 'iconlarge icon-post')));
$this->modulename, array('class' => 'iconlarge icon-post ml-1')));
$this->add_setting($activity_included);
// Look for "activities" root setting
$activities = $this->plan->get_setting('activities');
@@ -297,7 +297,7 @@ abstract class restore_activity_task extends restore_task {
$settingname = $settingprefix . 'included';
$activity_included = new restore_activity_generic_setting($settingname, base_setting::IS_BOOLEAN, true);
$activity_included->get_ui()->set_icon(new image_icon('icon', get_string('pluginname', $this->modulename),
$this->modulename, array('class' => 'iconlarge icon-post')));
$this->modulename, array('class' => 'iconlarge icon-post ml-1')));
$this->add_setting($activity_included);
// Look for "activities" root setting
$activities = $this->plan->get_setting('activities');
+53 -9
View File
@@ -2112,14 +2112,29 @@ class restore_ras_and_caps_structure_step extends restore_structure_step {
$data = (object)$data;
// Check roleid is one of the mapped ones
$newroleid = $this->get_mappingid('role', $data->roleid);
$newrole = $this->get_mapping('role', $data->roleid);
$newroleid = $newrole->newitemid ?? false;
$userid = $this->task->get_userid();
// If newroleid and context are valid assign it via API (it handles dupes and so on)
if ($newroleid && $this->task->get_contextid()) {
if (!get_capability_info($data->capability)) {
if (!$capability = get_capability_info($data->capability)) {
$this->log("Capability '{$data->capability}' was not found!", backup::LOG_WARNING);
} else {
// TODO: assign_capability() needs one userid param to be able to specify our restore userid.
assign_capability($data->capability, $data->permission, $newroleid, $this->task->get_contextid());
$context = context::instance_by_id($this->task->get_contextid());
$overrideableroles = get_overridable_roles($context, ROLENAME_SHORT);
$safecapability = is_safe_capability($capability);
// Check if the new role is an overrideable role AND if the user performing the restore has the
// capability to assign the capability.
if (in_array($newrole->info['shortname'], $overrideableroles) &&
($safecapability && has_capability('moodle/role:safeoverride', $context, $userid) ||
!$safecapability && has_capability('moodle/role:override', $context, $userid))
) {
assign_capability($data->capability, $data->permission, $newroleid, $this->task->get_contextid());
} else {
$this->log("Insufficient capability to assign capability '{$data->capability}' to role!", backup::LOG_WARNING);
}
}
}
}
@@ -2139,11 +2154,22 @@ class restore_default_enrolments_step extends restore_execution_step {
}
$course = $DB->get_record('course', array('id'=>$this->get_courseid()), '*', MUST_EXIST);
// Return any existing course enrolment instances.
$enrolinstances = enrol_get_instances($course->id, false);
if ($enrolinstances) {
// Something already added instances.
// Get the existing enrolment methods in the course.
$enrolmethods = array_map(function($enrolinstance) {
return $enrolinstance->enrol;
}, $enrolinstances);
if ($DB->record_exists('enrol', array('courseid'=>$this->get_courseid(), 'enrol'=>'manual'))) {
// Something already added instances, do not add default instances.
$plugins = enrol_get_plugins(true);
foreach ($plugins as $plugin) {
foreach ($plugins as $pluginname => $plugin) {
// Make sure all default enrolment methods exist in the course.
if (!in_array($pluginname, $enrolmethods)) {
$plugin->course_updated(true, $course, null);
}
$plugin->restore_sync_course($course);
}
@@ -4702,10 +4728,28 @@ class restore_create_categories_and_questions extends restore_structure_step {
}
$userid = $this->get_mappingid('user', $data->createdby);
$data->createdby = $userid ? $userid : $this->task->get_userid();
if ($userid) {
// The question creator is included in the backup, so we can use their mapping id.
$data->createdby = $userid;
} else {
// Leave the question creator unchanged when we are restoring the same site.
// Otherwise use current user id.
if (!$this->task->is_samesite()) {
$data->createdby = $this->task->get_userid();
}
}
$userid = $this->get_mappingid('user', $data->modifiedby);
$data->modifiedby = $userid ? $userid : $this->task->get_userid();
if ($userid) {
// The question modifier is included in the backup, so we can use their mapping id.
$data->modifiedby = $userid;
} else {
// Leave the question modifier unchanged when we are restoring the same site.
// Otherwise use current user id.
if (!$this->task->is_samesite()) {
$data->modifiedby = $this->task->get_userid();
}
}
// With newitemid = 0, let's create the question
if (!$questionmapping->newitemid) {
@@ -82,16 +82,17 @@ class restore_quiz_decode_testcase extends \core_privacy\tests\provider_testcase
$newcm = duplicate_module($course, get_fast_modinfo($course)->get_cm($quiz->cmid));
$sql = "SELECT qa.answer
$sql = "SELECT qa.id, qa.answer
FROM {quiz} q
LEFT JOIN {quiz_slots} qs ON qs.quizid = q.id
LEFT JOIN {question_answers} qa ON qa.question = qs.questionid
WHERE q.id = :quizid";
$params = array('quizid' => $newcm->instance);
$answers = $DB->get_fieldset_sql($sql, $params);
$this->assertEquals($CFG->wwwroot . '/course/view.php?id=' . $course->id, $answers[0]);
$this->assertEquals($CFG->wwwroot . '/mod/quiz/view.php?id=' . $quiz->cmid, $answers[1]);
$this->assertEquals($CFG->wwwroot . '/grade/report/index.php?id=' . $quiz->cmid, $answers[2]);
$this->assertEquals($CFG->wwwroot . '/mod/quiz/index.php?id=' . $quiz->cmid, $answers[3]);
$answers = $DB->get_records_sql_menu($sql, $params);
$this->assertEquals($CFG->wwwroot . '/course/view.php?id=' . $course->id, $answers[$firstanswer->id]);
$this->assertEquals($CFG->wwwroot . '/mod/quiz/view.php?id=' . $quiz->cmid, $answers[$secondanswer->id]);
$this->assertEquals($CFG->wwwroot . '/grade/report/index.php?id=' . $quiz->cmid, $answers[$thirdanswer->id]);
$this->assertEquals($CFG->wwwroot . '/mod/quiz/index.php?id=' . $quiz->cmid, $answers[$fourthanswer->id]);
}
}
+1 -1
View File
@@ -317,7 +317,7 @@ abstract class base_moodleform extends moodleform {
$label = format_string($settingui->get_label($task), true, array('context' => $context));
$labelicon = $settingui->get_icon();
if (!empty($labelicon)) {
$label .= '&nbsp;'.$OUTPUT->render($labelicon);
$label .= $OUTPUT->render($labelicon);
}
$this->_form->addElement('static', 'static_'.$settingui->get_name(), $label, $settingui->get_static_value().$icon);
$this->_form->addElement('html', html_writer::end_tag('div'));
+5 -4
View File
@@ -152,13 +152,14 @@ class copy_form extends \moodleform {
$mform->addHelpButton('relativedatesmodegroup', 'relativedatesmode');
}
// Course id number.
// Course ID number (default to the current course ID number; blank for users who can't change ID numbers).
$mform->addElement('text', 'idnumber', get_string('idnumbercourse'), 'maxlength="100" size="10"');
$mform->setDefault('idnumber', $course->idnumber);
$mform->addHelpButton('idnumber', 'idnumbercourse');
$mform->setType('idnumber', PARAM_RAW);
if (!empty($course->id) and !has_capability('moodle/course:changeidnumber', $coursecontext)) {
if (!has_capability('moodle/course:changeidnumber', $coursecontext)) {
$mform->hardFreeze('idnumber');
$mform->setConstants('idnumber', $course->idnumber);
$mform->setConstant('idnumber', '');
}
// Keep source course user data.
@@ -172,7 +173,7 @@ class copy_form extends \moodleform {
);
if (!has_all_capabilities($requiredcapabilities, $coursecontext)) {
$mform->hardFreeze('userdata');
$mform->setConstants('userdata', 0);
$mform->setConstant('userdata', 0);
}
// Keep manual enrolments.
+73 -33
View File
@@ -126,8 +126,9 @@ class core_backup_renderer extends plugin_renderer_base {
$html = html_writer::start_tag('div', array('class' => 'backup-restore'));
$html .= html_writer::start_tag('div', array('class' => 'backup-section'));
$html .= $this->output->heading(get_string('backupdetails', 'backup'), 2, array('class' => 'header'));
$html .= html_writer::start_tag('div', ['class' => 'backup-section',
'role' => 'table', 'aria-labelledby' => 'backupdetailsheader']);
$html .= $this->output->heading(get_string('backupdetails', 'backup'), 2, 'header', 'backupdetailsheader');
$html .= $this->backup_detail_pair(get_string('backuptype', 'backup'), get_string('backuptype'.$details->type, 'backup'));
$html .= $this->backup_detail_pair(get_string('backupformat', 'backup'), get_string('backupformat'.$details->format, 'backup'));
$html .= $this->backup_detail_pair(get_string('backupmode', 'backup'), get_string('backupmode'.$details->mode, 'backup'));
@@ -153,8 +154,9 @@ class core_backup_renderer extends plugin_renderer_base {
$html .= html_writer::end_tag('div');
$html .= html_writer::start_tag('div', array('class' => 'backup-section settings-section'));
$html .= $this->output->heading(get_string('backupsettings', 'backup'), 2, array('class' => 'header'));
$html .= html_writer::start_tag('div', ['class' => 'backup-section settings-section',
'role' => 'table', 'aria-labelledby' => 'backupsettingsheader']);
$html .= $this->output->heading(get_string('backupsettings', 'backup'), 2, 'header', 'backupsettingsheader');
foreach ($details->root_settings as $label => $value) {
if ($label == 'filename' or $label == 'user_files') {
continue;
@@ -164,8 +166,9 @@ class core_backup_renderer extends plugin_renderer_base {
$html .= html_writer::end_tag('div');
if ($details->type === 'course') {
$html .= html_writer::start_tag('div', array('class' => 'backup-section'));
$html .= $this->output->heading(get_string('backupcoursedetails', 'backup'), 2, array('class' => 'header'));
$html .= html_writer::start_tag('div', ['class' => 'backup-section',
'role' => 'table', 'aria-labelledby' => 'backupcoursedetailsheader']);
$html .= $this->output->heading(get_string('backupcoursedetails', 'backup'), 2, 'header', 'backupcoursedetailsheader');
$html .= $this->backup_detail_pair(get_string('coursetitle', 'backup'), $details->course->title);
$html .= $this->backup_detail_pair(get_string('courseid', 'backup'), $details->course->courseid);
@@ -200,7 +203,7 @@ class core_backup_renderer extends plugin_renderer_base {
$table->data = array();
}
$name = get_string('pluginname', $activity->modulename);
$icon = new image_icon('icon', $name, $activity->modulename, array('class' => 'iconlarge icon-pre'));
$icon = new image_icon('icon', '', $activity->modulename, ['class' => 'iconlarge icon-pre']);
$table->data[] = array(
$this->output->render($icon).$name,
$activity->title,
@@ -424,13 +427,25 @@ class core_backup_renderer extends plugin_renderer_base {
protected function backup_detail_pair($label, $value) {
static $count = 0;
$count ++;
$html = html_writer::start_tag('div', array('class' => 'detail-pair'));
$html .= html_writer::tag('label', $label, array('class' => 'detail-pair-label', 'for' => 'detail-pair-value-'.$count));
$html .= html_writer::tag('div', $value, array('class' => 'detail-pair-value pl-2', 'name' => 'detail-pair-value-'.$count));
$html = html_writer::start_tag('div', ['class' => 'detail-pair', 'role' => 'row']);
$html .= html_writer::tag('div', $label, ['class' => 'detail-pair-label mb-2', 'role' => 'cell']);
$html .= html_writer::tag('div', $value, ['class' => 'detail-pair-value pl-2', 'role' => 'cell']);
$html .= html_writer::end_tag('div');
return $html;
}
/**
* Creates a unique id string by appending an incremental number to the prefix.
*
* @param string $prefix To be used as the left part of the id string.
* @return string
*/
protected function make_unique_id(string $prefix): string {
static $count = 0;
return $prefix . '-' . $count++;
}
/**
* Created a detailed pairing with an input
*
@@ -448,9 +463,11 @@ class core_backup_renderer extends plugin_renderer_base {
} else {
$description = '';
}
$id = $this->make_unique_id('detail-pair-value');
return $this->backup_detail_pair(
$label,
html_writer::empty_tag('input', $attributes + array('name' => $name, 'type' => $type, 'value' => $value)) . $description
html_writer::label($label, $id),
html_writer::empty_tag('input', $attributes + ['id' => $id, 'name' => $name, 'type' => $type, 'value' => $value]) .
$description
);
}
@@ -718,8 +735,6 @@ class core_backup_renderer extends plugin_renderer_base {
* @return string
*/
public function render_restore_course_search(restore_course_search $component) {
$url = $component->get_url();
$output = html_writer::start_tag('div', array('class' => 'restore-course-search form-inline mb-1'));
$output .= html_writer::start_tag('div', array('class' => 'rcs-results table-sm w-75'));
@@ -733,11 +748,18 @@ class core_backup_renderer extends plugin_renderer_base {
if (!$course->visible) {
$row->attributes['class'] .= ' dimmed';
}
$row->cells = array(
html_writer::empty_tag('input', array('type' => 'radio', 'name' => 'targetid', 'value' => $course->id)),
format_string($course->shortname, true, array('context' => context_course::instance($course->id))),
format_string($course->fullname, true, array('context' => context_course::instance($course->id)))
);
$id = $this->make_unique_id('restore-course');
$row->cells = [
html_writer::empty_tag('input', ['type' => 'radio', 'name' => 'targetid', 'value' => $course->id,
'id' => $id]),
html_writer::label(
format_string($course->shortname, true, ['context' => context_course::instance($course->id)]),
$id,
true,
['class' => 'd-block']
),
format_string($course->fullname, true, ['context' => context_course::instance($course->id)])
];
$table->data[] = $row;
}
if ($component->has_more_results()) {
@@ -764,6 +786,8 @@ class core_backup_renderer extends plugin_renderer_base {
'type' => 'text',
'name' => restore_course_search::$VAR_SEARCH,
'value' => $component->get_search(),
'aria-label' => get_string('searchcourses'),
'placeholder' => get_string('searchcourses'),
'class' => 'form-control'
);
$output .= html_writer::empty_tag('input', $attrs);
@@ -787,8 +811,6 @@ class core_backup_renderer extends plugin_renderer_base {
* @return string
*/
public function render_import_course_search(import_course_search $component) {
$url = $component->get_url();
$output = html_writer::start_tag('div', array('class' => 'import-course-search'));
if ($component->get_count() === 0) {
$output .= $this->output->notification(get_string('nomatchingcourses', 'backup'));
@@ -798,6 +820,8 @@ class core_backup_renderer extends plugin_renderer_base {
'type' => 'text',
'name' => restore_course_search::$VAR_SEARCH,
'value' => $component->get_search(),
'aria-label' => get_string('searchcourses'),
'placeholder' => get_string('searchcourses'),
'class' => 'form-control'
);
$output .= html_writer::empty_tag('input', $attrs);
@@ -833,11 +857,18 @@ class core_backup_renderer extends plugin_renderer_base {
if (!$course->visible) {
$row->attributes['class'] .= ' dimmed';
}
$row->cells = array(
html_writer::empty_tag('input', array('type' => 'radio', 'name' => 'importid', 'value' => $course->id)),
format_string($course->shortname, true, array('context' => context_course::instance($course->id))),
format_string($course->fullname, true, array('context' => context_course::instance($course->id)))
);
$id = $this->make_unique_id('import-course');
$row->cells = [
html_writer::empty_tag('input', ['type' => 'radio', 'name' => 'importid', 'value' => $course->id,
'id' => $id]),
html_writer::label(
format_string($course->shortname, true, ['context' => context_course::instance($course->id)]),
$id,
true,
['class' => 'd-block']
),
format_string($course->fullname, true, ['context' => context_course::instance($course->id)])
];
$table->data[] = $row;
}
if ($component->has_more_results()) {
@@ -856,6 +887,8 @@ class core_backup_renderer extends plugin_renderer_base {
'type' => 'text',
'name' => restore_course_search::$VAR_SEARCH,
'value' => $component->get_search(),
'aria-label' => get_string('searchcourses'),
'placeholder' => get_string('searchcourses'),
'class' => 'form-control');
$output .= html_writer::empty_tag('input', $attrs);
$attrs = array(
@@ -878,8 +911,6 @@ class core_backup_renderer extends plugin_renderer_base {
* @return string
*/
public function render_restore_category_search(restore_category_search $component) {
$url = $component->get_url();
$output = html_writer::start_tag('div', array('class' => 'restore-course-search form-inline mb-1'));
$output .= html_writer::start_tag('div', array('class' => 'rcs-results table-sm w-75'));
@@ -895,12 +926,19 @@ class core_backup_renderer extends plugin_renderer_base {
$row->attributes['class'] .= ' dimmed';
}
$context = context_coursecat::instance($category->id);
$row->cells = array(
html_writer::empty_tag('input', array('type' => 'radio', 'name' => 'targetid', 'value' => $category->id)),
format_string($category->name, true, array('context' => context_coursecat::instance($category->id))),
$id = $this->make_unique_id('restore-category');
$row->cells = [
html_writer::empty_tag('input', ['type' => 'radio', 'name' => 'targetid', 'value' => $category->id,
'id' => $id]),
html_writer::label(
format_string($category->name, true, ['context' => context_coursecat::instance($category->id)]),
$id,
true,
['class' => 'd-block']
),
format_text(file_rewrite_pluginfile_urls($category->description, 'pluginfile.php', $context->id,
'coursecat', 'description', null), $category->descriptionformat, array('overflowdiv' => true))
);
'coursecat', 'description', null), $category->descriptionformat, ['overflowdiv' => true])
];
$table->data[] = $row;
}
if ($component->has_more_results()) {
@@ -927,6 +965,8 @@ class core_backup_renderer extends plugin_renderer_base {
'type' => 'text',
'name' => restore_category_search::$VAR_SEARCH,
'value' => $component->get_search(),
'aria-label' => get_string('searchcoursecategories'),
'placeholder' => get_string('searchcoursecategories'),
'class' => 'form-control'
);
$output .= html_writer::empty_tag('input', $attrs);
+20 -6
View File
@@ -39,6 +39,20 @@ use stdClass;
*/
class assertion_exporter extends exporter {
/**
* Constructor - saves the persistent object, and the related objects.
*
* @param mixed $data - Either an stdClass or an array of values.
* @param array $related - An optional list of pre-loaded objects related to this object.
*/
public function __construct($data, $related = array()) {
// Having mixed $data is causing some issues. As this class is treating $data as an object everywhere, it can be converted
// to object at this point, to avoid errors and get the expected behaviour always.
// $data is an array when this class is a request exporter in backpack_api_mapping, but it is an object when this is
// used as a response exporter.
parent::__construct((object) $data, $related);
}
/**
* Map from a request response data to the internal structure.
*
@@ -104,16 +118,16 @@ class assertion_exporter extends exporter {
global $DB;
$result = [];
if (array_key_exists('related_badge', $this->data)) {
$exporter = new badgeclass_exporter($this->data['related_badge'], $this->related);
if (property_exists($this->data, 'related_badge')) {
$exporter = new badgeclass_exporter($this->data->related_badge, $this->related);
$result['badge'] = $exporter->export($output);
}
if (array_key_exists('related_recipient', $this->data)) {
$exporter = new recipient_exporter($this->data['related_recipient'], $this->related);
if (property_exists($this->data, 'related_recipient')) {
$exporter = new recipient_exporter($this->data->related_recipient, $this->related);
$result['recipient'] = $exporter->export($output);
}
if (array_key_exists('related_verify', $this->data)) {
$exporter = new verification_exporter($this->data['related_verify'], $this->related);
if (property_exists($this->data, 'related_verify')) {
$exporter = new verification_exporter($this->data->related_verify, $this->related);
$result['verification'] = $exporter->export($output);
}
return $result;
+14 -8
View File
@@ -45,6 +45,12 @@ class badgeclass_exporter extends exporter {
* @param array $related - An optional list of pre-loaded objects related to this object.
*/
public function __construct($data, $related = array()) {
// Having mixed $data is causing some issues. As this class is treating $data as an object everywhere, it can be converted
// to object at this point, to avoid errors and get the expected behaviour always.
// $data is an array when this class is a request exporter in backpack_api_mapping, but it is an object when this is
// used as a response exporter.
$data = (object) $data;
$pick = $this->pick_related();
foreach ($pick as $one) {
$isarray = false;
@@ -54,28 +60,28 @@ class badgeclass_exporter extends exporter {
$isarray = true;
}
$prefixed = 'related_' . $one;
if (array_key_exists($one, $data) && !array_key_exists($one, $related)) {
if (property_exists($data, $one) && !array_key_exists($one, $related)) {
if ($isarray) {
$newrelated = [];
foreach ($data[$one] as $item) {
foreach ($data->$one as $item) {
$newrelated[] = (object) $item;
}
$related[$one] = $newrelated;
} else {
$related[$one] = (object) $data[$one];
$related[$one] = (object) $data->$one;
}
unset($data[$one]);
} else if (array_key_exists($prefixed, $data) && !array_key_exists($one, $related)) {
unset($data->$one);
} else if (property_exists($data, $prefixed) && !array_key_exists($one, $related)) {
if ($isarray) {
$newrelated = [];
foreach ($data[$prefixed] as $item) {
foreach ($data->$prefixed as $item) {
$newrelated[] = (object) $item;
}
$related[$one] = $newrelated;
} else {
$related[$one] = (object) $data[$prefixed];
$related[$one] = (object) $data->$prefixed;
}
unset($data[$prefixed]);
unset($data->$prefixed);
} else if (!array_key_exists($one, $related)) {
$related[$one] = null;
}
+2 -2
View File
@@ -808,7 +808,7 @@ class core_badges_renderer extends plugin_renderer_base {
);
if (has_capability('moodle/badges:configuredetails', $context)) {
$row[] = new tabobject('details',
$row[] = new tabobject('badge',
new moodle_url('/badges/edit.php', array('id' => $badgeid, 'action' => 'badge')),
get_string('bdetails', 'badges')
);
@@ -859,7 +859,7 @@ class core_badges_renderer extends plugin_renderer_base {
if (has_capability('moodle/badges:configuredetails', $context)) {
$alignments = $DB->count_records_sql("SELECT COUNT(bc.id)
FROM {badge_alignment} bc WHERE bc.badgeid = :badgeid", array('badgeid' => $badgeid));
$row[] = new tabobject('balignment',
$row[] = new tabobject('alignment',
new moodle_url('/badges/alignment.php', array('id' => $badgeid)),
get_string('balignment', 'badges', $alignments)
);
+4 -1
View File
@@ -59,7 +59,7 @@ class core_block_external extends external_api {
'visible' => new external_value(PARAM_BOOL, 'Whether the block is visible.', VALUE_OPTIONAL),
'contents' => new external_single_structure(
array(
'title' => new external_value(PARAM_TEXT, 'Block title.'),
'title' => new external_value(PARAM_RAW, 'Block title.'),
'content' => new external_value(PARAM_RAW, 'Block contents.'),
'contentformat' => new external_format_value('content'),
'footer' => new external_value(PARAM_RAW, 'Block footer.'),
@@ -92,6 +92,9 @@ class core_block_external extends external_api {
private static function get_all_current_page_blocks($includeinvisible = false, $returncontents = false) {
global $PAGE, $OUTPUT;
// Set page URL to a fake URL to avoid errors.
$PAGE->set_url(new \moodle_url('/webservice/core_block_external/'));
// Load the block instances for all the regions.
$PAGE->blocks->load_blocks($includeinvisible);
$PAGE->blocks->create_all_block_instances();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+7 -8
View File
@@ -537,11 +537,9 @@ function(
// Filter out all pagination options which are too large for the amount of courses user is enrolled in.
var totalCourseCount = parseInt(root.find(Selectors.courseView.region).attr('data-totalcoursecount'), 10);
if (totalCourseCount) {
itemsPerPage = itemsPerPage.filter(function(pagingOption) {
return pagingOption.value < totalCourseCount;
});
}
itemsPerPage = itemsPerPage.filter(function(pagingOption) {
return pagingOption.value < totalCourseCount || pagingOption.value === 0;
});
var filters = getFilterValues(root);
var config = $.extend({}, DEFAULT_PAGED_CONTENT_CONFIG);
@@ -596,7 +594,8 @@ function(
pageCourses = $.merge(loadedPages[currentPage].courses, courses.slice(0, nextPageStart));
}
} else {
nextPageStart = pageData.limit;
// When the page limit is zero, there is only one page of courses, no start for next page.
nextPageStart = pageData.limit || false;
pageCourses = (pageData.limit > 0) ? courses.slice(0, pageData.limit) : courses;
}
@@ -605,8 +604,8 @@ function(
courses: pageCourses
};
// Set up the next page
var remainingCourses = nextPageStart ? courses.slice(nextPageStart, courses.length) : [];
// Set up the next page (if there is more than one page).
var remainingCourses = nextPageStart !== false ? courses.slice(nextPageStart, courses.length) : [];
if (remainingCourses.length) {
loadedPages[currentPage + 1] = {
courses: remainingCourses
+5 -3
View File
@@ -202,8 +202,9 @@ class main implements renderable, templatable {
// Check and remember the given view.
$this->view = $view ? $view : BLOCK_MYOVERVIEW_VIEW_CARD;
// Check and remember the given page size.
if ($paging == BLOCK_MYOVERVIEW_PAGING_ALL) {
// Check and remember the given page size, `null` indicates no page size set
// while a `0` indicates a paging size of `All`.
if (!is_null($paging) && $paging == BLOCK_MYOVERVIEW_PAGING_ALL) {
$this->paging = BLOCK_MYOVERVIEW_PAGING_ALL;
} else {
$this->paging = $paging ? $paging : BLOCK_MYOVERVIEW_PAGING_12;
@@ -370,8 +371,9 @@ class main implements renderable, templatable {
$select = "instanceid $csql AND fieldid = :fieldid";
$params['fieldid'] = $fieldid;
$distinctablevalue = $DB->sql_compare_text('value');
$values = $DB->get_records_select_menu('customfield_data', $select, $params, $DB->sql_order_by_text('value'),
$values = $DB->get_records_select_menu('customfield_data', $select, $params, '',
"DISTINCT $distinctablevalue, $distinctablevalue AS value2");
\core_collator::asort($values, \core_collator::SORT_NATURAL);
$values = array_filter($values);
if (!$values) {
return [];
@@ -36,10 +36,10 @@
{{#summary}}{{#str}} summary, block_myoverview {{/str}}{{/summary}}
</span>
</button>
<ul class="dropdown-menu" data-show-active-item aria-labelledby="displaydropdown">
<ul class="dropdown-menu" role="menu" data-show-active-item data-skip-active-class="true" aria-labelledby="displaydropdown">
{{#layouts}}
<li>
<a class="dropdown-item {{#active}}active{{/active}}" href="#" data-display-option="display" data-value="{{id}}" data-pref="{{id}}" aria-label="{{arialabel}}" aria-controls="courses-view-{{uniqid}}">
<a class="dropdown-item" href="#" data-display-option="display" data-value="{{id}}" data-pref="{{id}}" aria-label="{{arialabel}}" aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#active}}aria-current="true"{{/active}}>
{{name}}
</a>
</li>
@@ -53,10 +53,10 @@
{{selectedcustomfield}}
</span>
</button>
<ul class="dropdown-menu" data-show-active-item data-active-item-text aria-labelledby="groupingdropdown">
<ul class="dropdown-menu" role="menu" data-show-active-item data-skip-active-class="true" data-active-item-text aria-labelledby="groupingdropdown">
{{#displaygroupingallincludinghidden}}
<li>
<a class="dropdown-item {{#allincludinghidden}}active{{/allincludinghidden}}" href="#" data-filter="grouping" data-value="allincludinghidden" data-pref="allincludinghidden" aria-label="{{#str}} aria:allcoursesincludinghidden, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
<a class="dropdown-item" href="#" data-filter="grouping" data-value="allincludinghidden" data-pref="allincludinghidden" aria-label="{{#str}} aria:allcoursesincludinghidden, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#allincludinghidden}}aria-current="true"{{/allincludinghidden}}>
{{#str}} allincludinghidden, block_myoverview {{/str}}
</a>
</li>
@@ -66,7 +66,7 @@
<span class="filler">&nbsp;</span>
</li>
<li>
<a class="dropdown-item {{#all}}active{{/all}}" href="#" data-filter="grouping" data-value="all" data-pref="all" aria-label="{{#str}} aria:allcourses, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
<a class="dropdown-item" href="#" data-filter="grouping" data-value="all" data-pref="all" aria-label="{{#str}} aria:allcourses, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#all}}aria-current="true"{{/all}}>
{{#str}} all, block_myoverview {{/str}}
</a>
</li>
@@ -76,7 +76,7 @@
<span class="filler">&nbsp;</span>
</li>
<li>
<a class="dropdown-item {{#inprogress}}active{{/inprogress}}" href="#" data-filter="grouping" data-value="inprogress" data-pref="inprogress" aria-label="{{#str}} aria:inprogress, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
<a class="dropdown-item" href="#" data-filter="grouping" data-value="inprogress" data-pref="inprogress" aria-label="{{#str}} aria:inprogress, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#inprogress}}aria-current="true"{{/inprogress}}>
{{#str}} inprogress, block_myoverview {{/str}}
</a>
</li>
@@ -88,7 +88,7 @@
</li>
{{/displaygroupinginprogress}}
<li>
<a class="dropdown-item {{#future}}active{{/future}}" href="#" data-filter="grouping" data-value="future" data-pref="future" aria-label="{{#str}} aria:future, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
<a class="dropdown-item" href="#" data-filter="grouping" data-value="future" data-pref="future" aria-label="{{#str}} aria:future, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#future}}aria-current="true"{{/future}}>
{{#str}} future, block_myoverview {{/str}}
</a>
</li>
@@ -102,7 +102,7 @@
{{/displaygroupingfuture}}
{{/displaygroupinginprogress}}
<li>
<a class="dropdown-item {{#past}}active{{/past}}" href="#" data-filter="grouping" data-value="past" data-pref="past" aria-label="{{#str}} aria:past, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
<a class="dropdown-item" href="#" data-filter="grouping" data-value="past" data-pref="past" aria-label="{{#str}} aria:past, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#past}}aria-current="true"{{/past}}>
{{#str}} past, block_myoverview {{/str}}
</a>
</li>
@@ -113,10 +113,10 @@
</li>
{{#customfieldvalues}}
<li>
<a class="dropdown-item {{#active}}active{{/active}}" href="#" data-filter="grouping"
<a class="dropdown-item" href="#" data-filter="grouping"
data-value="customfield" data-pref="customfield" data-customfieldvalue="{{value}}"
aria-label="{{#str}}aria:customfield, block_myoverview, {{name}}{{/str}}"
aria-controls="courses-view-{{uniqid}}">
aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#active}}aria-current="true"{{/active}}>
{{name}}
</a>
</li>
@@ -127,7 +127,7 @@
<span class="filler">&nbsp;</span>
</li>
<li>
<a class="dropdown-item {{#favourites}}active{{/favourites}}" href="#" data-filter="grouping" data-value="favourites" data-pref="favourites" aria-label="{{#str}} aria:favourites, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
<a class="dropdown-item" href="#" data-filter="grouping" data-value="favourites" data-pref="favourites" aria-label="{{#str}} aria:favourites, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#favourites}}aria-current="true"{{/favourites}}>
{{#str}} favourites, block_myoverview {{/str}}
</a>
{{/displaygroupingfavourites}}
@@ -136,7 +136,7 @@
<span class="filler">&nbsp;</span>
</li>
<li>
<a class="dropdown-item {{#hidden}}active{{/hidden}}" href="#" data-filter="grouping" data-value="hidden" data-pref="hidden" aria-label="{{#str}} aria:hiddencourses, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
<a class="dropdown-item" href="#" data-filter="grouping" data-value="hidden" data-pref="hidden" aria-label="{{#str}} aria:hiddencourses, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#hidden}}aria-current="true"{{/hidden}}>
{{#str}} hiddencourses, block_myoverview {{/str}}
</a>
</li>
@@ -36,21 +36,21 @@
{{#shortname}}{{#str}} shortname, block_myoverview {{/str}}{{/shortname}}
</span>
</button>
<ul class="dropdown-menu" data-show-active-item aria-labelledby="sortingdropdown">
<ul class="dropdown-menu" role="menu" data-show-active-item data-skip-active-class="true" aria-labelledby="sortingdropdown">
<li>
<a class="dropdown-item {{#title}}active{{/title}}" href="#" data-filter="sort" data-pref="title" data-value="fullname" aria-label="{{#str}} aria:title, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
<a class="dropdown-item" href="#" data-filter="sort" data-pref="title" data-value="fullname" aria-label="{{#str}} aria:title, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#title}}aria-current="true"{{/title}}>
{{#str}} title, block_myoverview {{/str}}
</a>
</li>
{{#showsortbyshortname}}
<li>
<a class="dropdown-item {{#shortname}}active{{/shortname}}" href="#" data-filter="sort" data-pref="shortname" data-value="shortname" aria-label="{{#str}} aria:shortname, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
<a class="dropdown-item" href="#" data-filter="sort" data-pref="shortname" data-value="shortname" aria-label="{{#str}} aria:shortname, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#shortname}}aria-current="true"{{/shortname}}>
{{#str}} shortname, block_myoverview {{/str}}
</a>
</li>
{{/showsortbyshortname}}
<li>
<a class="dropdown-item {{#lastaccessed}}active{{/lastaccessed}}" href="#" data-filter="sort" data-pref="lastaccessed" data-value="ul.timeaccess desc" aria-label="{{#str}} aria:lastaccessed, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
<a class="dropdown-item" href="#" data-filter="sort" data-pref="lastaccessed" data-value="ul.timeaccess desc" aria-label="{{#str}} aria:lastaccessed, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}" role="menuitem" {{#lastaccessed}}aria-current="true"{{/lastaccessed}}>
{{#str}} lastaccessed, block_myoverview {{/str}}
</a>
</li>
@@ -7,30 +7,30 @@ Feature: The my overview block allows users to persistence of their page limits
| student1 | Student | X | student1@example.com | S1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
| Course 2 | C2 | 0 |
| Course 3 | C3 | 0 |
| Course 4 | C4 | 0 |
| Course 5 | C5 | 0 |
| Course 6 | C6 | 0 |
| Course 7 | C7 | 0 |
| Course 8 | C8 | 0 |
| Course 9 | C9 | 0 |
| Course 1 | C01 | 0 |
| Course 2 | C02 | 0 |
| Course 3 | C03 | 0 |
| Course 4 | C04 | 0 |
| Course 5 | C05 | 0 |
| Course 6 | C06 | 0 |
| Course 7 | C07 | 0 |
| Course 8 | C08 | 0 |
| Course 9 | C09 | 0 |
| Course 10 | C10 | 0 |
| Course 11 | C11 | 0 |
| Course 12 | C12 | 0 |
| Course 13 | C13 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student1 | C2 | student |
| student1 | C3 | student |
| student1 | C4 | student |
| student1 | C5 | student |
| student1 | C6 | student |
| student1 | C7 | student |
| student1 | C8 | student |
| student1 | C9 | student |
| student1 | C01 | student |
| student1 | C02 | student |
| student1 | C03 | student |
| student1 | C04 | student |
| student1 | C05 | student |
| student1 | C06 | student |
| student1 | C07 | student |
| student1 | C08 | student |
| student1 | C09 | student |
| student1 | C10 | student |
| student1 | C11 | student |
| student1 | C12 | student |
@@ -38,8 +38,8 @@ Feature: The my overview block allows users to persistence of their page limits
Scenario: Toggle the page limit between page reloads
Given I log in as "student1"
When I click on "[data-toggle='dropdown']" "css_element" in the "Course overview" "block"
And I click on "All" "link"
When I click on "[data-action='limit-toggle']" "css_element" in the "Course overview" "block"
And I click on "All" "link" in the ".dropdown-menu.show" "css_element"
Then I should see "Course 13"
And I reload the page
Then I should see "Course 13"
@@ -47,8 +47,8 @@ Feature: The my overview block allows users to persistence of their page limits
Scenario: Toggle the page limit between grouping changes
Given I log in as "student1"
When I click on "[data-toggle='dropdown']" "css_element" in the "Course overview" "block"
And I click on "All" "link"
When I click on "[data-action='limit-toggle']" "css_element" in the "Course overview" "block"
And I click on "All" "link" in the ".dropdown-menu.show" "css_element"
And I click on "All (except removed from view)" "button" in the "Course overview" "block"
And I click on "In progress" "link" in the "Course overview" "block"
Then I should see "Course 13"
@@ -0,0 +1,191 @@
@block @block_myoverview @javascript
Feature: My overview block pagination
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| student1 | Student | X | student1@example.com | S1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 01 | C1 | 0 |
| Course 02 | C2 | 0 |
| Course 03 | C3 | 0 |
| Course 04 | C4 | 0 |
| Course 05 | C5 | 0 |
| Course 06 | C6 | 0 |
| Course 07 | C7 | 0 |
| Course 08 | C8 | 0 |
| Course 09 | C9 | 0 |
| Course 10 | C10 | 0 |
| Course 11 | C11 | 0 |
| Course 12 | C12 | 0 |
| Course 13 | C13 | 0 |
| Course 14 | C14 | 0 |
| Course 15 | C15 | 0 |
| Course 16 | C16 | 0 |
| Course 17 | C17 | 0 |
| Course 18 | C18 | 0 |
| Course 19 | C19 | 0 |
| Course 20 | C20 | 0 |
| Course 21 | C21 | 0 |
| Course 22 | C22 | 0 |
| Course 23 | C23 | 0 |
| Course 24 | C24 | 0 |
| Course 25 | C25 | 0 |
Scenario: The pagination controls should be hidden if I am not enrolled in any courses
When I log in as "student1"
Then I should see "No courses" in the "Course overview" "block"
And I should not see "Show" in the "Course overview" "block"
And ".block_myoverview .dropdown-menu.show" "css_element" should not be visible
And ".block_myoverview [data-control='next']" "css_element" should not be visible
And ".block_myoverview [data-control='previous']" "css_element" should not be visible
And I log out
Scenario: The pagination controls should be hidden if I am enrolled in 12 courses or less
Given the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student1 | C2 | student |
| student1 | C3 | student |
| student1 | C4 | student |
| student1 | C5 | student |
| student1 | C6 | student |
| student1 | C7 | student |
| student1 | C8 | student |
| student1 | C9 | student |
| student1 | C10 | student |
| student1 | C11 | student |
| student1 | C12 | student |
When I log in as "student1"
Then I should not see "Show" in the "Course overview" "block"
And ".block_myoverview .dropdown-menu.show" "css_element" should not be visible
And ".block_myoverview [data-control='next']" "css_element" should not be visible
And ".block_myoverview [data-control='previous']" "css_element" should not be visible
And I log out
Scenario: The default pagination should be 12 courses
Given the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student1 | C2 | student |
| student1 | C3 | student |
| student1 | C4 | student |
| student1 | C5 | student |
| student1 | C6 | student |
| student1 | C7 | student |
| student1 | C8 | student |
| student1 | C9 | student |
| student1 | C10 | student |
| student1 | C11 | student |
| student1 | C12 | student |
| student1 | C13 | student |
When I log in as "student1"
Then I should see "12" in the "[data-action='limit-toggle']" "css_element"
And I log out
Scenario: I should only see pagination limit options less than total number of enrolled courses
Given the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student1 | C2 | student |
| student1 | C3 | student |
| student1 | C4 | student |
| student1 | C5 | student |
| student1 | C6 | student |
| student1 | C7 | student |
| student1 | C8 | student |
| student1 | C9 | student |
| student1 | C10 | student |
| student1 | C11 | student |
| student1 | C12 | student |
| student1 | C13 | student |
And I log in as "student1"
When I click on "[data-action='limit-toggle']" "css_element" in the "Course overview" "block"
Then I should see "All" in the ".dropdown-menu.show" "css_element"
And I should see "12" in the ".dropdown-menu.show" "css_element"
And ".block_myoverview [data-control='next']" "css_element" should be visible
And ".block_myoverview [data-control='previous']" "css_element" should be visible
But I should not see "24" in the ".block_myoverview .dropdown-menu.show" "css_element"
And I log out
Scenario: Previous page button should be disabled when on the first page of courses
Given the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student1 | C2 | student |
| student1 | C3 | student |
| student1 | C4 | student |
| student1 | C5 | student |
| student1 | C6 | student |
| student1 | C7 | student |
| student1 | C8 | student |
| student1 | C9 | student |
| student1 | C10 | student |
| student1 | C11 | student |
| student1 | C12 | student |
| student1 | C13 | student |
When I log in as "student1"
Then the "class" attribute of ".block_myoverview [data-control='previous']" "css_element" should contain "disabled"
And I log out
Scenario: Next page button should be disabled when on the last page of courses
Given the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student1 | C2 | student |
| student1 | C3 | student |
| student1 | C4 | student |
| student1 | C5 | student |
| student1 | C6 | student |
| student1 | C7 | student |
| student1 | C8 | student |
| student1 | C9 | student |
| student1 | C10 | student |
| student1 | C11 | student |
| student1 | C12 | student |
| student1 | C13 | student |
When I log in as "student1"
And I click on "[data-control='next']" "css_element" in the "Course overview" "block"
And I wait until ".block_myoverview [data-control='next']" "css_element" exists
Then the "class" attribute of ".block_myoverview [data-control='next']" "css_element" should contain "disabled"
And I log out
Scenario: Next and previous page buttons should both be enabled when not on last or first page of courses
Given the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student1 | C2 | student |
| student1 | C3 | student |
| student1 | C4 | student |
| student1 | C5 | student |
| student1 | C6 | student |
| student1 | C7 | student |
| student1 | C8 | student |
| student1 | C9 | student |
| student1 | C10 | student |
| student1 | C11 | student |
| student1 | C12 | student |
| student1 | C13 | student |
| student1 | C14 | student |
| student1 | C15 | student |
| student1 | C16 | student |
| student1 | C17 | student |
| student1 | C18 | student |
| student1 | C19 | student |
| student1 | C20 | student |
| student1 | C21 | student |
| student1 | C22 | student |
| student1 | C23 | student |
| student1 | C24 | student |
| student1 | C25 | student |
When I log in as "student1"
And I click on "[data-control='next']" "css_element" in the "Course overview" "block"
And I wait until ".block_myoverview [data-control='next']" "css_element" exists
Then the "class" attribute of ".block_myoverview [data-control='next']" "css_element" should not contain "disabled"
And the "class" attribute of ".block_myoverview [data-control='previous']" "css_element" should not contain "disabled"
And I should see "Course 13" in the "Course overview" "block"
And I should see "Course 24" in the "Course overview" "block"
But I should not see "Course 12" in the "Course overview" "block"
And I should not see "Course 25" in the "Course overview" "block"
And I log out
+5 -1
View File
@@ -115,9 +115,13 @@ class block_news_items extends block_base {
$discussion->subject = format_string($discussion->subject, true, $forum->course);
$posttime = $discussion->modified;
if (!empty($CFG->forum_enabletimedposts) && ($discussion->timestart > $posttime)) {
$posttime = $discussion->timestart;
}
$text .= '<li class="post">'.
'<div class="head clearfix">'.
'<div class="date">'.userdate($discussion->modified, $strftimerecent).'</div>'.
'<div class="date">'.userdate($posttime, $strftimerecent).'</div>'.
'<div class="name">'.fullname($discussion).'</div></div>'.
'<div class="info"><a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$discussion->discussion.'">'.$discussion->subject.'</a></div>'.
"</li>\n";

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