Compare commits

...

625 Commits

Author SHA1 Message Date
Jake Dallimore 6acc0648d8 Moodle release 4.2.6 2024-02-09 10:33:33 +08:00
Sara Arjona f6533c6b7d weekly release 4.2.5+ 2024-02-08 16:18:18 +01:00
Sara Arjona 0d616e922c NOBUG: Fixed SVG browser compatibility 2024-02-08 16:18:15 +01:00
Sara Arjona add0bcf30f Merge branch 'MDL-80544-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 11:27:16 +01:00
Paul Holden 955fc14841 MDL-80544 h5p: add v126 library to list of standard plugins. 2024-02-08 10:15:57 +00:00
Andrew Nicols 59e71de878 Merge branch 'MDL-75081-402-fix' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2024-02-08 16:13:04 +08:00
Huong Nguyen 4421459ceb Merge branch 'MDL-80809-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 16:13:04 +08:00
Andrew Nicols 404a6b418c Merge branch 'MDL-80768-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 16:13:04 +08:00
Jun Pataleta 24d053f783 MDL-75081 gradereport_grader: Ensure correct search results are shown 2024-02-08 16:13:03 +08:00
Ilya Tregubov 4e3c61ba0e MDL-80504 forum: Fix seperate group mode 2024-02-08 16:13:03 +08:00
Leon Stringer bd305ed770 MDL-80501 mod_h5pactivity: activity group mode
Respect activity's group mode when checking access to the report.
Previously only the course's group mode was checked.
2024-02-08 16:13:03 +08:00
Andrew Nicols 9d57938602 Merge branch 'MDL-80738-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 16:13:03 +08:00
Huong Nguyen f9eb47625c MDL-80544 h5plib: Use the correct plugin version 2024-02-08 16:13:03 +08:00
Huong Nguyen b43e19ba93 Merge branch 'MDL-80544-402' of https://github.com/sarjona/moodle into MOODLE_402_STABLE 2024-02-08 16:13:02 +08:00
Daniel Ziegenberg feefa25d3c MDL-80648 files: extend xsendfilealiases
Add missing entry for custom $CFG->localrequestdir locations in the
preconfigured array for $CFG->xsendfilealiases in config-dist.php.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2024-02-08 16:13:02 +08:00
Andrew Nicols f62c8d5383 Merge branch 'MDL-80803-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 16:13:02 +08:00
Andrew Nicols 5e9fdc8f6b Merge branch 'MDL-36733-MOODLE_402_STABLE' of https://github.com/PascalHamar/moodle into MOODLE_402_STABLE 2024-02-08 16:13:01 +08:00
Andrew Nicols d036e5e3fd Merge branch 'MDL-80667-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 16:13:01 +08:00
Ilya Tregubov 030204dc4f Merge branch 'MDL-78173-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 16:13:01 +08:00
Sara Arjona da1fb2b149 Merge branch 'mdl-78095-402' of https://github.com/james-cnz/moodle into MOODLE_402_STABLE 2024-02-08 16:13:01 +08:00
Sara Arjona e4b3c5056b Merge branch 'MDL-74500-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 16:13:00 +08:00
Sara Arjona c71455259b Merge branch 'MDL-80808_402' of https://github.com/timhunt/moodle into MOODLE_402_STABLE 2024-02-08 16:13:00 +08:00
Sara Arjona 581ff0fe7c Merge branch 'MDL-79514-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 16:11:36 +08:00
Sara Arjona 85a545b3a6 Merge branch 'MDL-79577-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 16:11:36 +08:00
Jun Pataleta 3807a2d2d4 Merge branch 'MDL-80784-402' of https://github.com/noeldemartin/moodle into MOODLE_402_STABLE 2024-02-08 16:11:35 +08:00
Ilya Tregubov 26ed8fda6c MDL-69774 mod_forum: Restrict URL to accpet only expected params 2024-02-08 16:11:35 +08:00
Huong Nguyen 13fd81f316 Merge branch 'MDL-78417-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 16:11:35 +08:00
Huong Nguyen 32473f46a3 Merge branch 'MDL-80512-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-08 16:11:35 +08:00
Paul Holden dbfddeb48a MDL-74500 profilefield_checkbox: override show/empty class methods. 2024-02-07 14:13:54 +00:00
Ilya Tregubov 65123d48bc Merge branch 'MDL-80124-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-07 13:16:43 +08:00
Ilya Tregubov 71836d9dfd Merge branch 'MDL-80324-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-07 13:12:46 +08:00
Jun Pataleta eb617a25a8 Merge branch 'MDL-70058-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-07 12:31:25 +08:00
Jun Pataleta 416a1434e9 Merge branch '402_check_cached_empty_modnames' of https://github.com/opitz/moodle into MOODLE_402_STABLE 2024-02-07 11:17:44 +08:00
Jun Pataleta ed69ba56f0 Merge branch 'MDL-75081-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-07 10:37:12 +08:00
Ilya Tregubov ac77568bc3 Merge branch 'MDL-79433-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-07 10:13:18 +08:00
meirzamoodle be3404290c MDL-74641 repository: Fix wrong increment of temporary file for small sizes 2024-02-07 02:33:17 +01:00
meirzamoodle 9072dd8fdd MDL-74641 repository: Handles increase bytes while extracting zip files
We should not rely solely on the provided size information.
Therefore the system needs to recalculate the size of each file in the zip file,
whether small or big.

