Compare commits
361 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fe8d759b17 | |||
| f72244a8c2 | |||
| d09f737c7d | |||
| b654282b18 | |||
| bdb5a4ba40 | |||
| 419d7f40c3 | |||
| 7be05aae41 | |||
| 04261e8722 | |||
| a53121b74a | |||
| 6814c42260 | |||
| 658953e34f | |||
| c2c03f203f | |||
| 9a1a58e593 | |||
| 0f63155d58 | |||
| 25e00b5e1f | |||
| b2bc3b9e7e | |||
| 38ed732727 | |||
| 463f16617e | |||
| 260924aeb8 | |||
| b38413afe4 | |||
| 05ab53734b | |||
| 708732ed72 | |||
| 121d6fb20a | |||
| e4acb387bb | |||
| ff74bb2682 | |||
| 17fb4afaab | |||
| 60541d90e5 | |||
| 4b26df011f | |||
| fbecc7132d | |||
| bbea6e1d31 | |||
| 9e3ca2a866 | |||
| 40ee4ab3fa | |||
| d40fc8708a | |||
| 2a60bc604f | |||
| e8237560d3 | |||
| 258783a754 | |||
| 81de0469c1 | |||
| 638cbfac93 | |||
| 85c70539df | |||
| 5b442418ad | |||
| 9c641bf38e | |||
| f9797aca63 | |||
| d4b1ecbed4 | |||
| d140771110 | |||
| 762df4050c | |||
| bee2d552b7 | |||
| f172248f20 | |||
| db71e79e05 | |||
| 05c9ce4bd8 | |||
| ade9f7177a | |||
| 05846ae405 | |||
| e186ad572d | |||
| 9f636a3de3 | |||
| d79ad5de6a | |||
| b7c8f7f723 | |||
| 46192ca77e | |||
| d68ea95f26 | |||
| 85af2e6a7c | |||
| 136aef1fe6 | |||
| 79ea6a2d22 | |||
| e2f5104676 | |||
| bc133f6fc3 | |||
| bea6119692 | |||
| b04fcb4527 | |||
| b4278ca6b0 | |||
| d20c47f89c | |||
| d29433ddc6 | |||
| 0a494aa9f6 | |||
| a418e9e53a | |||
| 3f10ec31b5 | |||
| 488a653e50 | |||
| 7fa08a0b35 | |||
| 6a89731462 | |||
| fd8b7fc730 | |||
| 006eaeef08 | |||
| 2862cce2a9 | |||
| e3d76202cd | |||
| 6441cca4d1 | |||
| 04892e4707 | |||
| 17282deeea | |||
| c2e8975523 | |||
| c5e3ce289e | |||
| 83e442cc69 | |||
| b8f0f87b5f | |||
| 539e5db429 | |||
| 4c3523d987 | |||
| a0951e25b3 | |||
| 70a95b8eae | |||
| 5705496179 | |||
| e77912a7c5 | |||
| fb13f6dd01 | |||
| fbeef47a58 | |||
| 8fa5a3008d | |||
| 2c94380acf | |||
| 8cd66034e4 | |||
| 0bb3a2f20a | |||
| 96f06326f8 | |||
| 8b6d43705e | |||
| eb0575859b | |||
| a6ce3c0758 | |||
| a9bfc2075b | |||
| 6a1644abff | |||
| 1bbc0425e3 | |||
| cb18237b5c | |||
| c898074fd8 | |||
| 14b5d0694f | |||
| 54d0894ec3 | |||
| 0b326e9e72 | |||
| eae154a081 | |||
| 42022a1d26 | |||
| c59c0f906b | |||
| e82f1d43c8 | |||
| 6ff6327a6b | |||
| 4b34028221 | |||
| edbbe29706 | |||
| fc35bc5876 | |||
| 6c5f358ca2 | |||
| 895189107f | |||
| d8c4a57ce8 | |||
| 3d5c60ad26 | |||
| a2cfa93011 | |||
| e40f4e4d83 | |||
| 1f0f185176 | |||
| d5d2c59161 | |||
| c2c357dfb2 | |||
| fccf80c3a3 | |||
| ee26c16e90 | |||
| d38211efc6 | |||
| dd844035ac | |||
| 778b8f51b1 | |||
| 4d28563eeb | |||
| 89f3fced22 | |||
| 1ed0cb2562 | |||
| 7e1589b2ee | |||
| bc5d145dfb | |||
| 5aaba2850f | |||
| 3116b46192 | |||
| 3a1aed3578 | |||
| a2544fd5ca | |||
| ebab82c9f3 | |||
| 40e56b3adc | |||
| 0a360e1eb2 | |||
| 59aa25852c | |||
| ba60319c94 | |||
| ad836b6d4c | |||
| 72d7395c96 | |||
| d376741b93 | |||
| ca991dbe29 | |||
| 3a7594c71a | |||
| 9f88fb2125 | |||
| f29c4e36a4 | |||
| a87db5a60d | |||
| 07bbe2fa5e | |||
| 1c11297195 | |||
| 5f59e2a61e | |||
| 7e4119de7e | |||
| c30c1ca9cd | |||
| f50c83ac37 | |||
| c54b573bd0 | |||
| 1f5e140ae9 | |||
| f65d067dec | |||
| dbe914883c | |||
| 783dc4cdb2 | |||
| 26e91219e8 | |||
| 15526541b3 | |||
| c78364eb73 | |||
| 0c9bc880c1 | |||
| 93f282a345 | |||
| 7d4ba18a65 | |||
| e78cbaa6c4 | |||
| 9b401dfc29 | |||
| 3e179325e9 | |||
| 60727a7cdf | |||
| 4d59c788ee | |||
| d5993fffd4 | |||
| 136bd2c4c4 | |||
| b2d8615725 | |||
| 4e880779f9 | |||
| e5efe8b6d1 | |||
| da4a2d6191 | |||
| 84ec153634 | |||
| b69c42db5d | |||
| 55d5f7756d | |||
| b262a67c89 | |||
| 05492ddbb3 | |||
| 185856927d | |||
| 935c2509f1 | |||
| a502fbcd1e | |||
| 061186c215 | |||
| eac49ffa4c | |||
| db82329f6c | |||
| 875ad48c9d | |||
| c627e1a4de | |||
| 3b0165ec67 | |||
| 96bfaf67fd | |||
| fc4354c7e3 | |||
| b5c49b8ac9 | |||
| 2721a7cdc3 | |||
| ab79a0e972 | |||
| 275af6c114 | |||
| dcc8300ef4 | |||
| af62e9773c | |||
| 0ac35f9248 | |||
| a028969791 | |||
| 7bc41babf8 | |||
| 4e08cbd42e | |||
| d3427d45fa | |||
| 67a690d176 | |||
| 81d72254b5 | |||
| b2e58aed7b | |||
| 5ca36b0731 | |||
| b105ec5188 | |||
| a85f7c200b | |||
| f09f15e0be | |||
| e35be12fb7 | |||
| 2f1a67685f | |||
| d3bc17fe56 | |||
| adfd93a303 | |||
| 82f9838f28 | |||
| a18057fd06 | |||
| dbc285e49e | |||
| 31b409d920 | |||
| 501c58729f | |||
| 3cc283a25e | |||
| 188b5021fb | |||
| be7a698223 | |||
| 60a1c97289 | |||
| 92afaa484f | |||
| 9fdb460330 | |||
| ccfc156b43 | |||
| 10f10ee269 | |||
| 47bf3467a2 | |||
| 04d7b13fc4 | |||
| a3e7f7fd14 | |||
| 745b504426 | |||
| 89913c7eeb | |||
| eb658e33c3 | |||
| 03e68d81b4 | |||
| ae80f632bf | |||
| e2079313e2 | |||
| b4bade5ca9 | |||
| 10883ef268 | |||
| 19e1e834a7 | |||
| f30b0eee9b | |||
| 0ad939f062 | |||
| e8f534c4f4 | |||
| 7e22a9c2c7 | |||
| c542a77f11 | |||
| db52a8bc31 | |||
| 4800afbc3e | |||
| 990b740ec1 | |||
| b1d436a281 | |||
| 8bf31f2277 | |||
| 97fc41ebcb | |||
| bac3ffbe79 | |||
| dc7dd96189 | |||
| 67c567062e | |||
| b7ee271c8b | |||
| 81cdd8db81 | |||
| 90d7b45f5f | |||
| 632d4faeec | |||
| aac3b19bff | |||
| a65a8fc40a | |||
| c0bedfd833 | |||
| b72551c475 | |||
| 437967f78e | |||
| e05747e353 | |||
| 4865c40790 | |||
| d63fd0365a | |||
| f054958593 | |||
| 7ee0ee6206 | |||
| cf715c550a | |||
| 440a27c5de | |||
| 2130e4ff8b | |||
| 676626064c | |||
| 655ac0b6a6 | |||
| 28233e5b3d | |||
| e001508f68 | |||
| 9b96653fc5 | |||
| 920ddcb70f | |||
| 82d1033f43 | |||
| 6856da7f09 | |||
| 150d134fa2 | |||
| d30fa9918f | |||
| 343ad024c0 | |||
| 4f8778cfc7 | |||
| b770c56b6d | |||
| 156953f115 | |||
| 07a6698d01 | |||
| 1ec619db69 | |||
| 9f5f8d4a0a | |||
| 810f134cdc | |||
| 7b1a0a0e65 | |||
| 447530591d | |||
| 34223e32ef | |||
| ac3cda51f0 | |||
| f25ac24adf | |||
| c3ba14a052 | |||
| bd844a184c | |||
| c968b1236f | |||
| ff2d542295 | |||
| bf68987951 | |||
| e2049d770c | |||
| 021bdd0e4b | |||
| 9bb59ad004 | |||
| fd1035ecf0 | |||
| 0602fdc0cb | |||
| 1294e309dc | |||
| 596bc2c2bf | |||
| 09568062fd | |||
| b205b758e8 | |||
| 55077e45bb | |||
| 9c4f0d31f2 | |||
| c220ad62dd | |||
| ffc8c116fd | |||
| 8679a15604 | |||
| 9995038273 | |||
| 70ee7b1beb | |||
| 5cc2ab26eb | |||
| cf0446155b | |||
| 87c42699d9 | |||
| 97bcb22dba | |||
| ecd82700a7 | |||
| daa598b1b4 | |||
| 13eb20d8d1 | |||
| d0a9c57c0b | |||
| 21b11cdb3d | |||
| d4b2c50163 | |||
| bd50ac1876 | |||
| da4204c491 | |||
| 780b99229c | |||
| bebde352fe | |||
| 1adf99597e | |||
| 70c1b02809 | |||
| 335c9c920d | |||
| b1ad4fb830 | |||
| 2b5073a222 | |||
| 731b150241 | |||
| 228ee621e6 | |||
| 16f65ba275 | |||
| 165918258d | |||
| 3392a198d7 | |||
| 7cba44007c | |||
| 0004f31e2e | |||
| 83865c7979 | |||
| b43222dc67 | |||
| e857efcf28 | |||
| e7ab69fa26 | |||
| f4743bbb8d | |||
| d1b63c5e18 | |||
| cf5065ed71 | |||
| bf380e2d46 | |||
| 4b40f8273d | |||
| c0f2ff773f | |||
| 2ef18bce0d | |||
| 536780ce38 | |||
| 5174e4e36d | |||
| 91135c5305 | |||
| 3720532cb2 | |||
| 7f569fc1f1 | |||
| 1437ed51ef |
@@ -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
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -97,7 +97,7 @@ class role extends base {
|
||||
->set_type(column::TYPE_TEXT)
|
||||
->add_fields("{$rolealias}.name, {$rolealias}.shortname, {$rolealias}.id, {$contextalias}.id AS contextid")
|
||||
->add_fields(context_helper::get_preload_record_columns_sql($contextalias))
|
||||
->set_is_sortable(true)
|
||||
->set_is_sortable(true, ["CASE WHEN {$rolealias}.name = '' THEN {$rolealias}.shortname ELSE {$rolealias}.name END"])
|
||||
->set_callback(static function($name, stdClass $role): string {
|
||||
if ($name === null) {
|
||||
return '';
|
||||
|
||||
@@ -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)');
|
||||
|
||||
@@ -200,14 +200,14 @@ reports,core_reportbuilder|/reportbuilder/index.php',
|
||||
));
|
||||
|
||||
$choices = [HOMEPAGE_SITE => new lang_string('home')];
|
||||
if (!empty($CFG->enabledashboard)) {
|
||||
if (!isset($CFG->enabledashboard) || $CFG->enabledashboard) {
|
||||
$choices[HOMEPAGE_MY] = new lang_string('mymoodle', 'admin');
|
||||
}
|
||||
$choices[HOMEPAGE_MYCOURSES] = new lang_string('mycourses', 'admin');
|
||||
$choices[HOMEPAGE_USER] = new lang_string('userpreference', 'admin');
|
||||
$temp->add(new admin_setting_configselect('defaulthomepage', new lang_string('defaulthomepage', 'admin'),
|
||||
new lang_string('configdefaulthomepage', 'admin'), get_default_home_page(), $choices));
|
||||
if (!empty($CFG->enabledashboard)) {
|
||||
if (!isset($CFG->enabledashboard) || $CFG->enabledashboard) {
|
||||
$temp->add(new admin_setting_configcheckbox(
|
||||
'allowguestmymoodle',
|
||||
new lang_string('allowguestmymoodle', 'admin'),
|
||||
|
||||
@@ -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}}
|
||||
|
||||
+46
-1
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -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'])) {
|
||||
|
||||
+112
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,5 +61,8 @@ function xmldb_tool_cohortroles_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2023042401, 'tool', 'cohortroles');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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 >}}
|
||||
|
||||
@@ -41,5 +41,8 @@ function xmldb_tool_customlang_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -152,5 +152,8 @@ function xmldb_tool_dataprivacy_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2023062700, 'tool', 'dataprivacy');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -45,5 +45,8 @@ function xmldb_tool_log_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -39,5 +39,8 @@ function xmldb_logstore_database_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -66,5 +66,8 @@ function xmldb_logstore_standard_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -46,5 +46,8 @@ function xmldb_factor_auth_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2021020500, 'factor', 'auth');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ $string['error:futurecode'] = 'This code is invalid. Please verify the time on y
|
||||
Current system time is {$a}.';
|
||||
$string['error:oldcode'] = 'This code is too old. Please verify the time on your authenticator device is correct and try again.
|
||||
Current system time is {$a}.';
|
||||
$string['error:wrongverification'] = 'Incorrect verification code';
|
||||
$string['error:wrongverification'] = 'Incorrect verification code.';
|
||||
$string['factorsetup'] = 'App setup';
|
||||
$string['info'] = '<p>Use any time-based one-time password (TOTP) authenticator app on your device to generate a verification code, even when it is offline.</p>
|
||||
|
||||
|
||||
@@ -384,7 +384,8 @@ class api {
|
||||
$settings->searchhideallcategory = $CFG->searchhideallcategory;
|
||||
$settings->searchmaxtopresults = $CFG->searchmaxtopresults;
|
||||
$settings->searchbannerenable = $CFG->searchbannerenable;
|
||||
$settings->searchbanner = $CFG->searchbanner;
|
||||
$settings->searchbanner = \core_external\util::format_text(
|
||||
$CFG->searchbanner, FORMAT_HTML, $context)[0];
|
||||
}
|
||||
|
||||
return $settings;
|
||||
@@ -515,6 +516,7 @@ class api {
|
||||
'comments' => 'CoreBlockDelegate_AddonBlockComments',
|
||||
'completionstatus' => 'CoreBlockDelegate_AddonBlockCompletionStatus',
|
||||
'feedback' => 'CoreBlockDelegate_AddonBlockFeedback',
|
||||
'globalsearch' => 'CoreBlockDelegate_AddonBlockGlobalSearch',
|
||||
'glossary_random' => 'CoreBlockDelegate_AddonBlockGlossaryRandom',
|
||||
'html' => 'CoreBlockDelegate_AddonBlockHtml',
|
||||
'lp' => 'CoreBlockDelegate_AddonBlockLp',
|
||||
@@ -523,6 +525,7 @@ class api {
|
||||
'private_files' => 'CoreBlockDelegate_AddonBlockPrivateFiles',
|
||||
'recent_activity' => 'CoreBlockDelegate_AddonBlockRecentActivity',
|
||||
'rss_client' => 'CoreBlockDelegate_AddonBlockRssClient',
|
||||
'search_forums' => 'CoreBlockDelegate_AddonBlockSearchForums',
|
||||
'selfcompletion' => 'CoreBlockDelegate_AddonBlockSelfCompletion',
|
||||
'tags' => 'CoreBlockDelegate_AddonBlockTags',
|
||||
);
|
||||
|
||||
@@ -47,5 +47,8 @@ function xmldb_tool_mobile_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -75,5 +75,8 @@ function xmldb_tool_monitor_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -155,5 +155,8 @@ function xmldb_tool_moodlenet_upgrade(int $oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -46,5 +46,8 @@ function xmldb_tool_policy_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ if ($taskid) {
|
||||
if (!$classname) {
|
||||
throw new \moodle_exception('noclassname', 'tool_task');
|
||||
}
|
||||
$heading = "Run $classname " . ($failedonly ? "failed" : "all")." tasks";
|
||||
$heading = "Run " . s($classname) . " " . ($failedonly ? "failed" : "all")." tasks";
|
||||
$now = time();
|
||||
$tasks = array_filter(
|
||||
core\task\manager::get_adhoc_tasks($classname, $failedonly, true),
|
||||
@@ -111,6 +111,7 @@ require_sesskey();
|
||||
\core\session\manager::write_close();
|
||||
|
||||
// Prepare to handle output via mtrace.
|
||||
require('lib.php');
|
||||
$CFG->mtrace_wrapper = 'tool_task_mtrace_wrapper';
|
||||
|
||||
// Run the specified tasks.
|
||||
|
||||
@@ -89,6 +89,7 @@ echo $OUTPUT->select_element_for_append();
|
||||
|
||||
// Prepare to handle output via mtrace.
|
||||
echo html_writer::start_tag('pre', ['style' => 'color: #fff; background: #333; padding: 1em; min-height: 24lh']);
|
||||
require('lib.php');
|
||||
$CFG->mtrace_wrapper = 'tool_task_mtrace_wrapper';
|
||||
|
||||
// Run the specified task (this will output an error if it doesn't exist).
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -146,5 +146,8 @@ function xmldb_tool_usertours_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2023053000, 'tool', 'usertours');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -52,5 +52,8 @@ function xmldb_auth_cas_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,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) {
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_db_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_email_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -52,5 +52,8 @@ function xmldb_auth_ldap_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -94,5 +94,8 @@ function xmldb_auth_lti_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_manual_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_mnet_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_none_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,5 +45,8 @@ function xmldb_auth_oauth2_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -66,5 +66,8 @@ function xmldb_auth_shibboleth_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -74,3 +74,48 @@ 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 |
|
||||
|
||||
@@ -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~'
|
||||
|
||||
@@ -239,7 +239,7 @@ Feature: edit_availability
|
||||
And "Edit restrictions" "link" should exist in the "section-1" "core_availability > Section availability"
|
||||
When I click on "Edit restrictions" "link" in the "section-1" "core_availability > Section availability"
|
||||
Then I should see "Restrict access"
|
||||
And I should not see "General"
|
||||
And I should not see "Summary of General"
|
||||
And I should see "Collapse all"
|
||||
And I should not see "Expand all"
|
||||
And I click on "Cancel" "button"
|
||||
@@ -264,3 +264,16 @@ Feature: edit_availability
|
||||
And I should not see "Content"
|
||||
And I should see "Collapse all"
|
||||
And I should not see "Expand all"
|
||||
|
||||
@javascript
|
||||
Scenario: Edit activity availability button is shown after duplicating an activity
|
||||
# Setting a restriction up
|
||||
Given I am on the "MyForum" "forum activity editing" page logged in as teacher1
|
||||
And I expand all fieldsets
|
||||
And I press "Add restriction..."
|
||||
And I click on "Date" "button" in the "Add restriction..." "dialogue"
|
||||
When I press "Save and return to course"
|
||||
And I turn editing mode on
|
||||
And I duplicate "MyForum" activity
|
||||
# Testing edit restrictions link
|
||||
Then "Edit restrictions" "link" should exist in the "MyForum (copy)" "core_availability > Activity availability"
|
||||
|
||||
@@ -1663,7 +1663,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);
|
||||
|
||||
@@ -4442,7 +4442,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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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" in the "region-main" "region"
|
||||
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"
|
||||
|
||||
@@ -57,5 +57,8 @@ function xmldb_block_badges_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -72,5 +72,8 @@ function xmldb_block_calendar_month_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -57,5 +57,8 @@ function xmldb_block_calendar_upcoming_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -60,5 +60,8 @@ function xmldb_block_completionstatus_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+27
-75
@@ -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:
|
||||
| Add requirements | 1 |
|
||||
| View the activity | 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:
|
||||
| Add requirements | 1 |
|
||||
| View the activity | 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:
|
||||
| Add requirements | 1 |
|
||||
| Receive a grade | 1 |
|
||||
| Passing grade | 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:
|
||||
| Add requirements | 1 |
|
||||
| Receive a grade | 1 |
|
||||
| Passing grade | 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
|
||||
|
||||
@@ -71,5 +71,8 @@ function xmldb_block_course_summary_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -67,5 +67,8 @@ function xmldb_block_feedback_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,5 +45,8 @@ function xmldb_block_html_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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']
|
||||
);
|
||||
}
|
||||
@@ -580,7 +580,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
|
||||
*/
|
||||
|
||||
@@ -84,5 +84,8 @@ function xmldb_block_myoverview_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -67,5 +67,8 @@ function xmldb_block_navigation_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -59,5 +59,8 @@ function xmldb_block_recent_activity_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+3
-3
@@ -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,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -72,5 +72,8 @@ function xmldb_block_recentlyaccesseditems_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -56,5 +56,8 @@ function xmldb_block_rss_client_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -61,5 +61,8 @@ function xmldb_block_section_links_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,5 +71,8 @@ function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -67,5 +67,8 @@ function xmldb_block_settings_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -141,5 +141,8 @@ function xmldb_block_tag_youtube_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,5 +71,8 @@ function xmldb_block_timeline_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Vendored
+14
-4
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
<span class="arrow_text">{{previousperiodname}}</span>
|
||||
</a>
|
||||
@@ -58,7 +58,7 @@
|
||||
}}>
|
||||
<span class="arrow_text">{{nextperiodname}}</span>
|
||||
|
||||
<span class="arrow">{{{rarrow}}}</span>
|
||||
<span class="arrow" aria-hidden="true">{{{rarrow}}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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>
|
||||
|
||||
<span class="arrow_text">{{previousperiodname}}</span>
|
||||
</a>
|
||||
@@ -63,7 +63,7 @@
|
||||
}}>
|
||||
<span class="arrow_text">{{nextperiodname}}</span>
|
||||
|
||||
<span class="arrow">{{{rarrow}}}</span>
|
||||
<span class="arrow" aria-hidden="true">{{{rarrow}}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -191,6 +191,8 @@ class communication_feature implements
|
||||
|
||||
public function update_room_membership(array $userids): void {
|
||||
$this->set_matrix_power_levels();
|
||||
// Mark the users as synced for the updated members.
|
||||
$this->processor->mark_users_as_synced($userids);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,5 +51,8 @@ function xmldb_communication_matrix_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2023071900, 'communication', 'matrix');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ $string['matrixhomeserverurl_desc'] = 'The URL of the Synapse homeserver to conn
|
||||
$string['matrixaccesstoken'] = 'Access token';
|
||||
$string['matrixaccesstoken_desc'] = 'Access token for the account which will perform actions on the homeserver.';
|
||||
$string['matrixrefreshtoken'] = 'Refresh token';
|
||||
$string['matrixrefreshtoken_desc'] = 'Admin refresh token to associated with the access token.';
|
||||
$string['matrixrefreshtoken_desc'] = 'Admin refresh token to be associated with the access token.';
|
||||
$string['matrixelementurl'] = 'Element web URL';
|
||||
$string['matrixroomtopic'] = 'Room topic';
|
||||
$string['matrixroomtopic_help'] = 'A short description of what this room is for.';
|
||||
|
||||
@@ -28,22 +28,21 @@ Feature: Communication matrix form field
|
||||
And I navigate to "Communication" in current page administration
|
||||
Then the field "id_communicationroomname" matches value "Sampleroomname"
|
||||
|
||||
# Skipping while we update the Mock Server with the new route.
|
||||
# Scenario: I can add room topic for matrix room
|
||||
# Given a Matrix mock server is configured
|
||||
# And I log in as "teacher1"
|
||||
# And I am on "Test course" course homepage
|
||||
# When I navigate to "Communication" in current page administration
|
||||
# And I set the field "id_selectedcommunication" to "Matrix"
|
||||
# And I wait to be redirected
|
||||
# And I should see "Room name"
|
||||
# And I should see "Room topic"
|
||||
# And I set the field "id_communicationroomname" to "Sampleroomname"
|
||||
# And I set the field "id_matrixroomtopic" to "Sampleroomtopic"
|
||||
# And I press "Save changes"
|
||||
# And I navigate to "Communication" in current page administration
|
||||
# Then the field "id_communicationroomname" matches value "Sampleroomname"
|
||||
# And I press "Cancel"
|
||||
# And I run all adhoc tasks
|
||||
# And I navigate to "Communication" in current page administration
|
||||
# And the field "id_matrixroomtopic" matches value "Sampleroomtopic"
|
||||
Scenario: I can add room topic for matrix room
|
||||
Given a Matrix mock server is configured
|
||||
And I log in as "teacher1"
|
||||
And I am on "Test course" course homepage
|
||||
When I navigate to "Communication" in current page administration
|
||||
And I set the field "id_selectedcommunication" to "Matrix"
|
||||
And I wait to be redirected
|
||||
And I should see "Room name"
|
||||
And I should see "Room topic"
|
||||
And I set the field "id_communicationroomname" to "Sampleroomname"
|
||||
And I set the field "id_matrixroomtopic" to "Sampleroomtopic"
|
||||
And I press "Save changes"
|
||||
And I navigate to "Communication" in current page administration
|
||||
Then the field "id_communicationroomname" matches value "Sampleroomname"
|
||||
And I press "Cancel"
|
||||
And I run all adhoc tasks
|
||||
And I navigate to "Communication" in current page administration
|
||||
And the field "id_matrixroomtopic" matches value "Sampleroomtopic"
|
||||
|
||||
@@ -24,17 +24,16 @@ Feature: Display communication room status banner
|
||||
# Not for students to see.
|
||||
Then I should not see "Your Matrix room will be ready soon." in the "page-content" "region"
|
||||
|
||||
# Skipping while we update the Mock Server with the new route.
|
||||
# Scenario: I can see the room has been created and ready to access
|
||||
# When I run all adhoc tasks
|
||||
# And I am on the "Test course" "Course" page logged in as "teacher1"
|
||||
# Then I should see "Your Matrix room is ready!" in the "page-content" "region"
|
||||
# # This is a one time message per user.
|
||||
# When I reload the page
|
||||
# Then I should not see "Your Matrix room is ready." in the "page-content" "region"
|
||||
# # Not for students to see.
|
||||
# When I am on the "Test course" "Course" page logged in as "student1"
|
||||
# Then I should not see "Your Matrix room is ready." in the "page-content" "region"
|
||||
Scenario: I can see the room has been created and ready to access
|
||||
When I run all adhoc tasks
|
||||
And I am on the "Test course" "Course" page logged in as "teacher1"
|
||||
Then I should see "Your Matrix room is ready." in the "page-content" "region"
|
||||
# This is a one time message per user.
|
||||
When I reload the page
|
||||
Then I should not see "Your Matrix room is ready." in the "page-content" "region"
|
||||
# Not for students to see.
|
||||
When I am on the "Test course" "Course" page logged in as "student1"
|
||||
Then I should not see "Your Matrix room is ready." in the "page-content" "region"
|
||||
|
||||
Scenario: Enabling or disabling the matrix plugin hides the banner accordingly
|
||||
Given I am on the "Test course" "Course" page logged in as "teacher1"
|
||||
|
||||
@@ -368,8 +368,6 @@ class communication_feature_test extends \advanced_testcase {
|
||||
* @covers ::set_matrix_power_levels
|
||||
*/
|
||||
public function test_add_and_remove_members_from_room(): void {
|
||||
$this->markTestSkipped('Skipping while we update the Mock Server with the new route');
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
|
||||
@@ -413,28 +411,32 @@ class communication_feature_test extends \advanced_testcase {
|
||||
* @covers ::get_user_allowed_power_level
|
||||
*/
|
||||
public function test_update_room_membership(): void {
|
||||
$this->markTestSkipped('Skipping while we update the Mock Server with the new route');
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
global $DB;
|
||||
|
||||
// Create a new room.
|
||||
$course = $this->get_course('Sampleroom', 'none');
|
||||
$coursecontext = \context_course::instance($course->id);
|
||||
$user = $this->get_user();
|
||||
|
||||
$communication = $this->create_room(
|
||||
component: 'core_course',
|
||||
itemtype: 'coursecommunication',
|
||||
itemid: $course->id
|
||||
itemid: $course->id,
|
||||
roomname: 'sampleroom',
|
||||
roomtopic: 'sampltopic',
|
||||
roomavatar: null,
|
||||
members: [$user->id],
|
||||
context: $coursecontext,
|
||||
);
|
||||
|
||||
$provider = $communication->get_room_user_provider();
|
||||
|
||||
// Add the members to the room.
|
||||
$provider->add_members_to_room([$user->id]);
|
||||
|
||||
// Assign teacher role to the user.
|
||||
$coursecontext = \context_course::instance($course->id);
|
||||
$teacherrole = $DB->get_record('role', ['shortname' => 'teacher']);
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id);
|
||||
role_assign($teacherrole->id, $user->id, $coursecontext->id);
|
||||
@@ -443,7 +445,7 @@ class communication_feature_test extends \advanced_testcase {
|
||||
$provider->update_room_membership([$user->id]);
|
||||
|
||||
$processor = \core_communication\processor::load_by_instance(
|
||||
context: \core\context\course::instance($course->id),
|
||||
context: $coursecontext,
|
||||
component: 'core_course',
|
||||
instancetype: 'coursecommunication',
|
||||
instanceid: $course->id,
|
||||
|
||||
@@ -193,6 +193,32 @@ class cm_completion_details {
|
||||
return (int)$this->completiondata->completionstate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the overall completion state of this course module should be marked as complete or not.
|
||||
* This is based on the completion settings of the course module, so when the course module requires a passing grade,
|
||||
* it will only be marked as complete when the user has passed the course module. Otherwise, it will be marked as complete
|
||||
* even when the user has failed the course module.
|
||||
*
|
||||
* @return bool True when the module can be marked as completed.
|
||||
*/
|
||||
public function is_overall_complete(): bool {
|
||||
$completionstates = [];
|
||||
if ($this->is_manual()) {
|
||||
$completionstates = [COMPLETION_COMPLETE];
|
||||
} else if ($this->is_automatic()) {
|
||||
// Successfull completion states depend on the completion settings.
|
||||
if (isset($this->completiondata->passgrade)) {
|
||||
// Passing grade is required. Don't mark it as complete when state is COMPLETION_COMPLETE_FAIL.
|
||||
$completionstates = [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS];
|
||||
} else {
|
||||
// Any grade is required. Mark it as complete even when state is COMPLETION_COMPLETE_FAIL.
|
||||
$completionstates = [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS, COMPLETION_COMPLETE_FAIL];
|
||||
}
|
||||
}
|
||||
|
||||
return in_array($this->get_overall_completion(), $completionstates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this activity module has completion enabled.
|
||||
*
|
||||
|
||||
@@ -129,7 +129,15 @@ class core_completion_defaultedit_form extends core_completion_edit_base_form {
|
||||
$this->get_suffix()
|
||||
);
|
||||
$data = (array)$data;
|
||||
$modform->data_preprocessing($data);
|
||||
try {
|
||||
$modform->data_preprocessing($data);
|
||||
} catch (moodle_exception $e) {
|
||||
debugging(
|
||||
'data_preprocessing function of module ' . $modnames[0] .
|
||||
' should be fixed so it can be shown together with other Default activity completion forms',
|
||||
DEBUG_DEVELOPER
|
||||
);
|
||||
}
|
||||
// Unset fields that will conflict with this form and set data to this form.
|
||||
unset($data['cmid']);
|
||||
unset($data['modids']);
|
||||
|
||||
@@ -125,7 +125,9 @@ abstract class core_completion_edit_base_form extends moodleform {
|
||||
' has wrong suffix and has been removed from the form. This has to be fixed by the developer',
|
||||
DEBUG_DEVELOPER
|
||||
);
|
||||
$moduleform->_form->removeElement($customcompletionelement);
|
||||
if ($moduleform->_form->elementExists($customcompletionelement)) {
|
||||
$moduleform->_form->removeElement($customcompletionelement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
| Add requirements | 1 |
|
||||
| Receive a grade | 1 |
|
||||
| Passing grade | 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:
|
||||
| Add requirements | 1 |
|
||||
| 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"
|
||||
|
||||
@@ -157,7 +157,7 @@ Feature: Allow teachers to edit the default activity completion rules in a cours
|
||||
And I set the following fields to these values:
|
||||
| id_completion_scorm_2 | 1 |
|
||||
| completionview_scorm | 0 |
|
||||
| completionscoredisabled | 1 |
|
||||
| completionscoreenabled_scorm | 1 |
|
||||
| completionscorerequired_scorm | 3 |
|
||||
| completionstatusrequired_scorm[2] | 1 |
|
||||
| completionstatusrequired_scorm[4] | 0 |
|
||||
@@ -187,14 +187,17 @@ Feature: Allow teachers to edit the default activity completion rules in a cours
|
||||
And the field "completionview_assign" matches value "0"
|
||||
And the field "completionusegrade_assign" matches value "0"
|
||||
And the field "completionsubmit_assign" matches value "1"
|
||||
And I click on "Expand Forum" "button"
|
||||
And the field "id_completion_forum_2" matches value "1"
|
||||
And the field "completionview_forum" matches value "0"
|
||||
And the field "completionpostsenabled_forum" matches value "1"
|
||||
And the field "completionposts_forum" matches value "3"
|
||||
And the field "completiondiscussionsenabled_forum" matches value "0"
|
||||
And the field "completionrepliesenabled_forum" matches value "0"
|
||||
And I click on "Expand SCORM package" "button"
|
||||
And the field "id_completion_scorm_2" matches value "1"
|
||||
And the field "completionview_scorm" matches value "0"
|
||||
And the field "completionscoreenabled_scorm" matches value "1"
|
||||
And the field "completionscorerequired_scorm" matches value "3"
|
||||
And the field "completionstatusrequired_scorm[2]" matches value "1"
|
||||
And the field "completionstatusrequired_scorm[4]" matches value "0"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user