Compare commits
426 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fb41a38153 | |||
| 4c6f1ec52e | |||
| ef572665e9 | |||
| 0383404678 | |||
| a7c2742900 | |||
| fc83888891 | |||
| 18811be378 | |||
| 56d54e1eed | |||
| 3a4a5356eb | |||
| 1a5986dab9 | |||
| c10fc915ad | |||
| a6683d327f | |||
| a9155c2875 | |||
| 4d52fbbc14 | |||
| bb07f7ecce | |||
| dee6316364 | |||
| f6b1260812 | |||
| 1e6919f6c8 | |||
| a852df6f11 | |||
| e235c97f09 | |||
| d7e626156e | |||
| 0bde9de161 | |||
| dafe65e438 | |||
| 204383e50d | |||
| f1293083a2 | |||
| f0d974fb28 | |||
| 16a2860ad2 | |||
| bb9024d9d4 | |||
| a77f19bc47 | |||
| 2bc8f21600 | |||
| 75b8d4a146 | |||
| 33b4331eaf | |||
| 00a2921469 | |||
| fc4523f8f3 | |||
| 39714cb255 | |||
| c11621b415 | |||
| 7698803c95 | |||
| ebc9b6d158 | |||
| ae754bba07 | |||
| d20391916c | |||
| 9a561bc5a1 | |||
| 7af092c2d6 | |||
| 706db16531 | |||
| e3c2cb4656 | |||
| 2738bb2c2f | |||
| c17768973e | |||
| 11ffc395f4 | |||
| 1608fbe7c0 | |||
| 0927af1e8d | |||
| 77504426de | |||
| 2fe9be7a9e | |||
| 52d485c435 | |||
| 93a2a0e3d7 | |||
| dc59a1b1f9 | |||
| 21d9cb723b | |||
| 32e550a6eb | |||
| 97a7b6a7aa | |||
| 3c4c23876c | |||
| ff46f98998 | |||
| 00b4836197 | |||
| 4af378d743 | |||
| fab0986a5b | |||
| 866ab6e1ce | |||
| 0b675e0ca2 | |||
| 3166c21471 | |||
| 2ab1b3de30 | |||
| 6e07abb32d | |||
| bc0227d3e5 | |||
| e9d80e664b | |||
| ffc480afbd | |||
| 3d4a0f2887 | |||
| 9067595bf3 | |||
| 94a541f7ff | |||
| 3e6f11b240 | |||
| 7991637057 | |||
| 4f61afa0b7 | |||
| fb42a8c761 | |||
| 4418496864 | |||
| 82125f7a78 | |||
| 9e5adb9305 | |||
| 23dd6b7ebf | |||
| af4bdb8c8d | |||
| 12a9b4ec3a | |||
| 084b971bc8 | |||
| df7662560b | |||
| 405a60712b | |||
| bce7b6d40e | |||
| 55384d2016 | |||
| f8bb8999e8 | |||
| 2fbf721f27 | |||
| 233edd4dde | |||
| 75f1afeda0 | |||
| 808043d356 | |||
| da0c3ea381 | |||
| a028ac4aaf | |||
| 02e1c8ad20 | |||
| 3174f09839 | |||
| 1a703d311e | |||
| 922a5cf370 | |||
| e978b66009 | |||
| 8e29fe2d72 | |||
| 11f6680dee | |||
| 0bad576425 | |||
| 1620d20165 | |||
| e2d5b6cbc8 | |||
| e787333622 | |||
| 4ab623b9b6 | |||
| 8526be5612 | |||
| eede0dbd7b | |||
| 4d7c173514 | |||
| 70d4b3182d | |||
| 32a3dc0ec0 | |||
| 663c69e974 | |||
| eaf4854359 | |||
| 04597742cf | |||
| f68a2c50e6 | |||
| 5e069cbd96 | |||
| 3d19b183c6 | |||
| d81ebc8f0d | |||
| 5cc26839e7 | |||
| a831f154ae | |||
| 54c7d518f3 | |||
| ec18ffb86c | |||
| 842aac5ecb | |||
| dc24efe971 | |||
| 160e432aee | |||
| e38c37939a | |||
| e15bf9b1e5 | |||
| 1d1b52eb0c | |||
| 209658eab2 | |||
| 49a60b6c65 | |||
| 8c155823cc | |||
| 3c4fcce769 | |||
| 443563a82e | |||
| 346765035a | |||
| 944fd1ca83 | |||
| ded65ca8e0 | |||
| 2bf9edf84f | |||
| 29a4508930 | |||
| bda2a7bdf5 | |||
| 64ddb28dfd | |||
| 6fa5e8658a | |||
| 43dc7aa976 | |||
| 5d9349b61a | |||
| ff24397ff3 | |||
| de5568b18e | |||
| d3cf194050 | |||
| 37d38a3125 | |||
| 2804eb29c6 | |||
| e85e3bff3e | |||
| 51c72ecaa5 | |||
| 30703dc8f2 | |||
| 33beb96847 | |||
| 7f742cece1 | |||
| ab0e64524d | |||
| 2a93e8d72c | |||
| 6780a2301e | |||
| 3a2e904098 | |||
| 6117c578e4 | |||
| 69303857c7 | |||
| a4848b4044 | |||
| a6b980d13b | |||
| 9e53bbd007 | |||
| e0699a7154 | |||
| aa41f96d1a | |||
| e4fcb52f44 | |||
| bacf4c5c71 | |||
| 43c5a7d5ad | |||
| 624f270a26 | |||
| 313bcd5268 | |||
| 5a21d336f3 | |||
| f60ad3fdff | |||
| 2daa9998ae | |||
| 6079448098 | |||
| 992c0ec50d | |||
| aca67ae8b0 | |||
| 474c13f27f | |||
| 7480e99306 | |||
| 96241e57e9 | |||
| ade2afc29f | |||
| 534f1476f4 | |||
| b625e48b87 | |||
| a327e87866 | |||
| 0f74c82897 | |||
| 3ee63c14e0 | |||
| f31670ef40 | |||
| b1f151c933 | |||
| 7f9f03442a | |||
| 9d1a909f0e | |||
| 8b7c33ae77 | |||
| c9d1c4993d | |||
| 7b9caeb92b | |||
| 49acbbad2f | |||
| afe247a0ca | |||
| f7c2942961 | |||
| 6f4232974e | |||
| f981643f58 | |||
| 2f8602990f | |||
| 7174920aaa | |||
| 57ecff6356 | |||
| 2d69af043d | |||
| a1d43d9e4f | |||
| 08c2a3ca1f | |||
| fbc635e400 | |||
| 00afef17bb | |||
| c174a19207 | |||
| d89fbe0285 | |||
| ddf1b0741d | |||
| dac7c261ca | |||
| 8504444307 | |||
| 602255df1a | |||
| ee7a52ae91 | |||
| 6964e6a580 | |||
| 5c8c94eabe | |||
| 00f906b114 | |||
| 2d28b03d90 | |||
| 03fa7a2ba3 | |||
| cd79352fbd | |||
| f082c5e390 | |||
| 266ceb16a6 | |||
| 35b76a3507 | |||
| 06de509918 | |||
| 788e1924a2 | |||
| 9bc4a4cc79 | |||
| d98b9a945e | |||
| 4ab6c6fbc0 | |||
| a2ec961309 | |||
| 86882b6dfe | |||
| ff3a54a5f7 | |||
| 82887b29e8 | |||
| 52286ac358 | |||
| d618e3c07d | |||
| 14e5c99960 | |||
| 333df7d951 | |||
| 6cf8499253 | |||
| a3fa82636d | |||
| 1430866232 | |||
| 1c437c97f7 | |||
| 0fbfae718d | |||
| 61899ac202 | |||
| 92c46e00eb | |||
| 1127607bce | |||
| ef580461f6 | |||
| 2d0faffb7f | |||
| f9d68a11da | |||
| 0a8985843e | |||
| e0e6015416 | |||
| 9db4dcb68b | |||
| 6b52abc0af | |||
| 179fbc7f11 | |||
| 28ce5653c0 | |||
| c017ccff4c | |||
| ea85ee6f63 | |||
| 2fb98d4bc0 | |||
| 9a0e9776c0 | |||
| 832aa7eb71 | |||
| 0e73df9df6 | |||
| ab8e75ef40 | |||
| ef8a1c4908 | |||
| 0f51a82bae | |||
| 358544f9b7 | |||
| 36e5df06b3 | |||
| 8c8b3eba24 | |||
| faccb2ba9f | |||
| bf2360c597 | |||
| e7bb4b1ee7 | |||
| 2b7e18fded | |||
| f85cb076aa | |||
| 836dab79c0 | |||
| 2fdfdd49d4 | |||
| cb1318754e | |||
| 491e196107 | |||
| 13f73be25b | |||
| 21c4402280 | |||
| 2140e5afa4 | |||
| acae4313c8 | |||
| 16725a78d0 | |||
| 3e17b1c4a7 | |||
| e19a07bfcb | |||
| c687e8d741 | |||
| 09c0ea1f39 | |||
| 1fe7be205c | |||
| 6399a82028 | |||
| 8a2cee5091 | |||
| ca7f399be7 | |||
| 6c37003d05 | |||
| d1963974a9 | |||
| 3b4752e1f2 | |||
| 618737d7e9 | |||
| 06ab9b8888 | |||
| c7abb11786 | |||
| 73f8ab649f | |||
| 189590bb37 | |||
| 827e54dde5 | |||
| 42a9e3efc2 | |||
| f58fadfeba | |||
| f498ae7652 | |||
| dd85f5aed0 | |||
| b91fcb9094 | |||
| dfb83eb132 | |||
| 1e558fdf66 | |||
| 7dad4a5e59 | |||
| 8b2e668a19 | |||
| 65380ecd0a | |||
| b5ce3bc8f4 | |||
| 51173470b6 | |||
| 8df87c160f | |||
| e5326193bf | |||
| e9fd6e5dd6 | |||
| a74edf03ad | |||
| bd205fa484 | |||
| 93ac52a9f3 | |||
| db8d852af9 | |||
| 068373c86a | |||
| 4c4c90f4b0 | |||
| a270a2c129 | |||
| 096707c01d | |||
| b4de832553 | |||
| f0dc1a71c1 | |||
| 2f467a82a1 | |||
| 91cf8cc82c | |||
| 2e80405940 | |||
| f36066fa9e | |||
| a4e0171b2c | |||
| 8352a1b138 | |||
| 028b56f875 | |||
| e9efc2baa2 | |||
| 7e720621ec | |||
| 626c84bca9 | |||
| 4bc4844d5b | |||
| 695f6f3c23 | |||
| f4075573b9 | |||
| a13cbfb3e7 | |||
| 799dbbfbaa | |||
| e5c6694de8 | |||
| d3aeeb93c2 | |||
| f5940428a9 | |||
| e58af1dfcd | |||
| 4f0d6118ff | |||
| 8b77e81201 | |||
| d6e2b0a03e | |||
| a665577b37 | |||
| f32e55c8d7 | |||
| 6a3a3bd868 | |||
| f70d382498 | |||
| e132b54a6a | |||
| c0b59154ba | |||
| 268cb03e2d | |||
| ad97a56875 | |||
| 8d94299b02 | |||
| 0653761da2 | |||
| e489df87bf | |||
| 87a445ec70 | |||
| 121e2492e8 | |||
| 6c16494f03 | |||
| 191e70c2e2 | |||
| 7291b026a0 | |||
| df4da0fe79 | |||
| ceb4030763 | |||
| 69ecf8c0a9 | |||
| 039c78702d | |||
| 7fa470de03 | |||
| 6ceb6eb672 | |||
| 644b1df502 | |||
| 161be92065 | |||
| 5878ac3957 | |||
| 761227cfc6 | |||
| 97d68b5652 | |||
| 3ecf7ddd15 | |||
| b6ef79950e | |||
| f65261d096 | |||
| 93f645f0ae | |||
| e5184cac0e | |||
| caaad8b08d | |||
| cb033b9fab | |||
| 4f629bc677 | |||
| d917dc9e40 | |||
| d74f740722 | |||
| 6168502474 | |||
| 751cebfc3d | |||
| acfd39cbf8 | |||
| 2efc8ff39f | |||
| 2a0b243137 | |||
| b8aca19538 | |||
| 2fbfedb310 | |||
| 6c43ee510f | |||
| d262212a1f | |||
| d50f747fd8 | |||
| d95506e05a | |||
| f7d180a7fb | |||
| 91af4fa5bf | |||
| b051261ecc | |||
| aeaf5c1337 | |||
| 9f13f53393 | |||
| 0bc310eb5a | |||
| ab6a0ac4f7 | |||
| 18003f2adb | |||
| 2ab5928066 | |||
| e3c1bd2593 | |||
| 99f5bad554 | |||
| 666117e830 | |||
| 9b19f3f4fb | |||
| b6d07f25a1 | |||
| e90eb091c5 | |||
| 5cc84acabe | |||
| 543b5feae0 | |||
| cdd041e631 | |||
| 6d393bd97c | |||
| f8aec131e9 | |||
| 62cf9a1d2a | |||
| 76f881c83a | |||
| c4500213d6 | |||
| 1cdcb6599a | |||
| ff3f1f3ef3 | |||
| b42e6e1c2e | |||
| d8581a2367 | |||
| 236ebcfe78 | |||
| c340dca9b0 | |||
| a3c292ee64 | |||
| b7bbb615d7 | |||
| 9141e05262 | |||
| e9cfbe4290 | |||
| 2e297423cd | |||
| 8daf98a10f | |||
| 0f387618cd | |||
| d8d0b8b390 |
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* This script fixed incorrectly deleted users.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage cli
|
||||
* @copyright 2013 Petr Skoda (http://skodak.org)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('CLI_SCRIPT', true);
|
||||
|
||||
require(__DIR__.'/../../config.php');
|
||||
require_once($CFG->libdir.'/clilib.php');
|
||||
|
||||
|
||||
// Now get cli options.
|
||||
list($options, $unrecognized) = cli_get_params(array('help'=>false),
|
||||
array('h'=>'help'));
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
|
||||
}
|
||||
|
||||
if ($options['help']) {
|
||||
$help =
|
||||
"Fix incorrectly deleted users.
|
||||
|
||||
This scripts detects users that are marked as deleted instead
|
||||
of calling delete_user().
|
||||
|
||||
Deleted users do not have original username, idnumber or email,
|
||||
we must also delete all roles, enrolments, group memberships, etc.
|
||||
|
||||
Please note this script does not delete any public information
|
||||
such as forum posts.
|
||||
|
||||
Options:
|
||||
-h, --help Print out this help
|
||||
|
||||
Example:
|
||||
\$sudo -u www-data /usr/bin/php admin/cli/fix_deleted_users.php
|
||||
";
|
||||
|
||||
echo $help;
|
||||
die;
|
||||
}
|
||||
|
||||
cli_heading('Looking for sloppy user deletes');
|
||||
|
||||
// Look for sloppy deleted users where somebody only flipped the deleted flag.
|
||||
$sql = "SELECT *
|
||||
FROM {user}
|
||||
WHERE deleted = 1 AND email LIKE '%@%' AND username NOT LIKE '%@%'";
|
||||
$rs = $DB->get_recordset_sql($sql);
|
||||
foreach ($rs as $user) {
|
||||
echo "Redeleting user $user->id: $user->username ($user->email)\n";
|
||||
delete_user($user);
|
||||
}
|
||||
|
||||
cli_heading('Deleting all leftovers');
|
||||
|
||||
$DB->set_field('user', 'idnumber', '', array('deleted'=>1));
|
||||
|
||||
$DB->delete_records_select('role_assignments', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
|
||||
$DB->delete_records_select('cohort_members', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
|
||||
$DB->delete_records_select('groups_members', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
|
||||
$DB->delete_records_select('user_enrolments', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
|
||||
$DB->delete_records_select('user_preferences', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
|
||||
$DB->delete_records_select('user_info_data', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
|
||||
$DB->delete_records_select('user_lastaccess', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
|
||||
$DB->delete_records_select('external_tokens', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
|
||||
$DB->delete_records_select('external_services_users', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
|
||||
|
||||
exit(0);
|
||||
@@ -892,4 +892,117 @@
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
</MOODLE>
|
||||
<MOODLE version="2.6" requires="2.2">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mysql" version="5.1.33" />
|
||||
<VENDOR name="postgres" version="8.3" />
|
||||
<VENDOR name="mssql" version="9.0" />
|
||||
<VENDOR name="oracle" version="10.2" />
|
||||
</DATABASE>
|
||||
<PHP version="5.3.3" 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="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="64M" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="settingmemorylimit" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="safe_mode" value="0" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingsafemode" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="file_uploads" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingfileuploads" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
</MOODLE>
|
||||
</COMPATIBILITY_MATRIX>
|
||||
|
||||
@@ -158,6 +158,7 @@ if ($hassiteconfig
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_blocks', new lang_string('generalblocks','backup'), new lang_string('configgeneralblocks','backup'), array('value'=>1, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_filters', new lang_string('generalfilters','backup'), new lang_string('configgeneralfilters','backup'), array('value'=>1, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_comments', new lang_string('generalcomments','backup'), new lang_string('configgeneralcomments','backup'), array('value'=>1, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_badges', new lang_string('generalbadges','backup'), new lang_string('configgeneralbadges','backup'), array('value'=>1,'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_userscompletion', new lang_string('generaluserscompletion','backup'), new lang_string('configgeneraluserscompletion','backup'), array('value'=>1, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_logs', new lang_string('generallogs','backup'), new lang_string('configgenerallogs','backup'), array('value'=>0, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_histories', new lang_string('generalhistories','backup'), new lang_string('configgeneralhistories','backup'), array('value'=>0, 'locked'=>0)));
|
||||
@@ -231,6 +232,7 @@ if ($hassiteconfig
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_blocks', new lang_string('generalblocks','backup'), new lang_string('configgeneralblocks','backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_filters', new lang_string('generalfilters','backup'), new lang_string('configgeneralfilters','backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_comments', new lang_string('generalcomments','backup'), new lang_string('configgeneralcomments','backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_badges', new lang_string('generalbadges','backup'), new lang_string('configgeneralbadges','backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_userscompletion', new lang_string('generaluserscompletion','backup'), new lang_string('configgeneraluserscompletion','backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_logs', new lang_string('generallogs', 'backup'), new lang_string('configgenerallogs', 'backup'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_histories', new lang_string('generalhistories','backup'), new lang_string('configgeneralhistories','backup'), 0));
|
||||
|
||||
@@ -65,6 +65,10 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
60 => new lang_string('numminutes', '', 60),
|
||||
30 => new lang_string('numminutes', '', 30),
|
||||
15 => new lang_string('numminutes', '', 15))));
|
||||
// Define the prefix to be added to imported profiling runs.
|
||||
$temp->add(new admin_setting_configtext('profilingimportprefix',
|
||||
new lang_string('profilingimportprefix', 'admin'),
|
||||
new lang_string('profilingimportprefix_desc', 'admin'), '(I)', PARAM_TAG, 10));
|
||||
|
||||
// Add the 'profiling' page to admin block
|
||||
$ADMIN->add('development', $temp);
|
||||
|
||||
@@ -14,7 +14,7 @@ Feature: Upload users
|
||||
| Section 1 | math102 | S1 |
|
||||
| Section 3 | math102 | S3 |
|
||||
And I log in as "admin"
|
||||
And I expand "Front page settings" node
|
||||
And I collapse "Front page settings" node
|
||||
And I expand "Site administration" node
|
||||
And I expand "Users" node
|
||||
And I expand "Accounts" node
|
||||
|
||||
@@ -30,6 +30,17 @@ Feature: Set up contextual data for tests
|
||||
Then I should see "Course 1"
|
||||
And I should see "Course 2"
|
||||
And I should see "Course 3"
|
||||
When I go to the courses management page
|
||||
And I follow "Cat 1"
|
||||
Then I should see "Cat 2"
|
||||
And I should see "Cat 3"
|
||||
When I follow "Cat 3"
|
||||
Then I should see "Course 1"
|
||||
And I should see "Course 2"
|
||||
When I select "Cat 2" from "Course categories:"
|
||||
Then I should see "No courses in this category"
|
||||
When I select "Miscellaneous" from "Course categories:"
|
||||
Then I should see "Course 3"
|
||||
|
||||
@javascript
|
||||
Scenario: Add a bunch of groups and groupings
|
||||
|
||||
@@ -38,5 +38,9 @@ function xmldb_tool_customlang_upgrade($oldversion) {
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ $lng = required_param('lng', PARAM_LANG);
|
||||
$currentpage = optional_param('p', 0, PARAM_INT);
|
||||
$translatorsubmitted = optional_param('translatorsubmitted', 0, PARAM_BOOL);
|
||||
|
||||
$PAGE->set_pagelayout('standard');
|
||||
$PAGE->set_pagelayout('report'); // Allows for wide page contents.
|
||||
$PAGE->set_url('/admin/tool/customlang/edit.php', array('lng' => $lng));
|
||||
navigation_node::override_active_url(new moodle_url('/admin/tool/customlang/index.php'));
|
||||
$PAGE->set_title(get_string('pluginname', 'tool_customlang'));
|
||||
|
||||
@@ -37,7 +37,7 @@ $string['missinglangparent'] = 'Missing parent language <em>{$a->parent}</em> of
|
||||
$string['nolangupdateneeded'] = 'All your language packs are up to date, no update is needed';
|
||||
$string['pluginname'] = 'Language packs';
|
||||
$string['purgestringcaches'] = 'Purge string caches';
|
||||
$string['remotelangnotavailable'] = 'Because Moodle can not connect to download.moodle.org, we are unable to do language pack installation automatically. Please download the appropriate zip file(s) from http://download.moodle.org, copy them to your {$a} directory and unzip them manually.';
|
||||
$string['remotelangnotavailable'] = 'Because Moodle cannot connect to download.moodle.org, it is not possible for language packs to be installed automatically. Please download the appropriate ZIP file(s) from <a href="http://download.moodle.org/langpack/">download.moodle.org/langpack</a>, copy them to your {$a} directory and unzip them manually.';
|
||||
$string['uninstall'] = 'Uninstall selected language pack';
|
||||
$string['uninstallconfirm'] = 'You are about to completely uninstall language pack {$a}, are you sure?';
|
||||
$string['updatelangs'] = 'Update all installed language packs';
|
||||
|
||||
@@ -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/>.
|
||||
|
||||
/**
|
||||
* Profiling tool export utility.
|
||||
*
|
||||
* @package tool_profiling
|
||||
* @copyright 2013 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir . '/xhprof/xhprof_moodle.php');
|
||||
|
||||
// Page parameters.
|
||||
$runid = required_param('runid', PARAM_ALPHANUM);
|
||||
$listurl = required_param('listurl', PARAM_PATH);
|
||||
|
||||
admin_externalpage_setup('toolprofiling');
|
||||
|
||||
$PAGE->navbar->add(get_string('export', 'tool_profiling'));
|
||||
|
||||
// Calculate export variables.
|
||||
$tempdir = 'profiling';
|
||||
make_temp_directory($tempdir);
|
||||
$runids = array($runid);
|
||||
$filename = $runid . '.mpr';
|
||||
$filepath = $CFG->tempdir . '/' . $tempdir . '/' . $filename;
|
||||
|
||||
// Generate the mpr file and send it.
|
||||
if (profiling_export_runs($runids, $filepath)) {
|
||||
send_file($filepath, $filename, 0, 0, false, false, '', true);
|
||||
unlink($filepath); // Delete once sent.
|
||||
die;
|
||||
}
|
||||
|
||||
// Something wrong happened, notice it and done.
|
||||
$urlparams = array(
|
||||
'runid' => $runid,
|
||||
'listurl' => $listurl);
|
||||
$url = new moodle_url('/admin/tool/profiling/index.php', $urlparams);
|
||||
notice(get_string('exportproblem', 'tool_profiling', $urlparams), $url);
|
||||
@@ -0,0 +1,70 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Profiling tool import utility.
|
||||
*
|
||||
* @package tool_profiling
|
||||
* @copyright 2013 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir . '/xhprof/xhprof_moodle.php');
|
||||
require_once(dirname(__FILE__) . '/import_form.php');
|
||||
|
||||
admin_externalpage_setup('toolprofiling');
|
||||
|
||||
$PAGE->navbar->add(get_string('import', 'tool_profiling'));
|
||||
|
||||
// Calculate export variables.
|
||||
$tempdir = 'profiling';
|
||||
make_temp_directory($tempdir);
|
||||
|
||||
// URL where we'll end, both on success and failure.
|
||||
$url = new moodle_url('/admin/tool/profiling/index.php');
|
||||
|
||||
// Instantiate the upload profiling runs form.
|
||||
$mform = new profiling_import_form();
|
||||
|
||||
// If there is any file to import.
|
||||
if ($data = $mform->get_data()) {
|
||||
$filename = $mform->get_new_filename('mprfile');
|
||||
$file = $CFG->tempdir . '/' . $tempdir . '/' . $filename;
|
||||
$status = $mform->save_file('mprfile', $file);
|
||||
if ($status) {
|
||||
// File saved properly, let's import it.
|
||||
$status = profiling_import_runs($file, $data->importprefix);
|
||||
}
|
||||
// Delete the temp file, not needed anymore.
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
if ($status) {
|
||||
// Import ended ok, let's redirect to main profiling page.
|
||||
redirect($url, get_string('importok', 'tool_profiling', $filename));
|
||||
}
|
||||
} else {
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading(get_string('import', 'tool_profiling'));
|
||||
$mform->display();
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
}
|
||||
|
||||
// Something wrong happened, notice it and done.
|
||||
notice(get_string('importproblem', 'tool_profiling', $filename), $url);
|
||||
@@ -0,0 +1,47 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Profiling tool import utility form.
|
||||
*
|
||||
* @package tool_profiling
|
||||
* @copyright 2013 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/formslib.php');
|
||||
|
||||
class profiling_import_form extends moodleform {
|
||||
public function definition () {
|
||||
global $CFG;
|
||||
|
||||
$mform = $this->_form;
|
||||
|
||||
$mform->addElement('header', 'settingsheader', get_string('upload'));
|
||||
|
||||
$mform->addElement('filepicker', 'mprfile', get_string('file'), null, array('accepted_types' => array('.mpr', '.zip')));
|
||||
$mform->addRule('mprfile', null, 'required');
|
||||
|
||||
$mform->addElement('text', 'importprefix',
|
||||
get_string('importprefix', 'tool_profiling'), array('size' => 10));
|
||||
$mform->setDefault('importprefix', $CFG->profilingimportprefix);
|
||||
$mform->setType('importprefix', PARAM_TAG);
|
||||
|
||||
$this->add_action_buttons(false, get_string('import', 'tool_profiling'));
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,7 @@
|
||||
/**
|
||||
* Profiling tool.
|
||||
*
|
||||
* @package tool
|
||||
* @subpackage profiling
|
||||
* @package tool_profiling
|
||||
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
@@ -161,6 +160,9 @@ if (isset($script)) {
|
||||
|
||||
echo $OUTPUT->heading($header);
|
||||
|
||||
// Print the controller block with different options.
|
||||
echo profiling_list_controls($listurl);
|
||||
|
||||
// TODO: Fix flexitable to validate tsort/thide/tshow/tifirs/tilast/page
|
||||
// TODO: Fix table_sql to allow it to work without WHERE clause
|
||||
// add silly condition (1 = 1) because of table_sql bug
|
||||
@@ -179,9 +181,6 @@ if (isset($script)) {
|
||||
$table->define_baseurl($baseurl);
|
||||
$table->column_suppress('url');
|
||||
$table->out(PROFILING_RUNSPERPAGE, true);
|
||||
|
||||
// Print the controller block with different options
|
||||
echo profiling_list_controls($listurl);
|
||||
}
|
||||
|
||||
// Footer.
|
||||
|
||||
@@ -24,13 +24,22 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['calls'] = 'Function calls';
|
||||
$string['cannotfindanyrunforurl'] = 'Sorry, cannot find any profiling run for the \'{$a}\' URL';
|
||||
$string['cannotfindanyrunforrunid'] = 'Sorry, cannot find the \'{$a}\' profiling run';
|
||||
$string['comment'] = 'Comment';
|
||||
$string['cputime'] = 'CPU time';
|
||||
$string['differencesbetween2runsof'] = 'Differences between 2 runs of {$a}';
|
||||
$string['executiontime'] = 'Execution time';
|
||||
$string['cputime'] = 'CPU time';
|
||||
$string['export'] = 'Export';
|
||||
$string['exportproblem'] = 'Some problem happened exporting the profile run "{$a->runid}" corresponding to the request "{$a->listurl}".';
|
||||
$string['exportthis'] = 'Export this profiling run';
|
||||
$string['import'] = 'Import';
|
||||
$string['importok'] = 'File "{$a}" imported successfully.';
|
||||
$string['importprefix'] = 'Import prefix';
|
||||
$string['importproblem'] = 'Some problem happened importing the file "{$a}".';
|
||||
$string['lastrunof'] = 'Summary of last run of {$a}';
|
||||
$string['markreferencerun'] = 'Mark as reference run/comment';
|
||||
$string['memory'] = 'Memory used';
|
||||
|
||||
@@ -17,14 +17,13 @@
|
||||
/**
|
||||
* Version details.
|
||||
*
|
||||
* @package tool
|
||||
* @subpackage profiling
|
||||
* @package tool_profiling
|
||||
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2013050100; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->version = 2013050200; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2013050100; // Requires this Moodle version
|
||||
$plugin->component = 'tool_profiling'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -23,6 +23,7 @@ echo $OUTPUT->header();
|
||||
//TODO: add support for large number of users
|
||||
|
||||
if ($confirm and confirm_sesskey()) {
|
||||
$notifications = '';
|
||||
list($in, $params) = $DB->get_in_or_equal($SESSION->bulk_users);
|
||||
$rs = $DB->get_recordset_select('user', "id $in", $params, '', 'id, username, secret, confirmed, auth, firstname, lastname');
|
||||
foreach ($rs as $user) {
|
||||
@@ -32,12 +33,19 @@ if ($confirm and confirm_sesskey()) {
|
||||
$auth = get_auth_plugin($user->auth);
|
||||
$result = $auth->user_confirm($user->username, $user->secret);
|
||||
if ($result != AUTH_CONFIRM_OK && $result != AUTH_CONFIRM_ALREADY) {
|
||||
echo $OUTPUT->notification(get_string('usernotconfirmed', '', fullname($user, true)));
|
||||
$notifications .= $OUTPUT->notification(get_string('usernotconfirmed', '', fullname($user, true)));
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
redirect($return, get_string('changessaved'));
|
||||
|
||||
echo $OUTPUT->box_start('generalbox', 'notice');
|
||||
if (!empty($notifications)) {
|
||||
echo $notifications;
|
||||
} else {
|
||||
echo $OUTPUT->notification(get_string('changessaved'), 'notifysuccess');
|
||||
}
|
||||
$continue = new single_button(new moodle_url($return), get_string('continue'), 'post');
|
||||
echo $OUTPUT->render($continue);
|
||||
echo $OUTPUT->box_end();
|
||||
} else {
|
||||
list($in, $params) = $DB->get_in_or_equal($SESSION->bulk_users);
|
||||
$userlist = $DB->get_records_select_menu('user', "id $in", $params, 'fullname', 'id,'.$DB->sql_fullname().' AS fullname');
|
||||
|
||||
@@ -23,20 +23,27 @@ echo $OUTPUT->header();
|
||||
//TODO: add support for large number of users
|
||||
|
||||
if ($confirm and confirm_sesskey()) {
|
||||
|
||||
$notifications = '';
|
||||
list($in, $params) = $DB->get_in_or_equal($SESSION->bulk_users);
|
||||
$rs = $DB->get_recordset_select('user', "id $in", $params);
|
||||
foreach ($rs as $user) {
|
||||
if (!is_siteadmin($user) and $USER->id != $user->id and delete_user($user)) {
|
||||
unset($SESSION->bulk_users[$user->id]);
|
||||
} else {
|
||||
echo $OUTPUT->notification(get_string('deletednot', '', fullname($user, true)));
|
||||
$notifications .= $OUTPUT->notification(get_string('deletednot', '', fullname($user, true)));
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
session_gc(); // remove stale sessions
|
||||
redirect($return, get_string('changessaved'));
|
||||
|
||||
echo $OUTPUT->box_start('generalbox', 'notice');
|
||||
if (!empty($notifications)) {
|
||||
echo $notifications;
|
||||
} else {
|
||||
echo $OUTPUT->notification(get_string('changessaved'), 'notifysuccess');
|
||||
}
|
||||
$continue = new single_button(new moodle_url($return), get_string('continue'), 'post');
|
||||
echo $OUTPUT->render($continue);
|
||||
echo $OUTPUT->box_end();
|
||||
} else {
|
||||
list($in, $params) = $DB->get_in_or_equal($SESSION->bulk_users);
|
||||
$userlist = $DB->get_records_select_menu('user', "id $in", $params, 'fullname', 'id,'.$DB->sql_fullname().' AS fullname');
|
||||
|
||||
+22
-1
@@ -174,7 +174,7 @@ class auth_plugin_cas extends auth_plugin_ldap {
|
||||
*
|
||||
*/
|
||||
function connectCAS() {
|
||||
global $PHPCAS_CLIENT;
|
||||
global $CFG, $PHPCAS_CLIENT;
|
||||
|
||||
if (!is_object($PHPCAS_CLIENT)) {
|
||||
// Make sure phpCAS doesn't try to start a new PHP session when connecting to the CAS server.
|
||||
@@ -185,6 +185,27 @@ class auth_plugin_cas extends auth_plugin_ldap {
|
||||
}
|
||||
}
|
||||
|
||||
// If Moodle is configured to use a proxy, phpCAS needs some curl options set.
|
||||
if (!empty($CFG->proxyhost) && !is_proxybypass($this->config->hostname)) {
|
||||
phpCAS::setExtraCurlOption(CURLOPT_PROXY, $CFG->proxyhost);
|
||||
if (!empty($CFG->proxyport)) {
|
||||
phpCAS::setExtraCurlOption(CURLOPT_PROXYPORT, $CFG->proxyport);
|
||||
}
|
||||
if (!empty($CFG->proxytype)) {
|
||||
// Only set CURLOPT_PROXYTYPE if it's something other than the curl-default http
|
||||
if ($CFG->proxytype == 'SOCKS5') {
|
||||
phpCAS::setExtraCurlOption(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
|
||||
}
|
||||
}
|
||||
if (!empty($CFG->proxyuser) and !empty($CFG->proxypassword)) {
|
||||
phpCAS::setExtraCurlOption(CURLOPT_PROXYUSERPWD, $CFG->proxyuser.':'.$CFG->proxypassword);
|
||||
if (defined('CURLOPT_PROXYAUTH')) {
|
||||
// any proxy authentication if PHP 5.1
|
||||
phpCAS::setExtraCurlOption(CURLOPT_PROXYAUTH, CURLAUTH_BASIC | CURLAUTH_NTLM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($this->config->certificate_check && $this->config->certificate_path){
|
||||
phpCAS::setCasServerCACert($this->config->certificate_path);
|
||||
}else{
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* CAS authentication plugin upgrade code
|
||||
*
|
||||
* @package auth_cas
|
||||
* @copyright 2013 Iñaki Arenaza
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param int $oldversion the version we are upgrading from
|
||||
* @return bool result
|
||||
*/
|
||||
function xmldb_auth_cas_upgrade($oldversion) {
|
||||
|
||||
// Moodle v2.5.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
// MDL-39323 New setting in 2.5, make sure it's defined.
|
||||
if ($oldversion < 2013052100) {
|
||||
if (get_config('start_tls', 'auth/cas') === false) {
|
||||
set_config('start_tls', 0, 'auth/cas');
|
||||
}
|
||||
upgrade_plugin_savepoint(true, 2013052100, 'auth', 'cas');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -26,6 +26,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2013050100; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->version = 2013052100; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2013050100; // Requires this Moodle version
|
||||
$plugin->component = 'auth_cas'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -598,6 +598,8 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
if ($user->firstaccess == 0) {
|
||||
$DB->set_field('user', 'firstaccess', time(), array('id'=>$user->id));
|
||||
}
|
||||
$euser = $DB->get_record('user', array('id' => $user->id));
|
||||
events_trigger('user_updated', $euser);
|
||||
return AUTH_CONFIRM_OK;
|
||||
}
|
||||
} else {
|
||||
@@ -770,6 +772,8 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
$updateuser->auth = 'nologin';
|
||||
$DB->update_record('user', $updateuser);
|
||||
echo "\t"; print_string('auth_dbsuspenduser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)); echo "\n";
|
||||
$euser = $DB->get_record('user', array('id' => $user->id));
|
||||
events_trigger('user_updated', $euser);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -795,6 +799,8 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
$updateuser->auth = $this->authtype;
|
||||
$DB->update_record('user', $updateuser);
|
||||
echo "\t"; print_string('auth_dbreviveduser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)); echo "\n";
|
||||
$euser = $DB->get_record('user', array('id' => $user->id));
|
||||
events_trigger('user_updated', $euser);
|
||||
}
|
||||
} else {
|
||||
print_string('nouserentriestorevive', 'auth_ldap');
|
||||
@@ -908,6 +914,8 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
|
||||
$id = $DB->insert_record('user', $user);
|
||||
echo "\t"; print_string('auth_dbinsertuser', 'auth_db', array('name'=>$user->username, 'id'=>$id)); echo "\n";
|
||||
$euser = $DB->get_record('user', array('id' => $user->id));
|
||||
events_trigger('user_created', $euser);
|
||||
if (!empty($this->config->forcechangepassword)) {
|
||||
set_user_preference('auth_forcepasswordchange', 1, $id);
|
||||
}
|
||||
@@ -978,6 +986,10 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($updatekeys)) {
|
||||
$euser = $DB->get_record('user', array('id' => $userid));
|
||||
events_trigger('user_updated', $euser);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* LDAP authentication plugin upgrade code
|
||||
*
|
||||
* @package auth_ldap
|
||||
* @copyright 2013 Iñaki Arenaza
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param int $oldversion the version we are upgrading from
|
||||
* @return bool result
|
||||
*/
|
||||
function xmldb_auth_ldap_upgrade($oldversion) {
|
||||
|
||||
// Moodle v2.5.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
// MDL-39323 New setting in 2.5, make sure it's defined.
|
||||
if ($oldversion < 2013052100) {
|
||||
if (get_config('start_tls', 'auth/ldap') === false) {
|
||||
set_config('start_tls', 0, 'auth/ldap');
|
||||
}
|
||||
upgrade_plugin_savepoint(true, 2013052100, 'auth', 'ldap');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -25,6 +25,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2013050100; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->version = 2013052100; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2013050100; // Requires this Moodle version
|
||||
$plugin->component = 'auth_ldap'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -40,5 +40,9 @@ function xmldb_auth_manual_upgrade($oldversion) {
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -40,5 +40,9 @@ function xmldb_auth_mnet_upgrade($oldversion) {
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,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 = 2013050100;
|
||||
const VERSION = 2013051400;
|
||||
const RELEASE = '2.5';
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,11 @@ class backup_final_task extends backup_task {
|
||||
// Generate the course completion
|
||||
$this->add_step(new backup_course_completion_structure_step('course_completion', 'completion.xml'));
|
||||
|
||||
// Conditionally generate the badges file.
|
||||
if ($this->get_setting_value('badges')) {
|
||||
$this->add_step(new backup_badges_structure_step('course_badges', 'badges.xml'));
|
||||
}
|
||||
|
||||
// Generate the scales file with all the (final) annotated scales
|
||||
$this->add_step(new backup_final_scales_structure_step('scaleslist', 'scales.xml'));
|
||||
|
||||
|
||||
@@ -122,6 +122,13 @@ class backup_root_task extends backup_task {
|
||||
$this->add_setting($comments);
|
||||
$users->add_dependency($comments);
|
||||
|
||||
// Define badges (dependent of activities).
|
||||
$badges = new backup_badges_setting('badges', base_setting::IS_BOOLEAN, true);
|
||||
$badges->set_ui(new backup_setting_ui_checkbox($badges, get_string('rootsettingbadges', 'backup')));
|
||||
$this->add_setting($badges);
|
||||
$activities->add_dependency($badges);
|
||||
$users->add_dependency($badges);
|
||||
|
||||
// Define calendar events (dependent of users)
|
||||
$events = new backup_calendarevents_setting('calendarevents', base_setting::IS_BOOLEAN, true);
|
||||
$events->set_ui(new backup_setting_ui_checkbox($events, get_string('rootsettingcalendarevents', 'backup')));
|
||||
|
||||
@@ -101,6 +101,12 @@ class backup_logs_setting extends backup_anonymize_setting {}
|
||||
*/
|
||||
class backup_comments_setting extends backup_anonymize_setting {}
|
||||
|
||||
/**
|
||||
* root setting to control if backup will include badges or not,
|
||||
* depends on @backup_activities_setting
|
||||
*/
|
||||
class backup_badges_setting extends backup_generic_setting {}
|
||||
|
||||
/**
|
||||
* root setting to control if backup will include
|
||||
* calender events or no (any level), depends of @backup_users_setting
|
||||
|
||||
@@ -812,6 +812,83 @@ class backup_comments_structure_step extends backup_structure_step {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* structure step in charge of constructing the badges.xml file for all the badges found
|
||||
* in a given context
|
||||
*/
|
||||
class backup_badges_structure_step extends backup_structure_step {
|
||||
|
||||
protected function execute_condition() {
|
||||
// Check that all activities have been included.
|
||||
if ($this->task->is_excluding_activities()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function define_structure() {
|
||||
|
||||
// Define each element separated.
|
||||
|
||||
$badges = new backup_nested_element('badges');
|
||||
$badge = new backup_nested_element('badge', array('id'), array('name', 'description',
|
||||
'timecreated', 'timemodified', 'usercreated', 'usermodified', 'issuername',
|
||||
'issuerurl', 'issuercontact', 'expiredate', 'expireperiod', 'type', 'courseid',
|
||||
'message', 'messagesubject', 'attachment', 'notification', 'status', 'nextcron'));
|
||||
|
||||
$criteria = new backup_nested_element('criteria');
|
||||
$criterion = new backup_nested_element('criterion', array('id'), array('badgeid',
|
||||
'criteriatype', 'method'));
|
||||
|
||||
$parameters = new backup_nested_element('parameters');
|
||||
$parameter = new backup_nested_element('parameter', array('id'), array('critid',
|
||||
'name', 'value', 'criteriatype'));
|
||||
|
||||
$manual_awards = new backup_nested_element('manual_awards');
|
||||
$manual_award = new backup_nested_element('manual_award', array('id'), array('badgeid',
|
||||
'recipientid', 'issuerid', 'issuerrole', 'datemet'));
|
||||
|
||||
// Build the tree.
|
||||
|
||||
$badges->add_child($badge);
|
||||
$badge->add_child($criteria);
|
||||
$criteria->add_child($criterion);
|
||||
$criterion->add_child($parameters);
|
||||
$parameters->add_child($parameter);
|
||||
$badge->add_child($manual_awards);
|
||||
$manual_awards->add_child($manual_award);
|
||||
|
||||
// Define sources.
|
||||
|
||||
$badge->set_source_table('badge', array('courseid' => backup::VAR_COURSEID));
|
||||
$criterion->set_source_table('badge_criteria', array('badgeid' => backup::VAR_PARENTID));
|
||||
|
||||
$parametersql = 'SELECT cp.*, c.criteriatype
|
||||
FROM {badge_criteria_param} cp JOIN {badge_criteria} c
|
||||
ON cp.critid = c.id
|
||||
WHERE critid = :critid';
|
||||
$parameterparams = array('critid' => backup::VAR_PARENTID);
|
||||
$parameter->set_source_sql($parametersql, $parameterparams);
|
||||
|
||||
$manual_award->set_source_table('badge_manual_award', array('badgeid' => backup::VAR_PARENTID));
|
||||
|
||||
// Define id annotations.
|
||||
|
||||
$badge->annotate_ids('user', 'usercreated');
|
||||
$badge->annotate_ids('user', 'usermodified');
|
||||
$criterion->annotate_ids('badge', 'badgeid');
|
||||
$parameter->annotate_ids('criterion', 'critid');
|
||||
$badge->annotate_files('badges', 'badgeimage', 'id');
|
||||
$manual_award->annotate_ids('badge', 'badgeid');
|
||||
$manual_award->annotate_ids('user', 'recipientid');
|
||||
$manual_award->annotate_ids('user', 'issuerid');
|
||||
$manual_award->annotate_ids('role', 'issuerrole');
|
||||
|
||||
// Return the root element ($badges).
|
||||
return $badges;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* structure step in charge of constructing the calender.xml file for all the events found
|
||||
* in a given context
|
||||
|
||||
@@ -73,8 +73,20 @@ class restore_course_task extends restore_task {
|
||||
|
||||
$this->add_step(new restore_course_legacy_files_step('legacy_files'));
|
||||
|
||||
// Restore course enrolments (plugins and membership). Conditionally prevented for any IMPORT/HUB operation
|
||||
if ($this->plan->get_mode() != backup::MODE_IMPORT && $this->plan->get_mode() != backup::MODE_HUB) {
|
||||
// Deal with enrolment methods and user enrolments.
|
||||
if ($this->plan->get_mode() == backup::MODE_IMPORT) {
|
||||
// No need to do anything with enrolments.
|
||||
|
||||
} else if (!$this->get_setting_value('users') or $this->plan->get_mode() == backup::MODE_HUB) {
|
||||
if ($this->get_target() == backup::TARGET_CURRENT_ADDING or $this->get_target() == backup::TARGET_EXISTING_ADDING) {
|
||||
// Keep current enrolments unchanged.
|
||||
} else {
|
||||
// If no instances yet add default enrol methods the same way as when creating new course in UI.
|
||||
$this->add_step(new restore_default_enrolments_step('default_enrolments'));
|
||||
}
|
||||
|
||||
} else {
|
||||
// Restore course enrolment data.
|
||||
$this->add_step(new restore_enrolments_structure_step('course_enrolments', 'enrolments.xml'));
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,11 @@ class restore_final_task extends restore_task {
|
||||
$this->add_step(new restore_course_completion_structure_step('course_completion', 'completion.xml'));
|
||||
}
|
||||
|
||||
// Conditionally restore course badges.
|
||||
if ($this->get_setting_value('badges')) {
|
||||
$this->add_step(new restore_badges_structure_step('course_badges', 'badges.xml'));
|
||||
}
|
||||
|
||||
// Review all the module_availability records in backup_ids in order
|
||||
// to match them with existing modules / grade items.
|
||||
$this->add_step(new restore_process_course_modules_availability('process_modules_availability'));
|
||||
@@ -143,6 +148,9 @@ class restore_final_task extends restore_task {
|
||||
$rules[] = new restore_log_rule('course', 'report stats', 'report/stats/index.php?id={course}', '{course}');
|
||||
$rules[] = new restore_log_rule('course', 'view section', 'view.php?id={course}§ionid={course_section}', '{course_section}');
|
||||
|
||||
// module 'grade' rules
|
||||
$rules[] = new restore_log_rule('grade', 'update', 'report/grader/index.php?id={course}', null);
|
||||
|
||||
// module 'user' rules
|
||||
$rules[] = new restore_log_rule('user', 'view', 'view.php?id={user}&course={course}', '{user}');
|
||||
$rules[] = new restore_log_rule('user', 'change password', 'view.php?id={user}&course={course}', '{user}');
|
||||
|
||||
@@ -115,6 +115,7 @@ class restore_root_task extends restore_task {
|
||||
$rootenrolmanual = new restore_users_setting('enrol_migratetomanual', base_setting::IS_BOOLEAN, false);
|
||||
$rootenrolmanual->set_ui(new backup_setting_ui_checkbox($rootenrolmanual, get_string('rootenrolmanual', 'backup')));
|
||||
$rootenrolmanual->get_ui()->set_changeable(enrol_is_enabled('manual'));
|
||||
$rootenrolmanual->get_ui()->set_changeable($changeable);
|
||||
$this->add_setting($rootenrolmanual);
|
||||
$users->add_dependency($rootenrolmanual);
|
||||
|
||||
@@ -180,6 +181,20 @@ class restore_root_task extends restore_task {
|
||||
$this->add_setting($comments);
|
||||
$users->add_dependency($comments);
|
||||
|
||||
// Define badges (dependent of activities).
|
||||
$defaultvalue = false; // Safer default.
|
||||
$changeable = false;
|
||||
if (isset($rootsettings['badges']) && $rootsettings['badges']) { // Only enabled when available.
|
||||
$defaultvalue = true;
|
||||
$changeable = true;
|
||||
}
|
||||
$badges = new restore_badges_setting('badges', base_setting::IS_BOOLEAN, $defaultvalue);
|
||||
$badges->set_ui(new backup_setting_ui_checkbox($badges, get_string('rootsettingbadges', 'backup')));
|
||||
$badges->get_ui()->set_changeable($changeable);
|
||||
$this->add_setting($badges);
|
||||
$activities->add_dependency($badges);
|
||||
$users->add_dependency($badges);
|
||||
|
||||
// Define Calendar events (dependent of users)
|
||||
$defaultvalue = false; // Safer default
|
||||
$changeable = false;
|
||||
|
||||
@@ -63,6 +63,12 @@ class restore_activities_setting extends restore_generic_setting {}
|
||||
*/
|
||||
class restore_comments_setting extends restore_role_assignments_setting {}
|
||||
|
||||
/**
|
||||
* root setting to control if restore will create badges or not,
|
||||
* depends on @restore_activities_setting
|
||||
*/
|
||||
class restore_badges_setting extends restore_generic_setting {}
|
||||
|
||||
/**
|
||||
* root setting to control if restore will create
|
||||
* events or no, depends of @restore_users_setting
|
||||
|
||||
@@ -477,6 +477,8 @@ class restore_rebuild_course_cache extends restore_execution_step {
|
||||
|
||||
// Rebuild cache now that all sections are in place
|
||||
rebuild_course_cache($this->get_courseid());
|
||||
cache_helper::purge_by_event('changesincourse');
|
||||
cache_helper::purge_by_event('changesincoursecat');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,7 +633,7 @@ class restore_load_included_files extends restore_structure_step {
|
||||
// TODO: qtype_xxx should be replaced by proper backup_qtype_plugin::get_components_and_fileareas() use,
|
||||
// but then we'll need to change it to load plugins itself (because this is executed too early in restore)
|
||||
$isfileref = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'fileref', $data->id);
|
||||
$iscomponent = ($data->component == 'user' || $data->component == 'group' ||
|
||||
$iscomponent = ($data->component == 'user' || $data->component == 'group' || $data->component == 'badges' ||
|
||||
$data->component == 'grouping' || $data->component == 'grade' ||
|
||||
$data->component == 'question' || substr($data->component, 0, 5) == 'qtype');
|
||||
if ($isfileref || $iscomponent) {
|
||||
@@ -1623,6 +1625,29 @@ class restore_ras_and_caps_structure_step extends restore_structure_step {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If no instances yet add default enrol methods the same way as when creating new course in UI.
|
||||
*/
|
||||
class restore_default_enrolments_step extends restore_execution_step {
|
||||
public function define_execution() {
|
||||
global $DB;
|
||||
|
||||
$course = $DB->get_record('course', array('id'=>$this->get_courseid()), '*', MUST_EXIST);
|
||||
|
||||
if ($DB->record_exists('enrol', array('courseid'=>$this->get_courseid(), 'enrol'=>'manual'))) {
|
||||
// Something already added instances, do not add default instances.
|
||||
$plugins = enrol_get_plugins(true);
|
||||
foreach ($plugins as $plugin) {
|
||||
$plugin->restore_sync_course($course);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Looks like a newly created course.
|
||||
enrol_course_updated(true, $course, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This structure steps restores the enrol plugins and their underlying
|
||||
* enrolments, performing all the mappings and/or movements required
|
||||
@@ -1930,6 +1955,178 @@ class restore_comments_structure_step extends restore_structure_step {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This structure steps restores the badges and their configs
|
||||
*/
|
||||
class restore_badges_structure_step extends restore_structure_step {
|
||||
|
||||
/**
|
||||
* Conditionally decide if this step should be executed.
|
||||
*
|
||||
* This function checks the following parameters:
|
||||
*
|
||||
* 1. Badges and course badges are enabled on the site.
|
||||
* 2. The course/badges.xml file exists.
|
||||
* 3. All modules are restorable.
|
||||
* 4. All modules are marked for restore.
|
||||
*
|
||||
* @return bool True is safe to execute, false otherwise
|
||||
*/
|
||||
protected function execute_condition() {
|
||||
global $CFG;
|
||||
|
||||
// First check is badges and course level badges are enabled on this site.
|
||||
if (empty($CFG->enablebadges) || empty($CFG->badges_allowcoursebadges)) {
|
||||
// Disabled, don't restore course badges.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if badges.xml is included in the backup.
|
||||
$fullpath = $this->task->get_taskbasepath();
|
||||
$fullpath = rtrim($fullpath, '/') . '/' . $this->filename;
|
||||
if (!file_exists($fullpath)) {
|
||||
// Not found, can't restore course badges.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check we are able to restore all backed up modules.
|
||||
if ($this->task->is_missing_modules()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Finally check all modules within the backup are being restored.
|
||||
if ($this->task->is_excluding_activities()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function define_structure() {
|
||||
$paths = array();
|
||||
$paths[] = new restore_path_element('badge', '/badges/badge');
|
||||
$paths[] = new restore_path_element('criterion', '/badges/badge/criteria/criterion');
|
||||
$paths[] = new restore_path_element('parameter', '/badges/badge/criteria/criterion/parameters/parameter');
|
||||
$paths[] = new restore_path_element('manual_award', '/badges/badge/manual_awards/manual_award');
|
||||
|
||||
return $paths;
|
||||
}
|
||||
|
||||
public function process_badge($data) {
|
||||
global $DB, $CFG;
|
||||
|
||||
require_once($CFG->libdir . '/badgeslib.php');
|
||||
|
||||
$data = (object)$data;
|
||||
$data->usercreated = $this->get_mappingid('user', $data->usercreated);
|
||||
$data->usermodified = $this->get_mappingid('user', $data->usermodified);
|
||||
|
||||
// We'll restore the badge image.
|
||||
$restorefiles = true;
|
||||
|
||||
$courseid = $this->get_courseid();
|
||||
|
||||
$params = array(
|
||||
'name' => $data->name,
|
||||
'description' => $data->description,
|
||||
'image' => 0,
|
||||
'timecreated' => $this->apply_date_offset($data->timecreated),
|
||||
'timemodified' => $this->apply_date_offset($data->timemodified),
|
||||
'usercreated' => $data->usercreated,
|
||||
'usermodified' => $data->usermodified,
|
||||
'issuername' => $data->issuername,
|
||||
'issuerurl' => $data->issuerurl,
|
||||
'issuercontact' => $data->issuercontact,
|
||||
'expiredate' => $this->apply_date_offset($data->expiredate),
|
||||
'expireperiod' => $data->expireperiod,
|
||||
'type' => BADGE_TYPE_COURSE,
|
||||
'courseid' => $courseid,
|
||||
'message' => $data->message,
|
||||
'messagesubject' => $data->messagesubject,
|
||||
'attachment' => $data->attachment,
|
||||
'notification' => $data->notification,
|
||||
'status' => BADGE_STATUS_INACTIVE,
|
||||
'nextcron' => $this->apply_date_offset($data->nextcron)
|
||||
);
|
||||
|
||||
$newid = $DB->insert_record('badge', $params);
|
||||
$this->set_mapping('badge', $data->id, $newid, $restorefiles);
|
||||
}
|
||||
|
||||
public function process_criterion($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
|
||||
$params = array(
|
||||
'badgeid' => $this->get_new_parentid('badge'),
|
||||
'criteriatype' => $data->criteriatype,
|
||||
'method' => $data->method
|
||||
);
|
||||
$newid = $DB->insert_record('badge_criteria', $params);
|
||||
$this->set_mapping('criterion', $data->id, $newid);
|
||||
}
|
||||
|
||||
public function process_parameter($data) {
|
||||
global $DB, $CFG;
|
||||
|
||||
require_once($CFG->libdir . '/badgeslib.php');
|
||||
|
||||
$data = (object)$data;
|
||||
$criteriaid = $this->get_new_parentid('criterion');
|
||||
|
||||
// Parameter array that will go to database.
|
||||
$params = array();
|
||||
$params['critid'] = $criteriaid;
|
||||
|
||||
$oldparam = explode('_', $data->name);
|
||||
|
||||
if ($data->criteriatype == BADGE_CRITERIA_TYPE_ACTIVITY) {
|
||||
$module = $this->get_mappingid('course_module', $oldparam[1]);
|
||||
$params['name'] = $oldparam[0] . '_' . $module;
|
||||
$params['value'] = $oldparam[0] == 'module' ? $module : $data->value;
|
||||
} else if ($data->criteriatype == BADGE_CRITERIA_TYPE_COURSE) {
|
||||
$params['name'] = $oldparam[0] . '_' . $this->get_courseid();
|
||||
$params['value'] = $oldparam[0] == 'course' ? $this->get_courseid() : $data->value;
|
||||
} else if ($data->criteriatype == BADGE_CRITERIA_TYPE_MANUAL) {
|
||||
$role = $this->get_mappingid('role', $data->value);
|
||||
if (!empty($role)) {
|
||||
$params['name'] = 'role_' . $role;
|
||||
$params['value'] = $role;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$DB->record_exists('badge_criteria_param', $params)) {
|
||||
$DB->insert_record('badge_criteria_param', $params);
|
||||
}
|
||||
}
|
||||
|
||||
public function process_manual_award($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
$role = $this->get_mappingid('role', $data->issuerrole);
|
||||
|
||||
if (!empty($role)) {
|
||||
$award = array(
|
||||
'badgeid' => $this->get_new_parentid('badge'),
|
||||
'recipientid' => $this->get_mappingid('user', $data->recipientid),
|
||||
'issuerid' => $this->get_mappingid('user', $data->issuerid),
|
||||
'issuerrole' => $role,
|
||||
'datemet' => $this->apply_date_offset($data->datemet)
|
||||
);
|
||||
$DB->insert_record('badge_manual_award', $award);
|
||||
}
|
||||
}
|
||||
|
||||
protected function after_execute() {
|
||||
// Add related files.
|
||||
$this->add_related_files('badges', 'badgeimage', 'badge');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This structure steps restores the calendar events
|
||||
*/
|
||||
|
||||
@@ -483,6 +483,7 @@ abstract class backup_controller_dbops extends backup_dbops {
|
||||
'backup_general_blocks' => 'blocks',
|
||||
'backup_general_filters' => 'filters',
|
||||
'backup_general_comments' => 'comments',
|
||||
'backup_general_badges' => 'badges',
|
||||
'backup_general_userscompletion' => 'userscompletion',
|
||||
'backup_general_logs' => 'logs',
|
||||
'backup_general_histories' => 'grade_histories'
|
||||
|
||||
-95
@@ -26,101 +26,6 @@ defined('MOODLE_INTERNAL') || die();
|
||||
// Include all the needed stuff
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
|
||||
|
||||
/**
|
||||
* Restore dbops tests (all).
|
||||
*/
|
||||
class restore_dbops_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Verify the xxx_ids_cached (in-memory backup_ids cache) stuff works as expected.
|
||||
*
|
||||
* Note that those private implementations are tested here by using the public
|
||||
* backup_ids API and later performing low-level tests.
|
||||
*/
|
||||
public function test_backup_ids_cached() {
|
||||
global $DB;
|
||||
$dbman = $DB->get_manager(); // We are going to use database_manager services.
|
||||
|
||||
$this->resetAfterTest(true); // Playing with temp tables, better reset once finished.
|
||||
|
||||
// Some variables and objects for testing.
|
||||
$restoreid = 'testrestoreid';
|
||||
|
||||
$mapping = new stdClass();
|
||||
$mapping->itemname = 'user';
|
||||
$mapping->itemid = 1;
|
||||
$mapping->newitemid = 2;
|
||||
$mapping->parentitemid = 3;
|
||||
$mapping->info = 'info';
|
||||
|
||||
// Create the backup_ids temp tables used by restore.
|
||||
restore_controller_dbops::create_restore_temp_tables($restoreid);
|
||||
|
||||
// Send one mapping using the public api with defaults.
|
||||
restore_dbops::set_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
// Get that mapping and verify everything is returned as expected.
|
||||
$result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
$this->assertSame($mapping->itemname, $result->itemname);
|
||||
$this->assertSame($mapping->itemid, $result->itemid);
|
||||
$this->assertSame(0, $result->newitemid);
|
||||
$this->assertSame(null, $result->parentitemid);
|
||||
$this->assertSame(null, $result->info);
|
||||
|
||||
// Drop the backup_xxx_temp temptables manually, so memory cache won't be invalidated.
|
||||
$dbman->drop_table(new xmldb_table('backup_ids_temp'));
|
||||
$dbman->drop_table(new xmldb_table('backup_files_temp'));
|
||||
|
||||
// Verify the mapping continues returning the same info,
|
||||
// now from cache (the table does not exist).
|
||||
$result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
$this->assertSame($mapping->itemname, $result->itemname);
|
||||
$this->assertSame($mapping->itemid, $result->itemid);
|
||||
$this->assertSame(0, $result->newitemid);
|
||||
$this->assertSame(null, $result->parentitemid);
|
||||
$this->assertSame(null, $result->info);
|
||||
|
||||
// Recreate the temp table, just to drop it using the restore API in
|
||||
// order to check that, then, the cache becomes invalid for the same request.
|
||||
restore_controller_dbops::create_restore_temp_tables($restoreid);
|
||||
restore_controller_dbops::drop_restore_temp_tables($restoreid);
|
||||
|
||||
// No cached info anymore, so the mapping request will arrive to
|
||||
// DB leading to error (temp table does not exist).
|
||||
try {
|
||||
$result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
$this->fail('Expecting an exception, none occurred');
|
||||
} catch (Exception $e) {
|
||||
$this->assertTrue($e instanceof dml_exception);
|
||||
$this->assertSame('Table "backup_ids_temp" does not exist', $e->getMessage());
|
||||
}
|
||||
|
||||
// Create the backup_ids temp tables once more.
|
||||
restore_controller_dbops::create_restore_temp_tables($restoreid);
|
||||
|
||||
// Send one mapping using the public api with complete values.
|
||||
restore_dbops::set_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid,
|
||||
$mapping->newitemid, $mapping->parentitemid, $mapping->info);
|
||||
// Get that mapping and verify everything is returned as expected.
|
||||
$result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
$this->assertSame($mapping->itemname, $result->itemname);
|
||||
$this->assertSame($mapping->itemid, $result->itemid);
|
||||
$this->assertSame($mapping->newitemid, $result->newitemid);
|
||||
$this->assertSame($mapping->parentitemid, $result->parentitemid);
|
||||
$this->assertSame($mapping->info, $result->info);
|
||||
|
||||
// Finally, drop the temp tables properly and get the DB error again (memory caches empty).
|
||||
restore_controller_dbops::drop_restore_temp_tables($restoreid);
|
||||
try {
|
||||
$result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
$this->fail('Expecting an exception, none occurred');
|
||||
} catch (Exception $e) {
|
||||
$this->assertTrue($e instanceof dml_exception);
|
||||
$this->assertSame('Table "backup_ids_temp" does not exist', $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup dbops tests (all).
|
||||
@@ -0,0 +1,122 @@
|
||||
<?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 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
// Include all the needed stuff
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
|
||||
|
||||
/**
|
||||
* Restore dbops tests (all).
|
||||
*/
|
||||
class restore_dbops_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Verify the xxx_ids_cached (in-memory backup_ids cache) stuff works as expected.
|
||||
*
|
||||
* Note that those private implementations are tested here by using the public
|
||||
* backup_ids API and later performing low-level tests.
|
||||
*/
|
||||
public function test_backup_ids_cached() {
|
||||
global $DB;
|
||||
$dbman = $DB->get_manager(); // We are going to use database_manager services.
|
||||
|
||||
$this->resetAfterTest(true); // Playing with temp tables, better reset once finished.
|
||||
|
||||
// Some variables and objects for testing.
|
||||
$restoreid = 'testrestoreid';
|
||||
|
||||
$mapping = new stdClass();
|
||||
$mapping->itemname = 'user';
|
||||
$mapping->itemid = 1;
|
||||
$mapping->newitemid = 2;
|
||||
$mapping->parentitemid = 3;
|
||||
$mapping->info = 'info';
|
||||
|
||||
// Create the backup_ids temp tables used by restore.
|
||||
restore_controller_dbops::create_restore_temp_tables($restoreid);
|
||||
|
||||
// Send one mapping using the public api with defaults.
|
||||
restore_dbops::set_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
// Get that mapping and verify everything is returned as expected.
|
||||
$result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
$this->assertSame($mapping->itemname, $result->itemname);
|
||||
$this->assertSame($mapping->itemid, $result->itemid);
|
||||
$this->assertSame(0, $result->newitemid);
|
||||
$this->assertSame(null, $result->parentitemid);
|
||||
$this->assertSame(null, $result->info);
|
||||
|
||||
// Drop the backup_xxx_temp temptables manually, so memory cache won't be invalidated.
|
||||
$dbman->drop_table(new xmldb_table('backup_ids_temp'));
|
||||
$dbman->drop_table(new xmldb_table('backup_files_temp'));
|
||||
|
||||
// Verify the mapping continues returning the same info,
|
||||
// now from cache (the table does not exist).
|
||||
$result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
$this->assertSame($mapping->itemname, $result->itemname);
|
||||
$this->assertSame($mapping->itemid, $result->itemid);
|
||||
$this->assertSame(0, $result->newitemid);
|
||||
$this->assertSame(null, $result->parentitemid);
|
||||
$this->assertSame(null, $result->info);
|
||||
|
||||
// Recreate the temp table, just to drop it using the restore API in
|
||||
// order to check that, then, the cache becomes invalid for the same request.
|
||||
restore_controller_dbops::create_restore_temp_tables($restoreid);
|
||||
restore_controller_dbops::drop_restore_temp_tables($restoreid);
|
||||
|
||||
// No cached info anymore, so the mapping request will arrive to
|
||||
// DB leading to error (temp table does not exist).
|
||||
try {
|
||||
$result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
$this->fail('Expecting an exception, none occurred');
|
||||
} catch (Exception $e) {
|
||||
$this->assertTrue($e instanceof dml_exception);
|
||||
$this->assertSame('Table "backup_ids_temp" does not exist', $e->getMessage());
|
||||
}
|
||||
|
||||
// Create the backup_ids temp tables once more.
|
||||
restore_controller_dbops::create_restore_temp_tables($restoreid);
|
||||
|
||||
// Send one mapping using the public api with complete values.
|
||||
restore_dbops::set_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid,
|
||||
$mapping->newitemid, $mapping->parentitemid, $mapping->info);
|
||||
// Get that mapping and verify everything is returned as expected.
|
||||
$result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
$this->assertSame($mapping->itemname, $result->itemname);
|
||||
$this->assertSame($mapping->itemid, $result->itemid);
|
||||
$this->assertSame($mapping->newitemid, $result->newitemid);
|
||||
$this->assertSame($mapping->parentitemid, $result->parentitemid);
|
||||
$this->assertSame($mapping->info, $result->info);
|
||||
|
||||
// Finally, drop the temp tables properly and get the DB error again (memory caches empty).
|
||||
restore_controller_dbops::drop_restore_temp_tables($restoreid);
|
||||
try {
|
||||
$result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid);
|
||||
$this->fail('Expecting an exception, none occurred');
|
||||
} catch (Exception $e) {
|
||||
$this->assertTrue($e instanceof dml_exception);
|
||||
$this->assertSame('Table "backup_ids_temp" does not exist', $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -383,6 +383,7 @@ abstract class backup_cron_automated_helper {
|
||||
'blocks' => 'backup_auto_blocks',
|
||||
'filters' => 'backup_auto_filters',
|
||||
'comments' => 'backup_auto_comments',
|
||||
'badges' => 'backup_auto_badges',
|
||||
'completion_information' => 'backup_auto_userscompletion',
|
||||
'logs' => 'backup_auto_logs',
|
||||
'histories' => 'backup_auto_histories'
|
||||
|
||||
@@ -322,7 +322,7 @@ class behat_backup extends behat_base {
|
||||
|
||||
try {
|
||||
$fieldnode = $this->find_field($locator);
|
||||
$field = behat_field_manager::get_field($fieldnode, $locator, $this->getSession());
|
||||
$field = behat_field_manager::get_form_field($fieldnode, $this->getSession());
|
||||
$field->set_value($value);
|
||||
|
||||
} catch (ElementNotFoundException $e) {
|
||||
|
||||
+24
-15
@@ -89,22 +89,31 @@ if (count($acceptedroles) > 1) {
|
||||
$roleids = array_map(create_function('$o', 'return $o->roleid;'), $roles);
|
||||
$selection = array_intersect($acceptedroles, $roleids);
|
||||
}
|
||||
list($usertest, $userparams) = $DB->get_in_or_equal($selection, SQL_PARAMS_NAMED, 'existing', true);
|
||||
$options = $DB->get_records_sql('SELECT * FROM {role} WHERE id ' . $usertest, $userparams);
|
||||
foreach ($options as $p) {
|
||||
$select[$p->id] = role_get_name($p);
|
||||
}
|
||||
if (!$role) {
|
||||
$pageurl = new moodle_url('/badges/award.php', array('id' => $badgeid));
|
||||
|
||||
if (!empty($selection)) {
|
||||
list($usertest, $userparams) = $DB->get_in_or_equal($selection, SQL_PARAMS_NAMED, 'existing', true);
|
||||
$options = $DB->get_records_sql('SELECT * FROM {role} WHERE id ' . $usertest, $userparams);
|
||||
foreach ($options as $p) {
|
||||
$select[$p->id] = role_get_name($p);
|
||||
}
|
||||
if (!$role) {
|
||||
$pageurl = new moodle_url('/badges/award.php', array('id' => $badgeid));
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->box(get_string('selectaward', 'badges') . $OUTPUT->single_select(new moodle_url($pageurl), 'role', $select));
|
||||
echo $OUTPUT->footer();
|
||||
die();
|
||||
} else {
|
||||
$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);
|
||||
}
|
||||
} else {
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->box(get_string('selectaward', 'badges') . $OUTPUT->single_select(new moodle_url($pageurl), 'role', $select));
|
||||
$return = html_writer::link(new moodle_url('recipients.php', array('id' => $badge->id)), $strrecipients);
|
||||
echo $OUTPUT->notification(get_string('notacceptedrole', 'badges', $return));
|
||||
echo $OUTPUT->footer();
|
||||
die();
|
||||
} else {
|
||||
$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);
|
||||
}
|
||||
} else {
|
||||
// User has to be an admin or the one with the required role.
|
||||
@@ -112,8 +121,8 @@ if (count($acceptedroles) > 1) {
|
||||
$usersids = array_keys($users);
|
||||
if (!$isadmin && !in_array($USER->id, $usersids)) {
|
||||
echo $OUTPUT->header();
|
||||
$rlink = html_writer::link(new moodle_url('recipients.php', array('id' => $badge->id)), get_string('recipients', 'badges'));
|
||||
echo $OUTPUT->notification(get_string('notacceptedrole', 'badges', $rlink));
|
||||
$return = html_writer::link(new moodle_url('recipients.php', array('id' => $badge->id)), $strrecipients);
|
||||
echo $OUTPUT->notification(get_string('notacceptedrole', 'badges', $return));
|
||||
echo $OUTPUT->footer();
|
||||
die();
|
||||
} else {
|
||||
|
||||
@@ -168,6 +168,7 @@ abstract class award_criteria {
|
||||
if (in_array('grade', $this->optional_params)) {
|
||||
$parameter[] =& $mform->createElement('static', 'mgrade_' . $param['id'], null, get_string('mingrade', 'badges'));
|
||||
$parameter[] =& $mform->createElement('text', 'grade_' . $param['id'], '', array('size' => '5'));
|
||||
$mform->setType('grade_' . $param['id'], PARAM_INT);
|
||||
}
|
||||
|
||||
if (in_array('bydate', $this->optional_params)) {
|
||||
|
||||
@@ -119,6 +119,7 @@ class award_criteria_course extends award_criteria {
|
||||
$parameter[] =& $mform->createElement('text', 'grade_' . $param['course'], '', array('size' => '5'));
|
||||
$parameter[] =& $mform->createElement('static', 'complby_' . $param['course'], null, get_string('bydate', 'badges'));
|
||||
$parameter[] =& $mform->createElement('date_selector', 'bydate_' . $param['course'], '', array('optional' => true));
|
||||
$mform->setType('grade_' . $param['course'], PARAM_INT);
|
||||
$mform->addGroup($parameter, 'param_' . $param['course'], '', array(' '), false);
|
||||
|
||||
$mform->disabledIf('bydate_' . $param['course'] . '[day]', 'bydate_' . $param['course'] . '[enabled]', 'notchecked');
|
||||
|
||||
+4
-1
@@ -191,8 +191,11 @@ if ($totalcount) {
|
||||
echo $output->render($badges);
|
||||
} else {
|
||||
echo $output->notification(get_string('nobadges', 'badges'));
|
||||
echo $OUTPUT->single_button(new moodle_url('newbadge.php', array('type' => $type, 'id' => $courseid)),
|
||||
|
||||
if (has_capability('moodle/badges:createbadge', $PAGE->context)) {
|
||||
echo $OUTPUT->single_button(new moodle_url('newbadge.php', array('type' => $type, 'id' => $courseid)),
|
||||
get_string('newbadge', 'badges'));
|
||||
}
|
||||
}
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
+6
-3
@@ -549,9 +549,12 @@ class core_badges_renderer extends plugin_renderer_base {
|
||||
$paging = new paging_bar($badges->totalcount, $badges->page, $badges->perpage, $this->page->url, 'page');
|
||||
|
||||
// New badge button.
|
||||
$n['type'] = $this->page->url->get_param('type');
|
||||
$n['id'] = $this->page->url->get_param('id');
|
||||
$htmlnew = $this->output->single_button(new moodle_url('newbadge.php', $n), get_string('newbadge', 'badges'));
|
||||
$htmlnew = '';
|
||||
if (has_capability('moodle/badges:createbadge', $this->page->context)) {
|
||||
$n['type'] = $this->page->url->get_param('type');
|
||||
$n['id'] = $this->page->url->get_param('id');
|
||||
$htmlnew = $this->output->single_button(new moodle_url('newbadge.php', $n), get_string('newbadge', 'badges'));
|
||||
}
|
||||
|
||||
$htmlpagingbar = $this->render($paging);
|
||||
$table = new html_table();
|
||||
|
||||
@@ -52,7 +52,7 @@ class block_badges extends block_base {
|
||||
return array(
|
||||
'admin' => false,
|
||||
'site-index' => true,
|
||||
'course-view' => false,
|
||||
'course-view' => true,
|
||||
'mod' => false,
|
||||
'my' => true
|
||||
);
|
||||
@@ -88,8 +88,16 @@ class block_badges extends block_base {
|
||||
|
||||
if (empty($CFG->enablebadges)) {
|
||||
$this->content->text .= get_string('badgesdisabled', 'badges');
|
||||
} else if ($badges = badges_get_user_badges($USER->id, null, 0, $this->config->numberofbadges)) {
|
||||
$output = $PAGE->get_renderer('core', 'badges');
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
$courseid = $this->page->course->id;
|
||||
if ($courseid == SITEID) {
|
||||
$courseid = null;
|
||||
}
|
||||
|
||||
if ($badges = badges_get_user_badges($USER->id, $courseid, 0, $this->config->numberofbadges)) {
|
||||
$output = $this->page->get_renderer('core', 'badges');
|
||||
$this->content->text = $output->print_badges_list($badges, $USER->id, true);
|
||||
} else {
|
||||
$this->content->text .= get_string('nothingtodisplay', 'block_badges');
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
|
||||
$capabilities = array(
|
||||
'block/badges:addinstance' => array(
|
||||
'riskbitmask' => RISK_PERSONAL,
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'archetypes' => array(
|
||||
'user' => CAP_ALLOW,
|
||||
'contextlevel' => CONTEXT_BLOCK,
|
||||
'archetypes' => array(
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
'manager' => CAP_ALLOW
|
||||
),
|
||||
'clonepermissionsfrom' => 'moodle/site:manageblocks'
|
||||
),
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2013050100; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2013050101; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2013050100; // Requires this Moodle version.
|
||||
$plugin->component = 'block_badges';
|
||||
@@ -54,5 +54,9 @@ function xmldb_block_community_upgrade($oldversion) {
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -60,5 +60,9 @@ function xmldb_block_completionstatus_upgrade($oldversion, $block) {
|
||||
// Savepoint reached.
|
||||
upgrade_block_savepoint(true, 2012112901, 'completionstatus');
|
||||
}
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -210,12 +210,12 @@ if (empty($completions)) {
|
||||
$agg = $info->get_aggregation_method($row['type']);
|
||||
echo '('. html_writer::start_tag('i');
|
||||
if ($agg == COMPLETION_AGGREGATION_ALL) {
|
||||
echo strtolower(get_string('all', 'completion'));
|
||||
echo textlib::strtolower(get_string('all', 'completion'));
|
||||
} else {
|
||||
echo strtolower(get_string('any', 'completion'));
|
||||
echo textlib::strtolower(get_string('any', 'completion'));
|
||||
}
|
||||
|
||||
echo html_writer::end_tag('i') .strtolower(get_string('required')).')';
|
||||
echo html_writer::end_tag('i') .textlib::strtolower(get_string('required')).')';
|
||||
$agg_type = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,9 @@ class block_course_overview_renderer extends plugin_renderer_base {
|
||||
|
||||
// No need to pass title through s() here as it will be done automatically by html_writer.
|
||||
$attributes = array('title' => $course->fullname);
|
||||
if (empty($course->visible)) {
|
||||
$attributes['class'] = 'dimmed';
|
||||
}
|
||||
if ($course->id > 0) {
|
||||
$courseurl = new moodle_url('/course/view.php', array('id' => $course->id));
|
||||
$coursefullname = format_string($course->fullname, true, $course->id);
|
||||
|
||||
@@ -65,5 +65,9 @@ function xmldb_block_course_summary_upgrade($oldversion, $block) {
|
||||
}
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
+9
-2
@@ -836,8 +836,15 @@ M.core_dock.genericblock.prototype = {
|
||||
}
|
||||
|
||||
// Must set the image src seperatly of we get an error with XML strict headers
|
||||
var moveto = Y.Node.create('<input type="image" class="moveto customcommand requiresjs" alt="'+M.str.block.addtodock+'" title="'+
|
||||
Y.Escape.html(M.util.get_string('dockblock', 'block', node.one('.header .title h2').getHTML())) +'" />');
|
||||
var moveto = Y.Node.create('<input type="image" class="moveto customcommand requiresjs" />');
|
||||
var header = node.one('.header .title h2');
|
||||
moveto.setAttribute('alt', Y.Escape.html(M.util.get_string('addtodock', 'block')));
|
||||
if (header) {
|
||||
moveto.setAttribute('title', Y.Escape.html(M.util.get_string('dockblock', 'block', header.getHTML())));
|
||||
} else {
|
||||
moveto.setAttribute('title', Y.Escape.html(M.util.get_string('addtodock', 'block')));
|
||||
}
|
||||
|
||||
var icon = 't/block_to_dock';
|
||||
if (right_to_left()) {
|
||||
icon = 't/block_to_dock_rtl';
|
||||
|
||||
@@ -40,5 +40,9 @@ function xmldb_block_html_upgrade($oldversion) {
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -340,7 +340,7 @@ class block_base {
|
||||
|
||||
/**
|
||||
* Subclasses should override this and return true if the
|
||||
* subclass block has a config_global.html file.
|
||||
* subclass block has a settings.php file.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
@@ -66,5 +66,9 @@ function xmldb_block_navigation_upgrade($oldversion, $block) {
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -105,7 +105,9 @@ class block_navigation_renderer extends plugin_renderer_base {
|
||||
if ($item->hidden) {
|
||||
$attributes['class'] = 'dimmed_text';
|
||||
}
|
||||
if (is_string($item->action) || empty($item->action) || ($item->type === navigation_node::TYPE_CATEGORY && empty($options['linkcategories']))) {
|
||||
if (is_string($item->action) || empty($item->action) ||
|
||||
(($item->type === navigation_node::TYPE_CATEGORY || $item->type === navigation_node::TYPE_MY_CATEGORY) &&
|
||||
empty($options['linkcategories']))) {
|
||||
$attributes['tabindex'] = '0'; //add tab support to span but still maintain character stream sequence.
|
||||
$content = html_writer::tag('span', $content, $attributes);
|
||||
} else if ($item->action instanceof action_link) {
|
||||
|
||||
+5
-1
@@ -391,11 +391,15 @@ BRANCH.prototype = {
|
||||
},
|
||||
/**
|
||||
* Attaches required events to the branch structure.
|
||||
*
|
||||
* @chainable
|
||||
* @method wire
|
||||
* @return {BRANCH} This function is chainable, it always returns itself.
|
||||
*/
|
||||
wire : function() {
|
||||
this.node = this.node || Y.one('#'+this.get('id'));
|
||||
if (!this.node) {
|
||||
return false;
|
||||
return this;
|
||||
}
|
||||
if (this.get('expandable')) {
|
||||
this.node.setAttribute('data-expandable', '1');
|
||||
|
||||
+1
-1
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
+5
-1
@@ -391,11 +391,15 @@ BRANCH.prototype = {
|
||||
},
|
||||
/**
|
||||
* Attaches required events to the branch structure.
|
||||
*
|
||||
* @chainable
|
||||
* @method wire
|
||||
* @return {BRANCH} This function is chainable, it always returns itself.
|
||||
*/
|
||||
wire : function() {
|
||||
this.node = this.node || Y.one('#'+this.get('id'));
|
||||
if (!this.node) {
|
||||
return false;
|
||||
return this;
|
||||
}
|
||||
if (this.get('expandable')) {
|
||||
this.node.setAttribute('data-expandable', '1');
|
||||
|
||||
+5
-1
@@ -389,11 +389,15 @@ BRANCH.prototype = {
|
||||
},
|
||||
/**
|
||||
* Attaches required events to the branch structure.
|
||||
*
|
||||
* @chainable
|
||||
* @method wire
|
||||
* @return {BRANCH} This function is chainable, it always returns itself.
|
||||
*/
|
||||
wire : function() {
|
||||
this.node = this.node || Y.one('#'+this.get('id'));
|
||||
if (!this.node) {
|
||||
return false;
|
||||
return this;
|
||||
}
|
||||
if (this.get('expandable')) {
|
||||
this.node.setAttribute('data-expandable', '1');
|
||||
|
||||
@@ -53,9 +53,6 @@ function xmldb_block_section_links_upgrade($oldversion, $block) {
|
||||
// Moodle v2.4.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
// Moodle v2.5.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
if ($oldversion < 2013012200.00) {
|
||||
|
||||
// The section links block used to use its own crazy plugin name.
|
||||
@@ -78,5 +75,10 @@ function xmldb_block_section_links_upgrade($oldversion, $block) {
|
||||
upgrade_block_savepoint(true, 2013012200.00, 'section_links');
|
||||
}
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -65,5 +65,9 @@ function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
|
||||
}
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -66,5 +66,9 @@ function xmldb_block_settings_upgrade($oldversion, $block) {
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
Vendored
+5
@@ -350,6 +350,11 @@ class cache_helper {
|
||||
* @param string $definition
|
||||
*/
|
||||
protected static function ensure_ready_for_stats($store, $definition) {
|
||||
// This function is performance-sensitive, so exit as quickly as possible
|
||||
// if we do not need to do anything.
|
||||
if (isset(self::$stats[$definition][$store])) {
|
||||
return;
|
||||
}
|
||||
if (!array_key_exists($definition, self::$stats)) {
|
||||
self::$stats[$definition] = array(
|
||||
$store => array(
|
||||
|
||||
Vendored
+11
-4
@@ -912,7 +912,8 @@ class cache implements cache_loader {
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_in_persist_cache($key) {
|
||||
if (is_array($key)) {
|
||||
// This method of checking if an array was supplied is faster than is_array.
|
||||
if ($key === (array)$key) {
|
||||
$key = $key['key'];
|
||||
}
|
||||
// This could be written as a single line, however it has been split because the ttl check is faster than the instanceof
|
||||
@@ -933,10 +934,15 @@ class cache implements cache_loader {
|
||||
* @return mixed|false The data from the persist cache or false if it wasn't there.
|
||||
*/
|
||||
protected function get_from_persist_cache($key) {
|
||||
if (is_array($key)) {
|
||||
// This method of checking if an array was supplied is faster than is_array.
|
||||
if ($key === (array)$key) {
|
||||
$key = $key['key'];
|
||||
}
|
||||
if (!$this->persist || !array_key_exists($key, $this->persistcache)) {
|
||||
// This isset check is faster than array_key_exists but will return false
|
||||
// for null values, meaning null values will come from backing store not
|
||||
// the persist cache. We think this okay because null usage should be
|
||||
// very rare (see comment in MDL-39472).
|
||||
if (!$this->persist || !isset($this->persistcache[$key])) {
|
||||
$result = false;
|
||||
} else {
|
||||
$data = $this->persistcache[$key];
|
||||
@@ -976,7 +982,8 @@ class cache implements cache_loader {
|
||||
* @return bool
|
||||
*/
|
||||
protected function set_in_persist_cache($key, $data) {
|
||||
if (is_array($key)) {
|
||||
// This method of checking if an array was supplied is faster than is_array.
|
||||
if ($key === (array)$key) {
|
||||
$key = $key['key'];
|
||||
}
|
||||
$this->persistcache[$key] = $data;
|
||||
|
||||
-1
@@ -27,7 +27,6 @@
|
||||
*/
|
||||
|
||||
require_once($CFG->dirroot.'/cache/forms.php');
|
||||
require_once($CFG->dirroot.'/cache/stores/file/lib.php');
|
||||
|
||||
/**
|
||||
* Form for adding a file instance.
|
||||
|
||||
Vendored
+34
@@ -101,6 +101,19 @@ class cachestore_file extends cache_store implements cache_is_key_aware, cache_i
|
||||
*/
|
||||
protected $definition;
|
||||
|
||||
/**
|
||||
* A reference to the global $CFG object.
|
||||
*
|
||||
* You may be asking yourself why on earth this is here, but there is a good reason.
|
||||
* By holding onto a reference of the $CFG object we can be absolutely sure that it won't be destroyed before
|
||||
* we are done with it.
|
||||
* This makes it possible to use a cache within a destructor method for the purposes of
|
||||
* delayed writes. Like how the session mechanisms work.
|
||||
*
|
||||
* @var stdClass
|
||||
*/
|
||||
private $cfg = null;
|
||||
|
||||
/**
|
||||
* Constructs the store instance.
|
||||
*
|
||||
@@ -111,6 +124,13 @@ class cachestore_file extends cache_store implements cache_is_key_aware, cache_i
|
||||
* @param array $configuration
|
||||
*/
|
||||
public function __construct($name, array $configuration = array()) {
|
||||
global $CFG;
|
||||
|
||||
if (isset($CFG)) {
|
||||
// Hold onto a reference of the global $CFG object.
|
||||
$this->cfg = $CFG;
|
||||
}
|
||||
|
||||
$this->name = $name;
|
||||
if (array_key_exists('path', $configuration) && $configuration['path'] !== '') {
|
||||
$this->custompath = true;
|
||||
@@ -605,13 +625,27 @@ class cachestore_file extends cache_store implements cache_is_key_aware, cache_i
|
||||
* @throws coding_exception
|
||||
*/
|
||||
protected function ensure_path_exists() {
|
||||
global $CFG;
|
||||
if (!is_writable($this->path)) {
|
||||
if ($this->custompath && !$this->autocreate) {
|
||||
throw new coding_exception('File store path does not exist. It must exist and be writable by the web server.');
|
||||
}
|
||||
$createdcfg = false;
|
||||
if (!isset($CFG)) {
|
||||
// This can only happen during destruction of objects.
|
||||
// A cache is being used within a destructor, php is ending a request and $CFG has
|
||||
// already being cleaned up.
|
||||
// Rebuild $CFG with directory permissions just to complete this write.
|
||||
$CFG = $this->cfg;
|
||||
$createdcfg = true;
|
||||
}
|
||||
if (!make_writable_directory($this->path, false)) {
|
||||
throw new coding_exception('File store path does not exist and can not be created.');
|
||||
}
|
||||
if ($createdcfg) {
|
||||
// We re-created it so we'll clean it up.
|
||||
unset($CFG);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
-1
@@ -27,7 +27,6 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->dirroot.'/cache/forms.php');
|
||||
require_once($CFG->dirroot.'/cache/stores/memcached/lib.php');
|
||||
|
||||
/**
|
||||
* Form for adding a memcache instance.
|
||||
|
||||
-1
@@ -35,7 +35,6 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
// Include the necessary evils.
|
||||
require_once($CFG->dirroot.'/cache/forms.php');
|
||||
require_once($CFG->dirroot.'/cache/stores/mongodb/lib.php');
|
||||
|
||||
/**
|
||||
* The form to add an instance of the MongoDB store to the system.
|
||||
|
||||
@@ -86,6 +86,7 @@ $search .= html_writer::start_tag('div');
|
||||
$search .= html_writer::label(get_string('searchcohort', 'cohort'), 'cohort_search_q'); // No : in form labels!
|
||||
$search .= html_writer::empty_tag('input', array('id'=>'cohort_search_q', 'type'=>'text', 'name'=>'search', 'value'=>$searchquery));
|
||||
$search .= html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('search', 'cohort')));
|
||||
$search .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'contextid', 'value'=>$contextid));
|
||||
$search .= html_writer::end_tag('div');
|
||||
$search .= html_writer::end_tag('form');
|
||||
echo $search;
|
||||
|
||||
@@ -12,7 +12,7 @@ Feature: Add cohorts of users
|
||||
| user3 | Third | User | third@user.com |
|
||||
| user4 | Forth | User | forth@user.com |
|
||||
And I log in as "admin"
|
||||
And I expand "Front page settings" node
|
||||
And I collapse "Front page settings" node
|
||||
And I expand "Site administration" node
|
||||
And I expand "Users" node
|
||||
And I expand "Accounts" node
|
||||
|
||||
@@ -65,7 +65,7 @@ class behat_cohort extends behat_base {
|
||||
$steps = array_merge(
|
||||
array(
|
||||
new Given('I am on homepage'),
|
||||
new Given('I expand "Front page settings" node'),
|
||||
new Given('I collapse "Front page settings" node'),
|
||||
new Given('I expand "Site administration" node'),
|
||||
new Given('I expand "Users" node'),
|
||||
new Given('I expand "Accounts" node'),
|
||||
|
||||
@@ -22,7 +22,7 @@ Feature: Upload users to a cohort
|
||||
And I follow "Course 2"
|
||||
And I add "Cohort sync" enrolment method with:
|
||||
| Cohort | Cohort 2 |
|
||||
And I expand "Course administration" node
|
||||
And I collapse "Course administration" node
|
||||
And I expand "Site administration" node
|
||||
And I expand "Users" node
|
||||
And I expand "Accounts" node
|
||||
|
||||
@@ -554,6 +554,11 @@ $CFG->admin = 'admin';
|
||||
//=========================================================================
|
||||
// 11. BEHAT SUPPORT
|
||||
//=========================================================================
|
||||
// Behat needs a separate data directory and unique database prefix:
|
||||
//
|
||||
// $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.
|
||||
// Example:
|
||||
@@ -574,6 +579,32 @@ $CFG->admin = 'admin';
|
||||
// 'verbose' => false
|
||||
// )
|
||||
// )
|
||||
// ),
|
||||
// 'Mac-Firefox' => array(
|
||||
// 'extensions' => array(
|
||||
// 'Behat\MinkExtension\Extension' => array(
|
||||
// 'selenium2' => array(
|
||||
// 'browser' => 'firefox',
|
||||
// 'capabilities' => array(
|
||||
// 'platform' => 'OS X 10.6',
|
||||
// 'version' => 20
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// ),
|
||||
// 'Mac-Safari' => array(
|
||||
// 'extensions' => array(
|
||||
// 'Behat\MinkExtension\Extension' => array(
|
||||
// 'selenium2' => array(
|
||||
// 'browser' => 'safari',
|
||||
// 'capabilities' => array(
|
||||
// 'platform' => 'OS X 10.8',
|
||||
// 'version' => 6
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// );
|
||||
//
|
||||
@@ -587,6 +618,13 @@ $CFG->admin = 'admin';
|
||||
// Example:
|
||||
// $CFG->behat_switchcompletely = true;
|
||||
//
|
||||
// You can force the browser session (not user's sessions) to restart after N seconds. This could
|
||||
// be useful if you are using a cloud-based service with time restrictions in the browser side.
|
||||
// Setting this value the browser session that Behat is using will be restarted. Set the time in
|
||||
// seconds. Is not recommended to use this setting if you don't explicitly need it.
|
||||
// Example:
|
||||
// $CFG->behat_restart_browser_after = 7200; // Restarts the browser session after 2 hours
|
||||
//
|
||||
|
||||
//=========================================================================
|
||||
// ALL DONE! To continue installation, visit your main page with a browser
|
||||
|
||||
@@ -81,7 +81,7 @@ class course_edit_form extends moodleform {
|
||||
$displaylist = coursecat::make_categories_list('moodle/course:create');
|
||||
if (!isset($displaylist[$course->category])) {
|
||||
//always keep current
|
||||
$displaylist[$course->category] = coursecat::get($course->category)->get_formatted_name();
|
||||
$displaylist[$course->category] = coursecat::get($course->category, MUST_EXIST, true)->get_formatted_name();
|
||||
}
|
||||
$mform->addElement('select', 'category', get_string('coursecategory'), $displaylist);
|
||||
$mform->addHelpButton('category', 'coursecategory');
|
||||
@@ -248,7 +248,7 @@ class course_edit_form extends moodleform {
|
||||
enrol_course_edit_form($mform, $course, $context);
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
$mform->addElement('header','groups', get_string('groups', 'group'));
|
||||
$mform->addElement('header','groups', get_string('groupsettingsheader', 'group'));
|
||||
|
||||
$choices = array();
|
||||
$choices[NOGROUPS] = get_string('groupsnone', 'group');
|
||||
|
||||
@@ -902,9 +902,9 @@ class core_course_external extends external_api {
|
||||
"users" (int) Include users (default to 0 that is equal to no),
|
||||
"role_assignments" (int) Include role assignments (default to 0 that is equal to no),
|
||||
"comments" (int) Include user comments (default to 0 that is equal to no),
|
||||
"completion_information" (int) Include user course completion information (default to 0 that is equal to no),
|
||||
"userscompletion" (int) Include user course completion information (default to 0 that is equal to no),
|
||||
"logs" (int) Include course logs (default to 0 that is equal to no),
|
||||
"histories" (int) Include histories (default to 0 that is equal to no)'
|
||||
"grade_histories" (int) Include histories (default to 0 that is equal to no)'
|
||||
),
|
||||
'value' => new external_value(PARAM_RAW, 'the value for the option 1 (yes) or 0 (no)'
|
||||
)
|
||||
@@ -966,9 +966,9 @@ class core_course_external extends external_api {
|
||||
'users' => 0,
|
||||
'role_assignments' => 0,
|
||||
'comments' => 0,
|
||||
'completion_information' => 0,
|
||||
'userscompletion' => 0,
|
||||
'logs' => 0,
|
||||
'histories' => 0
|
||||
'grade_histories' => 0
|
||||
);
|
||||
|
||||
$backupsettings = array();
|
||||
|
||||
@@ -235,7 +235,7 @@ abstract class format_base {
|
||||
return null;
|
||||
}
|
||||
if ($this->course === false) {
|
||||
$this->course = $DB->get_record('course', array('id' => $this->courseid));
|
||||
$this->course = get_course($this->courseid);
|
||||
$options = $this->get_format_options();
|
||||
foreach ($options as $optionname => $optionvalue) {
|
||||
if (!isset($this->course->$optionname)) {
|
||||
|
||||
@@ -257,6 +257,37 @@ class format_topics extends format_base {
|
||||
return $courseformatoptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds format options elements to the course/section edit form.
|
||||
*
|
||||
* This function is called from {@link course_edit_form::definition_after_data()}.
|
||||
*
|
||||
* @param MoodleQuickForm $mform form the elements are added to.
|
||||
* @param bool $forsection 'true' if this is a section edit form, 'false' if this is course edit form.
|
||||
* @return array array of references to the added form elements.
|
||||
*/
|
||||
public function create_edit_form_elements(&$mform, $forsection = false) {
|
||||
$elements = parent::create_edit_form_elements($mform, $forsection);
|
||||
|
||||
// Increase the number of sections combo box values if the user has increased the number of sections
|
||||
// using the icon on the course page beyond course 'maxsections' or course 'maxsections' has been
|
||||
// reduced below the number of sections already set for the course on the site administration course
|
||||
// defaults page. This is so that the number of sections is not reduced leaving unintended orphaned
|
||||
// activities / resources.
|
||||
if (!$forsection) {
|
||||
$maxsections = get_config('moodlecourse', 'maxsections');
|
||||
$numsections = $mform->getElementValue('numsections');
|
||||
$numsections = $numsections[0];
|
||||
if ($numsections > $maxsections) {
|
||||
$element = $mform->getElement('numsections');
|
||||
for ($i = $maxsections+1; $i <= $numsections; $i++) {
|
||||
$element->addOption("$i", $i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates format options for a course
|
||||
*
|
||||
|
||||
@@ -35,6 +35,20 @@ require_once($CFG->dirroot.'/course/format/renderer.php');
|
||||
*/
|
||||
class format_topics_renderer extends format_section_renderer_base {
|
||||
|
||||
/**
|
||||
* Constructor method, calls the parent constructor
|
||||
*
|
||||
* @param moodle_page $page
|
||||
* @param string $target one of rendering target constants
|
||||
*/
|
||||
public function __construct(moodle_page $page, $target) {
|
||||
parent::__construct($page, $target);
|
||||
|
||||
// Since format_topics_renderer::section_edit_controls() only displays the 'Set current section' control when editing mode is on
|
||||
// we need to be sure that the link 'Turn editing mode on' is available for a user who does not have any other managing capability.
|
||||
$page->set_other_editing_capability('moodle/course:setcurrentsection');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the starting container html for a list of sections
|
||||
* @return string HTML to output.
|
||||
|
||||
@@ -75,6 +75,7 @@ M.course.format.process_sections = function(Y, sectionlist, response, sectionfro
|
||||
for (var i = sectionfrom; i <= sectionto; i++) {
|
||||
// Update section title.
|
||||
sectionlist.item(i).one('.'+CSS.SECTIONNAME).setContent(response.sectiontitles[i]);
|
||||
|
||||
// Update move icon.
|
||||
ele = sectionlist.item(i).one(SELECTORS.SECTIONLEFTSIDE);
|
||||
str = ele.getAttribute('alt');
|
||||
@@ -82,6 +83,14 @@ M.course.format.process_sections = function(Y, sectionlist, response, sectionfro
|
||||
newstr = str.substr(0, stridx +1) + i;
|
||||
ele.setAttribute('alt', newstr);
|
||||
ele.setAttribute('title', newstr); // For FireFox as 'alt' is not refreshed.
|
||||
|
||||
// Remove the current class as section has been moved.
|
||||
sectionlist.item(i).removeClass('current');
|
||||
}
|
||||
// If there is a current section, apply corresponding class in order to highlight it.
|
||||
if (response.current !== -1) {
|
||||
// Add current class to the required section.
|
||||
sectionlist.item(response.current).addClass('current');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ class format_weeks extends format_base {
|
||||
// We subtract 24 hours for display purposes.
|
||||
$dates->end = ($dates->end - 86400);
|
||||
|
||||
$dateformat = ' '.get_string('strftimedateshort');
|
||||
$dateformat = get_string('strftimedateshort');
|
||||
$weekday = userdate($dates->start, $dateformat);
|
||||
$endweekday = userdate($dates->end, $dateformat);
|
||||
return $weekday.' - '.$endweekday;
|
||||
@@ -162,15 +162,19 @@ class format_weeks extends format_base {
|
||||
function ajax_section_move() {
|
||||
global $PAGE;
|
||||
$titles = array();
|
||||
$current = -1;
|
||||
$course = $this->get_course();
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$renderer = $this->get_renderer($PAGE);
|
||||
if ($renderer && ($sections = $modinfo->get_section_info_all())) {
|
||||
foreach ($sections as $number => $section) {
|
||||
$titles[$number] = $renderer->section_title($section, $course);
|
||||
if ($this->is_section_current($section)) {
|
||||
$current = $number;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array('sectiontitles' => $titles, 'action' => 'move');
|
||||
return array('sectiontitles' => $titles, 'current' => $current, 'action' => 'move');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,6 +266,37 @@ class format_weeks extends format_base {
|
||||
return $courseformatoptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds format options elements to the course/section edit form.
|
||||
*
|
||||
* This function is called from {@link course_edit_form::definition_after_data()}.
|
||||
*
|
||||
* @param MoodleQuickForm $mform form the elements are added to.
|
||||
* @param bool $forsection 'true' if this is a section edit form, 'false' if this is course edit form.
|
||||
* @return array array of references to the added form elements.
|
||||
*/
|
||||
public function create_edit_form_elements(&$mform, $forsection = false) {
|
||||
$elements = parent::create_edit_form_elements($mform, $forsection);
|
||||
|
||||
// Increase the number of sections combo box values if the user has increased the number of sections
|
||||
// using the icon on the course page beyond course 'maxsections' or course 'maxsections' has been
|
||||
// reduced below the number of sections already set for the course on the site administration course
|
||||
// defaults page. This is so that the number of sections is not reduced leaving unintended orphaned
|
||||
// activities / resources.
|
||||
if (!$forsection) {
|
||||
$maxsections = get_config('moodlecourse', 'maxsections');
|
||||
$numsections = $mform->getElementValue('numsections');
|
||||
$numsections = $numsections[0];
|
||||
if ($numsections > $maxsections) {
|
||||
$element = $mform->getElement('numsections');
|
||||
for ($i = $maxsections+1; $i <= $numsections; $i++) {
|
||||
$element->addOption("$i", $i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates format options for a course
|
||||
*
|
||||
|
||||
@@ -105,6 +105,9 @@ function make_log_url($module, $url) {
|
||||
case 'role':
|
||||
$url = '/'.$url;
|
||||
break;
|
||||
case 'grade':
|
||||
$url = "/grade/$url";
|
||||
break;
|
||||
default:
|
||||
$url = "/mod/$module/$url";
|
||||
break;
|
||||
|
||||
@@ -183,6 +183,7 @@ if ((!empty($moveupcat) or !empty($movedowncat)) and confirm_sesskey()) {
|
||||
if ($swapcategory and $movecategory) {
|
||||
$DB->set_field('course_categories', 'sortorder', $swapcategory->sortorder, array('id' => $movecategory->id));
|
||||
$DB->set_field('course_categories', 'sortorder', $movecategory->sortorder, array('id' => $swapcategory->id));
|
||||
cache_helper::purge_by_event('changesincoursecat');
|
||||
add_to_log(SITEID, "category", "move", "editcategory.php?id=$movecategory->id", $movecategory->id);
|
||||
}
|
||||
|
||||
|
||||
+25
-11
@@ -72,11 +72,11 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
$this->page->course->id == SITEID ||
|
||||
!$this->page->user_is_editing() ||
|
||||
!($context = context_course::instance($this->page->course->id)) ||
|
||||
!has_capability('moodle/course:update', $context) ||
|
||||
!has_capability('moodle/course:manageactivities', $context) ||
|
||||
!course_ajax_enabled($this->page->course) ||
|
||||
!($coursenode = $this->page->settingsnav->find('courseadmin', navigation_node::TYPE_COURSE)) ||
|
||||
!$coursenode->get('editsettings')) {
|
||||
// too late or we are on site page or we could not find the course settings node
|
||||
!($turneditingnode = $coursenode->get('turneditingonoff'))) {
|
||||
// too late or we are on site page or we could not find the adjacent nodes in course settings menu
|
||||
// or we are not allowed to edit
|
||||
return;
|
||||
}
|
||||
@@ -97,8 +97,13 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
$modchoosertogglestring = get_string('modchooserenable', 'moodle');
|
||||
$modchoosertoggleurl->param('modchooser', 'on');
|
||||
}
|
||||
$modchoosertoggle = navigation_node::create($modchoosertogglestring, $modchoosertoggleurl, navigation_node::TYPE_SETTING);
|
||||
$coursenode->add_node($modchoosertoggle, 'editsettings');
|
||||
$modchoosertoggle = navigation_node::create($modchoosertogglestring, $modchoosertoggleurl, navigation_node::TYPE_SETTING, null, 'modchoosertoggle');
|
||||
|
||||
// Insert the modchoosertoggle after the settings node 'turneditingonoff' (navigation_node only has function to insert before, so we insert before and then swap).
|
||||
$coursenode->add_node($modchoosertoggle, 'turneditingonoff');
|
||||
$turneditingnode->remove();
|
||||
$coursenode->add_node($turneditingnode, 'modchoosertoggle');
|
||||
|
||||
$modchoosertoggle->add_class('modchoosertoggle');
|
||||
$modchoosertoggle->add_class('visibleifjs');
|
||||
user_preference_allow_ajax_update('usemodchooser', PARAM_BOOL);
|
||||
@@ -369,9 +374,7 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
$activities = array(MOD_CLASS_ACTIVITY => array(), MOD_CLASS_RESOURCE => array());
|
||||
|
||||
foreach ($modules as $module) {
|
||||
if (!array_key_exists($module->archetype, $activities)) {
|
||||
// System modules cannot be added by user, do not add to dropdown
|
||||
} else if (isset($module->types)) {
|
||||
if (isset($module->types)) {
|
||||
// This module has a subtype
|
||||
// NOTE: this is legacy stuff, module subtypes are very strongly discouraged!!
|
||||
$subtypes = array();
|
||||
@@ -381,17 +384,28 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
}
|
||||
|
||||
// Sort module subtypes into the list
|
||||
$activityclass = MOD_CLASS_ACTIVITY;
|
||||
if ($module->archetype == MOD_CLASS_RESOURCE) {
|
||||
$activityclass = MOD_CLASS_RESOURCE;
|
||||
}
|
||||
if (!empty($module->title)) {
|
||||
// This grouping has a name
|
||||
$activities[$module->archetype][] = array($module->title => $subtypes);
|
||||
$activities[$activityclass][] = array($module->title => $subtypes);
|
||||
} else {
|
||||
// This grouping does not have a name
|
||||
$activities[$module->archetype] = array_merge($activities[$module->archetype], $subtypes);
|
||||
$activities[$activityclass] = array_merge($activities[$activityclass], $subtypes);
|
||||
}
|
||||
} else {
|
||||
// This module has no subtypes
|
||||
$activityclass = MOD_CLASS_ACTIVITY;
|
||||
if ($module->archetype == MOD_ARCHETYPE_RESOURCE) {
|
||||
$activityclass = MOD_CLASS_RESOURCE;
|
||||
} else if ($module->archetype === MOD_ARCHETYPE_SYSTEM) {
|
||||
// System modules cannot be added by user, do not add to dropdown
|
||||
continue;
|
||||
}
|
||||
$link = $module->link->out(true, $urlparams);
|
||||
$activities[$module->archetype][$link] = $module->title;
|
||||
$activities[$activityclass][$link] = $module->title;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,9 +71,9 @@ class course_request_form extends moodleform {
|
||||
|
||||
if (!empty($CFG->requestcategoryselection)) {
|
||||
$displaylist = coursecat::make_categories_list();
|
||||
$mform->addElement('select', 'category', get_string('category'), $displaylist);
|
||||
$mform->addElement('select', 'category', get_string('coursecategory'), $displaylist);
|
||||
$mform->setDefault('category', $CFG->defaultrequestcategory);
|
||||
$mform->addHelpButton('category', 'category');
|
||||
$mform->addHelpButton('category', 'coursecategory');
|
||||
}
|
||||
|
||||
$mform->addElement('editor', 'summary_editor', get_string('summary'), null, course_request::summary_editor_options());
|
||||
|
||||
+13
-5
@@ -84,7 +84,11 @@ foreach ($modinfo->cms as $cm) {
|
||||
|
||||
// preload instances
|
||||
foreach ($resources as $modname=>$instances) {
|
||||
$resources[$modname] = $DB->get_records_list($modname, 'id', $instances, 'id', 'id,name,intro,introformat,timemodified');
|
||||
$additionalfields = '';
|
||||
if (plugin_supports('mod', $modname, FEATURE_MOD_INTRO)) {
|
||||
$additionalfields = ',intro,introformat';
|
||||
}
|
||||
$resources[$modname] = $DB->get_records_list($modname, 'id', $instances, 'id', 'id,name'.$additionalfields);
|
||||
}
|
||||
|
||||
if (!$cms) {
|
||||
@@ -109,8 +113,8 @@ foreach ($cms as $cm) {
|
||||
continue;
|
||||
}
|
||||
$resource = $resources[$cm->modname][$cm->instance];
|
||||
$printsection = '';
|
||||
if ($usesections) {
|
||||
$printsection = '';
|
||||
if ($cm->sectionnum !== $currentsection) {
|
||||
if ($cm->sectionnum) {
|
||||
$printsection = get_section_name($course, $cm->sectionnum);
|
||||
@@ -120,8 +124,6 @@ foreach ($cms as $cm) {
|
||||
}
|
||||
$currentsection = $cm->sectionnum;
|
||||
}
|
||||
} else {
|
||||
$printsection = '<span class="smallinfo">'.userdate($resource->timemodified)."</span>";
|
||||
}
|
||||
|
||||
$extra = empty($cm->extra) ? '' : $cm->extra;
|
||||
@@ -131,11 +133,17 @@ foreach ($cms as $cm) {
|
||||
$icon = '<img src="'.$OUTPUT->pix_url('icon', $cm->modname).'" class="activityicon" alt="'.get_string('modulename', $cm->modname).'" /> ';
|
||||
}
|
||||
|
||||
if (isset($resource->intro) && isset($resource->introformat)) {
|
||||
$intro = format_module_intro('resource', $resource, $cm->id);
|
||||
} else {
|
||||
$intro = '';
|
||||
}
|
||||
|
||||
$class = $cm->visible ? '' : 'class="dimmed"'; // hidden modules are dimmed
|
||||
$table->data[] = array (
|
||||
$printsection,
|
||||
"<a $class $extra href=\"$CFG->wwwroot/mod/$cm->modname/view.php?id=$cm->id\">".$icon.format_string($resource->name)."</a>",
|
||||
format_module_intro('resource', $resource, $cm->id));
|
||||
$intro);
|
||||
}
|
||||
|
||||
echo html_writer::table($table);
|
||||
|
||||
@@ -433,7 +433,7 @@ class behat_course extends behat_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the specified activity to the first slot of a section. Editing mode should be on.
|
||||
* Moves the specified activity to the first slot of a section. This step is experimental when using it in Javascript tests. Editing mode should be on.
|
||||
*
|
||||
* @Given /^I move "(?P<activity_name_string>(?:[^"]|\\")*)" activity to section "(?P<section_number>\d+)"$/
|
||||
* @param string $activityname The activity name
|
||||
@@ -528,7 +528,7 @@ class behat_course extends behat_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the activity or resource specified by it's name. You should be in the course page with editing mode on.
|
||||
* Deletes the activity or resource specified by it's name. This step is experimental when using it in Javascript tests. You should be in the course page with editing mode on.
|
||||
*
|
||||
* @Given /^I delete "(?P<activity_name_string>(?:[^"]|\\")*)" activity$/
|
||||
* @param string $activityname
|
||||
|
||||
@@ -4,10 +4,10 @@ Feature: Course activity controls works as expected
|
||||
As a teacher
|
||||
I need to edit, hide, show and indent activities inside course sections
|
||||
|
||||
# This two scenario outlines contains exactly the same steps, the
|
||||
# only difference is whether JS is enabled or not; we can not use
|
||||
# Background sections when using Scenario Outlines because of Behat
|
||||
# framework restrictions.
|
||||
# The difference between these two scenario outlines is that one is with
|
||||
# JS enabled and the other one with JS disabled, also with JS disabled we
|
||||
# add the delete activity checking; we can not use Background sections
|
||||
# when using Scenario Outlines because of Behat framework restrictions.
|
||||
|
||||
# We are testing:
|
||||
# * Javascript on and off
|
||||
@@ -61,9 +61,6 @@ Feature: Course activity controls works as expected
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I click on "Hide" "link" in the "Test forum name 1" activity
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I delete "Test forum name 1" activity
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I should not see "Test forum name 1" in the ".region-content" "css_element"
|
||||
And I duplicate "Test forum name 2" activity editing the new copy with:
|
||||
| Forum name | Edited test forum name 2 |
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
|
||||
@@ -27,25 +27,6 @@ Feature: Activities can be moved between sections
|
||||
| Forum name | Test forum name |
|
||||
| Description | Test forum description |
|
||||
|
||||
@javascript @_cross_browser
|
||||
Scenario: Move activities in a single page course with Javascript enabled
|
||||
When I move "Test forum name" activity to section "2"
|
||||
And I reload the page
|
||||
Then I should see "Test forum name" in the "#section-2" "css_element"
|
||||
And I should not see "Test forum name" in the "#section-1" "css_element"
|
||||
|
||||
@javascript @_cross_browser
|
||||
Scenario: Move activities in the course home with Javascript enabled using paged mode
|
||||
Given I follow "Edit settings"
|
||||
And I fill the moodle form with:
|
||||
| Course layout | Show one section per page |
|
||||
And I press "Save changes"
|
||||
When I move "Test forum name" activity to section "2"
|
||||
# This reload step is added because of drap&drop & yui dd problem
|
||||
And I reload the page
|
||||
Then I should see "Test forum name" in the "#section-2" "css_element"
|
||||
And I should not see "Test forum name" in the "#section-1" "css_element"
|
||||
|
||||
Scenario: Move activities in a single page course with Javascript disabled
|
||||
When I move "Test forum name" activity to section "2"
|
||||
Then I should see "Test forum name" in the "#section-2" "css_element"
|
||||
|
||||
@@ -671,7 +671,15 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
* Test update_courses
|
||||
*/
|
||||
public function test_update_courses() {
|
||||
global $DB, $CFG, $USER;
|
||||
global $DB, $CFG, $USER, $COURSE;
|
||||
|
||||
// Get current $COURSE to be able to restore it later (defaults to $SITE). We need this
|
||||
// trick because we are both updating and getting (for testing) course information
|
||||
// in the same request and core_course_external::update_courses()
|
||||
// is overwriting $COURSE all over the time with OLD values, so later
|
||||
// use of get_course() fetches those OLD values instead of the updated ones.
|
||||
// See MDL-39723 for more info.
|
||||
$origcourse = clone($COURSE);
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
@@ -724,6 +732,7 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
$courses = array($course1, $course2);
|
||||
|
||||
$updatedcoursewarnings = core_course_external::update_courses($courses);
|
||||
$COURSE = $origcourse; // Restore $COURSE. Instead of using the OLD one set by the previous line.
|
||||
|
||||
// Check that right number of courses were created.
|
||||
$this->assertEquals(0, count($updatedcoursewarnings['warnings']));
|
||||
|
||||
+16
-13
@@ -122,7 +122,13 @@
|
||||
|
||||
$PAGE->set_pagelayout('course');
|
||||
$PAGE->set_pagetype('course-view-' . $course->format);
|
||||
$PAGE->set_other_editing_capability('moodle/course:update');
|
||||
$PAGE->set_other_editing_capability('moodle/course:manageactivities');
|
||||
$PAGE->set_other_editing_capability('moodle/course:activityvisibility');
|
||||
if (course_format_uses_sections($course->format)) {
|
||||
$PAGE->set_other_editing_capability('moodle/course:sectionvisibility');
|
||||
$PAGE->set_other_editing_capability('moodle/course:movesections');
|
||||
}
|
||||
|
||||
// Preload course format renderer before output starts.
|
||||
// This is a little hacky but necessary since
|
||||
@@ -189,20 +195,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (has_capability('moodle/course:update', $context)) {
|
||||
if (!empty($section)) {
|
||||
if (!empty($move) and has_capability('moodle/course:movesections', $context) and confirm_sesskey()) {
|
||||
$destsection = $section + $move;
|
||||
if (move_section_to($course, $section, $destsection)) {
|
||||
if ($course->id == SITEID) {
|
||||
redirect($CFG->wwwroot . '/?redirect=0');
|
||||
} else {
|
||||
redirect(course_get_url($course));
|
||||
}
|
||||
} else {
|
||||
echo $OUTPUT->notification('An error occurred while moving a section');
|
||||
}
|
||||
if (!empty($section) && !empty($move) &&
|
||||
has_capability('moodle/course:movesections', $context) && confirm_sesskey()) {
|
||||
$destsection = $section + $move;
|
||||
if (move_section_to($course, $section, $destsection)) {
|
||||
if ($course->id == SITEID) {
|
||||
redirect($CFG->wwwroot . '/?redirect=0');
|
||||
} else {
|
||||
redirect(course_get_url($course));
|
||||
}
|
||||
} else {
|
||||
echo $OUTPUT->notification('An error occurred while moving a section');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -37,5 +37,9 @@ function xmldb_enrol_authorize_upgrade($oldversion) {
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -213,6 +213,7 @@ function enrol_category_sync_course($course) {
|
||||
$sql = "SELECT ra.userid, ra.estart
|
||||
FROM (SELECT xra.userid, MIN(xra.timemodified) AS estart
|
||||
FROM {role_assignments} xra
|
||||
JOIN {user} xu ON (xu.id = xra.userid AND xu.deleted = 0)
|
||||
WHERE xra.roleid $roleids AND xra.contextid $contextids
|
||||
GROUP BY xra.userid
|
||||
) ra
|
||||
|
||||
@@ -184,6 +184,7 @@ function enrol_cohort_sync(progress_trace $trace, $courseid = NULL) {
|
||||
$sql = "SELECT cm.userid, e.id AS enrolid, ue.status
|
||||
FROM {cohort_members} cm
|
||||
JOIN {enrol} e ON (e.customint1 = cm.cohortid AND e.enrol = 'cohort' $onecourse)
|
||||
JOIN {user} u ON (u.id = cm.userid AND u.deleted = 0)
|
||||
LEFT JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = cm.userid)
|
||||
WHERE ue.id IS NULL OR ue.status = :suspended";
|
||||
$params = array();
|
||||
@@ -244,6 +245,7 @@ function enrol_cohort_sync(progress_trace $trace, $courseid = NULL) {
|
||||
JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = 'cohort' AND e.status = :statusenabled $onecourse)
|
||||
JOIN {role} r ON (r.id = e.roleid)
|
||||
JOIN {context} c ON (c.instanceid = e.courseid AND c.contextlevel = :coursecontext)
|
||||
JOIN {user} u ON (u.id = ue.userid AND u.deleted = 0)
|
||||
LEFT JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.userid = ue.userid AND ra.itemid = e.id AND ra.component = 'enrol_cohort' AND e.roleid = ra.roleid)
|
||||
WHERE ue.status = :useractive AND ra.id IS NULL";
|
||||
$params = array();
|
||||
@@ -307,6 +309,7 @@ function enrol_cohort_sync(progress_trace $trace, $courseid = NULL) {
|
||||
FROM {user_enrolments} ue
|
||||
JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = 'cohort' $onecourse)
|
||||
JOIN {groups} g ON (g.courseid = e.courseid AND g.id = e.customint2)
|
||||
JOIN {user} u ON (u.id = ue.userid AND u.deleted = 0)
|
||||
LEFT JOIN {groups_members} gm ON (gm.groupid = g.id AND gm.userid = ue.userid)
|
||||
WHERE gm.id IS NULL";
|
||||
$params = array();
|
||||
|
||||
@@ -37,5 +37,9 @@ function xmldb_enrol_database_upgrade($oldversion) {
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -38,5 +38,9 @@ function xmldb_enrol_flatfile_upgrade($oldversion) {
|
||||
// Put any upgrade step following this
|
||||
|
||||
|
||||
// Moodle v2.5.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ class enrol_flatfile_plugin extends enrol_plugin {
|
||||
}
|
||||
$roleid = $rolemap[$fields[1]];
|
||||
|
||||
if (!$user = $DB->get_record("user", array("idnumber"=>$fields[2]))) {
|
||||
if (empty($fields[2]) or !$user = $DB->get_record("user", array("idnumber"=>$fields[2]))) {
|
||||
$trace->output("Unknown user idnumber in field 3 - ignoring line $line", 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ class enrol_flatfile_testcase extends advanced_testcase {
|
||||
$user4 = $this->getDataGenerator()->create_user(array('idnumber'=>'čtvrtý'));
|
||||
$user5 = $this->getDataGenerator()->create_user(array('idnumber'=>'u5'));
|
||||
$user6 = $this->getDataGenerator()->create_user(array('idnumber'=>'u6'));
|
||||
$user7 = $this->getDataGenerator()->create_user(array('idnumber'=>''));
|
||||
|
||||
$course1 = $this->getDataGenerator()->create_course(array('idnumber'=>'c1'));
|
||||
$course2 = $this->getDataGenerator()->create_course(array('idnumber'=>'c2'));
|
||||
@@ -124,7 +125,8 @@ class enrol_flatfile_testcase extends advanced_testcase {
|
||||
add,student,u5,c2,20,10
|
||||
add,student,u6,c1,0,$future
|
||||
add,student,u6,c2,$future,0
|
||||
add,student,u6,c3,$future,$farfuture";
|
||||
add,student,u6,c3,$future,$farfuture
|
||||
add,student,,c2";
|
||||
file_put_contents($file, $data);
|
||||
|
||||
$this->assertEquals(0, $DB->count_records('user_enrolments'));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user