Compare commits
446 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e088aec08 | |||
| 378240d57d | |||
| d339d41274 | |||
| 02b5deb65a | |||
| 704ecfea00 | |||
| 8aaad0d2b6 | |||
| 8d5b7ed598 | |||
| d9aa7cbb6f | |||
| 61d35d7b9d | |||
| 963e29f6b2 | |||
| 8772689453 | |||
| 5cf42ac843 | |||
| 5bb7f7e0dc | |||
| 135634fbd3 | |||
| 6f70004a0d | |||
| d99f765ee6 | |||
| 87f4750d75 | |||
| a3fa0ca96f | |||
| 895e16ff28 | |||
| 93073173ce | |||
| 5c283bb713 | |||
| e86b3c7335 | |||
| 52d8541b5b | |||
| 99a57908f5 | |||
| ebe415f889 | |||
| f0d61c012d | |||
| d829440fed | |||
| e57bc1637c | |||
| 708e0804b8 | |||
| 3a8e16ecab | |||
| 9fe6a6f42b | |||
| 7f5a384c99 | |||
| 836399115b | |||
| adb28ab708 | |||
| c783a874f0 | |||
| 883ea035af | |||
| c56a930df8 | |||
| 28abbabae5 | |||
| 2010db2cd4 | |||
| 396b5cc75b | |||
| 49a9cc9bd1 | |||
| 5bf8b2e969 | |||
| 9ce83d0908 | |||
| 0f399f7f74 | |||
| 5726fe6263 | |||
| e3e938b861 | |||
| 3dd7b4f805 | |||
| cf3f46344e | |||
| 0cb1903bfd | |||
| 8571b889f3 | |||
| ec9f2a7d3f | |||
| 97e9098927 | |||
| 44b74479cb | |||
| 6a4e20e239 | |||
| adf125a30b | |||
| 3db84ae082 | |||
| 025000a221 | |||
| a90069245d | |||
| ddc72f06ef | |||
| 55f4cb7299 | |||
| 9d904936c8 | |||
| 560672aaa1 | |||
| 5aee2507d4 | |||
| 1f5b61e1db | |||
| c15270df73 | |||
| 5e10746ae7 | |||
| 84510e3b82 | |||
| a9df6656b8 | |||
| b33cc5d748 | |||
| 74b0aca7eb | |||
| e9ca5e144c | |||
| be6128fcd5 | |||
| 424c3248c7 | |||
| 81de3795fa | |||
| f29b93ad61 | |||
| e71a5333a3 | |||
| 910dc3393c | |||
| 5ac473e356 | |||
| 93b6f3c79e | |||
| 10beedc18f | |||
| 83797afa91 | |||
| d3220e229e | |||
| f2b1768da6 | |||
| e200f7a382 | |||
| 2d92ee0ad5 | |||
| a6cf46f473 | |||
| 1c5052e29f | |||
| 5c7d7dec73 | |||
| 61dde025a1 | |||
| b10fec1750 | |||
| a4c14b94ca | |||
| 072ce9a5e7 | |||
| 2347fe5450 | |||
| 43d6e05c24 | |||
| b3e24b7f60 | |||
| 2a8d78c00f | |||
| 69be43879e | |||
| 5d2169e053 | |||
| 996c1d5b15 | |||
| 206b1f6d6d | |||
| 997731210c | |||
| 83e305fa8c | |||
| 50809576b5 | |||
| 2d2faf8087 | |||
| 5f41d7ce6b | |||
| adcddcf776 | |||
| 15d16015b7 | |||
| 6acf61d35e | |||
| 8d7c3b0d50 | |||
| 4902bfaf3e | |||
| 9c5c2dbf5a | |||
| dd7e948dba | |||
| ae20e634d7 | |||
| c25dbc446a | |||
| 12c847fed9 | |||
| 04b53e0e0c | |||
| 6a8e8ac25e | |||
| f01cac675a | |||
| 6d69cf1045 | |||
| 3aa576a8ef | |||
| cc8ba5f12a | |||
| 303ea5f34e | |||
| 63e764faba | |||
| e74f735a99 | |||
| ae5884f8e6 | |||
| 2490febd82 | |||
| df1914d111 | |||
| 6e39ee0c82 | |||
| 13e8736049 | |||
| d868e5331c | |||
| 829897be3e | |||
| 20b9e53010 | |||
| 5470f3859f | |||
| 9cd60b20d0 | |||
| bd8dbfdbc3 | |||
| 21bb4f142c | |||
| 7809633d79 | |||
| 7f574aadff | |||
| 9c099d21eb | |||
| 8ee06a7b17 | |||
| 22c5c2f04c | |||
| 83818b0452 | |||
| e81efe7691 | |||
| a256d06cfd | |||
| ef483684d3 | |||
| 147c966a46 | |||
| a3a8490d3a | |||
| e9623e55e3 | |||
| ae1baf9042 | |||
| be7a37d442 | |||
| e646b89f8b | |||
| a0f5d96f1e | |||
| 45c0583312 | |||
| 05a423d850 | |||
| 12869bfdb1 | |||
| 909f01f17e | |||
| d8a4219d47 | |||
| c56dbe9c28 | |||
| d0e04db7fb | |||
| 2e96609a93 | |||
| 207f2c8880 | |||
| 2f7a48c0a9 | |||
| ad2d2f19a3 | |||
| 834f172c77 | |||
| 8703e6530c | |||
| 40d3bc442f | |||
| 3c790ba117 | |||
| f10d0d2745 | |||
| 668505a9e4 | |||
| b1915ed987 | |||
| bccff20039 | |||
| 736ce96319 | |||
| 4a6fb4a2ca | |||
| d06e9d3bef | |||
| 06805cb54f | |||
| fff8b97ebc | |||
| 26023575ba | |||
| 1a815ef7d4 | |||
| 9fc09121a8 | |||
| 26f9407892 | |||
| 4701b68a51 | |||
| a80eba9500 | |||
| 1ac6fd0322 | |||
| 1562e8d3eb | |||
| 139a8556e8 | |||
| 856be66774 | |||
| 3675c98506 | |||
| 43ed2ccbf2 | |||
| 5fbc32ebdb | |||
| 9f00dabf86 | |||
| 51d311f703 | |||
| 3ef86b3909 | |||
| 6085ca703d | |||
| bdb2677b79 | |||
| 8a630a771c | |||
| 409e4794d7 | |||
| 30ce0cd396 | |||
| e5a0c16bd3 | |||
| 6afd79df8d | |||
| 9f2e956580 | |||
| 4bc1b2151e | |||
| 66a437aca8 | |||
| 3b70fdaaf3 | |||
| 08f6d5de07 | |||
| 39d505664e | |||
| 286348d97f | |||
| e5bb9741b6 | |||
| c7f545bbb0 | |||
| b2a803d5d1 | |||
| 8eb717f993 | |||
| f37e3f357d | |||
| b1b09903b0 | |||
| 2470b6ea89 | |||
| cc2aca7c23 | |||
| d66fe9c1aa | |||
| 6203fc19f2 | |||
| 64c03072a9 | |||
| 780dc00ce5 | |||
| 75ceca0bf5 | |||
| db13e21956 | |||
| 42515a2e58 | |||
| ced275af37 | |||
| 6eb703ad69 | |||
| c4bc562172 | |||
| 45d1c530d2 | |||
| e6caeefe0c | |||
| b8351f4c24 | |||
| fb64bae5e2 | |||
| 9f8ef4294a | |||
| 503c8dddcc | |||
| 40daab14a4 | |||
| 01426638cb | |||
| f5940bfb5f | |||
| ae3dd7efdb | |||
| 35c2c697ce | |||
| 4ec1b7b094 | |||
| a2afdf4691 | |||
| 738e1d3556 | |||
| c673cdfee7 | |||
| b4d2e7f267 | |||
| 4bc526cc8a | |||
| 7ed7cabf5f | |||
| d33dffe53a | |||
| 19b1ff816f | |||
| 40f2d64856 | |||
| d6c8107249 | |||
| fcf15debfc | |||
| eadcc99eea | |||
| 102fe39706 | |||
| 3e6e38b2e3 | |||
| d04814641b | |||
| b4d09c2db0 | |||
| 2fc28aa794 | |||
| c5f2967a64 | |||
| 9a7713304c | |||
| 85c39e437b | |||
| e37014fafb | |||
| 77492a3e62 | |||
| b01548ecba | |||
| dd75bf89ff | |||
| 307d961277 | |||
| bc7ac30669 | |||
| fa4e8ee5c9 | |||
| efdb216ca9 | |||
| 62f68371df | |||
| 3690a9db9f | |||
| 952292945c | |||
| ac184c9db2 | |||
| 8e60097af8 | |||
| 786f04f485 | |||
| 310cf52b37 | |||
| 3893b5fa32 | |||
| f5a134213d | |||
| 7ac9576825 | |||
| b5036ee20c | |||
| 1abaa0c22e | |||
| 9a734d1862 | |||
| a108795999 | |||
| 7ef639c709 | |||
| cb891e57f0 | |||
| b470112643 | |||
| 4e14b95f0e | |||
| 4d32c0c6d0 | |||
| 0e44ba37cf | |||
| 5259c6b402 | |||
| ed52eb4c88 | |||
| 77325154af | |||
| b136969308 | |||
| 47d9d4cd00 | |||
| 61ae30255c | |||
| e2a2209ed6 | |||
| 1cf504414d | |||
| 2d6dfcde3e | |||
| 1cb0536bcb | |||
| d8be1d9ac5 | |||
| 88c5d93aa1 | |||
| cbb87c9568 | |||
| 7d2f938cf0 | |||
| eb1931ccd1 | |||
| 5f717f7aac | |||
| 64c5119637 | |||
| dad1bc64c5 | |||
| 812fa23e82 | |||
| fe0d1d488b | |||
| d76bc30606 | |||
| 39177fd3a7 | |||
| 0c94afe7af | |||
| b14196043d | |||
| 2f6a01e094 | |||
| c68fa5fcbb | |||
| 4f7ec48046 | |||
| fe0f1f5c19 | |||
| f098ca6d97 | |||
| 8aac99eb3d | |||
| 1affdad829 | |||
| f497fd1de8 | |||
| 0a44a45fea | |||
| fdc93e4092 | |||
| add7675e51 | |||
| 20f8cd8551 | |||
| 7ac884d457 | |||
| 4bbbd50202 | |||
| e6175024e6 | |||
| c21a04f63e | |||
| ad3bbeb5c0 | |||
| 18d2aac902 | |||
| 5546df9078 | |||
| d0e29366de | |||
| 78da7d9529 | |||
| ea04def291 | |||
| 6ba3f5d72a | |||
| 2153633aac | |||
| d6ece9f7f0 | |||
| a69c78724e | |||
| 7968f77edb | |||
| 6d7583c9b2 | |||
| 6dae822543 | |||
| 451044df4e | |||
| 9daaa37aac | |||
| 1880d3684c | |||
| dcef51b614 | |||
| 66d40a5dae | |||
| 9e56dabab6 | |||
| 168e14feee | |||
| 137778af00 | |||
| d4d848343b | |||
| 7f3fca8ff1 | |||
| a01d727a31 | |||
| d149d894a0 | |||
| 4c1ac80799 | |||
| 1e9c117f50 | |||
| 55b02e02e6 | |||
| cead41882b | |||
| 44e5ac93bc | |||
| b451ddf416 | |||
| 46d1d519f8 | |||
| c18fe9ec19 | |||
| f5af9b62e8 | |||
| ace15cee6d | |||
| addedcb142 | |||
| e55207d9d7 | |||
| 4743fdf290 | |||
| 5ffad8a406 | |||
| 00b965f609 | |||
| 5f9aa41321 | |||
| 5c1adaddba | |||
| 390896d3d9 | |||
| eab8b262be | |||
| 5464179b31 | |||
| 99a4c833b6 | |||
| da920040ad | |||
| fdbd1d7a9d | |||
| bb68dfc002 | |||
| 72cf8c6ca3 | |||
| a1554ea241 | |||
| 749db57b4c | |||
| 3b62f94787 | |||
| 13d5afea34 | |||
| 025bd122a6 | |||
| 7ce782e654 | |||
| c3208c17d1 | |||
| 0f4ea5911c | |||
| b955d07c33 | |||
| 60ee7cebc7 | |||
| 6508a3c68e | |||
| 9e2bc0490f | |||
| a2aceccdbe | |||
| d3ec6a9dcf | |||
| 80140c4592 | |||
| 7a2b15647e | |||
| bf5a6920bc | |||
| 295b622b0b | |||
| aa5b71c005 | |||
| 5ad8fa096d | |||
| ab077b368c | |||
| 5e946b2ceb | |||
| ca3b210680 | |||
| 2834f79e73 | |||
| bf752eb38b | |||
| 5018c28e43 | |||
| 2f874214ba | |||
| 981e960d34 | |||
| 7843fb7e14 | |||
| dbc251e25c | |||
| bdfb46a2d0 | |||
| 9da8b39169 | |||
| b642702aa2 | |||
| 740d260ce7 | |||
| ffe199b1fa | |||
| d583059471 | |||
| 5af5a205a3 | |||
| 6c816ca22c | |||
| f6240d9eea | |||
| 49d367d47e | |||
| f068ae74db | |||
| dd7b9d1dce | |||
| c7232a325a | |||
| be335eb8db | |||
| ff8cadd271 | |||
| a34073eeb8 | |||
| 223f133f88 | |||
| a47b6805be | |||
| 99b936835d | |||
| 8bd0487a4b | |||
| 600ad57d35 | |||
| 7628ac73f4 | |||
| 64b4fbebd8 | |||
| 52454bedee | |||
| 8f74fa4366 | |||
| 02e45bf269 | |||
| 28fccc09ce | |||
| 7ed24ca351 | |||
| e98f145ccc | |||
| 904f5815c7 | |||
| d29a7827c4 | |||
| 5cd5271673 | |||
| 005e784e22 | |||
| c20f615105 | |||
| 685badbb2b | |||
| eef55a6333 | |||
| fa28975f25 | |||
| 7d31a2999b | |||
| e161a5a319 | |||
| 8eb2ea83d2 | |||
| 7c9753a713 | |||
| 1f8662f6fb |
@@ -42,7 +42,7 @@
|
||||
"sub": false,
|
||||
"supernew": false,
|
||||
"maxerr": 500,
|
||||
"maxlen": 150,
|
||||
"maxlen": 180,
|
||||
"passfail": false,
|
||||
"latedef": true
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"coverage": false,
|
||||
"lint": "config"
|
||||
"lint": "config",
|
||||
"clean": true
|
||||
}
|
||||
|
||||
@@ -1013,4 +1013,120 @@
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
</MOODLE>
|
||||
<MOODLE version="2.7" requires="2.2">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mariadb" version="5.5.31" />
|
||||
<VENDOR name="mysql" version="5.5.31" />
|
||||
<VENDOR name="postgres" version="9.1" />
|
||||
<VENDOR name="mssql" version="10.0" />
|
||||
<VENDOR name="oracle" version="10.2" />
|
||||
</DATABASE>
|
||||
<PHP version="5.4.4" 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="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="mbstringrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="curl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="curlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="openssl" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="opensslrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="tokenizer" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="tokenizerrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xmlrpc" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="xmlrpcrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="soap" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="soaprecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="ctype" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ctyperequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zip" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ziprequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zlib" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="gd" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="gdrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="simplexml" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="simplexmlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="spl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="splrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="pcre" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="dom" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xml" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="intl" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="intlrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="json" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="hash" level="required"/>
|
||||
</PHP_EXTENSIONS>
|
||||
<PHP_SETTINGS>
|
||||
<PHP_SETTING name="memory_limit" value="96M" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="settingmemorylimit" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="file_uploads" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingfileuploads" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="opcache.enable" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="opcacherecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
</MOODLE>
|
||||
</COMPATIBILITY_MATRIX>
|
||||
|
||||
+66
-47
@@ -47,7 +47,9 @@ if (!function_exists('iconv')) {
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
if (empty($_GET['cache']) and empty($_POST['cache']) and empty($_GET['sesskey']) and empty($_POST['sesskey'])) {
|
||||
if ((isset($_GET['cache']) and $_GET['cache'] === '0')
|
||||
or (isset($_POST['cache']) and $_POST['cache'] === '0')
|
||||
or (!isset($_POST['cache']) and !isset($_GET['cache']) and empty($_GET['sesskey']) and empty($_POST['sesskey']))) {
|
||||
// Prevent caching at all cost when visiting this page directly,
|
||||
// we redirect to self once we known no upgrades are necessary.
|
||||
// Note: $_GET and $_POST are used here intentionally because our param cleaning is not loaded yet.
|
||||
@@ -90,9 +92,7 @@ $newaddonreq = optional_param('installaddonrequest', null, PARAM_RAW);
|
||||
|
||||
// Set up PAGE.
|
||||
$url = new moodle_url('/admin/index.php');
|
||||
if ($cache) {
|
||||
$url->param('cache', 1);
|
||||
}
|
||||
$url->param('cache', $cache);
|
||||
$PAGE->set_url($url);
|
||||
unset($url);
|
||||
|
||||
@@ -267,12 +267,13 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
$PAGE->set_pagelayout('maintenance');
|
||||
$PAGE->set_popup_notification_allowed(false);
|
||||
|
||||
/** @var core_admin_renderer $output */
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
|
||||
if (upgrade_stale_php_files_present()) {
|
||||
$PAGE->set_title($stradministration);
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
/** @var core_admin_renderer $output */
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->upgrade_stale_php_files_page();
|
||||
die();
|
||||
}
|
||||
@@ -287,8 +288,6 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
$PAGE->set_heading($strdatabasechecking);
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
/** @var core_admin_renderer $output */
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->upgrade_confirm_page($a->newversion, $maturity, $testsite);
|
||||
die();
|
||||
|
||||
@@ -302,8 +301,6 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
$PAGE->set_heading($strcurrentrelease);
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
/** @var core_admin_renderer $output */
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->upgrade_environment_page($release, $envstatus, $environment_results);
|
||||
die();
|
||||
|
||||
@@ -315,23 +312,13 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
$PAGE->set_heading($strplugincheck);
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
$reloadurl = new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1));
|
||||
|
||||
/** @var core_admin_renderer $output */
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
|
||||
// check plugin dependencies first
|
||||
$failed = array();
|
||||
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
|
||||
echo $output->unsatisfied_dependencies_page($version, $failed, $reloadurl);
|
||||
die();
|
||||
}
|
||||
unset($failed);
|
||||
$reloadurl = new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1, 'cache' => 0));
|
||||
|
||||
if ($fetchupdates) {
|
||||
// no sesskey support guaranteed here
|
||||
if (empty($CFG->disableupdatenotifications)) {
|
||||
\core\update\checker::instance()->fetch();
|
||||
// No sesskey support guaranteed here, because sessions might not work yet.
|
||||
$updateschecker = \core\update\checker::instance();
|
||||
if ($updateschecker->enabled()) {
|
||||
$updateschecker->fetch();
|
||||
}
|
||||
redirect($reloadurl);
|
||||
}
|
||||
@@ -342,6 +329,7 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
|
||||
$deploydata = $deployer->submitted_data();
|
||||
if (!empty($deploydata)) {
|
||||
// No sesskey support guaranteed here, because sessions might not work yet.
|
||||
echo $output->upgrade_plugin_confirm_deploy_page($deployer, $deploydata);
|
||||
die();
|
||||
}
|
||||
@@ -349,11 +337,22 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
|
||||
echo $output->upgrade_plugin_check_page(core_plugin_manager::instance(), \core\update\checker::instance(),
|
||||
$version, $showallplugins, $reloadurl,
|
||||
new moodle_url('/admin/index.php', array('confirmupgrade'=>1, 'confirmrelease'=>1, 'confirmplugincheck'=>1)));
|
||||
new moodle_url('/admin/index.php', array('confirmupgrade'=>1, 'confirmrelease'=>1, 'confirmplugincheck'=>1, 'cache'=>0)));
|
||||
die();
|
||||
|
||||
} else {
|
||||
// Launch main upgrade
|
||||
// Always verify plugin dependencies!
|
||||
$failed = array();
|
||||
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
|
||||
$PAGE->set_pagelayout('maintenance');
|
||||
$PAGE->set_popup_notification_allowed(false);
|
||||
$reloadurl = new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1, 'cache' => 0));
|
||||
echo $output->unsatisfied_dependencies_page($version, $failed, $reloadurl);
|
||||
die();
|
||||
}
|
||||
unset($failed);
|
||||
|
||||
// Launch main upgrade.
|
||||
upgrade_core($version, true);
|
||||
}
|
||||
} else if ($version < $CFG->version) {
|
||||
@@ -373,6 +372,10 @@ if (!$cache and $branch <> $CFG->branch) { // Update the branch
|
||||
if (!$cache and moodle_needs_upgrading()) {
|
||||
if (!$PAGE->headerprinted) {
|
||||
// means core upgrade or installation was not already done
|
||||
|
||||
/** @var core_admin_renderer $output */
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
|
||||
if (!$confirmplugins) {
|
||||
$strplugincheck = get_string('plugincheck');
|
||||
|
||||
@@ -384,40 +387,46 @@ if (!$cache and moodle_needs_upgrading()) {
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
if ($fetchupdates) {
|
||||
// no sesskey support guaranteed here
|
||||
\core\update\checker::instance()->fetch();
|
||||
require_sesskey();
|
||||
$updateschecker = \core\update\checker::instance();
|
||||
if ($updateschecker->enabled()) {
|
||||
$updateschecker->fetch();
|
||||
}
|
||||
redirect($PAGE->url);
|
||||
}
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
|
||||
$deployer = \core\update\deployer::instance();
|
||||
if ($deployer->enabled()) {
|
||||
$deployer->initialize($PAGE->url, $PAGE->url);
|
||||
|
||||
$deploydata = $deployer->submitted_data();
|
||||
if (!empty($deploydata)) {
|
||||
require_sesskey();
|
||||
echo $output->upgrade_plugin_confirm_deploy_page($deployer, $deploydata);
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
// check plugin dependencies first
|
||||
$failed = array();
|
||||
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
|
||||
echo $output->unsatisfied_dependencies_page($version, $failed, $PAGE->url);
|
||||
die();
|
||||
}
|
||||
unset($failed);
|
||||
|
||||
// dependencies check passed, let's rock!
|
||||
// Show plugins info.
|
||||
echo $output->upgrade_plugin_check_page(core_plugin_manager::instance(), \core\update\checker::instance(),
|
||||
$version, $showallplugins,
|
||||
new moodle_url($PAGE->url),
|
||||
new moodle_url('/admin/index.php', array('confirmplugincheck'=>1)));
|
||||
new moodle_url('/admin/index.php', array('confirmplugincheck'=>1, 'cache'=>0)));
|
||||
die();
|
||||
}
|
||||
|
||||
// Make sure plugin dependencies are always checked.
|
||||
$failed = array();
|
||||
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
|
||||
$PAGE->set_pagelayout('maintenance');
|
||||
$PAGE->set_popup_notification_allowed(false);
|
||||
$reloadurl = new moodle_url('/admin/index.php', array('cache' => 0));
|
||||
echo $output->unsatisfied_dependencies_page($version, $failed, $reloadurl);
|
||||
die();
|
||||
}
|
||||
unset($failed);
|
||||
}
|
||||
|
||||
// install/upgrade all plugins and other parts
|
||||
upgrade_noncore(true);
|
||||
}
|
||||
@@ -477,6 +486,17 @@ if (during_initial_install()) {
|
||||
upgrade_finished('upgradesettings.php');
|
||||
}
|
||||
|
||||
if (has_capability('moodle/site:config', context_system::instance())) {
|
||||
if ($fetchupdates) {
|
||||
require_sesskey();
|
||||
$updateschecker = \core\update\checker::instance();
|
||||
if ($updateschecker->enabled()) {
|
||||
$updateschecker->fetch();
|
||||
}
|
||||
redirect(new moodle_url('/admin/index.php', array('cache' => 0)));
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can be sure everything was upgraded and caches work fine,
|
||||
// redirect if necessary to make sure caching is enabled.
|
||||
if (!$cache) {
|
||||
@@ -485,6 +505,11 @@ if (!$cache) {
|
||||
|
||||
// Check for valid admin user - no guest autologin
|
||||
require_login(0, false);
|
||||
if (isguestuser()) {
|
||||
// Login as real user!
|
||||
$SESSION->wantsurl = (string)new moodle_url('/admin/index.php');
|
||||
redirect(get_login_url());
|
||||
}
|
||||
$context = context_system::instance();
|
||||
require_capability('moodle/site:config', $context);
|
||||
|
||||
@@ -564,12 +589,6 @@ $registered = $DB->count_records('registration_hubs', array('huburl' => HUB_MOOD
|
||||
|
||||
admin_externalpage_setup('adminnotifications');
|
||||
|
||||
if ($fetchupdates) {
|
||||
require_sesskey();
|
||||
$updateschecker->fetch();
|
||||
redirect(new moodle_url('/admin/index.php'));
|
||||
}
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
|
||||
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
|
||||
|
||||
@@ -16,8 +16,6 @@ require_login();
|
||||
|
||||
admin_externalpage_setup('ssoaccesscontrol');
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
if (!extension_loaded('openssl')) {
|
||||
print_error('requiresopenssl', 'mnet');
|
||||
}
|
||||
@@ -65,9 +63,11 @@ if (!empty($action) and confirm_sesskey()) {
|
||||
|
||||
if (mnet_update_sso_access_control($idrec->username, $idrec->mnet_host_id, $accessctrl)) {
|
||||
if ($accessctrl == 'allow') {
|
||||
redirect('access_control.php', get_string('ssl_acl_allow','mnet', array('uset'=>$idrec->username, 'host'=>$mnethosts[$idrec->mnet_host_id])));
|
||||
} elseif ($accessctrl == 'deny') {
|
||||
redirect('access_control.php', get_string('ssl_acl_deny','mnet', array('user'=>$idrec->username, 'host'=>$mnethosts[$idrec->mnet_host_id])));
|
||||
redirect('access_control.php', get_string('ssl_acl_allow','mnet', array('user' => $idrec->username,
|
||||
'host' => $mnethosts[$idrec->mnet_host_id])));
|
||||
} else if ($accessctrl == 'deny') {
|
||||
redirect('access_control.php', get_string('ssl_acl_deny','mnet', array('user' => $idrec->username,
|
||||
'host' => $mnethosts[$idrec->mnet_host_id])));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -118,6 +118,8 @@ if ($form = data_submitted() and confirm_sesskey()) {
|
||||
exit;
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
// Explain
|
||||
echo $OUTPUT->box(get_string('ssoacldescr','mnet'));
|
||||
// Are the needed bits enabled?
|
||||
|
||||
+7
-7
@@ -140,7 +140,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
public function upgrade_confirm_page($strnewversion, $maturity, $testsite) {
|
||||
$output = '';
|
||||
|
||||
$continueurl = new moodle_url('/admin/index.php', array('confirmupgrade' => 1));
|
||||
$continueurl = new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'cache' => 0));
|
||||
$continue = new single_button($continueurl, get_string('continue'), 'get');
|
||||
$cancelurl = new moodle_url('/admin/index.php');
|
||||
|
||||
@@ -170,7 +170,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$output .= $this->environment_check_table($envstatus, $environment_results);
|
||||
|
||||
if (!$envstatus) {
|
||||
$output .= $this->upgrade_reload(new moodle_url('/admin/index.php'), array('confirmupgrade' => 1));
|
||||
$output .= $this->upgrade_reload(new moodle_url('/admin/index.php'), array('confirmupgrade' => 1, 'cache' => 0));
|
||||
|
||||
} else {
|
||||
$output .= $this->notification(get_string('environmentok', 'admin'), 'notifysuccess');
|
||||
@@ -179,7 +179,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$output .= $this->box(get_string('langpackwillbeupdated', 'admin'), 'generalbox', 'notice');
|
||||
}
|
||||
|
||||
$output .= $this->continue_button(new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1)));
|
||||
$output .= $this->continue_button(new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1, 'cache' => 0)));
|
||||
}
|
||||
|
||||
$output .= $this->footer();
|
||||
@@ -711,7 +711,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
|
||||
$updateinfo .= $this->container_start('checkforupdates');
|
||||
$fetchurl = new moodle_url('/admin/index.php', array('fetchupdates' => 1, 'sesskey' => sesskey(), 'cache' => 1));
|
||||
$fetchurl = new moodle_url('/admin/index.php', array('fetchupdates' => 1, 'sesskey' => sesskey(), 'cache' => 0));
|
||||
$updateinfo .= $this->single_button($fetchurl, get_string('checkforupdates', 'core_plugin'));
|
||||
if ($fetch) {
|
||||
$updateinfo .= $this->container(get_string('checkforupdateslast', 'core_plugin',
|
||||
@@ -962,7 +962,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$out .= $this->output->heading(get_string('nonehighlighted', 'core_plugin'));
|
||||
if (empty($options['full'])) {
|
||||
$out .= html_writer::link(new moodle_url('/admin/index.php',
|
||||
array('confirmupgrade' => 1, 'confirmrelease' => 1, 'showallplugins' => 1)),
|
||||
array('confirmupgrade' => 1, 'confirmrelease' => 1, 'showallplugins' => 1, 'cache' => 0)),
|
||||
get_string('nonehighlightedinfo', 'core_plugin'));
|
||||
}
|
||||
$out .= $this->output->container_end();
|
||||
@@ -972,11 +972,11 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$out .= $this->output->heading(get_string('somehighlighted', 'core_plugin', $sumofhighlighted));
|
||||
if (empty($options['full'])) {
|
||||
$out .= html_writer::link(new moodle_url('/admin/index.php',
|
||||
array('confirmupgrade' => 1, 'confirmrelease' => 1, 'showallplugins' => 1)),
|
||||
array('confirmupgrade' => 1, 'confirmrelease' => 1, 'showallplugins' => 1, 'cache' => 0)),
|
||||
get_string('somehighlightedinfo', 'core_plugin'));
|
||||
} else {
|
||||
$out .= html_writer::link(new moodle_url('/admin/index.php',
|
||||
array('confirmupgrade' => 1, 'confirmrelease' => 1, 'showallplugins' => 0)),
|
||||
array('confirmupgrade' => 1, 'confirmrelease' => 1, 'showallplugins' => 0, 'cache' => 0)),
|
||||
get_string('somehighlightedonly', 'core_plugin'));
|
||||
}
|
||||
$out .= $this->output->container_end();
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
|
||||
// This file defines settingpages and externalpages under the "appearance" category
|
||||
|
||||
if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$capabilities = array(
|
||||
'moodle/my:configsyspages',
|
||||
'moodle/tag:manage'
|
||||
);
|
||||
|
||||
if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
$ADMIN->add('appearance', new admin_category('themes', new lang_string('themes')));
|
||||
// "themesettings" settingpage
|
||||
@@ -186,10 +191,12 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$temp->add(new admin_setting_configcheckbox('doctonewwindow', new lang_string('doctonewwindow', 'admin'), new lang_string('configdoctonewwindow', 'admin'), 0));
|
||||
$ADMIN->add('appearance', $temp);
|
||||
|
||||
$temp = new admin_externalpage('mypage', new lang_string('mypage', 'admin'), $CFG->wwwroot . '/my/indexsys.php');
|
||||
$temp = new admin_externalpage('mypage', new lang_string('mypage', 'admin'), $CFG->wwwroot . '/my/indexsys.php',
|
||||
'moodle/my:configsyspages');
|
||||
$ADMIN->add('appearance', $temp);
|
||||
|
||||
$temp = new admin_externalpage('profilepage', new lang_string('myprofile', 'admin'), $CFG->wwwroot . '/user/profilesys.php');
|
||||
$temp = new admin_externalpage('profilepage', new lang_string('myprofile', 'admin'), $CFG->wwwroot . '/user/profilesys.php',
|
||||
'moodle/my:configsyspages');
|
||||
$ADMIN->add('appearance', $temp);
|
||||
|
||||
// coursecontact is the person responsible for course - usually manages enrolments, receives notification, etc.
|
||||
@@ -219,7 +226,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$ADMIN->add('appearance', $temp);
|
||||
|
||||
// link to tag management interface
|
||||
$ADMIN->add('appearance', new admin_externalpage('managetags', new lang_string('managetags', 'tag'), "$CFG->wwwroot/tag/manage.php"));
|
||||
$ADMIN->add('appearance', new admin_externalpage('managetags', new lang_string('managetags', 'tag'), $CFG->wwwroot.'/tag/manage.php', 'moodle/tag:manage'));
|
||||
|
||||
$temp = new admin_settingpage('additionalhtml', new lang_string('additionalhtml', 'admin'));
|
||||
$temp->add(new admin_setting_heading('additionalhtml_heading', new lang_string('additionalhtml_heading', 'admin'), new lang_string('additionalhtml_desc', 'admin')));
|
||||
|
||||
@@ -485,6 +485,16 @@ if ($hassiteconfig) {
|
||||
}
|
||||
}
|
||||
|
||||
// Add Calendar type settings.
|
||||
if ($hassiteconfig) {
|
||||
$ADMIN->add('modules', new admin_category('calendartype', new lang_string('calendartypes', 'calendar')));
|
||||
foreach (core_component::get_plugin_list_with_file('calendartype', 'settings.php') as $plugin => $settingspath) {
|
||||
$settings = new admin_settingpage('calendartype_' . $plugin . '_settings', new lang_string('pluginname', 'calendartype_' . $plugin), 'moodle/site:config');
|
||||
include($settingspath);
|
||||
$ADMIN->add('calendartype', $settings);
|
||||
}
|
||||
}
|
||||
|
||||
/// Add all local plugins - must be always last!
|
||||
if ($hassiteconfig) {
|
||||
$ADMIN->add('modules', new admin_category('localplugins', new lang_string('localplugins')));
|
||||
|
||||
@@ -59,7 +59,7 @@ class behat_admin extends behat_base {
|
||||
// We expect admin block to be visible, otherwise go to homepage.
|
||||
if (!$this->getSession()->getPage()->find('css', '.block_settings')) {
|
||||
$this->getSession()->visit($this->locate_path('/'));
|
||||
$this->wait(self::TIMEOUT, '(document.readyState === "complete")');
|
||||
$this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS);
|
||||
}
|
||||
|
||||
// Search by label.
|
||||
@@ -68,7 +68,7 @@ class behat_admin extends behat_base {
|
||||
$submitsearch = $this->find('css', 'form.adminsearchform input[type=submit]');
|
||||
$submitsearch->press();
|
||||
|
||||
$this->wait(self::TIMEOUT, '(document.readyState === "complete")');
|
||||
$this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS);
|
||||
|
||||
// Admin settings does not use the same DOM structure than other moodle forms
|
||||
// but we also need to use lib/behat/form_field/* to deal with the different moodle form elements.
|
||||
@@ -127,21 +127,15 @@ class behat_admin extends behat_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Goes to notification page ensuring site admin navigation is loaded.
|
||||
* Will be deprecated in 2.7. Goes to notification page.
|
||||
*
|
||||
* @Given /^I go to notifications page$/
|
||||
* @return Given[]
|
||||
*/
|
||||
public function i_go_to_notifications_page() {
|
||||
if ($this->running_javascript()) {
|
||||
return array(
|
||||
new Given('I expand "' . get_string('administrationsite') . '" node'),
|
||||
new Given('I follow "' . get_string('notifications') . '"')
|
||||
);
|
||||
} else {
|
||||
return array(
|
||||
new Given('I follow "' . get_string('administrationsite') . '"')
|
||||
);
|
||||
}
|
||||
return array(
|
||||
new Given('I expand "' . get_string('administrationsite') . '" node'),
|
||||
new Given('I follow "' . get_string('notifications') . '"')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ Feature: Display extended course names
|
||||
And I should not see "C_shortname Course fullname"
|
||||
|
||||
Scenario: Courses list with extended course names
|
||||
Given I go to notifications page
|
||||
Given I expand "Site administration" node
|
||||
And I click on "Courses" "link" in the "//div[@id='settingsnav']/descendant::li[contains(concat(' ', normalize-space(@class), ' '), ' type_setting ')][contains(., 'Appearance')]" "xpath_element"
|
||||
And I check "Display extended course names"
|
||||
When I press "Save changes"
|
||||
|
||||
@@ -19,7 +19,7 @@ Feature: Upload users
|
||||
And I expand "Users" node
|
||||
And I expand "Accounts" node
|
||||
And I follow "Upload users"
|
||||
When I upload "lib/tests/fixtures/upload_users.csv" file to "File" filepicker
|
||||
When I upload "lib/tests/fixtures/upload_users.csv" file to "File" filemanager
|
||||
And I press "Upload users"
|
||||
Then I should see "Upload users preview"
|
||||
And I should see "Tom"
|
||||
@@ -42,5 +42,4 @@ Feature: Upload users
|
||||
And I expand "Users" node
|
||||
And I follow "Groups"
|
||||
And I select "Section 1 (1)" from "groups"
|
||||
And I wait "4" seconds
|
||||
And the "members" select box should contain "Tom Jones"
|
||||
|
||||
@@ -93,21 +93,17 @@ ini_set('log_errors', '1');
|
||||
// Getting $CFG data.
|
||||
require_once(__DIR__ . '/../../../../config.php');
|
||||
|
||||
// CFG->behat_prefix must be set and with value different than CFG->prefix and phpunit_prefix.
|
||||
if (empty($CFG->behat_prefix) ||
|
||||
($CFG->behat_prefix == $CFG->prefix) ||
|
||||
(!empty($CFG->phpunit_prefix) && $CFG->behat_prefix == $CFG->phpunit_prefix)) {
|
||||
behat_error(BEHAT_EXITCODE_CONFIG,
|
||||
'Define $CFG->behat_prefix in config.php with a value different than $CFG->prefix and $CFG->phpunit_prefix');
|
||||
}
|
||||
// When we use the utilities we don't know how the site
|
||||
// will be accessed, so if neither $CFG->behat_switchcompletely or
|
||||
// $CFG->behat_wwwroot are set we must think that the site will
|
||||
// be accessed using the built-in server which is set by default
|
||||
// to localhost:8000. We need to do this to prevent uses of the production
|
||||
// wwwroot when the site is being installed / dropped...
|
||||
$CFG->behat_wwwroot = behat_get_wwwroot();
|
||||
|
||||
// CFG->behat_dataroot must be set and with value different than CFG->dataroot and phpunit_dataroot.
|
||||
if (empty($CFG->behat_dataroot) ||
|
||||
($CFG->behat_dataroot == $CFG->dataroot) ||
|
||||
(!empty($CFG->phpunit_dataroot) && $CFG->behat_dataroot == $CFG->phpunit_dataroot)) {
|
||||
behat_error(BEHAT_EXITCODE_CONFIG,
|
||||
'Define $CFG->behat_dataroot in config.php with a value different than $CFG->dataroot and $CFG->phpunit_dataroot');
|
||||
}
|
||||
// Checking the integrity of the provided $CFG->behat_* vars
|
||||
// to prevent conflicts with production and phpunit environments.
|
||||
behat_check_config_vars();
|
||||
|
||||
// Create behat_dataroot if it doesn't exists.
|
||||
if (!file_exists($CFG->behat_dataroot)) {
|
||||
|
||||
@@ -18,7 +18,7 @@ Feature: Page contents assertions
|
||||
When I follow "Overview"
|
||||
And I wait until the page is ready
|
||||
And I wait "2" seconds
|
||||
And I hover ".region-content .generaltable td span" "css_element"
|
||||
And I hover "#region-main .generaltable td span" "css_element"
|
||||
Then I should see "I'm the description"
|
||||
And "Grouping" "select" in the "region-main" "region" should be visible
|
||||
And "Group" "select" should be visible
|
||||
@@ -26,8 +26,8 @@ Feature: Page contents assertions
|
||||
And "Change password" "link" should not be visible
|
||||
And I should see "Filter groups by"
|
||||
And I should not see "Filter groupssss by"
|
||||
And I should see "Group members" in the ".region-content table th.c1" "css_element"
|
||||
And I should not see "Group membersssss" in the ".region-content table th.c1" "css_element"
|
||||
And I should see "Group members" in the "#region-main table th.c1" "css_element"
|
||||
And I should not see "Group membersssss" in the "#region-main table th.c1" "css_element"
|
||||
And I follow "Groups"
|
||||
And the "#groupeditform #showcreateorphangroupform" "css_element" should be enabled
|
||||
And the "#groupeditform #showeditgroupsettingsform" "css_element" should be disabled
|
||||
@@ -39,7 +39,7 @@ Feature: Page contents assertions
|
||||
| Course 1 | C1 | 0 |
|
||||
And I log in as "admin"
|
||||
And I follow "Course 1"
|
||||
When I click on "Move this to the dock" "button" in the "Administration" "block"
|
||||
When I dock "Administration" block
|
||||
Then I should not see "Question bank" in the "region-pre" "region"
|
||||
And I click on "//div[@id='dock']/descendant::h2[normalize-space(.)='Administration']" "xpath_element"
|
||||
|
||||
@@ -49,5 +49,5 @@ Feature: Page contents assertions
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And I log in as "admin"
|
||||
When I click on "Move this to the dock" "button" in the "Administration" "block"
|
||||
When I dock "Administration" block
|
||||
Then I should not see "Turn editing on" in the "region-pre" "region"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@tool @tool_behat
|
||||
@tool @tool_behat @_only_local
|
||||
Feature: Set up contextual data for tests
|
||||
In order to write tests quickly
|
||||
As a developer
|
||||
@@ -143,13 +143,56 @@ Feature: Set up contextual data for tests
|
||||
| fullname | shortname |
|
||||
| Course 1 | C1 |
|
||||
And the following "activities" exists:
|
||||
| activity | name | intro | course | idnumber |
|
||||
| assign | Test assignment name | Test assignment description | C1 | assign1 |
|
||||
| data | Test database name | Test database description | C1 | data1 |
|
||||
| activity | name | intro | course | idnumber |
|
||||
| assign | Test assignment name | Test assignment description | C1 | assign1 |
|
||||
| assignment | Test assignment22 name | Test assignment22 description | C1 | assignment1 |
|
||||
| book | Test book name | Test book description | C1 | book1 |
|
||||
| chat | Test chat name | Test chat description | C1 | chat1 |
|
||||
| choice | Test choice name | Test choice description | C1 | choice1 |
|
||||
| data | Test database name | Test database description | C1 | data1 |
|
||||
| feedback | Test feedback name | Test feedback description | C1 | feedback1 |
|
||||
| folder | Test folder name | Test folder description | C1 | folder1 |
|
||||
| forum | Test forum name | Test forum description | C1 | forum1 |
|
||||
| glossary | Test glossary name | Test glossary description | C1 | glossary1 |
|
||||
| imscp | Test imscp name | Test imscp description | C1 | imscp1 |
|
||||
| label | Test label name | Test label description | C1 | label1 |
|
||||
| lesson | Test lesson name | Test lesson description | C1 | lesson1 |
|
||||
| lti | Test lti name | Test lti description | C1 | lti1 |
|
||||
| page | Test page name | Test page description | C1 | page1 |
|
||||
| quiz | Test quiz name | Test quiz description | C1 | quiz1 |
|
||||
| resource | Test resource name | Test resource description | C1 | resource1 |
|
||||
| scorm | Test scorm name | Test scorm description | C1 | scorm1 |
|
||||
| survey | Test survey name | Test survey description | C1 | survey1 |
|
||||
| url | Test url name | Test url description | C1 | url1 |
|
||||
| wiki | Test wiki name | Test wiki description | C1 | wiki1 |
|
||||
| workshop | Test workshop name | Test workshop description | C1 | workshop1 |
|
||||
When I log in as "admin"
|
||||
And I follow "Course 1"
|
||||
Then I should see "Test assignment name"
|
||||
# Assignment 2.2 module type is disabled by default
|
||||
# And I should see "Test assignment22 name"
|
||||
And I should see "Test book name"
|
||||
And I should see "Test chat name"
|
||||
And I should see "Test choice name"
|
||||
And I should see "Test database name"
|
||||
# Feedback module type is disabled by default
|
||||
# And I should see "Test feedback name"
|
||||
And I should see "Test folder name"
|
||||
And I should see "Test forum name"
|
||||
And I should see "Test glossary name"
|
||||
And I should see "Test imscp name"
|
||||
# We don't see label name, we see only description:
|
||||
And I should see "Test label description"
|
||||
And I should see "Test lesson name"
|
||||
And I should see "Test lti name"
|
||||
And I should see "Test page name"
|
||||
And I should see "Test quiz name"
|
||||
And I should see "Test resource name"
|
||||
And I should see "Test scorm name"
|
||||
And I should see "Test survey name"
|
||||
And I should see "Test url name"
|
||||
And I should see "Test wiki name"
|
||||
And I should see "Test workshop name"
|
||||
And I follow "Test assignment name"
|
||||
And I should see "Test assignment description"
|
||||
|
||||
@@ -187,8 +230,6 @@ Feature: Set up contextual data for tests
|
||||
Then the "groups" select box should contain "Group 1 (1)"
|
||||
And the "groups" select box should contain "Group 2 (1)"
|
||||
And I select "Group 1 (1)" from "groups"
|
||||
And I wait "5" seconds
|
||||
And the "members" select box should contain "Student 1"
|
||||
And I select "Group 2 (1)" from "groups"
|
||||
And I wait "5" seconds
|
||||
And the "members" select box should contain "Student 2"
|
||||
|
||||
@@ -32,5 +32,5 @@ Feature: Forms manipulation
|
||||
Then I should see "Close the quiz"
|
||||
And I should see "Group mode"
|
||||
And I should see "Grouping"
|
||||
And I should not see "Show more..." in the "region-main-box" "region"
|
||||
And I should not see "Show more..." in the "region-main" "region"
|
||||
And I should see "Show less..."
|
||||
|
||||
@@ -173,6 +173,9 @@ class tool_behat_testcase extends advanced_testcase {
|
||||
// directories values.
|
||||
$this->assertContains($CFG->dirroot . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'behat' . DIRECTORY_SEPARATOR . 'features', $contents);
|
||||
|
||||
// If it was empty should be filled by behat_config_manager::get_config_file_contents().
|
||||
$this->assertNotNull($CFG->behat_wwwroot);
|
||||
|
||||
// Not quoted strings.
|
||||
$this->assertContains('micarro: /me/lo/robaron', $contents);
|
||||
$this->assertContains('class: behat_init_context', $contents);
|
||||
@@ -183,6 +186,8 @@ class tool_behat_testcase extends advanced_testcase {
|
||||
// Lists.
|
||||
$this->assertContains('- feature1', $contents);
|
||||
$this->assertContains('- feature3', $contents);
|
||||
|
||||
unset($CFG->behat_wwwroot);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2013110500;
|
||||
$plugin->version = 2013110501;
|
||||
$plugin->requires = 2013110500; // Requires Moodle 2.5.
|
||||
$plugin->component = 'tool_behat';
|
||||
|
||||
@@ -74,9 +74,15 @@ function tool_capability_calculate_role_data($capability, array $roles) {
|
||||
// Put the contexts into a tree structure.
|
||||
foreach ($contexts as $conid => $con) {
|
||||
$context = context::instance_by_id($conid);
|
||||
$parentcontext = $context->get_parent_context();
|
||||
if ($parentcontext) {
|
||||
$contexts[$parentcontext->id]->children[] = $conid;
|
||||
try {
|
||||
$parentcontext = $context->get_parent_context();
|
||||
if ($parentcontext) { // Will be false if $context is the system context.
|
||||
$contexts[$parentcontext->id]->children[] = $conid;
|
||||
}
|
||||
} catch (dml_missing_record_exception $e) {
|
||||
// Ignore corrupt context tree structure here. Don't let it break
|
||||
// showing the rest of the report.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ class tool_capability_renderer extends plugin_renderer_base {
|
||||
$table->attributes['class'] = 'comparisontable';
|
||||
$table->head = array(' ');
|
||||
foreach ($roles as $role) {
|
||||
$url = new moodle_url('/admin/roles/override.php', array('contextid' => $contextid, 'roleid' => $role->id));
|
||||
$url = new moodle_url('/admin/roles/define.php', array('action' => 'view', 'roleid' => $role->id));
|
||||
$table->head[] = html_writer::div(html_writer::link($url, $role->localname));
|
||||
}
|
||||
$table->data = array();
|
||||
|
||||
@@ -42,5 +42,8 @@ function xmldb_tool_customlang_upgrade($oldversion) {
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -23,5 +23,7 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['multilangupgradeinfo'] = 'The multilang filter syntax was changed in 1.8, <lang> tag is not supported any more. <br /><br />Example: <span lang="en" class="multilang">Hello!</span><span lang="es" class="multilang">Hola!</span><br /><br /><strong>Do you want to upgrade the syntax in all existing texts now?</strong>';
|
||||
$string['multilangupgradeinfo'] = '<p>The multilang filter syntax was changed in 1.8 and so the <lang> tag is not supported any more.</p>
|
||||
<p>Example: <span lang="en" class="multilang">Hello!</span><span lang="es" class="multilang">Hola!</span></p>
|
||||
<p>Do you want to upgrade the syntax in all existing texts now?</p>';
|
||||
$string['pluginname'] = 'Multilang upgrade';
|
||||
|
||||
@@ -46,7 +46,7 @@ class tool_qeupgradehelper_extract_options_form extends moodleform {
|
||||
|
||||
$qtypes = core_component::get_plugin_list('qtype');
|
||||
foreach ($qtypes as $qtype => $notused) {
|
||||
$qtypes[$qtype] = get_string($qtype, 'qtype_' . $qtype);
|
||||
$qtypes[$qtype] = get_string('pluginname', 'qtype_' . $qtype);
|
||||
}
|
||||
|
||||
$mform->addElement('header', 'h1', 'Either extract a specific question_session');
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Site wide search-replace form.
|
||||
*
|
||||
* @package tool_replace
|
||||
* @copyright 2013 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once("$CFG->libdir/formslib.php");
|
||||
|
||||
/**
|
||||
* Site wide search-replace form.
|
||||
*/
|
||||
class tool_replace_form extends moodleform {
|
||||
function definition() {
|
||||
global $CFG, $DB;
|
||||
|
||||
$mform = $this->_form;
|
||||
|
||||
$mform->addElement('header', 'searchhdr', get_string('pluginname', 'tool_replace'));
|
||||
$mform->setExpanded('searchhdr', true);
|
||||
|
||||
$mform->addElement('text', 'search', get_string('searchwholedb', 'tool_replace'), 'size="50"');
|
||||
$mform->setType('search', PARAM_RAW);
|
||||
$mform->addElement('static', 'searchst', '', get_string('searchwholedbhelp', 'tool_replace'));
|
||||
$mform->addRule('search', get_string('required'), 'required', null, 'client');
|
||||
|
||||
$mform->addElement('text', 'replace', get_string('replacewith', 'tool_replace'), 'size="50"', PARAM_RAW);
|
||||
$mform->addElement('static', 'replacest', '', get_string('replacewithhelp', 'tool_replace'));
|
||||
$mform->setType('replace', PARAM_RAW);
|
||||
$mform->addElement('checkbox', 'shorten', get_string('shortenoversized', 'tool_replace'));
|
||||
$mform->addRule('replace', get_string('required'), 'required', null, 'client');
|
||||
|
||||
$mform->addElement('header', 'confirmhdr', get_string('confirm'));
|
||||
$mform->setExpanded('confirmhdr', true);
|
||||
$mform->addElement('checkbox', 'sure', get_string('disclaimer', 'tool_replace'));
|
||||
$mform->addRule('sure', get_string('required'), 'required', null, 'client');
|
||||
|
||||
$this->add_action_buttons(false, get_string('doit', 'tool_replace'));
|
||||
}
|
||||
|
||||
function validation($data, $files) {
|
||||
$errors = parent::validation($data, $files);
|
||||
|
||||
if (empty($data['shorten']) and core_text::strlen($data['search']) < core_text::strlen($data['replace'])) {
|
||||
$errors['shorten'] = get_string('required');
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,7 @@
|
||||
/**
|
||||
* Search and replace strings throughout all texts in the whole database
|
||||
*
|
||||
* @package tool
|
||||
* @subpackage replace
|
||||
* @package tool_replace
|
||||
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
@@ -31,56 +30,38 @@ require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('toolreplace');
|
||||
|
||||
$search = optional_param('search', '', PARAM_RAW);
|
||||
$replace = optional_param('replace', '', PARAM_RAW);
|
||||
$sure = optional_param('sure', 0, PARAM_BOOL);
|
||||
|
||||
###################################################################
|
||||
echo $OUTPUT->header();
|
||||
|
||||
echo $OUTPUT->heading(get_string('pageheader', 'tool_replace'));
|
||||
|
||||
if ($DB->get_dbfamily() !== 'mysql' and $DB->get_dbfamily() !== 'postgres') {
|
||||
//TODO: add $DB->text_replace() to DML drivers
|
||||
if (!$DB->replace_all_text_supported()) {
|
||||
echo $OUTPUT->notification(get_string('notimplemented', 'tool_replace'));
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
}
|
||||
|
||||
if (!data_submitted() or !$search or !$replace or !confirm_sesskey() or !$sure) { /// Print a form
|
||||
echo $OUTPUT->notification(get_string('notsupported', 'tool_replace'));
|
||||
echo $OUTPUT->notification(get_string('excludedtables', 'tool_replace'));
|
||||
|
||||
echo $OUTPUT->box_start();
|
||||
echo '<div class="mdl-align">';
|
||||
echo '<form action="index.php" method="post"><div>';
|
||||
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
|
||||
echo '<div><label for="search">'.get_string('searchwholedb', 'tool_replace').
|
||||
' </label><input id="search" type="text" name="search" size="40" /> ('.
|
||||
get_string('searchwholedbhelp', 'tool_replace').')</div>';
|
||||
echo '<div><label for="replace">'.get_string('replacewith', 'tool_replace').
|
||||
' </label><input type="text" id="replace" name="replace" size="40" /> ('.
|
||||
get_string('replacewithhelp', 'tool_replace').')</div>';
|
||||
echo '<div><label for="sure">'.get_string('disclaimer', 'tool_replace').' </label><input type="checkbox" id="sure" name="sure" value="1" /></div>';
|
||||
echo '<div class="buttons"><input type="submit" class="singlebutton" value="Yes, do it now" /></div>';
|
||||
echo '</div></form>';
|
||||
echo '</div>';
|
||||
echo $OUTPUT->box_end();
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
}
|
||||
|
||||
echo $OUTPUT->box_start();
|
||||
db_replace($search, $replace);
|
||||
echo $OUTPUT->notification(get_string('notsupported', 'tool_replace'));
|
||||
echo $OUTPUT->notification(get_string('excludedtables', 'tool_replace'));
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
/// Rebuild course cache which might be incorrect now
|
||||
echo $OUTPUT->notification(get_string('notifyrebuilding', 'tool_replace'), 'notifysuccess');
|
||||
rebuild_course_cache();
|
||||
echo $OUTPUT->notification(get_string('notifyfinished', 'tool_replace'), 'notifysuccess');
|
||||
$form = new tool_replace_form();
|
||||
|
||||
if (!$data = $form->get_data()) {
|
||||
$form->display();
|
||||
echo $OUTPUT->footer();
|
||||
die();
|
||||
}
|
||||
|
||||
// Scroll to the end when finished.
|
||||
$PAGE->requires->js_init_code("window.scrollTo(0, 5000000);");
|
||||
|
||||
echo $OUTPUT->box_start();
|
||||
db_replace($data->search, $data->replace);
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
// Course caches are now rebuilt on the fly.
|
||||
|
||||
echo $OUTPUT->continue_button(new moodle_url('/admin/index.php'));
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
|
||||
|
||||
@@ -23,15 +23,18 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['disclaimer'] = 'I understand the risks of this operation:';
|
||||
$string['cannotfit'] = 'The replacement is longer than original and shortening is not allow, cannot continue.';
|
||||
$string['disclaimer'] = 'I understand the risks of this operation';
|
||||
$string['doit'] = 'Yes, do it!';
|
||||
$string['excludedtables'] = 'Several tables are not updated as part of the text replacement. This include configuration, log, events, and session tables.';
|
||||
$string['pageheader'] = 'Search and replace text throughout the whole database';
|
||||
$string['notifyfinished'] = '...finished';
|
||||
$string['notifyrebuilding'] = 'Rebuilding course cache...';
|
||||
$string['notimplemented'] = 'Sorry, this feature is implemented only for MySQL and PostgreSQL databases.';
|
||||
$string['notimplemented'] = 'Sorry, this feature is not implemented in your database driver.';
|
||||
$string['notsupported'] ='This script is not supported, always make complete backup before proceeding!<br />This operation can not be reverted!';
|
||||
$string['pluginname'] = 'DB search and replace';
|
||||
$string['replacewith'] = 'Replace with this string:';
|
||||
$string['replacewith'] = 'Replace with this string';
|
||||
$string['replacewithhelp'] = 'usually new server URL';
|
||||
$string['searchwholedb'] = 'Search whole database for:';
|
||||
$string['searchwholedb'] = 'Search whole database for';
|
||||
$string['searchwholedbhelp'] = 'usually previous server URL';
|
||||
$string['shortenoversized'] = 'Shorten result if necessary';
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2013110500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->version = 2013110501; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2013110500; // Requires this Moodle version
|
||||
$plugin->component = 'tool_replace'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
|
||||
@@ -178,13 +178,47 @@ function search_spammers($keywords) {
|
||||
$conditions6 = '( '.implode(' OR ', $keywordfull6).' )';
|
||||
$conditions7 = '( '.implode(' OR ', $keywordfull7).' )';
|
||||
|
||||
$sql = "SELECT * FROM {user} WHERE deleted = 0 AND id <> :userid AND $conditions"; // Exclude oneself
|
||||
$sql2 = "SELECT u.*, p.summary FROM {user} AS u, {post} AS p WHERE $conditions2 AND u.deleted = 0 AND u.id=p.userid AND u.id <> :userid";
|
||||
$sql3 = "SELECT u.*, p.subject as postsubject FROM {user} AS u, {post} AS p WHERE $conditions3 AND u.deleted = 0 AND u.id=p.userid AND u.id <> :userid";
|
||||
$sql4 = "SELECT u.*, c.content FROM {user} AS u, {comments} AS c WHERE $conditions4 AND u.deleted = 0 AND u.id=c.userid AND u.id <> :userid";
|
||||
$sql5 = "SELECT u.*, m.fullmessage FROM {user} AS u, {message} AS m WHERE $conditions5 AND u.deleted = 0 AND u.id=m.useridfrom AND u.id <> :userid";
|
||||
$sql6 = "SELECT u.*, fp.message FROM {user} AS u, {forum_posts} AS fp WHERE $conditions6 AND u.deleted = 0 AND u.id=fp.userid AND u.id <> :userid";
|
||||
$sql7 = "SELECT u.*, fp.subject FROM {user} AS u, {forum_posts} AS fp WHERE $conditions7 AND u.deleted = 0 AND u.id=fp.userid AND u.id <> :userid";
|
||||
$sql = "SELECT *
|
||||
FROM {user}
|
||||
WHERE deleted = 0
|
||||
AND id <> :userid
|
||||
AND $conditions"; // Exclude oneself
|
||||
$sql2 = "SELECT u.*, p.summary
|
||||
FROM {user} u, {post} p
|
||||
WHERE $conditions2
|
||||
AND u.deleted = 0
|
||||
AND u.id=p.userid
|
||||
AND u.id <> :userid";
|
||||
$sql3 = "SELECT u.*, p.subject AS postsubject
|
||||
FROM {user} u, {post} p
|
||||
WHERE $conditions3
|
||||
AND u.deleted = 0
|
||||
AND u.id=p.userid
|
||||
AND u.id <> :userid";
|
||||
$sql4 = "SELECT u.*, c.content
|
||||
FROM {user} u, {comments} c
|
||||
WHERE $conditions4
|
||||
AND u.deleted = 0
|
||||
AND u.id=c.userid
|
||||
AND u.id <> :userid";
|
||||
$sql5 = "SELECT u.*, m.fullmessage
|
||||
FROM {user} u, {message} m
|
||||
WHERE $conditions5
|
||||
AND u.deleted = 0
|
||||
AND u.id=m.useridfrom
|
||||
AND u.id <> :userid";
|
||||
$sql6 = "SELECT u.*, fp.message
|
||||
FROM {user} u, {forum_posts} fp
|
||||
WHERE $conditions6
|
||||
AND u.deleted = 0
|
||||
AND u.id=fp.userid
|
||||
AND u.id <> :userid";
|
||||
$sql7 = "SELECT u.*, fp.subject
|
||||
FROM {user} u, {forum_posts} fp
|
||||
WHERE $conditions7
|
||||
AND u.deleted = 0
|
||||
AND u.id=fp.userid
|
||||
AND u.id <> :userid";
|
||||
|
||||
$spamusers_desc = $DB->get_recordset_sql($sql, $params);
|
||||
$spamusers_blog = $DB->get_recordset_sql($sql2, $params);
|
||||
|
||||
@@ -27,7 +27,8 @@ $string['pluginname'] = 'Spam cleaner';
|
||||
$string['spamauto'] = 'Autodetect common spam patterns';
|
||||
$string['spamcannotdelete'] = 'Cannot delete this user';
|
||||
$string['spamcannotfinduser'] = 'No users matching your search';
|
||||
$string['spamcleanerintro'] = 'This script allows you to search all user profiles for certain strings and then delete those accounts which are obviously created by spammers. You can search for multiple keywords using commas (eg casino, porn)<br /><br />Moodle docs has more information about <a href="http://docs.moodle.org/en/Reducing_spam_in_Moodle">Reducing spam in Moodle</a>.';
|
||||
$string['spamcleanerintro'] = '<p>This script allows you to search all user profiles for certain strings and then delete those accounts which are obviously created by spammers. You can search for multiple keywords using commas (e.g. casino, porn).</p>
|
||||
<p>For further information, see the documentation <a href="http://docs.moodle.org/en/Reducing_spam_in_Moodle">Reducing spam in Moodle</a>.</p>';
|
||||
$string['spamdeleteall'] = 'Delete all these user accounts';
|
||||
$string['spamdeleteallconfirm'] = 'Are you sure you want to delete all these user accounts? You can not undo this.';
|
||||
$string['spamdeleteconfirm'] = 'Are you sure you want to delete this entry? You can not undo this.';
|
||||
|
||||
@@ -15,7 +15,7 @@ Feature: An admin can create courses using a CSV file
|
||||
|
||||
@javascript
|
||||
Scenario: Creation of unexisting courses
|
||||
Given I upload "admin/tool/uploadcourse/tests/fixtures/courses.csv" file to "File" filepicker
|
||||
Given I upload "admin/tool/uploadcourse/tests/fixtures/courses.csv" file to "File" filemanager
|
||||
And I click on "Preview" "button"
|
||||
When I click on "Upload courses" "button"
|
||||
Then I should see "The course exists and update is not allowed"
|
||||
@@ -29,7 +29,7 @@ Feature: An admin can create courses using a CSV file
|
||||
|
||||
@javascript
|
||||
Scenario: Creation of existing courses
|
||||
Given I upload "admin/tool/uploadcourse/tests/fixtures/courses.csv" file to "File" filepicker
|
||||
Given I upload "admin/tool/uploadcourse/tests/fixtures/courses.csv" file to "File" filemanager
|
||||
And I select "Create all, increment shortname if needed" from "Upload mode"
|
||||
And I click on "Preview" "button"
|
||||
When I click on "Upload courses" "button"
|
||||
|
||||
@@ -15,7 +15,7 @@ Feature: An admin can update courses using a CSV file
|
||||
|
||||
@javascript
|
||||
Scenario: Updating a course fullname
|
||||
Given I upload "admin/tool/uploadcourse/tests/fixtures/courses.csv" file to "File" filepicker
|
||||
Given I upload "admin/tool/uploadcourse/tests/fixtures/courses.csv" file to "File" filemanager
|
||||
And I select "Only update existing courses" from "Upload mode"
|
||||
And I select "Update with CSV data only" from "Update mode"
|
||||
And I click on "Preview" "button"
|
||||
|
||||
@@ -123,12 +123,11 @@ if (empty($iid)) {
|
||||
$content = $mform1->get_file_content('userfile');
|
||||
|
||||
$readcount = $cir->load_csv_content($content, $formdata->encoding, $formdata->delimiter_name);
|
||||
$csvloaderror = $cir->get_error();
|
||||
unset($content);
|
||||
|
||||
if ($readcount === false) {
|
||||
print_error('csvloaderror', '', $returnurl);
|
||||
} else if ($readcount == 0) {
|
||||
print_error('csvemptyfile', 'error', $returnurl);
|
||||
if (!is_null($csvloaderror)) {
|
||||
print_error('csvloaderror', '', $returnurl, $csvloaderror);
|
||||
}
|
||||
// test if columns ok
|
||||
$filecolumns = uu_validate_user_upload_columns($cir, $STD_FIELDS, $PRF_FIELDS, $returnurl);
|
||||
@@ -235,10 +234,10 @@ if ($formdata = $mform2->is_cancelled()) {
|
||||
$user->$key['text'] = $value;
|
||||
$user->$key['format'] = FORMAT_MOODLE;
|
||||
} else {
|
||||
$user->$key = $value;
|
||||
$user->$key = trim($value);
|
||||
}
|
||||
} else {
|
||||
$user->$key = $value;
|
||||
$user->$key = trim($value);
|
||||
}
|
||||
|
||||
if (in_array($key, $upt->columns)) {
|
||||
@@ -550,8 +549,6 @@ if ($formdata = $mform2->is_cancelled()) {
|
||||
continue;
|
||||
}
|
||||
if (!property_exists($user, $column) or !property_exists($existinguser, $column)) {
|
||||
// this should never happen
|
||||
debugging("Could not find $column on the user objects", DEBUG_DEVELOPER);
|
||||
continue;
|
||||
}
|
||||
if ($updatetype == UU_UPDATE_MISSING) {
|
||||
@@ -966,7 +963,7 @@ if ($formdata = $mform2->is_cancelled()) {
|
||||
$status = null;
|
||||
|
||||
if (isset($user->{'enrolstatus'.$i})) {
|
||||
$enrolstatus = trim($user->{'enrolstatus'.$i});
|
||||
$enrolstatus = $user->{'enrolstatus'.$i};
|
||||
if ($enrolstatus == '') {
|
||||
$status = null;
|
||||
} else if ($enrolstatus === (string)ENROL_USER_ACTIVE) {
|
||||
@@ -1109,7 +1106,7 @@ while ($linenum <= $previewrows and $fields = $cir->next()) {
|
||||
$rowcols = array();
|
||||
$rowcols['line'] = $linenum;
|
||||
foreach($fields as $key => $field) {
|
||||
$rowcols[$filecolumns[$key]] = s($field);
|
||||
$rowcols[$filecolumns[$key]] = s(trim($field));
|
||||
}
|
||||
$rowcols['status'] = array();
|
||||
|
||||
@@ -1135,7 +1132,7 @@ while ($linenum <= $previewrows and $fields = $cir->next()) {
|
||||
}
|
||||
|
||||
if (isset($rowcols['city'])) {
|
||||
$rowcols['city'] = trim($rowcols['city']);
|
||||
$rowcols['city'] = $rowcols['city'];
|
||||
}
|
||||
// Check if rowcols have custom profile field with correct data and update error state.
|
||||
$noerror = uu_check_custom_profile_data($rowcols) && $noerror;
|
||||
|
||||
@@ -53,6 +53,8 @@ class check_foreign_keys extends XMLDBCheckAction {
|
||||
'noviolatedforeignkeysfound' => 'tool_xmldb',
|
||||
'violatedforeignkeysfound' => 'tool_xmldb',
|
||||
'violations' => 'tool_xmldb',
|
||||
'unknowntable' => 'tool_xmldb',
|
||||
'unknownfield' => 'tool_xmldb',
|
||||
));
|
||||
}
|
||||
|
||||
@@ -75,6 +77,19 @@ class check_foreign_keys extends XMLDBCheckAction {
|
||||
}
|
||||
$o.=' <li>' . $this->str['key'] . ': ' . $xmldb_key->readableInfo() . ' ';
|
||||
|
||||
$reftable = $xmldb_key->getRefTable();
|
||||
if (!$dbman->table_exists($reftable)) {
|
||||
$o.='<font color="red">' . $this->str['unknowntable'] . '</font>';
|
||||
// Add the missing index to the list
|
||||
$violation = new stdClass();
|
||||
$violation->string = 'fkunknowntable';
|
||||
$violation->table = $xmldb_table;
|
||||
$violation->key = $xmldb_key;
|
||||
$violation->reftable = $reftable;
|
||||
$violatedkeys[] = $violation;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Work out the SQL to find key violations.
|
||||
$keyfields = $xmldb_key->getFields();
|
||||
$reffields = $xmldb_key->getRefFields();
|
||||
@@ -82,6 +97,19 @@ class check_foreign_keys extends XMLDBCheckAction {
|
||||
$nullnessconditions = array();
|
||||
$params = array();
|
||||
foreach ($keyfields as $i => $field) {
|
||||
if (!$dbman->field_exists($reftable, $reffields[$i])) {
|
||||
$o.='<font color="red">' . $this->str['unknownfield'] . '</font>';
|
||||
// Add the missing index to the list
|
||||
$violation = new stdClass();
|
||||
$violation->string = 'fkunknownfield';
|
||||
$violation->table = $xmldb_table;
|
||||
$violation->key = $xmldb_key;
|
||||
$violation->reftable = $reftable;
|
||||
$violation->reffield = $reffields[$i];
|
||||
$violatedkeys[] = $violation;
|
||||
continue 2;
|
||||
}
|
||||
|
||||
$joinconditions[] = 't1.' . $field . ' = t2.' . $reffields[$i];
|
||||
$xmldb_field = $xmldb_table->getField($field);
|
||||
$default = $xmldb_field->getDefault();
|
||||
@@ -97,7 +125,7 @@ class check_foreign_keys extends XMLDBCheckAction {
|
||||
}
|
||||
$nullnessconditions[] = 't2.id IS NULL';
|
||||
$sql = 'SELECT count(1) FROM {' . $xmldb_table->getName() .
|
||||
'} t1 LEFT JOIN {' . $xmldb_key->getRefTable() . '} t2 ON ' .
|
||||
'} t1 LEFT JOIN {' . $reftable . '} t2 ON ' .
|
||||
implode(' AND ', $joinconditions) . ' WHERE ' .
|
||||
implode(' AND ', $nullnessconditions);
|
||||
|
||||
@@ -109,6 +137,7 @@ class check_foreign_keys extends XMLDBCheckAction {
|
||||
$o.='<font color="red">' . $this->str['violations'] . '</font>';
|
||||
// Add the missing index to the list
|
||||
$violation = new stdClass;
|
||||
$violation->string = 'fkviolationdetails';
|
||||
$violation->table = $xmldb_table;
|
||||
$violation->key = $xmldb_key;
|
||||
$violation->numviolations = $violations;
|
||||
@@ -145,8 +174,11 @@ class check_foreign_keys extends XMLDBCheckAction {
|
||||
$violation->tablename = $violation->table->getName();
|
||||
$violation->keyname = $violation->key->getName();
|
||||
|
||||
$r.= ' <li>' .get_string('fkviolationdetails', 'tool_xmldb', $violation) .
|
||||
'<pre>' . s($violation->sql) . '; ' . s($violation->sqlparams) . '</pre></li>';
|
||||
$r.= ' <li>' .get_string($violation->string, 'tool_xmldb', $violation);
|
||||
if (!empty($violation->sql)) {
|
||||
$r.= '<pre>' . s($violation->sql) . '; ' . s($violation->sqlparams) . '</pre>';
|
||||
}
|
||||
$r.= '</li>';
|
||||
}
|
||||
$r.= ' </ul>';
|
||||
} else {
|
||||
|
||||
@@ -106,6 +106,8 @@ $string['fieldsusedinindex'] = 'This field is used as index';
|
||||
$string['fieldsusedinkey'] = 'This field is used as key.';
|
||||
$string['filemodifiedoutfromeditor'] = 'Warning: File locally modified while using the XMLDB Editor. Saving will overwrite local changes.';
|
||||
$string['filenotwriteable'] = 'File not writeable';
|
||||
$string['fkunknownfield'] = 'Foreign key {$a->keyname} on table {$a->tablename} points to a non-existent field {$a->reffield} in referenced table {$a->reftable}.';
|
||||
$string['fkunknowntable'] = 'Foreign key {$a->keyname} on table {$a->tablename} points to a non-existent table {$a->reftable}.';
|
||||
$string['fkviolationdetails'] = 'Foreign key {$a->keyname} on table {$a->tablename} is violated by {$a->numviolations} out of {$a->numrows} rows.';
|
||||
$string['floatincorrectdecimals'] = 'Incorrect number of decimals for float field';
|
||||
$string['floatincorrectlength'] = 'Incorrect length for float field';
|
||||
@@ -183,6 +185,8 @@ $string['selecttable'] = 'Select table:';
|
||||
$string['table'] = 'Table';
|
||||
$string['tablenameempty'] = 'The table name cannot be empty';
|
||||
$string['tables'] = 'Tables';
|
||||
$string['unknownfield'] = 'Refers to an unknown field';
|
||||
$string['unknowntable'] = 'Refers to an unknown table';
|
||||
$string['unload'] = 'Unload';
|
||||
$string['up'] = 'Up';
|
||||
$string['view'] = 'View';
|
||||
@@ -206,7 +210,11 @@ $string['wronglengthforenum'] = 'Incorrect length for enum field';
|
||||
$string['wrongnumberofreffields'] = 'Wrong number of reference fields';
|
||||
$string['wrongreservedwords'] = 'Currently used reserved words<br />(note that table names aren\'t important if using $CFG->prefix)';
|
||||
$string['wrongoraclesemantics'] = 'Wrong Oracle BYTE semantics found';
|
||||
$string['yesmissingindexesfound'] = 'Some missing indexes have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all them (don\'t forget to backup your data before doing that).<br /><br />After doing that, it\'s highly recommended to execute this utility again to check that no more missing indexes are found.';
|
||||
$string['yeswrongdefaultsfound'] = 'Some inconsistent defaults have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to fix them all (don\'t forget to backup your data before doing that).<br /><br />After doing that, it\'s highly recommended to execute this utility again to check that no more inconsistent defaults are found.';
|
||||
$string['yeswrongintsfound'] = 'Some wrong integers have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all them (don\'t forget to backup your data before doing that).<br /><br />After doing that, it\'s highly recommended to execute this utility again to check that no more wrong integers are found.';
|
||||
$string['yeswrongoraclesemanticsfound'] = 'Some Oracle columns using BYTE semantics have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all them (don\'t forget to backup your data before doing that).<br /><br />After doing that, it\'s highly recommended to execute this utility again to check that no more wrong semantics are found.';
|
||||
$string['yesmissingindexesfound'] = '<p>Some missing indexes have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all of them. Remember to backup your data first!</p>
|
||||
<p>After doing that, it\'s highly recommended to execute this utility again to check that no more missing indexes are found.</p>';
|
||||
$string['yeswrongdefaultsfound'] = '<p>Some inconsistent defaults have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to fix them all. Remember to backup your data first!</p>
|
||||
<p>After doing that, it\'s highly recommended to execute this utility again to check that no more inconsistent defaults are found.</p>';
|
||||
$string['yeswrongintsfound'] = '<p>Some wrong integers have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all them. Remember to backup your data first!</p>
|
||||
<p>After doing that, it\'s highly recommended to execute this utility again to check that no more wrong integers are found.</p>';
|
||||
$string['yeswrongoraclesemanticsfound'] = '<p>Some Oracle columns using BYTE semantics have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all them. Remember to backup your data first!</p>
|
||||
<p>After doing that, it\'s highly recommended to execute this utility again to check that no more wrong semantics are found.</p>';
|
||||
|
||||
@@ -10,6 +10,11 @@ $return = optional_param('return', '', PARAM_ALPHA);
|
||||
|
||||
/// no guest autologin
|
||||
require_login(0, false);
|
||||
if (isguestuser()) {
|
||||
// Login as real user!
|
||||
$SESSION->wantsurl = (string)new moodle_url('/admin/upgradesettings.php', array('return'=>$return));
|
||||
redirect(get_login_url());
|
||||
}
|
||||
|
||||
admin_externalpage_setup('upgradesettings'); // now hidden page
|
||||
$PAGE->set_pagelayout('maintenance'); // do not print any blocks or other rubbish, we want to force saving
|
||||
|
||||
@@ -207,12 +207,14 @@ class web_service_token_form extends moodleform {
|
||||
|
||||
if ($usertotal < 500) {
|
||||
list($sort, $params) = users_order_by_sql('u');
|
||||
//user searchable selector - get all users (admin and guest included)
|
||||
//user must be confirmed, not deleted, not suspended, not guest
|
||||
$sql = "SELECT u.id, u.firstname, u.lastname
|
||||
FROM {user} u
|
||||
WHERE u.deleted = 0 AND u.confirmed = 1 AND u.suspended = 0 AND u.id != :siteguestid
|
||||
ORDER BY $sort";
|
||||
// User searchable selector - return users who are confirmed, not deleted, not suspended and not a guest.
|
||||
$sql = 'SELECT u.id, ' . get_all_user_name_fields(true, 'u') . '
|
||||
FROM {user} u
|
||||
WHERE u.deleted = 0
|
||||
AND u.confirmed = 1
|
||||
AND u.suspended = 0
|
||||
AND u.id != :siteguestid
|
||||
ORDER BY ' . $sort;
|
||||
$params['siteguestid'] = $CFG->siteguest;
|
||||
$users = $DB->get_records_sql($sql, $params);
|
||||
$options = array();
|
||||
|
||||
@@ -49,5 +49,8 @@ function xmldb_auth_cas_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2013091700, 'auth', 'cas');
|
||||
}
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -616,7 +616,6 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
if ($user->firstaccess == 0) {
|
||||
$user->firstaccess = time();
|
||||
}
|
||||
require_once($CFG->dirroot.'/user/lib.php');
|
||||
user_update_user($user, false);
|
||||
return AUTH_CONFIRM_OK;
|
||||
}
|
||||
|
||||
@@ -39,5 +39,8 @@ function xmldb_auth_ldap_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2013052100, 'auth', 'ldap');
|
||||
}
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_manual_upgrade($oldversion) {
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -941,7 +941,6 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
// run the keepalive client
|
||||
$this->keepalive_client();
|
||||
|
||||
// admin/cron.php should have run srand for us
|
||||
$random100 = rand(0,100);
|
||||
if ($random100 < 10) { // Approximately 10% of the time.
|
||||
// nuke olden sessions
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_auth_mnet_upgrade($oldversion) {
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ abstract class backup implements checksumable {
|
||||
const OPERATION_RESTORE ='restore';// We are performing one restore
|
||||
|
||||
// Version (to keep CFG->backup_version (and release) updated automatically)
|
||||
const VERSION = 2013110500;
|
||||
const VERSION = 2013111800;
|
||||
const RELEASE = '2.6';
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,13 @@ if ($backup->get_stage() == backup_ui::STAGE_FINAL) {
|
||||
// Carry out actual backup.
|
||||
$backup->execute();
|
||||
|
||||
// Backup controller gets saved/loaded so the logger object changes and we
|
||||
// have to retrieve it.
|
||||
$logger = $backup->get_controller()->get_logger();
|
||||
while (!is_a($logger, 'core_backup_html_logger')) {
|
||||
$logger = $logger->get_next();
|
||||
}
|
||||
|
||||
// Get HTML from logger.
|
||||
$loghtml = $logger->get_html();
|
||||
|
||||
|
||||
@@ -309,7 +309,6 @@ class entities {
|
||||
$source = str_split($source, 1);
|
||||
|
||||
for ($i = 1; $i <= $length; $i++) {
|
||||
mt_srand((double) microtime() * 1000000);
|
||||
$num = mt_rand(1, count($source));
|
||||
$response .= $source[$num - 1];
|
||||
}
|
||||
|
||||
@@ -131,20 +131,38 @@ class backup_course_task extends backup_task {
|
||||
/**
|
||||
* Code the transformations to perform in the course in
|
||||
* order to get transportable (encoded) links
|
||||
* @param string $content content in which to encode links.
|
||||
* @return string content with links encoded.
|
||||
*/
|
||||
static public function encode_content_links($content) {
|
||||
global $CFG;
|
||||
|
||||
$base = preg_quote($CFG->wwwroot, '/');
|
||||
|
||||
// Link to the course main page (it also covers "&topic=xx" and "&week=xx"
|
||||
// because they don't become transformed (section number) in backup/restore
|
||||
$search = '/(' . $base . '\/course\/view.php\?id\=)([0-9]+)/';
|
||||
$content= preg_replace($search, '$@COURSEVIEWBYID*$2@$', $content);
|
||||
// because they don't become transformed (section number) in backup/restore.
|
||||
$content = self::encode_links_helper($content, 'COURSEVIEWBYID', '/course/view.php?id=');
|
||||
|
||||
// A few other key course links.
|
||||
$content = self::encode_links_helper($content, 'GRADEINDEXBYID', '/grade/index.php?id=');
|
||||
$content = self::encode_links_helper($content, 'GRADEREPORTINDEXBYID', '/grade/report/index.php?id=');
|
||||
$content = self::encode_links_helper($content, 'BADGESVIEWBYID', '/badges/view.php?type=2&id=');
|
||||
$content = self::encode_links_helper($content, 'USERINDEXVIEWBYID', '/user/index.php?id=');
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method, used by encode_content_links.
|
||||
* @param string $content content in which to encode links.
|
||||
* @param unknown_type $name the name of this type of encoded link.
|
||||
* @param unknown_type $path the path that identifies this type of link, up
|
||||
* to the ?paramname= bit.
|
||||
* @return string content with one type of link encoded.
|
||||
*/
|
||||
static private function encode_links_helper($content, $name, $path) {
|
||||
global $CFG;
|
||||
$base = preg_quote($CFG->wwwroot . $path, '/');
|
||||
return preg_replace('/(' . $base . ')([0-9]+)/', '$@' . $name . '*$2@$', $content);
|
||||
}
|
||||
|
||||
// Protected API starts here
|
||||
|
||||
/**
|
||||
|
||||
@@ -107,7 +107,19 @@ class file_nested_element extends backup_nested_element {
|
||||
backup_file_manager::copy_file_moodle2backup($this->backupid, $values);
|
||||
} catch (file_exception $e) {
|
||||
$this->add_result(array('missing_files_in_pool' => true));
|
||||
$this->add_log('missing file in pool: ' . $e->debuginfo, backup::LOG_WARNING);
|
||||
|
||||
// Build helpful log message with all information necessary to identify
|
||||
// file location.
|
||||
$context = context::instance_by_id($values->contextid, IGNORE_MISSING);
|
||||
$contextname = '';
|
||||
if ($context) {
|
||||
$contextname = ' \'' . $context->get_context_name() . '\'';
|
||||
}
|
||||
$message = 'Missing file in pool: ' . $values->filepath . $values->filename .
|
||||
' (context ' . $values->contextid . $contextname . ', component ' .
|
||||
$values->component . ', filearea ' . $values->filearea . ', itemid ' .
|
||||
$values->itemid . ') [' . $e->debuginfo . ']';
|
||||
$this->add_log($message, backup::LOG_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,10 +135,17 @@ class restore_course_task extends restore_task {
|
||||
static public function define_decode_rules() {
|
||||
$rules = array();
|
||||
|
||||
$rules[] = new restore_decode_rule('COURSEVIEWBYID', '/course/view.php?id=$1', 'course');
|
||||
// Link to the course main page (it also covers "&topic=xx" and "&week=xx"
|
||||
// because they don't become transformed (section number) in backup/restore.
|
||||
$rules[] = new restore_decode_rule('COURSEVIEWBYID', '/course/view.php?id=$1', 'course');
|
||||
|
||||
// A few other key course links.
|
||||
$rules[] = new restore_decode_rule('GRADEINDEXBYID', '/grade/index.php?id=$1', 'course');
|
||||
$rules[] = new restore_decode_rule('GRADEREPORTINDEXBYID', '/grade/report/index.php?id=$1', 'course');
|
||||
$rules[] = new restore_decode_rule('BADGESVIEWBYID', '/badges/view.php?type=2&id=$1', 'course');
|
||||
$rules[] = new restore_decode_rule('USERINDEXVIEWBYID', '/user/index.php?id=$1', 'course');
|
||||
|
||||
return $rules;
|
||||
|
||||
}
|
||||
|
||||
// Protected API starts here
|
||||
|
||||
@@ -995,11 +995,7 @@ abstract class restore_dbops {
|
||||
if ($includesfiles) {
|
||||
// The file is not found in the backup.
|
||||
if (!file_exists($backuppath)) {
|
||||
$result = new stdClass();
|
||||
$result->code = 'file_missing_in_backup';
|
||||
$result->message = sprintf('missing file %s%s in backup', $file->filepath, $file->filename);
|
||||
$result->level = backup::LOG_WARNING;
|
||||
$results[] = $result;
|
||||
$results[] = self::get_missing_file_result($file);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1028,11 +1024,7 @@ abstract class restore_dbops {
|
||||
$fs->create_file_from_storedfile($file_record, $foundfile->id);
|
||||
} else {
|
||||
// A matching existing file record was not found in the database.
|
||||
$result = new stdClass();
|
||||
$result->code = 'file_missing_in_backup';
|
||||
$result->message = sprintf('missing file %s%s in backup', $file->filepath, $file->filename);
|
||||
$result->level = backup::LOG_WARNING;
|
||||
$results[] = $result;
|
||||
$results[] = self::get_missing_file_result($file);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1063,6 +1055,22 @@ abstract class restore_dbops {
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns suitable entry to include in log when there is a missing file.
|
||||
*
|
||||
* @param stdClass $file File definition
|
||||
* @return stdClass Log entry
|
||||
*/
|
||||
protected static function get_missing_file_result($file) {
|
||||
$result = new stdClass();
|
||||
$result->code = 'file_missing_in_backup';
|
||||
$result->message = 'Missing file in backup: ' . $file->filepath . $file->filename .
|
||||
' (old context ' . $file->contextid . ', component ' . $file->component .
|
||||
', filearea ' . $file->filearea . ', old itemid ' . $file->itemid . ')';
|
||||
$result->level = backup::LOG_WARNING;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one restoreid, create in DB all the users present
|
||||
* in backup_ids having newitemid = 0, as far as
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* @package core_backup
|
||||
* @category phpunit
|
||||
* @copyright 2013 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||
require_once($CFG->dirroot . '/backup/moodle2/backup_course_task.class.php');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tests for encoding content links in backup_course_task.
|
||||
*
|
||||
* The code that this tests is acutally in backup/moodle2/backup_course_task.class.php,
|
||||
* but there is no place for unit tests near there, and perhaps one day it will
|
||||
* be refactored so it becomes more generic.
|
||||
*/
|
||||
class backup_course_task_testcase extends basic_testcase {
|
||||
|
||||
/**
|
||||
* Test the encode_content_links method for course.
|
||||
*/
|
||||
public function test_course_encode_content_links() {
|
||||
global $CFG;
|
||||
$encoded = backup_course_task::encode_content_links(
|
||||
$CFG->wwwroot . '/course/view.php?id=123, ' .
|
||||
$CFG->wwwroot . '/grade/index.php?id=123, ' .
|
||||
$CFG->wwwroot . '/grade/report/index.php?id=123, ' .
|
||||
$CFG->wwwroot . '/badges/view.php?type=2&id=123 and ' .
|
||||
$CFG->wwwroot . '/user/index.php?id=123.');
|
||||
$this->assertEquals('$@COURSEVIEWBYID*123@$, $@GRADEINDEXBYID*123@$, ' .
|
||||
'$@GRADEREPORTINDEXBYID*123@$, $@BADGESVIEWBYID*123@$ and $@USERINDEXVIEWBYID*123@$.', $encoded);
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,6 @@ abstract class core_backup_progress {
|
||||
$this->currents[] = 0;
|
||||
$this->parentcounts[] = $parentcount;
|
||||
$this->update_progress();
|
||||
$lastprogresstime = $this->get_time();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -73,6 +73,14 @@ abstract class base_moodleform extends moodleform {
|
||||
*/
|
||||
function __construct(base_ui_stage $uistage, $action=null, $customdata=null, $method='post', $target='', $attributes=null, $editable=true) {
|
||||
$this->uistage = $uistage;
|
||||
// Add a class to the attributes to prevent the default collapsible behaviour.
|
||||
if (!$attributes) {
|
||||
$attributes = array();
|
||||
}
|
||||
$attributes['class'] = 'unresponsive';
|
||||
if (!isset($attributes['enctype'])) {
|
||||
$attributes['enctype'] = 'application/x-www-form-urlencoded'; // Enforce compatibility with our max_input_vars hack.
|
||||
}
|
||||
parent::__construct($action, $customdata, $method, $target, $attributes, $editable);
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -846,6 +846,7 @@ class restore_ui_stage_process extends restore_ui_stage {
|
||||
$html .= html_writer::start_tag('form', array(
|
||||
'action' => $url->out_omit_querystring(),
|
||||
'class' => 'backup-restore',
|
||||
'enctype' => 'application/x-www-form-urlencoded', // Enforce compatibility with our max_input_vars hack.
|
||||
'method' => 'post'));
|
||||
foreach ($url->params() as $name => $value) {
|
||||
$html .= html_writer::empty_tag('input', array(
|
||||
|
||||
@@ -38,7 +38,7 @@ Feature: Backup Moodle courses
|
||||
And I press "Continue"
|
||||
And I click on "Continue" "button" in the ".bcs-current-course" "css_element"
|
||||
And "//div[contains(concat(' ', normalize-space(@class), ' '), ' fitem ')][contains(., 'Include calendar events')]/descendant::img" "xpath_element" should exists
|
||||
And I check "Include course logs"
|
||||
And "Include course logs" "checkbox" should exists
|
||||
And I press "Next"
|
||||
|
||||
@javascript
|
||||
|
||||
@@ -56,27 +56,32 @@ class behat_backup extends behat_base {
|
||||
|
||||
// Go to homepage.
|
||||
$this->getSession()->visit($this->locate_path('/'));
|
||||
$this->wait();
|
||||
|
||||
// Click the course link.
|
||||
$this->find_link($backupcourse)->click();
|
||||
$this->wait();
|
||||
|
||||
// Click the backup link.
|
||||
$this->find_link(get_string('backup'))->click();
|
||||
$this->wait();
|
||||
|
||||
// Initial settings.
|
||||
$this->fill_backup_restore_form($options);
|
||||
$this->find_button(get_string('backupstage1action', 'backup'))->press();
|
||||
$this->wait();
|
||||
|
||||
// Schema settings.
|
||||
$this->fill_backup_restore_form($options);
|
||||
$this->find_button(get_string('backupstage2action', 'backup'))->press();
|
||||
$this->wait();
|
||||
|
||||
// Confirmation and review, backup filename can also be specified.
|
||||
$this->fill_backup_restore_form($options);
|
||||
$this->find_button(get_string('backupstage4action', 'backup'))->press();
|
||||
|
||||
// Waiting for it to finish.
|
||||
$this->wait(10);
|
||||
$this->wait(self::EXTENDED_TIMEOUT);
|
||||
|
||||
// Last backup continue button.
|
||||
$this->find_button(get_string('backupstage16action', 'backup'))->press();
|
||||
@@ -101,12 +106,15 @@ class behat_backup extends behat_base {
|
||||
|
||||
// Go to homepage.
|
||||
$this->getSession()->visit($this->locate_path('/'));
|
||||
$this->wait();
|
||||
|
||||
// Click the course link.
|
||||
$this->find_link($tocourse)->click();
|
||||
$this->wait();
|
||||
|
||||
// Click the import link.
|
||||
$this->find_link(get_string('import'))->click();
|
||||
$this->wait();
|
||||
|
||||
// Select the course.
|
||||
$exception = new ExpectationException('"' . $fromcourse . '" course not found in the list of courses to import from', $this->getSession());
|
||||
@@ -121,18 +129,21 @@ class behat_backup extends behat_base {
|
||||
$radionode->click();
|
||||
|
||||
$this->find_button(get_string('continue'))->press();
|
||||
$this->wait();
|
||||
|
||||
// Initial settings.
|
||||
$this->fill_backup_restore_form($options);
|
||||
$this->find_button(get_string('importbackupstage1action', 'backup'))->press();
|
||||
$this->wait();
|
||||
|
||||
// Schema settings.
|
||||
$this->fill_backup_restore_form($options);
|
||||
$this->find_button(get_string('importbackupstage2action', 'backup'))->press();
|
||||
$this->wait();
|
||||
|
||||
// Run it.
|
||||
$this->find_button(get_string('importbackupstage4action', 'backup'))->press();
|
||||
$this->wait();
|
||||
$this->wait(self::EXTENDED_TIMEOUT);
|
||||
|
||||
// Continue and redirect to 'to' course.
|
||||
$this->find_button(get_string('continue'))->press();
|
||||
@@ -294,17 +305,22 @@ class behat_backup extends behat_base {
|
||||
// Settings.
|
||||
$this->fill_backup_restore_form($options);
|
||||
$this->find_button(get_string('restorestage4action', 'backup'))->press();
|
||||
$this->wait();
|
||||
|
||||
// Schema.
|
||||
$this->fill_backup_restore_form($options);
|
||||
$this->find_button(get_string('restorestage8action', 'backup'))->press();
|
||||
$this->wait();
|
||||
|
||||
// Review, no options here.
|
||||
$this->find_button(get_string('restorestage16action', 'backup'))->press();
|
||||
$this->wait(10);
|
||||
$this->wait();
|
||||
|
||||
// Last restore continue button, redirected to restore course after this.
|
||||
$this->find_button(get_string('restorestage32action', 'backup'))->press();
|
||||
|
||||
// Long wait when waiting for the restore to finish.
|
||||
$this->wait(self::EXTENDED_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,11 +341,15 @@ class behat_backup extends behat_base {
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for the page to be loaded and the JS ready.
|
||||
$this->wait();
|
||||
|
||||
// If we find any of the provided options in the current form we should set the value.
|
||||
$datahash = $options->getRowsHash();
|
||||
foreach ($datahash as $locator => $value) {
|
||||
|
||||
try {
|
||||
// Using $this->find* to enforce stability over speed.
|
||||
$fieldnode = $this->find_field($locator);
|
||||
$field = behat_field_manager::get_form_field($fieldnode, $this->getSession());
|
||||
$field->set_value($value);
|
||||
@@ -341,9 +361,9 @@ class behat_backup extends behat_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the DOM is ready.
|
||||
* Waits until the DOM and the page Javascript code is ready.
|
||||
*
|
||||
* @param int To override the default timeout
|
||||
* @param int $timeout The number of seconds that we wait.
|
||||
* @return void
|
||||
*/
|
||||
protected function wait($timeout = false) {
|
||||
@@ -355,7 +375,8 @@ class behat_backup extends behat_base {
|
||||
if (!$timeout) {
|
||||
$timeout = self::TIMEOUT;
|
||||
}
|
||||
$this->getSession()->wait($timeout, '(document.readyState === "complete")');
|
||||
|
||||
$this->getSession()->wait($timeout * 1000, self::PAGE_READY_JS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ Feature: Duplicate activities
|
||||
And I add a "Database" to section "1" and I fill the form with:
|
||||
| Name | Test database name |
|
||||
| Description | Test database description |
|
||||
And I open "Test database name" actions menu
|
||||
When I click on "Duplicate" "link" in the "Test database name" activity
|
||||
And I duplicate "Test database name" activity
|
||||
And I wait until section "1" is available
|
||||
And I open "Test database name" actions menu
|
||||
And I click on "Edit settings" "link" in the "Test database name" activity
|
||||
And I fill the moodle form with:
|
||||
|
||||
+1
-1
@@ -109,7 +109,7 @@ if (count($acceptedroles) > 1) {
|
||||
$pageurl = new moodle_url('/badges/award.php', array('id' => $badgeid));
|
||||
$issuerrole = new stdClass();
|
||||
$issuerrole->roleid = $role;
|
||||
$roleselect = get_string('selectaward', 'badges') . $OUTPUT->single_select(new moodle_url($pageurl), 'role', $select, $role);
|
||||
$roleselect = get_string('selectaward', 'badges') . $OUTPUT->single_select(new moodle_url($pageurl), 'role', $select, $role, null);
|
||||
}
|
||||
} else {
|
||||
echo $OUTPUT->header();
|
||||
|
||||
@@ -36,7 +36,7 @@ Feature: Add badges to the system
|
||||
| Description | Test badge description |
|
||||
| issuername | Test Badge Site |
|
||||
| issuercontact | testuser@test-badge-site.com |
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filepicker
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filemanager
|
||||
When I press "Create badge"
|
||||
Then I should see "Edit details"
|
||||
And I should see "Test Badge"
|
||||
|
||||
@@ -4,13 +4,10 @@ Feature: Award badges
|
||||
As an admin
|
||||
I need to add criteria to badges in the system
|
||||
|
||||
Background:
|
||||
Given I am on homepage
|
||||
And I log in as "admin"
|
||||
|
||||
@javascript
|
||||
Scenario: Award profile badge
|
||||
Given I expand "Site administration" node
|
||||
Given I log in as "admin"
|
||||
And I expand "Site administration" node
|
||||
And I expand "Badges" node
|
||||
And I follow "Add a new badge"
|
||||
And I fill the moodle form with:
|
||||
@@ -18,7 +15,7 @@ Feature: Award badges
|
||||
| Description | Test badge description |
|
||||
| issuername | Test Badge Site |
|
||||
| issuercontact | testuser@test-badge-site.com |
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filepicker
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filemanager
|
||||
And I press "Create badge"
|
||||
And I select "Profile completion" from "type"
|
||||
And I check "First name"
|
||||
@@ -46,6 +43,7 @@ Feature: Award badges
|
||||
| username | firstname | lastname | email |
|
||||
| teacher | teacher | 1 | teacher1@asd.com |
|
||||
| student | student | 1 | student1@asd.com |
|
||||
And I log in as "admin"
|
||||
And I expand "Site administration" node
|
||||
And I expand "Badges" node
|
||||
And I follow "Add a new badge"
|
||||
@@ -53,7 +51,7 @@ Feature: Award badges
|
||||
| Name | Site Badge |
|
||||
| Description | Site badge description |
|
||||
| issuername | Tester of site badge |
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filepicker
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filemanager
|
||||
And I press "Create badge"
|
||||
And I select "Manual issue by role" from "type"
|
||||
And I check "Teacher"
|
||||
@@ -89,7 +87,6 @@ Feature: Award badges
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
| student2 | C1 | student |
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I click on "//span[text()='Badges']" "xpath_element" in the "Administration" "block"
|
||||
@@ -98,7 +95,7 @@ Feature: Award badges
|
||||
| Name | Course Badge |
|
||||
| Description | Course badge description |
|
||||
| issuername | Tester of course badge |
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filepicker
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filemanager
|
||||
And I press "Create badge"
|
||||
And I select "Manual issue by role" from "type"
|
||||
And I check "Teacher"
|
||||
@@ -133,7 +130,6 @@ Feature: Award badges
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And I log out
|
||||
And I log in as "admin"
|
||||
And I set the following administration settings values:
|
||||
| Enable completion tracking | 1 |
|
||||
@@ -156,7 +152,7 @@ Feature: Award badges
|
||||
| Name | Course Badge |
|
||||
| Description | Course badge description |
|
||||
| issuername | Tester of course badge |
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filepicker
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filemanager
|
||||
And I press "Create badge"
|
||||
And I select "Activity completion" from "type"
|
||||
And I check "Test assignment name"
|
||||
@@ -172,7 +168,6 @@ Feature: Award badges
|
||||
And I follow "Home"
|
||||
And I follow "Course 1"
|
||||
And I press "Mark as complete: Test assignment name"
|
||||
And I wait "2" seconds
|
||||
And I expand "My profile" node
|
||||
And I follow "My badges"
|
||||
Then I should see "Course Badge"
|
||||
@@ -190,7 +185,6 @@ Feature: Award badges
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And I log out
|
||||
And I log in as "admin"
|
||||
And I set the following administration settings values:
|
||||
| Enable completion tracking | 1 |
|
||||
@@ -219,7 +213,7 @@ Feature: Award badges
|
||||
| Name | Course Badge |
|
||||
| Description | Course badge description |
|
||||
| issuername | Tester of course badge |
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filepicker
|
||||
And I upload "badges/tests/behat/badge.png" file to "Image" filemanager
|
||||
And I press "Create badge"
|
||||
And I select "Course completion" from "type"
|
||||
And I fill the moodle form with:
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
@block @block_activity_modules @_only_local
|
||||
Feature: Block activity modules
|
||||
In order to overview activity modules in a course
|
||||
As a manager
|
||||
I can add activities block in a course or on the frontpage
|
||||
|
||||
Background:
|
||||
Given I log in as "admin"
|
||||
And I expand "Site administration" node
|
||||
And I expand "Plugins" node
|
||||
And I expand "Activity modules" node
|
||||
And I follow "Manage activities"
|
||||
And I click on "//a[@title=\"Show\"]" "xpath_element" in the "Feedback" "table_row"
|
||||
And I click on "//a[@title=\"Show\"]" "xpath_element" in the "Assignment (2.2)" "table_row"
|
||||
|
||||
Scenario: Add activities block on the frontpage
|
||||
And the following "activities" exists:
|
||||
| activity | name | intro | course | idnumber |
|
||||
| assign | Frontpage assignment name | Frontpage assignment description | Acceptance test site | assign0 |
|
||||
| assignment | Frontpage assignment22 name | Frontpage assignment22 description | Acceptance test site | assignment0 |
|
||||
| book | Frontpage book name | Frontpage book description | Acceptance test site | book0 |
|
||||
| chat | Frontpage chat name | Frontpage chat description | Acceptance test site | chat0 |
|
||||
| choice | Frontpage choice name | Frontpage choice description | Acceptance test site | choice0 |
|
||||
| data | Frontpage database name | Frontpage database description | Acceptance test site | data0 |
|
||||
| feedback | Frontpage feedback name | Frontpage feedback description | Acceptance test site | feedback0 |
|
||||
| forum | Frontpage forum name | Frontpage forum description | Acceptance test site | forum0 |
|
||||
| label | Frontpage label name | Frontpage label description | Acceptance test site | label0 |
|
||||
| lti | Frontpage lti name | Frontpage lti description | Acceptance test site | lti0 |
|
||||
| page | Frontpage page name | Frontpage page description | Acceptance test site | page0 |
|
||||
| quiz | Frontpage quiz name | Frontpage quiz description | Acceptance test site | quiz0 |
|
||||
| resource | Frontpage resource name | Frontpage resource description | Acceptance test site | resource0 |
|
||||
| imscp | Frontpage imscp name | Frontpage imscp description | Acceptance test site | imscp0 |
|
||||
| folder | Frontpage folder name | Frontpage folder description | Acceptance test site | folder0 |
|
||||
| glossary | Frontpage glossary name | Frontpage glossary description | Acceptance test site | glossary0 |
|
||||
| scorm | Frontpage scorm name | Frontpage scorm description | Acceptance test site | scorm0 |
|
||||
| lesson | Frontpage lesson name | Frontpage lesson description | Acceptance test site | lesson0 |
|
||||
| survey | Frontpage survey name | Frontpage survey description | Acceptance test site | survey0 |
|
||||
| url | Frontpage url name | Frontpage url description | Acceptance test site | url0 |
|
||||
| wiki | Frontpage wiki name | Frontpage wiki description | Acceptance test site | wiki0 |
|
||||
| workshop | Frontpage workshop name | Frontpage workshop description | Acceptance test site | workshop0 |
|
||||
|
||||
And I am on homepage
|
||||
When I follow "Turn editing on"
|
||||
And I add the "Activities" block
|
||||
And I click on "Assignments" "link" in the "Activities" "block"
|
||||
Then I should see "Frontpage assignment name"
|
||||
And I am on homepage
|
||||
And I click on "Assignments (2.2)" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage assignment22 name"
|
||||
And I am on homepage
|
||||
And I click on "Chats" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage chat name"
|
||||
And I am on homepage
|
||||
And I click on "Choices" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage choice name"
|
||||
And I am on homepage
|
||||
And I click on "Databases" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage database name"
|
||||
And I am on homepage
|
||||
And I click on "Feedback" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage feedback name"
|
||||
And I am on homepage
|
||||
And I click on "Forums" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage forum name"
|
||||
And I am on homepage
|
||||
And I click on "External Tools" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage lti name"
|
||||
And I am on homepage
|
||||
And I click on "Quizzes" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage quiz name"
|
||||
And I am on homepage
|
||||
And I click on "Glossaries" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage glossary name"
|
||||
And I am on homepage
|
||||
And I click on "SCORM packages" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage scorm name"
|
||||
And I am on homepage
|
||||
And I click on "Lessons" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage lesson name"
|
||||
And I am on homepage
|
||||
And I click on "Wikis" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage wiki name"
|
||||
And I am on homepage
|
||||
And I click on "Workshop" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage workshop name"
|
||||
And I am on homepage
|
||||
And I click on "Resources" "link" in the "Activities" "block"
|
||||
And I should see "Frontpage book name"
|
||||
And I should see "Frontpage page name"
|
||||
And I should see "Frontpage resource name"
|
||||
And I should see "Frontpage imscp name"
|
||||
And I should see "Frontpage folder name"
|
||||
And I should see "Frontpage url name"
|
||||
|
||||
Scenario: Add activities block in a course
|
||||
Given the following "courses" exists:
|
||||
| fullname | shortname | format |
|
||||
| Course 1 | C1 | topics |
|
||||
And the following "activities" exists:
|
||||
| activity | name | intro | course | idnumber |
|
||||
| assign | Test assignment name | Test assignment description | C1 | assign1 |
|
||||
| assignment | Test assignment22 name | Test assignment22 description | C1 | assignment1 |
|
||||
| book | Test book name | Test book description | C1 | book1 |
|
||||
| chat | Test chat name | Test chat description | C1 | chat1 |
|
||||
| choice | Test choice name | Test choice description | C1 | choice1 |
|
||||
| data | Test database name | Test database description | C1 | data1 |
|
||||
| feedback | Test feedback name | Test feedback description | C1 | feedback1 |
|
||||
| folder | Test folder name | Test folder description | C1 | folder1 |
|
||||
| forum | Test forum name | Test forum description | C1 | forum1 |
|
||||
| glossary | Test glossary name | Test glossary description | C1 | glossary1 |
|
||||
| imscp | Test imscp name | Test imscp description | C1 | imscp1 |
|
||||
| label | Test label name | Test label description | C1 | label1 |
|
||||
| lesson | Test lesson name | Test lesson description | C1 | lesson1 |
|
||||
| lti | Test lti name | Test lti description | C1 | lti1 |
|
||||
| page | Test page name | Test page description | C1 | page1 |
|
||||
| quiz | Test quiz name | Test quiz description | C1 | quiz1 |
|
||||
| resource | Test resource name | Test resource description | C1 | resource1 |
|
||||
| scorm | Test scorm name | Test scorm description | C1 | scorm1 |
|
||||
| survey | Test survey name | Test survey description | C1 | survey1 |
|
||||
| url | Test url name | Test url description | C1 | url1 |
|
||||
| wiki | Test wiki name | Test wiki description | C1 | wiki1 |
|
||||
| workshop | Test workshop name | Test workshop description | C1 | workshop1 |
|
||||
|
||||
When I follow "Courses"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add the "Activities" block
|
||||
And I click on "Assignments" "link" in the "Activities" "block"
|
||||
Then I should see "Test assignment name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Assignments (2.2)" "link" in the "Activities" "block"
|
||||
And I should see "Test assignment22 name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Chats" "link" in the "Activities" "block"
|
||||
And I should see "Test chat name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Choices" "link" in the "Activities" "block"
|
||||
And I should see "Test choice name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Databases" "link" in the "Activities" "block"
|
||||
And I should see "Test database name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Feedback" "link" in the "Activities" "block"
|
||||
And I should see "Test feedback name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Forums" "link" in the "Activities" "block"
|
||||
And I should see "Test forum name"
|
||||
And I follow "Course 1"
|
||||
And I click on "External Tools" "link" in the "Activities" "block"
|
||||
And I should see "Test lti name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Quizzes" "link" in the "Activities" "block"
|
||||
And I should see "Test quiz name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Glossaries" "link" in the "Activities" "block"
|
||||
And I should see "Test glossary name"
|
||||
And I follow "Course 1"
|
||||
And I click on "SCORM packages" "link" in the "Activities" "block"
|
||||
And I should see "Test scorm name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Lessons" "link" in the "Activities" "block"
|
||||
And I should see "Test lesson name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Wikis" "link" in the "Activities" "block"
|
||||
And I should see "Test wiki name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Workshop" "link" in the "Activities" "block"
|
||||
And I should see "Test workshop name"
|
||||
And I follow "Course 1"
|
||||
And I click on "Resources" "link" in the "Activities" "block"
|
||||
And I should see "Test book name"
|
||||
And I should see "Test page name"
|
||||
And I should see "Test resource name"
|
||||
And I should see "Test imscp name"
|
||||
And I should see "Test folder name"
|
||||
And I should see "Test url name"
|
||||
@@ -107,7 +107,7 @@ class block_admin_bookmarks extends block_base {
|
||||
|
||||
$this->content->footer = '';
|
||||
$this->page->settingsnav->initialise();
|
||||
$node = $this->page->settingsnav->get('root', navigation_node::TYPE_SETTING);
|
||||
$node = $this->page->settingsnav->get('root', navigation_node::TYPE_SITE_ADMIN);
|
||||
if (!$node || !$node->contains_active_node()) {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ class block_blog_recent extends block_base {
|
||||
|
||||
$this->content = new stdClass();
|
||||
$this->content->footer = '';
|
||||
$this->content->text = '';
|
||||
|
||||
$context = $this->page->context;
|
||||
|
||||
|
||||
@@ -65,9 +65,6 @@ class behat_block_comments extends behat_base {
|
||||
|
||||
$this->find_link(get_string('savecomment'))->click();
|
||||
|
||||
// Wait for the AJAX request.
|
||||
$this->getSession()->wait(4 * 1000, false);
|
||||
|
||||
} else {
|
||||
|
||||
$commentstextarea = $this->find('css', '.block_comments form textarea', $exception);
|
||||
@@ -103,7 +100,7 @@ class behat_block_comments extends behat_base {
|
||||
$deleteicon = $this->find('css', '.comment-delete a img', $deleteexception, $commentnode);
|
||||
$deleteicon->click();
|
||||
|
||||
// Wait for the AJAX request.
|
||||
// Wait for the animation to finish, in theory is just 1 sec, adding 4 just in case.
|
||||
$this->getSession()->wait(4 * 1000, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,5 +58,8 @@ function xmldb_block_community_upgrade($oldversion) {
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -64,5 +64,8 @@ function xmldb_block_completionstatus_upgrade($oldversion, $block) {
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -35,7 +35,14 @@ class block_course_list extends block_list {
|
||||
|
||||
if (empty($CFG->disablemycourses) and isloggedin() and !isguestuser() and
|
||||
!(has_capability('moodle/course:update', context_system::instance()) and $adminseesall)) { // Just print My Courses
|
||||
if ($courses = enrol_get_my_courses(NULL, 'visible DESC, fullname ASC')) {
|
||||
// As this is producing navigation sort order should default to $CFG->navsortmycoursessort instead
|
||||
// of using the default.
|
||||
if (!empty($CFG->navsortmycoursessort)) {
|
||||
$sortorder = 'visible DESC, ' . $CFG->navsortmycoursessort . ' ASC';
|
||||
} else {
|
||||
$sortorder = 'visible DESC, sortorder ASC';
|
||||
}
|
||||
if ($courses = enrol_get_my_courses(NULL, $sortorder)) {
|
||||
foreach ($courses as $course) {
|
||||
$coursecontext = context_course::instance($course->id);
|
||||
$linkcss = $course->visible ? "" : " class=\"dimmed\" ";
|
||||
@@ -121,8 +128,7 @@ class block_course_list extends block_list {
|
||||
$this->content->items[] = get_string('remotecourses','mnet');
|
||||
$this->content->icons[] = '';
|
||||
foreach ($courses as $course) {
|
||||
$coursecontext = context_course::instance($course->id);
|
||||
$this->content->items[]="<a title=\"" . format_string($course->shortname, true, array('context' => $coursecontext)) . "\" ".
|
||||
$this->content->items[]="<a title=\"" . format_string($course->shortname, true) . "\" ".
|
||||
"href=\"{$CFG->wwwroot}/auth/mnet/jump.php?hostid={$course->hostid}&wantsurl=/course/view.php?id={$course->remoteid}\">"
|
||||
.$icon. format_string(get_course_display_name_for_list($course)) . "</a>";
|
||||
}
|
||||
|
||||
@@ -69,5 +69,8 @@ function xmldb_block_course_summary_upgrade($oldversion, $block) {
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -44,5 +44,8 @@ function xmldb_block_html_upgrade($oldversion) {
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -70,5 +70,8 @@ function xmldb_block_navigation_upgrade($oldversion, $block) {
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -58,14 +58,11 @@ Feature: View my courses in navigation block
|
||||
And I should see "cat3" in the "Navigation" "block"
|
||||
And I should not see "cat2" in the "Navigation" "block"
|
||||
And I expand "cat3" node
|
||||
And I wait "2" seconds
|
||||
And I should see "cat31" in the "Navigation" "block"
|
||||
And I should see "cat33" in the "Navigation" "block"
|
||||
And I should not see "cat32" in the "Navigation" "block"
|
||||
And I expand "cat31" node
|
||||
And I wait "2" seconds
|
||||
And I should see "c31" in the "Navigation" "block"
|
||||
And I expand "cat33" node
|
||||
And I wait "2" seconds
|
||||
And I should see "c331" in the "Navigation" "block"
|
||||
And I should not see "c332" in the "Navigation" "block"
|
||||
|
||||
+26
-4
@@ -404,6 +404,15 @@ Y.extend(TREE, Y.Base, TREE.prototype, {
|
||||
}
|
||||
return val;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The navigation tree block instance.
|
||||
*/
|
||||
instance : {
|
||||
value : false,
|
||||
setter : function(val) {
|
||||
return parseInt(val, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -583,7 +592,7 @@ BRANCH.prototype = {
|
||||
} else {
|
||||
e.stopPropagation();
|
||||
}
|
||||
if (e.type === 'actionkey' && e.action === 'enter' && e.target.test('A')) {
|
||||
if ((e.type === 'actionkey' && e.action === 'enter') || e.target.test('a')) {
|
||||
// No ajaxLoad for enter.
|
||||
this.node.setAttribute('data-expandable', '0');
|
||||
this.node.setAttribute('data-loaded', '1');
|
||||
@@ -640,6 +649,12 @@ BRANCH.prototype = {
|
||||
this.node.setAttribute('data-loaded', '1');
|
||||
try {
|
||||
var object = Y.JSON.parse(outcome.responseText);
|
||||
if (object.error) {
|
||||
Y.use('moodle-core-notification-ajaxexception', function () {
|
||||
return new M.core.ajaxException(object).show();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (object.children && object.children.length > 0) {
|
||||
var coursecount = 0;
|
||||
for (var i in object.children) {
|
||||
@@ -663,9 +678,16 @@ BRANCH.prototype = {
|
||||
return true;
|
||||
}
|
||||
Y.log('AJAX loading complete but there were no children.', 'note', 'moodle-block_navigation');
|
||||
} catch (ex) {
|
||||
// If we got here then there was an error parsing the result.
|
||||
Y.log('Error parsing AJAX response or adding branches to the navigation tree', 'error', 'moodle-block_navigation');
|
||||
} catch (error) {
|
||||
if (outcome && outcome.status && outcome.status > 0) {
|
||||
// If we got here then there was an error parsing the result.
|
||||
Y.log('Error parsing AJAX response or adding branches to the navigation tree', 'error', 'moodle-block_navigation');
|
||||
Y.use('moodle-core-notification-exception', function () {
|
||||
return new M.core.exception(error).show();
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
// The branch is empty so class it accordingly
|
||||
this.node.replaceClass('branch', 'emptybranch');
|
||||
|
||||
+2
-2
File diff suppressed because one or more lines are too long
blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js
Vendored
+25
-3
@@ -403,6 +403,15 @@ Y.extend(TREE, Y.Base, TREE.prototype, {
|
||||
}
|
||||
return val;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The navigation tree block instance.
|
||||
*/
|
||||
instance : {
|
||||
value : false,
|
||||
setter : function(val) {
|
||||
return parseInt(val, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -582,7 +591,7 @@ BRANCH.prototype = {
|
||||
} else {
|
||||
e.stopPropagation();
|
||||
}
|
||||
if (e.type === 'actionkey' && e.action === 'enter' && e.target.test('A')) {
|
||||
if ((e.type === 'actionkey' && e.action === 'enter') || e.target.test('a')) {
|
||||
// No ajaxLoad for enter.
|
||||
this.node.setAttribute('data-expandable', '0');
|
||||
this.node.setAttribute('data-loaded', '1');
|
||||
@@ -638,6 +647,12 @@ BRANCH.prototype = {
|
||||
this.node.setAttribute('data-loaded', '1');
|
||||
try {
|
||||
var object = Y.JSON.parse(outcome.responseText);
|
||||
if (object.error) {
|
||||
Y.use('moodle-core-notification-ajaxexception', function () {
|
||||
return new M.core.ajaxException(object).show();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (object.children && object.children.length > 0) {
|
||||
var coursecount = 0;
|
||||
for (var i in object.children) {
|
||||
@@ -659,8 +674,15 @@ BRANCH.prototype = {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (ex) {
|
||||
// If we got here then there was an error parsing the result.
|
||||
} catch (error) {
|
||||
if (outcome && outcome.status && outcome.status > 0) {
|
||||
// If we got here then there was an error parsing the result.
|
||||
Y.use('moodle-core-notification-exception', function () {
|
||||
return new M.core.exception(error).show();
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
// The branch is empty so class it accordingly
|
||||
this.node.replaceClass('branch', 'emptybranch');
|
||||
|
||||
+26
-4
@@ -402,6 +402,15 @@ Y.extend(TREE, Y.Base, TREE.prototype, {
|
||||
}
|
||||
return val;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The navigation tree block instance.
|
||||
*/
|
||||
instance : {
|
||||
value : false,
|
||||
setter : function(val) {
|
||||
return parseInt(val, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -581,7 +590,7 @@ BRANCH.prototype = {
|
||||
} else {
|
||||
e.stopPropagation();
|
||||
}
|
||||
if (e.type === 'actionkey' && e.action === 'enter' && e.target.test('A')) {
|
||||
if ((e.type === 'actionkey' && e.action === 'enter') || e.target.test('a')) {
|
||||
// No ajaxLoad for enter.
|
||||
this.node.setAttribute('data-expandable', '0');
|
||||
this.node.setAttribute('data-loaded', '1');
|
||||
@@ -638,6 +647,12 @@ BRANCH.prototype = {
|
||||
this.node.setAttribute('data-loaded', '1');
|
||||
try {
|
||||
var object = Y.JSON.parse(outcome.responseText);
|
||||
if (object.error) {
|
||||
Y.use('moodle-core-notification-ajaxexception', function () {
|
||||
return new M.core.ajaxException(object).show();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (object.children && object.children.length > 0) {
|
||||
var coursecount = 0;
|
||||
for (var i in object.children) {
|
||||
@@ -661,9 +676,16 @@ BRANCH.prototype = {
|
||||
return true;
|
||||
}
|
||||
Y.log('AJAX loading complete but there were no children.', 'note', 'moodle-block_navigation');
|
||||
} catch (ex) {
|
||||
// If we got here then there was an error parsing the result.
|
||||
Y.log('Error parsing AJAX response or adding branches to the navigation tree', 'error', 'moodle-block_navigation');
|
||||
} catch (error) {
|
||||
if (outcome && outcome.status && outcome.status > 0) {
|
||||
// If we got here then there was an error parsing the result.
|
||||
Y.log('Error parsing AJAX response or adding branches to the navigation tree', 'error', 'moodle-block_navigation');
|
||||
Y.use('moodle-core-notification-exception', function () {
|
||||
return new M.core.exception(error).show();
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
// The branch is empty so class it accordingly
|
||||
this.node.replaceClass('branch', 'emptybranch');
|
||||
|
||||
@@ -80,5 +80,8 @@ function xmldb_block_section_links_upgrade($oldversion, $block) {
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -69,5 +69,8 @@ function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -70,5 +70,8 @@ function xmldb_block_settings_upgrade($oldversion, $block) {
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.6.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -27,4 +27,4 @@
|
||||
$string['enabledock'] = 'Allow the user to dock this block';
|
||||
$string['pluginname'] = 'Administration';
|
||||
$string['settings:addinstance'] = 'Add a new administration block';
|
||||
$string['settings:myaddinstance'] = 'Add a new settings block to My home';
|
||||
$string['settings:myaddinstance'] = 'Add a new administration block to My home';
|
||||
|
||||
@@ -89,6 +89,20 @@ class block_site_main_menu extends block_list {
|
||||
}
|
||||
if (!$ismoving) {
|
||||
$actions = course_get_cm_edit_actions($mod, -1);
|
||||
|
||||
// Add the action move.
|
||||
$modcontext = context_module::instance($mod->id);
|
||||
$hasmanageactivities = has_capability('moodle/course:manageactivities', $modcontext);
|
||||
if ($hasmanageactivities) {
|
||||
$baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey()));
|
||||
$actions['move'] = new action_menu_link_primary(
|
||||
new moodle_url($baseurl, array('copy' => $mod->id)),
|
||||
new pix_icon('t/move', get_string('move'), 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
null,
|
||||
array('title' => get_string('move'))
|
||||
);
|
||||
}
|
||||
|
||||
$editbuttons = html_writer::tag('div',
|
||||
$courserenderer->course_section_cm_edit_actions($actions, $mod, array('donotenhance' => true)),
|
||||
array('class' => 'buttons')
|
||||
|
||||
@@ -81,6 +81,7 @@ class block_tags extends block_base {
|
||||
}
|
||||
|
||||
$this->content = new stdClass;
|
||||
$this->content->text = '';
|
||||
$this->content->footer = '';
|
||||
|
||||
// Get a list of tags.
|
||||
|
||||
@@ -58,6 +58,20 @@ class behat_blocks extends behat_base {
|
||||
return $steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Docks a block. Editing mode should be previously enabled.
|
||||
*
|
||||
* @Given /^I dock "(?P<block_name_string>(?:[^"]|\\")*)" block$/
|
||||
* @param string $blockname
|
||||
* @return Given
|
||||
*/
|
||||
public function i_dock_block($blockname) {
|
||||
|
||||
// Looking for both title and alt.
|
||||
$xpath = "//input[@type='image'][@title='" . get_string('dockblock', 'block', $blockname) . "' or @alt='" . get_string('addtodock', 'block') . "']";
|
||||
return new Given('I click on " ' . $xpath . '" "xpath_element" in the "' . $this->escape($blockname) . '" "block"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a block's actions menu if it is not already opened.
|
||||
*
|
||||
|
||||
@@ -34,4 +34,4 @@ Feature: Add and configure blocks throughout the site
|
||||
And I press "Save changes"
|
||||
And I follow "Course 1"
|
||||
# The first block matching the pattern should be top-left block
|
||||
And I should see "Comments" in the "//*[@id='region-pre']/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' block ')]" "xpath_element"
|
||||
And I should see "Comments" in the "//*[@id='region-pre' or @id='block-region-side-pre']/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' block ')]" "xpath_element"
|
||||
|
||||
@@ -81,4 +81,4 @@ Feature: Block appearances
|
||||
| Visible | Yes |
|
||||
| Region | Right |
|
||||
And I press "Save changes"
|
||||
And I should see "Comments" in the "#region-post" "css_element"
|
||||
And I should see "Comments" in the "//*[@id='region-post' or @id='block-region-side-post']" "xpath_element"
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ if (empty($CFG->enableblogs)) {
|
||||
|
||||
//correct tagid if a text tag is provided as a param
|
||||
if (!empty($tag)) {
|
||||
if ($tagrec = $DB->get_record_sql("SELECT * FROM {tag} WHERE ". $DB->sql_like('name', '?', false), array("%$tag%"))) {
|
||||
if ($tagrec = $DB->get_record('tag', array('name' => $tag))) {
|
||||
$tagid = $tagrec->id;
|
||||
} else {
|
||||
unset($tagid);
|
||||
|
||||
+6
-2
@@ -880,8 +880,12 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
|
||||
$tagrec = $DB->get_record('tag', array('id'=>$tagid));
|
||||
$PAGE->navbar->add($tagrec->name, $blogurl);
|
||||
} elseif (!empty($tag)) {
|
||||
$blogurl->param('tag', $tag);
|
||||
$PAGE->navbar->add(get_string('tagparam', 'blog', $tag), $blogurl);
|
||||
if ($tagrec = $DB->get_record('tag', array('name' => $tag))) {
|
||||
$tagid = $tagrec->id;
|
||||
$headers['filters']['tag'] = $tagid;
|
||||
$blogurl->param('tag', $tag);
|
||||
$PAGE->navbar->add(get_string('tagparam', 'blog', $tag), $blogurl);
|
||||
}
|
||||
}
|
||||
|
||||
// Append Search info
|
||||
|
||||
@@ -33,11 +33,9 @@ Feature: Comment on a blog entry
|
||||
And I follow "Comments (0)"
|
||||
When I fill in "content" with "$My own >nasty< \"string\"!"
|
||||
And I follow "Save comment"
|
||||
And I wait "4" seconds
|
||||
Then I should see "$My own >nasty< \"string\"!"
|
||||
And I fill in "content" with "Another $Nasty <string?>"
|
||||
And I follow "Save comment"
|
||||
And I wait "4" seconds
|
||||
And I should see "Comments (2)" in the ".comment-link" "css_element"
|
||||
|
||||
@javascript
|
||||
@@ -53,8 +51,8 @@ Feature: Comment on a blog entry
|
||||
And I follow "Comments (0)"
|
||||
And I fill in "content" with "$My own >nasty< \"string\"!"
|
||||
And I follow "Save comment"
|
||||
And I wait "4" seconds
|
||||
When I click on ".comment-delete a" "css_element"
|
||||
# Waiting for the animation to finish.
|
||||
And I wait "4" seconds
|
||||
Then I should not see "$My own >nasty< \"string\"!"
|
||||
And I follow "Blog post from user 1"
|
||||
@@ -73,5 +71,4 @@ Feature: Comment on a blog entry
|
||||
When I follow "Comments (0)"
|
||||
And I fill in "content" with "$My own >nasty< \"string\"!"
|
||||
And I follow "Save comment"
|
||||
And I wait "4" seconds
|
||||
Then I should see "$My own >nasty< \"string\"!"
|
||||
|
||||
Vendored
+1
@@ -282,6 +282,7 @@ if (!empty($action) && confirm_sesskey()) {
|
||||
|
||||
$PAGE->set_title($title);
|
||||
$PAGE->set_heading($SITE->fullname);
|
||||
/* @var core_cache_renderer $renderer */
|
||||
$renderer = $PAGE->get_renderer('core_cache');
|
||||
|
||||
echo $renderer->header();
|
||||
|
||||
Vendored
+43
-2
@@ -281,7 +281,7 @@ class cache_definition {
|
||||
* An array of identifiers provided to this cache when it was initialised.
|
||||
* @var array
|
||||
*/
|
||||
protected $identifiers = array();
|
||||
protected $identifiers = null;
|
||||
|
||||
/**
|
||||
* Key prefix for use with single key cache stores
|
||||
@@ -654,6 +654,9 @@ class cache_definition {
|
||||
* @return array
|
||||
*/
|
||||
public function get_identifiers() {
|
||||
if (!isset($this->identifiers)) {
|
||||
return array();
|
||||
}
|
||||
return $this->identifiers;
|
||||
}
|
||||
|
||||
@@ -766,11 +769,22 @@ class cache_definition {
|
||||
* @throws coding_exception
|
||||
*/
|
||||
public function set_identifiers(array $identifiers = array()) {
|
||||
// If we are setting the exact same identifiers then just return as nothing really changed.
|
||||
// We don't care about order as cache::make will use the same definition order all the time.
|
||||
if ($identifiers === $this->identifiers) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->requireidentifiers as $identifier) {
|
||||
if (!isset($identifiers[$identifier])) {
|
||||
throw new coding_exception('Identifier required for cache has not been provided: '.$identifier);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->identifiers === null) {
|
||||
// Initialize identifiers if they have not been.
|
||||
$this->identifiers = array();
|
||||
}
|
||||
foreach ($identifiers as $name => $value) {
|
||||
$this->identifiers[$name] = (string)$value;
|
||||
}
|
||||
@@ -893,7 +907,7 @@ class cache_definition {
|
||||
'area' => $this->area,
|
||||
'siteidentifier' => $this->get_cache_identifier()
|
||||
);
|
||||
if (!empty($this->identifiers)) {
|
||||
if (isset($this->identifiers) && !empty($this->identifiers)) {
|
||||
$identifiers = array();
|
||||
foreach ($this->identifiers as $key => $value) {
|
||||
$identifiers[] = htmlentities($key, ENT_QUOTES, 'UTF-8').'='.htmlentities($value, ENT_QUOTES, 'UTF-8');
|
||||
@@ -963,4 +977,31 @@ class cache_definition {
|
||||
public function has_required_identifiers() {
|
||||
return (count($this->requireidentifiers) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the possible sharing options that can be used with this defintion.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_sharing_options() {
|
||||
return $this->sharingoptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user entered sharing key for this definition.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_user_input_sharing_key() {
|
||||
return $this->userinputsharingkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user selected sharing option for this definition.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_selected_sharing_option() {
|
||||
return $this->selectedsharingoption;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+9
-8
@@ -235,14 +235,14 @@ class cache_factory {
|
||||
*/
|
||||
public function create_cache(cache_definition $definition) {
|
||||
$class = $definition->get_cache_class();
|
||||
if ($this->is_initialising()) {
|
||||
// Do nothing we just want the dummy store.
|
||||
$stores = array();
|
||||
} else {
|
||||
$stores = cache_helper::get_cache_stores($definition);
|
||||
$stores = cache_helper::get_stores_suitable_for_definition($definition);
|
||||
foreach ($stores as $key => $store) {
|
||||
if (!$store::are_requirements_met()) {
|
||||
unset($stores[$key]);
|
||||
}
|
||||
}
|
||||
if (count($stores) === 0) {
|
||||
// Hmm no stores, better provide a dummy store to mimick functionality. The dev will be none the wiser.
|
||||
// Hmm still no stores, better provide a dummy store to mimic functionality. The dev will be none the wiser.
|
||||
$stores[] = $this->create_dummy_store($definition);
|
||||
}
|
||||
$loader = null;
|
||||
@@ -258,7 +258,7 @@ class cache_factory {
|
||||
/**
|
||||
* Creates a store instance given its name and configuration.
|
||||
*
|
||||
* If the store has already been instantiated then the original objetc will be returned. (reused)
|
||||
* If the store has already been instantiated then the original object will be returned. (reused)
|
||||
*
|
||||
* @param string $name The name of the store (must be unique remember)
|
||||
* @param array $details
|
||||
@@ -272,8 +272,9 @@ class cache_factory {
|
||||
$store = new $class($details['name'], $details['configuration']);
|
||||
$this->stores[$name] = $store;
|
||||
}
|
||||
/* @var cache_store $store */
|
||||
$store = $this->stores[$name];
|
||||
if (!$store->is_ready() || !$store->is_supported_mode($definition->get_mode())) {
|
||||
if (!$store::are_requirements_met() || !$store->is_ready() || !$store->is_supported_mode($definition->get_mode())) {
|
||||
return false;
|
||||
}
|
||||
// We always create a clone of the original store.
|
||||
|
||||
Vendored
+70
-8
@@ -143,7 +143,7 @@ class cache_helper {
|
||||
*
|
||||
* @param array $stores
|
||||
* @param cache_definition $definition
|
||||
* @return array
|
||||
* @return cache_store[]
|
||||
*/
|
||||
protected static function initialise_cachestore_instances(array $stores, cache_definition $definition) {
|
||||
$return = array();
|
||||
@@ -382,34 +382,40 @@ class cache_helper {
|
||||
/**
|
||||
* Record a cache hit in the stats for the given store and definition.
|
||||
*
|
||||
* @internal
|
||||
* @param string $store
|
||||
* @param string $definition
|
||||
* @param int $hits The number of hits to record (by default 1)
|
||||
*/
|
||||
public static function record_cache_hit($store, $definition) {
|
||||
public static function record_cache_hit($store, $definition, $hits = 1) {
|
||||
self::ensure_ready_for_stats($store, $definition);
|
||||
self::$stats[$definition][$store]['hits']++;
|
||||
self::$stats[$definition][$store]['hits'] += $hits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record a cache miss in the stats for the given store and definition.
|
||||
*
|
||||
* @internal
|
||||
* @param string $store
|
||||
* @param string $definition
|
||||
* @param int $misses The number of misses to record (by default 1)
|
||||
*/
|
||||
public static function record_cache_miss($store, $definition) {
|
||||
public static function record_cache_miss($store, $definition, $misses = 1) {
|
||||
self::ensure_ready_for_stats($store, $definition);
|
||||
self::$stats[$definition][$store]['misses']++;
|
||||
self::$stats[$definition][$store]['misses'] += $misses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record a cache set in the stats for the given store and definition.
|
||||
*
|
||||
* @internal
|
||||
* @param string $store
|
||||
* @param string $definition
|
||||
* @param int $sets The number of sets to record (by default 1)
|
||||
*/
|
||||
public static function record_cache_set($store, $definition) {
|
||||
public static function record_cache_set($store, $definition, $sets = 1) {
|
||||
self::ensure_ready_for_stats($store, $definition);
|
||||
self::$stats[$definition][$store]['sets']++;
|
||||
self::$stats[$definition][$store]['sets'] += $sets;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -462,8 +468,9 @@ class cache_helper {
|
||||
$class = $store['class'];
|
||||
|
||||
// Found the store: is it ready?
|
||||
/* @var cache_store $instance */
|
||||
$instance = new $class($store['name'], $store['configuration']);
|
||||
if (!$instance->is_ready()) {
|
||||
if (!$instance::are_requirements_met() || !$instance->is_ready()) {
|
||||
unset($instance);
|
||||
return false;
|
||||
}
|
||||
@@ -672,4 +679,59 @@ class cache_helper {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of stores that would meet the requirements for every definition.
|
||||
*
|
||||
* These stores would be 100% suitable to map as defaults for cache modes.
|
||||
*
|
||||
* @return array[] An array of stores, keys are the store names.
|
||||
*/
|
||||
public static function get_stores_suitable_for_mode_default() {
|
||||
$factory = cache_factory::instance();
|
||||
$config = $factory->create_config_instance();
|
||||
$requirements = 0;
|
||||
foreach ($config->get_definitions() as $definition) {
|
||||
$definition = cache_definition::load($definition['component'].'/'.$definition['area'], $definition);
|
||||
$requirements = $requirements | $definition->get_requirements_bin();
|
||||
}
|
||||
$stores = array();
|
||||
foreach ($config->get_all_stores() as $name => $store) {
|
||||
if (!empty($store['features']) && ($store['features'] & $requirements)) {
|
||||
$stores[$name] = $store;
|
||||
}
|
||||
}
|
||||
return $stores;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns stores suitable for use with a given definition.
|
||||
*
|
||||
* @param cache_definition $definition
|
||||
* @return cache_store[]
|
||||
*/
|
||||
public static function get_stores_suitable_for_definition(cache_definition $definition) {
|
||||
$factory = cache_factory::instance();
|
||||
$stores = array();
|
||||
if ($factory->is_initialising() || $factory->stores_disabled()) {
|
||||
// No suitable stores here.
|
||||
return $stores;
|
||||
} else {
|
||||
$stores = self::get_cache_stores($definition);
|
||||
if (count($stores) === 0) {
|
||||
// No suitable stores we found for the definition. We need to come up with a sensible default.
|
||||
// If this has happened we can be sure that the user has mapped custom stores to either the
|
||||
// mode of the definition. The first alternative to try is the system default for the mode.
|
||||
// e.g. the default file store instance for application definitions.
|
||||
$config = $factory->create_config_instance();
|
||||
foreach ($config->get_stores($definition->get_mode()) as $name => $details) {
|
||||
if (!empty($details['default'])) {
|
||||
$stores[] = $factory->create_store_from_config($name, $details, $definition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $stores;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+35
-7
@@ -463,6 +463,20 @@ class cache implements cache_loader {
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->perfdebug) {
|
||||
$hits = 0;
|
||||
$misses = 0;
|
||||
foreach ($fullresult as $value) {
|
||||
if ($value === false) {
|
||||
$misses++;
|
||||
} else {
|
||||
$hits++;
|
||||
}
|
||||
}
|
||||
cache_helper::record_cache_hit($this->storetype, $this->definition->get_id(), $hits);
|
||||
cache_helper::record_cache_miss($this->storetype, $this->definition->get_id(), $misses);
|
||||
}
|
||||
|
||||
// Return the result. Phew!
|
||||
return $fullresult;
|
||||
}
|
||||
@@ -633,10 +647,11 @@ class cache implements cache_loader {
|
||||
$this->static_acceleration_set($data[$key]['key'], $value);
|
||||
}
|
||||
}
|
||||
if ($this->perfdebug) {
|
||||
cache_helper::record_cache_set($this->storetype, $this->definition->get_id());
|
||||
$successfullyset = $this->store->set_many($data);
|
||||
if ($this->perfdebug && $successfullyset) {
|
||||
cache_helper::record_cache_set($this->storetype, $this->definition->get_id(), $successfullyset);
|
||||
}
|
||||
return $this->store->set_many($data);
|
||||
return $successfullyset;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1937,7 +1952,19 @@ class cache_session extends cache {
|
||||
if ($hasmissingkeys && $strictness === MUST_EXIST) {
|
||||
throw new coding_exception('Requested key did not exist in any cache stores and could not be loaded.');
|
||||
}
|
||||
|
||||
if ($this->perfdebug) {
|
||||
$hits = 0;
|
||||
$misses = 0;
|
||||
foreach ($return as $value) {
|
||||
if ($value === false) {
|
||||
$misses++;
|
||||
} else {
|
||||
$hits++;
|
||||
}
|
||||
}
|
||||
cache_helper::record_cache_hit($this->storetype, $this->get_definition()->get_id(), $hits);
|
||||
cache_helper::record_cache_miss($this->storetype, $this->get_definition()->get_id(), $misses);
|
||||
}
|
||||
return $return;
|
||||
|
||||
}
|
||||
@@ -2011,10 +2038,11 @@ class cache_session extends cache {
|
||||
'value' => $value
|
||||
);
|
||||
}
|
||||
if ($this->perfdebug) {
|
||||
cache_helper::record_cache_set($this->storetype, $definitionid);
|
||||
$successfullyset = $this->get_store()->set_many($data);
|
||||
if ($this->perfdebug && $successfullyset) {
|
||||
cache_helper::record_cache_set($this->storetype, $definitionid, $successfullyset);
|
||||
}
|
||||
return $this->get_store()->set_many($data);
|
||||
return $successfullyset;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Vendored
+23
-44
@@ -778,63 +778,36 @@ abstract class cache_administration_helper extends cache_helper {
|
||||
* @return array
|
||||
*/
|
||||
public static function get_definition_summaries() {
|
||||
$instance = cache_config::instance();
|
||||
$definitions = $instance->get_definitions();
|
||||
|
||||
$factory = cache_factory::instance();
|
||||
$config = $factory->create_config_instance();
|
||||
$storenames = array();
|
||||
foreach ($instance->get_all_stores() as $key => $store) {
|
||||
foreach ($config->get_all_stores() as $key => $store) {
|
||||
if (!empty($store['default'])) {
|
||||
$storenames[$key] = new lang_string('store_'.$key, 'cache');
|
||||
}
|
||||
}
|
||||
|
||||
$modemappings = array();
|
||||
foreach ($instance->get_mode_mappings() as $mapping) {
|
||||
$mode = $mapping['mode'];
|
||||
if (!array_key_exists($mode, $modemappings)) {
|
||||
$modemappings[$mode] = array();
|
||||
}
|
||||
if (array_key_exists($mapping['store'], $storenames)) {
|
||||
$modemappings[$mode][] = $storenames[$mapping['store']];
|
||||
} else {
|
||||
$modemappings[$mode][] = $mapping['store'];
|
||||
$storenames[$store['name']] = $store['name'];
|
||||
}
|
||||
}
|
||||
|
||||
$definitionmappings = array();
|
||||
foreach ($instance->get_definition_mappings() as $mapping) {
|
||||
$definition = $mapping['definition'];
|
||||
if (!array_key_exists($definition, $definitionmappings)) {
|
||||
$definitionmappings[$definition] = array();
|
||||
}
|
||||
if (array_key_exists($mapping['store'], $storenames)) {
|
||||
$definitionmappings[$definition][] = $storenames[$mapping['store']];
|
||||
} else {
|
||||
$definitionmappings[$definition][] = $mapping['store'];
|
||||
}
|
||||
/* @var cache_definition[] $definitions */
|
||||
$definitions = array();
|
||||
foreach ($config->get_definitions() as $key => $definition) {
|
||||
$definitions[$key] = cache_definition::load($definition['component'].'/'.$definition['area'], $definition);
|
||||
}
|
||||
|
||||
$return = array();
|
||||
|
||||
foreach ($definitions as $id => $definition) {
|
||||
|
||||
$mappings = array();
|
||||
if (array_key_exists($id, $definitionmappings)) {
|
||||
$mappings = $definitionmappings[$id];
|
||||
} else if (empty($definition['mappingsonly'])) {
|
||||
$mappings = $modemappings[$definition['mode']];
|
||||
foreach (cache_helper::get_stores_suitable_for_definition($definition) as $store) {
|
||||
$mappings[] = $storenames[$store->my_name()];
|
||||
}
|
||||
|
||||
$return[$id] = array(
|
||||
'id' => $id,
|
||||
'name' => cache_helper::get_definition_name($definition),
|
||||
'mode' => $definition['mode'],
|
||||
'component' => $definition['component'],
|
||||
'area' => $definition['area'],
|
||||
'name' => $definition->get_name(),
|
||||
'mode' => $definition->get_mode(),
|
||||
'component' => $definition->get_component(),
|
||||
'area' => $definition->get_area(),
|
||||
'mappings' => $mappings,
|
||||
'sharingoptions' => self::get_definition_sharing_options($definition['sharingoptions'], false),
|
||||
'selectedsharingoption' => self::get_definition_sharing_options($definition['selectedsharingoption'], true),
|
||||
'userinputsharingkey' => $definition['userinputsharingkey']
|
||||
'sharingoptions' => self::get_definition_sharing_options($definition->get_sharing_options(), false),
|
||||
'selectedsharingoption' => self::get_definition_sharing_options($definition->get_selected_sharing_option(), true),
|
||||
'userinputsharingkey' => $definition->get_user_input_sharing_key()
|
||||
);
|
||||
}
|
||||
return $return;
|
||||
@@ -1126,7 +1099,10 @@ abstract class cache_administration_helper extends cache_helper {
|
||||
* @return array An array containing sub-arrays, one for each mode.
|
||||
*/
|
||||
public static function get_default_mode_stores() {
|
||||
global $OUTPUT;
|
||||
$instance = cache_config::instance();
|
||||
$adequatestores = cache_helper::get_stores_suitable_for_mode_default();
|
||||
$icon = new pix_icon('i/warning', new lang_string('inadequatestoreformapping', 'cache'));
|
||||
$storenames = array();
|
||||
foreach ($instance->get_all_stores() as $key => $store) {
|
||||
if (!empty($store['default'])) {
|
||||
@@ -1149,6 +1125,9 @@ abstract class cache_administration_helper extends cache_helper {
|
||||
} else {
|
||||
$modemappings[$mode][$mapping['store']] = $mapping['store'];
|
||||
}
|
||||
if (!array_key_exists($mapping['store'], $adequatestores)) {
|
||||
$modemappings[$mode][$mapping['store']] = $modemappings[$mode][$mapping['store']].' '.$OUTPUT->render($icon);
|
||||
}
|
||||
}
|
||||
return $modemappings;
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -131,7 +131,7 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
|
||||
|
||||
$this->connection = new Memcache;
|
||||
foreach ($this->servers as $server) {
|
||||
$this->connection->addServer($server[0], $server[1], true, $server[2]);
|
||||
$this->connection->addServer($server[0], (int) $server[1], true, (int) $server[2]);
|
||||
}
|
||||
// Test the connection to the pool of servers.
|
||||
$this->isready = @$this->connection->set($this->parse_key('ping'), 'ping', MEMCACHE_COMPRESSED, 1);
|
||||
|
||||
@@ -309,6 +309,7 @@ class core_calendar_renderer extends plugin_renderer_base {
|
||||
global $CFG;
|
||||
|
||||
$event = calendar_add_event_metadata($event);
|
||||
$context = $event->context;
|
||||
|
||||
$anchor = html_writer::tag('a', '', array('name'=>'event_'.$event->id));
|
||||
|
||||
@@ -331,7 +332,7 @@ class core_calendar_renderer extends plugin_renderer_base {
|
||||
if (!empty($event->referer)) {
|
||||
$table->data[0]->cells[1]->text .= html_writer::tag('div', $event->referer, array('class'=>'referer'));
|
||||
} else {
|
||||
$table->data[0]->cells[1]->text .= html_writer::tag('div', $event->name, array('class'=>'name'));
|
||||
$table->data[0]->cells[1]->text .= html_writer::tag('div', format_string($event->name, false, array('context' => $context)), array('class'=>'name'));
|
||||
}
|
||||
if (!empty($event->courselink)) {
|
||||
$table->data[0]->cells[1]->text .= html_writer::tag('div', $event->courselink, array('class'=>'course'));
|
||||
@@ -355,7 +356,7 @@ class core_calendar_renderer extends plugin_renderer_base {
|
||||
$table->data[1]->cells[0] = new html_table_cell(' ');
|
||||
$table->data[1]->cells[0]->attributes['class'] .= 'side';
|
||||
|
||||
$table->data[1]->cells[1] = new html_table_cell($event->description);
|
||||
$table->data[1]->cells[1] = new html_table_cell(format_text($event->description, $event->format, array('context' => $context)));
|
||||
$table->data[1]->cells[1]->attributes['class'] .= ' description';
|
||||
if (isset($event->cssclass)) {
|
||||
$table->data[1]->cells[1]->attributes['class'] .= ' '.$event->cssclass;
|
||||
|
||||
@@ -54,7 +54,7 @@ class behat_cohort extends behat_base {
|
||||
$userid = $DB->get_field('user', 'id', array('username' => $username));
|
||||
|
||||
$steps = array(
|
||||
new Given('I click on "' . get_string('assign', 'cohort') . '" "link" in the "' . $this->escape($cohortidnumber) . '" table row'),
|
||||
new Given('I click on "' . get_string('assign', 'cohort') . '" "link" in the "' . $this->escape($cohortidnumber) . '" "table_row"'),
|
||||
new Given('I select "' . $userid . '" from "' . get_string('potusers', 'cohort') . '"'),
|
||||
new Given('I press "' . get_string('add') . '"'),
|
||||
new Given('I press "' . get_string('backtocohorts', 'cohort') . '"')
|
||||
|
||||
@@ -27,16 +27,16 @@ Feature: Upload users to a cohort
|
||||
And I expand "Users" node
|
||||
And I expand "Accounts" node
|
||||
When I follow "Upload users"
|
||||
And I upload "lib/tests/fixtures/upload_users_cohorts.csv" file to "File" filepicker
|
||||
And I upload "lib/tests/fixtures/upload_users_cohorts.csv" file to "File" filemanager
|
||||
And I press "Upload users"
|
||||
And I press "Upload users"
|
||||
And I press "Continue"
|
||||
And I follow "Cohorts"
|
||||
And I click on "Assign" "link" in the "Cohort 1" table row
|
||||
And I click on "Assign" "link" in the "Cohort 1" "table_row"
|
||||
Then the "Current users" select box should contain "Tom Jones (tomjones@example.com)"
|
||||
And the "Current users" select box should contain "Bob Jones (bobjones@example.com)"
|
||||
And I press "Back to cohorts"
|
||||
And I click on "Assign" "link" in the "Cohort 2" table row
|
||||
And I click on "Assign" "link" in the "Cohort 2" "table_row"
|
||||
And the "Current users" select box should contain "Mary Smith (marysmith@example.com)"
|
||||
And the "Current users" select box should contain "Alice Smith (alicesmith@example.com)"
|
||||
And I am on homepage
|
||||
|
||||
@@ -37,7 +37,6 @@ Feature: Allow students to manually mark an activity as complete
|
||||
And I log in as "student1"
|
||||
And I follow "Course 1"
|
||||
And I press "Mark as complete: Test forum name"
|
||||
And I wait "3" seconds
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
|
||||
@@ -20,13 +20,16 @@ Feature: Restrict activity availability through date conditions
|
||||
And I set the following administration settings values:
|
||||
| Enable conditional access | 1 |
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
# Adding the page like this because id_available*_enabled needs to be clicked to trigger the action.
|
||||
And I add a "Assignment" to section "1"
|
||||
And I expand all fieldsets
|
||||
|
||||
@javascript
|
||||
Scenario: Show activity greyed-out to students when available from date is in future
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "Assignment" to section "1"
|
||||
Given I click on "id_availablefrom_enabled" "checkbox"
|
||||
And I fill the moodle form with:
|
||||
| Assignment name | Test assignment 1 |
|
||||
| Description | This assignment is restricted by date |
|
||||
@@ -36,7 +39,6 @@ Feature: Restrict activity availability through date conditions
|
||||
| id_availablefrom_month | 12 |
|
||||
| id_availablefrom_year | 2050 |
|
||||
| id_showavailability | 1 |
|
||||
And I click on "id_availablefrom_enabled" "checkbox"
|
||||
And I press "Save and return to course"
|
||||
And I log out
|
||||
When I log in as "student1"
|
||||
@@ -47,10 +49,7 @@ Feature: Restrict activity availability through date conditions
|
||||
|
||||
@javascript
|
||||
Scenario: Show activity hidden to students when available until date is in past
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "Assignment" to section "2"
|
||||
Given I click on "id_availableuntil_enabled" "checkbox"
|
||||
And I fill the moodle form with:
|
||||
| Assignment name | Test assignment 2 |
|
||||
| Description | This assignment is restricted by date |
|
||||
@@ -60,7 +59,6 @@ Feature: Restrict activity availability through date conditions
|
||||
| id_availableuntil_month | 2 |
|
||||
| id_availableuntil_year | 2013 |
|
||||
| id_showavailability | 0 |
|
||||
And I click on "id_availableuntil_enabled" "checkbox"
|
||||
And I press "Save and return to course"
|
||||
And I log out
|
||||
When I log in as "student1"
|
||||
|
||||
@@ -29,13 +29,18 @@ Feature: Restrict activity availability through grade conditions
|
||||
| Description | Grade this assignment to revoke restriction on restricted assignment |
|
||||
| assignsubmission_onlinetext_enabled | 1 |
|
||||
| assignsubmission_file_enabled | 0 |
|
||||
And I add a "Page" to section "2" and I fill the form with:
|
||||
# Adding the page like this because id_availableform_enabled needs to be clicked to trigger the action.
|
||||
And I add a "Page" to section "2"
|
||||
And I expand all fieldsets
|
||||
And I click on "id_availablefrom_enabled" "checkbox"
|
||||
And I fill the moodle form with:
|
||||
| Name | Test page name |
|
||||
| Description | Restricted page, till grades in Grade assignment is at least 20% |
|
||||
| Page content | Test page contents |
|
||||
| id_conditiongradegroup_0_conditiongradeitemid | 2 |
|
||||
| id_conditiongradegroup_0_conditiongrademin | 20 |
|
||||
| id_showavailability | 1 |
|
||||
And I press "Save and return to course"
|
||||
And I log out
|
||||
When I log in as "student1"
|
||||
And I follow "Course 1"
|
||||
|
||||
+1
-1
@@ -8,6 +8,6 @@
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "3.7.*",
|
||||
"phpunit/dbUnit": "1.2.*",
|
||||
"moodlehq/behat-extension": "1.26.*"
|
||||
"moodlehq/behat-extension": "1.26.4"
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -589,10 +589,16 @@ $CFG->admin = 'admin';
|
||||
// $CFG->behat_prefix = 'bht_';
|
||||
// $CFG->behat_dataroot = '/home/example/bht_moodledata';
|
||||
//
|
||||
// Behat uses http://localhost:8000 as default URL to run
|
||||
// the acceptance tests, you can override this value.
|
||||
// To set a seperate wwwroot for Behat to use, use $CFG->behat_wwwroot; this is set automatically
|
||||
// to http://localhost:8000 as it is the proposed PHP built-in server URL. Instead of that you can,
|
||||
// for example, use an alias, add a host to /etc/hosts or add a new virtual host having a URL
|
||||
// poiting to your production site and another one poiting to your test site. Note that you need
|
||||
// to ensure that this URL is not accessible from the www as the behat test site uses "sugar"
|
||||
// credentials (admin/admin) and can be easily hackable.
|
||||
//
|
||||
// Example:
|
||||
// $CFG->behat_wwwroot = 'http://192.168.1.250:8000';
|
||||
// $CFG->behat_wwwroot = 'http://localhost/moodlesitetesting';
|
||||
//
|
||||
// You can override default Moodle configuration for Behat and add your own
|
||||
// params; here you can add more profiles, use different Mink drivers than Selenium...
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user