Compare commits
337 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a591e36a9 | |||
| 73aca3b00c | |||
| a9cffb2445 | |||
| b3fe61f9ea | |||
| b117c4e23f | |||
| c19d2c324b | |||
| 9538e66f1b | |||
| 0fc009e6a6 | |||
| 6504585b75 | |||
| 1f7125f372 | |||
| 35842437e6 | |||
| 4a09cd7dad | |||
| cab14fc8b2 | |||
| ff2962fdcf | |||
| 0f6d6d90ac | |||
| 9334d08ba7 | |||
| 41a39d24e1 | |||
| b85d42a3d7 | |||
| 372f8da557 | |||
| b4b1dab0a9 | |||
| 0e24f8be19 | |||
| 06ffbbf1de | |||
| 749bdfe00d | |||
| 6beb85435b | |||
| 3d8ce1728e | |||
| 2e6ffa6a73 | |||
| c7ae3e37e6 | |||
| 1f82f1fa65 | |||
| 14c2f54c3d | |||
| db1fd7f53f | |||
| e797ad651e | |||
| f67cd86431 | |||
| 4b3926de7a | |||
| 83740af0c6 | |||
| c254733047 | |||
| 3e9a86affe | |||
| a6726e4977 | |||
| 36c7af0e7e | |||
| 4ef5597d7d | |||
| e490115306 | |||
| 5124deed08 | |||
| 7f0420d619 | |||
| 811fae41ac | |||
| a7c779c738 | |||
| f850097c93 | |||
| 65254822e7 | |||
| 4a0dfea83f | |||
| bce737d1a5 | |||
| 3c9ddce77e | |||
| 641f227228 | |||
| 47751e701b | |||
| 71e7fb3a20 | |||
| 471566fde2 | |||
| 21f89c034c | |||
| 3a3f575f4d | |||
| e2b71acd1f | |||
| 0551e106ba | |||
| 40c64cf9ff | |||
| 3df77c0829 | |||
| f01bcdcbe3 | |||
| c0523b9857 | |||
| becebd955f | |||
| 0c7a83a632 | |||
| 92d19efe4c | |||
| 13c21e81b8 | |||
| 7121cdfc3e | |||
| 1d24a0fe2f | |||
| dab49d9fcd | |||
| eecc7ff372 | |||
| adfc2dd7a6 | |||
| 80ad2ce7ce | |||
| fda021dcc6 | |||
| 7b47a1e464 | |||
| 49212a0e82 | |||
| 9875c6c899 | |||
| 83939aeed6 | |||
| b5a794e133 | |||
| ab05a777b8 | |||
| 4126e44fa3 | |||
| 768e1558be | |||
| f42720e3f9 | |||
| 60fbdc0e23 | |||
| 306a3eba3f | |||
| 3d75433495 | |||
| f55ffd1d37 | |||
| 2ab4e9e320 | |||
| 016d93e1df | |||
| a15fae38cb | |||
| c1d666c078 | |||
| ccca9cf794 | |||
| 9f9350068b | |||
| 3c665aed99 | |||
| da0bb6a820 | |||
| 36043eacd3 | |||
| 9434133480 | |||
| 2e6b69cbca | |||
| a0ec6413d5 | |||
| 1d1086e3e5 | |||
| 311076f3a2 | |||
| 107ea0f3c7 | |||
| bd2c01bb9e | |||
| 0e7e457214 | |||
| 1e802bb449 | |||
| 5bd85d7f4f | |||
| ed76eb03f7 | |||
| db1898291d | |||
| 2d56bc1c72 | |||
| 2ba8535459 | |||
| 88bbfa1dc2 | |||
| c4c6e31630 | |||
| f6db012818 | |||
| d83e2ba4cd | |||
| baab74b9d3 | |||
| 44b817cf60 | |||
| 590706db1f | |||
| a7f16bb296 | |||
| 042dd6335d | |||
| 0bd1bd92dc | |||
| c03a53e8d8 | |||
| 267a719a17 | |||
| eaea57597c | |||
| 0dc5bfa27e | |||
| b18cde3450 | |||
| a0b2649a16 | |||
| 9a11ca8fd6 | |||
| 7ec9a6daa7 | |||
| ee461eee7f | |||
| 55711a938a | |||
| c860ca5c91 | |||
| 828a24f784 | |||
| 78e92b3fb1 | |||
| 48dbf89252 | |||
| 83d284be42 | |||
| 263528b0d8 | |||
| 966c52eb3d | |||
| 438da5c13b | |||
| bc299c8d4d | |||
| 29e276eeea | |||
| 4c28e8abe3 | |||
| 570b297303 | |||
| 261af24e61 | |||
| 20df9e8faa | |||
| 14f2ce60a7 | |||
| 00c2d21bab | |||
| ba3904e81b | |||
| 6e90b081c2 | |||
| 1a4b29ae88 | |||
| b627bcfd25 | |||
| 8e378ca989 | |||
| 41c8216718 | |||
| ad80abc65c | |||
| 40be01a636 | |||
| 5b497b1bde | |||
| fc6209584d | |||
| 3a3198767c | |||
| f94376bfc4 | |||
| 086815b1d6 | |||
| 5a03d41860 | |||
| 470a2e32fa | |||
| 1a58e38ea2 | |||
| 3e2732fbc7 | |||
| 494d18b16a | |||
| 6b818f0534 | |||
| cf3ee0a406 | |||
| 4635a07e6a | |||
| 661e129873 | |||
| 6644d7328e | |||
| d969814e09 | |||
| a00083a947 | |||
| 858fd41248 | |||
| c69f396769 | |||
| 8fa79442fd | |||
| 03488ecc9c | |||
| c4bb09b742 | |||
| 0b3e013f64 | |||
| fde74736a4 | |||
| 17b978cd90 | |||
| 73728cb33e | |||
| 9f021bd587 | |||
| 43f269a3d8 | |||
| 8caec2eb7a | |||
| a1dee21ec1 | |||
| 56df23be4f | |||
| 1712134d00 | |||
| 71db3b4410 | |||
| b8e10f239b | |||
| a3b0fce39c | |||
| 1b0d340042 | |||
| 81b900a2f2 | |||
| 4c3d434cb4 | |||
| 8835fd01c5 | |||
| a57c2774e8 | |||
| 9a4fbd4574 | |||
| 4270255272 | |||
| 778d746f6c | |||
| 4e41d6c56f | |||
| 04b1f4254e | |||
| d58ae0c075 | |||
| dab2233925 | |||
| 370f78715e | |||
| 6c436ac37e | |||
| 6df049fa3c | |||
| c7813fa674 | |||
| 61a96642f0 | |||
| 09b1711d94 | |||
| 0fe0954344 | |||
| f6d4edd3aa | |||
| 18f5851994 | |||
| b9fef33112 | |||
| 0730e8a380 | |||
| cdd836011f | |||
| c9b29b832b | |||
| d93d2a0d86 | |||
| ef89f89988 | |||
| fe53da02a3 | |||
| 0233c84101 | |||
| c3b3d04ca6 | |||
| 59dd0cc761 | |||
| 7fa35eca49 | |||
| cf266bd3e2 | |||
| 6b0bf399e2 | |||
| fb00e2dc97 | |||
| abfaf22dfb | |||
| 69865a1de3 | |||
| 66ccbfeb99 | |||
| 19bda8aa7e | |||
| e17f45f120 | |||
| c63b1749ba | |||
| 6f7bff5aa9 | |||
| 68049f376f | |||
| cf97659678 | |||
| 6a74606965 | |||
| 4d286aa730 | |||
| ff93f3915a | |||
| 95b73b0858 | |||
| 3c051e549a | |||
| e4b90ebdab | |||
| 939b9ab977 | |||
| 2b3ebab6dd | |||
| a5fc11023b | |||
| 2923e19928 | |||
| c26afb9b76 | |||
| ac5e3e9c6b | |||
| a9739a84dc | |||
| 4b1402490a | |||
| 3ee60271fa | |||
| 579b44ef14 | |||
| 76fd4da35d | |||
| c2d1467a7d | |||
| 6eb39155d4 | |||
| b3b909e1b4 | |||
| 77917ed26b | |||
| 1da8d303ef | |||
| 6d01904503 | |||
| fe6903b33f | |||
| 1dbe5c038e | |||
| c457cf5d35 | |||
| 4495103f17 | |||
| ce7cb88198 | |||
| 67ad699c28 | |||
| d94ac2bfbc | |||
| 3a1a441a7b | |||
| 7b7f45307a | |||
| 5f3cb3de39 | |||
| 1284339766 | |||
| b1517ff214 | |||
| e9f31bb710 | |||
| 0c95cbef53 | |||
| c4a970c345 | |||
| 0525300ebc | |||
| 930ef87ff8 | |||
| 469c46aa3a | |||
| facf5f3b6f | |||
| f4ef37425a | |||
| c27af3af45 | |||
| 9648379ea2 | |||
| 074034db86 | |||
| 9c65fc25cb | |||
| 74b092ca47 | |||
| 9cd7403fe6 | |||
| e667a98f86 | |||
| d016049dc9 | |||
| 82aab5855c | |||
| 38bd68868d | |||
| df61d236f5 | |||
| 6c0671bbf0 | |||
| a7c710c1b8 | |||
| a247bf678e | |||
| c51c6351b3 | |||
| 5b9fc0b69b | |||
| a1a2903db4 | |||
| 821c414049 | |||
| 2904e5e987 | |||
| 2337e280cf | |||
| f5a1435789 | |||
| 335f04772b | |||
| cb617fa262 | |||
| d19291fbf3 | |||
| 7fb6fdf6a7 | |||
| d4fd2325fe | |||
| d549a9d973 | |||
| 437a07a572 | |||
| c225ebf975 | |||
| cc60733069 | |||
| 7e364756ae | |||
| 43d4117912 | |||
| 3a960acf1e | |||
| 3e55e065fe | |||
| 856fa58440 | |||
| 0a64999259 | |||
| 9f861ddcbb | |||
| dff980ab44 | |||
| 8aab2713e9 | |||
| f7d3978d8d | |||
| cc15eb08e7 | |||
| 75788c63c5 | |||
| 57d11528b0 | |||
| 52155a2496 | |||
| 1b81de7861 | |||
| 5258d49a10 | |||
| 7e14be9814 | |||
| df68f1fcbd | |||
| 9b7b9d2740 | |||
| 3b92e304d3 | |||
| cb9f449c71 | |||
| 255ef8e427 | |||
| c84a3c9c40 | |||
| 6961e8882d | |||
| c079d43dc1 | |||
| b46369041c | |||
| 51cd0c4072 | |||
| def68f84a0 | |||
| ad445893db | |||
| fec32f3cd7 | |||
| bd937195eb | |||
| e3993969d6 | |||
| 6eeaf27bd1 |
+2
-5
@@ -52,12 +52,9 @@ matrix:
|
||||
fast_finish: true
|
||||
|
||||
include:
|
||||
# Run grunt/npm install on lowest supported npm version
|
||||
- php: 7.1
|
||||
env: DB=none TASK=GRUNT NVM_VERSION='4'
|
||||
# Run grunt/npm install on highest version ('node' is an alias for the latest node.js version.)
|
||||
- php: 7.1
|
||||
env: DB=none TASK=GRUNT NVM_VERSION='node'
|
||||
env: DB=none TASK=GRUNT NVM_VERSION='8.9'
|
||||
|
||||
exclude:
|
||||
# MySQL - it's just too slow.
|
||||
@@ -94,7 +91,7 @@ install:
|
||||
sudo service postgresql stop
|
||||
sudo mv /var/lib/postgresql /mnt/ramdisk
|
||||
sudo ln -s /mnt/ramdisk/postgresql /var/lib/postgresql
|
||||
sudo service postgresql start 9.1
|
||||
sudo service postgresql start 9.6
|
||||
fi
|
||||
- >
|
||||
if [ "$TASK" = 'PHPUNIT' ];
|
||||
|
||||
@@ -1754,6 +1754,7 @@
|
||||
<VENDOR name="oracle" version="10.2" />
|
||||
</DATABASE>
|
||||
<PHP version="5.6.5" level="required">
|
||||
<RESTRICT function="restrict_php_version_72" message="unsupportedphpversion72" />
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
@@ -1919,6 +1920,7 @@
|
||||
<VENDOR name="oracle" version="10.2" />
|
||||
</DATABASE>
|
||||
<PHP version="5.6.5" level="required">
|
||||
<RESTRICT function="restrict_php_version_72" message="unsupportedphpversion72" />
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
@@ -2257,4 +2259,180 @@
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
<MOODLE version="3.5" requires="3.1">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mariadb" version="5.5.31" />
|
||||
<VENDOR name="mysql" version="5.5.31" />
|
||||
<VENDOR name="postgres" version="9.3" />
|
||||
<VENDOR name="mssql" version="10.0" />
|
||||
<VENDOR name="oracle" version="10.2" />
|
||||
</DATABASE>
|
||||
<PHP version="7.0.0" level="required">
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="pcreunicodewarning" />
|
||||
</FEEDBACK>
|
||||
</PCREUNICODE>
|
||||
<PHP_EXTENSIONS>
|
||||
<PHP_EXTENSION name="iconv" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="iconvrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="mbstring" level="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="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="opensslrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="tokenizer" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="tokenizerrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xmlrpc" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="xmlrpcrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="soap" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="soaprecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="ctype" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ctyperequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zip" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ziprequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zlib" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="gd" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="gdrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="simplexml" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="simplexmlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="spl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="splrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="pcre" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="dom" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xml" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xmlreader" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="intl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="intlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="json" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="hash" level="required"/>
|
||||
<PHP_EXTENSION name="fileinfo" level="required"/>
|
||||
</PHP_EXTENSIONS>
|
||||
<PHP_SETTINGS>
|
||||
<PHP_SETTING name="memory_limit" value="96M" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="settingmemorylimit" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="file_uploads" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingfileuploads" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="opcache.enable" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="opcacherecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
<CUSTOM_CHECKS>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbstorageengine" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="quizattemptsupgradedmessage" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="slashargumentswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="unsupporteddbtablerowformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_unoconv_version" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="unoconvwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="libcurlwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfileformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfilepertable" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddblargeprefix" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_is_https" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="ishttpswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_incomplete_unicode_support" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="incompleteunicodesupport" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
</COMPATIBILITY_MATRIX>
|
||||
|
||||
+9
-1
@@ -5,11 +5,19 @@
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
redirect_if_major_upgrade_required();
|
||||
|
||||
$query = trim(optional_param('query', '', PARAM_NOTAGS)); // Search string
|
||||
|
||||
$context = context_system::instance();
|
||||
$PAGE->set_context($context);
|
||||
|
||||
$hassiteconfig = has_capability('moodle/site:config', $context);
|
||||
|
||||
if ($hassiteconfig && moodle_needs_upgrading()) {
|
||||
redirect(new moodle_url('/admin/index.php'));
|
||||
}
|
||||
|
||||
admin_externalpage_setup('search', '', array('query' => $query)); // now hidden page
|
||||
|
||||
$adminroot = admin_get_root(); // need all settings here
|
||||
@@ -55,7 +63,7 @@ if ($errormsg !== '') {
|
||||
|
||||
$showsettingslinks = true;
|
||||
|
||||
if (has_capability('moodle/site:config', $context)) {
|
||||
if ($hassiteconfig) {
|
||||
require_once("admin_settings_search_form.php");
|
||||
$form = new admin_settings_search_form();
|
||||
$form->display();
|
||||
|
||||
@@ -127,7 +127,7 @@ class api {
|
||||
'rememberusername' => $CFG->rememberusername,
|
||||
'authloginviaemail' => $CFG->authloginviaemail,
|
||||
'registerauth' => $CFG->registerauth,
|
||||
'forgottenpasswordurl' => $CFG->forgottenpasswordurl,
|
||||
'forgottenpasswordurl' => clean_param($CFG->forgottenpasswordurl, PARAM_URL), // We may expect a mailto: here.
|
||||
'authinstructions' => $authinstructions,
|
||||
'authnoneenabled' => (int) is_enabled_auth('none'),
|
||||
'enablewebservices' => $CFG->enablewebservices,
|
||||
@@ -153,10 +153,11 @@ class api {
|
||||
$settings['launchurl'] = $url->out(false);
|
||||
}
|
||||
|
||||
if ($logourl = $OUTPUT->get_logo_url()) {
|
||||
// Check that we are receiving a moodle_url object, themes can override get_logo_url and may return incorrect values.
|
||||
if (($logourl = $OUTPUT->get_logo_url()) && $logourl instanceof moodle_url) {
|
||||
$settings['logourl'] = $logourl->out(false);
|
||||
}
|
||||
if ($compactlogourl = $OUTPUT->get_compact_logo_url()) {
|
||||
if (($compactlogourl = $OUTPUT->get_compact_logo_url()) && $compactlogourl instanceof moodle_url) {
|
||||
$settings['compactlogourl'] = $compactlogourl->out(false);
|
||||
}
|
||||
|
||||
@@ -203,12 +204,17 @@ class api {
|
||||
}
|
||||
|
||||
if (empty($section) or $section == 'sitepolicies') {
|
||||
$settings->sitepolicy = $CFG->sitepolicy;
|
||||
$settings->disableuserimages = $CFG->disableuserimages;
|
||||
}
|
||||
|
||||
if (empty($section) or $section == 'gradessettings') {
|
||||
require_once($CFG->dirroot . '/user/lib.php');
|
||||
$settings->mygradesurl = user_mygrades_url()->out(false);
|
||||
$settings->mygradesurl = user_mygrades_url();
|
||||
// The previous function may return moodle_url instances or plain string URLs.
|
||||
if ($settings->mygradesurl instanceof moodle_url) {
|
||||
$settings->mygradesurl = $settings->mygradesurl->out(false);
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
namespace tool_mobile;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once("$CFG->libdir/externallib.php");
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['autologinkeygenerationlockout'] = 'Auto-login key generation is blocked because of too many requests within an hour.';
|
||||
$string['autologinkeygenerationlockout'] = 'Auto-login key generation is blocked. You need to wait 6 minutes between requests.';
|
||||
$string['autologinnotallowedtoadmins'] = 'Auto-login is not allowed for site admins.';
|
||||
$string['cachedef_plugininfo'] = 'This stores the list of plugins with mobile addons';
|
||||
$string['clickheretolaunchtheapp'] = 'Click here if the app does not open automatically.';
|
||||
|
||||
@@ -94,12 +94,14 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
|
||||
set_config('typeoflogin', api::LOGIN_VIA_BROWSER, 'tool_mobile');
|
||||
set_config('logo', 'mock.png', 'core_admin');
|
||||
set_config('logocompact', 'mock.png', 'core_admin');
|
||||
set_config('forgottenpasswordurl', 'mailto:fake@email.zy'); // Test old hack.
|
||||
|
||||
list($authinstructions, $notusedformat) = external_format_text($authinstructions, FORMAT_MOODLE, $context->id);
|
||||
$expected['registerauth'] = 'email';
|
||||
$expected['authinstructions'] = $authinstructions;
|
||||
$expected['typeoflogin'] = api::LOGIN_VIA_BROWSER;
|
||||
$expected['launchurl'] = "$CFG->wwwroot/$CFG->admin/tool/mobile/launch.php";
|
||||
$expected['forgottenpasswordurl'] = ''; // Expect empty when it's not an URL.
|
||||
|
||||
if ($logourl = $OUTPUT->get_logo_url()) {
|
||||
$expected['logourl'] = $logourl->out(false);
|
||||
@@ -121,6 +123,10 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
|
||||
require_once($CFG->dirroot . '/course/format/lib.php');
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$mysitepolicy = 'http://mysite.is/policy/';
|
||||
set_config('sitepolicy', $mysitepolicy);
|
||||
|
||||
$result = external::get_config();
|
||||
$result = external_api::clean_returnvalue(external::get_config_returns(), $result);
|
||||
|
||||
@@ -141,6 +147,7 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
|
||||
array('name' => 'numsections', 'value' => course_get_format($SITE)->get_course()->numsections),
|
||||
array('name' => 'newsitems', 'value' => $SITE->newsitems),
|
||||
array('name' => 'commentsperpage', 'value' => $CFG->commentsperpage),
|
||||
array('name' => 'sitepolicy', 'value' => $mysitepolicy),
|
||||
array('name' => 'disableuserimages', 'value' => $CFG->disableuserimages),
|
||||
array('name' => 'mygradesurl', 'value' => user_mygrades_url()->out(false)),
|
||||
);
|
||||
@@ -150,8 +157,7 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
|
||||
// Change a value and retrieve filtering by section.
|
||||
set_config('commentsperpage', 1);
|
||||
$expected[10]['value'] = 1;
|
||||
unset($expected[11]);
|
||||
unset($expected[12]);
|
||||
array_splice($expected, 11);
|
||||
|
||||
$result = external::get_config('frontpagesettings');
|
||||
$result = external_api::clean_returnvalue(external::get_config_returns(), $result);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace tool_templatelibrary;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once("$CFG->libdir/externallib.php");
|
||||
|
||||
|
||||
@@ -112,11 +112,11 @@ class auth_email_external extends external_api {
|
||||
}
|
||||
|
||||
if (signup_captcha_enabled()) {
|
||||
require_once($CFG->libdir . '/recaptchalib.php');
|
||||
// We return the public key, maybe we want to use the javascript api to get the image.
|
||||
// With reCAPTCHA v2 the captcha will be rendered by the mobile client using just the publickey.
|
||||
// For now include placeholders for the v1 paramaters to support older mobile app versions.
|
||||
$result['recaptchapublickey'] = $CFG->recaptchapublickey;
|
||||
list($result['recaptchachallengehash'], $result['recaptchachallengeimage'], $result['recaptchachallengejs']) =
|
||||
recaptcha_get_challenge_hash_and_urls(RECAPTCHA_API_SECURE_SERVER, $CFG->recaptchapublickey);
|
||||
array('', '', '');
|
||||
}
|
||||
|
||||
$result['warnings'] = array();
|
||||
@@ -137,7 +137,7 @@ class auth_email_external extends external_api {
|
||||
new external_value(PARAM_NOTAGS, 'The order of the name fields')
|
||||
),
|
||||
'passwordpolicy' => new external_value(PARAM_RAW, 'Password policy', VALUE_OPTIONAL),
|
||||
'sitepolicy' => new external_value(PARAM_URL, 'Site policy url', VALUE_OPTIONAL),
|
||||
'sitepolicy' => new external_value(PARAM_RAW, 'Site policy', VALUE_OPTIONAL),
|
||||
'defaultcity' => new external_value(PARAM_NOTAGS, 'Default city', VALUE_OPTIONAL),
|
||||
'country' => new external_value(PARAM_ALPHA, 'Default country', VALUE_OPTIONAL),
|
||||
'profilefields' => new external_multiple_structure(
|
||||
@@ -307,11 +307,11 @@ class auth_email_external extends external_api {
|
||||
|
||||
// Validate recaptcha.
|
||||
if (signup_captcha_enabled()) {
|
||||
require_once($CFG->libdir . '/recaptchalib.php');
|
||||
$response = recaptcha_check_answer($CFG->recaptchaprivatekey, getremoteaddr(), $params['recaptchachallengehash'],
|
||||
$params['recaptcharesponse'], true);
|
||||
if (!$response->is_valid) {
|
||||
$errors['recaptcharesponse'] = $response->error;
|
||||
require_once($CFG->libdir . '/recaptchalib_v2.php');
|
||||
$response = recaptcha_check_response(RECAPTCHA_VERIFY_URL, $CFG->recaptchaprivatekey,
|
||||
getremoteaddr(), $params['recaptcharesponse']);
|
||||
if (!$response['isvalid']) {
|
||||
$errors['recaptcharesponse'] = $response['error'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ $string['didntfindexpiretime'] = 'password_expire() didn\'t find expiration time
|
||||
$string['didntgetusersfromldap'] = "Did not get any users from LDAP -- error? -- exiting\n";
|
||||
$string['gotcountrecordsfromldap'] = "Got {\$a} records from LDAP\n";
|
||||
$string['morethanoneuser'] = 'Strange! More than one user record found in ldap. Only using the first one.';
|
||||
$string['needbcmath'] = 'You need the BCMath extension to use grace logins with Active Directory';
|
||||
$string['needbcmath'] = 'You need the BCMath extension to use expired password checking with Active Directory.';
|
||||
$string['needmbstring'] = 'You need the mbstring extension to change passwords in Active Directory';
|
||||
$string['nodnforusername'] = 'Error in user_update_password(). No DN for: {$a->username}';
|
||||
$string['noemail'] = 'Tried to send you an email but failed!';
|
||||
|
||||
@@ -136,6 +136,15 @@ abstract class backup implements checksumable {
|
||||
* Usually same than major release zero version, mainly for informative/historic purposes.
|
||||
*/
|
||||
const RELEASE = '3.2';
|
||||
|
||||
/**
|
||||
* Cipher to be used in backup and restore operations.
|
||||
*/
|
||||
const CIPHER = 'aes-256-cbc';
|
||||
/**
|
||||
* Bytes enforced for key, using the cypher above. Restrictive? Yes, but better than unsafe lengths
|
||||
*/
|
||||
const CIPHERKEYLEN = 32;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -112,7 +112,7 @@ class cc_forum extends entities {
|
||||
|
||||
public function get_topic_data ($instance) {
|
||||
|
||||
$topic_data = '';
|
||||
$topic_data = array();
|
||||
|
||||
$topic_file = $this->get_external_xml($instance['resource_indentifier']);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class cc_quiz extends entities {
|
||||
$last_question_id = 0;
|
||||
$last_answer_id = 0;
|
||||
|
||||
$instances = '';
|
||||
$instances = array();
|
||||
|
||||
$types = array(MOODLE_TYPE_QUIZ, MOODLE_TYPE_QUESTION_BANK);
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ class cc11_basiclti extends entities11 {
|
||||
|
||||
public function get_basiclti_data($instance) {
|
||||
|
||||
$topic_data = '';
|
||||
$topic_data = array();
|
||||
|
||||
$basiclti_file = $this->get_external_xml($instance['resource_indentifier']);
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ class cc11_forum extends entities11 {
|
||||
|
||||
public function get_topic_data ($instance) {
|
||||
|
||||
$topic_data = '';
|
||||
$topic_data = array();
|
||||
|
||||
$topic_file = $this->get_external_xml($instance['resource_indentifier']);
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class cc11_lti extends entities11 {
|
||||
|
||||
public function get_basiclti_data($instance) {
|
||||
|
||||
$topic_data = '';
|
||||
$topic_data = array();
|
||||
|
||||
$basiclti_file = $this->get_external_xml($instance['resource_indentifier']);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class cc11_quiz extends entities11 {
|
||||
$last_question_id = 0;
|
||||
$last_answer_id = 0;
|
||||
|
||||
$instances = '';
|
||||
$instances = array();
|
||||
|
||||
$types = array(MOODLE_TYPE_QUIZ, MOODLE_TYPE_QUESTION_BANK);
|
||||
|
||||
|
||||
@@ -97,6 +97,138 @@ class base64_encode_final_element extends backup_final_element {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link backup_final_element} that provides symmetric-key AES-256 encryption of contents.
|
||||
*
|
||||
* This final element transparently encrypts, for secure storage and transport, any content
|
||||
* that shouldn't be shown normally in plain text. Usually, passwords or keys that cannot use
|
||||
* hashing algorithms, although potentially can encrypt any content. All information is encoded
|
||||
* using base64.
|
||||
*
|
||||
* Features:
|
||||
* - requires openssl extension to work. Without it contents are completely omitted.
|
||||
* - automatically creates an appropriate default key for the site and stores it into backup_encryptkey config (bas64 encoded).
|
||||
* - uses a different appropriate init vector for every operation, which is transmited with the encrypted contents.
|
||||
* - all generated data is base64 encoded for safe transmission.
|
||||
* - automatically adds "encrypted" attribute for easier detection.
|
||||
* - implements HMAC for providing integrity.
|
||||
*
|
||||
* @copyright 2017 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class encrypted_final_element extends backup_final_element {
|
||||
|
||||
/** @var string cypher appropiate raw key for backups in the site. Defaults to backup_encryptkey config. */
|
||||
protected $key = null;
|
||||
|
||||
/**
|
||||
* Constructor - instantiates a encrypted_final_element, specifying its basic info.
|
||||
*
|
||||
* Overridden to automatically add the 'encrypted' attribute if missing.
|
||||
*
|
||||
* @param string $name name of the element
|
||||
* @param array $attributes attributes this element will handle (optional, defaults to null)
|
||||
*/
|
||||
public function __construct($name, $attributes = null) {
|
||||
parent::__construct($name, $attributes);
|
||||
if (! $this->get_attribute('encrypted')) {
|
||||
$this->add_attributes('encrypted');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the encryption key manually, overriding default backup_encryptkey config.
|
||||
*
|
||||
* @param string $key key to be used for encrypting. Required to be 256-bit key.
|
||||
* Use a safe generation technique. See self::generate_encryption_random_key() below.
|
||||
*/
|
||||
protected function set_key($key) {
|
||||
$bytes = strlen($key); // Get key length in bytes.
|
||||
|
||||
// Only accept keys with the expected (backup::CIPHERKEYLEN) key length. There are a number of hashing,
|
||||
// random generators to achieve this esasily, like the one shown below to create the default
|
||||
// site encryption key and ivs.
|
||||
if ($bytes !== backup::CIPHERKEYLEN) {
|
||||
$info = (object)array('expected' => backup::CIPHERKEYLEN, 'found' => $bytes);
|
||||
throw new base_element_struct_exception('encrypted_final_element incorrect key length', $info);
|
||||
}
|
||||
// Everything went ok, store the key.
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the field.
|
||||
*
|
||||
* This method sets the value of the element, encrypted using the specified key for it,
|
||||
* defaulting to (and generating) backup_encryptkey config. HMAC is used for integrity.
|
||||
*
|
||||
* @param string $value plain-text content the will be stored encrypted and encoded.
|
||||
*/
|
||||
public function set_value($value) {
|
||||
|
||||
// No openssl available, skip this field completely.
|
||||
if (!function_exists('openssl_encrypt')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No hmac available, skip this field completely.
|
||||
if (!function_exists('hash_hmac')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Cypher not available, skip this field completely.
|
||||
if (!in_array(backup::CIPHER, openssl_get_cipher_methods())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure we have a good key, manual or default.
|
||||
if (empty($this->key)) {
|
||||
// The key has not been set manually, look for it at config (base64 encoded there).
|
||||
$enckey = get_config('backup', 'backup_encryptkey');
|
||||
if ($enckey === false) {
|
||||
// Has not been set, calculate and save an appropiate random key automatically.
|
||||
$enckey = base64_encode(self::generate_encryption_random_key(backup::CIPHERKEYLEN));
|
||||
set_config('backup_encryptkey', $enckey, 'backup');
|
||||
}
|
||||
$this->set_key(base64_decode($enckey));
|
||||
}
|
||||
|
||||
// Now we need an iv for this operation.
|
||||
$iv = self::generate_encryption_random_key(openssl_cipher_iv_length(backup::CIPHER));
|
||||
|
||||
// Everything is ready, let's encrypt and prepend the 1-shot iv.
|
||||
$value = $iv . openssl_encrypt($value, backup::CIPHER, $this->key, OPENSSL_RAW_DATA, $iv);
|
||||
|
||||
// Calculate the hmac of the value (iv + encrypted) and prepend it.
|
||||
$hmac = hash_hmac('sha256', $value, $this->key, true);
|
||||
$value = $hmac . $value;
|
||||
|
||||
// Ready, set the encoded value.
|
||||
parent::set_value(base64_encode($value));
|
||||
|
||||
// Finally, if the field has an "encrypted" attribute, set it to true.
|
||||
if ($att = $this->get_attribute('encrypted')) {
|
||||
$att->set_value('true');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an appropiate random key to be used for encrypting backup information.
|
||||
*
|
||||
* Normally used as site default encryption key (backup_encryptkey config) and also
|
||||
* for calculating the init vectors.
|
||||
*
|
||||
* Note that until PHP 5.6.12 openssl_random_pseudo_bytes() did NOT
|
||||
* use a "cryptographically strong algorithm" {@link https://bugs.php.net/bug.php?id=70014}
|
||||
* But it's beyond my crypto-knowledge when it's worth finding a *real* better alternative.
|
||||
*
|
||||
* @param int $bytes Number of bytes to determine the key length expected.
|
||||
*/
|
||||
protected static function generate_encryption_random_key($bytes) {
|
||||
return openssl_random_pseudo_bytes($bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of backup_nested_element that provides special handling of files
|
||||
*
|
||||
|
||||
@@ -522,7 +522,7 @@ class backup_enrolments_structure_step extends backup_structure_step {
|
||||
$enrol->annotate_ids('role', 'roleid');
|
||||
|
||||
// Add enrol plugin structure.
|
||||
$this->add_plugin_structure('enrol', $enrol, false);
|
||||
$this->add_plugin_structure('enrol', $enrol, true);
|
||||
|
||||
return $enrolments;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Tests for the handling of encrypted contents in backup and restore.
|
||||
*
|
||||
* @package core_backup
|
||||
* @copyright 2016 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();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
|
||||
require_once($CFG->dirroot . '/backup/moodle2/backup_custom_fields.php');
|
||||
|
||||
class core_backup_encrypted_content_testscase extends advanced_testcase {
|
||||
|
||||
public function setUp() {
|
||||
if (!function_exists('openssl_encrypt')) {
|
||||
$this->markTestSkipped('OpenSSL extension is not loaded.');
|
||||
|
||||
} else if (!function_exists('hash_hmac')) {
|
||||
$this->markTestSkipped('Hash extension is not loaded.');
|
||||
|
||||
} else if (!in_array(backup::CIPHER, openssl_get_cipher_methods())) {
|
||||
$this->markTestSkipped('Expected cipher not available: ' . backup::CIPHER);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_encrypted_final_element() {
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Some basic verifications.
|
||||
$efe = new encrypted_final_element('test', array('encrypted'));
|
||||
$this->assertInstanceOf('encrypted_final_element', $efe);
|
||||
$this->assertSame('test', $efe->get_name());
|
||||
$atts = $efe->get_attributes();
|
||||
$this->assertCount(1, $atts);
|
||||
$att = reset($atts);
|
||||
$this->assertInstanceOf('backup_attribute', $att);
|
||||
$this->assertSame('encrypted', $att->get_name());
|
||||
|
||||
// Using a manually defined (incorrect length) key.
|
||||
$efe = new encrypted_final_element('test', array('encrypted'));
|
||||
$key = 'this_in_not_correct_32_byte_key';
|
||||
try {
|
||||
set_config('backup_encryptkey', base64_encode($key), 'backup');
|
||||
$efe->set_value('tiny_secret');
|
||||
$this->fail('Expecting base_element_struct_exception exception, none happened');
|
||||
} catch (exception $e) {
|
||||
$this->assertInstanceOf('base_element_struct_exception', $e);
|
||||
$this->assertEquals('encrypted_final_element incorrect key length', $e->errorcode);
|
||||
|
||||
}
|
||||
|
||||
// Using a manually defined (correct length) key.
|
||||
$efe = new encrypted_final_element('test', array('testattr', 'encrypted'));
|
||||
$key = hash('md5', 'Moodle rocks and this is not secure key, who cares, it is a test');
|
||||
set_config('backup_encryptkey', base64_encode($key), 'backup');
|
||||
$this->assertEmpty($efe->get_value());
|
||||
$secret = 'This is a secret message that nobody else will be able to read but me 💩 ';
|
||||
$efe->set_value($secret);
|
||||
$atts = $efe->get_attributes();
|
||||
$this->assertCount(2, $atts);
|
||||
$this->assertArrayHasKey('encrypted', $atts); // We added it explicitly.
|
||||
$this->assertTrue($atts['encrypted']->is_set());
|
||||
$this->assertSame('true', $atts['encrypted']->get_value());
|
||||
$this->assertNotEmpty($efe->get_value());
|
||||
$this->assertTrue($efe->is_set());
|
||||
// Get the crypted content and decrypt it manually.
|
||||
$ctext = $efe->get_value();
|
||||
$hmaclen = 32; // SHA256 is 32 bytes.
|
||||
$ivlen = openssl_cipher_iv_length(backup::CIPHER);
|
||||
list($hmac, $iv, $text) = array_values(unpack("a{$hmaclen}hmac/a{$ivlen}iv/a*text", base64_decode($ctext)));
|
||||
$this->assertSame(hash_hmac('sha256', $iv . $text, $key, true), $hmac);
|
||||
$this->assertSame($secret, openssl_decrypt($text, backup::CIPHER, $key, OPENSSL_RAW_DATA, $iv));
|
||||
|
||||
// Using the default site-generated key.
|
||||
$efe = new encrypted_final_element('test', array('testattr'));
|
||||
$this->assertEmpty($efe->get_value());
|
||||
$secret = 'This is a secret message that nobody else will be able to read but me 💩 ';
|
||||
$efe->set_value($secret);
|
||||
$atts = $efe->get_attributes();
|
||||
$this->assertCount(2, $atts);
|
||||
$this->assertArrayHasKey('encrypted', $atts); // Was added automatcally, we did not specify it.
|
||||
$this->assertTrue($atts['encrypted']->is_set());
|
||||
$this->assertSame('true', $atts['encrypted']->get_value());
|
||||
$this->assertNotEmpty($efe->get_value());
|
||||
$this->assertTrue($efe->is_set());
|
||||
// Get the crypted content and decrypt it manually.
|
||||
$ctext = $efe->get_value();
|
||||
$hmaclen = 32; // SHA256 is 32 bytes.
|
||||
$ivlen = openssl_cipher_iv_length(backup::CIPHER);
|
||||
list($hmac, $iv, $text) = array_values(unpack("a{$hmaclen}hmac/a{$ivlen}iv/a*text", base64_decode($ctext)));
|
||||
$key = base64_decode(get_config('backup', 'backup_encryptkey'));
|
||||
$this->assertSame(hash_hmac('sha256', $iv . $text, $key, true), $hmac);
|
||||
$this->assertSame($secret, openssl_decrypt($text, backup::CIPHER, $key, OPENSSL_RAW_DATA, $iv));
|
||||
}
|
||||
}
|
||||
@@ -94,6 +94,66 @@ abstract class restore_step extends base_step {
|
||||
// Return the passed value with cached offset applied.
|
||||
return $value + $cache[$this->get_restoreid()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns symmetric-key AES-256 decryption of base64 encoded contents.
|
||||
*
|
||||
* This method is used in restore operations to decrypt contents encrypted with
|
||||
* {@link encrypted_final_element} automatically decoding (base64) and decrypting
|
||||
* contents using the key stored in backup_encryptkey config.
|
||||
*
|
||||
* Requires openssl, cipher availability, and key existence (backup
|
||||
* automatically sets it if missing). Integrity is provided via HMAC.
|
||||
*
|
||||
* @param string $value {@link encrypted_final_element} value to decode and decrypt.
|
||||
* @return string|null decoded and decrypted value or null if the operation can not be performed.
|
||||
*/
|
||||
public function decrypt($value) {
|
||||
|
||||
// No openssl available, skip this field completely.
|
||||
if (!function_exists('openssl_encrypt')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// No hash available, skip this field completely.
|
||||
if (!function_exists('hash_hmac')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Cypher not available, skip this field completely.
|
||||
if (!in_array(backup::CIPHER, openssl_get_cipher_methods())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get the decrypt key. Skip if missing.
|
||||
$key = get_config('backup', 'backup_encryptkey');
|
||||
if ($key === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// And decode it.
|
||||
$key = base64_decode($key);
|
||||
|
||||
// Arrived here, let's proceed with authentication (provides integrity).
|
||||
$hmaclen = 32; // SHA256 is 32 bytes.
|
||||
$ivlen = openssl_cipher_iv_length(backup::CIPHER);
|
||||
list($hmac, $iv, $text) = array_values(unpack("a{$hmaclen}hmac/a{$ivlen}iv/a*text", base64_decode($value)));
|
||||
|
||||
// Verify HMAC matches expectations, skip if not (integrity failed).
|
||||
if (!hash_equals($hmac, hash_hmac('sha256', $iv . $text, $key, true))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Arrived here, integrity is ok, let's decrypt.
|
||||
$result = openssl_decrypt($text, backup::CIPHER, $key, OPENSSL_RAW_DATA, $iv);
|
||||
|
||||
// For some reason decrypt failed (strange, HMAC check should have deteted it), skip this field completely.
|
||||
if ($result === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -91,6 +91,52 @@ class backup_step_testcase extends advanced_testcase {
|
||||
$bc->destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* test restore_step class, decrypt method
|
||||
*/
|
||||
public function test_restore_step_decrypt() {
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
if (!function_exists('openssl_encrypt')) {
|
||||
$this->markTestSkipped('OpenSSL extension is not loaded.');
|
||||
|
||||
} else if (!function_exists('hash_hmac')) {
|
||||
$this->markTestSkipped('Hash extension is not loaded.');
|
||||
|
||||
} else if (!in_array(backup::CIPHER, openssl_get_cipher_methods())) {
|
||||
$this->markTestSkipped('Expected cipher not available: ' . backup::CIPHER);
|
||||
}
|
||||
|
||||
$bt = new mock_restore_task_basepath('taskname');
|
||||
$bs = new mock_restore_structure_step('steptest', null, $bt);
|
||||
$this->assertTrue(method_exists($bs, 'decrypt'));
|
||||
|
||||
// Let's prepare a string for being decrypted.
|
||||
$secret = 'This is a secret message that nobody else will be able to read but me 💩 ';
|
||||
$key = hash('md5', 'Moodle rocks and this is not secure key, who cares, it is a test');
|
||||
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(backup::CIPHER));
|
||||
$message = $iv . openssl_encrypt($secret, backup::CIPHER, $key, OPENSSL_RAW_DATA, $iv);
|
||||
$hmac = hash_hmac('sha256', $message, $key, true);
|
||||
$crypt = base64_encode($hmac . $message);
|
||||
|
||||
// Running it without a key configured, returns null.
|
||||
$this->assertNull($bs->decrypt($crypt));
|
||||
|
||||
// Store the key into config.
|
||||
set_config('backup_encryptkey', base64_encode($key), 'backup');
|
||||
|
||||
// Verify decrypt works and returns original.
|
||||
$this->assertSame($secret, $bs->decrypt($crypt));
|
||||
|
||||
// Finally, test the integrity failure detection is working.
|
||||
// (this can be caused by changed hmac, key or message, in
|
||||
// this case we are just forcing it via changed hmac).
|
||||
$hmac = md5($message);
|
||||
$crypt = base64_encode($hmac . $message);
|
||||
$this->assertNull($bs->decrypt($crypt));
|
||||
}
|
||||
|
||||
/**
|
||||
* test backup_structure_step class
|
||||
*/
|
||||
|
||||
@@ -50,7 +50,7 @@ class block_glossary_random extends block_base {
|
||||
if (empty($this->config->title)) {
|
||||
$this->title = get_string('pluginname','block_glossary_random');
|
||||
} else {
|
||||
$this->title = $this->config->title;
|
||||
$this->title = format_string($this->config->title, true, ['context' => $this->context]);
|
||||
}
|
||||
|
||||
if (empty($this->config->glossary)) {
|
||||
|
||||
@@ -37,7 +37,11 @@ class block_html extends block_base {
|
||||
}
|
||||
|
||||
function specialization() {
|
||||
$this->title = isset($this->config->title) ? format_string($this->config->title) : format_string(get_string('newhtmlblock', 'block_html'));
|
||||
if (isset($this->config->title)) {
|
||||
$this->title = $this->title = format_string($this->config->title, true, ['context' => $this->context]);
|
||||
} else {
|
||||
$this->title = get_string('newhtmlblock', 'block_html');
|
||||
}
|
||||
}
|
||||
|
||||
function instance_allow_multiple() {
|
||||
|
||||
+1
-1
@@ -411,7 +411,7 @@ function calendar_get_mini($courses, $groups, $users, $calmonth = false, $calyea
|
||||
$name = format_string($event->name, true);
|
||||
}
|
||||
}
|
||||
$popupcontent .= html_writer::link($dayhref, $name);
|
||||
$popupcontent .= html_writer::link($dayhref, clean_text($name));
|
||||
$popupcontent .= html_writer::end_tag('div');
|
||||
}
|
||||
|
||||
|
||||
@@ -872,7 +872,7 @@ class core_calendar_rrule_manager_testcase extends advanced_testcase {
|
||||
$records = $DB->get_records('event', ['repeatid' => $this->event->id], 'timestart ASC', 'id, repeatid, timestart');
|
||||
$expecteddate = new DateTime('first Monday of this month');
|
||||
// Move to the next interval's first Monday if the calculated start date is after this month's first Monday.
|
||||
if ($expecteddate->getTimestamp() < $startdatetime->getTimestamp()) {
|
||||
if ($expecteddate->getTimestamp() < $startdate->getTimestamp()) {
|
||||
$expecteddate->add($interval);
|
||||
$expecteddate->modify('first Monday of this month');
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once("$CFG->libdir/externallib.php");
|
||||
|
||||
class core_cohort_external extends external_api {
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
* @since Moodle 2.9
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once("$CFG->libdir/externallib.php");
|
||||
require_once("$CFG->dirroot/comment/lib.php");
|
||||
|
||||
|
||||
@@ -1349,7 +1349,8 @@ class api {
|
||||
JOIN {user} u
|
||||
ON u.id = uc.userid
|
||||
WHERE (uc.status = :waitingforreview
|
||||
OR (uc.status = :inreview AND uc.reviewerid = :reviewerid))";
|
||||
OR (uc.status = :inreview AND uc.reviewerid = :reviewerid))
|
||||
AND u.deleted = 0";
|
||||
$ordersql = " ORDER BY c.shortname ASC";
|
||||
$params = array(
|
||||
'inreview' => user_competency::STATUS_IN_REVIEW,
|
||||
|
||||
@@ -4564,6 +4564,9 @@ class core_competency_api_testcase extends advanced_testcase {
|
||||
}
|
||||
|
||||
public function test_list_user_competencies_to_review() {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/user/lib.php');
|
||||
|
||||
$dg = $this->getDataGenerator();
|
||||
$this->resetAfterTest();
|
||||
$ccg = $dg->get_plugin_generator('core_competency');
|
||||
@@ -4580,10 +4583,12 @@ class core_competency_api_testcase extends advanced_testcase {
|
||||
|
||||
$u1 = $dg->create_user();
|
||||
$u2 = $dg->create_user();
|
||||
$u3 = $dg->create_user();
|
||||
$f1 = $ccg->create_framework();
|
||||
$c1 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]);
|
||||
$c2 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]);
|
||||
$c3 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]);
|
||||
$c4 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]);
|
||||
$uc1a = $ccg->create_user_competency(['userid' => $u1->id, 'competencyid' => $c1->get_id(),
|
||||
'status' => user_competency::STATUS_IDLE]);
|
||||
$uc1b = $ccg->create_user_competency(['userid' => $u1->id, 'competencyid' => $c2->get_id(),
|
||||
@@ -4596,14 +4601,23 @@ class core_competency_api_testcase extends advanced_testcase {
|
||||
'status' => user_competency::STATUS_IDLE]);
|
||||
$uc2c = $ccg->create_user_competency(['userid' => $u2->id, 'competencyid' => $c3->get_id(),
|
||||
'status' => user_competency::STATUS_IN_REVIEW]);
|
||||
$uc3a = $ccg->create_user_competency(['userid' => $u3->id, 'competencyid' => $c4->get_id(),
|
||||
'status' => user_competency::STATUS_WAITING_FOR_REVIEW]);
|
||||
|
||||
// The reviewer can review all plans waiting for review, or in review where they are the reviewer.
|
||||
$this->setUser($reviewer);
|
||||
$result = api::list_user_competencies_to_review();
|
||||
$this->assertEquals(3, $result['count']);
|
||||
$this->assertEquals(4, $result['count']);
|
||||
$this->assertEquals($uc2a->get_id(), $result['competencies'][0]->usercompetency->get_id());
|
||||
$this->assertEquals($uc1b->get_id(), $result['competencies'][1]->usercompetency->get_id());
|
||||
$this->assertEquals($uc1c->get_id(), $result['competencies'][2]->usercompetency->get_id());
|
||||
$this->assertEquals($uc3a->get_id(), $result['competencies'][3]->usercompetency->get_id());
|
||||
|
||||
// Now, let's delete user 3.
|
||||
// It should not be listed on user competencies to review any more.
|
||||
user_delete_user($u3);
|
||||
$result = api::list_user_competencies_to_review();
|
||||
$this->assertEquals(3, $result['count']);
|
||||
|
||||
// The reviewer cannot view the plans when they do not have the permission in the user's context.
|
||||
role_assign($roleprohibit, $reviewer->id, context_user::instance($u2->id)->id);
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "moodle/moodle",
|
||||
"license": "GPL-3.0",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"description": "Moodle - the world's open source learning platform",
|
||||
"type": "project",
|
||||
"homepage": "https://moodle.org",
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "5.5.*",
|
||||
"phpunit/dbUnit": "1.4.*",
|
||||
"moodlehq/behat-extension": "3.32.5"
|
||||
"moodlehq/behat-extension": "3.32.6"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+370
-271
File diff suppressed because it is too large
Load Diff
@@ -259,6 +259,8 @@ $CFG->admin = 'admin';
|
||||
// $CFG->session_memcached_prefix = 'memc.sess.key.';
|
||||
// $CFG->session_memcached_acquire_lock_timeout = 120;
|
||||
// $CFG->session_memcached_lock_expire = 7200; // Ignored if PECL memcached is below version 2.2.0
|
||||
// $CFG->session_memcached_lock_retry_sleep = 150; // Spin-lock retry sleeptime (msec). Only effective
|
||||
// // for tuning php-memcached 3.0.x (PHP 7)
|
||||
//
|
||||
// Redis session handler (requires redis server and redis extension):
|
||||
// $CFG->session_handler_class = '\core\session\redis';
|
||||
|
||||
@@ -256,8 +256,9 @@ class core_course_external extends external_api {
|
||||
|
||||
if (!empty($cm->showdescription) or $cm->modname == 'label') {
|
||||
// We want to use the external format. However from reading get_formatted_content(), $cm->content format is always FORMAT_HTML.
|
||||
$options = array('noclean' => true);
|
||||
list($module['description'], $descriptionformat) = external_format_text($cm->content,
|
||||
FORMAT_HTML, $modcontext->id, $cm->modname, 'intro', $cm->id);
|
||||
FORMAT_HTML, $modcontext->id, $cm->modname, 'intro', $cm->id, $options);
|
||||
}
|
||||
|
||||
//url of the module
|
||||
@@ -3072,6 +3073,7 @@ class core_course_external extends external_api {
|
||||
*/
|
||||
public static function check_updates($courseid, $tocheck, $filter = array()) {
|
||||
global $CFG, $DB;
|
||||
require_once($CFG->dirroot . "/course/lib.php");
|
||||
|
||||
$params = self::validate_parameters(
|
||||
self::check_updates_parameters(),
|
||||
|
||||
@@ -81,6 +81,10 @@ final class util {
|
||||
}
|
||||
error_log($logerrmsg);
|
||||
|
||||
if (http_response_code() == 200) {
|
||||
http_response_code(500);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
};
|
||||
}
|
||||
|
||||
+33
-35
@@ -32,6 +32,7 @@
|
||||
// comment out when debugging or better look into error log!
|
||||
define('NO_DEBUG_DISPLAY', true);
|
||||
|
||||
// @codingStandardsIgnoreLine This script does not require login.
|
||||
require("../../config.php");
|
||||
require_once("lib.php");
|
||||
require_once($CFG->libdir.'/eventslib.php');
|
||||
@@ -42,9 +43,16 @@ require_once($CFG->libdir . '/filelib.php');
|
||||
// the custom handler just logs exceptions and stops.
|
||||
set_exception_handler(\enrol_paypal\util::get_exception_handler());
|
||||
|
||||
// Make sure we are enabled in the first place.
|
||||
if (!enrol_is_enabled('paypal')) {
|
||||
http_response_code(503);
|
||||
throw new moodle_exception('errdisabled', 'enrol_paypal');
|
||||
}
|
||||
|
||||
/// Keep out casual intruders
|
||||
if (empty($_POST) or !empty($_GET)) {
|
||||
print_error("Sorry, you can not use the script that way.");
|
||||
http_response_code(400);
|
||||
throw new moodle_exception('invalidrequest', 'core_error');
|
||||
}
|
||||
|
||||
/// Read all the data from PayPal and get it ready for later;
|
||||
@@ -57,11 +65,27 @@ $req = 'cmd=_notify-validate';
|
||||
$data = new stdClass();
|
||||
|
||||
foreach ($_POST as $key => $value) {
|
||||
if ($key !== clean_param($key, PARAM_ALPHANUMEXT)) {
|
||||
throw new moodle_exception('invalidrequest', 'core_error', '', null, $key);
|
||||
}
|
||||
if (is_array($value)) {
|
||||
throw new moodle_exception('invalidrequest', 'core_error', '', null, 'Unexpected array param: '.$key);
|
||||
}
|
||||
$req .= "&$key=".urlencode($value);
|
||||
$data->$key = fix_utf8($value);
|
||||
}
|
||||
|
||||
if (empty($data->custom)) {
|
||||
throw new moodle_exception('invalidrequest', 'core_error', '', null, 'Missing request param: custom');
|
||||
}
|
||||
|
||||
$custom = explode('-', $data->custom);
|
||||
unset($data->custom);
|
||||
|
||||
if (empty($custom) || count($custom) < 3) {
|
||||
throw new moodle_exception('invalidrequest', 'core_error', '', null, 'Invalid value of the request param: custom');
|
||||
}
|
||||
|
||||
$data->userid = (int)$custom[0];
|
||||
$data->courseid = (int)$custom[1];
|
||||
$data->instanceid = (int)$custom[2];
|
||||
@@ -69,36 +93,13 @@ $data->payment_gross = $data->mc_gross;
|
||||
$data->payment_currency = $data->mc_currency;
|
||||
$data->timeupdated = time();
|
||||
|
||||
// Required for message_send.
|
||||
$PAGE->set_context(context_system::instance());
|
||||
$user = $DB->get_record("user", array("id" => $data->userid), "*", MUST_EXIST);
|
||||
$course = $DB->get_record("course", array("id" => $data->courseid), "*", MUST_EXIST);
|
||||
$context = context_course::instance($course->id, MUST_EXIST);
|
||||
|
||||
/// get the user and course records
|
||||
|
||||
if (! $user = $DB->get_record("user", array("id"=>$data->userid))) {
|
||||
\enrol_paypal\util::message_paypal_error_to_admin("Not a valid user id", $data);
|
||||
die;
|
||||
}
|
||||
|
||||
if (! $course = $DB->get_record("course", array("id"=>$data->courseid))) {
|
||||
\enrol_paypal\util::message_paypal_error_to_admin("Not a valid course id", $data);
|
||||
die;
|
||||
}
|
||||
|
||||
if (! $context = context_course::instance($course->id, IGNORE_MISSING)) {
|
||||
\enrol_paypal\util::message_paypal_error_to_admin("Not a valid context id", $data);
|
||||
die;
|
||||
}
|
||||
|
||||
// Now that the course/context has been validated, we can set it. Not that it's wonderful
|
||||
// to set contexts more than once but system->course switches are accepted.
|
||||
// Required for message_send.
|
||||
$PAGE->set_context($context);
|
||||
|
||||
if (! $plugin_instance = $DB->get_record("enrol", array("id"=>$data->instanceid, "status"=>0))) {
|
||||
\enrol_paypal\util::message_paypal_error_to_admin("Not a valid instance id", $data);
|
||||
die;
|
||||
}
|
||||
|
||||
$plugin_instance = $DB->get_record("enrol", array("id" => $data->instanceid, "enrol" => "paypal", "status" => 0), "*", MUST_EXIST);
|
||||
$plugin = enrol_get_plugin('paypal');
|
||||
|
||||
/// Open a connection back to PayPal to validate the data
|
||||
@@ -113,10 +114,9 @@ $options = array(
|
||||
$location = "https://$paypaladdr/cgi-bin/webscr";
|
||||
$result = $c->post($location, $req, $options);
|
||||
|
||||
if (!$result) { /// Could not connect to PayPal - FAIL
|
||||
echo "<p>Error: could not access paypal.com</p>";
|
||||
\enrol_paypal\util::message_paypal_error_to_admin("Could not access paypal.com to verify payment", $data);
|
||||
die;
|
||||
if ($c->get_errno()) {
|
||||
throw new moodle_exception('errpaypalconnect', 'enrol_paypal', '', array('url' => $paypaladdr, 'result' => $result),
|
||||
json_encode($data));
|
||||
}
|
||||
|
||||
/// Connection is OK, so now we post the data to validate it
|
||||
@@ -318,8 +318,6 @@ if (strlen($result) > 0) {
|
||||
|
||||
} else if (strcmp ($result, "INVALID") == 0) { // ERROR
|
||||
$DB->insert_record("enrol_paypal", $data, false);
|
||||
\enrol_paypal\util::message_paypal_error_to_admin("Received an invalid payment notification!! (Fake payment?)", $data);
|
||||
throw new moodle_exception('erripninvalid', 'enrol_paypal', '', null, json_encode($data));
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
@@ -39,6 +39,9 @@ $string['enrolperiod_desc'] = 'Default length of time that the enrolment is vali
|
||||
$string['enrolperiod_help'] = 'Length of time that the enrolment is valid, starting with the moment the user is enrolled. If disabled, the enrolment duration will be unlimited.';
|
||||
$string['enrolstartdate'] = 'Start date';
|
||||
$string['enrolstartdate_help'] = 'If enabled, users can be enrolled from this date onward only.';
|
||||
$string['errdisabled'] = 'PayPal plugin is disabled and does not handle payment notifications.';
|
||||
$string['erripninvalid'] = 'Instant payment notification has not been verified by PayPal.';
|
||||
$string['errpaypalconnect'] = 'Could not connect to {$a->url} to verify the instant payment notification: {$a->result}';
|
||||
$string['expiredaction'] = 'Enrolment expiry action';
|
||||
$string['expiredaction_help'] = 'Select action to carry out when user enrolment expires. Please note that some user data and settings are purged from course during course unenrolment.';
|
||||
$string['mailadmins'] = 'Notify admin';
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once("$CFG->libdir/externallib.php");
|
||||
require_once("$CFG->libdir/filelib.php");
|
||||
|
||||
|
||||
@@ -138,7 +138,8 @@ MathJax.Hub.Config({
|
||||
// setting. Since it is preferably to always load the secure resource.
|
||||
|
||||
$httpurl = get_config('filter_mathjaxloader', 'httpurl');
|
||||
if ($httpurl !== 'http://cdn.mathjax.org/mathjax/2.6-latest/MathJax.js') {
|
||||
if ($httpurl !== 'http://cdn.mathjax.org/mathjax/2.6-latest/MathJax.js' &&
|
||||
$httpurl !== 'http://cdn.mathjax.org/mathjax/2.6.1/MathJax.js') {
|
||||
// If the http setting has been changed, we make the admin choose the https setting because
|
||||
// it indicates some sort of custom setup. This will be supported by the release notes.
|
||||
unset_config('httpsurl', 'filter_mathjaxloader');
|
||||
@@ -196,5 +197,15 @@ MathJax.Hub.Config({
|
||||
upgrade_plugin_savepoint(true, 2016120502, 'filter', 'mathjaxloader');
|
||||
}
|
||||
|
||||
if ($oldversion < 2016120503) {
|
||||
|
||||
$httpsurl = get_config('filter_mathjaxloader', 'httpsurl');
|
||||
if (empty($httpsurl)) {
|
||||
// URL is empty, most likely because of bad upgrade path. See MDL-59780.
|
||||
set_config('httpsurl', 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js', 'filter_mathjaxloader');
|
||||
}
|
||||
upgrade_plugin_savepoint(true, 2016120503, 'filter', 'mathjaxloader');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2016120502;
|
||||
$plugin->version = 2016120503;
|
||||
$plugin->requires = 2016112900; // Requires this Moodle version.
|
||||
$plugin->component= 'filter_mathjaxloader';
|
||||
|
||||
@@ -489,7 +489,7 @@ class grading_manager {
|
||||
* Returns the given method's controller in the gradable area
|
||||
*
|
||||
* @param string $method the method name, eg 'rubric' (must be available)
|
||||
* @return grading_controller
|
||||
* @return gradingform_controller
|
||||
*/
|
||||
public function get_controller($method) {
|
||||
global $CFG, $DB;
|
||||
@@ -534,7 +534,7 @@ class grading_manager {
|
||||
/**
|
||||
* Returns the controller for the active method if it is available
|
||||
*
|
||||
* @return null|grading_controller
|
||||
* @return null|gradingform_controller
|
||||
*/
|
||||
public function get_active_controller() {
|
||||
if ($gradingmethod = $this->get_active_method()) {
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once("$CFG->libdir/externallib.php");
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['clianswerno'] = 'n';
|
||||
$string['cliansweryes'] = 's';
|
||||
$string['cliincorrectvalueerror'] = 'Error, valor incorrecta "{$a->value}" pa "{$a->option}"';
|
||||
$string['cliincorrectvalueretry'] = 'Valor incorrecta, per favor, intente de nuevo';
|
||||
$string['clitypevalue'] = 'valor d\'o tipo';
|
||||
$string['clitypevaluedefault'] = 'valor d\'o tipo, prete Enter pa utilizar la valor per defecto ({$a})';
|
||||
$string['cliunknowoption'] = 'Opcions no reconoixidas:
|
||||
{$a}
|
||||
Per favor, utilice la opción Aduya.';
|
||||
$string['cliyesnoprompt'] = 'escriba s (pa sí) u n (pa no)';
|
||||
$string['environmentrequireinstall'] = 'ha d\'estar instalau/activau';
|
||||
$string['environmentrequireversion'] = 'versión {$a->needed} ye obligatoria y ye executando {$a->current}';
|
||||
$string['upgradekeyset'] = 'Clau d\'actualización (deixar en blanco pa no establir-la)';
|
||||
@@ -0,0 +1,51 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['cannotcreatedboninstall'] = '<p> No se puede creyar la base de datos. </p><p> La base de datos especificada no existe y l\'usuario indicau no tiene permiso pa creyar la base de datos. </p><p> L\'administrador d\'o puesto ha de comprebar la configuración de base de datos. </p>';
|
||||
$string['cannotcreatelangdir'] = 'No se puede creyar lo directorio d\'idioma.';
|
||||
$string['cannotcreatetempdir'] = 'No se puede creyar lo directorio temp.';
|
||||
$string['cannotdownloadcomponents'] = 'No se puede descargar components';
|
||||
$string['cannotdownloadzipfile'] = 'No se puede descargar lo fichero ZIP';
|
||||
$string['cannotfindcomponent'] = 'No se puede trobar lo component.';
|
||||
$string['cannotsavemd5file'] = 'No se puede alzar lo fichero md5';
|
||||
$string['cannotsavezipfile'] = 'No se puede alzar lo fichero ZIP';
|
||||
$string['cannotunzipfile'] = 'No se puede descomprimir lo fichero';
|
||||
$string['componentisuptodate'] = 'Lo component ye actualizau';
|
||||
$string['dmlexceptiononinstall'] = '<p>S\'ha produciu una error de base de datos [{$a->errorcode}].<br />{$a->debuginfo}</p>';
|
||||
$string['downloadedfilecheckfailed'] = 'Ha fallau la comprebación d\'o fichero descargau';
|
||||
$string['invalidmd5'] = 'La variable de verificación MD5 ye incorrecta no ye valida - tracte nuevament';
|
||||
$string['missingrequiredfield'] = 'Falta bell campo necesario';
|
||||
$string['remotedownloaderror'] = '<p>Falló la descarga d\'o component a lo suyo servidor. Se recomienda verificar los achustes d\'o proxy, extensión PHP cURL.</p>
|
||||
<p>Ha de descargar lo <a href="{$a->url}">{$a->url}</a> fichero manualment, copiar-lo en "{$a->dest}" en o suyo servidor y descomprimir-lo allí.</p>';
|
||||
$string['wrongdestpath'] = 'Rota de destín erronia.';
|
||||
$string['wrongsourcebase'] = 'Base de fuent d\'URL erronia.';
|
||||
$string['wrongzipfilename'] = 'Nombre de fichero ZIP erronio.';
|
||||
@@ -0,0 +1,99 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['admindirname'] = 'Directorio Admin';
|
||||
$string['availablelangs'] = 'Packs d\'idiomas disponibles';
|
||||
$string['chooselanguagehead'] = 'Triar idioma';
|
||||
$string['chooselanguagesub'] = 'Per favor, tríe un idioma pa lo proceso d\'instalación. Este idioma s\'usará tamién como idioma per defecto d\'o puesto, si bien puede cambiar-se mas abance.';
|
||||
$string['clialreadyconfigured'] = 'Lo fichero de configuración config.php ya existe. Per favor, faga servir admin/cli/install_database.php pa instalar Moodle en este puesto.';
|
||||
$string['clialreadyinstalled'] = 'Lo fichero de configuración config.php ya existe. Per favor, faga servir admin/cli/install_database.php pa actualizar Moodle en este puesto.';
|
||||
$string['cliinstallheader'] = 'Programa d\'instalación Moodle de linia de comando {$a}';
|
||||
$string['databasehost'] = 'Servidor d\'a base de datos';
|
||||
$string['databasename'] = 'Nombre d\'a base de datos';
|
||||
$string['databasetypehead'] = 'Tríe lo controlador d\'a base de datos';
|
||||
$string['dataroot'] = 'Directorio de Datos';
|
||||
$string['datarootpermission'] = 'Permiso directorios de datos';
|
||||
$string['dbprefix'] = 'Prefixo de tablas';
|
||||
$string['dirroot'] = 'Directorio de Moodle';
|
||||
$string['environmenthead'] = 'Comprebando lo suyo entorno';
|
||||
$string['environmentsub2'] = 'Cada versión de Moodle tiene bell requisito minimo d\'a versión de PHP y un numero obligatorio d\'extensions de PHP.
|
||||
Una comprebación de l\'entorno completo se realiza antes de cada instalación y actualización. Per favor, se meta en contacto con l\'administrador d\'o servidor si no sabes cómo instalar la nueva versión u habilitar las extensions PHP.';
|
||||
$string['errorsinenvironment'] = 'La comprebación de l\'entorno fallo!';
|
||||
$string['installation'] = 'Instalación';
|
||||
$string['langdownloaderror'] = 'L\'idioma "{$a}" no podió estar descargau. Lo proceso d\'instalación continará en Anglés.';
|
||||
$string['memorylimithelp'] = '<p>Lo limite de memoria PHP en o suyo servidor ye actualment {$a}.</p>
|
||||
|
||||
<p>Esto puede ocasionar que Moodle tienga problemas de memoria mas abance, especialment si vusté tiene activaus muitos modulos y/u muitos usuarios.</p>
|
||||
|
||||
<p>Recomendamos que configure PHP con o limite mas alto posible, y.g. 40M.
|
||||
I hai quantas formas de fer esto:</p>
|
||||
<ol>
|
||||
<li>Si puede fer-lo, recompile PHP con <i>--enable-memory-limit</i>.
|
||||
Esto fa que Moodle fixe per ell mesmo lo limite de memoria.</li>
|
||||
<li>Si tiene acceso a lo fichero php.ini, puede cambiar l\'achuste <b>memory_limit</b>
|
||||
a, digamos, 40M. Si no lo tiene, pida a lo suyo administrador que lo faiga per vusté.</li>
|
||||
<li>En qualques servidors PHP vusté puede creyar en o directorio Moodle un fichero .htaccess que contienga esta linia:
|
||||
<p><blockquote>php_value memory_limit 40M</blockquote></p>
|
||||
<p>Manimenos, en qualques servidors esto fa que <b>totas</b> las pachinas PHP deixen de funcionar (podrá veyer las errors quan mire las pachinas) de traza que habrá d\'eliminar lo fichero .htaccess.</p></li>
|
||||
</ol>';
|
||||
$string['paths'] = 'Rotas';
|
||||
$string['pathserrcreatedataroot'] = 'Lo directorio d\'os datos ({$a->dataroot}) no puede estar creyau per l\'instalador.';
|
||||
$string['pathshead'] = 'Confirme las rotas';
|
||||
$string['pathsrodataroot'] = 'Lo directorio dataroot no tiene permisos d\'escritura.';
|
||||
$string['pathsroparentdataroot'] = 'Lo directorio pai ({$a->parent}) no tiene permisos d\'escritura. Lo directorio d\'os datos ({$a->dataroot}) no puede estar creyau per l\'instalador.';
|
||||
$string['pathssubadmindir'] = 'Muit pocos servidors web usan /admin como un URL especial pa acceder a un panel de control u bella cosa semellant. Lamentablement, esto dentra en conflicto con a ubicación estandard pa las pachinas d\'administración de Moodle. Vusté puede solucionar este problema, renombrando lo directorio admin en a suya instalación Moodle, metendo un nuevo nombre aquí. Per eixemplo: <em> moodleadmin </em>. Esto solucionará los vinclos d\'administración en instalación Moodle.';
|
||||
$string['pathssubdataroot'] = 'Necesita bell espacio an que Moodle puede alzar los fichers puyaus. En este directorio ha de poder LEYER y ESCRIBIR l\'usuario d\'o servidor web (per lo cheneral \'nobody\', \'apache\' u \'www-data\'), pero no ha de poder-se acceder a esta carpeta dreitament a traviés d\'a web. L\'instalador tractará de creyar-la si no existe.';
|
||||
$string['pathssubdirroot'] = '<p>Rota completa d\'o directorio que contiene lo codigo de Moodle.</p>';
|
||||
$string['pathssubwwwroot'] = 'Adreza web completa pa acceder a Moodle. No ye posible acceder a Moodle utilizando multiples adrezas. Si lo suyo puesto tiene quantas adrezas publicas ha de configurar redireccions permanents en totas ellas, fueras d\'en2 esta. Si lo suyo puesto web ye accesible tanto dende una intranet como dende Internet, escriba aquí l\'adreza publica y configure la suya DNS pa que los usuarios d\'o suyo intranet puedan tamién utilizar l\'adreza publica.';
|
||||
$string['pathsunsecuredataroot'] = 'La ubicación de dataroot no ye segura';
|
||||
$string['pathswrongadmindir'] = 'Lo directorio admin no existe';
|
||||
$string['phpextension'] = 'Extensión PHP {$a}';
|
||||
$string['phpversion'] = 'Versión PHP';
|
||||
$string['phpversionhelp'] = '<p>Moodle requiere a lo menos una versión de PHP 4.3.0 u 5.1.0 ((5.0.x tiene una serie de problemas conoixius).</p>
|
||||
<p>En este momento ye executando la versión {$a}</p>
|
||||
<p>Ha d\'actualizar PHP u tresladar-se a unatro servidor con una versión mas recient de PHP!<br />
|
||||
(En caso de 5.0.x podría tamién revertir a la versión 4.4.x)</p>';
|
||||
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
|
||||
$string['welcomep20'] = 'Si ye veyendo esta pachina ye perque ha puesto executar lo paquet <strong>{$a->packname} {$a->packversion}</strong> en o suyo ordinador. Parabiens!';
|
||||
$string['welcomep30'] = 'Esta versión de <strong>{$a->installername}</strong> incluye las
|
||||
aplicacions necesarias pa que <strong>Moodle</strong> funcione en o suyo ordinador,
|
||||
principalment:';
|
||||
$string['welcomep40'] = 'Lo paquet tamién incluye <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
|
||||
$string['welcomep50'] = 'L\'uso de totas las aplicacions d\'o paquet ye gubernau per las suyas respectivas
|
||||
licencias. Lo programa <strong>{$a->installername}</strong> ye
|
||||
<a href="http://www.opensource.org/docs/definition_plain.html">codigo ubierto</a> y se distribuye
|
||||
baixo licencia <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a>.';
|
||||
$string['welcomep60'] = 'Las siguients pachinas le guiarán a traviés de qualques sencillos pasos pa configurar
|
||||
y achustar <strong>Moodle</strong> en o suyo ordinador. Puede utilizar las valors per defecto sucherius u,
|
||||
de forma opcional, modificar-los pa que s\'achusten a las suyas necesidatz.';
|
||||
$string['welcomep70'] = 'Prete en o botón "Siguient" pa continar con a configuración de <strong>Moodle</strong>.';
|
||||
$string['wwwroot'] = 'Adreza Web';
|
||||
@@ -0,0 +1,37 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['language'] = 'Idioma';
|
||||
$string['moodlelogo'] = 'Logo de Moodle';
|
||||
$string['next'] = 'Siguient';
|
||||
$string['previous'] = 'Anterior';
|
||||
$string['reload'] = 'Recargar';
|
||||
@@ -36,7 +36,7 @@ $string['chooselanguagehead'] = 'Sprache wählen';
|
||||
$string['chooselanguagesub'] = 'Wählen Sie eine Sprache, die Sie während der Installation verwenden wollen. Die ausgewählte Sprache wird nach der Installation als Standardsprache der Instanz benutzt, aber Sie dürfen die Sprache jederzeit ändern.';
|
||||
$string['clialreadyconfigured'] = 'Die Datei config.php existiert bereits. Bitte benutzen Sie admin/cli/install_database.php, wenn Sie diese Site installieren möchten.';
|
||||
$string['clialreadyinstalled'] = 'Die Datei config.php existiert bereits. Bitte benutzen Sie admin/cli/install_database.php, wenn Sie diese Site aktualisieren möchten.';
|
||||
$string['cliinstallheader'] = 'Installation von Moodle {$a} über die Kommandozeile';
|
||||
$string['cliinstallheader'] = 'Installation von Moodle {$a} über die Befehlszeile';
|
||||
$string['databasehost'] = 'Datenbank-Server';
|
||||
$string['databasename'] = 'Datenbank-Name';
|
||||
$string['databasetypehead'] = 'Datenbank-Treiber wählen';
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['admindirname'] = 'Directorio Admin';
|
||||
$string['availablelangs'] = 'Packs de idiomas disponibles';
|
||||
$string['availablelangs'] = 'Paquetes de idiomas disponibles';
|
||||
$string['chooselanguagehead'] = 'Seleccionar idioma';
|
||||
$string['chooselanguagesub'] = 'Por favor, seleccione un idioma para el proceso de instalación. Este idioma se usará también como idioma por defecto del sitio, si bien puede cambiarse más adelante.';
|
||||
$string['clialreadyconfigured'] = 'El archivo de configuración config.php ya existe. Por favor, utilice admin/cli/install_database.php para instalar Moodle en este sitio.';
|
||||
|
||||
@@ -88,9 +88,9 @@ $string['pathsunsecuredataroot'] = 'Andmete juurkataloogi asukoht pole turvaline
|
||||
$string['pathswrongadmindir'] = 'Halduskataloogi pole olemas';
|
||||
$string['phpextension'] = '{$a} PHP-laiendus';
|
||||
$string['phpversion'] = 'PHP versioon';
|
||||
$string['phpversionhelp'] = '<p>Moodle vajab vähemalt PHP versiooni 4.1.0</p>
|
||||
<p>Sinu jooksev versioon on {$a}</p>
|
||||
<p>Sa pead oma PHP-d uuendama või kolima hosti, kus on uuem PHP versioon!</p>';
|
||||
$string['phpversionhelp'] = '<p>Moodle vajab vähemalt PHP versiooni 5.6.5 või 7.1 (versioonil 7.0.x on mõned mootoripiirangud).</p>
|
||||
<p>Teie praegune versioon on {$a}.</p>
|
||||
<p>Peate uuendama oma PHP või kolima hosti, kus on uuem PHP versioon.</p>';
|
||||
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
|
||||
$string['welcomep20'] = 'Teile kuvatakse see leht, kuna olete edukalt oma arvutisse installinud ja
|
||||
käivitanud paketi <strong>{$a->packname} {$a->packversion}</strong>. Õnnitleme!';
|
||||
|
||||
@@ -41,3 +41,4 @@ Mesedez, erabili --laguntza aukera.';
|
||||
$string['cliyesnoprompt'] = 'idatzi b (bai esateko) edo e (ez esateko)';
|
||||
$string['environmentrequireinstall'] = 'derrigorrezkoa da instalatuta eta gaituta izatea';
|
||||
$string['environmentrequireversion'] = '{$a->needed} bertsioa beharrezkoa da eta zu {$a->current} ari zara egikaritzen';
|
||||
$string['upgradekeyset'] = 'Eguneraketa-kodea (utzi hutsik kodea erabili nahi ez baduzu)';
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['cannotcreatedboninstall'] = '<p>Ezin da datu-basea sortu.<p>
|
||||
<p>Zehaztutako datu-basea ez da existitzen eta adierazitako erabiltzaileak ez du baimenik datu-basea sortzeko.<p>
|
||||
$string['cannotcreatedboninstall'] = '<p>Ezin da datu-basea sortu.</p>
|
||||
<p>Zehaztutako datu-basea ez da existitzen eta adierazitako erabiltzaileak ez du baimenik datu-basea sortzeko.</p>
|
||||
<p>Guneko kudeatzaileak datu-basearen konfigurazioa egiaztatu behar du.</p>';
|
||||
$string['cannotcreatelangdir'] = 'Ezin da hizkuntza-direktorioa sortu';
|
||||
$string['cannotcreatetempdir'] = 'Ezin da temp direktorioa sortu';
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['language'] = 'שפת ממשק';
|
||||
$string['moodlelogo'] = 'לוגו של Moodle';
|
||||
$string['next'] = 'הבא';
|
||||
$string['previous'] = 'קודם';
|
||||
$string['reload'] = 'טעינה מחדש';
|
||||
|
||||
@@ -35,4 +35,8 @@ $string['cliansweryes'] = 'वाई';
|
||||
$string['cliincorrectvalueerror'] = 'त्रुटि, "{$a->option}" के लिए गलत मान जो की "{$a->value}" है';
|
||||
$string['cliincorrectvalueretry'] = 'ग़लत मान, कृपया पुनः प्रयास करें';
|
||||
$string['clitypevalue'] = 'टाइप मूल्य';
|
||||
$string['clitypevaluedefault'] = 'वैल्यू टाइप करें, डिफ़ॉल्ट वैल्यू ({$ a}) का उपयोग करने के लिए Enter दबाएं';
|
||||
$string['cliunknowoption'] = 'अपरिचित विकल्प:
|
||||
{$a}
|
||||
कृपया --help विकल्प का उपयोग करें।';
|
||||
$string['cliyesnoprompt'] = 'टाइप Y (का मतलब है हाँ) या N (का मतलब है नहीं )';
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['language'] = 'Jezik';
|
||||
$string['moodlelogo'] = 'Moodle logo';
|
||||
$string['next'] = 'Nastavi';
|
||||
$string['previous'] = 'Prethodni';
|
||||
$string['reload'] = 'Učitaj ponovno';
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['thislanguage'] = 'Igbo';
|
||||
@@ -35,7 +35,7 @@ $string['availablelangs'] = '利用可能な言語パック';
|
||||
$string['chooselanguagehead'] = '言語を選択してください。';
|
||||
$string['chooselanguagesub'] = 'インストールにのみ使用する言語を選択してください。この言語はサイトのデフォルト言語としても使用されます。後でサイト言語を変更することができます。';
|
||||
$string['clialreadyconfigured'] = '設定ファイルconfig.phpはすでに登録されています。このサイトをインストールする場合、admin/cli/install_database.phpを使用してください。';
|
||||
$string['clialreadyinstalled'] = '設定ファイルconfig.phpは、すでに登録されています。このサイトをアップグレードする場合、admin/cli/upgrade.phpを使用してください。';
|
||||
$string['clialreadyinstalled'] = '設定ファイルconfig.phpはすでに登録されています。このサイトをアップグレードする場合、admin/cli/upgrade.phpを使用してください。';
|
||||
$string['cliinstallheader'] = 'Moodle {$a} コマンドラインインストールプログラム';
|
||||
$string['databasehost'] = 'データベースホスト :';
|
||||
$string['databasename'] = 'データベース名 :';
|
||||
@@ -57,7 +57,7 @@ $string['memorylimithelp'] = '<p>現在、サーバのPHPメモリ制限が {$a}
|
||||
<ol>
|
||||
<li>あなたがリコンパイル可能な場合、PHPを<i>--enable-memory-limit</i>オプションでコンパイルしてください。これにより、Moodle自身がメモリ制限を設定することが可能になります。</li>
|
||||
<li>あなたがphp.iniファイルにアクセスできる場合、<b>memory_limit</b>設定を40Mのように変更することができます。php.iniファイルにアクセスできない場合、管理者に変更を依頼してください。</li>
|
||||
<li>いくつかのPHPサーバでは、下記の行を含む.htaccessファイルをMoodleディレクトリに作成することができます:
|
||||
<li>いくつかのPHPサーバでは下記の行を含む.htaccessファイルをMoodleディレクトリに作成することができます:
|
||||
<blockquote><div>php_value memory_limit 40M</div></blockquote>
|
||||
<p>しかし、この設定が<b>すべての</b>PHPページの動作を妨げる場合もあります。ページ閲覧中にエラーが表示される場合、.htaccessファイルを削除してください。</p></li>
|
||||
</ol>';
|
||||
|
||||
@@ -40,3 +40,4 @@ $string['cliunknowoption'] = 'Neatpažintos parinktys: {$a} naudokite --žinyno
|
||||
$string['cliyesnoprompt'] = 'įveskite t (taip) arba n (ne)';
|
||||
$string['environmentrequireinstall'] = 'turi būti įdiegta ir įjungta';
|
||||
$string['environmentrequireversion'] = 'būtina naudoti versiją {$a->needed}, o jūs naudojate {$a->current}';
|
||||
$string['upgradekeyset'] = 'Naujovinimo raktas (palikite tuščią, jei nenorite nustatyti)';
|
||||
|
||||
@@ -63,7 +63,9 @@ $string['pathsunsecuredataroot'] = 'Šakninio duomenų katalogo kelias nesaugus'
|
||||
$string['pathswrongadmindir'] = 'Nėra administratoriaus katalogo';
|
||||
$string['phpextension'] = '{$a} PHP plėtinys';
|
||||
$string['phpversion'] = 'PHP versija';
|
||||
$string['phpversionhelp'] = '<p>„Moodle“ reikalauja, kad PHP versija būtų bent 4.3.0 arba 5.1.0 (5.0.x versijoje yra daug problemų).</p> <p>Dabar naudojate versiją {$a}</p> <p>Turite atnaujinti PHP versiją arba perkelti į pagrindinį kompiuterį, kuriame veikia naujesnė PHP versija!<br /> (Jei naudojate 5.0.x versiją, taip pat galite paleisti senesnę 4.4.x versiją)</p>';
|
||||
$string['phpversionhelp'] = '<p>„Moodle“ reikalauja, kad PHP versija būtų ne žemesnė 5.6.5 arba 7.1 (7.0.x versijoje yra tam tikrų trūkumų).</p>
|
||||
<p>Dabar naudojate versiją {$a}</p>
|
||||
<p>Turite atnaujinti PHP versiją arba perkelti į pagrindinį kompiuterį, kuriame veikia naujesnė PHP versija.</p>';
|
||||
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
|
||||
$string['welcomep20'] = 'Matote šį puslapį, nes į kompiuterį sėkmingai įdiegėte ir paleidote <strong>{$a->packname} {$a->packversion}</strong> paketą. Sveikiname!';
|
||||
$string['welcomep30'] = 'Šiame <strong>{$a->installername}</strong> leidime yra taikomosios programos, skirtos aplinkai, kurioje veiks <strong>Moodle</strong>, sukurti:';
|
||||
|
||||
@@ -30,6 +30,5 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = '';
|
||||
$string['thisdirection'] = 'ltr';
|
||||
$string['thislanguage'] = 'Lietuvių';
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['thisdirection'] = 'ltr';
|
||||
$string['thislanguage'] = 'Māori (Te Reo)';
|
||||
@@ -37,6 +37,9 @@ $string['cliincorrectvalueerror'] = 'Грешка, погрешна вредно
|
||||
$string['cliincorrectvalueretry'] = 'Неточни вредност, ве молиме обидете се повторно';
|
||||
$string['clitypevalue'] = 'впишете вредност';
|
||||
$string['clitypevaluedefault'] = 'впишете вредност, притиснете Enter за да го користите стандардната вредност ({$a})';
|
||||
$string['cliunknowoption'] = 'Непрепознаена опција:
|
||||
{$a}
|
||||
Ве молиме употребете --help опција.';
|
||||
$string['cliyesnoprompt'] = 'впишете y (значи да) или n (значи не)';
|
||||
$string['environmentrequireinstall'] = 'потребно е да се инсталира/овозможи';
|
||||
$string['environmentrequireversion'] = 'верзијата {$a->needed} е потребна, а вие извршувате {$a->current}';
|
||||
|
||||
@@ -35,11 +35,11 @@ $string['cliansweryes'] = 'y';
|
||||
$string['cliincorrectvalueerror'] = 'Error, valor incorrècta « {$a->value} » pel paramètre « {$a->option} »';
|
||||
$string['cliincorrectvalueretry'] = 'Valor incorrècta, ensajar tornamai';
|
||||
$string['clitypevalue'] = 'tipe valor';
|
||||
$string['clitypevaluedefault'] = 'tipe valor, tapez Entrée per utilizar la valor per defaut ({$a})';
|
||||
$string['clitypevaluedefault'] = 'tipe valor, picatz Entrada per utilizar la valor per defaut ({$a})';
|
||||
$string['cliunknowoption'] = 'Options non reconegudas :
|
||||
{$a}.
|
||||
Utilisez l\'option --help.';
|
||||
Utilizatz l\'opcion --help.';
|
||||
$string['cliyesnoprompt'] = 'Picatz y (per òc) o n (per non)';
|
||||
$string['environmentrequireinstall'] = 'doit èsser installat e activat';
|
||||
$string['environmentrequireinstall'] = 'deu èsser installat e activat';
|
||||
$string['environmentrequireversion'] = 'la version {$a->needed} es requesida ; utilizatz actualament la version {$a->current}';
|
||||
$string['upgradekeyset'] = 'Metre a jorn la clau (daissar void per la definir pas)';
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['thislanguage'] = 'Pidgin';
|
||||
@@ -37,9 +37,9 @@ $string['chooselanguagesub'] = 'Por favor, escolha o idioma para a instalação.
|
||||
$string['clialreadyconfigured'] = 'Arquivo config.php já existe. Por favor, use admin/cli/install_database.php para instalar o Moodle neste site.';
|
||||
$string['clialreadyinstalled'] = 'Arquivo config.php já existe. Por favor use admin/cli/install_database.php para atualizar o Moodle neste site.';
|
||||
$string['cliinstallheader'] = 'Programa de instalação por linha de comando do Moodle {$a}';
|
||||
$string['databasehost'] = 'Host da base de dados';
|
||||
$string['databasename'] = 'Nome da base de dados';
|
||||
$string['databasetypehead'] = 'Escolha o driver da base de dados';
|
||||
$string['databasehost'] = 'Host do banco de dados';
|
||||
$string['databasename'] = 'Nome do banco de dados';
|
||||
$string['databasetypehead'] = 'Escolha o driver do banco de dados';
|
||||
$string['dataroot'] = 'Diretório de dados';
|
||||
$string['datarootpermission'] = 'Permissões nos diretórios de dados';
|
||||
$string['dbprefix'] = 'Prefixo das tabelas';
|
||||
|
||||
@@ -72,5 +72,11 @@ $string['welcomep20'] = 'Vedeți această pagină deoarece ați instalat și lan
|
||||
$string['welcomep30'] = 'Lansarea <strong>{$a->installername}</strong> include aplicațiile
|
||||
pentru a crea un mediu în care <strong>Moodle</strong> va funcționa, și anume:';
|
||||
$string['welcomep40'] = 'Pachetul include și <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
|
||||
$string['welcomep50'] = 'Utilizarea tuturor aplicațiilor din acest pachet este determinată de respectivele lor
|
||||
licențe. Pachetul complet <strong>{$a->installername}</strong> este
|
||||
<a href="http://www.opensource.org/docs/definition_plain.html">open source</a> și este distribuit sub licența <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a>.';
|
||||
$string['welcomep60'] = 'Următoarele pagini vă oferă pași ușor de urmat pentru a
|
||||
configura și seta <strong>Moodle</strong> în computerul dumneavoastră. Puteți accepta setările implicite
|
||||
sau, opțional, să le modificați pentru a corespunde nevoilor dumneavoastră.';
|
||||
$string['welcomep70'] = 'Click pe butonul "Next" de mai jos pentru a continua setarea <strong>Moodle</strong>.';
|
||||
$string['wwwroot'] = 'Adresă Web';
|
||||
|
||||
@@ -31,3 +31,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['databasename'] = 'Databasens namn';
|
||||
$string['welcomep50'] = 'Användningen av alla applikationer i detta paket regleras av sina respektive licenser. Det fullständiga paketet <strong>{$a->installername}</strong> är <a href="http://www.opensource.org/docs/definition_plain.html">Öppen källkod</a> och distribueras under <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> licensen.';
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['language'] = 'Забон';
|
||||
$string['moodlelogo'] = 'Логотипи Moodle';
|
||||
$string['next'] = 'Давомаш';
|
||||
$string['previous'] = 'Ба ақиб';
|
||||
$string['reload'] = 'Навсозӣ карда шавад';
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['thislanguage'] = 'Uyghur - latin';
|
||||
@@ -0,0 +1,34 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['clianswerno'] = 'ن';
|
||||
$string['cliansweryes'] = 'ي';
|
||||
@@ -0,0 +1,34 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['thisdirection'] = 'rtl';
|
||||
$string['thislanguage'] = 'ئۇيغۇرچە';
|
||||
@@ -81,17 +81,16 @@ class core_iplookup_geoip_testcase extends advanced_testcase {
|
||||
}
|
||||
|
||||
public function test_ipv4() {
|
||||
|
||||
$result = iplookup_find_location('131.111.150.25');
|
||||
$result = iplookup_find_location('192.30.255.112');
|
||||
|
||||
$this->assertEquals('array', gettype($result));
|
||||
$this->assertEquals('Cambridge', $result['city']);
|
||||
$this->assertEquals(0.1167, $result['longitude'], 'Coordinates are out of accepted tolerance', 0.01);
|
||||
$this->assertEquals(52.2, $result['latitude'], 'Coordinates are out of accepted tolerance', 0.01);
|
||||
$this->assertEquals('San Francisco', $result['city']);
|
||||
$this->assertEquals(-122.3933, $result['longitude'], 'Coordinates are out of accepted tolerance', 0.01);
|
||||
$this->assertEquals(37.7697, $result['latitude'], 'Coordinates are out of accepted tolerance', 0.01);
|
||||
$this->assertNull($result['error']);
|
||||
$this->assertEquals('array', gettype($result['title']));
|
||||
$this->assertEquals('Cambridge', $result['title'][0]);
|
||||
$this->assertEquals('United Kingdom', $result['title'][1]);
|
||||
$this->assertEquals('San Francisco', $result['title'][0]);
|
||||
$this->assertEquals('United States', $result['title'][1]);
|
||||
}
|
||||
|
||||
public function test_ipv6() {
|
||||
@@ -110,4 +109,3 @@ class core_iplookup_geoip_testcase extends advanced_testcase {
|
||||
$this->assertEquals('United States', $result['title'][1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,17 +46,17 @@ class core_iplookup_geoplugin_testcase extends advanced_testcase {
|
||||
$CFG->geoipfile = '';
|
||||
}
|
||||
|
||||
public function test_geoip_ipv4() {
|
||||
$result = iplookup_find_location('131.111.150.25');
|
||||
public function test_ipv4() {
|
||||
$result = iplookup_find_location('192.30.255.112');
|
||||
|
||||
$this->assertEquals('array', gettype($result));
|
||||
$this->assertEquals('Cambridge', $result['city']);
|
||||
$this->assertEquals(0.1167, $result['longitude'], '', 0.001);
|
||||
$this->assertEquals(52.200000000000003, $result['latitude'], '', 0.001);
|
||||
$this->assertEquals('San Francisco', $result['city']);
|
||||
$this->assertEquals(-122.3933, $result['longitude'], 'Coordinates are out of accepted tolerance', 0.01);
|
||||
$this->assertEquals(37.7697, $result['latitude'], 'Coordinates are out of accepted tolerance', 0.01);
|
||||
$this->assertNull($result['error']);
|
||||
$this->assertEquals('array', gettype($result['title']));
|
||||
$this->assertEquals('Cambridge', $result['title'][0]);
|
||||
$this->assertEquals('United Kingdom', $result['title'][1]);
|
||||
$this->assertEquals('San Francisco', $result['title'][0]);
|
||||
$this->assertEquals('United States', $result['title'][1]);
|
||||
}
|
||||
|
||||
public function test_geoip_ipv6() {
|
||||
|
||||
+4
-3
@@ -137,7 +137,7 @@ $string['configallowblockstodock'] = 'If enabled and supported by the selected t
|
||||
$string['configallowcategorythemes'] = 'If you enable this, then themes can be set at the category level. This will affect all child categories and courses unless they have specifically set their own theme. WARNING: Enabling category themes may affect performance.';
|
||||
$string['configallowcoursethemes'] = 'If you enable this, then courses will be allowed to set their own themes. Course themes override all other theme choices (site, user, or session themes)';
|
||||
$string['configallowedemaildomains'] = 'List email domains that are allowed to be disclosed in the "From" section of outgoing email. The default of "Empty" will use the No-reply address for all outgoing email. The use of wildcards is allowed e.g. *.example.com will allow emails sent from any subdomain of example.com, but not example.com itself. This will require separate entry.';
|
||||
$string['configallowemailaddresses'] = 'If you want to restrict all new email addresses to particular domains, then list them here separated by spaces. All other domains will be rejected. To allow subdomains add the domain with a preceding \'.\'. eg <strong>ourcollege.edu.au .gov.au</strong>';
|
||||
$string['configallowemailaddresses'] = 'To restrict new email addresses to particular domains, list them here separated by spaces. All other domains will be rejected. To allow subdomains, add the domain with a preceding \'.\'. To allow a root domain together with its subdomains, add the domain twice - once with a preceding \'.\' and once without e.g. .ourcollege.edu.au ourcollege.edu.au.';
|
||||
$string['configallowguestmymoodle'] = 'If enabled guests can access Dashboard, otherwise guests are redirected to the site front page.';
|
||||
$string['configallowobjectembed'] = 'As a default security measure, normal users are not allowed to embed multimedia (like Flash) within texts using explicit EMBED and OBJECT tags in their HTML (although it can still be done safely using the mediaplugins filter). If you wish to allow these tags then enable this option.';
|
||||
$string['configallowoverride'] = 'You can allow people with the roles on the left side to override some of the column roles';
|
||||
@@ -296,8 +296,8 @@ $string['configproxypassword'] = 'Password needed to access internet through pro
|
||||
$string['configproxyport'] = 'If this server needs to use a proxy computer, then provide the proxy port here.';
|
||||
$string['configproxytype'] = 'Type of web proxy (PHP5 and cURL extension required for SOCKS5 support).';
|
||||
$string['configproxyuser'] = 'Username needed to access internet through proxy if required, empty if none (PHP cURL extension required).';
|
||||
$string['configrecaptchaprivatekey'] = 'String of characters (private key) used to communicate between your Moodle server and the recaptcha server. ReCAPTCHA keys can be obtained from <a target="_blank" href="https://www.google.com/recaptcha">Google reCAPTCHA</a>.';
|
||||
$string['configrecaptchapublickey'] = 'String of characters (public key) used to display the reCAPTCHA element in the signup form. ReCAPTCHA keys can be obtained from <a target="_blank" href="https://www.google.com/recaptcha">Google reCAPTCHA</a>.';
|
||||
$string['configrecaptchaprivatekey'] = 'String of characters (secret key) used to communicate between your Moodle server and the recaptcha server. ReCAPTCHA keys can be obtained from <a target="_blank" href="https://www.google.com/recaptcha">Google reCAPTCHA</a>.';
|
||||
$string['configrecaptchapublickey'] = 'String of characters (site key) used to display the reCAPTCHA element in the signup form. ReCAPTCHA keys can be obtained from <a target="_blank" href="https://www.google.com/recaptcha">Google reCAPTCHA</a>.';
|
||||
$string['configrequestcategoryselection'] = 'Allow the selection of a category when requesting a course.';
|
||||
$string['configrequestedstudentname'] = 'Word for student used in requested courses';
|
||||
$string['configrequestedstudentsname'] = 'Word for students used in requested courses';
|
||||
@@ -1148,6 +1148,7 @@ $string['unsupporteddbstorageengine'] = 'The database storage engine being used
|
||||
$string['unsupporteddbtablerowformat'] = 'Your database has tables using Antelope as the file format. You are recommended to convert the tables to the Barracuda file format. See the documentation <a href="https://docs.moodle.org/en/cli">Administration via command line</a> for details of a tool for converting InnoDB tables to Barracuda.';
|
||||
$string['unsupportedphpversion7'] = 'PHP version 7 is not supported.';
|
||||
$string['unsupportedphpversion71'] = 'PHP version 7.1 is not supported.';
|
||||
$string['unsupportedphpversion72'] = 'PHP version 7.2 is not supported.';
|
||||
$string['unsuspenduser'] = 'Activate user account';
|
||||
$string['updateaccounts'] = 'Update existing accounts';
|
||||
$string['updatecomponent'] = 'Update component';
|
||||
|
||||
+3
-2
@@ -97,6 +97,7 @@ $string['forgottenpasswordurl'] = 'Forgotten password URL';
|
||||
$string['getanaudiocaptcha'] = 'Get an audio CAPTCHA';
|
||||
$string['getanimagecaptcha'] = 'Get an image CAPTCHA';
|
||||
$string['getanothercaptcha'] = 'Get another CAPTCHA';
|
||||
$string['getrecaptchaapi'] = 'To use reCAPTCHA you must get an API key from <a href=\'https://www.google.com/recaptcha/admin\'>https://www.google.com/recaptcha/admin</a>';
|
||||
$string['guestloginbutton'] = 'Guest login button';
|
||||
$string['changepassword'] = 'Change password URL';
|
||||
$string['changepasswordhelp'] = 'URL of lost password recovery page, which will be sent to users in an email. Note that this setting will have no effect if a forgotten password URL is set in the authentication common settings.';
|
||||
@@ -133,9 +134,9 @@ $string['pluginnotenabled'] = 'Authentication plugin \'{$a}\' is not enabled.';
|
||||
$string['pluginnotinstalled'] = 'Authentication plugin \'{$a}\' is not installed.';
|
||||
$string['potentialidps'] = 'Log in using your account on:';
|
||||
$string['recaptcha'] = 'reCAPTCHA';
|
||||
$string['recaptcha_help'] = 'The CAPTCHA is for preventing abuse from automated programs. Simply enter the words in the box, in order and separated by a space.
|
||||
$string['recaptcha_help'] = 'The CAPTCHA is for preventing abuse from automated programs. Follow the instructions to verify you are a person. This could be a box to check, characters presented in an image you must enter or a set of images to select from.
|
||||
|
||||
If you are not sure what the words are, you can try getting another CAPTCHA or an audio CAPTCHA.';
|
||||
If you are not sure what the images are, you can try getting another CAPTCHA or an audio CAPTCHA.';
|
||||
$string['recaptcha_link'] = 'auth/email';
|
||||
$string['security_question'] = 'Security question';
|
||||
$string['selfregistration'] = 'Self registration';
|
||||
|
||||
@@ -448,6 +448,8 @@ $string['notlocalisederrormessage'] = '{$a}';
|
||||
$string['notmemberofgroup'] = 'You are not a member of this course group';
|
||||
$string['notownerofkey'] = 'You are not owner of this key';
|
||||
$string['nousers'] = 'No such user!';
|
||||
$string['oauth1accesstoken'] = 'OAuth 1.0 error: We did not obtain the access token.';
|
||||
$string['oauth1requesttoken'] = 'OAuth 1.0 error: We did not obtain the request token - the service provider may be temporarily down.';
|
||||
$string['onlyadmins'] = 'Only administrators can do that';
|
||||
$string['onlyeditingteachers'] = 'Only editing teachers can do that';
|
||||
$string['onlyeditown'] = 'You can only edit your own information';
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ $string['duplicate_usernames'] = 'We failed to create an index on the columns "m
|
||||
$string['enabled_for_all'] = '(This service has been enabled for all hosts).';
|
||||
$string['enterausername'] = 'Please enter a username, or a list of usernames separated by commas.';
|
||||
$string['error7020'] = 'This error normally occurs if the remote site has created a record for you with the wrong wwwroot, for example, http://yoursite.com instead of http://www.yoursite.com. You should contact the administrator of the remote site with your wwwroot (as specified in config.php) asking her to update her record for your host.';
|
||||
$string['error7022'] = 'The message you sent to the remote site was encrypted properly, but not signed. This is very unexpected; you should probably file a bug if this occurs (giving as much information as possible about the application versions in question, etc.';
|
||||
$string['error7022'] = 'The message you sent to the remote site was encrypted properly, but not signed. This is very unexpected; you should probably file a bug if this occurs (giving as much information as possible about the application versions in question etc).';
|
||||
$string['error7023'] = 'The remote site has tried to decrypt your message with all the keys it has on record for your site. They have all failed. You might be able to fix this problem by manually re-keying with the remote site. This is unlikely to occur unless you\'ve been out of communication with the remote site for a few months.';
|
||||
$string['error7024'] = 'You send an unencrypted message to the remote site, but the remote site doesn\'t accept unencrypted communication from your site. This is very unexpected; you should probably file a bug if this occurs (giving as much information as possible about the application versions in question, etc.';
|
||||
$string['error7026'] = 'The key that your message was signed with differs from the key that the remote host has on file for your server. Further, the remote host attempted to fetch your current key and failed to do so. Please manually re-key with the remote host and try again.';
|
||||
|
||||
+5
-3
@@ -614,6 +614,8 @@ $string['emaildisplayyes'] = 'Allow everyone to see my email address';
|
||||
$string['emailenable'] = 'This email address is enabled';
|
||||
$string['emailenableclick'] = 'Click here to re-enable all email being sent to this address';
|
||||
$string['emailexists'] = 'This email address is already registered.';
|
||||
$string['emailexistssignuphint'] = 'Perhaps you created an account in the past? {$a}';
|
||||
$string['emailexistshintlink'] = 'Recover forgotten username or password';
|
||||
$string['emailformat'] = 'Email format';
|
||||
$string['emailcharset'] = 'Email charset';
|
||||
$string['emailmustbereal'] = 'Note: your email address must be a real one';
|
||||
@@ -705,7 +707,7 @@ $string['emptydragdropregion'] = 'empty region';
|
||||
$string['enable'] = 'Enable';
|
||||
$string['encryptedcode'] = 'Encrypted code';
|
||||
$string['enddate'] = 'Course end date';
|
||||
$string['enddate_help'] = 'The course end date is only used for reports. Users can still enter the course after the end date.';
|
||||
$string['enddate_help'] = 'The course end date is used for determining whether a course should be included in a user\'s list of courses in the navigation. When the end date is past, the course is no longer listed. The course end date may also be used by custom reports. Users can still enter the course after the end date; in other words the date does not restrict access.';
|
||||
$string['english'] = 'English';
|
||||
$string['enrolmentmethods'] = 'Enrolment methods';
|
||||
$string['entercourse'] = 'Click to enter this course';
|
||||
@@ -970,7 +972,7 @@ $string['choosereportfilter'] = 'Choose a filter for the report';
|
||||
$string['choosetheme'] = 'Choose theme';
|
||||
$string['chooseuser'] = 'Choose a user';
|
||||
$string['courseduration'] = 'Course duration';
|
||||
$string['courseduration_desc'] = 'The course duration is used to calculate the default course end date. The course end date is only used for reports. Users can still enter the course after the end date.';
|
||||
$string['courseduration_desc'] = 'The course duration is used to calculate the default course end date. The course end date is used for determining whether a course should be included in a user\'s list of courses. It may also be used by custom reports. Users can still enter the course after the end date.';
|
||||
$string['eventcontentviewed'] = 'Content viewed';
|
||||
$string['icqnumber'] = 'ICQ number';
|
||||
$string['icon'] = 'Icon';
|
||||
@@ -1156,7 +1158,7 @@ $string['missinglastname'] = 'Missing surname';
|
||||
$string['missingname'] = 'Missing name';
|
||||
$string['missingnewpassword'] = 'Missing new password';
|
||||
$string['missingpassword'] = 'Missing password';
|
||||
$string['missingrecaptchachallengefield'] = 'Missing reCAPTCHA challenge field';
|
||||
$string['missingrecaptchachallengefield'] = 'Failed reCAPTCHA challenge, try again.';
|
||||
$string['missingreqreason'] = 'Missing reason';
|
||||
$string['missingshortname'] = 'Missing short name';
|
||||
$string['missingshortsitename'] = 'Missing short site name';
|
||||
|
||||
@@ -164,6 +164,7 @@ $string['manage'] = 'Manage repositories';
|
||||
$string['manageinstances'] = 'Manage instances';
|
||||
$string['manageurl'] = 'Manage';
|
||||
$string['manageuserrepository'] = 'Manage individual repository';
|
||||
$string['missingsourcekey'] = 'The source key is missing. This key must also be provided to retrieve the file.';
|
||||
$string['moving'] = 'Moving';
|
||||
$string['name'] = 'Name';
|
||||
$string['newfolder'] = 'New folder';
|
||||
@@ -220,6 +221,7 @@ $string['setmainfile'] = 'Set main file';
|
||||
$string['setmainfile_help'] = 'If there are multiple files in the folder, the main file is the one that appears on the view page. Other files such as images or videos may be embedded in it. In filemanager the main file is indicated with a title in bold.';
|
||||
$string['siteinstances'] = 'Repositories instances of the site';
|
||||
$string['size'] = 'Size';
|
||||
$string['sourcekeymismatch'] = 'The source url does not match the sourcekey.';
|
||||
$string['submit'] = 'Submit';
|
||||
$string['sync'] = 'Sync';
|
||||
$string['syncfiletimeout'] = 'Sync file timeout';
|
||||
|
||||
+1
-1
@@ -349,7 +349,7 @@ $string['restore:restoretargetimport'] = 'Restore from files targeted as import'
|
||||
$string['restore:rolldates'] = 'Allowed to roll activity configuration dates on restore';
|
||||
$string['restore:uploadfile'] = 'Upload files to backup areas';
|
||||
$string['restore:userinfo'] = 'Restore user data';
|
||||
$string['restore:viewautomatedfilearea'] = 'View automated backup area';
|
||||
$string['restore:viewautomatedfilearea'] = 'Restore courses from automated backups';
|
||||
$string['risks'] = 'Risks';
|
||||
$string['roleallowheader'] = 'Allow role:';
|
||||
$string['roleallowinfo'] = 'Select a role to be added to the list of allowed roles in context "{$a->context}", capability "{$a->cap}":';
|
||||
|
||||
+25
-12
@@ -2743,20 +2743,28 @@ function get_component_string($component, $contextlevel) {
|
||||
|
||||
/**
|
||||
* Gets the list of roles assigned to this context and up (parents)
|
||||
* from the list of roles that are visible on user profile page
|
||||
* and participants page.
|
||||
* from the aggregation of:
|
||||
* a) the list of roles that are visible on user profile page and participants page (profileroles setting) and;
|
||||
* b) if applicable, those roles that are assigned in the context.
|
||||
*
|
||||
* @param context $context
|
||||
* @return array
|
||||
*/
|
||||
function get_profile_roles(context $context) {
|
||||
global $CFG, $DB;
|
||||
|
||||
if (empty($CFG->profileroles)) {
|
||||
return array();
|
||||
// If the current user can assign roles, then they can see all roles on the profile and participants page,
|
||||
// provided the roles are assigned to at least 1 user in the context. If not, only the policy-defined roles.
|
||||
if (has_capability('moodle/role:assign', $context)) {
|
||||
$rolesinscope = array_keys(get_all_roles($context));
|
||||
} else {
|
||||
$rolesinscope = empty($CFG->profileroles) ? [] : array_map('trim', explode(',', $CFG->profileroles));
|
||||
}
|
||||
|
||||
list($rallowed, $params) = $DB->get_in_or_equal(explode(',', $CFG->profileroles), SQL_PARAMS_NAMED, 'a');
|
||||
if (empty($rolesinscope)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
list($rallowed, $params) = $DB->get_in_or_equal($rolesinscope, SQL_PARAMS_NAMED, 'a');
|
||||
list($contextlist, $cparams) = $DB->get_in_or_equal($context->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'p');
|
||||
$params = array_merge($params, $cparams);
|
||||
|
||||
@@ -2815,18 +2823,23 @@ function get_roles_used_in_context(context $context) {
|
||||
*/
|
||||
function get_user_roles_in_course($userid, $courseid) {
|
||||
global $CFG, $DB;
|
||||
|
||||
if (empty($CFG->profileroles)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($courseid == SITEID) {
|
||||
$context = context_system::instance();
|
||||
} else {
|
||||
$context = context_course::instance($courseid);
|
||||
}
|
||||
// If the current user can assign roles, then they can see all roles on the profile and participants page,
|
||||
// provided the roles are assigned to at least 1 user in the context. If not, only the policy-defined roles.
|
||||
if (has_capability('moodle/role:assign', $context)) {
|
||||
$rolesinscope = array_keys(get_all_roles($context));
|
||||
} else {
|
||||
$rolesinscope = empty($CFG->profileroles) ? [] : array_map('trim', explode(',', $CFG->profileroles));
|
||||
}
|
||||
if (empty($rolesinscope)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
list($rallowed, $params) = $DB->get_in_or_equal(explode(',', $CFG->profileroles), SQL_PARAMS_NAMED, 'a');
|
||||
list($rallowed, $params) = $DB->get_in_or_equal($rolesinscope, SQL_PARAMS_NAMED, 'a');
|
||||
list($contextlist, $cparams) = $DB->get_in_or_equal($context->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'p');
|
||||
$params = array_merge($params, $cparams);
|
||||
|
||||
|
||||
+6
-16
@@ -3645,16 +3645,11 @@ class admin_setting_configmixedhostiplist extends admin_setting_configtextarea {
|
||||
$entries = explode("\n", $data);
|
||||
foreach ($entries as $key => $entry) {
|
||||
$entry = trim($entry);
|
||||
// This regex matches any string which:
|
||||
// a) contains at least one non-ascii unicode character AND
|
||||
// b) starts with a-zA-Z0-9 or any non-ascii unicode character AND
|
||||
// c) ends with a-zA-Z0-9 or any non-ascii unicode character
|
||||
// d) contains a-zA-Z0-9, hyphen, dot or any non-ascii unicode characters in the middle.
|
||||
if (preg_match('/^(?=[^\x00-\x7f])([^\x00-\x7f]|[a-zA-Z0-9])([^\x00-\x7f]|[a-zA-Z0-9-.])*([^\x00-\x7f]|[a-zA-Z0-9])$/',
|
||||
$entry)) {
|
||||
// This regex matches any string that has non-ascii character.
|
||||
if (preg_match('/[^\x00-\x7f]/', $entry)) {
|
||||
// If we can convert the unicode string to an idn, do so.
|
||||
// Otherwise, leave the original unicode string alone and let the validation function handle it (it will fail).
|
||||
$val = idn_to_ascii($entry);
|
||||
$val = idn_to_ascii($entry, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
|
||||
$entries[$key] = $val ? $val : $entry;
|
||||
}
|
||||
}
|
||||
@@ -3672,7 +3667,7 @@ class admin_setting_configmixedhostiplist extends admin_setting_configtextarea {
|
||||
foreach ($entries as $key => $entry) {
|
||||
$entry = trim($entry);
|
||||
if (strpos($entry, 'xn--') !== false) {
|
||||
$entries[$key] = idn_to_utf8($entry);
|
||||
$entries[$key] = idn_to_utf8($entry, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
|
||||
}
|
||||
}
|
||||
return implode("\n", $entries);
|
||||
@@ -8445,16 +8440,11 @@ class admin_setting_enablemobileservice extends admin_setting_configcheckbox {
|
||||
* @return string XHTML
|
||||
*/
|
||||
public function output_html($data, $query='') {
|
||||
global $CFG, $OUTPUT;
|
||||
global $OUTPUT;
|
||||
$html = parent::output_html($data, $query);
|
||||
|
||||
if ((string)$data === $this->yes) {
|
||||
require_once($CFG->dirroot . "/lib/filelib.php");
|
||||
$curl = new curl();
|
||||
$httpswwwroot = str_replace('http:', 'https:', $CFG->wwwroot); //force https url
|
||||
$curl->head($httpswwwroot . "/login/index.php");
|
||||
$info = $curl->get_info();
|
||||
if (empty($info['http_code']) or ($info['http_code'] >= 400)) {
|
||||
if (!is_https()) {
|
||||
$html .= $OUTPUT->notification(get_string('nohttpsformobilewarning', 'admin'));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
define(["jquery","core/ajax","core/templates","core/notification","core/str","core/config","core/url"],function(a,b,c,d,e,f,g){return a("body").on("click keypress","[data-inplaceeditable] [data-inplaceeditablelink]",function(h){if("keypress"!==h.type||13===h.keyCode){h.stopImmediatePropagation(),h.preventDefault();var i=a(this),j=i.closest("[data-inplaceeditable]"),k=function(b){b.addClass("updating");var c=b.find("img.spinner");c.length?c.show():(c=a("<img/>").attr("src",g.imageUrl("i/loading_small")).addClass("spinner").addClass("smallicon"),b.append(c))},l=function(a){a.removeClass("updating"),a.find("img.spinner").hide()},m=function(e,f){k(e),b.call([{methodname:"core_update_inplace_editable",args:{itemid:e.attr("data-itemid"),component:e.attr("data-component"),itemtype:e.attr("data-itemtype"),value:f},done:function(b){var d=e.attr("data-value");c.render("core/inplace_editable",b).done(function(f,g){var h=a(f);c.replaceNode(e,h,g),h.find("[data-inplaceeditablelink]").focus(),h.trigger({type:"updated",ajaxreturn:b,oldvalue:d})})},fail:function(b){var c=a.Event("updatefailed",{exception:b,newvalue:f});l(e),e.trigger(c),c.isDefaultPrevented()||d.exception(b)}}],!0)},n=function(a){a.find("input").off(),a.find("select").off(),a.html(a.attr("data-oldcontent")),a.removeAttr("data-oldcontent"),a.removeClass("inplaceeditingon"),a.find("[data-inplaceeditablelink]").focus()},o=function(){a("span.inplaceeditable.inplaceeditingon").each(function(){n(a(this))})},p=function(b,c){var d,e=b;for(d=0;d<c;d++)e+=String(Math.floor(10*Math.random()));return 0===a("#"+e).length?e:p(b,c)},q=function(b){e.get_string("edittitleinstructions").done(function(c){var d=a('<span class="editinstructions">'+c+"</span>").attr("id",p("id_editinstructions_",20)),e=a('<input type="text"/>').attr("id",p("id_inplacevalue_",20)).attr("value",b.attr("data-value")).attr("aria-describedby",d.attr("id")).addClass("ignoredirty").addClass("form-control"),g=a('<label class="accesshide">'+j.attr("data-editlabel")+"</label>").attr("for",e.attr("id"));b.html("").append(d).append(g).append(e),e.focus(),e.select(),e.on("keyup keypress focusout",function(a){if(!f.behatsiterunning||"focusout"!==a.type){if("keypress"===a.type&&13===a.keyCode){var c=e.val();n(b),m(b,c)}("keyup"===a.type&&27===a.keyCode||"focusout"===a.type)&&n(b)}})})},r=function(a,b){n(a),m(a,b)},s=function(b,c){var d,e=a("<select></select>").attr("id",p("id_inplacevalue_",20)).addClass("custom-select"),g=a('<label class="accesshide">'+j.attr("data-editlabel")+"</label>").attr("for",e.attr("id"));for(d in c)e.append(a("<option>").attr("value",c[d].key).html(c[d].value));e.val(b.attr("data-value")),b.html("").append(g).append(e),e.focus(),e.select(),e.on("keyup change focusout",function(a){if(!f.behatsiterunning||"focusout"!==a.type){if("change"===a.type){var c=e.val();n(b),m(b,c)}("keyup"===a.type&&27===a.keyCode||"focusout"===a.type)&&n(b)}})},t=function(b){b.addClass("inplaceeditingon"),b.attr("data-oldcontent",b.html());var c=b.attr("data-type"),d=b.attr("data-options");"toggle"===c?r(b,d):"select"===c?s(b,a.parseJSON(d)):q(b)};o(),t(j)}}),{}});
|
||||
define(["jquery","core/ajax","core/templates","core/notification","core/str","core/config","core/url"],function(a,b,c,d,e,f,g){return a("body").on("click keypress","[data-inplaceeditable] [data-inplaceeditablelink]",function(h){if("keypress"!==h.type||13===h.keyCode){h.stopImmediatePropagation(),h.preventDefault();var i=a(this),j=i.closest("[data-inplaceeditable]"),k=function(b){b.addClass("updating");var c=b.find("img.spinner");c.length?c.show():(c=a("<img/>").attr("src",g.imageUrl("i/loading_small")).addClass("spinner").addClass("smallicon"),b.append(c))},l=function(a){a.removeClass("updating"),a.find("img.spinner").hide()},m=function(e,f){var g=[e.attr("data-itemid"),e.attr("data-component"),e.attr("data-itemtype")].join("-");M.util.js_pending(g),k(e),b.call([{methodname:"core_update_inplace_editable",args:{itemid:e.attr("data-itemid"),component:e.attr("data-component"),itemtype:e.attr("data-itemtype"),value:f},done:function(b){var d=e.attr("data-value");c.render("core/inplace_editable",b).done(function(f,h){var i=a(f);c.replaceNode(e,i,h),i.find("[data-inplaceeditablelink]").focus(),i.trigger({type:"updated",ajaxreturn:b,oldvalue:d}),M.util.js_complete(g)})},fail:function(b){var c=a.Event("updatefailed",{exception:b,newvalue:f});l(e),M.util.js_complete(g),e.trigger(c),c.isDefaultPrevented()||d.exception(b)}}],!0)},n=function(a){a.find("input").off(),a.find("select").off(),a.html(a.attr("data-oldcontent")),a.removeAttr("data-oldcontent"),a.removeClass("inplaceeditingon"),a.find("[data-inplaceeditablelink]").focus()},o=function(){a("span.inplaceeditable.inplaceeditingon").each(function(){n(a(this))})},p=function(b,c){var d,e=b;for(d=0;d<c;d++)e+=String(Math.floor(10*Math.random()));return 0===a("#"+e).length?e:p(b,c)},q=function(b){e.get_string("edittitleinstructions").done(function(c){var d=a('<span class="editinstructions">'+c+"</span>").attr("id",p("id_editinstructions_",20)),e=a('<input type="text"/>').attr("id",p("id_inplacevalue_",20)).attr("value",b.attr("data-value")).attr("aria-describedby",d.attr("id")).addClass("ignoredirty").addClass("form-control"),g=a('<label class="accesshide">'+j.attr("data-editlabel")+"</label>").attr("for",e.attr("id"));b.html("").append(d).append(g).append(e),e.focus(),e.select(),e.on("keyup keypress focusout",function(a){if(!f.behatsiterunning||"focusout"!==a.type){if("keypress"===a.type&&13===a.keyCode){var c=e.val();n(b),m(b,c)}("keyup"===a.type&&27===a.keyCode||"focusout"===a.type)&&n(b)}})})},r=function(a,b){n(a),m(a,b)},s=function(b,c){var d,e=a("<select></select>").attr("id",p("id_inplacevalue_",20)).addClass("custom-select"),g=a('<label class="accesshide">'+j.attr("data-editlabel")+"</label>").attr("for",e.attr("id"));for(d in c)e.append(a("<option>").attr("value",c[d].key).html(c[d].value));e.val(b.attr("data-value")),b.html("").append(g).append(e),e.focus(),e.select(),e.on("keyup change focusout",function(a){if(!f.behatsiterunning||"focusout"!==a.type){if("change"===a.type){var c=e.val();n(b),m(b,c)}("keyup"===a.type&&27===a.keyCode||"focusout"===a.type)&&n(b)}})},t=function(b){b.addClass("inplaceeditingon"),b.attr("data-oldcontent",b.html());var c=b.attr("data-type"),d=b.attr("data-options");"toggle"===c?r(b,d):"select"===c?s(b,a.parseJSON(d)):q(b)};o(),t(j)}}),{}});
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
||||
define(["jquery","core/modal_events","core/modal","core/modal_save_cancel","core/modal_confirm","core/modal_cancel","core/templates","core/notification","core/custom_interaction_events"],function(a,b,c,d,e,f,g,h,i){var j={DEFAULT:"core/modal",SAVE_CANCEL:"core/modal_save_cancel",CONFIRM:"core/modal_confirm",CANCEL:"core/modal_cancel"},k={DEFAULT:c,SAVE_CANCEL:d,CONFIRM:e,CANCEL:f},l={DEFAULT:"DEFAULT",SAVE_CANCEL:"SAVE_CANCEL",CONFIRM:"CONFIRM",CANCEL:"CANCEL"},m=function(a,c){"undefined"!=typeof c&&(i.define(c,[i.events.activate]),c.on(i.events.activate,function(b,c){a.then(function(a){return a.show(),a}),c.originalEvent.preventDefault()}),a.then(function(a){return a.getRoot().on(b.hidden,function(){c.focus()}),a}))},n=function(b,c){c=a(c);var d=k[b],e=new d(c);return e},o=function(b,c){var d=j[b],e=g.render(d,{}).then(function(c){var d=a(c);return n(b,d)}).fail(h.exception);return m(e,c),e},p=function(a,b){var c=a.type||l.DEFAULT,d=!!a.large;return l[c]||(c=l.DEFAULT),o(c,b).then(function(b){return"undefined"!=typeof a.title&&b.setTitle(a.title),"undefined"!=typeof a.body&&b.setBody(a.body),"undefined"!=typeof a.footer&&b.setFooter(a.footer),d&&b.setLarge(),b})};return{create:p,types:l}});
|
||||
define(["jquery","core/modal_events","core/modal","core/modal_save_cancel","core/modal_confirm","core/modal_cancel","core/templates","core/notification","core/custom_interaction_events"],function(a,b,c,d,e,f,g,h,i){var j={DEFAULT:"core/modal",SAVE_CANCEL:"core/modal_save_cancel",CONFIRM:"core/modal_confirm",CANCEL:"core/modal_cancel"},k={DEFAULT:c,SAVE_CANCEL:d,CONFIRM:e,CANCEL:f},l={DEFAULT:"DEFAULT",SAVE_CANCEL:"SAVE_CANCEL",CONFIRM:"CONFIRM",CANCEL:"CANCEL"},m=function(a,c){if("undefined"!=typeof c){var d=null;i.define(c,[i.events.activate]),c.on(i.events.activate,function(b,c){d=b.currentTarget,a.then(function(a){return a.show(),a}),c.originalEvent.preventDefault()}),a.then(function(a){return a.getRoot().on(b.hidden,function(){null!==d&&d.focus()}),a})}},n=function(b,c){c=a(c);var d=k[b],e=new d(c);return e},o=function(b,c){var d=j[b],e=g.render(d,{}).then(function(c){var d=a(c);return n(b,d)}).fail(h.exception);return m(e,c),e},p=function(a,b){var c=a.type||l.DEFAULT,d=!!a.large;return l[c]||(c=l.DEFAULT),o(c,b).then(function(b){return"undefined"!=typeof a.title&&b.setTitle(a.title),"undefined"!=typeof a.body&&b.setBody(a.body),"undefined"!=typeof a.footer&&b.setFooter(a.footer),d&&b.setLarge(),b})};return{create:p,types:l}});
|
||||
@@ -37,6 +37,8 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
|
||||
UP: 38
|
||||
};
|
||||
|
||||
var uniqueId = $.now();
|
||||
|
||||
/**
|
||||
* Make an item in the selection list "active".
|
||||
*
|
||||
@@ -774,11 +776,15 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
|
||||
// Find or generate some ids.
|
||||
var state = {
|
||||
selectId: originalSelect.attr('id'),
|
||||
inputId: 'form_autocomplete_input-' + $.now(),
|
||||
suggestionsId: 'form_autocomplete_suggestions-' + $.now(),
|
||||
selectionId: 'form_autocomplete_selection-' + $.now(),
|
||||
downArrowId: 'form_autocomplete_downarrow-' + $.now()
|
||||
inputId: 'form_autocomplete_input-' + uniqueId,
|
||||
suggestionsId: 'form_autocomplete_suggestions-' + uniqueId,
|
||||
selectionId: 'form_autocomplete_selection-' + uniqueId,
|
||||
downArrowId: 'form_autocomplete_downarrow-' + uniqueId
|
||||
};
|
||||
|
||||
// Increment the unique counter so we don't get duplicates ever.
|
||||
uniqueId++;
|
||||
|
||||
options.multiple = originalSelect.attr('multiple');
|
||||
|
||||
var originalLabel = $('[for=' + state.selectId + ']');
|
||||
|
||||
@@ -60,6 +60,13 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
|
||||
};
|
||||
|
||||
var updateValue = function(mainelement, value) {
|
||||
var pendingId = [
|
||||
mainelement.attr('data-itemid'),
|
||||
mainelement.attr('data-component'),
|
||||
mainelement.attr('data-itemtype'),
|
||||
].join('-');
|
||||
M.util.js_pending(pendingId);
|
||||
|
||||
addSpinner(mainelement);
|
||||
ajax
|
||||
.call([{
|
||||
@@ -77,6 +84,7 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
|
||||
templates.replaceNode(mainelement, newelement, js);
|
||||
newelement.find('[data-inplaceeditablelink]').focus();
|
||||
newelement.trigger({type: 'updated', ajaxreturn: data, oldvalue: oldvalue});
|
||||
M.util.js_complete(pendingId);
|
||||
});
|
||||
},
|
||||
fail: function(ex) {
|
||||
@@ -85,6 +93,7 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
|
||||
newvalue: value
|
||||
});
|
||||
removeSpinner(mainelement);
|
||||
M.util.js_complete(pendingId);
|
||||
mainelement.trigger(e);
|
||||
if (!e.isDefaultPrevented()) {
|
||||
notification.exception(ex);
|
||||
|
||||
+105
-17
@@ -50,6 +50,12 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes',
|
||||
*/
|
||||
var backdropPromise;
|
||||
|
||||
/**
|
||||
* A counter that gets incremented for each modal created. This can be
|
||||
* used to generate unique values for the modals.
|
||||
*/
|
||||
var modalCounter = 0;
|
||||
|
||||
/**
|
||||
* Constructor for the Modal.
|
||||
*
|
||||
@@ -66,6 +72,7 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes',
|
||||
this.isAttached = false;
|
||||
this.bodyJS = null;
|
||||
this.footerJS = null;
|
||||
this.modalCount = modalCounter++;
|
||||
|
||||
if (!this.root.is(SELECTORS.CONTAINER)) {
|
||||
Notification.exception({message: 'Element is not a modal container'});
|
||||
@@ -212,6 +219,16 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes',
|
||||
return this.footer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the unique modal count.
|
||||
*
|
||||
* @method getModalCount
|
||||
* @return {int}
|
||||
*/
|
||||
Modal.prototype.getModalCount = function() {
|
||||
return this.modalCount;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the modal title element.
|
||||
*
|
||||
@@ -249,25 +266,96 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes',
|
||||
// Just set the value if it's a string.
|
||||
body.html(value);
|
||||
} else {
|
||||
var jsPendingId = 'amd-modal-js-pending-id-' + this.getModalCount();
|
||||
M.util.js_pending(jsPendingId);
|
||||
// Otherwise we assume it's a promise to be resolved with
|
||||
// html and javascript.
|
||||
Templates.render(TEMPLATES.LOADING, {}).done(function(html) {
|
||||
body.html(html);
|
||||
var contentPromise = null;
|
||||
body.css('overflow', 'hidden');
|
||||
|
||||
value.done(function(html, js) {
|
||||
if (value.state() == 'pending') {
|
||||
// We're still waiting for the body promise to resolve so
|
||||
// let's show a loading icon.
|
||||
body.animate({height: '100px'}, 150);
|
||||
|
||||
body.html('');
|
||||
contentPromise = Templates.render(TEMPLATES.LOADING, {})
|
||||
.then(function(html) {
|
||||
var loadingIcon = $(html).hide();
|
||||
body.html(loadingIcon);
|
||||
loadingIcon.fadeIn(150);
|
||||
|
||||
// We only want the loading icon to fade out
|
||||
// when the content for the body has finished
|
||||
// loading.
|
||||
return $.when(loadingIcon.promise(), value);
|
||||
})
|
||||
.then(function(loadingIcon) {
|
||||
// Once the content has finished loading and
|
||||
// the loading icon has been shown then we can
|
||||
// fade the icon away to reveal the content.
|
||||
return loadingIcon.fadeOut(100).promise();
|
||||
})
|
||||
.then(function() {
|
||||
return value;
|
||||
});
|
||||
} else {
|
||||
// The content is already loaded so let's just display
|
||||
// it to the user. No need for a loading icon.
|
||||
contentPromise = value;
|
||||
}
|
||||
|
||||
// Now we can actually display the content.
|
||||
contentPromise.then(function(html, js) {
|
||||
var result = null;
|
||||
|
||||
if (this.isVisible()) {
|
||||
// If the modal is visible then we should display
|
||||
// the content gracefully for the user.
|
||||
body.css('opacity', 0);
|
||||
var currentHeight = body.innerHeight();
|
||||
body.html(html);
|
||||
// We need to clear any height values we've set here
|
||||
// in order to measure the height of the content being
|
||||
// added. This then allows us to animate the height
|
||||
// transition.
|
||||
body.css('height', '');
|
||||
var newHeight = body.innerHeight();
|
||||
body.css('height', currentHeight + 'px');
|
||||
result = body.animate(
|
||||
{height: newHeight + 'px', opacity: 1},
|
||||
{duration: 150, queue: false}
|
||||
).promise();
|
||||
} else {
|
||||
// Since the modal isn't visible we can just immediately
|
||||
// set the content. No need to animate it.
|
||||
body.html(html);
|
||||
}
|
||||
|
||||
if (js) {
|
||||
if (this.isAttached) {
|
||||
// If we're in the DOM then run the JS immediately.
|
||||
Templates.runTemplateJS(js);
|
||||
} else {
|
||||
// Otherwise cache it to be run when we're attached.
|
||||
this.bodyJS = js;
|
||||
}
|
||||
if (js) {
|
||||
if (this.isAttached) {
|
||||
// If we're in the DOM then run the JS immediately.
|
||||
Templates.runTemplateJS(js);
|
||||
} else {
|
||||
// Otherwise cache it to be run when we're attached.
|
||||
this.bodyJS = js;
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
return result;
|
||||
}.bind(this))
|
||||
.fail(Notification.exception)
|
||||
.always(function() {
|
||||
// When we're done displaying all of the content we need
|
||||
// to clear the custom values we've set here.
|
||||
body.css('height', '');
|
||||
body.css('overflow', '');
|
||||
body.css('opacity', '');
|
||||
M.util.js_complete(jsPendingId);
|
||||
|
||||
return;
|
||||
})
|
||||
.fail(Notification.exception);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -320,7 +408,7 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes',
|
||||
return;
|
||||
}
|
||||
|
||||
this.getRoot().addClass('large');
|
||||
this.getModal().addClass('modal-lg');
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -330,7 +418,7 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes',
|
||||
* @return {bool}
|
||||
*/
|
||||
Modal.prototype.isLarge = function() {
|
||||
return this.getRoot().hasClass('large');
|
||||
return this.getModal().hasClass('modal-lg');
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -343,7 +431,7 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes',
|
||||
return;
|
||||
}
|
||||
|
||||
this.getRoot().removeClass('large');
|
||||
this.getModal().removeClass('modal-lg');
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -353,7 +441,7 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes',
|
||||
* @return {bool}
|
||||
*/
|
||||
Modal.prototype.isSmall = function() {
|
||||
return !this.getRoot().hasClass('large');
|
||||
return !this.getModal().hasClass('modal-lg');
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,8 +60,11 @@ define(['jquery', 'core/modal_events', 'core/modal', 'core/modal_save_cancel', '
|
||||
*/
|
||||
var setUpTrigger = function(modalPromise, triggerElement) {
|
||||
if (typeof triggerElement != 'undefined') {
|
||||
// The element that actually shows the modal.
|
||||
var actualTriggerElement = null;
|
||||
CustomEvents.define(triggerElement, [CustomEvents.events.activate]);
|
||||
triggerElement.on(CustomEvents.events.activate, function(e, data) {
|
||||
actualTriggerElement = e.currentTarget;
|
||||
modalPromise.then(function(modal) {
|
||||
modal.show();
|
||||
|
||||
@@ -72,7 +75,10 @@ define(['jquery', 'core/modal_events', 'core/modal', 'core/modal_save_cancel', '
|
||||
|
||||
modalPromise.then(function(modal) {
|
||||
modal.getRoot().on(ModalEvents.hidden, function() {
|
||||
triggerElement.focus();
|
||||
// Focus on the trigger element that actually launched the modal.
|
||||
if (actualTriggerElement !== null) {
|
||||
actualTriggerElement.focus();
|
||||
}
|
||||
});
|
||||
|
||||
return modal;
|
||||
|
||||
+3
-1
@@ -845,7 +845,9 @@ function signup_validate_data($data, $files) {
|
||||
$errors['email'] = get_string('invalidemail');
|
||||
|
||||
} else if ($DB->record_exists('user', array('email' => $data['email']))) {
|
||||
$errors['email'] = get_string('emailexists').' <a href="forgot_password.php">'.get_string('newpassword').'?</a>';
|
||||
$errors['email'] = get_string('emailexists') . ' ' .
|
||||
get_string('emailexistssignuphint', 'moodle',
|
||||
html_writer::link(new moodle_url('/login/forgot_password.php'), get_string('emailexistshintlink')));
|
||||
}
|
||||
if (empty($data['email2'])) {
|
||||
$errors['email2'] = get_string('missingemail');
|
||||
|
||||
@@ -1183,6 +1183,12 @@ function badges_download($userid) {
|
||||
* @return string Code of backpack accessibility status.
|
||||
*/
|
||||
function badges_check_backpack_accessibility() {
|
||||
if (defined('BEHAT_SITE_RUNNING') && BEHAT_SITE_RUNNING) {
|
||||
// For behat sites, do not poll the remote badge site.
|
||||
// Behat sites should not be available, but we should pretend as though they are.
|
||||
return 'available';
|
||||
}
|
||||
|
||||
global $CFG;
|
||||
include_once $CFG->libdir . '/filelib.php';
|
||||
|
||||
|
||||
@@ -128,6 +128,8 @@ XPATH
|
||||
]) = %locator%] |
|
||||
.//div[contains(concat(' ', normalize-space(@class), ' '), ' yui-dialog ') and
|
||||
normalize-space(descendant::div[@class='hd']) = %locator%]
|
||||
|
|
||||
.//div[@data-region='modal' and descendant::*[@data-region='title'] = %locator%]
|
||||
XPATH
|
||||
, 'list_item' => <<<XPATH
|
||||
.//li[contains(normalize-space(.), %locator%) and not(.//li[contains(normalize-space(.), %locator%)])]
|
||||
|
||||
+17
-12
@@ -689,7 +689,7 @@ class block_manager {
|
||||
if ($includeinvisible) {
|
||||
$visiblecheck = '';
|
||||
} else {
|
||||
$visiblecheck = 'AND (bp.visible = 1 OR bp.visible IS NULL)';
|
||||
$visiblecheck = 'AND (bp.visible = 1 OR bp.visible IS NULL) AND (bs.visible = 1 OR bs.visible IS NULL)';
|
||||
}
|
||||
|
||||
$context = $this->page->context;
|
||||
@@ -710,24 +710,26 @@ class block_manager {
|
||||
$ccjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = bi.id AND ctx.contextlevel = :contextlevel)";
|
||||
|
||||
$systemcontext = context_system::instance();
|
||||
list($bpcontext, $bpcontextidparams) = $DB->get_in_or_equal(array($context->id, $systemcontext->id),
|
||||
SQL_PARAMS_NAMED, 'bpcontextid');
|
||||
$params = array(
|
||||
'contextlevel' => CONTEXT_BLOCK,
|
||||
'subpage1' => $this->page->subpage,
|
||||
'subpage2' => $this->page->subpage,
|
||||
'subpage3' => $this->page->subpage,
|
||||
'contextid1' => $context->id,
|
||||
'contextid2' => $context->id,
|
||||
'contextid3' => $systemcontext->id,
|
||||
'contextid4' => $systemcontext->id,
|
||||
'pagetype' => $this->page->pagetype,
|
||||
'pagetype2' => $this->page->pagetype,
|
||||
);
|
||||
if ($this->page->subpage === '') {
|
||||
$params['subpage1'] = '';
|
||||
$params['subpage2'] = '';
|
||||
$params['subpage3'] = '';
|
||||
}
|
||||
$sql = "SELECT
|
||||
bi.id,
|
||||
bp.id AS blockpositionid,
|
||||
COALESCE(bp.id, bs.id) AS blockpositionid,
|
||||
bi.blockname,
|
||||
bi.parentcontextid,
|
||||
bi.showinsubcontexts,
|
||||
@@ -736,18 +738,22 @@ class block_manager {
|
||||
bi.subpagepattern,
|
||||
bi.defaultregion,
|
||||
bi.defaultweight,
|
||||
COALESCE(bp.visible, 1) AS visible,
|
||||
COALESCE(bp.region, bi.defaultregion) AS region,
|
||||
COALESCE(bp.weight, bi.defaultweight) AS weight,
|
||||
COALESCE(bp.visible, bs.visible, 1) AS visible,
|
||||
COALESCE(bp.region, bs.region, bi.defaultregion) AS region,
|
||||
COALESCE(bp.weight, bs.weight, bi.defaultweight) AS weight,
|
||||
bi.configdata
|
||||
$ccselect
|
||||
|
||||
FROM {block_instances} bi
|
||||
JOIN {block} b ON bi.blockname = b.name
|
||||
LEFT JOIN {block_positions} bp ON bp.blockinstanceid = bi.id
|
||||
AND bp.contextid $bpcontext
|
||||
AND bp.contextid = :contextid1
|
||||
AND bp.pagetype = :pagetype
|
||||
AND bp.subpage = :subpage1
|
||||
LEFT JOIN {block_positions} bs ON bs.blockinstanceid = bi.id
|
||||
AND bs.contextid = :contextid4
|
||||
AND bs.pagetype = :pagetype2
|
||||
AND bs.subpage = :subpage3
|
||||
$ccjoin
|
||||
|
||||
WHERE
|
||||
@@ -759,12 +765,11 @@ class block_manager {
|
||||
$requiredbythemecheck
|
||||
|
||||
ORDER BY
|
||||
COALESCE(bp.region, bi.defaultregion),
|
||||
COALESCE(bp.weight, bi.defaultweight),
|
||||
COALESCE(bp.region, bs.region, bi.defaultregion),
|
||||
COALESCE(bp.weight, bs.weight, bi.defaultweight),
|
||||
bi.id";
|
||||
|
||||
$allparams = $params + $parentcontextparams + $pagetypepatternparams + $requiredbythemeparams;
|
||||
$allparams = $allparams + $requiredbythemenotparams + $bpcontextidparams;
|
||||
$allparams = $params + $parentcontextparams + $pagetypepatternparams + $requiredbythemeparams + $requiredbythemenotparams;
|
||||
$blockinstances = $DB->get_recordset_sql($sql, $allparams);
|
||||
|
||||
$this->birecordsbyregion = $this->prepare_per_region_arrays();
|
||||
|
||||
@@ -70,7 +70,23 @@ class user_login_failed extends base {
|
||||
public function get_description() {
|
||||
// Note that username could be any random user input.
|
||||
$username = s($this->other['username']);
|
||||
return "Login failed for the username '{$username}' for the reason with id '{$this->other['reason']}'.";
|
||||
$reasonid = $this->other['reason'];
|
||||
$loginfailed = 'Login failed for user';
|
||||
switch ($reasonid){
|
||||
case 1:
|
||||
return $loginfailed." '{$username}'. User does not exist (error ID '{$reasonid}').";
|
||||
case 2:
|
||||
return $loginfailed." '{$username}'. User is suspended (error ID '{$reasonid}').";
|
||||
case 3:
|
||||
return $loginfailed." '{$username}'. Most likely the password did not match (error ID '{$reasonid}').";
|
||||
case 4:
|
||||
return $loginfailed." '{$username}'. User is locked out (error ID '{$reasonid}').";
|
||||
case 5:
|
||||
return $loginfailed." '{$username}'. User is not authorised (error ID '{$reasonid}').";
|
||||
default:
|
||||
return $loginfailed." '{$username}', error ID '{$reasonid}'.";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -113,6 +113,9 @@ class curl_security_helper extends curl_security_helper_base {
|
||||
* 2. Check the host component against the list of domain names and wildcard domain names.
|
||||
* - This will perform a DNS reverse lookup if required.
|
||||
*
|
||||
* The behaviour of this function can be classified as strict, as it returns true for hosts which are invalid or
|
||||
* could not be parsed, as well as those valid URLs which were found in the blacklist.
|
||||
*
|
||||
* @param string $host the host component of the URL to check against the blacklist.
|
||||
* @return bool true if the host is both valid and blocked, false otherwise.
|
||||
*/
|
||||
@@ -132,7 +135,8 @@ class curl_security_helper extends curl_security_helper_base {
|
||||
|
||||
// Only perform a reverse lookup if there is a point to it (i.e. we have rules to check against).
|
||||
if ($blacklistedhosts['domain'] || $blacklistedhosts['domainwildcard']) {
|
||||
$hostname = gethostbyaddr($host); // DNS reverse lookup - supports both IPv4 and IPv6 address formats.
|
||||
// DNS reverse lookup - supports both IPv4 and IPv6 address formats.
|
||||
$hostname = gethostbyaddr($host);
|
||||
if ($hostname !== $host && $this->host_explicitly_blocked($hostname)) {
|
||||
return true;
|
||||
}
|
||||
@@ -144,15 +148,39 @@ class curl_security_helper extends curl_security_helper_base {
|
||||
|
||||
// Only perform a forward lookup if there are IP rules to check against.
|
||||
if ($blacklistedhosts['ipv4'] || $blacklistedhosts['ipv6']) {
|
||||
$hostip = gethostbyname($host); // DNS forward lookup - only returns IPv4 addresses!
|
||||
if ($hostip !== $host && $this->address_explicitly_blocked($hostip)) {
|
||||
// DNS forward lookup - returns a list of only IPv4 addresses!
|
||||
$hostips = $this->get_host_list_by_name($host);
|
||||
|
||||
// If we don't get a valid record, bail (so cURL is never called).
|
||||
if (!$hostips) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If any of the returned IPs are in the blacklist, block the request.
|
||||
foreach ($hostips as $hostip) {
|
||||
if ($this->address_explicitly_blocked($hostip)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Was not something we consider to be a valid IP or domain name, block it.
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all hosts for a domain name.
|
||||
*
|
||||
* @param string $param
|
||||
* @return array An array of IPs associated with the host name.
|
||||
*/
|
||||
protected function get_host_list_by_name($host) {
|
||||
return ($hostips = gethostbynamel($host)) ? $hostips : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given port is blocked, as determined by its absence on the ports whitelist.
|
||||
* Ports are assumed to be blocked unless found in the whitelist.
|
||||
|
||||
@@ -36,18 +36,29 @@ defined('MOODLE_INTERNAL') || die();
|
||||
class memcached extends handler {
|
||||
/** @var string $savepath save_path string */
|
||||
protected $savepath;
|
||||
|
||||
/** @var array $servers list of servers parsed from save_path */
|
||||
protected $servers;
|
||||
|
||||
/** @var string $prefix session key prefix */
|
||||
protected $prefix;
|
||||
|
||||
/** @var int $acquiretimeout how long to wait for session lock */
|
||||
protected $acquiretimeout = 120;
|
||||
|
||||
/**
|
||||
* @var int $lockexpire how long to wait before expiring the lock so that other requests
|
||||
* may continue execution, ignored if PECL memcached is below version 2.2.0.
|
||||
*/
|
||||
protected $lockexpire = 7200;
|
||||
|
||||
/**
|
||||
* @var integer $lockretrysleep Used for memcached 3.x (PHP7), the amount of time to
|
||||
* sleep between attempts to acquire the session lock. Mimics the deprecated config
|
||||
* memcached.sess_lock_wait.
|
||||
*/
|
||||
protected $lockretrysleep = 150;
|
||||
|
||||
/**
|
||||
* Create new instance of handler.
|
||||
*/
|
||||
@@ -79,6 +90,10 @@ class memcached extends handler {
|
||||
if (!empty($CFG->session_memcached_lock_expire)) {
|
||||
$this->lockexpire = (int)$CFG->session_memcached_lock_expire;
|
||||
}
|
||||
|
||||
if (!empty($CFG->session_memcached_lock_retry_sleep)) {
|
||||
$this->lockretrysleep = (int)$CFG->session_memcached_lock_retry_sleep;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,15 +149,32 @@ class memcached extends handler {
|
||||
ini_set('session.save_path', $this->savepath);
|
||||
ini_set('memcached.sess_prefix', $this->prefix);
|
||||
ini_set('memcached.sess_locking', '1'); // Locking is required!
|
||||
ini_set('memcached.sess_lock_expire', $this->lockexpire);
|
||||
|
||||
// Try to configure lock and expire timeouts - ignored if memcached is before version 2.2.0.
|
||||
if (version_compare($version, '3.0.0-dev') >= 0) {
|
||||
ini_set('memcached.sess_lock_wait_max', $this->acquiretimeout * 1000);
|
||||
// With memcached 3.x (PHP 7) we configure the max retries to make and the time to sleep between each retry.
|
||||
// There are two sleep config values, an initial and a max value.
|
||||
// After each attempt the memcached module adjusts the sleep value to be the lesser of the configured max
|
||||
// value, or 2X the previous value.
|
||||
// With default memcached.ini configs (5, 1s, 2s) the result is only 5 attempts to lock over 9 sec.
|
||||
// To mimic the behavior of the 2.2.x module so we get more attempts and much more frequently, config both
|
||||
// sleep values to the old default value of 150 msec (making it constant) and calculate number of retries
|
||||
// using the existing Moodle config $CFG->session_memcached_acquire_lock_timeout.
|
||||
// Doing this so admins configure session lock attempt timeout in familiar terms, and more straight-forward
|
||||
// to detect if lock attempt timeout has occurred in start().
|
||||
// If _min and _max values are not equal, the actual lock acquire timeout will not be the expected
|
||||
// configured value in $CFG->session_memcached_acquire_lock_timeout; this will cause session data loss when
|
||||
// failure to acquire the lock is not detected.
|
||||
ini_set('memcached.sess_lock_wait_min', $this->lockretrysleep);
|
||||
ini_set('memcached.sess_lock_wait_max', $this->lockretrysleep);
|
||||
ini_set('memcached.sess_lock_retries', (int)(($this->acquiretimeout * 1000) / $this->lockretrysleep) + 1);
|
||||
} else {
|
||||
// With memcached 2.2.x we configure max time to attempt lock, and accept default value (in memcached.ini)
|
||||
// for sleep time between each attempt (usually 150 msec), then memcached calculates the max number of
|
||||
// retries to make.
|
||||
ini_set('memcached.sess_lock_max_wait', $this->acquiretimeout);
|
||||
}
|
||||
|
||||
ini_set('memcached.sess_lock_expire', $this->lockexpire);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+30
-1
@@ -2576,7 +2576,12 @@ function xmldb_main_upgrade($oldversion) {
|
||||
['hub', '%' . $DB->sql_like_escape('_' . $cleanoldhuburl)]);
|
||||
foreach ($entries as $entry) {
|
||||
$newname = substr($entry->name, 0, -strlen($cleanoldhuburl)) . $cleannewhuburl;
|
||||
$DB->update_record('config_plugins', ['id' => $entry->id, 'name' => $newname]);
|
||||
try {
|
||||
$DB->update_record('config_plugins', ['id' => $entry->id, 'name' => $newname]);
|
||||
} catch (dml_exception $e) {
|
||||
// Entry with new name already exists, remove the one with an old name.
|
||||
$DB->delete_records('config_plugins', ['id' => $entry->id]);
|
||||
}
|
||||
}
|
||||
|
||||
// Update published courses.
|
||||
@@ -2602,5 +2607,29 @@ function xmldb_main_upgrade($oldversion) {
|
||||
upgrade_main_savepoint(true, 2016120504.08);
|
||||
}
|
||||
|
||||
if ($oldversion < 2016120505.01) {
|
||||
|
||||
// Force all messages to be reindexed.
|
||||
set_config('core_message_message_sent_lastindexrun', '0', 'core_search');
|
||||
set_config('core_message_message_received_lastindexrun', '0', 'core_search');
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2016120505.01);
|
||||
}
|
||||
|
||||
if ($oldversion < 2016120505.04) {
|
||||
|
||||
// Remove duplicate registrations.
|
||||
$newhuburl = "https://moodle.net";
|
||||
$registrations = $DB->get_records('registration_hubs', ['huburl' => $newhuburl], 'confirmed DESC, id ASC');
|
||||
if (count($registrations) > 1) {
|
||||
$reg = array_shift($registrations);
|
||||
$DB->delete_records_select('registration_hubs', 'huburl = ? AND id <> ?', [$newhuburl, $reg->id]);
|
||||
}
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2016120505.04);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -176,6 +176,8 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
$result = $this->mysqli->query($sql);
|
||||
$this->query_end($result);
|
||||
if ($rec = $result->fetch_assoc()) {
|
||||
// MySQL 8 BC: information_schema.* returns the fields in upper case.
|
||||
$rec = array_change_key_case($rec, CASE_LOWER);
|
||||
$engine = $rec['engine'];
|
||||
}
|
||||
$result->close();
|
||||
@@ -248,6 +250,8 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
$result = $this->mysqli->query($sql);
|
||||
$this->query_end($result);
|
||||
if ($rec = $result->fetch_assoc()) {
|
||||
// MySQL 8 BC: information_schema.* returns the fields in upper case.
|
||||
$rec = array_change_key_case($rec, CASE_LOWER);
|
||||
$collation = $rec['collation_name'];
|
||||
}
|
||||
$result->close();
|
||||
@@ -309,10 +313,12 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
$result = $this->mysqli->query($sql);
|
||||
$this->query_end($result);
|
||||
if ($rec = $result->fetch_assoc()) {
|
||||
// MySQL 8 BC: information_schema.* returns the fields in upper case.
|
||||
$rec = array_change_key_case($rec, CASE_LOWER);
|
||||
if (isset($table)) {
|
||||
$rowformat = $rec['row_format'];
|
||||
} else {
|
||||
$rowformat = $rec['Value'];
|
||||
$rowformat = $rec['value'];
|
||||
}
|
||||
}
|
||||
$result->close();
|
||||
@@ -691,6 +697,8 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
if ($result->num_rows > 0) {
|
||||
// standard table exists
|
||||
while ($rawcolumn = $result->fetch_assoc()) {
|
||||
// MySQL 8 BC: information_schema.* returns the fields in upper case.
|
||||
$rawcolumn = array_change_key_case($rawcolumn, CASE_LOWER);
|
||||
$info = (object)$this->get_column_info((object)$rawcolumn);
|
||||
$structure[$info->name] = new database_column_info($info);
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -956,4 +956,4 @@ Y.namespace('M.atto_media').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
});
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
|
||||
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin", "moodle-form-shortforms"]});
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user