The changes also cover the filemanager.js file if an error appears.
2024-02-07 02:33:17 +01:00
meirzamoodle 9d97e933e8 MDL-78300 block: Determine if users can comment based on context 2024-02-07 02:33:17 +01:00
Paul Holden f3790e330a MDL-54749 tool_langimport: require sesskey to update lang packs. 2024-02-07 02:33:17 +01:00
Ilya Tregubov 8acb4b5218 Merge branch 'MDL-79527_402' of https://github.com/timhunt/moodle into MOODLE_402_STABLE 2024-02-07 09:28:47 +08:00
Ilya Tregubov a3d4a43b29 Merge branch 'MDL-78621-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-07 08:57:25 +08:00
Jun Pataleta 9775201ff9 Merge branch 'MDL-80693-m402' of https://github.com/sammarshallou/moodle into MOODLE_402_STABLE 2024-02-07 08:32:48 +08:00
Paul Holden 83ae3639eb MDL-75081 grade: fix rogue gradebook scenarios containing invalid steps. 2024-02-06 17:15:13 +00:00
Paul Holden 06f50b1f9b MDL-75081 behat: define new heading named selector.
Co-authored-by: Jun Pataleta <jun@moodle.com>
2024-02-06 17:06:53 +00:00
Paul Holden edcfa562f0 MDL-75081 behat: correct tests of table contents asserting one column.
Prior to this change, assertions of "should exist" and "should not
exist" in table content, where the step provided only a single column,
could give false positives and pass (when they shouldn't).
2024-02-06 16:41:38 +00:00
Paul Holden 131e3c2619 Merge branch 'MDL-80735-402' of https://github.com/marinaglancy/moodle into MOODLE_402_STABLE 2024-02-06 15:26:49 +00:00
Marina Glancy c894510194 MDL-80735 reportbuilder: do not render filters form during download
this removes unnecessary calculations and also prevents the session mutation
2024-02-06 14:52:54 +00:00
Sara Arjona c0619f6058 Merge branch 'MDL-80816_402' of https://github.com/stronk7/moodle into MOODLE_402_STABLE 2024-02-06 15:51:51 +01:00
Jun Pataleta 9eedc76274 Merge branch 'MDL-80725-402-enfix' of https://github.com/mudrd8mz/moodle into MOODLE_402_STABLE 2024-02-06 15:58:50 +08:00
Sara Arjona 114b81bb01 MDL-80544 core_h5p: Remove the h5plib_v124 plugin
The h5plib_v124 plugin can be removed because it has been replaced
with h5plib_v126, which is using the latest versions of the
libraries.
2024-02-06 08:13:18 +01:00
Sara Arjona d1aed3f685 MDL-80544 core_h5p: Add core lib changes after upgrading it 2024-02-06 08:12:08 +01:00
Sara Arjona 47a8c8c232 MDL-80544 core_h5p: Upgrade core lib to 1.26
This commit is upgrading the joubel/core library to the one
tagged as 1.26 (which also increases the coreApi minorVersion).
That's why the previous commit was duplicating the existing
h5plib_v124.
This tag is also pointing to the same tag that the mod_hvp is using
too: https://github.com/h5p/moodle-mod_hvp/releases/tag/1.26.1
2024-02-06 08:12:08 +01:00
Sara Arjona 4679b8797c MDL-80544 h5plib: Create first version of h5plib_v126
AMOS BEGIN
 CPY [editor:a11ytitleshowlabel,h5plib_v124],[editor:a11ytitleshowlabel,h5plib_v126]
 CPY [editor:a11ytitlehidelabel,h5plib_v124],[editor:a11ytitlehidelabel,h5plib_v126]
 CPY [editor:atoz,h5plib_v124],[editor:atoz,h5plib_v126]
 CPY [editor:add,h5plib_v124],[editor:add,h5plib_v126]
 CPY [editor:addauthor,h5plib_v124],[editor:addauthor,h5plib_v126]
 CPY [editor:addentity,h5plib_v124],[editor:addentity,h5plib_v126]
 CPY [editor:addfile,h5plib_v124],[editor:addfile,h5plib_v126]
 CPY [editor:addnewchange,h5plib_v124],[editor:addnewchange,h5plib_v126]
 CPY [editor:addtitle,h5plib_v124],[editor:addtitle,h5plib_v126]
 CPY [editor:addvideodescription,h5plib_v124],[editor:addvideodescription,h5plib_v126]
 CPY [editor:avtablistlabel,h5plib_v124],[editor:avtablistlabel,h5plib_v126]
 CPY [editor:belowmin,h5plib_v124],[editor:belowmin,h5plib_v126]
 CPY [editor:cancel,h5plib_v124],[editor:cancel,h5plib_v126]
 CPY [editor:cancellabel,h5plib_v124],[editor:cancellabel,h5plib_v126]
 CPY [editor:changefile,h5plib_v124],[editor:changefile,h5plib_v126]
 CPY [editor:changelanguage,h5plib_v124],[editor:changelanguage,h5plib_v126]
 CPY [editor:changelibrary,h5plib_v124],[editor:changelibrary,h5plib_v126]
 CPY [editor:changelogdescription,h5plib_v124],[editor:changelogdescription,h5plib_v126]
 CPY [editor:close,h5plib_v124],[editor:close,h5plib_v126]
 CPY [editor:commonfields,h5plib_v124],[editor:commonfields,h5plib_v126]
 CPY [editor:commonfieldsdescription,h5plib_v124],[editor:commonfieldsdescription,h5plib_v126]
 CPY [editor:confirmchangelibrary,h5plib_v124],[editor:confirmchangelibrary,h5plib_v126]
 CPY [editor:confirmdeletechangelog,h5plib_v124],[editor:confirmdeletechangelog,h5plib_v126]
 CPY [editor:confirmimageremoval,h5plib_v124],[editor:confirmimageremoval,h5plib_v126]
 CPY [editor:confirmpastebuttontext,h5plib_v124],[editor:confirmpastebuttontext,h5plib_v126]
 CPY [editor:confirmpastecontent,h5plib_v124],[editor:confirmpastecontent,h5plib_v126]
 CPY [editor:confirmremoval,h5plib_v124],[editor:confirmremoval,h5plib_v126]
 CPY [editor:confirmremoveauthor,h5plib_v124],[editor:confirmremoveauthor,h5plib_v126]
 CPY [editor:contenttypebackbuttonlabel,h5plib_v124],[editor:contenttypebackbuttonlabel,h5plib_v126]
 CPY [editor:contenttypecacheoutdated,h5plib_v124],[editor:contenttypecacheoutdated,h5plib_v126]
 CPY [editor:contenttypecacheoutdateddesc,h5plib_v124],[editor:contenttypecacheoutdateddesc,h5plib_v126]
 CPY [editor:contenttypedemobuttonlabel,h5plib_v124],[editor:contenttypedemobuttonlabel,h5plib_v126]
 CPY [editor:contenttypedetailbuttonlabel,h5plib_v124],[editor:contenttypedetailbuttonlabel,h5plib_v126]
 CPY [editor:contenttypegetbuttonlabel,h5plib_v124],[editor:contenttypegetbuttonlabel,h5plib_v126]
 CPY [editor:contenttypeiconalttext,h5plib_v124],[editor:contenttypeiconalttext,h5plib_v126]
 CPY [editor:contenttypeinstallbuttonlabel,h5plib_v124],[editor:contenttypeinstallbuttonlabel,h5plib_v126]
 CPY [editor:contenttypeinstallerror,h5plib_v124],[editor:contenttypeinstallerror,h5plib_v126]
 CPY [editor:contenttypeinstallsuccess,h5plib_v124],[editor:contenttypeinstallsuccess,h5plib_v126]
 CPY [editor:contenttypeinstallingbuttonlabel,h5plib_v124],[editor:contenttypeinstallingbuttonlabel,h5plib_v126]
 CPY [editor:contenttypelicensepaneltitle,h5plib_v124],[editor:contenttypelicensepaneltitle,h5plib_v126]
 CPY [editor:contenttypenotinstalled,h5plib_v124],[editor:contenttypenotinstalled,h5plib_v126]
 CPY [editor:contenttypenotinstalleddesc,h5plib_v124],[editor:contenttypenotinstalleddesc,h5plib_v126]
 CPY [editor:contenttypeowner,h5plib_v124],[editor:contenttypeowner,h5plib_v126]
 CPY [editor:contenttyperestricted,h5plib_v124],[editor:contenttyperestricted,h5plib_v126]
 CPY [editor:contenttyperestricteddesc,h5plib_v124],[editor:contenttyperestricteddesc,h5plib_v126]
 CPY [editor:contenttypesearchfieldplaceholder,h5plib_v124],[editor:contenttypesearchfieldplaceholder,h5plib_v126]
 CPY [editor:contenttypesectionall,h5plib_v124],[editor:contenttypesectionall,h5plib_v126]
 CPY [editor:contenttypeunsupportedapiversioncontent,h5plib_v124],[editor:contenttypeunsupportedapiversioncontent,h5plib_v126]
 CPY [editor:contenttypeunsupportedapiversiontitle,h5plib_v124],[editor:contenttypeunsupportedapiversiontitle,h5plib_v126]
 CPY [editor:contenttypeupdateavailable,h5plib_v124],[editor:contenttypeupdateavailable,h5plib_v126]
 CPY [editor:contenttypeupdatebuttonlabel,h5plib_v124],[editor:contenttypeupdatebuttonlabel,h5plib_v126]
 CPY [editor:contenttypeupdatesuccess,h5plib_v124],[editor:contenttypeupdatesuccess,h5plib_v126]
 CPY [editor:contenttypeupdatingbuttonlabel,h5plib_v124],[editor:contenttypeupdatingbuttonlabel,h5plib_v126]
 CPY [editor:contenttypeusebuttonlabel,h5plib_v124],[editor:contenttypeusebuttonlabel,h5plib_v126]
 CPY [editor:contributetranslations,h5plib_v124],[editor:contributetranslations,h5plib_v126]
 CPY [editor:copiedbutton,h5plib_v124],[editor:copiedbutton,h5plib_v126]
 CPY [editor:copiedtoclipboard,h5plib_v124],[editor:copiedtoclipboard,h5plib_v126]
 CPY [editor:copybutton,h5plib_v124],[editor:copybutton,h5plib_v126]
 CPY [editor:copytoclipboard,h5plib_v124],[editor:copytoclipboard,h5plib_v126]
 CPY [editor:createcontenttablabel,h5plib_v124],[editor:createcontenttablabel,h5plib_v126]
 CPY [editor:currentmenuselected,h5plib_v124],[editor:currentmenuselected,h5plib_v126]
 CPY [editor:editcopyright,h5plib_v124],[editor:editcopyright,h5plib_v126]
 CPY [editor:editimage,h5plib_v124],[editor:editimage,h5plib_v126]
 CPY [editor:editmode,h5plib_v124],[editor:editmode,h5plib_v126]
 CPY [editor:enteraudiotitle,h5plib_v124],[editor:enteraudiotitle,h5plib_v126]
 CPY [editor:enteraudiourl,h5plib_v124],[editor:enteraudiourl,h5plib_v126]
 CPY [editor:enterfullscreenbuttonlabel,h5plib_v124],[editor:enterfullscreenbuttonlabel,h5plib_v126]
 CPY [editor:entervideotitle,h5plib_v124],[editor:entervideotitle,h5plib_v126]
 CPY [editor:entervideourl,h5plib_v124],[editor:entervideourl,h5plib_v126]
 CPY [editor:errorcalculatingmaxscore,h5plib_v124],[editor:errorcalculatingmaxscore,h5plib_v126]
 CPY [editor:errorcommunicatinghubcontent,h5plib_v124],[editor:errorcommunicatinghubcontent,h5plib_v126]
 CPY [editor:errorcommunicatinghubtitle,h5plib_v124],[editor:errorcommunicatinghubtitle,h5plib_v126]
 CPY [editor:errorheader,h5plib_v124],[editor:errorheader,h5plib_v126]
 CPY [editor:errornotsupported,h5plib_v124],[editor:errornotsupported,h5plib_v126]
 CPY [editor:errorparamsbroken,h5plib_v124],[editor:errorparamsbroken,h5plib_v126]
 CPY [editor:errortoohighversion,h5plib_v124],[editor:errortoohighversion,h5plib_v126]
 CPY [editor:example,h5plib_v124],[editor:example,h5plib_v126]
 CPY [editor:exceedsmax,h5plib_v124],[editor:exceedsmax,h5plib_v126]
 CPY [editor:exitfullscreenbuttonlabel,h5plib_v124],[editor:exitfullscreenbuttonlabel,h5plib_v126]
 CPY [editor:expandcollapse,h5plib_v124],[editor:expandcollapse,h5plib_v126]
 CPY [editor:filetolarge,h5plib_v124],[editor:filetolarge,h5plib_v126]
 CPY [editor:fillinthefieldsbelow,h5plib_v124],[editor:fillinthefieldsbelow,h5plib_v126]
 CPY [editor:gethelp,h5plib_v124],[editor:gethelp,h5plib_v126]
 CPY [editor:h5pfileuploadservererrorcontent,h5plib_v124],[editor:h5pfileuploadservererrorcontent,h5plib_v126]
 CPY [editor:h5pfileuploadservererrortitle,h5plib_v124],[editor:h5pfileuploadservererrortitle,h5plib_v126]
 CPY [editor:h5pfilevalidationfailedcontent,h5plib_v124],[editor:h5pfilevalidationfailedcontent,h5plib_v126]
 CPY [editor:h5pfilevalidationfailedtitle,h5plib_v124],[editor:h5pfilevalidationfailedtitle,h5plib_v126]
 CPY [editor:h5pfilewrongextensioncontent,h5plib_v124],[editor:h5pfilewrongextensioncontent,h5plib_v126]
 CPY [editor:h5pfilewrongextensiontitle,h5plib_v124],[editor:h5pfilewrongextensiontitle,h5plib_v126]
 CPY [editor:height,h5plib_v124],[editor:height,h5plib_v126]
 CPY [editor:hide,h5plib_v124],[editor:hide,h5plib_v126]
 CPY [editor:hideimportantinstructions,h5plib_v124],[editor:hideimportantinstructions,h5plib_v126]
 CPY [editor:hubpanellabel,h5plib_v124],[editor:hubpanellabel,h5plib_v126]
 CPY [editor:illegaldecimalnumber,h5plib_v124],[editor:illegaldecimalnumber,h5plib_v126]
 CPY [editor:imagelightboxprogress,h5plib_v124],[editor:imagelightboxprogress,h5plib_v126]
 CPY [editor:imagelightboxtitle,h5plib_v124],[editor:imagelightboxtitle,h5plib_v126]
 CPY [editor:importantinstructions,h5plib_v124],[editor:importantinstructions,h5plib_v126]
 CPY [editor:insert,h5plib_v124],[editor:insert,h5plib_v126]
 CPY [editor:invalidformat,h5plib_v124],[editor:invalidformat,h5plib_v126]
 CPY [editor:language,h5plib_v124],[editor:language,h5plib_v126]
 CPY [editor:librarymissing,h5plib_v124],[editor:librarymissing,h5plib_v126]
 CPY [editor:licensecandistribute,h5plib_v124],[editor:licensecandistribute,h5plib_v126]
 CPY [editor:licensecanholdliable,h5plib_v124],[editor:licensecanholdliable,h5plib_v126]
 CPY [editor:licensecanmodify,h5plib_v124],[editor:licensecanmodify,h5plib_v126]
 CPY [editor:licensecansublicense,h5plib_v124],[editor:licensecansublicense,h5plib_v126]
 CPY [editor:licensecanusecommercially,h5plib_v124],[editor:licensecanusecommercially,h5plib_v126]
 CPY [editor:licensecannotholdliable,h5plib_v124],[editor:licensecannotholdliable,h5plib_v126]
 CPY [editor:licensedescription,h5plib_v124],[editor:licensedescription,h5plib_v126]
 CPY [editor:licensefetchdetailsfailed,h5plib_v124],[editor:licensefetchdetailsfailed,h5plib_v126]
 CPY [editor:licensemodalsubtitle,h5plib_v124],[editor:licensemodalsubtitle,h5plib_v126]
 CPY [editor:licensemodaltitle,h5plib_v124],[editor:licensemodaltitle,h5plib_v126]
 CPY [editor:licensemustincludecopyright,h5plib_v124],[editor:licensemustincludecopyright,h5plib_v126]
 CPY [editor:licensemustincludelicense,h5plib_v124],[editor:licensemustincludelicense,h5plib_v126]
 CPY [editor:licenseunspecified,h5plib_v124],[editor:licenseunspecified,h5plib_v126]
 CPY [editor:listbelowmin,h5plib_v124],[editor:listbelowmin,h5plib_v126]
 CPY [editor:listexceedsmax,h5plib_v124],[editor:listexceedsmax,h5plib_v126]
 CPY [editor:listlabel,h5plib_v124],[editor:listlabel,h5plib_v126]
 CPY [editor:loading,h5plib_v124],[editor:loading,h5plib_v126]
 CPY [editor:loadingimageeditor,h5plib_v124],[editor:loadingimageeditor,h5plib_v126]
 CPY [editor:logthischange,h5plib_v124],[editor:logthischange,h5plib_v126]
 CPY [editor:loggedchanges,h5plib_v124],[editor:loggedchanges,h5plib_v126]
 CPY [editor:maxscoresemanticsmissing,h5plib_v124],[editor:maxscoresemanticsmissing,h5plib_v126]
 CPY [editor:metadata,h5plib_v124],[editor:metadata,h5plib_v126]
 CPY [editor:metadatasharingandlicensinginfo,h5plib_v124],[editor:metadatasharingandlicensinginfo,h5plib_v126]
 CPY [editor:missingproperty,h5plib_v124],[editor:missingproperty,h5plib_v126]
 CPY [editor:missingtranslation,h5plib_v124],[editor:missingtranslation,h5plib_v126]
 CPY [editor:newchangehasbeenlogged,h5plib_v124],[editor:newchangehasbeenlogged,h5plib_v126]
 CPY [editor:newestfirst,h5plib_v124],[editor:newestfirst,h5plib_v126]
 CPY [editor:nextimage,h5plib_v124],[editor:nextimage,h5plib_v126]
 CPY [editor:nochangeshavebeenlogged,h5plib_v124],[editor:nochangeshavebeenlogged,h5plib_v126]
 CPY [editor:nocontenttypesavailable,h5plib_v124],[editor:nocontenttypesavailable,h5plib_v126]
 CPY [editor:nocontenttypesavailabledesc,h5plib_v124],[editor:nocontenttypesavailabledesc,h5plib_v126]
 CPY [editor:nofollow,h5plib_v124],[editor:nofollow,h5plib_v126]
 CPY [editor:notimageordimensionsfield,h5plib_v124],[editor:notimageordimensionsfield,h5plib_v126]
 CPY [editor:numresults,h5plib_v124],[editor:numresults,h5plib_v126]
 CPY [editor:numberfield,h5plib_v124],[editor:numberfield,h5plib_v126]
 CPY [editor:ok,h5plib_v124],[editor:ok,h5plib_v126]
 CPY [editor:onlynumbers,h5plib_v124],[editor:onlynumbers,h5plib_v126]
 CPY [editor:or,h5plib_v124],[editor:or,h5plib_v126]
 CPY [editor:orderitemdown,h5plib_v124],[editor:orderitemdown,h5plib_v126]
 CPY [editor:orderitemup,h5plib_v124],[editor:orderitemup,h5plib_v126]
 CPY [editor:outofstep,h5plib_v124],[editor:outofstep,h5plib_v126]
 CPY [editor:pasteandreplacebutton,h5plib_v124],[editor:pasteandreplacebutton,h5plib_v126]
 CPY [editor:pasteandreplacefromclipboard,h5plib_v124],[editor:pasteandreplacefromclipboard,h5plib_v126]
 CPY [editor:pastebutton,h5plib_v124],[editor:pastebutton,h5plib_v126]
 CPY [editor:pastecontent,h5plib_v124],[editor:pastecontent,h5plib_v126]
 CPY [editor:pastecontentnotsupported,h5plib_v124],[editor:pastecontentnotsupported,h5plib_v126]
 CPY [editor:pastecontentrestricted,h5plib_v124],[editor:pastecontentrestricted,h5plib_v126]
 CPY [editor:pasteerror,h5plib_v124],[editor:pasteerror,h5plib_v126]
 CPY [editor:pastefromclipboard,h5plib_v124],[editor:pastefromclipboard,h5plib_v126]
 CPY [editor:pastenocontent,h5plib_v124],[editor:pastenocontent,h5plib_v126]
 CPY [editor:pastetoonew,h5plib_v124],[editor:pastetoonew,h5plib_v126]
 CPY [editor:pastetooold,h5plib_v124],[editor:pastetooold,h5plib_v126]
 CPY [editor:popularfirst,h5plib_v124],[editor:popularfirst,h5plib_v126]
 CPY [editor:previousimage,h5plib_v124],[editor:previousimage,h5plib_v126]
 CPY [editor:proceedbuttonlabel,h5plib_v124],[editor:proceedbuttonlabel,h5plib_v126]
 CPY [editor:readless,h5plib_v124],[editor:readless,h5plib_v126]
 CPY [editor:readmore,h5plib_v124],[editor:readmore,h5plib_v126]
 CPY [editor:recentlyusedfirst,h5plib_v124],[editor:recentlyusedfirst,h5plib_v126]
 CPY [editor:reloadbuttonlabel,h5plib_v124],[editor:reloadbuttonlabel,h5plib_v126]
 CPY [editor:removefile,h5plib_v124],[editor:removefile,h5plib_v126]
 CPY [editor:removeimage,h5plib_v124],[editor:removeimage,h5plib_v126]
 CPY [editor:removeitem,h5plib_v124],[editor:removeitem,h5plib_v126]
 CPY [editor:requiredproperty,h5plib_v124],[editor:requiredproperty,h5plib_v126]
 CPY [editor:resettooriginallabel,h5plib_v124],[editor:resettooriginallabel,h5plib_v126]
 CPY [editor:savelabel,h5plib_v124],[editor:savelabel,h5plib_v126]
 CPY [editor:savemetadata,h5plib_v124],[editor:savemetadata,h5plib_v126]
 CPY [editor:screenshots,h5plib_v124],[editor:screenshots,h5plib_v126]
 CPY [editor:scriptmissing,h5plib_v124],[editor:scriptmissing,h5plib_v126]
 CPY [editor:searchresults,h5plib_v124],[editor:searchresults,h5plib_v126]
 CPY [editor:selectfiletoupload,h5plib_v124],[editor:selectfiletoupload,h5plib_v126]
 CPY [editor:selectlibrary,h5plib_v124],[editor:selectlibrary,h5plib_v126]
 CPY [editor:semanticserror,h5plib_v124],[editor:semanticserror,h5plib_v126]
 CPY [editor:show,h5plib_v124],[editor:show,h5plib_v126]
 CPY [editor:showimportantinstructions,h5plib_v124],[editor:showimportantinstructions,h5plib_v126]
 CPY [editor:tabtitlebasicfileupload,h5plib_v124],[editor:tabtitlebasicfileupload,h5plib_v126]
 CPY [editor:tabtitleinputlinkurl,h5plib_v124],[editor:tabtitleinputlinkurl,h5plib_v126]
 CPY [editor:textfield,h5plib_v124],[editor:textfield,h5plib_v126]
 CPY [editor:thecontenttype,h5plib_v124],[editor:thecontenttype,h5plib_v126]
 CPY [editor:thiswillpotentially,h5plib_v124],[editor:thiswillpotentially,h5plib_v126]
 CPY [editor:title,h5plib_v124],[editor:title,h5plib_v126]
 CPY [editor:toolong,h5plib_v124],[editor:toolong,h5plib_v126]
 CPY [editor:tryagain,h5plib_v124],[editor:tryagain,h5plib_v126]
 CPY [editor:tutorial,h5plib_v124],[editor:tutorial,h5plib_v126]
 CPY [editor:unabletointerpreterror,h5plib_v124],[editor:unabletointerpreterror,h5plib_v126]
 CPY [editor:unabletointerpretsolution,h5plib_v124],[editor:unabletointerpretsolution,h5plib_v126]
 CPY [editor:unknownfieldpath,h5plib_v124],[editor:unknownfieldpath,h5plib_v126]
 CPY [editor:uploadinstructionstitle,h5plib_v124],[editor:uploadinstructionstitle,h5plib_v126]
 CPY [editor:uploadplaceholder,h5plib_v124],[editor:uploadplaceholder,h5plib_v126]
 CPY [editor:uploadsuccess,h5plib_v124],[editor:uploadsuccess,h5plib_v126]
 CPY [editor:uploadtablabel,h5plib_v124],[editor:uploadtablabel,h5plib_v126]
 CPY [editor:uploadvideotitle,h5plib_v124],[editor:uploadvideotitle,h5plib_v126]
 CPY [editor:uploading,h5plib_v124],[editor:uploading,h5plib_v126]
 CPY [editor:uploadingthrobber,h5plib_v124],[editor:uploadingthrobber,h5plib_v126]
 CPY [editor:usedforsearchingreportsandcopyrightinformation,h5plib_v124],[editor:usedforsearchingreportsandcopyrightinformation,h5plib_v126]
 CPY [editor:videoquality,h5plib_v124],[editor:videoquality,h5plib_v126]
 CPY [editor:videoqualitydefaultlabel,h5plib_v124],[editor:videoqualitydefaultlabel,h5plib_v126]
 CPY [editor:videoqualitydescription,h5plib_v124],[editor:videoqualitydescription,h5plib_v126]
 CPY [editor:warningchangebrowsingtoseeresults,h5plib_v124],[editor:warningchangebrowsingtoseeresults,h5plib_v126]
 CPY [editor:warningnocontenttypesinstalled,h5plib_v124],[editor:warningnocontenttypesinstalled,h5plib_v126]
 CPY [editor:warningupdateavailablebody,h5plib_v124],[editor:warningupdateavailablebody,h5plib_v126]
 CPY [editor:warningupdateavailabletitle,h5plib_v124],[editor:warningupdateavailabletitle,h5plib_v126]
 CPY [editor:width,h5plib_v124],[editor:width,h5plib_v126]
AMOS END
2024-02-06 08:12:07 +01:00
Jun Pataleta 4ec88a2e6e Merge branch 'MDL-72703-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-06 12:10:04 +08:00
Ilya Tregubov 2b41d90a9e Merge branch 'MDL-80713-402' of https://github.com/HuongNV13/moodle into MOODLE_402_STABLE 2024-02-06 11:20:18 +08:00
Tim Hunt c19fa82e7c MDL-80808 quiz: improve message when the student can't review 2024-02-05 10:50:10 +00:00
Jun Pataleta bb80d04930 Merge branch 'MDL-80060-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-05 16:06:47 +08:00
Huong Nguyen d6295c30ef Merge branch 'MDL-80718-402' of https://github.com/dpalou/moodle into MOODLE_402_STABLE 2024-02-05 13:37:49 +07:00
Huong Nguyen 8af2a58c33 Merge branch 'MDL-67772-email-thread-headers-MOODLE_402_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_402_STABLE 2024-02-05 13:33:57 +07:00
Jun Pataleta cea960eeb4 Merge branch 'MDL-80694-402' of https://github.com/marinaglancy/moodle into MOODLE_402_STABLE 2024-02-05 14:26:53 +08:00
Huong Nguyen f1e4c6595e Merge branch 'MDL-80537_402' of https://github.com/timhunt/moodle into MOODLE_402_STABLE 2024-02-05 11:29:18 +07:00
Huong Nguyen 2d9eb08806 MDL-80713 Unit Tests: Message sink improvement
- Added a new method called get_messages_by_component()
  This method will help to retreive the redirected messages
  of specific component only
- Added a new method called get_messages_by_component_and_type()
  This method will help to retreive the redirected messages
  of specific component and type only
2024-02-05 09:24:42 +07:00
Eloy Lafuente (stronk7) fdcb6755a9 MDL-80816 core: Bump actions to newer versions
All the new ones are Nodejs 20 based, because
Nodejs 16 is being deprecated @ GH environments.

https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20
2024-02-02 17:17:03 +01:00
Tim Hunt 8c2029ef64 MDL-79527 questions: category tree loading handling bad data
It should always be the case that a question category and its parent
category belong to the same context. However, over the years, we have
observed that this becomes violated by some data in some Moodle sites.
(The suspicion is that this is a backup/restor bug of some sort which
has never been tracked down.)

Since this happens, we should make the code robust to it, which is what
this change does. It ensure that when loading child categories, we only
consider ones in the same context.
2024-02-02 11:33:44 +00:00
Ilya Tregubov 44fd4d7dc0 weekly release 4.2.5+ 2024-02-02 08:56:29 +08:00
Ilya Tregubov 8c8885420b Merge branch 'install_402_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_402_STABLE 2024-02-02 08:56:25 +08:00
james-cnz 8da787e789 MDL-78095 course: Respect is_bulk_editable() 2024-02-02 10:26:40 +13:00
David Mudrák b175313da9 MDL-80725 lang: Fix Behat regressions related to the question rename 2024-02-01 20:05:27 +01:00
David Mudrák cb831f890f MDL-80725 lang: Fix Help and documentation regressions 2024-02-01 20:05:22 +01:00
Paul Holden 7ef9f78c01 MDL-80809 course: correct context arguments when formatting strings. 2024-02-01 18:16:37 +00:00
Tim Hunt 24826f4fc3 MDL-80537 question bank: escape plain text display of question text 2024-02-01 16:35:51 +00:00
Paul Holden f0c4f19c46 MDL-80803 course: observe mod availability before update notification. 2024-02-01 14:51:35 +00:00
Brendan Heywood 60c7936c6a MDL-67772 mod_forum: Fix email threading for first message 2024-02-01 16:18:40 +11:00
Huong Nguyen 5559f6d08c Merge branch 'MDL-80485-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-01 11:31:40 +07:00
Huong Nguyen 919cbdf64c Merge branch 'MDL-80660-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-01 11:24:16 +07:00
Huong Nguyen e4f05ef164 Merge branch 'MDL-80538-402' of https://github.com/lameze/moodle into MOODLE_402_STABLE 2024-02-01 11:18:28 +07:00
Simey Lameze 54608ed959 MDL-80538 phpdoc: add missing null parameter type to phpdoc 2024-02-01 12:07:34 +08:00
info@eWallah.net 12db10be31 MDL-80538 phpdoc: Incorrect dataformat type documentation in table lib 2024-02-01 12:07:34 +08:00
Huong Nguyen 150568f88c Merge branch 'MDL-71665-402' of https://github.com/laurentdavid/moodle into MOODLE_402_STABLE 2024-02-01 11:07:20 +07:00
Huong Nguyen 271e8d1924 Merge branch 'MDL-80450-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-01 11:01:37 +07:00
Huong Nguyen 41b9d54489 Merge branch 'MDL-80692-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-01 10:57:52 +07:00
Huong Nguyen 2beaddf3c0 Merge branch 'MDL-73010-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-01 10:50:54 +07:00
Jun Pataleta 4869ee3499 Merge branch 'MDL-74775-402' of https://github.com/HuongNV13/moodle into MOODLE_402_STABLE 2024-02-01 11:47:02 +08:00
Huong Nguyen ba638f834a Merge branch 'MDL-29261-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-01 10:45:57 +07:00
Huong Nguyen 4572833853 Merge branch 'MDL-80706-402' of https://github.com/marinaglancy/moodle into MOODLE_402_STABLE 2024-02-01 10:44:22 +07:00
Jun Pataleta 180a3e8a73 Merge branch 'MDL-80247-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-01 11:38:54 +08:00
Jun Pataleta d1131393aa Merge branch 'MDL-79725-402' of https://github.com/snake/moodle into MOODLE_402_STABLE 2024-02-01 11:33:00 +08:00
Ilya Tregubov fbb8aa92ad Merge branch 'MDL-80202-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-01 10:39:26 +08:00
Ilya Tregubov 328b34ca98 Merge branch 'MDL-80199-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-01 10:31:43 +08:00
Ilya Tregubov 553b9e2a60 Merge branch 'MDL-80727-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-02-01 10:27:06 +08:00
Huong Nguyen aacb33bd48 Merge branch 'MDL-80289-402' of https://github.com/call-learning/moodle into MOODLE_402_STABLE 2024-02-01 08:55:59 +07:00
David Mudrák 393b277e29 MDL-80725 lang: Use the fixed strings in tests, too 2024-01-31 22:12:47 +01:00
Helen Foster ecb3d0a1b0 MDL-80725 lang: Import fixed English strings (en_fix) 2024-01-31 22:12:29 +01:00
Noel De Martin e87d652092 MDL-80784 behat: Disable SSL checks for app initialization 2024-01-31 14:07:17 +01:00
Ilya Tregubov ac57e1a023 Merge branch 'MDL-80575-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-31 09:25:25 +08:00
Paul Holden 5a1aef5a51 MDL-80768 output: stricter progress bar component percentage type.
Avoid mixing float/string types, where the decimal separator could
vary according to current locale.
2024-01-30 23:28:47 +00:00
Paul Holden deed60f5a1 MDL-80738 quiz_statistics: ensure tests uses a DB-backed lock class.
Fix the test file/class name too.

Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
2024-01-30 15:39:07 +00:00
Paul Holden dd46cc65d7 MDL-80692 calendar: calculate today relative to users own timezone.
Co-authored-by: Archil Abuladze <armiworker@gmail.com>
2024-01-30 14:39:12 +00:00
Paul Holden 93f80f61d3 MDL-74500 user: method to determine whether to show profile fields.
The new API replaces identical behaviour in existing calling code, but
allows for profile field types to override/separate the logic used to
show the field and determine whether it's empty
2024-01-30 11:34:04 +00:00
Paul Holden 365a1ca7f5 MDL-80485 tool_lp: consistent activity icon element styling. 2024-01-30 11:28:54 +00:00
Huong Nguyen 76c94c34e4 Merge branch 'MDL-80523-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-30 09:42:30 +07:00
Laurent David 7b3be7dfbc MDL-71665 core_courseformat: Sync activity name in the page
* Changing the name of an activity should change the access restriction messages.
* Introduction of a marker as data-cm-name-for to be able to change any
occurence of a course module name in the page when this one changes.
2024-01-29 09:04:08 +01:00
Huong Nguyen 06802bd46d MDL-74775 adhoc_task: Do not clear the timecreated of failed tasks 2024-01-29 10:03:17 +07:00
Jun Pataleta f710c51f93 Merge branch 'MDL-69225-402' of https://github.com/sarjona/moodle into MOODLE_402_STABLE 2024-01-29 10:20:05 +08:00
Jun Pataleta ba013f48eb Merge branch 'MDL-78311-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-29 10:08:23 +08:00
Jun Pataleta 2e4169e2e7 Merge branch 'M402-MDL-79930' of https://github.com/marcusboon/moodle into MOODLE_402_STABLE 2024-01-29 10:04:10 +08:00
Marcus Boon 8f4d6f460d MDL-79930 mod_forum: Use MUC for forum count discussions 2024-01-29 08:35:02 +10:00
AMOS bot fc76bbb142 Automatically generated installer lang files 2024-01-27 00:11:28 +00:00
Paul Holden 2bdc211928 MDL-78311 core: fix host parameter type cleaning by IPv4 address. 2024-01-25 23:39:18 +00:00
Paul Holden 6dc458a4f9 MDL-80727 tool_task: replace hard-coded adhoc task runner strings. 2024-01-25 22:46:23 +00:00
Paul Holden 81794e4ec7 MDL-80124 admin: prevent deletion of pre-installed preset definitions. 2024-01-25 21:51:54 +00:00
Sara Arjona 734c027367 MDL-69225 h5pactivity: Review when and which banners display
The UX team proposal is to display two different notifications, to avoid confusion:

1. When the user is in preview mode:
Message: 'You are in preview mode.'
Notification Type: Information (blue), with the information permanently visible and not dismissible,
ensuring continuous awareness.

2. When activity tracking is disabled:
Message: 'Attempt tracking is not enabled for this activity. You can enable it in Settings.'
Notification Type: Warning (yellow) with a close icon for dismissal if tracking is intentionally disabled.

These notifications should only be visible to teachers and content creators, not students.
If a teacher also has a student role, this information should not appear when logged in as a student.

That's why the pre-existing is_tracking_enabled() function has been updated to only check if tracking
is on for an activity, without considering user capabilities (that's why the $user parameter has been
removed from this function too). Besides, a new function called can_submit() has been created to find
out if users are allowed to submit an activity.
2024-01-25 17:48:34 +01:00
Sara Arjona 3958f68d9b weekly release 4.2.5+ 2024-01-25 16:48:32 +01:00
Paul Holden 05b76a28a9 MDL-80660 user: preserve return URL upon role switch from frontpage. 2024-01-25 15:40:58 +00:00
Dani Palou 9f09e25cdd MDL-80718 quiz: Apply overrides in mod_quiz_get_combined_review_options 2024-01-25 10:54:18 +01:00
Jun Pataleta 3f90aea54e Merge branch 'MDL-80656-402' of https://github.com/lameze/moodle into MOODLE_402_STABLE 2024-01-25 12:13:55 +08:00
Huong Nguyen 50b19d282e Merge branch 'MDL-80224-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-25 11:02:15 +07:00
Huong Nguyen 033f0522ba Merge branch 'MDL-80516-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-25 10:45:56 +07:00
Huong Nguyen 81c290fc31 Merge branch 'MDL-76671-402' of https://github.com/jleyva/moodle into MOODLE_402_STABLE 2024-01-25 10:25:17 +07:00
Ilya Tregubov e9f133abc1 Merge branch 'MDL-80098-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-25 10:20:53 +08:00
Huong Nguyen 31a54100d2 Merge branch 'MDL-80676-402' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2024-01-25 09:08:10 +07:00
Ilya Tregubov 54441ad964 Merge branch 'MDL-79927-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-25 09:54:06 +08:00
Huong Nguyen 8a03f02e83 Merge branch 'MDL-76716-m402' of https://github.com/stefangub/moodle into MOODLE_402_STABLE 2024-01-25 08:51:44 +07:00
Ilya Tregubov caee1d8cb3 Merge branch 'MDL-79159-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2024-01-25 09:36:05 +08:00
Ilya Tregubov b63c94587c Merge branch 'MDL-80653-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-25 09:26:19 +08:00
Sara Arjona 196a388010 Merge branch 'MDL-79681-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-24 17:02:33 +01:00
Sara Arjona 14a63c9988 Merge branch 'MDL-79152-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2024-01-24 16:03:02 +01:00
Paul Holden 1344a8a477 MDL-78173 user: correct return URL upon login as from frontpage. 2024-01-24 14:58:35 +00:00
Sara Arjona b8f6a64ace Merge branch 'MDL-80668-402' of https://github.com/pedrojordao/moodle into MOODLE_402_STABLE 2024-01-24 15:16:26 +01:00
Sara Arjona 4f9de1b21e Merge branch 'MDL-78888-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-24 13:26:02 +01:00
Sara Arjona 64a1d7a056 Merge branch 'MDL-76723-402' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2024-01-24 13:14:03 +01:00
Sara Arjona 4ac202c713 Merge branch 'MDL-79940-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2024-01-24 09:22:42 +01:00
Angelia Dela Cruz f48aae4514 MDL-79159 mod_lesson: Behat coverage for lesson question max attempts 2024-01-24 16:18:15 +08:00
Ilya Tregubov 047654cffd Merge branch 'MDL-80270-402' of https://github.com/mihailges/moodle into MOODLE_402_STABLE 2024-01-24 13:47:13 +08:00
Simey Lameze 435ac352ca MDL-80656 behat: remove unnecessary activity duplication steps 2024-01-24 11:14:35 +08:00
Angelia Dela Cruz 81f203b60c MDL-79940 mod_workshop: Behat to confirm review button for reviewers 2024-01-24 09:03:37 +08:00
Marina Glancy b9486a01c5 MDL-80706 customfield: php8.1 warning about passing null to strlen 2024-01-23 14:58:30 +00:00
Marina Glancy dee152197f MDL-80694 external: fix return param in inplace_editable WS 2024-01-23 14:21:08 +00:00
Stefan Van der Vyver b151356bcf MDL-76716 grades: handle open delegated transaction on grade delete 2024-01-23 10:08:06 +00:00
Paul Holden c88b80e715 MDL-80512 tool_task: absolute path to required library file. 2024-01-23 09:25:03 +00:00
Jun Pataleta d73782a68a Merge branch 'MDL-80271-MOODLE_402_STABLE' of https://github.com/PhMemmel/moodle into MOODLE_402_STABLE 2024-01-23 16:32:39 +08:00
Paul Holden 1b846984eb MDL-80324 webservice: correct current page URL for user settings. 2024-01-23 08:22:53 +00:00
Sara Arjona dad2eebff4 Merge branch 'MDL-80339-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2024-01-23 07:48:31 +01:00
Jake Dallimore 66e6fd329d MDL-79725 libraries: fix auth URL generation in lti1p3 library 2024-01-23 12:53:29 +08:00
Ilya Tregubov c28c449259 Merge branch 'MDL-75579-402' of https://github.com/HuongNV13/moodle into MOODLE_402_STABLE 2024-01-23 12:05:02 +08:00
Jun Pataleta 564671dd5f Merge branch 'MDL-78219-402' of https://github.com/snake/moodle into MOODLE_402_STABLE 2024-01-23 11:59:18 +08:00
Huong Nguyen 922471c050 MDL-75579 Backup: Prevent failed course restore task to be retried 2024-01-23 09:34:12 +07:00
Huong Nguyen ca05ed2c18 MDL-75579 adhoc_task: Implement no-retry flag 2024-01-23 09:34:12 +07:00
Angelia Dela Cruz 53a516b798 MDL-80339 mod_lesson: Behat to confirm grade visibility in lesson 2024-01-23 10:13:03 +08:00
Jun Pataleta 0aa92a472a Merge branch 'MDL-79029-402' of https://github.com/ferranrecio/moodle into MOODLE_402_STABLE 2024-01-23 09:21:34 +08:00
Sara Arjona dbd36ffd0c Merge branch 'MDL-80559-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-22 16:23:37 +01:00
sam marshall 85a522280b MDL-80693 core_user: search() fails if no standard identify fields 2024-01-22 12:55:09 +00:00
Paul Holden a56bd8d4e1 MDL-80202 repository_local: null check when recursing child nodes. 2024-01-22 10:19:51 +00:00
Ferran Recio 4958cb4245 MDL-79029 behat: optimize behat tests
Replace some add activity to section steps to the new
add activity to course section so they are faster and do
not require javascript.
2024-01-22 11:18:22 +01:00
Ferran Recio ac095c5aa4 MDL-79029 behat: new add activity steps 2024-01-22 11:18:19 +01:00
Paul Holden 5d37f3a5d9 MDL-80653 h5p: handle content type creation errors in test.
See also same in c7d08f85.
2024-01-22 09:46:16 +00:00
Huong Nguyen 464a02ca84 Merge branch 'MDL-80532-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-22 15:39:36 +07:00
Huong Nguyen 609761ba2e Merge branch 'MDL-80499-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-22 15:36:44 +07:00
Jun Pataleta c63571cfca Merge branch 'MDL-80377-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2024-01-22 16:32:22 +08:00
Jun Pataleta 3f1e893a17 Merge branch 'MDL-80374-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-22 16:29:48 +08:00
Jun Pataleta 352b995cb9 Merge branch 'MDL-80323-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-22 16:26:00 +08:00
Jun Pataleta 0760a174f0 Merge branch 'MDL-80232-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-22 15:04:38 +08:00
Pedro Jordao c9683882e6 MDL-80668 modal: Change aria roles on modal to improve accessibility.
The roles we were using were no longer the most recommended for modals.
2024-01-19 08:14:43 -03:00
Paul Holden a7739ffa3c MDL-79577 user: better parsing of user menu lang string identifiers. 2024-01-19 09:49:33 +00:00
Matthias Opitz 5742078443 MDL-79988 course: checking for cached empty modnames
Check if empty modnames have been cached and if so retrieve them again.
2024-01-19 09:45:24 +00:00
Angelia Dela Cruz 29b0224de7 MDL-80377 block: Behat confirming folder file in recent activity block 2024-01-19 14:30:27 +08:00
Jun Pataleta b58bebbf9f MDL-80676 core: Remove unnecessary aria-labelledby for action menu links
The aria-labelledby attribute for the action menu link's <a> tag is
unnecessary as the <span> tag containing the action menu link's text
is already within the <a> tag and already serves as the link's label by
default.
2024-01-19 14:13:06 +08:00
Philipp Memmel 09db8f17d4 MDL-80271 core_user: Only update record if necessary 2024-01-19 05:59:24 +00:00
Huong Nguyen 72c1d1921f weekly release 4.2.5+ 2024-01-19 11:24:17 +07:00
Paul Holden 01e627bb87 MDL-79514 mod_feedback: ensure base item class library is required. 2024-01-18 20:46:39 +00:00
Paul Holden 70cee4252f MDL-80667 task: preserve environment when running tasks from web.
For sites that rely on environment variables to set configuration,
ensure they are also present when executing task process.

Co-authored-by: Olivier Wenger <olivier.wenger@liip.ch>
2024-01-18 16:54:08 +00:00
Paul Holden dc2e3d8eec MDL-79433 tiny_autosave: allow non-logged in user calls to webservice.
Accounts for the editor being added to pages for non-logged in users,
such as the "New account" page.
2024-01-18 10:49:22 +00:00
Paul Holden f635e0a44e MDL-73010 repository_filesystem: fix directory read comparison.
Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
2024-01-18 10:02:19 +00:00
Andrew Nicols 9e6cdc07c6 MDL-79152 editor_tiny: Enable browser-based spell-checking 2024-01-18 12:55:59 +08:00
Andrew Nicols f93bc845e6 Merge branch 'MDL-80201-402' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2024-01-18 11:34:34 +08:00
Jun Pataleta bac138d997 Merge branch 'MDL-79498-402' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2024-01-18 10:59:13 +08:00
Andrew Nicols 52bf269e7d Merge branch 'MDL-80591_402' of https://github.com/stronk7/moodle into MOODLE_402_STABLE 2024-01-18 10:57:30 +08:00
Justus Dieckmann 04bbf2a1f3 MDL-79498 javascript: Adjust get_string function signature
In order to reflect param and lang being optional parameters.
2024-01-18 10:54:37 +08:00
Andrew Nicols 64f937689b Merge branch 'MDL-80041-402' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2024-01-18 10:54:20 +08:00
Sara Arjona 9a91e0fae4 Merge branch 'MDL-80058-402' of https://github.com/meirzamoodle/moodle into MOODLE_402_STABLE 2024-01-17 18:46:54 +01:00
Sara Arjona c28aa03f2b Merge branch 'MDL-80081-402' of https://github.com/meirzamoodle/moodle into MOODLE_402_STABLE 2024-01-17 18:18:15 +01:00
Juan Leyva 8af5f10f2b MDL-76671 tool_mobile: Allow OAuth launches after accepting policies 2024-01-17 16:50:41 +01:00
Sara Arjona e195bd680f Merge branch 'MDL-80255-402' of https://github.com/aanabit/moodle into MOODLE_402_STABLE 2024-01-17 11:51:15 +01:00
Paul Holden c70803f489 MDL-78888 tool_uploaduser: case-insensitive email matching on upload. 2024-01-17 09:01:18 +00:00
Paul Holden 88c6878fa6 MDL-80098 core: correct arguments for invalidmoduleid exceptions.
The "invalid module ID" should be passed as the `$a` constructor
argument.
2024-01-17 08:59:01 +00:00
Paul Holden 0c2af009dd MDL-80060 enrol_manual: correct exception constructor arguments. 2024-01-17 08:57:49 +00:00
Paul Holden 552f60f51b MDL-78417 tool_uploaduser: handle empty default in custom menu field. 2024-01-17 08:56:01 +00:00
Huong Nguyen 5d9ed882b6 Merge branch 'MDL-79701-402' of https://github.com/rjnl/moodle into MOODLE_402_STABLE 2024-01-17 14:10:53 +07:00
Huong Nguyen b915a4bde0 Merge branch 'MDL-80498_402' of https://github.com/santoshndev/moodle into MOODLE_402_STABLE 2024-01-17 10:38:41 +07:00
Amaia Anabitarte a2fc550ab4 MDL-80255 mod_scorm: Remove 'Completed' as default completion 2024-01-16 17:26:54 +01:00
Paul Holden 4a3a5872e0 MDL-72703 profilefield_text: validate field length when editing.
This also means the same validation is applied elsewhere,  such as
in the upload user tool.
2024-01-16 09:54:20 +00:00
Sara Arjona 59d66f6b21 Merge branch 'MDL-80266-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2024-01-16 07:20:16 +01:00
Andrew Nicols 0a06809d17 MDL-80266 mod_forum: Reset subscription caches between behat tests 2024-01-16 13:34:40 +08:00
Ilya Tregubov 0852082960 Merge branch 'MDL-69615-402' of https://github.com/HuongNV13/moodle into MOODLE_402_STABLE 2024-01-16 10:58:09 +08:00
Huong Nguyen 0ba6c2d20c MDL-69615 core_backup: Send backup report email once the tasks are done 2024-01-16 09:31:36 +07:00
Sara Arjona ffb3f3595f Merge branch 'MDL-59467-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2024-01-15 17:28:22 +01:00
Sara Arjona 550f16c903 Merge branch 'MDL-79519-402_url_select' of https://github.com/Tsheke/moodle into MOODLE_402_STABLE 2024-01-15 17:03:10 +01:00
Paul Holden d643996bcf MDL-29261 tool_uploaduser: warn user about invalid data values. 2024-01-15 15:15:01 +00:00
Paul Holden b36e7ecce2 MDL-80516 core: more robust plugin update component checking.
Occurs when a plugin in incorrectly removed (via file system only,
rather than following proper uninstall process), and also contains
it's own sub-plugins.

In the above scenario, the update would request and receive back a
response for a plugin whose name was comprised of an empty string,
subsequently causing errors when processing said response.
2024-01-15 14:10:10 +00:00
Johnny Tsheke 2a839aed46 MDL-79519 course: remove null to use the default value. 2024-01-15 08:59:49 -05:00
Sara Arjona 57dd86d987 Merge branch 'MDL-79091-MOODLE_402_STABLE' of https://github.com/jay-oswald/moodle into MOODLE_402_STABLE 2024-01-15 12:31:47 +01:00
Jake Dallimore e798226270 MDL-78219 enrol_lti: fix auth method usage in base testcase 2024-01-15 15:45:07 +08:00
Jake Dallimore 1363941461 MDL-78219 auth_lti: ensure user updates happen after authentication
If an existing session is active at the time of launch, that user id
appears in the user_updated log. This log should show the launching user
updating their own record, not someone else. To resolve this, auth the
user before making any record updates so that the event gets the correct
user id.
2024-01-15 15:45:07 +08:00
Jake Dallimore 0b1159c314 MDL-78219 auth_lti: force empty session before launch user creation
If an existing session is active at the time of launch, that user id
appears in the user_created log, incorrectly (it should be system/0).
This patch makes sure that any existing session is terminated before
creation of a new user during launches.
2024-01-15 15:45:07 +08:00
Huong Nguyen e0594f0d68 MDL-69615 privacy: Use task trait for unit tests 2024-01-15 11:26:26 +07:00
Huong Nguyen 88814648a6 MDL-69615 core_task: Add a task trait 2024-01-15 11:26:26 +07:00
Eloy Lafuente (stronk7) 8edbf3d1f7 MDL-80591 phpunit: delegate run to phpunit binary
Instead of manually including composer's auto-loading
stuff and then run PHPUnit\TextUI\Command::main(), now
we are using the PHPUnit "binary".

That way behaviour should be 100% the same than
running vendor/bin/phpunit (recommended instead of util.php --run).

Also, note that, for other util.php commands, we still need
composer's auto-loading to happen, so we have moved it immediately
after the --run command.

Finally, a few more file_exists() conditions have been added
to ensure that PHPUnit is properly installed. Redundant but...
2024-01-13 18:32:14 +01:00
Paul Holden ee74b1752d MDL-70058 customfield: reference field element names correctly.
In the course external create/update methods, we must ensure that
the correct form element names are used. Specifically because the
textarea field type uses non-standard name.
2024-01-12 10:29:31 +00:00
Jun Pataleta af8d6ce5f4 Merge branch 'MDL-80192-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-12 17:28:17 +08:00
Paul Holden 32d33c7112 Merge branch 'MDL-80564-402' of https://github.com/marinaglancy/moodle into MOODLE_402_STABLE 2024-01-12 09:07:42 +00:00
Santosh Nagargoje 8267670f60 MDL-80498 group: Added required rule for filepicker field 2024-01-12 14:28:57 +05:30
Paul Holden 3aac83edc4 MDL-80192 reportbuilder: ensure filter form group elements have labels.
This ensures compliance with the following WCAG criterion:

"H71: Providing a description for groups of form controls using fieldset
and legend elements".
2024-01-12 08:39:43 +00:00
Paul Holden 3cc4de3368 MDL-80192 forms: implement method to set group element hidden label.
This is consistent with the API used for other form element types,
in order to provide screen-readable text in the fieldset legend while
not necessarily wanting to display said label.

The new class property is automatically exported to the template via
the `templatable_form_element` trait.
2024-01-12 08:33:45 +00:00
Jun Pataleta 20960a5781 Merge branch 'MDL-80353-MOODLE_402_STABLE' of https://github.com/marinaglancy/moodle into MOODLE_402_STABLE 2024-01-12 16:20:20 +08:00
meirzamoodle b9cc529140 MDL-80081 editor_tiny: Allow empty content in the i tag 2024-01-12 14:11:14 +07:00
Ilya Tregubov 287cfcbe83 weekly release 4.2.5+ 2024-01-12 09:11:44 +08:00
Marina Glancy d3696a6fb5 MDL-80564 reportbuilder: Consistent permission check for user full name 2024-01-11 14:45:51 +00:00
Paul Holden 6cc27fbb73 MDL-80575 mod_forum: correct field name for "Notify students" setting. 2024-01-11 11:44:34 +00:00
Jun Pataleta b841e46332 Merge branch 'MDL-80246-402' of https://github.com/mihailges/moodle into MOODLE_402_STABLE 2024-01-11 11:49:54 +08:00
Huong Nguyen 75982525d9 Merge branch 'MDL-80452-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2024-01-11 10:45:01 +07:00
Huong Nguyen 97e7e26a6a Merge branch 'MDL-80229-402' of https://github.com/davewoloszyn/moodle into MOODLE_402_STABLE 2024-01-11 10:36:29 +07:00
Angelia Dela Cruz 03a0584a1e MDL-80452 mod_h5pactivity: Behat for H5Pactivity duplication and delete 2024-01-11 11:21:09 +08:00
Ilya Tregubov 38f083d339 Merge branch 'MDL-80446-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-11 10:44:51 +08:00
Ilya Tregubov ddd8dc3290 Merge branch 'MDL-80357_402_STABLE' of https://github.com/SimonasAdams/moodle into MOODLE_402_STABLE 2024-01-11 10:38:57 +08:00
Ilya Tregubov 0e2f602534 Merge branch 'MDL-80333_402' of https://github.com/santoshndev/moodle into MOODLE_402_STABLE 2024-01-11 10:35:04 +08:00
Paul Holden 0012117629 MDL-80499 datafield_date: specify UTC time when editing field content. 2024-01-10 19:23:13 +00:00
Paul Holden 8555750bf4 MDL-80199 report_log: remove duplicate "all logs" breadcrumb. 2024-01-10 10:07:59 +00:00
Santosh Nagargoje b9978b0dd4 MDL-80333 Authentication: Fixed new login notification adhoc task 2024-01-10 15:31:04 +05:30
Paul Holden 7d3eff209c MDL-78621 mod_choice: verify limited responses before showing "full". 2024-01-10 09:48:59 +00:00
Huong Nguyen dac069b1d4 Merge branch 'MDL-73639-402-fix' of https://github.com/sarjona/moodle into MOODLE_402_STABLE 2024-01-10 14:46:29 +07:00
Sara Arjona 1d9ec2a6d2 Merge branch 'MDL-80340-402' of https://github.com/lameze/moodle into MOODLE_402_STABLE 2024-01-10 07:35:08 +01:00
Huong Nguyen 763280d045 Merge branch 'MDL-80382-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2024-01-10 10:30:46 +07:00
meirzamoodle 55d828df88 MDL-80058 editor_tiny: add preformatted format to the blocks 2024-01-10 09:40:22 +07:00
Angelia Dela Cruz db95f6c51a MDL-80382 behat: Replace "Frist" typos in Behat tests to "First" 2024-01-10 09:16:42 +08:00
Paul Holden 681f3b8afb MDL-80559 badges: set contexturl/name in badge awarded notification. 2024-01-09 17:17:05 +00:00
Sara Arjona 5f26ab7eb4 MDL-73639 behat: Fix the failure with the Enrol button
The button at the top of the page is hidden a few seconds by the
un-enrolment confirmation dialogue. Instead of waiting a few seconds
or reloading the page, the button at the bottom is clicked instead.
2024-01-09 16:32:33 +01:00
Simey Lameze f7fd5ac77d MDL-80340 behat: make query to fetch h5p attempts less strict 2024-01-09 16:15:57 +08:00
Sara Arjona 2def6cb4cd Merge branch 'MDL-78999_402' of https://github.com/santoshndev/moodle into MOODLE_402_STABLE 2024-01-08 16:38:44 +01:00
Paul Holden a85e2ca6ca MDL-80323 h5p: fail content type retrieval task on errors.
It's better for the task to fail gracefully rather than silently
swallow any errors, so that the task API can schedule re-tries.

If the endpoint is temporarily down and/or misbehaving, this will
allow admins to have clearer failures.
2024-01-08 10:06:43 +00:00
Huong Nguyen 72f3b26589 Merge branch 'MDL-73639-402' of https://github.com/lameze/moodle into MOODLE_402_STABLE 2024-01-08 16:09:04 +07:00
Simey Lameze e7316bd9e3 MDL-73639 behat: improvements to the new recover grades test 2024-01-08 13:09:13 +08:00
Angelia Dela Cruz d203ed497e MDL-73639 core_grades: Behat to test Recover grades default settings 2024-01-08 13:09:13 +08:00
Ilya Tregubov 71f4243351 Merge branch 'MDL-69497-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-08 10:04:35 +08:00
Ilya Tregubov 2d61dd30e7 Merge branch 'MDL-79937-402_fixlessonmatching' of https://github.com/catalystfd/moodle into MOODLE_402_STABLE 2024-01-08 09:20:43 +08:00
Víctor Déniz a5f9878fc5 MDL-79681 user: fix conditional to get the last access to a course 2024-01-05 13:56:05 +00:00
Paul Holden a72d1e7e75 MDL-79681 user: fix participant filter "never accessed" options.
For courses, determine whether "Never accessed" should be available,
and correct the used value to match that expected by the API (-1).
2024-01-05 13:56:04 +00:00
Laurent David eee5c76aa3 MDL-80289 mod_bigbluebutton: Fix retrieval of meeting via meetingid 2024-01-05 11:15:17 +01:00
Santosh Nagargoje 78a8085801 MDL-78999 theme: Fixed site logo issue in small screens 2024-01-05 01:11:26 +05:30
Rajneel Totaram 96e9cd62ec MDL-79701 block_calendar_upcoming: Display activity name in tooltip 2024-01-05 07:18:01 +12:00
Paul Holden da8e3dd790 MDL-80523 mod_label: correct upgrade step select query parameters. 2024-01-04 16:22:37 +00:00
Paul Holden 930a5644c5 MDL-80532 block_myoverview: don't post sesskey to quickstart guide URL. 2024-01-04 14:38:41 +00:00
Paul Holden 3a3bde5a17 MDL-79927 files: scope toggleall checkboxes per filemanager instance.
Ensures that when multiple exist on the same page, each operates
independently of the others.
2024-01-04 13:22:46 +00:00
Paul Holden d690b1c0c8 MDL-80247 files: multi-byte aware filename shortening in exporter.
Also correctly extract the original file extension.

Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
Co-authored-by: Mazitov Artem <maz@2i.tusur.ru>
2024-01-04 13:20:26 +00:00
Sara Arjona 591cdd8211 weekly release 4.2.5+ 2024-01-04 12:02:06 +01:00
Sara Arjona 6fe0b2f549 Merge branch 'install_402_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_402_STABLE 2024-01-04 12:02:02 +01:00
Sara Arjona 4558e3cc76 Merge branch 'MDL-79307-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-03 17:18:26 +01:00
Sara Arjona f553ee9fb6 Merge branch 'MDL-76719-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2024-01-03 16:32:48 +01:00
Huong Nguyen 93c949c3ae Merge branch 'MDL-80412-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-12-27 17:22:40 +07:00
AMOS bot b77f1985cc Automatically generated installer lang files 2023-12-23 00:11:25 +00:00
Jun Pataleta 8ec1e5d96a Moodle release 4.2.5 2023-12-22 10:01:03 +08:00
Jun Pataleta 924565f64a MDL-80041 gradereport_singleview: Implement grade validation
Implement grade validation for numeric grade overrides by setting
the type attribute for the grade input to number and setting a min
and max attribute values. Submitting the form with invalid values
will trigger built-in validation of the inputs.
2023-12-21 22:19:02 +08:00
Sara Arjona 28c4db5a53 weekly release 4.2.4+ 2023-12-21 13:34:26 +01:00
Paul Holden e8df849c04 MDL-80450 mod_resource: observe print intro setting when embedding. 2023-12-21 11:37:43 +00:00
Huong Nguyen 34b0267471 Merge branch 'MDL-80151-402' of https://github.com/lameze/moodle into MOODLE_402_STABLE 2023-12-20 15:40:11 +07:00
Huong Nguyen 20712c35da MDL-80151 behat: Improve viewing site calendar step 2023-12-20 16:32:46 +08:00
Angelia Dela Cruz 5e2476c137 MDL-80151 mod_chat: Behat for chat repeat times and past session view 2023-12-20 16:32:46 +08:00
Simey Lameze 75a9f6c7bc MDL-80151 behat: add calendar step to navigate to specific view 2023-12-20 16:32:46 +08:00
Jun Pataleta 50c647ec32 Merge branch 'MDL-68124-402' of https://github.com/sarjona/moodle into MOODLE_402_STABLE 2023-12-20 15:01:17 +08:00
Simon Adams fb68a79b34 MDL-80357 theme_boost: Correctly interpolate SCSS
Fixes interpolation between SCSS setting and background images SCSS when SCSS setting is a single line comment
2023-12-19 15:26:42 +00:00
Jun Pataleta 8a52036e91 Merge branch 'MDL-80393-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-12-19 17:25:03 +08:00
Paul Holden 4baf48383b MDL-80446 mod_feedback: stricter selector for getting draggable items.
Ensure we don't also match inner nodes of the label question.
2023-12-19 08:27:28 +00:00
Jun Pataleta f48e9d5899 MDL-76723 core_tag: Use external_format_value constructor properly
* First parameter should be the field name that the format property
points to.
* No need for VALUE_REQUIRED since it's the default for the $required
parameter.
* Third parameter is the default value and not a description string.
2023-12-19 15:50:30 +08:00
Jun Pataleta 5b5a3fd550 MDL-76723 mod_page: Use external_format_value constructor properly
* 'Content format' is passed to the $default parameter which is
incorrect.
* Also removed passing of VALUE_REQUIRED because it's already the
default value for the $required parameter.
2023-12-19 15:50:30 +08:00
Jun Pataleta 23cbb7ffa4 MDL-76723 core_external: Handle format properties properly
- If a text format property defines the 'optional' attribute as true,
then the $required parameter that
is passed to \core\external\exporter::get_format_structure() should be
VALUE_OPTIONAL.
- If a default value is provided for a format property,
\core\external\exporter::get_format_structure() should pass the default
value to the external_format_value constructor.
- Added validation for external_format_value for the default parameter.
  Debugging will be shown in case an invalid default value is passed.
- Amended unit tests for better coverage.
2023-12-19 15:50:30 +08:00
Frédéric Massart 09f5efdbd7 MDL-76723 core_external: Test invalid required value for format fields 2023-12-19 15:50:30 +08:00
Paul Holden f78b33e6bf MDL-80393 lang: expose current page language to JS modules.
Since 4be39296 the root HTML element contains the iso6391 language
code of the current language pack. However various JS modules need
access to the original Moodle language pack code, so expose that
in the `M.cfg` structure.
2023-12-19 07:48:02 +00:00
Jun Pataleta 797e4fbee0 MDL-80201 core: Check for default format value for exporter::export() 2023-12-19 15:47:08 +08:00
Andrew Nicols 40966eedaa MDL-59467 core: Use hasHelper instead of catching exception
When xdebug is set to break on exceptions it stops on all exceptions,
including _caught_ exceptions.

As a result we regularly hit this uniqid helper issue if debugging with
xdebug.

The solution is to check if the helper exists using the hasHelper method
instead of catching an exception when it does not exist.
2023-12-19 09:20:51 +08:00
Sara Arjona 46a4fafc46 MDL-68124 lesson: Fix random behat error with Oracle
This random error was caused because when reviewing an attempt,
the first pageid to display is calculated based on the timeseen
field in the lesson_attempst table.
In Oracle, sometimes it returned the second pageid (because both
had the same timeseen), so which led to these random failures.

Apart from adding 1-second wait when the attempt is created (to
guarantee the first page is returned properly), a few more
improvements have been also made, like removing manual steps for
setting the lesson activity or adding some extra checks to
confirm the information displayed is expected.
2023-12-18 09:48:59 +01:00
Huong Nguyen 92f457aa21 Merge branch 'MDL-80401-402' of https://github.com/aanabit/moodle into MOODLE_402_STABLE 2023-12-18 14:06:43 +07:00
Paul Holden cf85c59831 MDL-80412 reportbuilder: Behat scenario to view/sort additional names.
Related to fixes from 8f32e623.
2023-12-15 10:55:35 +00:00
Paul Holden 8aa82eff4a MDL-80412 reportbuilder: remove duplicate columns from order clause.
This works around a problem in SQL Server, which caused it to throw a
DML exception if the same column is duplicated in `ORDER BY` clause.

Backported from MDL-79270.
2023-12-15 10:54:14 +00:00
Huong Nguyen bc6e29023b weekly release 4.2.4+ 2023-12-15 08:44:39 +07:00
Huong Nguyen 13cf39fb4f Merge branch 'install_402_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_402_STABLE 2023-12-15 08:44:36 +07:00
Huong Nguyen f43d27963e Merge branch 'MDL-79828-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2023-12-14 10:15:27 +07:00
Huong Nguyen 285a480aaa Merge branch 'MDL-79050-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2023-12-14 09:57:00 +07:00
Huong Nguyen d57d384b29 Merge branch 'MDL-80394-402' of https://github.com/ilyatregubov/moodle into MOODLE_402_STABLE 2023-12-14 09:22:58 +07:00
Ilya Tregubov 2923c911be Merge branch 'MDL-79938-m402' of https://github.com/sammarshallou/moodle into MOODLE_402_STABLE 2023-12-14 08:51:23 +08:00
AMOS bot e89af7978b Automatically generated installer lang files 2023-12-14 00:11:09 +00:00
Angelia Dela Cruz c396f4a7b6 MDL-79050 Behat: Add behat coverage to retake lesson activity 2023-12-13 16:26:03 +08:00
Huong Nguyen f64a52cc7e Merge branch 'MDL-74466-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-12-13 09:29:13 +07:00
Ilya Tregubov f82c0f1a4b MDL-80394 core_grades: Revert changes to graded_users_iterator
Third party plugins are using it and change was breaking it
2023-12-13 09:38:21 +08:00
Ilya Tregubov d6bafb16a7 Merge branch 'MDL-80003_402' of https://github.com/PhilippImhof/moodle into MOODLE_402_STABLE 2023-12-13 09:22:36 +08:00
Sara Arjona 95cf12db60 Merge branch 'MDL-77572_402' of https://github.com/santoshndev/moodle into MOODLE_402_STABLE 2023-12-12 17:59:25 +01:00
sam marshall 498e5bea37 MDL-79938 Behat: Add steps to support multiple tabs 2023-12-12 16:43:52 +00:00
Santosh Nagargoje 99ce28a961 MDL-77572 Course: Added fix for section,activity visibility capabilities
fixed bug
2023-12-12 21:57:25 +05:30
Amaia Anabitarte b284d7852d MDL-80401 completion: New SCORM activity completion rules 2023-12-12 17:09:39 +01:00
Sara Arjona 6193d59626 Merge branch 'MDL-80315-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2023-12-12 14:19:57 +01:00
Sara Arjona 9bc9099ebe Merge branch 'MDL-79835_402' of https://github.com/timhunt/moodle into MOODLE_402_STABLE 2023-12-12 14:11:46 +01:00
Paul Holden f6cd4f8a45 MDL-80224 tool_uploaduser: better user defaults per site configuration.
Improve use of `core_user` type/default/choice definitions when setting
fields in the "Default values" form, used on upload.
2023-12-12 10:13:04 +00:00
Paul Holden a86fac1edb MDL-80374 grade: show localised plugin name in report column heading. 2023-12-11 10:35:04 +00:00
Marina Glancy 487e1c4ac6 MDL-80353 core_user: announce user selector changes to the screenreader 2023-12-08 15:29:44 +00:00
Huong Nguyen 86a0b87658 Moodle release 4.2.4 2023-12-08 09:21:47 +07:00
Mihail Geshoski c85976dcfc MDL-80246 tiny_equation: Escape elementid in the data-target attribute
Tabs use the value of the data-target attribute of the active tab link
to find and display the appropriate tab content. In some situations the
elementid value that is used to generate the data-target may contain
certain characters that have a special meaning in the selector context
(e.g. ".", ",", "#") and because of that the target element cannot be
correctly identified. To fix this problem the elementid value needs to
be escaped prior to generating the data-target attribute.
2023-12-08 09:51:20 +08:00
Francis Devine 889b850a42 MDL-79937 mod_lesson: Fix matching pagetype question matching
The addition of text format on the output of the answer responses broke
the matching later when comparing the valid answer against the sent
response, as the answer response was not correspondingly formatted.

I decided to use the un formatted answer response as the key, to keep it
as close as identical to prior behaviour
2023-12-08 09:07:46 +13:00
Paul Holden 2f71e00e81 MDL-80232 forumreport_summary: fix pagination count for summary report. 2023-12-07 17:25:49 +00:00
Philipp Imhof d021745498 MDL-80003 mod_quiz: watch all instances of tinyMCE 2023-12-07 17:30:12 +01:00
Sara Arjona 4f347438c5 weekly release 4.2.3+ 2023-12-07 16:22:08 +01:00
Paul Holden c151ed6853 MDL-79980 mod_survey: remove responses link if user cannot access.
Update Behat scenario to match.
2023-12-07 12:09:10 +01:00
Brendan Heywood e5fc6edb1d MDL-80309 tasks: Clean up mtrace logs 2023-12-07 12:07:55 +08:00
Huong Nguyen 27ad69c575 Merge branch 'MDL-80341_402' of https://github.com/timhunt/moodle into MOODLE_402_STABLE 2023-12-07 10:28:24 +07:00
Paul Holden c0a3fd11a0 MDL-79839 tool_task: clean task classname parameter prior to use. 2023-12-07 10:53:53 +08:00
Huong Nguyen 4329ce029a Merge branch 'MDL-79061-402-2' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2023-12-07 09:52:53 +07:00
Jun Pataleta f59a763929 MDL-79061 course: Create a sr-only mutations logger
* Create SRLogger that extends from the default Logger class. This
logger outputs the feedback to a sr-only ARIA live region to allow
screen readers to announce the feedback from mutations.
* Update the course editor to use the SRLogger.
2023-12-07 10:43:47 +08:00
Ferran Recio 39f03ba9c3 MDL-79061 core: Mechanism for logging mutation feedbacks
* Create a mechanism for logging mutation feedbacks.
* The mutation feedbacks are displayed as a toast by default.
* Apply this logging mechanism on the course homepage to provide
feedback for the results of actions performed on course modules and
course sections.
2023-12-07 10:43:47 +08:00
Huong Nguyen 9378404bc3 Merge branch 'MDL-68652-402-1' of https://github.com/ilyatregubov/moodle into MOODLE_402_STABLE 2023-12-07 09:32:29 +07:00
Jun Pataleta b42ffb923c Merge branch 'MDL-80281_402_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_402_STABLE 2023-12-07 10:16:45 +08:00
Huong Nguyen 82968da537 Merge branch 'MDL-77136-402' of https://github.com/lucaboesch/moodle into MOODLE_402_STABLE 2023-12-07 08:36:50 +07:00
Paul Holden 21d1673c56 MDL-79980 mod_survey: respect activity group mode getting report. 2023-12-07 09:31:50 +08:00
Ilya Tregubov 28f37199f4 MDL-68652 core_grades: Only return allowed fields.
Grade iterator should check user permissions.
2023-12-07 09:13:26 +08:00
Ilya Tregubov 1c21156c4f Merge branch 'MOODLE_402_MDL-73378' of https://github.com/danielneis/moodle into MOODLE_402_STABLE 2023-12-07 09:02:37 +08:00
Paul Holden 115d05b7a1 MDL-80239 grade: escape matched data in user search results. 2023-12-07 08:42:57 +08:00
Paul Holden aedb7ff6e5 MDL-80287 grade: escape current value in search templates. 2023-12-07 08:36:49 +08:00
Tim Hunt 01515859f2 MDL-79835 behat_core_generator: remove misleading error obfuscation 2023-12-06 18:13:50 +00:00
Jun Pataleta a94f1b2db0 Merge branch 'MDL-80127_402' of https://github.com/timhunt/moodle into MOODLE_402_STABLE 2023-12-06 22:12:05 +08:00
Jun Pataleta 122fa72a27 Merge branch 'MDL-80079-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2023-12-06 21:58:35 +08:00
Luca Bösch 14e0e1423e MDL-77136 qtype_randomsamatch: Newest versions for shortanswer questions 2023-12-06 14:13:09 +01:00
Luca Bösch be87aed144 MDL-77136 core_question: Newest versions get_questions_from_categories 2023-12-06 14:13:09 +01:00
Tim Hunt de1396fd70 MDL-80127 question engine: prevent fatal errors from old bad data 2023-12-06 11:38:26 +00:00
Tim Hunt 4ab988703f MDL-80127 question engine: don't convert null to '' before storing 2023-12-06 11:38:24 +00:00
Tim Hunt 28cd6e023e MDL-80341 quiz: unseen descriptions are not unanswered questonis
This was causing confusing in the 'are you sure you want to submit' confirmation pop-up.
2023-12-06 11:16:38 +00:00
Angelia Dela Cruz 4a66bfe57e MDL-80315 block_comments: Removed duplicate Behat test
Deleted the duplicated course comments block behat test. The file
blocks/comments/tests/behat/add_comment.feature is deleted as a
result.
2023-12-06 18:19:45 +08:00
Ilya Tregubov 32cd67aedd Merge branch 'MDL-76109-402' of https://github.com/meirzamoodle/moodle into MOODLE_402_STABLE 2023-12-06 15:43:17 +08:00
Huong Nguyen f49269ef3a Merge branch 'MDL-50650-402' of https://github.com/ilyatregubov/moodle into MOODLE_402_STABLE 2023-12-06 14:07:08 +07:00
Ilya Tregubov b928d8a604 Merge branch 'MDL-80043-402' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2023-12-06 15:00:52 +08:00
Stephan Robotta 74a3ed0258 MDL-41465 reports: In separate group mode, limit to same 2023-12-06 13:52:18 +07:00
Jun Pataleta 7a90b04fef MDL-80043 gradereport_grader: No need to pass header parameter
No need to pass a value for the header parameter in
print_grade_page_head() because:
1. We don't really render a header on that page.
2. It will allow the use of the editingmode_title lang string for the
grader report so the page title can reflect the display mode of the
grader report, especially when editing mode is turned on.
2023-12-06 13:49:20 +08:00
Ilya Tregubov 5ad9b4ae57 MDL-68652 mod_forum: Only include gradable users in grading 2023-12-06 12:46:42 +08:00
David Woloszyn b39c9fb8d8 MDL-79759 repository_url: Limit css imports and remove fragments
There are checks to urls that attempt to limit recurrsion when
parse_file is called. This is problematic for css import urls that
can call an indefinite amount of nested import urls. An import limit
has been introduced to address this. Fragments have also been removed.
2023-12-06 03:53:17 +01:00
Stevani Andolo fdacc779e7 MDL-80174 tool_log: ensure "other" data is safely unserialized. 2023-12-06 03:53:17 +01:00
Paul Holden 7bd8adfd89 MDL-80268 badges: require capability to view awarded badges. 2023-12-06 03:53:17 +01:00
Paul Holden 11128057ee MDL-79797 backup: ensure block config is safely unserialized. 2023-12-06 03:53:17 +01:00
Ilya Tregubov 7eb7b63231 Merge branch 'MDL-79692-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-12-06 10:50:34 +08:00
Huong Nguyen fb17f84e80 Merge branch 'MDL-80180-402' of https://github.com/jbs1/moodle into MOODLE_402_STABLE 2023-12-06 09:16:56 +07:00
Ilya Tregubov 5587eaa54f Merge branch 'MDL-74248-MOODLE_402_STABLE-fix_mp3_mod_folder' of https://github.com/praxisdigital/moodle into MOODLE_402_STABLE 2023-12-06 10:01:26 +08:00
Sara Arjona 37b2c0aabc Merge branch 'MDL-80286-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-12-05 16:42:19 +01:00
Sara Arjona 3d5fe79377 Merge branch 'MDL-79979-402' of https://github.com/aanabit/moodle into MOODLE_402_STABLE 2023-12-05 16:16:52 +01:00
Jun Pataleta e8a21f7636 Merge branch 'MDL-73974-402' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2023-12-05 23:09:05 +08:00
Karen Holland 5d3346bdb2 MDL-73974 tool_brickfield: Processing alpha fontsizes 2023-12-05 23:08:08 +08:00
Sara Arjona 02bb4161e1 Merge branch 'MDL-55640-m402' of https://github.com/sammarshallou/moodle into MOODLE_402_STABLE 2023-12-05 16:02:00 +01:00
Sara Arjona e4f31a2a5b Merge branch 'MDL-80015-402' of https://github.com/roland04/moodle into MOODLE_402_STABLE 2023-12-05 15:51:35 +01:00
Sara Arjona 1a87ce267c Merge branch 'MDL-80254-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-12-05 15:45:43 +01:00
Paul Holden f4b502a493 MDL-79307 assignfeedback_editpdf: more informative task failure.
If ghostscript is not correctly configured the task will never
succeed, so error out earlier with a more informative exception
explaining this.
2023-12-05 12:20:30 +00:00
Jun Pataleta ec97ffa6cb Merge branch 'MDL-79806_402_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_402_STABLE 2023-12-05 12:48:20 +08:00
Huong Nguyen 25ab55144f Merge branch 'MDL-71336-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-12-05 11:20:05 +07:00
Jun Pataleta 3f013a6f89 Merge branch 'm42-mdl64431' of https://github.com/danmarsden/moodle into MOODLE_402_STABLE 2023-12-05 12:13:32 +08:00
Huong Nguyen 10bf4f5e27 Merge branch 'MOODLE_402_STABLE' of https://github.com/dragos5436/moodle into MOODLE_402_STABLE 2023-12-05 10:40:50 +07:00
Ilya Tregubov 175eb51e18 MDL-68652 core_grades: Refactor grades functions.
get_gradable_users now has extra param to retrieve only active
users. Grade reports hase their own grade_report::get_gradable_users
since they decided whether to inlcude active users from report preferences
2023-12-05 10:52:55 +08:00
Ilya Tregubov d18acd7025 MDL-68652 core_grades: Add a webservice to retrive only gradable users. 2023-12-05 10:52:55 +08:00
Ilya Tregubov 9a29ac8266 Merge branch 'MDL-80043-402' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2023-12-05 09:11:28 +08:00
Ilya Tregubov 2dc5cac7ec Merge branch 'MDL-80131-402' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2023-12-05 09:01:08 +08:00
Sara Arjona 4a6f8d9b13 Merge branch 'MDL-80185-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-12-04 11:00:50 +01:00
Paul Holden 67a3a39d11 MDL-80254 reportbuilder: better handling of deleted users in schedules.
We should verify that schedule and audience users are active accounts,
and that we don't try to send report schedules either from/to them if
they aren't.
2023-12-04 09:48:44 +00:00
Paul Holden 11787aaa7f MDL-74466 repository: avoid passing around sesskey when not required. 2023-12-04 09:22:38 +00:00
Jun Pataleta bfa1b6cf19 Merge branch 'MDL-80221-402-enfix' of https://github.com/mudrd8mz/moodle into MOODLE_402_STABLE 2023-12-04 16:11:21 +08:00
Ilya Tregubov c95b5bc821 MDL-50650 core_grades: Validate minimum grade when importing grades
Also add behat test for max and min grade validation.
2023-12-04 16:02:28 +08:00
Kyle Matter 2af9d3d576 MDL-50650 core_grades: allow grade imports larger than 100 points 2023-12-04 12:54:52 +08:00
Jun Pataleta 933261722b MDL-80131 mod_data: Make page titles unique 2023-12-02 07:20:45 +08:00
dragos5436 c36d886087 MDL-60632 mod_quiz: Fix chart rendering fail in quiz report
If a quiz activity has negative grading enabled for incorrect answers,
students can achieve overall negative grades in this quiz. If at least
one student achieves a negative grade, the chart at the bottom of the
quiz 'Results' tab will fail to display. This patch add a search for
negative results, removes them from the band below 0 and adds them to
the 0 band. This will make the chart render correctly again.

Co-authored-by: Susana Leitão <sleitao@uporto.pt>
Co-authored-by: Matthias Opitz <m.opitz@ucl.ac.uk>

Removed whitespace at end of lines
2023-12-01 15:25:50 +00:00
Paul Holden 95446e49e2 MDL-76719 mod_assign: don't try to load user if there are none. 2023-12-01 13:17:40 +00:00
Paul Holden bb118b2328 MDL-69497 mod_assign: amend preference definitions for current user.
Ensure they can always be updated when using the grader.
2023-12-01 10:55:33 +00:00
David Mudrák 83054f331b MDL-80221 lang: Use fixed strings in the tests, too 2023-12-01 06:24:27 +01:00
Ilya Tregubov caacef2ea2 weekly release 4.2.3+ 2023-12-01 13:12:29 +08:00
Jun Pataleta 205d7dd83d MDL-80043 grade: Add upgrade.txt notes 2023-12-01 09:11:47 +08:00
Jun Pataleta e3592f4c44 MDL-80043 gradereport_grader: Define editingmode_title lang string 2023-12-01 09:11:47 +08:00
Jun Pataleta 8754e9c76e MDL-80043 grade: editingmode_title support for grade report plugins
* Add support for grade report plugins that define an
`editingmode_title` lang string. If the grade report plugin defines this
 language string, it will be used for the page title's unique
 identifying information when editing mode is turned on.
2023-12-01 09:11:47 +08:00
Jun Pataleta 0635ae4081 MDL-80043 gradereport_singleview: Improve heading wordings
* Make the headings for the single view easier to read and understand
* When on editing mode, update the heading for the grade and user
screens to convey to the user that the page is currently on editing
mode. This is helpful for screen reader users as they can immediately
know the current display mode of the single view report page when this
gets read via the page title.
2023-12-01 09:11:47 +08:00
Jun Pataleta e372e143ca MDL-80043 grade: Use heading parameter for the page title if provided 2023-12-01 09:11:46 +08:00
sam marshall e133aeef69 MDL-55640 setuplib: test_localcachedir fails sporadically 2023-11-30 13:58:23 +00:00
Paul Holden 328fe7ec6b MDL-80286 datafield_date: cast field content to real when sorting.
This ensures we don't under/overflow the size of an integer in DB.
2023-11-30 10:05:10 +00:00
Mark Johnson b43db639b3 MDL-79806 quiz_statistics: Queue recalculation on attempt_deleted 2023-11-30 08:53:34 +00:00
Jay Oswald 04b4eeb16a MDL-79091 core_badges: refactor bades cron task 2023-11-30 17:24:29 +11:00
Jay Oswald d70903a077 MDL-79091 core_badges: use adhoc tasks 2023-11-30 17:24:29 +11:00
Huong Nguyen b8e9bd5c1d Merge branch 'MDL-79816-402' of https://github.com/rmady/moodle into MOODLE_402_STABLE 2023-11-30 10:40:57 +07:00
Meirza 5d7492c54a MDL-76109 core: Don't check password policy for guest user
Besides adding the is_guest() check in the check_password_policy() condition,
I also changed the temporary user ID because the temporary user and
the guest must not share the same ID. Otherwise, it will raise an error.

Co-authored-by: Andrei Bautu <abautu@gmail.com>
2023-11-30 10:35:33 +07:00
Huong Nguyen c2f8ca5fd5 Merge branch 'MDL-74378_402' of https://github.com/PhilippImhof/moodle into MOODLE_402_STABLE 2023-11-30 10:12:05 +07:00
Ilya Tregubov 254d53cee8 Merge branch 'MDL-79890-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2023-11-30 10:45:20 +08:00
Ilya Tregubov d98419ea93 Merge branch 'MDL-78849-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-11-30 10:38:31 +08:00
Mihail Geshoski c9c5947e1c MDL-80270 gradereport_grader: User row as the last row cannot be sticky
In certain scenarios, a user row can be the last row in the grader
report table. The current logic does not take this into account and
always pins the last row regardless of the type.
This change ensures that the last row is not a user row before executing
the logic responsible for pinning this row.
2023-11-30 09:58:54 +08:00
Ilya Tregubov e045c69681 Merge branch 'MDL-79325-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-11-30 09:35:11 +08:00
Jun Pataleta 27c51d0fab Merge branch 'MDL-79841-402' of https://github.com/laurentdavid/moodle into MOODLE_402_STABLE 2023-11-29 23:48:30 +08:00
Sara Arjona 3028b06859 Merge branch 'MDL-79275-402' of https://github.com/lameze/moodle into MOODLE_402_STABLE 2023-11-29 16:44:05 +01:00
Jun Pataleta d12944b1a3 Merge branch 'MDL-80234-402' of https://github.com/aanabit/moodle into MOODLE_402_STABLE 2023-11-29 23:40:35 +08:00
Sara Arjona 27354b214d Merge branch 'MDL-80150-402' of https://github.com/lucaboesch/moodle into MOODLE_402_STABLE 2023-11-29 13:34:47 +01:00
Jun Pataleta b8f71fe67f Merge branch 'MDL-79148-402' of https://github.com/ssj365/moodle into MOODLE_402_STABLE 2023-11-29 15:20:18 +08:00
Huong Nguyen 95981fec91 Merge branch 'v_4_2_0' of https://github.com/dominicchinkh/moodle into MOODLE_402_STABLE 2023-11-29 10:33:39 +07:00
Huong Nguyen b705bcd66f Merge branch 'MDL-80002-402' of https://github.com/roland04/moodle into MOODLE_402_STABLE 2023-11-29 09:36:28 +07:00
Huong Nguyen 6de7215961 Merge branch 'MDL-79267-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-11-29 09:18:08 +07:00
Huong Nguyen aef3c1d974 Merge branch 'MDL-79512-402' of https://github.com/laurentdavid/moodle into MOODLE_402_STABLE 2023-11-29 09:09:01 +07:00
Jake Dallimore 3a086999f0 MDL-76694 core_comment: exit the js init if the element cannot be found
In pages which result in the theme_boost/embedded template being used,
blocks may be rendered and the resulting HTML ignored, leaving any JS
they may have added to run without a corresponding DOM element to act
on. This fixes that case for comments, making sure we exit gracefully
during the init if the element can't be found.
2023-11-29 09:00:41 +07:00
Jun Pataleta 07fb55e3b1 Merge branch 'MDL-80181-402' of https://github.com/srobotta/moodle into MOODLE_402_STABLE 2023-11-29 09:37:40 +08:00
Sara Arjona 43a10cb268 MDL-80150 resource: Reintroduce file icon
The new activity card design, planned for Moodle 4.3, reintroduces
the resource MIME icon that was removed in Moodle 4.0.
This is a backport of MDL-78285.
2023-11-29 02:07:07 +01:00
Jeremy Schulz 21613c49b3 MDL-80180 admin: added readonly support for multicheckbox 2023-11-28 14:35:23 -05:00
Helen Foster d6a1af70d8 MDL-80221 lang: Import fixed English strings (en_fix) 2023-11-28 19:51:58 +01:00
Pascal Hamar 8641eaa822 MDL-36733 qtype_calculated: Wildcards in calculated question hints
The placeholders for the hints are properly replaced by this change and any formulas present are replaced.

The validation is performed by the existing function qtype_calculated_find_formula_errors(),
which is called by the calculate() function,
which in turn is called by the variable substituter "vs" using the replace_expressions_in_text() function.

vs -> replace_expressions_in_text() -> calculate() -> qtype_calculated_find_formula_errors().
2023-11-28 18:47:45 +01:00
Mark Johnson 03c4de78ae MDL-80281 session: Don't report long session locks for readonly sessions
Previously, $CFG->sessionlockdebug was reporting long session locks for
all requests, even if they defined READ_ONLY_SESSION. This change
ensures that only sessions with locks are reported.
2023-11-28 16:21:32 +00:00
Shamiso.Jaravaza 0240b8fee1 MDL-79148 mod_bigbluebuttonbn: fix recording link 2023-11-27 23:57:37 -07:00
Ilya Tregubov eaa7bdec56 Merge branch 'MDL-79603-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2023-11-28 13:53:44 +08:00
Laurent David 034d447375 MDL-79841 theme_boost: Do not remove card borders
* When we are in small screensize we had removed the
left and right borders for cards. This is now restored
2023-11-28 06:37:32 +01:00
Simey Lameze ea693e675e MDL-79275 behat: add one second wait to avoid random 2023-11-28 11:05:12 +08:00
Amaia Anabitarte adc1e510ad MDL-80234 mod_scorm: Saved passed status requirement 2023-11-24 21:25:20 +01:00
Stephan Robotta cc0aa28495 MDL-80181 wiki: fix width of left column in comments 2023-11-24 11:18:04 +01:00
Philipp Imhof e0b8adbb98 MDL-74378 mod_quiz: make sure timer is initialized 2023-11-24 08:52:20 +01:00
Huong Nguyen 253028f813 weekly release 4.2.3+ 2023-11-24 12:23:20 +07:00
Huong Nguyen fdcd9ca6e4 Merge branch 'install_402_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_402_STABLE 2023-11-24 12:23:17 +07:00
David Woloszyn f59d91480d MDL-80229 core: Add tolerance to min_get_minimum_revision 2023-11-24 15:54:11 +11:00
Eloy Lafuente (stronk7) af58302ff7 Merge branch 'MDL-79966-m402' of https://github.com/sammarshallou/moodle into MOODLE_402_STABLE 2023-11-23 23:41:06 +01:00
sam marshall edb057d922 MDL-79966 core_task: NEVER_RUN_TIME did not fit in 10 digits 2023-11-23 16:24:15 +00:00
Rodrigo Mady 6f55283c98 MDL-79816 block_recentlyaccesseditems: Fix modname type in WS 2023-11-23 11:54:30 -03:00
Paul Holden d264ccea06 MDL-71336 forms: ensure grouped date elements have unique IDs.
Previously they were each taking the ID of their parent group element.
2023-11-23 12:01:33 +00:00
Andrew Nicols 5b9fc748bb Merge branch 'MDL-79966-m402' of https://github.com/sammarshallou/moodle into MOODLE_402_STABLE 2023-11-23 10:31:51 +08:00
Huong Nguyen 5ad71ada1d Merge branch 'MDL-78496-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2023-11-23 09:23:29 +07:00
Ilya Tregubov 02e4d6c6c5 Merge branch 'MDL-80157_storedfileproblem-402' of https://github.com/leonstr/moodle into MOODLE_402_STABLE 2023-11-23 09:47:26 +08:00
Ilya Tregubov f91b44c004 Merge branch 'MDL-79185-MOODLE_402_STABLE' of https://github.com/dmitriim/moodle into MOODLE_402_STABLE 2023-11-22 11:48:30 +08:00
Dmitrii Metelkin 521ca60292 MDL-79185 cache: don't throw exception if cache data is corrupted 2023-11-22 12:48:49 +11:00
Ilya Tregubov fb76e3a046 Merge branch 'MDL-78670-402' of https://github.com/rmady/moodle into MOODLE_402_STABLE 2023-11-22 09:11:21 +08:00
Paul Holden 9078635183 MDL-80185 lang: use iso6391 language code for HTML lang attributes.
This resolves accessibility issues where Moodle language pack codes
didn't always map to correspondingly named iso6391 codes.

Where this value is defined in the language configuration, it will
now be used.
2023-11-21 22:55:31 +00:00
Mikel Martín 0393e4cce5 MDL-80015 course: Fix category 'More' dropdown alignment
Co-authored-by: Stephen Sharpe <stephen.sharpe@synergy-learning.com>
2023-11-21 14:15:42 +01:00
Angelia Dela Cruz a0fdbfac3a MDL-79828 core_badges: Delete already awarded course badges 2023-11-21 17:23:46 +08:00
Amaia Anabitarte 6ccdd08641 MDL-79979 tool_generator: Use auto-enrol admin in new courses setting 2023-11-21 08:43:14 +01:00
sam marshall 8f01753027 MDL-79966 core_task: Scheduled task timing (crontab fields) is wrong 2023-11-20 17:11:32 +00:00
Rodrigo Mady 903c67404f MDL-78670 mod_quiz: Add offline atempt rule for sequential navigation 2023-11-20 12:08:24 -03:00
Juan Olivares 5cd19b757f MDL-74248 mod_folder: Fix mp3 files being unaccessible in chrome
Platform users that host mp3 files within a folder are not able to access them using Chrome. This fix allows them to do so.
2023-11-20 11:29:36 +01:00
Huong Nguyen 321facce94 Merge branch 'MDL-79604-402' of https://github.com/srobotta/moodle into MOODLE_402_STABLE 2023-11-20 14:01:52 +07:00
Laurent David 1358d27f82 MDL-79512 mod_feedback: Add toast dialog when saved
* Add notification to notify the user once the changes have been
successfully saved
2023-11-20 06:55:22 +01:00
Laurent David 2fe64cf016 MDL-79512 mod_feedback: Fix issue with drag and drop
* A teacher can not change the order of the questions in feedback
as the order is not saved.
2023-11-20 06:55:21 +01:00
AMOS bot f761432b06 Automatically generated installer lang files 2023-11-20 00:10:40 +00:00
Leon Stringer eba5cdff20 MDL-80157 file: Exception message spelling 2023-11-17 14:36:22 +00:00
Paul Holden b34a5d8376 MDL-79325 group: consistent name formatting in overview page/export. 2023-11-17 09:48:12 +00:00
Dominic Chin 6905fec8b3 MDL-80035 theme_boost: Fix fourth argument of single_button constructor 2023-11-17 09:15:12 +11:00
Sara Arjona 3790c0a8fe weekly release 4.2.3+ 2023-11-16 16:22:40 +01:00
Sara Arjona 5076567efd Merge branch 'install_402_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_402_STABLE 2023-11-16 16:22:36 +01:00
Paul Holden 3cc243bbd9 MDL-78849 user: correct logical operator behaviour for guest button.
Apart from being banned per MDL-74990, it causes a subtle bug here
due to operator precedence.

Co-authored-by: Tom Mayfield <tmayfield@costrack.com>
2023-11-16 11:32:02 +00:00
Huong Nguyen 5652247245 Merge branch 'MDL-76457-402' of https://github.com/roland04/moodle into MOODLE_402_STABLE 2023-11-16 10:58:39 +07:00
Huong Nguyen acd56e570f Merge branch 'MDL-80066-402' of https://github.com/elza3ym/moodle into MOODLE_402_STABLE 2023-11-16 10:53:20 +07:00
Ilya Tregubov 94904e3d33 Merge branch 'MDL-80121-402' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2023-11-16 10:01:24 +08:00
Ilya Tregubov 309ef4f8cf Merge branch 'MDL-75616-402' of https://github.com/davewoloszyn/moodle into MOODLE_402_STABLE 2023-11-16 09:23:38 +08:00
Mohamed Shehata 28d83c2e26 MDL-80066 form: fix date picker on small screens 2023-11-15 23:45:25 +02:00
Sara Arjona 129ca39c6d Merge branch 'MDL-79981-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2023-11-15 17:10:16 +01:00
Sara Arjona 5d93ccf205 Merge branch 'MDL-76937-402' of https://github.com/laurentdavid/moodle into MOODLE_402_STABLE 2023-11-15 16:33:14 +01:00
Sara Arjona ec412116cf Merge branch 'MDL-79697-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2023-11-15 16:15:56 +01:00
Andrew Nicols 328bf5f691 MDL-79697 core: PSR-4 NS can be spread across multiple dirs
The PSR-4 specification does not preclude a single namespaces from
having multiple sources. This is the case for several PSR standards
including standard packagist packages distributed by PSR:

- PSR-7 - HTTP Message Interfaces: \Psr\Http\Message
- PSR-17 - HTTP Factories: \Psr\Http\Message
- PSR-15 - http-server-handler: \Psr\Http\Server
- PSR-15 - http-server-middleware: \Psr\Http\Server
2023-11-15 21:25:08 +08:00
Sara Arjona e8356d64a8 Merge branch 'MDL-80045-402' of https://github.com/roland04/moodle into MOODLE_402_STABLE 2023-11-15 13:47:15 +01:00
Sara Arjona c2d63c1044 Merge branch 'MDL-79956-402' of https://github.com/ssj365/moodle into MOODLE_402_STABLE 2023-11-15 13:31:58 +01:00
Jun Pataleta 3c339154c8 MDL-80121 gradereport_singleview: Increase zero-state heading level
With the h2 heading not being rendered on the zero-state pages of the
Single view report, we need to increase the heading level of the
"Search for a user to view all their grades" and
"Select a grade item above" headings from h3 to h2.
2023-11-15 19:29:05 +08:00
Jun Pataleta ac6f82440a MDL-80121 grade: Trim heading
In order to prevent rendering an empty heading <h2>, we need to make
sure that the $heading parameter passed to print_grade_page_head() is
not an empty string.
2023-11-15 19:29:01 +08:00
Stephan Robotta f9a852881f MDL-79604 mod_data: exception if mandatory checkox list is missing 2023-11-15 12:23:51 +01:00
Dan Marsden 63c92d18f4 MDL-64431 assignfeedback_editpdf: Flatten PDF files 2023-11-15 19:29:09 +13:00
Angelia Dela Cruz c6d048f6fc MDL-79603 mod_scorm: Behat coverage for Scorm package display options 2023-11-15 10:53:41 +08:00
Huong Nguyen a5dd36b647 Merge branch 'MDL-79648-402' of https://github.com/SergioComeron/moodle into MOODLE_402_STABLE 2023-11-15 09:13:59 +07:00
Huong Nguyen 07f4965b83 Merge branch 'MDL-79601-402' of https://github.com/roland04/moodle into MOODLE_402_STABLE 2023-11-15 09:09:45 +07:00
Andrew Nicols bed2ece03a MDL-79890 core: Stop using get_class() without args
PHP 8.3 deprecates the use of `get_class()` without arguments. The
following alternatives should instead be used as appropriate:

- `get_class($this)` - The equivalent for instance methods
- `self::class` - The current class

Note that the behaviour of `get_class()` in a static method was
equivalent to `self::class` and _not_ `static::class`. That is to say
that the previous behaviour did not respect late static binding.
2023-11-15 09:14:08 +08:00
Andrew Nicols 4e03a113fa MDL-79890 core: ReflectionProperties::setValue() should take 2 args
Since PHP 8.3 setValue() must be called with null as the first arg if
called statically.
2023-11-15 09:13:08 +08:00
Mikel Martín e0f753bf5a MDL-76457 tool_usertours: Fix tour popovers in RTL 2023-11-14 21:27:44 +01:00
Mikel Martín 991926e9b6 MDL-76457 theme_boost: Fix bootstrap popovers in RTL
- Fix the arrow placement for bootstrap popovers in RTL mode.
- Remove unneded css parser workaround for popover arrows.
  After MDL-67386 was integrated those changes were not needed anymore.
2023-11-14 21:27:44 +01:00
Sara Arjona 9bd4f7f93f MDL-77581 lesson: Fix behat random failures 2023-11-14 16:24:49 +01:00
Andrew Nicols ce9a65ce4d MDL-78496 environment: Moodle 4.4 requirements
The only changes to requirements since Moodle 4.3 are increases to:

* the minimum PHP version required; and
* the minimum required Moodle version.
2023-11-14 22:47:55 +08:00
Andrew Nicols e7c8762353 MDL-80079 core: Correct incorrect arg to format_text::$options 2023-11-14 22:28:55 +08:00
Andrew Nicols 79a42253c3 MDL-80079 core: Correct incorrect arg to format_string::$options 2023-11-14 22:28:55 +08:00
Mikel Martín 07eb0e821e MDL-80045 block_starredcourses: Fix cards alignment in small screens 2023-11-14 14:36:29 +01:00
Sara Arjona 5f5a393f32 Merge branch 'MDL-77581-402' of https://github.com/dpalou/moodle into MOODLE_402_STABLE 2023-11-14 11:52:56 +01:00
Dani Palou 5409754f3d MDL-77581 lesson: Fix generator unit tests in oracle 2023-11-14 11:10:00 +01:00
SergioComeron 8cd37b6a4e MDL-79648 core_course: 29 October repeating day 2023-11-13 18:33:20 +01:00
Sara Arjona cf63a0afcc Merge branch 'MDL-77581-402' of https://github.com/dpalou/moodle into MOODLE_402_STABLE 2023-11-13 17:20:14 +01:00
Mark Johnson 03d18db837 MDL-79806 mod_quiz: Implement new quiz_attempt_deleted callback 2023-11-13 15:07:19 +00:00
Paul Holden 3aa910c237 MDL-79692 enrol_meta: check for group validity when adding members. 2023-11-13 10:23:20 +00:00
Huong Nguyen 7e5e176f43 Merge branch 'MDL-74129-402' of https://github.com/sarjona/moodle into MOODLE_402_STABLE 2023-11-13 10:43:36 +07:00
David Saylor c808279568 MDL-75616 backup: Use standard temp directory for extraction 2023-11-13 11:08:25 +11:00
AMOS bot 46363d6f0f Automatically generated installer lang files 2023-11-12 00:10:11 +00:00
Sara Arjona ee8960fdd7 MDL-74129 h5p: Preserve metadata information
The metadata information was not restored when an H5P file was uploaded
(it was saved when it was edited directly from the Content bank, but the
original information in the H5P file was lost).
This patch includes all the metadata fields and its values in the original
H5P file to preserve this information too.
2023-11-10 10:33:57 +01:00
Ilya Tregubov d7e3b07082 weekly release 4.2.3+ 2023-11-10 09:17:20 +08:00
Dani Palou 9efd86d55b MDL-77581 behat: Test create lesson pages using UI 2023-11-09 11:32:53 +01:00
Dani Palou cd5d5a3090 MDL-77581 behat: Apply new lesson cluster generators to existing tests 2023-11-09 11:32:53 +01:00
Dani Palou 7cb334e138 MDL-77581 behat: Create generators for lesson clusters 2023-11-09 11:32:53 +01:00
Dani Palou dcc18dced2 MDL-77581 lesson: Fix wrong PHPDoc in some generator functions
While creating the new perform_create_page function I noticed that the PHPDoc return type of the existing functions was wrong
2023-11-09 11:07:00 +01:00
Dani Palou b4c4904af1 MDL-77581 behat: Remove lesson_student_dashboard test file
After f7c476bac5 was integrated, these tests didn't assert anything specific and similar steps are already tested in lesson_navigation
2023-11-09 11:06:43 +01:00
Dani Palou 40bf6fced0 MDL-77581 behat: Apply new lesson generators to existing tests 2023-11-09 11:06:33 +01:00
Dani Palou 6e979a85c0 MDL-77581 behat: Create generators for lesson pages and answers 2023-11-09 11:04:00 +01:00
Dani Palou a27cae466c MDL-77581 behat: Support finish_generate_ in generators 2023-11-09 11:03:43 +01:00
Shamiso.Jaravaza f201ab66d3 MDL-79956 mod_bigbluebuttonbn: fix import links 2023-11-08 21:47:29 -07:00
Michael Aherne 75fae6a479 MDL-80030 filelib: Fix info type. 2023-11-09 11:13:59 +08:00
Ilya Tregubov 9e94c6b857 Merge branch 'MDL-79992-402' of https://github.com/sarjona/moodle into MOODLE_402_STABLE 2023-11-09 09:57:41 +08:00
Sara Arjona 17571e2f05 Merge branch 'MDL-79827-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-11-08 18:10:49 +01:00
Sara Arjona 81cf77e4e2 Merge branch 'MDL-79975-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-11-08 18:03:14 +01:00
Sara Arjona d716c7e54b Merge branch 'MDL-79781-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-11-08 17:20:08 +01:00
Sara Arjona 7396a627fc Merge branch 'MDL-76555-402' of https://github.com/pmaneggia/moodle into MOODLE_402_STABLE 2023-11-08 17:06:24 +01:00
Mikel Martín 0a6c151515 MDL-79601 report_completion: Fix RTL First/Last name alignment 2023-11-08 16:23:32 +01:00
Mikel Martín 1af6dd1035 MDL-79601 report_progress: Fix RTL First/Last name alignment 2023-11-08 16:23:32 +01:00
Laurent David c5f89e6730 MDL-76937 core_course: Delete button can be used twice
* Disable the Delete button in the confirmation dialog once
clicked so we avoid running the process twice by mistake.
2023-11-08 07:53:18 +01:00
Andrew Nicols 7364fe4716 MDL-79981 core: Add ability to manually run and filter phpunit on GHA 2023-11-08 12:53:54 +08:00
Ilya Tregubov f6a14afe2d Merge branch 'MDL-79615_402_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_402_STABLE 2023-11-08 10:43:39 +08:00
Huong Nguyen c4db30f0ef Merge branch 'MDL-79739-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2023-11-08 09:24:09 +07:00
Ilya Tregubov d1cdb4dce5 Merge branch 'MDL-79858-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-11-08 09:50:05 +08:00
Paul Holden d6ffa9bd39 MDL-79267 mod_forum: define report subplugin type language strings. 2023-11-07 09:50:02 +00:00
Huong Nguyen de9d123349 Merge branch 'MDL-78953-402' of https://github.com/pedrojordao/moodle into MOODLE_402_STABLE 2023-11-07 15:34:06 +07:00
Jun Pataleta bdba59a789 Merge branch 'MDL-80019-402' of https://github.com/call-learning/moodle into MOODLE_402_STABLE 2023-11-07 13:13:36 +08:00
Laurent David ee4849900d MDL-80019 mod_bigbluebuttonbn: Completion form freeze fix
* When the completion is locked, we should not be able to edit the completion elements
2023-11-06 22:11:31 +01:00
Sara Arjona 144c6b4dae Merge branch 'mdl-78650-402-stable' of https://github.com/Fragonite/moodle into MOODLE_402_STABLE 2023-11-06 09:51:06 +01:00
Huong Nguyen ec1f6f2cf5 Merge branch 'MDL-79062-402-2' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2023-11-06 10:52:18 +07:00
Paola Maneggia 02ca268931 MDL-76555 mod_resource: Fix PHP8.0 type error (legacy resources) 2023-11-05 13:47:32 +01:00
Mikel Martín e66840a3a7 MDL-80002 forumreport_summary: Fix summary report date filtering 2023-11-03 15:47:33 +01:00
Sara Arjona f58a867a50 MDL-79992 backup: Display course backups from activity restore
The Course backup area was not displaying the course backups when
accessing to the Restore page for an activity because the context
was not updated properly for this area.
2023-11-03 12:23:26 +01:00
Pedro Jordao 1ff16a3823 MDL-78953 autocomplete: Add only one empty option when deselecting item.
Each option that was deselected was prepending an empty option in the select.
2023-11-02 18:55:48 -03:00
Paul Holden d4596bf0a0 MDL-79975 tool_task: correct class attribute table cell property. 2023-11-02 13:19:57 +00:00
Sara Arjona 5d44f11444 weekly release 4.2.3+ 2023-11-02 13:41:09 +01:00
Jun Pataleta dc5a065006 MDL-79062 grade: Behat test fixes
* Feature: We can use a minimum grade different than zero
  - Use correct minimum input values.
  - Use data generators for faster test execution.
* Scenario: Disable category overriding
  - Use the field name to ensure that the correct field is being tested.
2023-11-02 17:32:42 +08:00
Jun Pataleta 7e5a2f73df MDL-79062 grades: Sort-by-name menu item accessibility fixes
* <h6> tags cannot be in table cells. Replace them with <div> tags.
* Group the ascending/descending sort menu items to better indicate
where they belong to.
2023-11-02 17:32:42 +08:00
Jun Pataleta 25c1db7275 MDL-79062 gradereport_grader: Set numeric type for grade value inputs
* Set grade inputs for grade items with type set to GRADE_VALUE to
number and add min and max input attributes, where necessary.
2023-11-02 17:32:42 +08:00
Huong Nguyen 467a6be1f1 Merge branch 'MDL-78903-402' of https://github.com/meirzamoodle/moodle into MOODLE_402_STABLE 2023-11-02 10:18:48 +07:00
Huong Nguyen f4e322aa3c Merge branch 'MDL-79801-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-11-02 10:15:15 +07:00
Huong Nguyen 4fb844989a Merge branch 'MDL-79617_402_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_402_STABLE 2023-11-02 09:04:49 +07:00
Jun Pataleta 6f91e223e1 MDL-79062 gradereport_grader: Remove setting of tabindex >= 1
Tab indices that are greater than or equal to 1 break the natural
tab order of the document and may cause problems for keyboard users.
2023-11-02 09:50:42 +08:00
Alexander Van der Bellen b77c00f3f5 MDL-78650 mod_assign: Improve group submission action event handling
Don't return an event action when a group submission has already been submitted
by another student.
2023-11-01 20:34:42 +08:00
Alexander Van der Bellen ec78f6135b MDL-78650 mod_assign: Add Behat test 2023-11-01 20:34:36 +08:00
Alexander Van der Bellen 82acec75cb MDL-78650 mod_assign: Add unit test 2023-11-01 20:34:33 +08:00
Daniel Neis Araujo fcaf6f601e MDL-73378 gradebook: Category grade null when all subgrades are null 2023-10-31 13:55:10 -03:00
Sara Arjona 900a3f35ef Merge branch 'MDL-79856-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-10-31 13:26:37 +01:00
Jun Pataleta fbd085e68d Merge branch 'MDL-79853-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2023-10-31 16:45:56 +08:00
Huong Nguyen 22d17775f6 Merge branch 'MDL-79807_402_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_402_STABLE 2023-10-31 12:51:18 +08:00
Meirza 90408b2e64 MDL-78903 tiny_h5p: show repositories if editor filepicker type set 2023-10-31 08:04:35 +07:00
Meirza ae3fac6ddd MDL-78903 tiny_media: show repositories if editor filepicker type set 2023-10-31 08:04:21 +07:00
Jun Pataleta 2269130354 Merge branch 'MDL-77274-402' of https://github.com/laurentdavid/moodle into MOODLE_402_STABLE 2023-10-30 17:13:50 +08:00
Laurent David bbd015f89b MDL-77274 core_renderer: Respect full name format in letter avatars
* Make sure that we respect the fullnamedisplay and alternativefullnameformat
parameters to decide on the initials for a given user
* Add further tests

Co-authored-by: Tatsunori Uchino <tats.u@live.jp>
2023-10-30 06:17:57 +01:00
Huong Nguyen 8186259f7e Merge branch 'MDL-79639_402_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_402_STABLE 2023-10-30 11:23:40 +07:00
Jun Pataleta be729ebf64 Merge branch 'MDL-79194-402' of https://github.com/laurentdavid/moodle into MOODLE_402_STABLE 2023-10-27 23:31:56 +08:00
Mark Johnson 690b27c832 MDL-79615 course: Improve efficency of cache rebuilds
When bulk-updating course module visibility, set_coursemodule_visibily
was triggering a partial cache purge and rebuild for each course module.
This potentially led to 2 cache sets each requiring a lock to be
acquired and released per course module, plus any other cache updates
for other changes to the course in the same request.

This adds a new $rebuildcache paramter to the
set_coursemodule_visibilty, which is true by default to retain the
existing behaviour. If set false, it will skip doing the partial purge
and rebuild for that course module, and it is up to the calling code to
ensure the cache is updated as requried.

To assist with this, there is a new
course_modinfo::purge_course_module_cache_multiple() method, which
allows multiple course modules to be purged from the cache in a single
cache set.
2023-10-27 10:51:45 +01:00
Jun Pataleta 3b0433e44d Merge branch 'MDL-77364-402' of https://github.com/sarjona/moodle into MOODLE_402_STABLE 2023-10-27 16:33:55 +08:00
Sara Arjona 074d411eb7 MDL-77364 myoverview: Display course name tooltip
Based on the feedback given by the UX team:
- The text has been increased to display more (50 vs 55).
- A tooltip has been added to display the full course name on hover,
following the accessibility guidelines.
2023-10-27 07:26:32 +02:00
Jun Pataleta 933c9c0756 weekly release 4.2.3+ 2023-10-27 09:43:08 +08:00
Jun Pataleta d9e4881aa5 Merge branch 'MDL-79768-402-fix' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2023-10-26 23:05:41 +08:00
Mark Johnson 9586685724 MDL-79807 quiz_statistics: Clear stats cache when question added/removed 2023-10-26 13:44:44 +01:00
Paul Holden 8561485239 MDL-79858 block_myoverview: correctly export request course button. 2023-10-26 13:40:37 +01:00
Paul Holden 479faa9735 MDL-79781 course: detect invalid creator role for pending courses. 2023-10-26 13:18:39 +01:00
Ferran Recio 41f098e7da MDL-79194 core_courseformat: optimize section reload
* When reloading a section, we also forced the reloading of
course modules, resulting in doing the same work twice (once for
the section reload and once for the course module reload)
* Debounce the reloading process so prevent unwanted duplicate
reloads
2023-10-26 14:11:10 +02:00
Paul Holden 8be8e244dd MDL-79856 roles: use role localname when confirming deletion. 2023-10-26 12:01:02 +01:00
Angelia Dela Cruz b5d5825b3f MDL-79768 fix: Fixed random failing Behat due to time difference 2023-10-26 18:02:08 +08:00
Andrew Nicols 38f2aaf4d7 MDL-79853 core: Add phpunit options to manual runs 2023-10-26 14:48:59 +08:00
Jun Pataleta d014dc94ab Merge branch 'MDL-79768-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2023-10-26 10:47:48 +08:00
Jun Pataleta 4c041328c8 Merge branch 'MDL-42189-402' of https://github.com/davewoloszyn/moodle into MOODLE_402_STABLE 2023-10-26 10:32:08 +08:00
Jun Pataleta e68ebb8a7b Merge branch 'MDL-75572-402' of https://github.com/sarjona/moodle into MOODLE_402_STABLE 2023-10-25 13:44:33 +08:00
Sara Arjona 65f0bfdc49 MDL-75572 criteria: Only award badges to sucessfull completions
The UX team confirmed a badge shouldn't be awarded when the criteria
use a passing grade and the user gets a failing grade.
So the COMPLETION_COMPLETE_FAIL status won't be considered
completed for activities with completion that require a passing
grade.
2023-10-25 07:07:39 +02:00
Andrew Lyons 560c42964d MDL-79194 core: Wrap combobox debounce in pending Promise
This addresses a random failure with the combobox search results where
the debounce causes the results to be shown, and then the same search
result is returned again, re-rendered, and replaced after Behat has
moved on.

Partly cherry-picked from MDL-78779.
2023-10-24 13:40:48 +08:00
Jun Pataleta faa16533da Merge branch 'MDL-79637-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2023-10-24 10:49:05 +08:00
Paul Holden 926fe4f429 MDL-79827 tiny_link: show repositories only if editor filepicker set. 2023-10-23 22:07:01 +01:00
Mark Johnson a9ed3dd710 MDL-79617 repository_upload: Close session early in upload process 2023-10-23 15:32:36 +01:00
Angelia Dela Cruz b3afaa0c54 MDL-79768 mod_data: Test for student can see upcoming data activity 2023-10-23 08:48:27 +08:00
David Woloszyn 8d3962e056 MDL-42189 gradereport_overview: Report hidden from suspended enrolments 2023-10-23 09:47:08 +11:00
Paul Holden 1fcd9911d9 MDL-79801 tag: fix report entity flagged column/filter query.
The "flag" field isn't a boolean state (1/0), it's a cumulative
count of how many times the tag has been flagged by users. This
should be accounted for to ensure that column aggregation and
filtering performs correctly.
2023-10-20 14:22:27 +01:00
Sara Arjona bfb3763947 weekly release 4.2.3+ 2023-10-20 12:16:24 +02:00
Huong Nguyen 3549288d8d Merge branch 'MDL-78775-402' of https://github.com/ilyatregubov/moodle into MOODLE_402_STABLE 2023-10-20 09:30:30 +07:00
Ilya Tregubov 025ab5fc7f MDL-78775 gradereport_grade: Fix Behat.
Sort by lastname before doing any assertions.
2023-10-20 09:57:00 +08:00
Mark Johnson 6a9e714c97 MDL-79639 quiz_statistics: Prevent database deadlocks
This changes the cache purge code to select IDs for deletion
first, rather than using a subquery in a DELETE, since this
risks causing a deadlock in MySQL.
2023-10-19 08:58:07 +01:00
Huong Nguyen 25b30d5a43 Merge branch 'MDL-79689-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2023-10-19 10:04:31 +07:00
Sara Arjona 16cc533e46 Merge branch 'MDL-79635-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-10-18 19:55:55 +02:00
Sara Arjona 855bc6da54 Merge branch 'MDL-77651-402' of https://github.com/junpataleta/moodle into MOODLE_402_STABLE 2023-10-18 15:47:17 +02:00
Sara Arjona 8e34fa9bf8 Merge branch 'MDL-79747_402' of https://github.com/timhunt/moodle into MOODLE_402_STABLE 2023-10-18 10:29:02 +02:00
Huong Nguyen a3f5947c41 Merge branch 'MDL-78775-402' of https://github.com/ilyatregubov/moodle into MOODLE_402_STABLE 2023-10-18 12:57:47 +07:00
Ilya Tregubov a780e2253e MDL-78775 core_grades: Fix Behat 2023-10-18 12:53:02 +08:00
Angelia Dela Cruz e6c9273720 MDL-79689 mod_assign: Behat for enabling anonymous submissions 2023-10-18 10:52:57 +08:00
Huong Nguyen bc075c9653 Merge branch 'MDL-79705-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-10-18 09:37:05 +07:00
Huong Nguyen fd1ce04f08 Merge branch 'MDL-78979-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-10-18 09:23:53 +07:00
Jun Pataleta f52f6d5719 MDL-77651 calendar: Hide left/right arrow characters
* Hide the arrow characters for the calendar templates so they won't be
read out by screen readers and avoid confusion for screen reader users.
2023-10-17 23:52:01 +08:00
Jun Pataleta a7d8106957 MDL-77651 core: Hide left/right arrow characters for link_arrow_xx()
* The arrow characters in link_arrow_right() and link_arrow_left()
functions get announced by screen readers. This causes confusion
and is unnecessary.
2023-10-17 23:52:01 +08:00
Paul Holden f80cf55ab3 MDL-79705 reportbuilder: remove checkbox field callback handling.
We no longer need special handling of this field type, because it
now returns language strings rather than HTML markup for a checkbox
element on display.
2023-10-17 16:51:31 +01:00
Paul Holden 6cc24abb78 MDL-79705 profilefield_checkbox: display data as simple Yes/No. 2023-10-17 16:51:31 +01:00
Tim Hunt 04d92abc79 MDL-79747 quiz stats: task should run as admin the right way
The correct way to get an ad-hoc task to run as the main admin account
is to leave userid as null.

Setting it causes fatal errors if the main admin account is set to
auth: nologin.
2023-10-17 16:44:08 +01:00
Sara Arjona c1db959770 Merge branch 'MDL-78481-402' of https://github.com/iarenaza/moodle into MOODLE_402_STABLE 2023-10-17 17:15:17 +02:00
Andrew Nicols 7544f66e0e MDL-79739 core: Only run some tests in separate processes 2023-10-17 12:21:21 +08:00
Huong Nguyen a7cf0a9da8 Merge branch 'MDL-78775-402' of https://github.com/ilyatregubov/moodle into MOODLE_402_STABLE 2023-10-17 10:47:41 +07:00
Ilya Tregubov 9d602fb813 Merge branch 'MDL-79691-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2023-10-17 10:28:49 +08:00
Huong Nguyen d1bb8ef0f5 Merge branch 'MDL-79367-402' of https://github.com/sarjona/moodle into MOODLE_402_STABLE 2023-10-17 09:18:05 +07:00
Paul Holden 9ebc3f2fdc MDL-78979 mod_data: correct restore decode rule for data view page. 2023-10-16 20:53:58 +01:00
Angelia Dela Cruz 5dca2f72dd MDL-79691 mod_h5pactivity: Behat coverage for H5P activity grades reset 2023-10-16 16:52:41 +08:00
Sara Arjona a03972b0f3 Merge branch 'MDL-79566-402' of https://github.com/HuongNV13/moodle into MOODLE_402_STABLE 2023-10-16 09:53:53 +02:00
Ilya Tregubov 6444c72bed Merge branch 'MDL-79365-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-10-16 14:08:23 +08:00
Sara Arjona 895c094a9b MDL-79367 availability: Fail grade does not mark activities as completed
The UX team confirmed that an activity shouldn't be considered completed
when the criteria use a passing grade and the user gets a failing grade.
So the COMPLETION_COMPLETE_FAIL status won't be considered
completed from now on.
2023-10-16 07:54:07 +02:00
Huong Nguyen e57d09c00d Merge branch 'MDL-79698-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2023-10-16 11:40:09 +07:00
Huong Nguyen dcb935bf21 Merge branch 'MDL-79653-402' of https://github.com/andelacruz/moodle into MOODLE_402_STABLE 2023-10-16 10:54:59 +07:00
Huong Nguyen ebb8eeb4bd Merge branch 'MDL-79352-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-10-16 10:42:29 +07:00
Huong Nguyen b93fa5e412 MDL-79566 tiny_autosave: Add Javascript submission handler 2023-10-16 09:29:22 +07:00
Paul Holden c426f8e97e MDL-79365 customfield_textarea: ensure field uniqueness is correct. 2023-10-13 14:30:02 +01:00
Andrew Nicols c6ca6cd629 MDL-79698 core: Correct duplicate array key in test provider 2023-10-13 15:44:26 +08:00
Ilya Tregubov f0c782c87c MDL-78775 core_grades: Fix saving on grader report page
When we have a pagination on grader page and search for user
that is not on first page, saving was throwing an error
since page didn't have enough data
2023-10-13 14:20:11 +08:00
Ilya Tregubov ce43783c16 weekly release 4.2.3+ 2023-10-13 13:39:28 +08:00
Angelia Dela Cruz e1168e9a33 MDL-79653 gradingform_guide: Behat coverage for deleting marking guide 2023-10-13 10:58:57 +08:00
Huong Nguyen f97a376cd7 Merge branch 'MDL-79638-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2023-10-12 11:07:41 +07:00
Ilya Tregubov f71088b26a Merge branch 'MDL-79160-402' of https://github.com/danghieu1407/moodle into MOODLE_402_STABLE 2023-10-12 09:44:01 +08:00
Ilya Tregubov d3d0e0d147 Merge branch 'MDL-79422-402' of https://github.com/andrewnicols/moodle into MOODLE_402_STABLE 2023-10-12 09:09:52 +08:00
Jun Pataleta 4a2b27a493 Merge branch 'MDL-79611-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-10-11 18:15:32 +08:00
Jun Pataleta 7cb3f15da7 Merge branch 'MDL-79633-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-10-11 13:41:24 +08:00
Huong Nguyen 086cdc566b Merge branch 'MDL-78103-402' of https://github.com/HuongNV13/moodle into MOODLE_402_STABLE 2023-10-11 11:25:30 +07:00
chen levy d009f95aeb MDL-78103 theme: Fixed dropdown menu size by the content 2023-10-11 11:14:43 +07:00
Andrew Nicols 77f8e2b834 MDL-79637 phpunit: Do not reset DB during init of isolated tests
During the bootstrap of PHPUnit we ensure that the database has been
reset to its initial state.

We do this by checking the internally-stored DB write count between
runs. If the count is not yet set (null), or it has been increased, we
force a reset.

When running an isolated test the test runner resets the database, it
then sets up a new isolated test environment by writing a new PHPUnit
test case and passing it to a new PHP Process using standard in. As part
of this, the bootstrap is run for that process.

Because we are in a new process, the db write count is fresh and not yet
set. This has been leading to an additional db reset before the isolated
test.

To handle this we want to _not_ perform a reset during the
initialisation for isolated runs. We know that the DB is in a fresh
state before we start the run.

To support this we need to know whether the test is an isolated test
during the bootstrap, which means we cannot use the previous approach to
calculating this.

Instead we look at the PHP_SELF value. PHP sets this to "Standard input
code" when run from stdin, instead of running a file.

There should not be any other legitimate reason to run a PHPUnit
bootstrap via this stdin approach.

Unfortunately this approach is a little bit risky as it depends on the
presence of a specific string, however this string has been in place
since 2016, and there is no legitimate way of calculating this.

I did consider looking at whether the called script included `/vendor/`
and `/phpunit`, but this is also likely a risky approach if someone
calls PHPUnit in an unexpected way.

This approach is itself unit tested so any change to PHP's stdin string
before we deprecate this approach entirely in 12 months time will be
caught.
2023-10-11 09:29:26 +08:00
Andrew Nicols a4cf2b2a59 MDL-79638 phpunit: Add unit test for increment resets 2023-10-11 00:10:33 +08:00
Andrew Nicols f3de0635a1 MDL-79638 phpunit: Remove mysql/mariadb hack
This hack was introduced to work around a bug in MySQL 5.6.14 and
MariaDB at the time.

https://bugs.mysql.com/bug.php?id=69882

It was addressed a few months later in 5.6.16, and 5.7.4.
MariaDB merged version 5.6.16 of MySQL's InnoDB engine in MariaDB
10.0.11 and got hte patch from there.

Moodle has required MySQL 8.0, and MariaDB 10.6.7 since Moodle 4.2 and
it is therefore safe to remove these hacks.
2023-10-10 23:35:55 +08:00
Sara Arjona 1f3cf81ff2 Merge branch 'MDL-79623-MOODLE_402_STABLE' of https://github.com/PhMemmel/moodle into MOODLE_402_STABLE 2023-10-10 16:19:25 +02:00
Paul Holden 7e7f7fc803 MDL-79635 group: ensure unique params used to determine visibility.
Or we'll trigger DML "Incorrect number of query parameters" exception.
2023-10-10 10:08:59 +01:00
Sara Arjona 09740de2e2 Merge branch 'MDL-77816-402' of https://github.com/paulholden/moodle into MOODLE_402_STABLE 2023-10-10 09:21:34 +02:00
Ilya Tregubov 914fadcd2c Merge branch 'MDL-79501-MOODLE_402_STABLE' of https://github.com/geichelberger/moodle into MOODLE_402_STABLE 2023-10-10 15:07:01 +08:00
Ilya Tregubov 8d4c5ee417 Merge branch 'MDL-79279_402' of https://github.com/timhunt/moodle into MOODLE_402_STABLE 2023-10-10 11:24:12 +08:00
Ilya Tregubov 608528726a Merge branch 'MDL-71414-402' of https://github.com/laurentdavid/moodle into MOODLE_402_STABLE 2023-10-10 10:19:22 +08:00
Paul Holden 3cbd94ce8b MDL-79633 mod_data: correct timemodified tag replacement attribute. 2023-10-09 19:41:10 +01:00
Paul Holden c911a134fd MDL-79352 admin: fix links to tool plugin management page. 2023-10-09 15:11:18 +01:00
Laurent David 2e95ee0fb2 MDL-71414 mod_h5pactivity: Add a new "None" message
* In matching types of questions, sometimes the user does not answer all
questions. We now display "None" in the result report. The answer can
be either correct or incorrect.
* Fix "unknown" answer constant name.
2023-10-09 11:57:44 +02:00
Laurent David cdbfb77b5c MDL-71414 mod_h5pactivity: Fix issue with drop down report
* Drag and Drop report were missing answers when target could be dropped on multiple
drop zones.
2023-10-09 11:57:43 +02:00
Philipp Memmel fb15469759 MDL-79623 tool_componentlibrary: Fix correct modal content attribute 2023-10-09 09:05:44 +00:00
Paul Holden aed9018825 MDL-79611 group: early exit getting members of non-existing group. 2023-10-05 22:37:00 +01:00
danghieu1407 a375941564 MDL-79160 Question: Answer field overflows parent width with large size 2023-10-05 11:03:30 +07:00
Paul Holden d07882d219 MDL-77816 mod_bigbluebuttonbn: feedback when validating completion. 2023-10-04 21:06:40 +01:00
Yannick Schillinger 262a3951ae MDL-77816 mod_bigbluebuttonbn: Fix completionValidate argument format 2023-10-04 20:27:27 +01:00
Tim Hunt eff2ee3103 MDL-79279 qformat_xml: multianswer import should support idnumber
Fix suggested by Georg Maißer.
2023-10-03 20:42:23 +01:00
Gregor Eichelberger 3e05ff74bc MDL-79501 tiny: Fix editing multiple videos
The selection gets lost while opening the modal dialogue to update an
embedded media. Caching the current selection allows us to update the
previously selected node instead of updating the first embedded media.

Signed-off-by: Gregor Eichelberger <gregor.eichelberger@tuwien.ac.at>
2023-09-29 13:06:06 +02:00
Andrew Nicols 35cec39a6d MDL-79422 ajax: Allow no-login WS calls to fetch after a failure 2023-09-20 16:02:31 +08:00
Laurent David e455c5bdb8 MDL-79194 core_course: Refresh modules menus with section changes
* Whenever a section is hidden, we need to refresh all contextual (hamburger)
menus of each course modules.
2023-09-13 11:16:09 +02:00
Iñaki Arenaza fa331c5360 MDL-78481 mod_lesson: matching pagetype applying filters fix 2023-07-31 16:30:20 +02:00
1202 changed files with 12951 additions and 4562 deletions
+10 -4
View File
@@ -7,6 +7,12 @@ on:
- MOODLE_[0-9]+_STABLE
tags-ignore:
- v[0-9]+.[0-9]+.[0-9]+*
workflow_dispatch:
inputs:
phpunit_extra_options:
description: Additional options to apply to PHPUnit
required: false
default: ''
env:
php: 8.2
@@ -17,10 +23,10 @@ jobs:
steps:
- name: Checking out code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Configuring node & npm
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -99,7 +105,7 @@ jobs:
coverage: none
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setting up PHPUnit
env:
@@ -115,4 +121,4 @@ jobs:
env:
dbtype: ${{ matrix.db }}
phpunit_options: ${{ secrets.phpunit_options }}
run: vendor/bin/phpunit $phpunit_options
run: vendor/bin/phpunit $phpunit_options ${{ inputs.phpunit_extra_options }}
+10 -5
View File
@@ -1,7 +1,12 @@
name: Windows Testing
on:
workflow_dispatch
workflow_dispatch:
inputs:
phpunit_extra_options:
description: Additional options to apply to PHPUnit
required: false
default: ''
env:
php: 8.2
@@ -16,10 +21,10 @@ jobs:
git config --global core.eol lf
- name: Checking out code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Configuring node & npm
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -112,7 +117,7 @@ jobs:
git config --global core.eol lf
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
uses: actions/checkout@v3
uses: actions/checkout@v4
# Needs to be done after php is available, git configured and Moodle checkout has happened.
- name: Setting up moodle-exttests service
@@ -141,4 +146,4 @@ jobs:
env:
dbtype: ${{ matrix.db }}
phpunit_options: ${{ secrets.phpunit_options }}
run: vendor/bin/phpunit $phpunit_options
run: vendor/bin/phpunit $phpunit_options ${{ inputs.phpunit_extra_options }}
@@ -19,7 +19,7 @@ namespace core_admin\table;
use moodle_url;
/**
* Tiny admin settings.
* Admin tool settings.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
@@ -30,12 +30,6 @@ class tool_plugin_management_table extends \core_admin\table\plugin_management_t
return 'tool';
}
public function guess_base_url(): void {
$this->define_baseurl(
new moodle_url('/admin/tools.php')
);
}
protected function get_column_list(): array {
$columns = parent::get_column_list();
@@ -45,6 +39,6 @@ class tool_plugin_management_table extends \core_admin\table\plugin_management_t
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/tool.php', $params);
return new moodle_url('/admin/settings.php', array_merge(['section' => 'toolsmanagement'], $params));
}
}
+2 -2
View File
@@ -80,8 +80,8 @@ if (!$category = $DB->get_record('course_categories', ['id' => $options['categor
throw new \moodle_exception('invalidcategoryid');
}
$backupdir = "restore_" . uniqid();
$path = $CFG->tempdir . DIRECTORY_SEPARATOR . "backup" . DIRECTORY_SEPARATOR . $backupdir;
$backupdir = restore_controller::get_tempdir_name(SITEID, $USER->id);
$path = make_backup_temp_directory($backupdir);
cli_heading(get_string('extractingbackupfileto', 'backup', $path));
$fp = get_file_packer('application/vnd.moodle.backup');
+191
View File
@@ -4305,4 +4305,195 @@
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
<MOODLE version="4.4" requires="4.1.2">
<UNICODE level="required">
<FEEDBACK>
<ON_ERROR message="unicoderequired" />
</FEEDBACK>
</UNICODE>
<DATABASE level="required">
<VENDOR name="mariadb" version="10.6.7" />
<VENDOR name="mysql" version="8.0" />
<VENDOR name="postgres" version="13" />
<VENDOR name="mssql" version="14.0" />
<VENDOR name="oracle" version="19" />
</DATABASE>
<PHP version="8.1.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="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_EXTENSION name="exif" level="optional"/>
</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="required">
<FEEDBACK>
<ON_ERROR message="sixtyfourbitsrequired" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_max_input_vars" level="optional">
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_admin_dir_usage" level="optional">
<FEEDBACK>
<ON_CHECK message="iscustomadminwarnings" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_xmlrpc_usage" level="optional">
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mod_assignment" level="required">
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_db_prefix_length" level="required">
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
</COMPATIBILITY_MATRIX>
+2 -2
View File
@@ -761,8 +761,8 @@ class manager {
public function delete_preset(int $presetid): void {
global $DB;
// Check the preset exists.
$preset = $DB->get_record('adminpresets', ['id' => $presetid]);
// Check the preset exists (cannot delete the pre-installed core "Starter" and "Full" presets).
$preset = $DB->get_record('adminpresets', ['id' => $presetid, 'iscore' => self::NONCORE_PRESET]);
if (!$preset) {
throw new moodle_exception('errordeleting', 'core_adminpresets');
}
+20 -1
View File
@@ -16,6 +16,7 @@
namespace core_adminpresets;
use moodle_exception;
use stdClass;
/**
@@ -599,10 +600,28 @@ class manager_test extends \advanced_testcase {
$manager = new manager();
$this->expectException(\moodle_exception::class);
$this->expectException(moodle_exception::class);
$this->expectExceptionMessage('Error deleting from database');
$manager->delete_preset($unexistingid);
}
/**
* Test trying to delete the core/pre-defined presets
*
* @covers ::delete_preset
*/
public function test_delete_preset_core(): void {
global $DB;
$this->resetAfterTest();
$starterpreset = $DB->get_record('adminpresets', ['iscore' => manager::STARTER_PRESET]);
$this->expectException(moodle_exception::class);
$this->expectExceptionMessage('Error deleting from database');
(new manager())->delete_preset($starterpreset->id);
}
/**
* Test the behaviour of delete_preset() method.
*
+32 -43
View File
@@ -49,26 +49,11 @@ if ($action == 'newon') {
admin_externalpage_setup($pagename);
$sesskeyurl = $CFG->wwwroot.'/'.$CFG->admin.'/repository.php?sesskey=' . sesskey();
$baseurl = $CFG->wwwroot.'/'.$CFG->admin.'/repository.php';
$configstr = get_string('manage', 'repository');
// The URL used for redirection, and that all edit related URLs will be based off.
$baseurl = new moodle_url('/admin/repository.php');
$return = true;
if (!empty($action)) {
require_sesskey();
}
/**
* Helper function that generates a moodle_url object
* relevant to the repository
*/
function repository_action_url($repository) {
global $baseurl;
return new moodle_url($baseurl, array('sesskey'=>sesskey(), 'repos'=>$repository));
}
if (($action == 'edit') || ($action == 'new')) {
$pluginname = '';
if ($action == 'edit') {
@@ -182,16 +167,12 @@ if (($action == 'edit') || ($action == 'new')) {
}
}
} else if ($action == 'show') {
if (!confirm_sesskey()) {
throw new \moodle_exception('confirmsesskeybad', '', $baseurl);
}
require_sesskey();
$class = \core_plugin_manager::resolve_plugininfo_class('repository');
$class::enable_plugin($repository, 1);
$return = true;
} else if ($action == 'hide') {
if (!confirm_sesskey()) {
throw new \moodle_exception('confirmsesskeybad', '', $baseurl);
}
require_sesskey();
$class = \core_plugin_manager::resolve_plugininfo_class('repository');
$class::enable_plugin($repository, 0);
$return = true;
@@ -199,9 +180,7 @@ if (($action == 'edit') || ($action == 'new')) {
$repositorytype = repository::get_type_by_typename($repository);
if ($sure) {
$PAGE->set_pagetype('admin-repository-' . $repository);
if (!confirm_sesskey()) {
throw new \moodle_exception('confirmsesskeybad', '', $baseurl);
}
require_sesskey();
if ($repositorytype->delete($downloadcontents)) {
// Include this information into config changes table.
@@ -220,20 +199,15 @@ if (($action == 'edit') || ($action == 'new')) {
$output = $OUTPUT->box_start('generalbox', 'notice');
$output .= html_writer::tag('p', $message);
$removeurl = new moodle_url($sesskeyurl);
$removeurl->params(array(
$removeurl = new moodle_url($baseurl, [
'action' =>'delete',
'repos' => $repository,
'sure' => 'yes',
));
]);
$removeanddownloadurl = new moodle_url($sesskeyurl);
$removeanddownloadurl->params(array(
'action' =>'delete',
'repos'=> $repository,
'sure' => 'yes',
$removeanddownloadurl = new moodle_url($removeurl, [
'downloadcontents' => 1,
));
]);
$output .= $OUTPUT->single_button($removeurl, get_string('continueuninstall', 'repository'));
$output .= $OUTPUT->single_button($removeanddownloadurl, get_string('continueuninstallanddownload', 'repository'));
@@ -245,9 +219,11 @@ if (($action == 'edit') || ($action == 'new')) {
$return = false;
}
} else if ($action == 'moveup') {
require_sesskey();
$repositorytype = repository::get_type_by_typename($repository);
$repositorytype->move_order('up');
} else if ($action == 'movedown') {
require_sesskey();
$repositorytype = repository::get_type_by_typename($repository);
$repositorytype->move_order('down');
} else {
@@ -339,8 +315,7 @@ if (($action == 'edit') || ($action == 'new')) {
$userinstancenumbertext = "";
}
$settings .= '<a href="' . $sesskeyurl . '&amp;action=edit&amp;repos=' . $typename . '">' . $settingsstr .'</a>';
$settings = html_writer::link(new moodle_url($baseurl, ['action' => 'edit', 'repos' => $typename]), $settingsstr);
$settings .= $OUTPUT->container_start('mdl-left');
$settings .= '<br/>';
$settings .= $admininstancenumbertext;
@@ -357,22 +332,34 @@ if (($action == 'edit') || ($action == 'new')) {
$currentaction = 'hide';
}
$select = new single_select(repository_action_url($typename, 'repos'), 'action', $actionchoicesforexisting, $currentaction, null, 'applyto' . basename($typename));
// Active toggle.
$selectaction = new moodle_url($baseurl, ['sesskey' => sesskey(), 'repos' => $typename]);
$select = new single_select($selectaction, 'action', $actionchoicesforexisting, $currentaction, null,
'applyto' . basename($typename));
$select->set_label(get_string('action'), array('class' => 'accesshide'));
// Display up/down link
$updown = '';
$spacer = $OUTPUT->spacer(array('height'=>15, 'width'=>15)); // should be done with CSS instead
if ($updowncount > 1) {
$updown .= "<a href=\"$sesskeyurl&amp;action=moveup&amp;repos=".$typename."\">";
$updown .= $OUTPUT->pix_icon('t/up', get_string('moveup')) . "</a>&nbsp;";
$moveupaction = new moodle_url($baseurl, [
'sesskey' => sesskey(),
'action' => 'moveup',
'repos' => $typename,
]);
$updown .= html_writer::link($moveupaction, $OUTPUT->pix_icon('t/up', get_string('moveup'))) . '&nbsp;';
}
else {
$updown .= $spacer;
}
if ($updowncount < $totalrepositorytypes) {
$updown .= "<a href=\"$sesskeyurl&amp;action=movedown&amp;repos=".$typename."\">";
$updown .= $OUTPUT->pix_icon('t/down', get_string('movedown')) . "</a>&nbsp;";
$movedownaction = new moodle_url($baseurl, [
'sesskey' => sesskey(),
'action' => 'movedown',
'repos' => $typename,
]);
$updown .= html_writer::link($movedownaction, $OUTPUT->pix_icon('t/down', get_string('movedown'))) . '&nbsp;';
}
else {
$updown .= $spacer;
@@ -400,7 +387,9 @@ if (($action == 'edit') || ($action == 'new')) {
foreach ($plugins as $plugin => $dir) {
// Check that it has not already been listed
if (!in_array($plugin, $alreadyplugins)) {
$select = new single_select(repository_action_url($plugin, 'repos'), 'action', $actionchoicesfornew, 'delete', null, 'applyto' . basename($plugin));
$selectaction = new moodle_url($baseurl, ['sesskey' => sesskey(), 'repos' => $plugin]);
$select = new single_select($selectaction, 'action', $actionchoicesfornew, 'delete', null,
'applyto' . basename($plugin));
$select->set_label(get_string('action'), array('class' => 'accesshide'));
$uninstall = '';
if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('repository_' . $plugin, 'manage')) {
+9 -10
View File
@@ -18,8 +18,6 @@ require_once(__DIR__ . '/../config.php');
require_once($CFG->dirroot . '/repository/lib.php');
require_once($CFG->libdir . '/adminlib.php');
require_sesskey();
// id of repository
$edit = optional_param('edit', 0, PARAM_INT);
$new = optional_param('new', '', PARAM_PLUGIN);
@@ -43,12 +41,8 @@ if ($edit){
admin_externalpage_setup($pagename, '', null, new moodle_url('/admin/repositoryinstance.php'));
$baseurl = new moodle_url("/$CFG->admin/repositoryinstance.php", array('sesskey'=>sesskey()));
$parenturl = new moodle_url("/$CFG->admin/repository.php", array(
'sesskey'=>sesskey(),
'action'=>'edit',
));
// The URL used for redirection, and that all edit related URLs will be based off.
$parenturl = new moodle_url('/admin/repository.php', ['action' => 'edit']);
if ($new) {
$parenturl->param('repos', $new);
@@ -116,6 +110,7 @@ if (!empty($edit) || !empty($new)) {
$return = false;
}
} else if (!empty($hide)) {
require_sesskey();
$instance = repository::get_type_by_typename($hide);
$instance->hide();
core_plugin_manager::reset_caches();
@@ -129,6 +124,7 @@ if (!empty($edit) || !empty($new)) {
throw new repository_exception('nopermissiontoaccess', 'repository');
}
if ($sure) {
require_sesskey();
if ($instance->delete($downloadcontents)) {
$deletedstr = get_string('instancedeleted', 'repository');
core_plugin_manager::reset_caches();
@@ -141,14 +137,17 @@ if (!empty($edit) || !empty($new)) {
echo $OUTPUT->header();
echo $OUTPUT->box_start('generalbox', 'notice');
$continueurl = new moodle_url($baseurl, array(
$continueurl = new moodle_url($PAGE->url, [
'type' => $type,
'delete' => $delete,
'sure' => 'yes',
));
]);
$continueanddownloadurl = new moodle_url($continueurl, array(
'downloadcontents' => 1
));
$message = get_string('confirmdelete', 'repository', $instance->name);
echo html_writer::tag('p', $message);
+1 -1
View File
@@ -76,7 +76,7 @@ switch ($action) {
$optionsyes = array('action'=>'delete', 'roleid'=>$roleid, 'sesskey'=>sesskey(), 'confirm'=>1);
$a = new stdClass();
$a->id = $roleid;
$a->name = $roles[$roleid]->name;
$a->name = $roles[$roleid]->localname;
$a->shortname = $roles[$roleid]->shortname;
$a->count = $DB->count_records_select('role_assignments',
'roleid = ?', array($roleid), 'COUNT(DISTINCT userid)');
@@ -23,12 +23,15 @@
* name - form element name
* hasoptions - there are some options
* options - list of options containing name, key, id, checked, label
* readonly - bool
Example context (json):
{
"name": "test",
"hasoptions": true,
"options": [ { "name": "Option", "key": "k1", "id": "id0", "checked": true, "label": "Option label"} ]
"options": [ { "name": "Option", "key": "k1", "id": "id0", "checked": true, "label": "Option label"} ],
"readonly": false
}
}}
<div class="form-multicheckbox">
@@ -37,7 +40,7 @@
<ul>
{{#options}}
<li>
<input type="checkbox" name="{{name}}[{{key}}]" value="1" id="{{id}}_{{key}}" {{#checked}}checked{{/checked}}>
<input type="checkbox" name="{{name}}[{{key}}]" value="1" id="{{id}}_{{key}}" {{#readonly}}disabled{{/readonly}} {{#checked}}checked{{/checked}}>
<label for="{{id}}_{{key}}">{{{label}}}</label>
</li>
{{/options}}
@@ -16,6 +16,7 @@
namespace tool_admin_presets\local\action;
use core_adminpresets\manager;
use moodle_exception;
/**
@@ -34,8 +35,8 @@ class delete extends base {
public function show(): void {
global $DB, $OUTPUT;
// Getting the preset name.
$presetdata = $DB->get_record('adminpresets', ['id' => $this->id], 'name');
// Check the preset exists (cannot delete the pre-installed core "Starter" and "Full" presets).
$presetdata = $DB->get_record('adminpresets', ['id' => $this->id, 'iscore' => manager::NONCORE_PRESET], 'name');
if ($presetdata) {
$deletetext = get_string('deletepreset', 'tool_admin_presets', $presetdata->name);
+34
View File
@@ -0,0 +1,34 @@
@tool_behat
Feature: Confirm that we can open multiple browser tabs
In order to use multiple browser tabs
As a test writer
I need the relevant Behat steps to work
@javascript @_switch_window
Scenario: Open multiple browser tabs
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
| Course 2 | C2 |
| Course 3 | C3 |
And I am on the "C1" "Course" page logged in as "admin"
# Open a new tab on the same page.
When I open a tab named "CourseViewer1" on the current page
And I should see "Course 1" in the "h1" "css_element"
And I am on the "C2" "Course" page
# Open new tab for specified page with identifier.
And I open a tab named "CourseViewer2" on the "C3" "Course" page
# And for a specified page without identifier.
And I open a tab named "CourseViewer4" on the "My courses" page
# Switch between all the tabs and confirm their different contents.
Then I should see "You're not enrolled in any course"
And I switch to "CourseViewer2" tab
And "Course 3" "heading" should exist
And I switch to "CourseViewer1" tab
And "Course 2" "heading" should exist
And I switch to the main tab
And "Course 1" "heading" should exist
@@ -170,6 +170,19 @@ class brickfield_accessibility_color_test extends brickfield_accessibility_test
'yellowgreen' => '9acd32'
];
/** @var string[] Define estimated relative font-size codes to pt values. */
public $fontsizenames = [
'xx-small' => 9,
'x-small' => 10,
'small' => 11,
'smaller' => 11,
'medium' => 12,
'large' => 14,
'larger' => 14,
'x-large' => 18,
'xx-large' => 24,
];
/**
* Helper method that finds the luminosity between the provided
* foreground and background parameters.
@@ -227,7 +240,8 @@ class brickfield_accessibility_color_test extends brickfield_accessibility_test
$l2 = (.2126 * $r4 + 0.7152 * $g4 + 0.0722 * $b4);
}
$luminosity = round(($l1 + 0.05) / ($l2 + 0.05), 2);
// Increase round to 4 to avoid a 4.49 contrast being round up to a false pass of 4.5.
$luminosity = round(($l1 + 0.05) / ($l2 + 0.05), 4);
return $luminosity;
}
@@ -362,4 +376,35 @@ class brickfield_accessibility_color_test extends brickfield_accessibility_test
: $backrgb['b'] - $forergb['b'];
return ['red' => $reddiff, 'green' => $greendiff, 'blue' => $bluediff];
}
/**
* Helper method that finds the estimated font-size for the provided
* string font-size parameter.
* @param string $fontsize The css font-size, in various formats
* @return int The estimated font-size
*/
public function get_fontsize(string $fontsize): int {
$newfontsize = 12; // Default value, in pt, equivalent to 16px.
// Search for rem, em, and px initially, typical font-size values.
$pos1 = stripos($fontsize, 'rem');
$pos2 = stripos($fontsize, 'em');
$pos3 = stripos($fontsize, 'px');
if ($pos1 !== false) {
$rem = substr($fontsize, 0, -3);
$newfontsize = $newfontsize * $rem;
} else if ($pos2 !== false) {
$em = substr($fontsize, 0, -2);
$newfontsize = $newfontsize * $em;
} else if ($pos3 !== false) {
$px = substr($fontsize, 0, -2);
$newfontsize = 0.75 * $px;
} else if (in_array($fontsize, array_keys($this->fontsizenames))) {
$newfontsize = $this->fontsizenames[$fontsize];
} else {
preg_match_all('!\d+!', $fontsize, $matches);
$newfontsize = $matches[0][0] ?? $newfontsize;
}
return (int) $newfontsize;
}
}
@@ -92,8 +92,7 @@ class css_text_has_contrast extends brickfield_accessibility_color_test {
$italic = false;
if (isset($style['font-size'])) {
preg_match_all('!\d+!', $style['font-size'], $matches);
$fontsize = $matches[0][0];
$fontsize = $this->get_fontsize($style['font-size']);
}
if (isset($style['font-weight'])) {
@@ -178,6 +178,54 @@ EOD;
</html>
EOD;
/** @var string HTML with px18 fail colour values. */
private $px18 = <<<EOD
<body><p style="color:#EF0000; background-color:white; font-size: 18px">
This is not contrasty enough.</p></body>
EOD;
/** @var string HTML with px19bold pass colour values. */
private $px19bold = <<<EOD
<body><p style="color:#EF0000; background-color:white; font-size: 19px; font-weight: bold;">
This is contrasty enough.</p></body>
EOD;
/** @var string HTML with px18 pass colour values. */
private $px18pass = <<<EOD
<body><p style="color:#E60000; background-color:white; font-size: 18px">
This is contrasty enough.</p></body>
EOD;
/** @var string HTML with medium size colour values. */
private $mediumfail = <<<EOD
<body><p style="color:#EF0000; background-color:white; font-size: medium">
This is not contrasty enough.</p></body>
EOD;
/** @var string HTML with px18 colour values. */
private $mediumpass = <<<EOD
<body><p style="color:#E60000; background-color:white; font-size: medium">
This is contrasty enough.</p></body>
EOD;
/** @var string HTML with larger fail colour values. */
private $largerfail = <<<EOD
<body><p style="color:#FF6161; background-color:white; font-size: larger">
This is not contrasty enough.</p></body>
EOD;
/** @var string HTML with px18 colour values. */
private $largerpass = <<<EOD
<body><p style="color:#FF5C5C; background-color:white; font-size: larger;">
This is contrasty enough.</p></body>
EOD;
/** @var string HTML with px18 colour values. */
private $largerboldpass = <<<EOD
<body><p style="color:#FF5C5C; background-color:white; font-size: larger; font-weight: bold;">
This is contrasty enough.</p></body>
EOD;
/**
* Test for the area assign intro
*/
@@ -235,4 +283,68 @@ EOD;
$results = $this->get_checker_results($this->emptyvalue);
$this->assertEmpty($results);
}
/**
* Test for text px18 with insufficient contrast of 4.49.
*/
public function test_check_for_px18_fail() {
$results = $this->get_checker_results($this->px18);
$this->assertTrue($results[0]->element->tagName == 'p');
}
/**
* Test for text px19 bold with sufficient contrast of 4.49.
*/
public function test_check_for_px19bold_pass() {
$results = $this->get_checker_results($this->px19bold);
$this->assertEmpty($results);
}
/**
* Test for text px18 with sufficient contrast of 4.81.
*/
public function test_check_for_px18_pass() {
$results = $this->get_checker_results($this->px18pass);
$this->assertEmpty($results);
}
/**
* Test for medium (12pt) text with insufficient contrast of 4.49.
*/
public function test_check_for_medium_fail() {
$results = $this->get_checker_results($this->mediumfail);
$this->assertTrue($results[0]->element->tagName == 'p');
}
/**
* Test for medium (12pt) text with sufficient contrast of 4.81.
*/
public function test_check_for_medium_pass() {
$results = $this->get_checker_results($this->mediumpass);
$this->assertEmpty($results);
}
/**
* Test for larger (14pt) text with insufficient contrast of 2.94.
*/
public function test_check_for_larger_fail() {
$results = $this->get_checker_results($this->largerfail);
$this->assertTrue($results[0]->element->tagName == 'p');
}
/**
* Test for larger (14pt) text with insufficient contrast of 3.02.
*/
public function test_check_for_larger_pass() {
$results = $this->get_checker_results($this->largerpass);
$this->assertTrue($results[0]->element->tagName == 'p');
}
/**
* Test for larger (14pt) bold text with sufficient contrast of 3.02.
*/
public function test_check_for_largerbold_pass() {
$results = $this->get_checker_results($this->largerboldpass);
$this->assertEmpty($results);
}
}
@@ -24,7 +24,7 @@ The confirmation AMD module is loaded automatically, so the only thing you need
to the target element:
{{< highlight html >}}
<button type="button" class="btn btn-primary" data-confirmation="modal" data-confirmation-title-str='["delete", "core"]'
data-confirmation-question-str='["areyousure"]' data-confirmation-yes-button-str='["delete", "core"]'>Show confirmation modal</button>
data-confirmation-content-str='["areyousure"]' data-confirmation-yes-button-str='["delete", "core"]'>Show confirmation modal</button>
{{< /highlight >}}
You can also use it on PHP, you just need to set the attributes parameter to any moodle output component that takes attributes:
@@ -32,7 +32,7 @@ You can also use it on PHP, you just need to set the attributes parameter to any
echo $OUTPUT->single_button('#', get_string('delete'), 'get', [
'data-confirmation' => 'modal',
'data-confirmation-title-str' => json_encode(['delete', 'core']),
'data-confirmation-question-str' => json_encode(['areyousure']),
'data-confirmation-content-str' => json_encode(['areyousure']),
'data-confirmation-yes-button-str' => json_encode(['delete', 'core'])
]);
{{< / php >}}
@@ -56,8 +56,8 @@ echo $OUTPUT->single_button('#', get_string('delete'), 'get', [
<td>The modal title language string identifier, must be provided in JSON encoded format.</td>
</tr>
<tr>
<td>data-confirmation-question-str</td>
<td>The confirmation question language string identifier, must be provided in JSON encoded format.</td>
<td>data-confirmation-content-str</td>
<td>The modal main content language string identifier, must be provided in JSON encoded format.</td>
</tr>
<tr>
<td>data-confirmation-yes-button-str</td>
@@ -86,14 +86,14 @@ echo $OUTPUT->single_button('#', get_string('delete'), 'get', [
{{< example >}}
<button type="button" class="btn btn-primary" data-confirmation="modal" data-confirmation-title-str='["ok", "core"]'
data-confirmation-question-str='["areyousure"]' data-confirmation-yes-button-str='["ok", "core"]'>Show confirmation modal</button>
data-confirmation-content-str='["areyousure"]' data-confirmation-yes-button-str='["ok", "core"]'>Show confirmation modal</button>
{{< /example >}}
#### Delete Modal
{{< example >}}
<button type="button" class="btn btn-primary" data-confirmation="modal" data-confirmation-type="delete" data-confirmation-title-str='["delete", "core"]'
data-confirmation-question-str='["areyousure"]' data-confirmation-yes-button-str='["delete", "core"]'>Show delete modal</button>
data-confirmation-content-str='["areyousure"]' data-confirmation-yes-button-str='["delete", "core"]'>Show delete modal</button>
{{< /example >}}
@@ -101,7 +101,7 @@ data-confirmation-question-str='["areyousure"]' data-confirmation-yes-button-str
{{< example >}}
<button type="button" class="btn btn-primary" data-confirmation="modal" data-confirmation-title-str='["save", "core"]'
data-confirmation-question-str='["areyousure"]' data-confirmation-yes-button-str='["save", "core"]' data-confirmation-toast="true"
data-confirmation-content-str='["areyousure"]' data-confirmation-yes-button-str='["save", "core"]' data-confirmation-toast="true"
data-confirmation-toast-confirmation-str='["saved", "core_question", "My question"]'>Show confirmation modal</button>
{{< /example >}}
@@ -109,6 +109,6 @@ data-confirmation-toast-confirmation-str='["saved", "core_question", "My questio
{{< example >}}
<button type="button" class="btn btn-primary" data-confirmation="modal" data-confirmation-title-str='["save", "core"]'
data-confirmation-question-str='["areyousure"]' data-confirmation-yes-button-str='["save", "core"]'
data-confirmation-content-str='["areyousure"]' data-confirmation-yes-button-str='["save", "core"]'
data-confirmation-destination="http://moodle.com">Show confirmation modal</button>
{{< /example >}}
@@ -22,12 +22,12 @@ Feature: Within a moodle instance, an administrator should be able to modify lan
Scenario: Edit an string but don't save it to lang pack.
When I press "Apply changes and continue editing"
Then I should not see "moodle documents" in the "page-footer" "region"
And I should see "Help and documentation" in the "page-footer" "region"
And I should see "Documentation for this page" in the "page-footer" "region"
@javascript
Scenario: Customize an string as admin and save it to lang pack.
Given I press "Save changes to the language pack"
And I should see "There are 1 modified strings."
When I click on "Continue" "button"
Then I should not see "Help and documentation" in the "page-footer" "region"
Then I should not see "Documentation for this page" in the "page-footer" "region"
And I should see "moodle documents" in the "page-footer" "region"
@@ -16,6 +16,7 @@
namespace tool_dataprivacy\task;
use core\task\task_trait;
use tool_dataprivacy\api;
defined('MOODLE_INTERNAL') || die();
@@ -30,6 +31,8 @@ require_once(__DIR__ . '/../data_privacy_testcase.php');
*/
class task_test extends \data_privacy_testcase {
use task_trait;
/**
* Test tearDown.
*/
@@ -215,17 +218,4 @@ class task_test extends \data_privacy_testcase {
$this->assertCount(1, \tool_dataprivacy\api::get_data_requests($user->id,
[api::DATAREQUEST_STATUS_CANCELLED], [api::DATAREQUEST_TYPE_DELETE]));
}
/**
* Helper to execute a particular task.
*
* @param string $task The task.
*/
private function execute_task($task) {
// Run the scheduled task.
ob_start();
$task = \core\task\manager::get_scheduled_task($task);
$task->execute();
ob_end_clean();
}
}
@@ -120,8 +120,7 @@ Feature: Add customised file types
| Custom description | Froggy file |
And I press "Save changes"
# Create a resource activity and add it to a course
And I am on "Course 1" course homepage with editing mode on
When I add a "File" to section "1"
When I add a resource activity to course "Course 1" section "1"
And I set the following fields to these values:
| Name | An example of customised file type |
| Description | File description |
@@ -216,7 +216,7 @@ class tool_generator_course_backend extends tool_generator_backend {
* @return int Course id
*/
public function make() {
global $DB, $CFG;
global $DB, $CFG, $USER;
require_once($CFG->dirroot . '/lib/phpunit/classes/util.php');
raise_memory_limit(MEMORY_EXTRA);
@@ -252,6 +252,12 @@ class tool_generator_course_backend extends tool_generator_backend {
}
}
// We are checking 'enroladminnewcourse' setting to decide to enrol admins or not.
if (!empty($CFG->creatornewroleid) && !empty($CFG->enroladminnewcourse) && is_siteadmin($USER->id)) {
// Deal with course creators - enrol them internally with default role.
enrol_try_internal_enrol($this->course->id, $USER->id, $CFG->creatornewroleid);
}
// Log total time.
$this->log('coursecompleted', round(microtime(true) - $entirestart, 1));
@@ -0,0 +1,33 @@
@core @core_course @tool_generator
Feature: Admins can create test courses
In order to create testing information
As an admin
I need to create testing courses quickly
@javascript
Scenario: 'Auto-enrol admin in new courses' setting when creating a test course as admin
Given I log in as "admin"
And the following config values are set as admin:
| enroladminnewcourse | 0 |
And I navigate to "Development > Make test course" in site administration
And I set the following fields to these values:
| Size of course | XS |
| Course full name | Fake course for testing |
| Course short name | fake |
And I press "Create course"
And I click on "Continue" "link"
And I navigate to course participants
Then I should not see "Teacher"
And I should not see "Nothing to display"
And the following config values are set as admin:
| enroladminnewcourse | 1 |
And I navigate to "Courses > Add a new course" in site administration
And I navigate to "Development > Make test course" in site administration
And I set the following fields to these values:
| Size of course | XS |
| Course full name | New fake course for testing |
| Course short name | newfake |
And I press "Create course"
And I click on "Continue" "link"
And I navigate to course participants
And I should see "Teacher"
@@ -68,9 +68,14 @@ class maketestcourse_test extends \advanced_testcase {
$this->assertEquals(2, count($modinfo->get_section_info_all()));
// Check user is enrolled.
// enroladminnewcourse is enabled by default, so admin is also enrolled as teacher.
$users = get_enrolled_users($context);
$this->assertEquals(1, count($users));
$this->assertEquals('tool_generator_000001', reset($users)->username);
$this->assertEquals(2, count($users));
$usernames = array_map(function($user) {
return $user->username;
}, $users);
$this->assertTrue(in_array('admin', $usernames));
$this->assertTrue(in_array('tool_generator_000001', $usernames));
// Check there's a page on the course.
$pages = $modinfo->get_instances_of('page');
+1 -1
View File
@@ -114,7 +114,7 @@ if ($mode == DELETION_OF_SELECTED_LANG and (!empty($uninstalllang) or !empty($co
}
}
if ($mode == UPDATE_ALL_LANG) {
if ($mode == UPDATE_ALL_LANG && confirm_sesskey()) {
core_php_time_limit::raise();
$controller->update_all_installed_languages();
}
@@ -87,6 +87,7 @@
<div>
<form id="updateform" action="{{updateurl}}" method="post">
<fieldset>
<input type="hidden" name="sesskey" value="{{sesskey}}">
<input type="submit" value="{{#str}}updatelangs, tool_langimport{{/str}}" class="btn btn-secondary">
{{#hasmanyinstalledlanguages}}
<p class="mt-2 small">{{#str}} updatelangsnote, tool_langimport, {"taskname": {{#quote}}{{updatelangstaskname}}{{/quote}} }{{/str}}</p>
+1 -1
View File
@@ -82,7 +82,7 @@ trait reader {
*/
public static function decode_other(?string $other) {
if ($other === 'N;' || preg_match('~^.:~', $other ?? '')) {
return unserialize($other);
return unserialize($other, ['allowed_classes' => [stdClass::class]]);
} else {
return json_decode($other ?? '', true);
}
@@ -102,7 +102,7 @@
<strong>{{#str}}activities{{/str}}</strong>
<ul class="inline list-inline p-2">
{{#coursemodules}}
<li class="list-inline-item"><a href="{{url}}"><img src="{{iconurl}}"> {{name}} </a></li>
<li class="list-inline-item"><a href="{{url}}"><img class="icon" src="{{iconurl}}"> {{name}} </a></li>
{{/coursemodules}}
{{^coursemodules}}
<li class="list-inline-item">{{#str}}noactivities, tool_lp{{/str}}</li>
@@ -49,7 +49,7 @@
<p>
<ul class="inline list-inline">
{{#coursemodules}}
<li class="list-inline-item"><a href="{{url}}"><img src="{{iconurl}}"> {{name}} </a></li>
<li class="list-inline-item"><a href="{{url}}"><img class="icon" src="{{iconurl}}"> {{name}} </a></li>
{{/coursemodules}}
{{^coursemodules}}
<li class="list-inline-item"><span class="alert">{{#str}}noactivities, tool_lp{{/str}}</span></li>
+3 -2
View File
@@ -56,8 +56,9 @@ if (!empty($oauthsso) && is_enabled_auth('oauth2')) {
// Check if the plugin is properly configured.
$typeoflogin = get_config('tool_mobile', 'typeoflogin');
if (empty($SESSION->justloggedin) and
$typeoflogin != tool_mobile\api::LOGIN_VIA_BROWSER and
if (empty($SESSION->justloggedin) &&
!is_enabled_auth('oauth2') &&
$typeoflogin != tool_mobile\api::LOGIN_VIA_BROWSER &&
$typeoflogin != tool_mobile\api::LOGIN_VIA_EMBEDDED_BROWSER) {
throw new moodle_exception('pluginnotenabledorconfigured', 'tool_mobile');
}
+6 -7
View File
@@ -50,12 +50,10 @@ list($options, $unrecognized) = cli_get_params(
)
);
if (file_exists(__DIR__.'/../../../../vendor/phpunit/phpunit/composer.json')) {
// Composer packages present.
require_once(__DIR__.'/../../../../vendor/autoload.php');
} else {
// Note: installation via PEAR is not supported any more.
// Basic check to see if phpunit is installed.
if (!file_exists(__DIR__.'/../../../../vendor/phpunit/phpunit/composer.json') ||
!file_exists(__DIR__.'/../../../../vendor/bin/phpunit') ||
!file_exists(__DIR__.'/../../../../vendor/autoload.php')) {
phpunit_bootstrap_error(PHPUNIT_EXITCODE_PHPUNITMISSING);
}
@@ -74,12 +72,13 @@ if ($options['run']) {
}
}
$_SERVER['argv'] = array_values($_SERVER['argv']);
PHPUnit\TextUI\Command::main();
require(__DIR__ . '/../../../../vendor/bin/phpunit');
exit(0);
}
define('PHPUNIT_UTIL', true);
require(__DIR__.'/../../../../vendor/autoload.php');
require(__DIR__ . '/../../../../lib/phpunit/bootstrap.php');
// from now on this is a regular moodle CLI_SCRIPT
+1 -1
View File
@@ -35,7 +35,7 @@ $renderer = $PAGE->get_renderer('tool_task');
if ($classname) {
$pageurl = new moodle_url('/admin/tool/task/adhoctasks.php');
$PAGE->navbar->add(get_string('adhoctasks', 'tool_task'), $pageurl);
$PAGE->navbar->add($classname, $PAGE->url);
$PAGE->navbar->add(s($classname), $PAGE->url);
$tasks = core\task\manager::get_adhoc_tasks($classname, $failedonly);
+3
View File
@@ -80,6 +80,9 @@ $string['runnow'] = 'Run now';
$string['runagain'] = 'Run again';
$string['runadhoc_confirm'] = 'Tasks will run on the web server and may take some time to complete.';
$string['runadhoc'] = 'Run ad hoc tasks now?';
$string['runadhoctask'] = 'Run \'{$a->task}\' task ID {$a->taskid}';
$string['runadhoctasks'] = 'Run all \'{$a}\' tasks';
$string['runadhoctasksfailed'] = 'Run failed \'{$a}\' tasks';
$string['runnow_confirm'] = 'Are you sure you want to run this task \'{$a}\' now? The task will run on the web server and may take some time to complete.';
$string['runclassname'] = 'Run all';
$string['runclassnamefailedonly'] = 'Run all failed';
+2 -1
View File
@@ -45,5 +45,6 @@ function tool_task_status_checks() : array {
* @param string $eol End of line character
*/
function tool_task_mtrace_wrapper(string $message, string $eol): void {
echo s($message . $eol);
$message = s($message);
echo $message . $eol;
}
+2 -2
View File
@@ -82,7 +82,7 @@ class tool_task_renderer extends plugin_renderer_base {
);
$classcell = new html_table_cell($classcontent);
$classcell->header = true;
$classcell->class = "task-class-summary text-ltr";
$classcell->attributes['class'] = "task-class-summary text-ltr";
$duecontent = $stats['due'];
if ($canruntasks && ($stats['due'] > 0 || $stats['failed'] > 0)) {
@@ -166,7 +166,7 @@ class tool_task_renderer extends plugin_renderer_base {
// Main tasks table.
$table = $this->generate_adhoc_tasks_simple_table($tasks, $canruntasks);
$table->caption = "$classname "
$table->caption = s($classname) . " "
. get_string($failedonly ? 'adhoctasksfailed' : 'adhoctasks', 'tool_task');
$table->head[3] .= " $failedorall"; // Spice up faildelay heading.
+9 -2
View File
@@ -54,13 +54,19 @@ if ($taskid) {
throw new \moodle_exception('invalidtaskid');
}
$classname = $record->classname;
$heading = "Run $classname task Id $taskid";
$heading = get_string('runadhoctask', 'tool_task', ['task' => $classname, 'taskid' => $taskid]);
$tasks = [core\task\manager::adhoc_task_from_record($record)];
} else {
if (!$classname) {
throw new \moodle_exception('noclassname', 'tool_task');
}
$heading = "Run $classname " . ($failedonly ? "failed" : "all")." tasks";
$heading = get_string(
$failedonly ? 'runadhoctasksfailed' : 'runadhoctasks',
'tool_task',
s($classname),
);
$now = time();
$tasks = array_filter(
core\task\manager::get_adhoc_tasks($classname, $failedonly, true),
@@ -111,6 +117,7 @@ require_sesskey();
\core\session\manager::write_close();
// Prepare to handle output via mtrace.
require_once("{$CFG->dirroot}/{$CFG->admin}/tool/task/lib.php");
$CFG->mtrace_wrapper = 'tool_task_mtrace_wrapper';
// Run the specified tasks.
+2
View File
@@ -85,6 +85,8 @@ require_sesskey();
// Prepare to handle output via mtrace.
echo html_writer::start_tag('pre');
require_once("{$CFG->dirroot}/{$CFG->admin}/tool/task/lib.php");
$CFG->mtrace_wrapper = 'tool_task_mtrace_wrapper';
// Run the specified task (this will output an error if it doesn't exist).
+5 -1
View File
@@ -236,6 +236,8 @@ class form_test extends \advanced_testcase {
$checker->set_day_of_week('6');
$this->assertTrue($checker->is_valid($checker::FIELD_DAYOFWEEK));
$checker->set_day_of_week('7');
$this->assertTrue($checker->is_valid($checker::FIELD_DAYOFWEEK));
$checker->set_day_of_week('8');
$this->assertFalse($checker->is_valid($checker::FIELD_DAYOFWEEK));
$checker->set_day_of_week('20');
$this->assertFalse($checker->is_valid($checker::FIELD_DAYOFWEEK));
@@ -247,7 +249,7 @@ class form_test extends \advanced_testcase {
$checker->set_day_of_week('*/6');
$this->assertTrue($checker->is_valid($checker::FIELD_DAYOFWEEK));
$checker->set_day_of_week('*/7');
$this->assertFalse($checker->is_valid($checker::FIELD_DAYOFWEEK));
$this->assertTrue($checker->is_valid($checker::FIELD_DAYOFWEEK));
$checker->set_day_of_week('*/13');
$this->assertFalse($checker->is_valid($checker::FIELD_DAYOFWEEK));
$checker->set_day_of_week('*/35');
@@ -271,6 +273,8 @@ class form_test extends \advanced_testcase {
$checker->set_day_of_week('65-2');
$this->assertFalse($checker->is_valid($checker::FIELD_DAYOFWEEK));
$checker->set_day_of_week('3-7');
$this->assertTrue($checker->is_valid($checker::FIELD_DAYOFWEEK));
$checker->set_day_of_week('3-8');
$this->assertFalse($checker->is_valid($checker::FIELD_DAYOFWEEK));
}
}
@@ -367,6 +367,11 @@ class cli_helper {
$firstoption = reset($selectoptions);
$default = $firstoption['attr']['value'];
}
// The menu profile field type allows for an empty default value, handle that here.
if (preg_match('/^profile_field_/', $name) && $default === '') {
$possiblevalues[] = $default;
}
}
if ($element instanceof \HTML_QuickForm_checkbox) {
+23 -4
View File
@@ -461,9 +461,22 @@ class process {
return;
}
$matchparam = $this->get_match_on_email() ? ['email' => $user->email] : ['username' => $user->username];
if ($existinguser = $DB->get_records('user', $matchparam + ['mnethostid' => $user->mnethostid])) {
if (is_array($existinguser) && count($existinguser) !== 1) {
if ($this->get_match_on_email()) {
// Case-insensitive query for the given email address.
$userselect = $DB->sql_equal('email', ':email', false);
$userparams = ['email' => $user->email];
} else {
$userselect = 'username = :username';
$userparams = ['username' => $user->username];
}
// Match the user, also accounting for multiple records by email.
$existinguser = $DB->get_records_select('user', "{$userselect} AND mnethostid = :mnethostid",
$userparams + ['mnethostid' => $user->mnethostid]);
$existingusercount = count($existinguser);
if ($existingusercount > 0) {
if ($existingusercount !== 1) {
$this->upt->track('status', get_string('duplicateemail', 'tool_uploaduser', $user->email), 'warning');
$this->userserrors++;
return;
@@ -1371,8 +1384,14 @@ class process {
}
}
}
// Warn user about invalid data values.
if (($invalid = \core_user::validate($user)) !== true) {
$this->upt->track('status', get_string('invaliduserdata', 'tool_uploaduser', s($user->username)), 'warning');
$listseparator = get_string('listsep', 'langconfig') . ' ';
$this->upt->track('status', get_string('invaliduserdatavalues', 'tool_uploaduser', [
'username' => s($user->username),
'values' => implode($listseparator, array_keys($invalid)),
]), 'warning');
}
}
@@ -50,6 +50,7 @@ The example text file may also be used for testing, as you are able to preview u
$string['infoprefix'] = 'Info:';
$string['invalidupdatetype'] = 'This option cannot be selected with the chosen upload type.';
$string['invaliduserdata'] = 'Invalid data detected for user {$a} and it has been automatically cleaned.';
$string['invaliduserdatavalues'] = 'Invalid data detected for user \'{$a->username}\' ({$a->values}), which has been automatically cleaned.';
$string['invalidtheme'] = 'Theme "{$a}" is not installed and will be ignored.';
$string['linex'] = 'Line {$a}';
$string['matchemail'] = 'Match on email address';
@@ -186,6 +186,26 @@ EOF;
$this->assertEquals('student1', reset($usersasdefaultrole)->username);
}
/**
* Test that invalid data contained in uploaded CSV triggers appropriate warnings
*/
public function test_user_upload_user_validate(): void {
$this->resetAfterTest();
$this->setAdminUser();
$csv = <<<EOF
username,firstname,lastname,email,country
student1,Student,One,s1@example.com,Wales
EOF;
$output = $this->process_csv_upload($csv, ['--uutype=' . UU_USER_ADDNEW]);
// We should get the debugging from the user class itself, as well as warning in the output regarding the same.
$this->assertDebuggingCalled('The property \'country\' has invalid data and has been cleaned.');
$this->assertStringContainsString('Invalid data detected for user \'student1\' (country), ' .
'which has been automatically cleaned.', $output);
}
/**
* Generate cli_helper and mock $_SERVER['argv']
*
+13 -29
View File
@@ -97,9 +97,6 @@ class admin_uploaduser_form2 extends moodleform {
$columns = $this->_customdata['columns'];
$data = $this->_customdata['data'];
// I am the template user, why should it be the administrator? we have roles now, other ppl may use this script ;-)
$templateuser = $USER;
// upload settings and file
$mform->addElement('header', 'settingsheader', get_string('settings'));
@@ -276,30 +273,19 @@ class admin_uploaduser_form2 extends moodleform {
$mform->setDefault('autosubscribe', core_user::get_property_default('autosubscribe'));
$mform->addElement('text', 'city', get_string('city'), 'maxlength="120" size="25"');
$mform->setType('city', PARAM_TEXT);
if (empty($CFG->defaultcity)) {
$mform->setDefault('city', $templateuser->city);
} else {
$mform->setDefault('city', core_user::get_property_default('city'));
}
$mform->setType('city', core_user::get_property_type('city'));
$mform->setDefault('city', core_user::get_property_default('city'));
$choices = get_string_manager()->get_list_of_countries();
$choices = array(''=>get_string('selectacountry').'...') + $choices;
$mform->addElement('select', 'country', get_string('selectacountry'), $choices);
if (empty($CFG->country)) {
$mform->setDefault('country', $templateuser->country);
} else {
$mform->setDefault('country', core_user::get_property_default('country'));
}
$mform->addElement('select', 'country', get_string('selectacountry'), core_user::get_property_choices('country'));
$mform->setDefault('country', core_user::get_property_default('country') ?: '');
$mform->setAdvanced('country');
$choices = core_date::get_list_of_timezones($templateuser->timezone, true);
$mform->addElement('select', 'timezone', get_string('timezone'), $choices);
$mform->setDefault('timezone', $templateuser->timezone);
$mform->addElement('select', 'timezone', get_string('timezone'), core_date::get_list_of_timezones(null, true));
$mform->setDefault('timezone', core_user::get_property_default('timezone'));
$mform->setAdvanced('timezone');
$mform->addElement('select', 'lang', get_string('preferredlanguage'), get_string_manager()->get_list_of_translations());
$mform->setDefault('lang', $templateuser->lang);
$mform->addElement('select', 'lang', get_string('preferredlanguage'), core_user::get_property_choices('lang'));
$mform->setDefault('lang', core_user::get_property_default('lang'));
$mform->setAdvanced('lang');
$editoroptions = array('maxfiles'=>0, 'maxbytes'=>0, 'trusttext'=>false, 'forcehttps'=>false);
@@ -313,25 +299,23 @@ class admin_uploaduser_form2 extends moodleform {
$mform->setForceLtr('idnumber');
$mform->addElement('text', 'institution', get_string('institution'), 'maxlength="255" size="25"');
$mform->setType('institution', PARAM_TEXT);
$mform->setDefault('institution', $templateuser->institution);
$mform->setType('institution', core_user::get_property_type('institution'));
$mform->addElement('text', 'department', get_string('department'), 'maxlength="255" size="25"');
$mform->setType('department', PARAM_TEXT);
$mform->setDefault('department', $templateuser->department);
$mform->setType('department', core_user::get_property_type('department'));
$mform->addElement('text', 'phone1', get_string('phone1'), 'maxlength="20" size="25"');
$mform->setType('phone1', PARAM_NOTAGS);
$mform->setType('phone1', core_user::get_property_type('phone1'));
$mform->setAdvanced('phone1');
$mform->setForceLtr('phone1');
$mform->addElement('text', 'phone2', get_string('phone2'), 'maxlength="20" size="25"');
$mform->setType('phone2', PARAM_NOTAGS);
$mform->setType('phone2', core_user::get_property_type('phone2'));
$mform->setAdvanced('phone2');
$mform->setForceLtr('phone2');
$mform->addElement('text', 'address', get_string('address'), 'maxlength="255" size="25"');
$mform->setType('address', PARAM_TEXT);
$mform->setType('address', core_user::get_property_type('address'));
$mform->setAdvanced('address');
// Next the profile defaults
@@ -102,7 +102,7 @@ class block extends base {
*/
public static function add_disabled_constraints_to_form(\MoodleQuickForm $mform) {
$mform->hideIf('targetvalue_block', 'targettype', 'noteq',
\tool_usertours\target::get_target_constant_for_class(get_class()));
\tool_usertours\target::get_target_constant_for_class(self::class));
}
/**
@@ -92,7 +92,7 @@ class selector extends base {
*/
public static function add_disabled_constraints_to_form(\MoodleQuickForm $mform) {
$mform->hideIf('targetvalue_selector', 'targettype', 'noteq',
\tool_usertours\target::get_target_constant_for_class(get_class()));
\tool_usertours\target::get_target_constant_for_class(self::class));
}
/**
@@ -81,7 +81,7 @@ class unattached extends base {
* @param MoodleQuickForm $mform The form to add configuration to.
*/
public static function add_disabled_constraints_to_form(\MoodleQuickForm $mform) {
$myvalue = \tool_usertours\target::get_target_constant_for_class(get_class());
$myvalue = \tool_usertours\target::get_target_constant_for_class(self::class);
foreach (array_keys(self::$forcedsettings) as $settingname) {
$mform->hideIf($settingname, 'targettype', 'eq', $myvalue);
+4 -5
View File
@@ -33,18 +33,17 @@ $userid = required_param('userid', PARAM_INT);
admin_externalpage_setup('externalserviceusersettings');
//define nav bar
$PAGE->set_url('/' . $CFG->admin . '/webservice/service_user_settings.php',
array('id' => $serviceid, 'userid' => $userid));
$PAGE->set_url('/admin/webservice/service_user_settings.php', ['serviceid' => $serviceid, 'userid' => $userid]);
$node = $PAGE->settingsnav->find('externalservices', navigation_node::TYPE_SETTING);
if ($node) {
$node->make_active();
}
$PAGE->navbar->add(get_string('serviceusers', 'webservice'),
new moodle_url('/' . $CFG->admin . '/webservice/service_users.php', array('id' => $serviceid)));
$returnurl = new moodle_url('/admin/webservice/service_users.php', ['id' => $serviceid]);
$PAGE->navbar->add(get_string('serviceusers', 'webservice'), $returnurl);
$PAGE->navbar->add(get_string('serviceusersettings', 'webservice'));
$formaction = new moodle_url('', array('id' => $serviceid, 'userid' => $userid));
$returnurl = new moodle_url('/' . $CFG->admin . '/webservice/service_users.php', array('id' => $serviceid));
$webservicemanager = new webservice();
$serviceuser = $webservicemanager->get_ws_authorised_user($serviceid, $userid);
+1 -1
View File
@@ -86,7 +86,7 @@ class login implements renderable, templatable {
$languagedata = new \core\output\language_menu($PAGE);
$this->languagemenu = $languagedata->export_for_action_menu($OUTPUT);
$this->canloginasguest = $CFG->guestloginbutton and !isguestuser();
$this->canloginasguest = $CFG->guestloginbutton && !isguestuser();
$this->canloginbyemail = !empty($CFG->authloginviaemail);
$this->cansignup = $CFG->registerauth == 'email' || !empty($CFG->registerauth);
if ($CFG->rememberusername == 0) {
+30 -22
View File
@@ -110,8 +110,7 @@ class auth_plugin_lti extends \auth_plugin_base {
// The platform user is already linked with a user account.
if ($this->get_user_binding($launchdata['iss'], $launchdata['sub'])) {
// Always sync the PII, regardless of whether we're already authenticated as this user or not.
$user = $this->find_or_create_user_from_launch($launchdata, true);
$user = $this->find_or_create_user_from_launch($launchdata);
if (isloggedin()) {
// If a different user is currently logged in, authenticate the linked user instead.
@@ -121,11 +120,13 @@ class auth_plugin_lti extends \auth_plugin_base {
}
// If the linked user is already logged in, skip the call to complete_user_login() because this affects deep linking
// workflows on sites publishing and consuming resources on the same site, due to the regenerated sesskey.
return;
} else {
complete_user_login($user);
return;
}
// Always sync the PII, regardless of whether we're already authenticated as this user or not.
$this->update_user_account($user, $launchdata, $launchdata['iss']);
return;
}
// The platform user is not bound to a user account, check provisioning mode now.
@@ -136,7 +137,9 @@ class auth_plugin_lti extends \auth_plugin_base {
switch ($provisioningmode) {
case self::PROVISIONING_MODE_AUTO_ONLY:
// Automatic provisioning - this will create/migrate a user account and log the user in.
complete_user_login($this->find_or_create_user_from_launch($launchdata, true, $legacyconsumersecrets));
$user = $this->find_or_create_user_from_launch($launchdata, $legacyconsumersecrets);
complete_user_login($user);
$this->update_user_account($user, $launchdata, $launchdata['iss']);
break;
case self::PROVISIONING_MODE_PROMPT_NEW_EXISTING:
case self::PROVISIONING_MODE_PROMPT_EXISTING_ONLY:
@@ -211,21 +214,13 @@ class auth_plugin_lti extends \auth_plugin_base {
* itself and pass relevant data in - as auth_plugin_lti::complete_login() does.
*
* @param array $launchdata all data in the decoded JWT including iss and sub.
* @param bool $syncpicture whether to sync the user's picture with the picture sent in the launch.
* @param array $legacyconsumersecrets all secrets found for the legacy consumer, facilitating user migration.
* @return stdClass the Moodle user who is mapped to the platform user identified in the JWT data.
*/
public function find_or_create_user_from_launch(array $launchdata, bool $syncpicture = false,
array $legacyconsumersecrets = []): stdClass {
if (!$syncpicture) {
unset($launchdata['picture']);
}
public function find_or_create_user_from_launch(array $launchdata, array $legacyconsumersecrets = []): stdClass {
if ($binduser = $this->get_user_binding($launchdata['iss'], $launchdata['sub'])) {
$user = \core_user::get_user((int) $binduser);
$this->update_user_account($user, $launchdata, $launchdata['iss']);
return \core_user::get_user($user->id);
return \core_user::get_user($binduser);
} else {
// Is the intent to migrate a user account used in legacy launches?
if (!empty($legacyconsumersecrets)) {
@@ -234,11 +229,10 @@ class auth_plugin_lti extends \auth_plugin_base {
$usermigrationclaim = new user_migration_claim($launchdata, $legacyconsumersecrets);
$username = 'enrol_lti' .
sha1($usermigrationclaim->get_consumer_key() . '::' .
$usermigrationclaim->get_consumer_key() .':' .$usermigrationclaim->get_user_id());
if ($user = \core_user::get_user_by_username($username)) {
$usermigrationclaim->get_consumer_key() . ':' . $usermigrationclaim->get_user_id());
if ($user = core_user::get_user_by_username($username)) {
$this->create_user_binding($launchdata['iss'], $launchdata['sub'], $user->id);
$this->update_user_account($user, $launchdata, $launchdata['iss']);
return \core_user::get_user($user->id);
return core_user::get_user($user->id);
}
} catch (Exception $e) {
// There was an issue validating the user migration claim. We don't want to fail auth entirely though.
@@ -247,9 +241,12 @@ class auth_plugin_lti extends \auth_plugin_base {
"'{$launchdata['iss']}'. The migration claim could not be validated. A new account will be created.");
}
}
// At the point of the creation, to ensure the user_created event correctly reflects the creating user of '0' (the user
// performing the action), ensure any active session is terminated and an empty session initialised.
$this->empty_session();
$user = $this->create_new_account($launchdata, $launchdata['iss']);
$this->update_user_account($user, $launchdata, $launchdata['iss']);
return \core_user::get_user($user->id);
return core_user::get_user($user->id);
}
}
@@ -301,6 +298,17 @@ class auth_plugin_lti extends \auth_plugin_base {
return $binduser;
}
/**
* If there's an existing session, inits an empty session.
*
* @return void
*/
protected function empty_session(): void {
if (isloggedin()) {
\core\session\manager::init_empty_session();
}
}
/**
* Check whether a provisioning mode is valid or not.
*
@@ -361,7 +369,7 @@ class auth_plugin_lti extends \auth_plugin_base {
* @param array $userdata the user data coming from either a launch or membership service call.
* @param string $iss the issuer to which the user belongs.
*/
protected function update_user_account(stdClass $user, array $userdata, string $iss): void {
public function update_user_account(stdClass $user, array $userdata, string $iss): void {
global $CFG;
require_once($CFG->dirroot.'/user/lib.php');
if ($user->auth !== 'lti') {
+2 -1
View File
@@ -72,8 +72,9 @@ if ($newaccount) {
} else {
// Create a new account and link it, logging the user in.
$auth = get_auth_plugin('lti');
$newuser = $auth->find_or_create_user_from_launch($launchdata, true);
$newuser = $auth->find_or_create_user_from_launch($launchdata);
complete_user_login($newuser);
$auth->update_user_account($newuser, $launchdata, $launchdata['iss']);
$PAGE->set_context(context_system::instance());
$PAGE->set_url(new moodle_url('/auth/lti/login.php'));
+226 -80
View File
@@ -214,7 +214,7 @@ class auth_test extends \advanced_testcase {
* @param array $expected the test case expectations.
* @covers ::find_or_create_user_from_launch
*/
public function test_find_or_create_user_from_launch(?array $legacydata, array $launchdata, array $expected) {
public function test_find_or_create_user_from_launch(?array $legacydata, array $launchdata, array $expected = []) {
$this->resetAfterTest();
global $DB;
$auth = get_auth_plugin('lti');
@@ -251,7 +251,7 @@ class auth_test extends \advanced_testcase {
// Authenticate the platform user.
$sink = $this->redirectEvents();
$countusersbefore = $DB->count_records('user');
$user = $auth->find_or_create_user_from_launch($mockjwtdata, true, $legacysecrets);
$user = $auth->find_or_create_user_from_launch($mockjwtdata, $legacysecrets);
if (!empty($expected['migration_debugging'])) {
$this->assertDebuggingCalled();
}
@@ -266,47 +266,15 @@ class auth_test extends \advanced_testcase {
0 : $numnewusers;
$this->assertEquals($numnewusers, $countusersafter - $countusersbefore);
// Verify PII is updated appropriately.
switch ($expected['PII']) {
case self::PII_ALL:
$this->assertEquals($launchdata['user']['given_name'], $user->firstname);
$this->assertEquals($launchdata['user']['family_name'], $user->lastname);
$this->assertEquals($launchdata['user']['email'], $user->email);
break;
case self::PII_NAMES_ONLY:
$this->assertEquals($launchdata['user']['given_name'], $user->firstname);
$this->assertEquals($launchdata['user']['family_name'], $user->lastname);
$email = 'enrol_lti_13_' . sha1($mockjwtdata['iss'] . '_' . $mockjwtdata['sub']) . "@example.com";
$this->assertEquals($email, $user->email);
break;
case self::PII_EMAILS_ONLY:
$this->assertEquals($mockjwtdata['iss'], $user->lastname);
$this->assertEquals($mockjwtdata['sub'], $user->firstname);
$this->assertEquals($launchdata['user']['email'], $user->email);
break;
default:
case self::PII_NONE:
$this->assertEquals($mockjwtdata['iss'], $user->lastname);
$this->assertEquals($mockjwtdata['sub'], $user->firstname);
$email = 'enrol_lti_13_' . sha1($mockjwtdata['iss'] . '_' . $mockjwtdata['sub']) . "@example.com";
$this->assertEquals($email, $user->email);
break;
}
// Verify picture sync occurs, if expected.
if (!empty($expected['syncpicture']) && $expected['syncpicture']) {
$this->verify_user_profile_image_updated($user->id);
}
if (!empty($expected['migrated']) && $expected['migrated']) {
// If migrated, verify the user account is reusing the legacy user account.
$legacyuserids = array_column($legacyusers, 'id');
$this->assertContains($user->id, $legacyuserids);
$this->assertInstanceOf(\core\event\user_updated::class, $events[0]);
$this->assertEmpty($events); // No updates as part of this method.
} else if (isset($firstauthuser)) {
// If the user is authenticating a second time, confirm the same account is being returned.
$this->assertEquals($firstauthuser->id, $user->id);
$this->assertEmpty($events); // The user authenticated with the same data once before, so we don't expect an update.
$this->assertEmpty($events); // No updates as part of this method.
} else {
// The user wasn't migrated and hasn't launched before, so we expect a user_created event.
$this->assertInstanceOf(\core\event\user_created::class, $events[0]);
@@ -329,9 +297,6 @@ class auth_test extends \advanced_testcase {
)[0],
'migration_claim' => null
],
'expected' => [
'PII' => self::PII_ALL,
]
],
'New (unlinked) platform learner excluding names, no legacy user, no migration claim' => [
'legacy_data' => null,
@@ -343,9 +308,6 @@ class auth_test extends \advanced_testcase {
)[0],
'migration_claim' => null
],
'expected' => [
'PII' => self::PII_EMAILS_ONLY,
]
],
'New (unlinked) platform learner excluding emails, no legacy user, no migration claim' => [
'legacy_data' => null,
@@ -358,9 +320,6 @@ class auth_test extends \advanced_testcase {
)[0],
'migration_claim' => null
],
'expected' => [
'PII' => self::PII_NAMES_ONLY,
]
],
'New (unlinked) platform learner excluding all PII, no legacy user, no migration claim' => [
'legacy_data' => null,
@@ -373,9 +332,6 @@ class auth_test extends \advanced_testcase {
)[0],
'migration_claim' => null
],
'expected' => [
'PII' => self::PII_NONE,
]
],
'New (unlinked) platform learner including PII, existing legacy user, valid migration claim' => [
'legacy_data' => [
@@ -403,7 +359,6 @@ class auth_test extends \advanced_testcase {
]
],
'expected' => [
'PII' => self::PII_ALL,
'migrated' => true
]
],
@@ -426,7 +381,6 @@ class auth_test extends \advanced_testcase {
'migration_claim' => null,
],
'expected' => [
'PII' => self::PII_ALL,
'migrated' => false,
]
],
@@ -455,7 +409,6 @@ class auth_test extends \advanced_testcase {
]
],
'expected' => [
'PII' => self::PII_ALL,
'migrated' => false,
'migration_debugging' => true,
]
@@ -486,7 +439,6 @@ class auth_test extends \advanced_testcase {
]
],
'expected' => [
'PII' => self::PII_ALL,
'migrated' => false,
]
],
@@ -516,7 +468,6 @@ class auth_test extends \advanced_testcase {
]
],
'expected' => [
'PII' => self::PII_ALL,
'migrated' => false
]
],
@@ -546,7 +497,6 @@ class auth_test extends \advanced_testcase {
]
],
'expected' => [
'PII' => self::PII_ALL,
'migrated' => true
]
],
@@ -576,7 +526,6 @@ class auth_test extends \advanced_testcase {
]
],
'expected' => [
'PII' => self::PII_ALL,
'migrated' => false,
'migration_debugging' => true,
]
@@ -605,7 +554,6 @@ class auth_test extends \advanced_testcase {
]
],
'expected' => [
'PII' => self::PII_ALL,
'migrated' => false
]
],
@@ -637,7 +585,6 @@ class auth_test extends \advanced_testcase {
]
],
'expected' => [
'PII' => self::PII_NONE,
'migrated' => true
]
],
@@ -650,9 +597,6 @@ class auth_test extends \advanced_testcase {
)[0],
'migration_claim' => null
],
'expected' => [
'PII' => self::PII_ALL,
]
],
'New (unlinked) platform instructor excluding PII, no legacy user, no migration claim' => [
'legacy_data' => null,
@@ -665,9 +609,6 @@ class auth_test extends \advanced_testcase {
)[0],
'migration_claim' => null
],
'expected' => [
'PII' => self::PII_NONE,
]
],
'New (unlinked) platform instructor including PII, existing legacy user, valid migration claim' => [
'legacy_data' => [
@@ -695,7 +636,6 @@ class auth_test extends \advanced_testcase {
]
],
'expected' => [
'PII' => self::PII_ALL,
'migrated' => true
]
],
@@ -709,9 +649,6 @@ class auth_test extends \advanced_testcase {
)[0],
'migration_claim' => null
],
'expected' => [
'PII' => self::PII_ALL,
]
],
'Existing (linked) platform learner excluding PII, no legacy user, no migration claim' => [
'legacy_data' => null,
@@ -725,9 +662,6 @@ class auth_test extends \advanced_testcase {
)[0],
'migration_claim' => null
],
'expected' => [
'PII' => self::PII_NONE,
]
],
'Existing (linked) platform instructor including PII, no legacy user, no migration claim' => [
'legacy_data' => null,
@@ -739,9 +673,6 @@ class auth_test extends \advanced_testcase {
)[0],
'migration_claim' => null
],
'expected' => [
'PII' => self::PII_ALL,
]
],
'Existing (linked) platform instructor excluding PII, no legacy user, no migration claim' => [
'legacy_data' => null,
@@ -755,9 +686,6 @@ class auth_test extends \advanced_testcase {
)[0],
'migration_claim' => null
],
'expected' => [
'PII' => self::PII_NONE,
]
],
'New (unlinked) platform instructor excluding PII, picture included' => [
'legacy_data' => null,
@@ -772,10 +700,6 @@ class auth_test extends \advanced_testcase {
)[0],
'migration_claim' => null
],
'expected' => [
'PII' => self::PII_NONE,
'syncpicture' => true
]
]
];
}
@@ -1154,4 +1078,226 @@ class auth_test extends \advanced_testcase {
// Assert idempotency of the bind call.
$this->assertNull($auth->create_user_binding($mockiss, $mocksub, $user->id));
}
/**
* Test updating a user account based on a given set of launchdata.
*
* @param array $firstlaunchdata the data from the first launch the user made.
* @param array $launchdata the current launch data, which will dictate what data is updated.
* @param array $expected array of test expectations
* @dataProvider update_user_account_provider
* @covers ::update_user_account
*/
public function test_update_user_account(array $firstlaunchdata, array $launchdata, array $expected): void {
$this->resetAfterTest();
$auth = get_auth_plugin('lti');
// Mock the first authentication of the user.
$firstmockjwtdata = $this->get_mock_launchdata_for_user($firstlaunchdata['user']);
$user = $auth->find_or_create_user_from_launch($firstmockjwtdata);
// Now, mock the recent authentication, confirming updates.
$mockjwtdata = $this->get_mock_launchdata_for_user($launchdata['user']);
$sink = $this->redirectEvents();
$auth->update_user_account($user, $mockjwtdata, $mockjwtdata['iss']);
$user = \core_user::get_user($user->id);
$events = $sink->get_events();
$sink->close();
if (!empty($expected['user_updated'])) {
$this->assertInstanceOf(\core\event\user_updated::class, $events[0]);
} else {
$this->assertEmpty($events);
}
// Verify PII is updated appropriately.
switch ($expected['PII']) {
case self::PII_ALL:
$this->assertEquals($launchdata['user']['given_name'], $user->firstname);
$this->assertEquals($launchdata['user']['family_name'], $user->lastname);
$this->assertEquals($launchdata['user']['email'], $user->email);
break;
case self::PII_NAMES_ONLY:
$this->assertEquals($launchdata['user']['given_name'], $user->firstname);
$this->assertEquals($launchdata['user']['family_name'], $user->lastname);
$email = 'enrol_lti_13_' . sha1($mockjwtdata['iss'] . '_' . $mockjwtdata['sub']) . "@example.com";
$this->assertEquals($email, $user->email);
break;
case self::PII_EMAILS_ONLY:
$this->assertEquals($mockjwtdata['iss'], $user->lastname);
$this->assertEquals($mockjwtdata['sub'], $user->firstname);
$this->assertEquals($launchdata['user']['email'], $user->email);
break;
default:
case self::PII_NONE:
$this->assertEquals($mockjwtdata['iss'], $user->lastname);
$this->assertEquals($mockjwtdata['sub'], $user->firstname);
$email = 'enrol_lti_13_' . sha1($mockjwtdata['iss'] . '_' . $mockjwtdata['sub']) . "@example.com";
$this->assertEquals($email, $user->email);
break;
}
// Verify picture sync occurs, if expected.
if (!empty($expected['picture_updated'])) {
$this->verify_user_profile_image_updated($user->id);
}
}
/**
* Data provider for testing user user_update_account.
*
* @return array the test case data.
*/
public function update_user_account_provider(): array {
return [
'Full PII included in both auths, no picture in either' => [
'first_launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner'
)[0]
],
'launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner'
)[0],
],
'expected' => [
'PII' => self::PII_ALL,
'user_updated' => false,
'picture_updated' => false
]
],
'No PII included in both auths, no picture in either' => [
'first_launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner',
false,
false
)[0]
],
'launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner',
false,
false
)[0],
],
'expected' => [
'PII' => self::PII_NONE,
'user_updated' => false,
'picture_updated' => false
]
],
'First auth no PII, second auth including PII, no picture in either' => [
'first_launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner',
false,
false
)[0]
],
'launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner'
)[0],
],
'expected' => [
'PII' => self::PII_ALL,
'user_updated' => true,
'picture_updated' => false
]
],
'First auth full PII, second auth no PII, no picture in either' => [
'first_launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner',
)[0]
],
'launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner',
false,
false
)[0],
],
'expected' => [
'PII' => self::PII_NONE,
'user_updated' => true,
'picture_updated' => false
]
],
'First auth full PII, second auth emails only, no picture in either' => [
'first_launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner',
)[0]
],
'launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner',
false
)[0],
],
'expected' => [
'PII' => self::PII_EMAILS_ONLY,
'user_updated' => true,
'picture_updated' => false
]
],
'First auth full PII, second auth names only, no picture in either' => [
'first_launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner',
)[0]
],
'launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner',
true,
false
)[0],
],
'expected' => [
'PII' => self::PII_NAMES_ONLY,
'user_updated' => true,
'picture_updated' => false
]
],
'Full PII included in both auths, picture included in the second auth' => [
'first_launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner'
)[0]
],
'launch_data' => [
'user' => $this->get_mock_users_with_ids(
['1'],
'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner',
true,
true,
true
)[0],
],
'expected' => [
'PII' => self::PII_ALL,
'user_updated' => false,
'picture_updated' => false
]
],
];
}
}
+7 -3
View File
@@ -298,6 +298,7 @@ abstract class info {
// So instead use the numbers (cmid) from the tag.
$htmlname = preg_replace('~[^0-9]~', '', $name);
}
$htmlname = html_to_text($htmlname, 75, false);
$info = 'Error processing availability data for &lsquo;' . $htmlname
. '&rsquo;: ' . s($e->a);
debugging($info, DEBUG_DEVELOPER);
@@ -740,11 +741,14 @@ abstract class info {
$info = preg_replace_callback('~<AVAILABILITY_CMNAME_([0-9]+)/>~',
function($matches) use($modinfo, $context) {
$cm = $modinfo->get_cm($matches[1]);
if ($cm->has_view() and $cm->get_user_visible()) {
$modulename = format_string($cm->get_name(), true, ['context' => $context]);
// We make sure that we add a data attribute to the name so we can change it later if the
// original module name changes.
if ($cm->has_view() && $cm->get_user_visible()) {
// Help student by providing a link to the module which is preventing availability.
return \html_writer::link($cm->get_url(), format_string($cm->get_name(), true, ['context' => $context]));
return \html_writer::link($cm->get_url(), $modulename, ['data-cm-name-for' => $cm->id]);
} else {
return format_string($cm->get_name(), true, ['context' => $context]);
return \html_writer::span($modulename, '', ['data-cm-name-for' => $cm->id]);
}
}, $info);
$info = preg_replace_callback('~<AVAILABILITY_FORMAT_STRING>(.*?)</AVAILABILITY_FORMAT_STRING>~s',
@@ -149,15 +149,23 @@ class condition extends \core_availability\condition {
$allow = true;
if ($this->expectedcompletion == COMPLETION_COMPLETE) {
// Complete also allows the pass, fail states.
// Complete also allows the pass state.
switch ($completiondata->completionstate) {
case COMPLETION_COMPLETE:
case COMPLETION_COMPLETE_FAIL:
case COMPLETION_COMPLETE_PASS:
break;
default:
$allow = false;
}
} else if ($this->expectedcompletion == COMPLETION_INCOMPLETE) {
// Incomplete also allows the fail state.
switch ($completiondata->completionstate) {
case COMPLETION_INCOMPLETE:
case COMPLETION_COMPLETE_FAIL:
break;
default:
$allow = false;
}
} else {
// Other values require exact match.
if ($completiondata->completionstate != $this->expectedcompletion) {
@@ -20,6 +20,8 @@ Feature: availability_completion
| activity | course | name | completion |
| page | C1 | Page 1 | 1 |
| page | C1 | Page 2 | |
| page | C1 | Page 3 | 1 |
| page | C1 | Page 4 | |
@javascript
Scenario: Test condition
@@ -74,3 +76,70 @@ Feature: availability_completion
And I click on "forum 1" "link" in the "region-main" "region"
And I am on "Course 1" course homepage
And I should see "Page 2" in the "region-main" "region"
@javascript
Scenario Outline: Restrict access for activity completion should display correctly
Given the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | First question | Answer the first question |
And the following "activities" exist:
| activity | name | course | idnumber | gradepass | completion | completionpassgrade | completionusegrade |
| quiz | Test quiz name | C1 | quiz1 | 5.00 | 2 | 1 | 1 |
And quiz "Test quiz name" contains the following questions:
| question | page |
| First question | 1 |
And I am on the "Page 2" "page activity editing" page logged in as "teacher1"
And I expand all fieldsets
And I press "Add restriction..."
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
And I click on ".availability-item .availability-eye img" "css_element"
And I set the following fields to these values:
| Required completion status | <condition> |
| cm | quiz |
And I press "Save and return to course"
And I am on the "Course 1" "course" page logged in as "student1"
And I <shouldornot> see "Page 2" in the "region-main" "region"
# Failed grade for quiz.
When user "student1" has attempted "Test quiz name" with responses:
| slot | response |
| 1 | <answer1> |
And I reload the page
And I <shouldornotanswer1> see "Page 2" in the "region-main" "region"
# Passing grade for quiz.
But user "student1" has attempted "Test quiz name" with responses:
| slot | response |
| 1 | <answer2> |
And I reload the page
And I <shouldornotanswer2> see "Page 2" in the "region-main" "region"
Examples:
| condition | answer1 | answer2 | shouldornot | shouldornotanswer1 | shouldornotanswer2 |
| must be marked complete | False | True | should not | should not | should |
| must not be marked complete | False | True | should | should | should not |
| must be complete with pass grade | False | True | should not | should not | should |
| must be complete with fail grade | False | True | should not | should | should not |
@javascript
Scenario: Edit dependent activity name should also change the access restriction message
Given I am on the "Page 2" "page activity editing" page logged in as "teacher1"
And I expand all fieldsets
And I click on "Add restriction..." "button"
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
And I click on ".availability-item .availability-eye img" "css_element"
And I set the field "Activity or resource" to "Page 1"
And I press "Save and return to course"
And I am on the "Page 4" "page activity editing" page
And I expand all fieldsets
And I click on "Add restriction..." "button"
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
And I click on ".availability-item .availability-eye img" "css_element"
And I set the field "Activity or resource" to "Page 3"
And I press "Save and return to course"
And I switch editing mode on
And I set the field "Edit title" in the "Page 1" "activity" to "Page X"
And I wait until the page is ready
Then I should see "Not available unless: The activity Page X is marked complete" in the "Page 2" "activity"
Then I should see "Not available unless: The activity Page 3 is marked complete" in the "Page 4" "activity"
@@ -301,14 +301,14 @@ class condition_test extends \advanced_testcase {
$cond = new condition((object)[
'cm' => (int)$assigncm->id, 'e' => COMPLETION_INCOMPLETE
]);
$this->assertFalse($cond->is_available(false, $info, true, $user->id));
$this->assertTrue($cond->is_available(true, $info, true, $user->id));
$this->assertTrue($cond->is_available(false, $info, true, $user->id));
$this->assertFalse($cond->is_available(true, $info, true, $user->id));
$cond = new condition((object)[
'cm' => (int)$assigncm->id, 'e' => COMPLETION_COMPLETE
]);
$this->assertTrue($cond->is_available(false, $info, true, $user->id));
$this->assertFalse($cond->is_available(true, $info, true, $user->id));
$this->assertFalse($cond->is_available(false, $info, true, $user->id));
$this->assertTrue($cond->is_available(true, $info, true, $user->id));
$cond = new condition((object)[
'cm' => (int)$assigncm->id, 'e' => COMPLETION_COMPLETE_PASS
@@ -531,10 +531,10 @@ class condition_test extends \advanced_testcase {
],
// Depending on assign with grade.
'Previous complete condition with previous fail grade' => [
40, COMPLETION_COMPLETE, '', 'page3', true, false, '~Assign!.*is marked complete~'
40, COMPLETION_COMPLETE, '', 'page3', false, true, '~Assign!.*is marked complete~',
],
'Previous incomplete condition with previous fail grade' => [
40, COMPLETION_INCOMPLETE, '', 'page3', false, true, '~Assign!.*is incomplete~'
40, COMPLETION_INCOMPLETE, '', 'page3', true, false, '~Assign!.*is incomplete~',
],
'Previous complete pass condition with previous fail grade' => [
40, COMPLETION_COMPLETE_PASS, '', 'page3', false, true, '~Assign!.*is complete and passed~'
@@ -21,8 +21,7 @@ Feature: Private rule sets
| Group A | C1 | GA | 0 |
| Group B | C1 | GB | 1 |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add a "Page" to section "1"
And I add a page activity to course "Course 1" section "1"
And I expand all fieldsets
Scenario: Add restriction with visible condition (must match), display option should be active
+7 -1
View File
@@ -1602,7 +1602,13 @@ class backup_block_instance_structure_step extends backup_structure_step {
// Transform configdata information if needed (process links and friends)
$blockrec = $DB->get_record('block_instances', array('id' => $this->task->get_blockid()));
if ($attrstotransform = $this->task->get_configdata_encoded_attributes()) {
$configdata = (array)unserialize(base64_decode($blockrec->configdata));
$configdata = array_filter(
(array) unserialize_object(base64_decode($blockrec->configdata)),
static function($value): bool {
return !($value instanceof __PHP_Incomplete_Class);
}
);
foreach ($configdata as $attribute => $value) {
if (in_array($attribute, $attrstotransform)) {
$configdata[$attribute] = $this->contenttransformer->process($value);
+7 -1
View File
@@ -4398,7 +4398,13 @@ class restore_block_instance_structure_step extends restore_structure_step {
// Let's look for anything within configdata neededing processing
// (nulls and uses of legacy file.php)
if ($attrstotransform = $this->task->get_configdata_encoded_attributes()) {
$configdata = (array) unserialize_object(base64_decode($data->configdata));
$configdata = array_filter(
(array) unserialize_object(base64_decode($data->configdata)),
static function($value): bool {
return !($value instanceof __PHP_Incomplete_Class);
}
);
foreach ($configdata as $attribute => $value) {
if (in_array($attribute, $attrstotransform)) {
$configdata[$attribute] = $this->contentprocessor->process_cdata($value);
+5 -1
View File
@@ -160,12 +160,16 @@ if ($context->contextlevel == CONTEXT_MODULE) {
$renderer = $PAGE->get_renderer('core', 'backup');
echo $renderer->backup_files_viewer($treeview_options);
echo $OUTPUT->container_end();
// Update the course context with the proper value, because $context contains the module context.
$coursecontext = \context_course::instance($course->id);
} else {
$coursecontext = $context;
}
echo $OUTPUT->heading_with_help(get_string('choosefilefromcoursebackup', 'backup'), 'choosefilefromcoursebackup', 'backup');
echo $OUTPUT->container_start();
$treeview_options = array();
$treeview_options['filecontext'] = $context;
$treeview_options['filecontext'] = $coursecontext;
$treeview_options['currentcontext'] = $context;
$treeview_options['component'] = 'backup';
$treeview_options['context'] = $context;
@@ -137,9 +137,11 @@ abstract class backup_cron_automated_helper {
$rs->close();
// Send email to admin if necessary.
if ($emailpending) {
self::send_backup_status_to_admin($admin);
}
set_config(
'backup_auto_emailpending',
$emailpending ? 1 : 0,
'backup',
);
} finally {
// Everything is finished release lock.
$lock->release();
@@ -188,7 +190,7 @@ abstract class backup_cron_automated_helper {
* @param stdClass $admin
* @return array
*/
private static function send_backup_status_to_admin($admin) {
public static function send_backup_status_to_admin($admin) {
global $DB, $CFG;
mtrace("Sending email to admin");
@@ -386,7 +388,22 @@ abstract class backup_cron_automated_helper {
'courseid' => $backupcourse->courseid,
'adminid' => $admin->id
));
\core\task\manager::queue_adhoc_task($asynctask);
$taskid = \core\task\manager::queue_adhoc_task($asynctask);
// Get the queued tasks.
$queuedtasks = [];
if ($value = get_config('backup', 'backup_auto_adhoctasks')) {
$queuedtasks = explode(',', $value);
}
if ($taskid) {
$queuedtasks[] = (int) $taskid;
}
// Save the queued tasks.
set_config(
'backup_auto_adhoctasks',
implode(',', $queuedtasks),
'backup',
);
$backupcourse->laststatus = self::BACKUP_STATUS_QUEUED;
$DB->update_record('backup_courses', $backupcourse);
+5 -8
View File
@@ -14,20 +14,17 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die();
use \core_badges\badge;
/**
* Local stuff for category enrolment plugin.
* Event observer for badges.
*
* @package core_badges
* @copyright 2013 Rajesh Taneja <rajesh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
use \core_badges\badge;
/**
* Event observer for badges.
*/
class core_badges_observer {
/**
* Triggered when 'course_module_completion_updated' event is triggered.
+9 -2
View File
@@ -188,8 +188,6 @@ class award_criteria_activity extends award_criteria {
* @return bool Whether criteria is complete
*/
public function review($userid, $filtered = false) {
$completionstates = array(COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS, COMPLETION_COMPLETE_FAIL);
if ($this->course->startdate > time()) {
return false;
}
@@ -209,6 +207,15 @@ class award_criteria_activity extends award_criteria {
$check_date = ($date <= $param['bydate']);
}
// Successfull completion states depend on the completion settings.
if (isset($data->passgrade)) {
// Passing grade is required. Don't issue a badge when state is COMPLETION_COMPLETE_FAIL.
$completionstates = [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS];
} else {
// Any grade is required. Issue a badge even when state is COMPLETION_COMPLETE_FAIL.
$completionstates = [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS, COMPLETION_COMPLETE_FAIL];
}
if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) {
if (in_array($data->completionstate, $completionstates) && $check_date) {
$overall = true;
+2
View File
@@ -54,6 +54,8 @@ $badge = new badge($badgeid);
$context = $badge->get_context();
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type));
require_capability('moodle/badges:viewawarded', $context);
if ($badge->type == BADGE_TYPE_COURSE) {
if (empty($CFG->badges_allowcoursebadges)) {
throw new \moodle_exception('coursebadgesdisabled', 'badges');
+78 -71
View File
@@ -1,14 +1,14 @@
@mod @mod_quiz @core @core_badges @javascript
@mod @mod_quiz @core @core_badges @core_completion @javascript
Feature: Award badges based on activity completion
In order to ensure a student has learned the material before being marked complete
As a teacher
I need to set a quiz to award a badge when upon completion when the student receives a passing grade, or completed_fail if they use all attempts without passing
I need to configure an activity to grant a badge only when the student achieves a passing grade upon completion.
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 1 | student2@example.com |
| student2 | Student | 2 | student2@example.com |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | category | enablecompletion |
@@ -27,96 +27,103 @@ Feature: Award badges based on activity completion
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | First question | Answer the first question |
And the following "activities" exist:
| activity | name | course | idnumber | attempts | gradepass | completion | completionattemptsexhausted | completionpassgrade | completionusegrade |
| quiz | Test quiz name | C1 | quiz1 | 2 | 5.00 | 2 | 1 | 1 | 1 |
And quiz "Test quiz name" contains the following questions:
| activity | name | course | idnumber | attempts | gradepass | completion | completionpassgrade | completionusegrade |
| quiz | Test quiz name 1 | C1 | quiz1 | 2 | 5.00 | 2 | 1 | 1 |
| quiz | Test quiz name 2 | C1 | quiz2 | 2 | 5.00 | 2 | 0 | 1 |
And quiz "Test quiz name 1" contains the following questions:
| question | page |
| First question | 1 |
And quiz "Test quiz name 2" contains the following questions:
| question | page |
| First question | 1 |
And user "student1" has attempted "Test quiz name" with responses:
| slot | response |
| 1 | False |
And user "student2" has attempted "Test quiz name" with responses:
| slot | response |
| 1 | False |
And the following "core_badges > Badge" exists:
| name | Course Badge |
| name | Course Badge 1 |
| status | 0 |
| type | 2 |
| course | C1 |
| description | Course badge description |
| description | Course badge 1 description |
| image | badges/tests/behat/badge.png |
And the following "core_badges > Badge" exists:
| name | Course Badge 2 |
| status | 0 |
| type | 2 |
| course | C1 |
| description | Course badge 2 description |
| image | badges/tests/behat/badge.png |
And I am on the "Course 1" course page logged in as teacher1
Scenario: Student earns a badge using activity completion, but does not get passing grade
Given I am on the "Course 1" course page logged in as teacher1
And I navigate to "Badges" in current page administration
Scenario: Student does not earn a badge using activity completion when does not get passing grade
Given I navigate to "Badges" in current page administration
And I press "Manage badges"
And I follow "Course Badge"
And I follow "Course Badge 1"
And I select "Criteria" from the "jump" singleselect
And I set the field "type" to "Activity completion"
And I set the field "Quiz - Test quiz name" to "1"
And I set the field "Quiz - Test quiz name 1" to "1"
And I press "Save"
And I press "Enable access"
And I press "Continue"
And I should see "Recipients (0)"
And I log out
And I am on the "Course 1" course page logged in as student1
And the "Receive a grade" completion condition of "Test quiz name" is displayed as "done"
And the "Receive a passing grade" completion condition of "Test quiz name" is displayed as "failed"
And the "Receive a pass grade or complete all available attempts" completion condition of "Test quiz name" is displayed as "todo"
When I am on the "Test quiz name" "quiz activity" page
And I press "Re-attempt quiz"
And I set the field "False" to "1"
And I press "Finish attempt ..."
And I press "Submit all and finish"
And I click on "Submit" "button" in the "Submit all your answers and finish?" "dialogue"
And I log out
And I am on the "Course 1" course page logged in as teacher1
# Pass grade for student1. Activity is considered complete because student1 got a passing grade.
And user "student1" has attempted "Test quiz name 1" with responses:
| slot | response |
| 1 | True |
# Fail grade for student2. Activity is considered incomplete because student2 got a failing grade.
And user "student2" has attempted "Test quiz name 1" with responses:
| slot | response |
| 1 | False |
And I navigate to "Badges > Manage badges" in current page administration
And I follow "Course Badge"
And I follow "Course Badge 1"
Then I should see "Recipients (1)"
And I select "Recipients (1)" from the "jump" singleselect
And I should see "Student 1"
And I should not see "Student 2"
Scenario Outline: Previously graded pass/fail students should earn a badge after enabling a badge
Given I am on the "Course 1" course page logged in as teacher1
And I navigate to "Badges" in current page administration
Scenario: Students with any grades in an activity will receive a badge if the completion condition is set to receive any grade
Given I navigate to "Badges" in current page administration
And I press "Manage badges"
And I follow "Course Badge"
And I follow "Course Badge 2"
And I select "Criteria" from the "jump" singleselect
And I set the field "type" to "Activity completion"
And I click on "Expand all" "link"
And I set the field "Quiz - Test quiz name" to "1"
And I set the field "<aggregationcriteria>" to "1"
And I set the field "Quiz - Test quiz name 2" to "1"
And I press "Save"
# Fail grade with student2
And I am on the "Course 1" course page logged in as student2
And I am on the "Test quiz name" "quiz activity" page
And I press "Re-attempt quiz"
And I set the field "False" to "1"
And I press "Finish attempt ..."
And I press "Submit all and finish"
And I click on "Submit" "button" in the "Submit all your answers and finish?" "dialogue"
And I log out
# Pass grade with student1
And I am on the "Course 1" course page logged in as student1
And I am on the "Test quiz name" "quiz activity" page
And I press "Re-attempt quiz"
And I set the field "False" to "0"
And I press "Finish attempt ..."
And I press "Submit all and finish"
And I click on "Submit" "button" in the "Submit all your answers and finish?" "dialogue"
And I log out
# Enable badge access once all students have completed an activity.
And I am on the "Course 1" course page logged in as teacher1
And I press "Enable access"
And I press "Continue"
# Pass grade for student1.
And user "student1" has attempted "Test quiz name 2" with responses:
| slot | response |
| 1 | True |
# Fail grade for student2. Activity is considered complete even if student2 got a failing grade.
And user "student2" has attempted "Test quiz name 2" with responses:
| slot | response |
| 1 | False |
And I navigate to "Badges > Manage badges" in current page administration
And I follow "Course Badge"
And I follow "Course Badge 2"
Then I should see "Recipients (2)"
And I select "Recipients (2)" from the "jump" singleselect
And I should see "Student 1"
And I should see "Student 2"
Scenario: Previously graded pass/fail students should earn a badge after enabling a badge
# Pass grade for student1.
Given user "student1" has attempted "Test quiz name 1" with responses:
| slot | response |
| 1 | True |
# Fail grade for student2.
And user "student2" has attempted "Test quiz name 1" with responses:
| slot | response |
| 1 | False |
And I navigate to "Badges" in current page administration
And I press "Manage badges"
And I follow "Course Badge 1"
And I select "Criteria" from the "jump" singleselect
And I set the field "type" to "Activity completion"
And I set the field "Quiz - Test quiz name 1" to "1"
And I press "Save"
# Enable badge access once students have completed the activity.
When I press "Enable access"
And I press "Continue"
Then I should see "Recipients (2)"
Examples:
| aggregationcriteria |
| Any of the selected activities is complete |
| All of the selected activities are complete |
# Only student1 should earn the badge because student2 did not pass the quiz.
Then I should see "Recipients (1)"
And I select "Recipients (1)" from the "jump" singleselect
And I should see "Student 1"
And I should not see "Student 2"
@@ -0,0 +1,52 @@
@core @core_badges
Feature: Delete course badge already awarded
As a teacher
I can delete awarded course badge
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
@javascript
Scenario Outline: Delete course badge already awarded to student
Given the following "core_badges > Badges" exist:
| name | course | description | image | status | type |
| <badgename> | C1 | <badgename> description | badges/tests/behat/badge.png | active | 2 |
And the following "core_badges > Criterias" exist:
| badge | role |
| <badgename> | editingteacher |
And the following "core_badges > Issued badges" exist:
| badge | user |
| <badgename> | student1 |
When I am on the "Course 1" "enrolled users" page logged in as "teacher1"
And I click on "Student 1" "link"
Then I should see "<badgename>"
And I am on the "Course 1" course page
# Navigate to Manage Badges page in order to delete the badge
And I navigate to "Badges > Manage badges" in current page administration
# Delete the badge
And I click on "Delete" "icon" in the "<badgename>" "table_row"
And I press "<deleteoption>"
And I am on the "Course 1" "enrolled users" page
And I click on "Student 1" "link"
# Confirm that Badge 1 is retained as awarded badge but Badge 2 is not
And I <visibility> see "<badgename>"
And I am on the "Course 1" course page
# Navigate to Badges page to confirm that no badges exist, hence, Manage badges would not exist
And I navigate to "Badges" in current page administration
# Confirm that badges are sucessfully deleted
And I should see "There are currently no badges available for users to earn."
Examples:
| badgename | deleteoption | visibility |
| Badge 1 | Delete and keep existing issued badges | should |
| Badge 2 | Delete and remove existing issued badges | should not |
+20 -1
View File
@@ -59,7 +59,26 @@ function block_comments_comment_validate($comment_param) {
* @return array
*/
function block_comments_comment_permissions($args) {
return array('post'=>true, 'view'=>true);
global $DB, $USER;
// By default, anyone can post and view comments.
$canpost = $canview = true;
// Check if it's the user context and not the owner's profile.
if ($args->context->contextlevel == CONTEXT_USER && $USER->id != $args->context->instanceid) {
// Check whether the context owner has a comment block in the user's profile.
$sqlparam = [
'blockname' => 'comments',
'parentcontextid' => $args->context->id,
'pagetypepattern' => 'user-profile',
];
// If the comment block is not present at the target user's profile,
// then the logged-in user cannot post or view comments.
$canpost = $canview = $DB->record_exists_select(
'block_instances',
'blockname = :blockname AND parentcontextid = :parentcontextid AND pagetypepattern = :pagetypepattern',
$sqlparam,
);
}
return ['post' => $canpost, 'view' => $canview];
}
/**
@@ -10,7 +10,7 @@ Feature: Add a comment to the comments block
| Course 1 | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
| student1 | Student | First | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
@@ -25,11 +25,16 @@ Feature: Add a comment to the comments block
Scenario: Add a comment with Javascript enabled
When I add "I'm a comment from student1" comment to comments block
Then I should see "I'm a comment from student1"
And I am on the "Course 1" course page logged in as teacher1
And I should see "I'm a comment from student1"
Scenario: Add a comment with Javascript disabled
When I follow "Show comments"
And I add "I'm a comment from student1" comment to comments block
Then I should see "I'm a comment from student1"
And I am on the "Course 1" course page logged in as teacher1
And I follow "Show comments"
And I should see "I'm a comment from student1"
@javascript
Scenario: Test comment block pagination
@@ -10,7 +10,7 @@ Feature: Enable Block comments on an activity page and view comments
| Course 1 | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
| student1 | Student | First | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
@@ -1,27 +0,0 @@
@block @block_comments
Feature: Enable Block comments on a course page and view comments
In order to enable the comments block on a course page
As a teacher
I can add the comments block to the course page
Scenario: Add the comments block on the course page and add comments
Given the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| student1 | Student | First | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| comments | Course | C1 | course-view-* | side-pre |
And I am on the "Course 1" course page logged in as teacher1
And I follow "Show comments"
And I add "I'm a comment from the teacher" comment to comments block
When I am on the "Course 1" course page logged in as student1
And I follow "Show comments"
Then I should see "I'm a comment from the teacher"
@@ -10,7 +10,7 @@ Feature: Enable Block comments on the dashboard and view comments
| Course 1 | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
Scenario: Add the comments block on the dashboard and add comments with Javascript disabled
When I log in as "teacher1"
@@ -1,4 +1,4 @@
@block @block_completionstatus
@block @block_completionstatus @core_completion
Feature: Enable Block Completion in a course using activity completion
In order to view the completion block in a course
As a teacher
@@ -17,117 +17,69 @@ Feature: Enable Block Completion in a course using activity completion
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And the following "activities" exist:
| activity | course | idnumber | name | intro |
| page | C1 | page1 | Test page name | Test page description |
| assign | C1 | assign1 | Test assign name | Test page description |
| activity | course | idnumber | name | gradepass | completion | completionview | completionusegrade | completionpassgrade |
| page | C1 | page1 | Test page name | | 2 | 1 | 0 | 0 |
| assign | C1 | assign1 | Test assign name | 50 | 2 | 0 | 1 | 1 |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| completionstatus | Course | C1 | course-view-* | side-pre |
Scenario: Add the block to a the course and add course completion items
Given I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I follow "Test page name"
And I navigate to "Settings" in current page administration
And I set the following fields to these values:
| Completion tracking | Show activity as complete when conditions are met |
| Require view | 1 |
And I press "Save and return to course"
And I add the "Course completion status" block
Scenario: Completion status block when student has not started any activities
Given I am on the "Course 1" course page logged in as teacher1
And I navigate to "Course completion" in current page administration
And I expand all fieldsets
And I set the following fields to these values:
| Test page name | 1 |
And I press "Save changes"
And I log out
When I log in as "student1"
And I am on "Course 1" course homepage
When I am on the "Course 1" course page logged in as student1
Then I should see "Status: Not yet started" in the "Course completion status" "block"
And I should see "0 of 1" in the "Activity completion" "table_row"
Scenario: Add the block to a the course and add course completion items
Given I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I follow "Test page name"
And I navigate to "Settings" in current page administration
And I set the following fields to these values:
| Completion tracking | Show activity as complete when conditions are met |
| Require view | 1 |
And I press "Save and return to course"
And I add the "Course completion status" block
Scenario: Completion status block when student has completed a page
Given I am on the "Course 1" course page logged in as teacher1
And I navigate to "Course completion" in current page administration
And I expand all fieldsets
And I set the following fields to these values:
| Test page name | 1 |
And I press "Save changes"
And I log out
When I log in as "student1"
And I am on "Course 1" course homepage
And I follow "Test page name"
When I am on the "Test page name" "page activity" page logged in as student1
And I am on "Course 1" course homepage
Then I should see "Status: Complete" in the "Course completion status" "block"
And I should see "1 of 1" in the "Activity completion" "table_row"
And I follow "More details"
And I should see "Yes" in the "Activity completion" "table_row"
@javascript
Scenario: Add the block to a the course and add course completion items with passing grade
Given I am on the "Test assign name" "assign activity" page logged in as teacher1
And I navigate to "Settings" in current page administration
And I set the following fields to these values:
| Completion tracking | Show activity as complete when conditions are met |
| completionusegrade | 1 |
| completionpassgrade | 1 |
| gradepass | 50 |
And I press "Save and return to course"
And I am on the "Test assign name" "assign activity" page
And I follow "View all submissions"
And I click on "Grade" "link" in the "Student" "table_row"
And I set the field "Grade out of 100" to "53"
And I set the field "Notify student" to "0"
And I press "Save changes"
And I am on "Course 1" course homepage with editing mode on
And I add the "Course completion status" block
Scenario: Completion status block with items with passing grade
Given I am on the "Course 1" course page logged in as teacher1
And I navigate to "Course completion" in current page administration
And I expand all fieldsets
And I set the following fields to these values:
| Test assign name | 1 |
And I press "Save changes"
And I log out
When I am on the "Test assign name" "assign activity" page logged in as student1
And I am on "Course 1" course homepage
Then I should see "Status: Pending" in the "Course completion status" "block"
And I should see "0 of 1" in the "Activity completion" "table_row"
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assign name | student1 | 53 |
When I am on the "Course 1" course page logged in as student1
Then I should see "Status: Complete" in the "Course completion status" "block"
And I should see "1 of 1" in the "Activity completion" "table_row"
And I trigger cron
And I am on "Course 1" course homepage
And I follow "More details"
And I should see "Achieving grade, Achieving passing grade" in the "Activity completion" "table_row"
And I should see "Yes" in the "Activity completion" "table_row"
@javascript
Scenario: Add the block to a the course and add course completion items with failing grade.
Given I am on the "Test assign name" "assign activity" page logged in as teacher1
And I navigate to "Settings" in current page administration
And I set the following fields to these values:
| Completion tracking | Show activity as complete when conditions are met |
| completionusegrade | 1 |
| completionpassgrade | 1 |
| gradepass | 50 |
And I press "Save and return to course"
And I am on the "Test assign name" "assign activity" page
And I follow "View all submissions"
And I click on "Grade" "link" in the "Student" "table_row"
And I set the field "Grade out of 100" to "49"
And I set the field "Notify student" to "0"
And I press "Save changes"
And I am on "Course 1" course homepage with editing mode on
And I add the "Course completion status" block
Scenario: Completion status block with items with failing grade
Given I am on the "Course 1" course page logged in as teacher1
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assign name | student1 | 49 |
And I navigate to "Course completion" in current page administration
And I expand all fieldsets
And I set the following fields to these values:
| Test assign name | 1 |
And I press "Save changes"
And I log out
When I am on the "Test assign name" "assign activity" page logged in as student1
And I am on "Course 1" course homepage
Then I should see "Status: Pending" in the "Course completion status" "block"
When I am on the "Course 1" course page logged in as student1
Then I should see "Status: Not yet started" in the "Course completion status" "block"
And I should see "0 of 1" in the "Activity completion" "table_row"
And I trigger cron
And I am on "Course 1" course homepage
+3 -2
View File
@@ -509,7 +509,7 @@ class main implements renderable, templatable {
);
return $this->generate_zero_state_data(
$nocoursesimg,
[$button],
[$button->export_for_template($output)],
['title' => 'zero_request_title', 'intro' => 'zero_request_intro']
);
}
@@ -522,6 +522,7 @@ class main implements renderable, templatable {
$quickstartbutton = new \single_button(
new \moodle_url($quickstarturl, ['lang' => current_language()]),
get_string('viewquickstart', 'block_myoverview'),
'get',
);
$buttons = [$quickstartbutton->export_for_template($output)];
}
@@ -580,7 +581,7 @@ class main implements renderable, templatable {
* Generate the state zero data.
*
* @param \moodle_url $imageurl The URL to the image to show
* @param \single_button[] $buttons
* @param string[] $buttons Exported {@see \single_button} instances
* @param array $strings Title and intro strings for the zero state if needed.
* @return array Context variables for the template
*/
@@ -30,7 +30,7 @@ $string['aria:allcoursesincludinghidden'] = 'Show all courses';
$string['aria:allcourses'] = 'Show all courses except courses removed from view';
$string['aria:card'] = 'Switch to card view';
$string['aria:controls'] = 'Course overview controls';
$string['aria:courseactions'] = 'Actions for current course';
$string['aria:courseactions'] = 'Actions for course';
$string['aria:coursesummary'] = 'Course summary text:';
$string['aria:courseprogress'] = 'Course progress:';
$string['aria:customfield'] = 'Show {$a} courses';
@@ -26,7 +26,7 @@
"name": "Assignment due 1",
"viewurl": "https://moodlesite/course/view.php?id=2",
"courseimage": "https://moodlesite/pluginfile/123/course/overviewfiles/123.jpg",
"fullname": "course 3",
"fullname": "Course 3 for \"Statistical and Computational Tools\" ",
"hasprogress": true,
"progress": 10,
"coursecategory": "Category 1",
@@ -50,8 +50,11 @@
{{/hasprogress}}
{{/progress}}
{{$coursename}}
<span class="multiline">
{{#shortentext}}50, {{{fullname}}} {{/shortentext}}
<span class="multiline" title="{{fullname}}">
<span class="sr-only">{{{fullname}}}</span>
<span aria-hidden="true">
{{#shortentext}}55, {{{fullname}}} {{/shortentext}}
</span>
</span>
{{/coursename}}
{{$coursecategory}}
@@ -94,6 +94,7 @@ Feature: The my overview block allows users to hide their courses
When I click on "All" "link" in the "Course overview" "block"
And I click on ".coursemenubtn" "css_element" in the "//div[@class='card dashboard-card' and contains(.,'Course 2')]" "xpath_element"
And I click on "Remove from view" "link" in the "//div[@class='card dashboard-card' and contains(.,'Course 2')]" "xpath_element"
And I wait "1" seconds
Then I should not see "Course 2" in the "Course overview" "block"
Scenario: Test a course is never hidden with "All (including removed from view)" courses
@@ -86,7 +86,7 @@ class recentlyaccesseditems_item_exporter extends \core\external\exporter {
'type' => PARAM_INT,
),
'modname' => array(
'type' => PARAM_TEXT,
'type' => PARAM_PLUGIN,
),
'name' => array(
'type' => PARAM_TEXT,
@@ -108,7 +108,7 @@ class recentlyaccesseditems_item_exporter extends \core\external\exporter {
public static function define_other_properties() {
return array(
'viewurl' => array(
'type' => PARAM_TEXT,
'type' => PARAM_RAW,
),
'courseviewurl' => array(
'type' => PARAM_URL,
@@ -117,7 +117,7 @@ class recentlyaccesseditems_item_exporter extends \core\external\exporter {
'type' => PARAM_RAW,
),
'purpose' => array(
'type' => PARAM_TEXT,
'type' => PARAM_ALPHA,
)
);
}
+1 -1
View File
@@ -1220,7 +1220,7 @@ function blog_validate_access($courseid, $modid, $groupid, $entryid, $userid) {
throw new \moodle_exception('courseblogdisable', 'blog');
}
if (!$mod = $DB->get_record('course_modules', array('id' => $modid))) {
throw new \moodle_exception('invalidmoduleid', 'error', $modid);
throw new \moodle_exception('invalidmoduleid', 'error', '', $modid);
}
$courseid = $mod->course;
}
+14 -4
View File
@@ -441,8 +441,17 @@ class cachestore_file extends cache_store implements cache_is_key_aware, cache_i
} while (!feof($handle));
$this->lastiobytes = strlen($data);
if ($this->lastiobytes == 0) {
// Potentially statcache is stale. File can be deleted, let's clear cache and recheck.
clearstatcache(true, $file);
if (!file_exists($file)) {
// It's a completely normal condition. Just ignore and keep going.
return false;
}
}
// Return it unserialised.
return $this->prep_data_after_read($data);
return $this->prep_data_after_read($data, $file);
}
/**
@@ -548,13 +557,14 @@ class cachestore_file extends cache_store implements cache_is_key_aware, cache_i
* Prepares the data it has been read from the cache. Undoing what was done in prep_data_before_save.
*
* @param string $data
* @param string $path
* @return mixed
* @throws coding_exception
*/
protected function prep_data_after_read($data) {
protected function prep_data_after_read($data, $path) {
$result = @unserialize($data);
if ($result === false && $data != serialize(false)) {
throw new coding_exception('Failed to unserialise data from file. Either failed to read, or failed to write.');
debugging('Failed to unserialise data from cache file: ' . $path . '. Data: ' . $data, DEBUG_DEVELOPER);
return false;
}
return $result;
}
+9 -12
View File
@@ -14,22 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Contains event class for displaying the day view.
*
* @package core_calendar
* @copyright 2017 Simey Lameze <simey@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use core\external\exporter;
use core_date;
use DateTimeImmutable;
use renderer_base;
use moodle_url;
use \core_calendar\local\event\container;
use core_calendar\local\event\container;
/**
* Class for displaying the day view.
@@ -209,7 +201,12 @@ class calendar_day_exporter extends exporter {
// Need to account for user's timezone.
$usernow = usergetdate(time());
$today = new \DateTimeImmutable();
$today = new DateTimeImmutable(
timezone: core_date::get_user_timezone_object(),
);
// The start time should use the day's date but the current
// time of the day (adjusted for user's timezone).
$neweventtimestamp = $today->setTimestamp($date[0])->setTime(
$usernow['hours'],
$usernow['minutes'],
+6 -9
View File
@@ -14,14 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Contains event class for displaying the day view.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
@@ -29,6 +21,8 @@ defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/calendar/lib.php');
use core\external\exporter;
use core_date;
use DateTimeImmutable;
use renderer_base;
use moodle_url;
@@ -169,7 +163,10 @@ class day_exporter extends exporter {
$timestamp = $this->data[0];
// Need to account for user's timezone.
$usernow = usergetdate(time());
$today = new \DateTimeImmutable();
$today = new DateTimeImmutable(
timezone: core_date::get_user_timezone_object(),
);
// The start time should use the day's date but the current
// time of the day (adjusted for user's timezone).
$neweventstarttime = $today->setTimestamp($timestamp)->setTime(
+2 -2
View File
@@ -41,7 +41,7 @@
}} data-month="{{previousperiod.mon}}"{{!
}} data-day="{{previousperiod.mday}}"{{!
}}>
<span class="arrow">{{{larrow}}}</span>
<span class="arrow" aria-hidden="true">{{{larrow}}}</span>
&nbsp;
<span class="arrow_text">{{previousperiodname}}</span>
</a>
@@ -58,7 +58,7 @@
}}>
<span class="arrow_text">{{nextperiodname}}</span>
&nbsp;
<span class="arrow">{{{rarrow}}}</span>
<span class="arrow" aria-hidden="true">{{{rarrow}}}</span>
</a>
</div>
</div>
+2 -2
View File
@@ -41,7 +41,7 @@
}} data-month="{{previousperiod.mon}}"{{!
}} data-drop-zone="nav-link" {{!
}}>
<span class="arrow">{{{larrow}}}</span>
<span class="arrow" aria-hidden="true">{{{larrow}}}</span>
&nbsp;
<span class="arrow_text">{{previousperiodname}}</span>
</a>
@@ -63,7 +63,7 @@
}}>
<span class="arrow_text">{{nextperiodname}}</span>
&nbsp;
<span class="arrow">{{{rarrow}}}</span>
<span class="arrow" aria-hidden="true">{{{rarrow}}}</span>
</a>
</div>
</div>
@@ -62,6 +62,7 @@
}} data-action="view-event"{{!
}} data-event-id="{{id}}"{{!
}} href="{{viewurl}}"{{!
}} title="{{name}}"{{!
}}>{{{name}}}</a>
</h6>
<div class="date small">{{{formattedtime}}}</div>
+17 -1
View File
@@ -176,7 +176,23 @@ class behat_calendar extends behat_base {
* @return void
*/
public function i_am_viewing_site_calendar() {
$url = new moodle_url('/calendar/view.php', ['view' => 'month']);
$this->i_am_viewing_calendar_in_view('month');
}
/**
* Navigate to a specific view in the calendar.
*
* @Given /^I am viewing calendar in "([^"]+)" view$/
* @param string $view The calendar view ('month', 'day' and 'upcoming') to navigate to.
* @return void
*/
public function i_am_viewing_calendar_in_view(string $view): void {
if (!in_array($view, ['month', 'day', 'upcoming'])) {
throw new Exception("Invalid calendar view. Allowed values are: 'month', 'day' and 'upcoming'");
}
$url = new moodle_url('/calendar/view.php', ['view' => $view]);
$this->execute('behat_general::i_visit', [$url]);
}
}
+1 -1
View File
@@ -88,7 +88,7 @@ Feature: Manage custom reports for cohorts
And I click on "Show/hide 'Sorting'" "button"
And I click on "Move sorting for column 'Last name'" "button"
And I click on "To the top of the list" "link" in the "Move sorting for column 'Last name'" "dialogue"
And I click on "Enable initial sorting for column Last name" "checkbox"
And I click on "Enable initial sorting for column 'Last name'" "checkbox"
# "New system cohort" has fewer members than "Another one" cohort.
And "New system cohort" "table_row" should appear before "Another one" "table_row"
When I click on "Sort column 'Last name' descending" "button"
+5
View File
@@ -41,6 +41,11 @@ M.core_comment = {
this.courseid = args.courseid;
this.contextid = args.contextid;
this.autostart = (args.autostart);
// Fail fast if the comments element cannot be found, such as in embedded-type views where blocks may be loaded
// then discarded.
if (!Y.one('#comment-ctrl-'+this.client_id)) {
return;
}
// expand comments?
if (this.autostart) {
this.view(args.page);
@@ -155,8 +155,8 @@ class completion_criteria_activity extends completion_criteria {
$data = $info->get_data($cm, false, $completion->userid);
// If the activity is complete
if (in_array($data->completionstate, array(COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS, COMPLETION_COMPLETE_FAIL))) {
// If the activity is complete.
if (in_array($data->completionstate, [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS])) {
if ($mark) {
$completion->mark_complete();
}
@@ -10,7 +10,7 @@ Feature: Allow teachers to bulk edit activity completion rules in a course.
| Course 1 | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
| student1 | Student | First | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
@@ -1,4 +1,4 @@
@block @block_completionstatus @javascript
@block @block_completionstatus @core_completion @javascript
Feature: Course completion state should match completion criteria
In order to understand the configuration or status of an course's completion
As a user
@@ -8,7 +8,6 @@ Feature: Course completion state should match completion criteria
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| teacher2 | Teacher | 2 | teacher1@example.com | T2 |
| student1 | Student | 1 | student1@example.com | S1 |
And the following "courses" exist:
| fullname | shortname | category | enablecompletion | showcompletionconditions |
@@ -16,16 +15,18 @@ Feature: Course completion state should match completion criteria
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher2 | C1 | teacher |
| student1 | C1 | student |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment name |
| completion | 1 |
| assignsubmission_onlinetext_enabled | 1 |
| grade[modgrade_type] | Point |
| grade[modgrade_point] | 100 |
| grade[modgrade_type] | Point |
| grade[modgrade_point] | 100 |
| gradepass | 70 |
| completion | 2 |
| completionusegrade | 1 |
| completionpassgrade | 1 |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| completionstatus | Course | C1 | course-view-* | side-pre |
@@ -34,58 +35,36 @@ Feature: Course completion state should match completion criteria
And I click on "Condition: Activity completion" "link"
And I set the field "Assignment - Test assignment name" to "1"
And I press "Save changes"
And I am on the "Test assignment name" "assign activity editing" page
And I set the following fields to these values:
| Completion tracking | Show activity as complete when conditions are met |
| completionusegrade | 1 |
| completionpassgrade | 1 |
| gradepass | 70 |
And I press "Save and return to course"
Scenario: Completion status show match completion criteria when passgrage condition is set.
Given I am on the "Course 1" course page logged in as "student1"
And the "Receive a grade" completion condition of "Test assignment name" is displayed as "todo"
And the "Receive a passing grade" completion condition of "Test assignment name" is displayed as "todo"
And I should see "Status: Not yet started" in the "Course completion status" "block"
And I am on the "Test assignment name" "assign activity" page
And I press "Add submission"
And I set the following fields to these values:
| Online text | I'm the student1 submission |
And I press "Save changes"
And I press "Submit assignment"
And I press "Continue"
And I am on the "Test assignment name" "assign activity" page logged in as teacher1
And I follow "View all submissions"
And I click on "Grade" "link" in the "Student 1" "table_row"
And I set the following fields to these values:
| Grade out of 100 | 50.0 |
And I press "Save changes"
And I am on the "Course 1" course page
And I navigate to "Reports" in current page administration
And I click on "Activity completion" "link"
And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row"
And I navigate to "Reports" in current page administration
And I click on "Course completion" "link" in the "region-main" "region"
And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row"
And "Student 1, Course complete: Not completed" "icon" should exist in the "Student 1" "table_row"
When I am on the "Course 1" course page logged in as "student1"
And I should see "Status: Pending" in the "Course completion status" "block"
When the following "mod_assign > submissions" exist:
| assign | user | onlinetext |
| Test assignment name | student1 | This is a submission for assignment |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment name | student1 | 50 |
And I reload the page
Then I should see "Status: Not yet started" in the "Course completion status" "block"
And the "Receive a grade" completion condition of "Test assignment name" is displayed as "done"
And the "Receive a passing grade" completion condition of "Test assignment name" is displayed as "failed"
And I am on the "My courses" page
And I should not see "100%" in the "Course overview" "block"
And I am on the "Test assignment name" "assign activity" page logged in as teacher1
And I follow "View all submissions"
And I click on "Grade" "link" in the "Student 1" "table_row"
And I set the following fields to these values:
| Grade out of 100 | 75.0 |
And I press "Save changes"
And I am on the "Course 1" course page
And I navigate to "Reports" in current page administration
And I click on "Activity completion" "link"
And I am on the "Course 1" course page logged in as teacher1
And I navigate to "Reports > Activity completion" in current page administration
And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row"
And I navigate to "Reports > Course completion" in current page administration
And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row"
And "Student 1, Course complete: Not completed" "icon" should exist in the "Student 1" "table_row"
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment name | student1 | 75 |
And I navigate to "Reports > Activity completion" in current page administration
And "Student 1, Test assignment name: Completed (achieved pass grade)" "icon" should exist in the "Student 1" "table_row"
And I navigate to "Reports" in current page administration
And I click on "Course completion" "link" in the "region-main" "region"
And I navigate to "Reports > Course completion" in current page administration
And "Student 1, Test assignment name: Completed (achieved pass grade)" "icon" should exist in the "Student 1" "table_row"
And "Student 1, Course complete: Completed" "icon" should exist in the "Student 1" "table_row"
And I am on the "Course 1" course page logged in as "student1"
@@ -93,62 +72,46 @@ Feature: Course completion state should match completion criteria
And the "Receive a grade" completion condition of "Test assignment name" is displayed as "done"
And the "Receive a passing grade" completion condition of "Test assignment name" is displayed as "done"
And I am on the "My courses" page
Then I should see "100%" in the "Course overview" "block"
And I should see "100%" in the "Course overview" "block"
Scenario: Completion status show match completion criteria when passgrage condition is not set.
Given I am on the "Test assignment name" "assign activity editing" page logged in as teacher1
And I set the following fields to these values:
| Completion tracking | Show activity as complete when conditions are met |
| completionusegrade | 1 |
| completionpassgrade | 0 |
| gradepass | 70 |
| completionpassgrade | 0 |
And I press "Save and return to course"
And I am on the "Course 1" course page logged in as "student1"
And the "Receive a grade" completion condition of "Test assignment name" is displayed as "todo"
And I should see "Status: Not yet started" in the "Course completion status" "block"
And I am on the "Test assignment name" "assign activity" page
And I press "Add submission"
And I set the following fields to these values:
| Online text | I'm the student1 submission |
And I press "Save changes"
And I press "Submit assignment"
And I press "Continue"
And I am on the "Test assignment name" "assign activity" page logged in as teacher1
And I follow "View all submissions"
And I click on "Grade" "link" in the "Student 1" "table_row"
And I set the following fields to these values:
| Grade out of 100 | 50.0 |
And I press "Save changes"
And I am on the "Course 1" course page
And I navigate to "Reports" in current page administration
And I click on "Activity completion" "link"
And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row"
And I navigate to "Reports" in current page administration
And I click on "Course completion" "link" in the "region-main" "region"
And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row"
And "Student 1, Course complete: Completed" "icon" should exist in the "Student 1" "table_row"
When I am on the "Course 1" course page logged in as "student1"
And I should see "Status: Complete" in the "Course completion status" "block"
When the following "mod_assign > submissions" exist:
| assign | user | onlinetext |
| Test assignment name | student1 | I'm the student1 submission |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment name | student1 | 50 |
And I reload the page
# TODO: Expected status is Complete but activity is marked as completed with a failed icon.
# Then I should see "Status: Complete" in the "Course completion status" "block"
Then I should see "Status: Pending" in the "Course completion status" "block"
# Once MDL-75582 is fixed "failed" should be changed to "done"
And the "Receive a grade" completion condition of "Test assignment name" is displayed as "failed"
And I am on the "My courses" page
And I should see "100%" in the "Course overview" "block"
And I am on the "Test assignment name" "assign activity" page logged in as teacher1
And I follow "View all submissions"
And I click on "Grade" "link" in the "Student 1" "table_row"
And I set the following fields to these values:
| Grade out of 100 | 75.0 |
And I press "Save changes"
And I am on the "Course 1" course page
And I navigate to "Reports" in current page administration
And I click on "Activity completion" "link"
And I am on the "Course 1" course page logged in as teacher1
And I navigate to "Reports > Activity completion" in current page administration
And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row"
And I navigate to "Reports > Course completion" in current page administration
And "Student 1, Test assignment name: Completed (did not achieve pass grade)" "icon" should exist in the "Student 1" "table_row"
And "Student 1, Course complete: Completed" "icon" should exist in the "Student 1" "table_row"
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment name | student1 | 75 |
And I navigate to "Reports > Activity completion" in current page administration
And "Student 1, Test assignment name: Completed (achieved pass grade)" "icon" should exist in the "Student 1" "table_row"
And I navigate to "Reports" in current page administration
And I click on "Course completion" "link" in the "region-main" "region"
And I navigate to "Reports > Course completion" in current page administration
And "Student 1, Test assignment name: Completed (achieved pass grade)" "icon" should exist in the "Student 1" "table_row"
And "Student 1, Course complete: Completed" "icon" should exist in the "Student 1" "table_row"
And I am on the "Course 1" course page logged in as "student1"
And I should see "Status: Complete" in the "Course completion status" "block"
And the "Receive a grade" completion condition of "Test assignment name" is displayed as "done"
And I am on the "My courses" page
Then I should see "100%" in the "Course overview" "block"
And I should see "100%" in the "Course overview" "block"
@@ -14,7 +14,7 @@ Feature: Allow teachers to edit the default activity completion rules in a cours
| Course 1 | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
| student1 | Student | First | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
@@ -48,3 +48,37 @@ Feature: Allow teachers to edit the default activity completion rules in a cours
And I should see "Student must receive a grade to complete this activity" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element"
And I should see "Student must make a submission" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element"
And I should not see "Completion expected on" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element"
@javascript
Scenario: Course activity completion default rules for SCORM
Given the following "courses" exist:
| fullname | shortname | category | enablecompletion |
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | First | teacher1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I am on the "Course 1" course page logged in as teacher1
When I navigate to "Course completion" in current page administration
And I select "Default activity completion" from the "Course completion tertiary navigation" singleselect
And I click on "SCORM packages" "checkbox"
And I click on "Edit" "button"
# Check Passed option.
And I set the following fields to these values:
| completion | Show activity as complete when conditions are met|
| completionstatusrequired[2] | 1 |
And I click on "Save changes" "button"
Then I should see "Changes saved"
And I should see "Student must achieve at least one of the following statuses: Passed, Completed"
And I navigate to "Course completion" in current page administration
And I select "Default activity completion" from the "Course completion tertiary navigation" singleselect
And I click on "SCORM packages" "checkbox"
And I click on "Edit" "button"
# Uncheck Pass option.
And I set the following fields to these values:
| completionstatusrequired[2] | 0 |
And I click on "Save changes" "button"
Then I should see "Changes saved"
And I should see "Student must achieve at least one of the following statuses: Completed"
@@ -7,7 +7,7 @@ Feature: Students will be marked as completed if they have achieved a passing gr
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
| student1 | Student | First | student1@example.com |
| student2 | Student | Second | student2@example.com |
And the following "course enrolments" exist:
@@ -8,7 +8,7 @@ Feature: Students will be marked as completed and pass/fail
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
| student1 | Student | First | student1@example.com |
| student2 | Student | Second | student2@example.com |
| student3 | Student | Third | student3@example.com |
@@ -11,7 +11,7 @@ Feature: Allow students to manually mark an activity as complete
| Course 1 | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
| student1 | Student | First | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
@@ -10,7 +10,7 @@ Feature: Students will be shown relevant completion state based on grade item vi
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
| student1 | Student | First | student1@example.com |
| student2 | Student | Second | student2@example.com |
And the following "course enrolments" exist:
@@ -10,7 +10,7 @@ Feature: Restrict activity availability through date conditions
| Course 1 | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
| student1 | Student | First | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
@@ -11,7 +11,7 @@ Feature: Restrict activity availability through grade conditions
| Course 1 | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
| student1 | Student | First | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
@@ -10,7 +10,7 @@ Feature: Restrict sections availability through completion or grade conditions
| Course 1 | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Frist | teacher1@example.com |
| teacher1 | Teacher | First | teacher1@example.com |
| student1 | Student | First | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
+1
View File
@@ -298,6 +298,7 @@ $CFG->admin = 'admin';
// '/dataroot/' => $CFG->dataroot,
// '/cachedir/' => '/var/www/moodle/cache', // for custom $CFG->cachedir locations
// '/localcachedir/' => '/var/local/cache', // for custom $CFG->localcachedir locations
// '/localrequestdir/' => '/tmp', // for custom $CFG->localrequestdir locations
// '/tempdir/' => '/var/www/moodle/temp', // for custom $CFG->tempdir locations
// '/filedir' => '/var/www/moodle/filedir', // for custom $CFG->filedir locations
// );
+1 -1
View File
@@ -5,6 +5,6 @@ define("core_course/repository",["exports","core/ajax"],(function(_exports,_ajax
* @module core_course/repository
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};var _default={getEnrolledCoursesByTimelineClassification:(classification,limit,offset,sort)=>{const args={classification:classification};void 0!==limit&&(args.limit=limit),void 0!==offset&&(args.offset=offset),void 0!==sort&&(args.sort=sort);const request={methodname:"core_course_get_enrolled_courses_by_timeline_classification",args:args};return _ajax.default.call([request])[0]},getLastAccessedCourses:(userid,limit,offset,sort)=>{const args={};void 0!==userid&&(args.userid=userid),void 0!==limit&&(args.limit=limit),void 0!==offset&&(args.offset=offset),void 0!==sort&&(args.sort=sort);const request={methodname:"core_course_get_recent_courses",args:args};return _ajax.default.call([request])[0]},getUsersFromCourseModuleID:function(cmid,groupID){let onlyActive=arguments.length>2&&void 0!==arguments[2]&&arguments[2];var request={methodname:"core_course_get_enrolled_users_by_cmid",args:{cmid:cmid,groupid:groupID,onlyactive:onlyActive}};return _ajax.default.call([request])[0]},toggleManualCompletion:(cmid,completed)=>{const request={methodname:"core_completion_update_activity_completion_status_manually",args:{cmid:cmid,completed:completed}};return _ajax.default.call([request])[0]},getEnrolledCoursesWithEventsByTimelineClassification:function(classification){let limit=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,offset=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,sort=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,searchValue=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,eventsFrom=arguments.length>5&&void 0!==arguments[5]?arguments[5]:null,eventsTo=arguments.length>6&&void 0!==arguments[6]?arguments[6]:null;const args={classification:classification,limit:limit,offset:offset,sort:sort,eventsfrom:eventsFrom,eventsto:eventsTo,searchvalue:searchValue},request={methodname:"core_course_get_enrolled_courses_with_action_events_by_timeline_classification",args:args};return _ajax.default.call([request])[0]}};return _exports.default=_default,_exports.default}));
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};var _default={getEnrolledCoursesByTimelineClassification:(classification,limit,offset,sort)=>{const args={classification:classification};void 0!==limit&&(args.limit=limit),void 0!==offset&&(args.offset=offset),void 0!==sort&&(args.sort=sort);const request={methodname:"core_course_get_enrolled_courses_by_timeline_classification",args:args};return _ajax.default.call([request])[0]},getLastAccessedCourses:(userid,limit,offset,sort)=>{const args={};void 0!==userid&&(args.userid=userid),void 0!==limit&&(args.limit=limit),void 0!==offset&&(args.offset=offset),void 0!==sort&&(args.sort=sort);const request={methodname:"core_course_get_recent_courses",args:args};return _ajax.default.call([request])[0]},getUsersFromCourseModuleID:function(cmid,groupID){let onlyActive=arguments.length>2&&void 0!==arguments[2]&&arguments[2];var request={methodname:"core_course_get_enrolled_users_by_cmid",args:{cmid:cmid,groupid:groupID,onlyactive:onlyActive}};return _ajax.default.call([request])[0]},getGradableUsersFromCourseID:function(courseid,groupID){let onlyActive=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const request={methodname:"core_grades_get_gradable_users",args:{courseid:courseid,groupid:groupID,onlyactive:onlyActive}};return _ajax.default.call([request])[0]},toggleManualCompletion:(cmid,completed)=>{const request={methodname:"core_completion_update_activity_completion_status_manually",args:{cmid:cmid,completed:completed}};return _ajax.default.call([request])[0]},getEnrolledCoursesWithEventsByTimelineClassification:function(classification){let limit=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,offset=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,sort=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,searchValue=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,eventsFrom=arguments.length>5&&void 0!==arguments[5]?arguments[5]:null,eventsTo=arguments.length>6&&void 0!==arguments[6]?arguments[6]:null;const args={classification:classification,limit:limit,offset:offset,sort:sort,eventsfrom:eventsFrom,eventsto:eventsTo,searchvalue:searchValue},request={methodname:"core_course_get_enrolled_courses_with_action_events_by_timeline_classification",args:args};return _ajax.default.call([request])[0]}};return _exports.default=_default,_exports.default}));
//# sourceMappingURL=repository.min.js.map
File diff suppressed because one or more lines are too long
+22
View File
@@ -150,6 +150,27 @@ const getEnrolledUsersFromCourseModuleID = (cmid, groupID, onlyActive = false) =
return Ajax.call([request])[0];
};
/**
* Get the list of gradable users enrolled in this course.
*
* @param {Number} courseid Course ID from which the users will be obtained
* @param {Number} groupID Group ID from which the users will be obtained
* @param {Boolean} onlyActive Whether to fetch only the active enrolled users or all enrolled users in the course.
* @returns {Promise} Promise containing a list of users
*/
const getGradabaleUsersFromCourseID = (courseid, groupID, onlyActive = false) => {
const request = {
methodname: 'core_grades_get_gradable_users',
args: {
courseid: courseid,
groupid: groupID,
onlyactive: onlyActive,
},
};
return Ajax.call([request])[0];
};
/**
* Toggle the completion state of an activity with manual completion.
*
@@ -172,6 +193,7 @@ export default {
getEnrolledCoursesByTimelineClassification,
getLastAccessedCourses,
getUsersFromCourseModuleID: getEnrolledUsersFromCourseModuleID,
getGradableUsersFromCourseID: getGradabaleUsersFromCourseID,
toggleManualCompletion,
getEnrolledCoursesWithEventsByTimelineClassification,
};

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