Compare commits
324 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8634f2b672 | |||
| 7ec2bf3776 | |||
| a6227d5675 | |||
| e4d47ed2cc | |||
| 4d069c9339 | |||
| 3e741db933 | |||
| 90221b5ccf | |||
| f2de1293e1 | |||
| ea79b6597a | |||
| 3b97a56c6a | |||
| 07414b90e3 | |||
| d49c18bba5 | |||
| ecc61a125b | |||
| d8538f29c4 | |||
| 881b487433 | |||
| e0c0a0c05c | |||
| 246a03f7dd | |||
| 44fd35e8ee | |||
| a28a24e2f2 | |||
| 3639dc845e | |||
| d63c297351 | |||
| 54faefbefb | |||
| 735de9020e | |||
| 71e5f30504 | |||
| 5b9c5ccf83 | |||
| 46b6ca69d1 | |||
| dbd41fa613 | |||
| 381f45d005 | |||
| 0397309abf | |||
| dca95c6fe4 | |||
| 112fc4d513 | |||
| 3b81550b8e | |||
| 0cf43f11f0 | |||
| 035f5d9423 | |||
| 1bae8bd482 | |||
| 3bd1b121ed | |||
| db58c4cdf2 | |||
| b730bb5702 | |||
| d45a6dd3c3 | |||
| 0097d8d481 | |||
| ef6538a8c7 | |||
| fe65ebcf1c | |||
| bc2d3e8bb9 | |||
| d6ce289176 | |||
| d690ed3dd3 | |||
| 704153c454 | |||
| 37ee0fd966 | |||
| 58bf57d9d3 | |||
| 71d4cc2f4e | |||
| 913b96cb21 | |||
| 7c2fef6484 | |||
| 687c727cf9 | |||
| ee6d899130 | |||
| c18b08912f | |||
| a46018529b | |||
| 5ae95f265a | |||
| 456530205e | |||
| 6bfddeea21 | |||
| 4557b7fed2 | |||
| d93d8f65a8 | |||
| 406d9bb40f | |||
| a66d07b15c | |||
| 44b19c47bf | |||
| 81b393a717 | |||
| 6fb0f6f941 | |||
| 4d26e345d0 | |||
| 1c8b779f27 | |||
| a4099f2932 | |||
| 2557a7f8ff | |||
| 9518c81ab8 | |||
| befe7cce8d | |||
| 2dc698fb17 | |||
| 898415efec | |||
| 5b5233321e | |||
| 4d4ad0fe60 | |||
| 8fcb1b459d | |||
| 8816107de4 | |||
| 42cf09b5b4 | |||
| 408c793ed7 | |||
| 6324b63372 | |||
| 3c91dc0784 | |||
| 4d3658f7d8 | |||
| bcbc91091c | |||
| d57acc9d80 | |||
| bc125390bb | |||
| f097a1a20f | |||
| adc032b170 | |||
| 6c8f7e1ce2 | |||
| 8cb7cb1fdc | |||
| 5f6ce419c4 | |||
| 74235813b3 | |||
| 409baab766 | |||
| ee884c9728 | |||
| c6a9898ed0 | |||
| 80c3dcb8bf | |||
| 3c142d923f | |||
| 53e4c04237 | |||
| 8cf375b627 | |||
| 5e7c083dba | |||
| 7d896212f2 | |||
| 3a6950ccd7 | |||
| 24562c031c | |||
| deca8028d9 | |||
| 3063e8415a | |||
| ccbe61ee98 | |||
| ef874ad928 | |||
| 9a33db6bea | |||
| b51501b403 | |||
| 4f142bccce | |||
| dac9cc3139 | |||
| 281c882327 | |||
| bbc79e490a | |||
| 666365e46b | |||
| 28509546d3 | |||
| a860a76a68 | |||
| 8d650d9a01 | |||
| bbaab1109e | |||
| c8a07a5b68 | |||
| abb076ebbd | |||
| 56d6a5d731 | |||
| 59417f0b1d | |||
| 4180fe0f42 | |||
| 8a53b489bb | |||
| fecb0dcceb | |||
| 2b0ae390d7 | |||
| 1f274f5032 | |||
| 6f0115e399 | |||
| 4369ef0304 | |||
| fe3d7cdbaa | |||
| c852856ba7 | |||
| 019420fd11 | |||
| c2263f903d | |||
| 719333e0ec | |||
| 3a98b992e9 | |||
| 27a12aba40 | |||
| b529ffad65 | |||
| b5b8b1a486 | |||
| 2f360b90c5 | |||
| efa47a2ba5 | |||
| 4b47df0236 | |||
| d9fe693347 | |||
| 74206f3d78 | |||
| 0fce71647f | |||
| 3d50844c9f | |||
| 661c7a1988 | |||
| f8f58c441b | |||
| cdb0af69e1 | |||
| 85da65606b | |||
| 6e64255df2 | |||
| ec602d2f26 | |||
| 6079a72373 | |||
| 111fc893da | |||
| 5d7f88d98b | |||
| 3eb69a0a9e | |||
| 465c6e7c45 | |||
| 46323748fa | |||
| 32d28f8fac | |||
| 2591f4ce79 | |||
| c3764823cd | |||
| 49e32e25ff | |||
| 46962930f7 | |||
| 4c97f30360 | |||
| 35282e4d1a | |||
| 78f4960bce | |||
| 6fa2f55cd0 | |||
| d3756efc83 | |||
| 261804e95c | |||
| 53c46ffb2e | |||
| 7ba5f4896e | |||
| 3a76c07806 | |||
| 1794636ee6 | |||
| 24906971d7 | |||
| 1ac59631d8 | |||
| 4a77582d16 | |||
| 2140fe5549 | |||
| fc13b8c1a0 | |||
| f4163d2748 | |||
| a90af06899 | |||
| 81e276c743 | |||
| 45da2ac9d3 | |||
| 8c83815ab1 | |||
| e34877300c | |||
| e917a595b2 | |||
| 852cda447f | |||
| 9e2cb2075c | |||
| 13b26170b9 | |||
| 6f792b5ed8 | |||
| 1612572a62 | |||
| 5c5b0ee137 | |||
| 582e43bebe | |||
| 2ea2d6a72f | |||
| 37d7820816 | |||
| fc2c76e78e | |||
| 4c5684135a | |||
| 35dd608161 | |||
| 9faa136ca0 | |||
| 667d004a17 | |||
| 640838c117 | |||
| f4a77e8381 | |||
| 833d8bceb8 | |||
| bc010acae0 | |||
| 0deabbfbfd | |||
| 404288d3bc | |||
| b16b681a79 | |||
| 14cfb3dcbf | |||
| 074bdceb1f | |||
| c7545dc852 | |||
| cd1a39717a | |||
| c933e28af6 | |||
| 0b62a26225 | |||
| 8a977030fc | |||
| 0ff1309b3a | |||
| 26badfdd1a | |||
| 1dafe5fbe5 | |||
| f8621e3d58 | |||
| e48b197957 | |||
| 7045cd8e67 | |||
| 48583d2740 | |||
| 4ad9de59ea | |||
| b22accf82b | |||
| 99f948b4df | |||
| e94499f9b3 | |||
| 4e60865e2c | |||
| 43268a6a1c | |||
| 38cc6d1071 | |||
| 92ba52e21d | |||
| 13215b2415 | |||
| 0b464b93d8 | |||
| e3b6ebadcc | |||
| 6944da3315 | |||
| e67a6060e0 | |||
| 0aadca7a48 | |||
| 0efd87b0f2 | |||
| d42ad4800d | |||
| 19ebf2dc92 | |||
| a644c50920 | |||
| de19504712 | |||
| ff5773d511 | |||
| 314e9a4064 | |||
| 2f5490410e | |||
| 34f176586b | |||
| 7a168c3beb | |||
| 0be9bb13c7 | |||
| 55dde65d11 | |||
| 45978220ab | |||
| e8e5f49883 | |||
| efeef8d82d | |||
| 9821d4d9a7 | |||
| f138423971 | |||
| e6d212fc07 | |||
| 1adda884fd | |||
| 4fae2c3001 | |||
| 3427a6ec76 | |||
| ea5c0c6b61 | |||
| fcbc4ccee6 | |||
| dd293c28e1 | |||
| 79c6d0a453 | |||
| 1ac5b70c5a | |||
| 9b38e44dfb | |||
| 57382b0e5e | |||
| 2d2e93c6c6 | |||
| e23b038479 | |||
| a2defe29c4 | |||
| aecc9e7170 | |||
| a30ff32351 | |||
| 1b34fbb716 | |||
| 69e2477f90 | |||
| bca7a73d14 | |||
| c27c7abb6b | |||
| 82d46e5037 | |||
| 4853c245c5 | |||
| 4d56bb43b3 | |||
| 0cbb91e4c0 | |||
| 2ef16003f1 | |||
| 80787a98b3 | |||
| 698f0cff54 | |||
| 0e73dacaaf | |||
| 2ba93cc439 | |||
| cd0af947a7 | |||
| 9b2253898a | |||
| a81508489d | |||
| 3ec67cf4bb | |||
| 365bfab967 | |||
| a8b4b9f407 | |||
| c59656006b | |||
| 84d550cacb | |||
| b238304072 | |||
| 10127ac33d | |||
| 6a7350d44b | |||
| ed19fe85e4 | |||
| bd76f0bb66 | |||
| c78ebc9586 | |||
| d2886d283a | |||
| 3ab743dcd9 | |||
| 6f0506fa9d | |||
| 2faa47c934 | |||
| 6c86327b33 | |||
| 6619bdf99d | |||
| 74860627f2 | |||
| 738da05555 | |||
| 9c07f29d8e | |||
| ed68a025ef | |||
| 1f59f848d7 | |||
| b9fc865245 | |||
| d95f185556 | |||
| af9bf5f609 | |||
| f42b67ab2c | |||
| 088d4309fe | |||
| a84620c2d5 | |||
| 59afcdd850 | |||
| 69b0bbde10 | |||
| 660fa2871a | |||
| 24d7375f0f | |||
| 71caffb7e0 | |||
| 04e9010c92 | |||
| 9912c37afd | |||
| d37757abf1 | |||
| f9b144d6bf | |||
| 85bf5b2e2c | |||
| cc36c39b46 | |||
| 5d2be187a2 | |||
| 10bc73d5b6 | |||
| 80827f076c | |||
| 059f402a51 |
+9
-1
@@ -15,6 +15,7 @@ dist: xenial
|
||||
|
||||
services:
|
||||
- mysql
|
||||
- docker
|
||||
|
||||
php:
|
||||
# We only run the highest and lowest supported versions to reduce the load on travis-ci.org.
|
||||
@@ -61,8 +62,9 @@ cache:
|
||||
- $HOME/.npm
|
||||
|
||||
before_install:
|
||||
- docker run -d -p 127.0.0.1:8080:80 --name exttests moodlehq/moodle-exttests
|
||||
# Avoid IPv6 default binding as service (causes redis not to start).
|
||||
sudo service redis-server start --bind 127.0.0.1
|
||||
- sudo service redis-server start --bind 127.0.0.1
|
||||
|
||||
install:
|
||||
- >
|
||||
@@ -169,6 +171,10 @@ before_script:
|
||||
-e "/require_once/i \\\$CFG->phpunit_dataroot = '\/home\/travis\/roots\/phpunit';" \
|
||||
-e "/require_once/i \\\$CFG->phpunit_prefix = 'p_';" \
|
||||
config.php ;
|
||||
# Enable test external resources
|
||||
sed -i \
|
||||
-e "/require_once/i \\define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://127.0.0.1:8080');" \
|
||||
config.php ;
|
||||
# Redis cache store tests
|
||||
sed -i \
|
||||
-e "/require_once/i \\define('TEST_CACHESTORE_REDIS_TESTSERVERS', '127.0.0.1');" \
|
||||
@@ -248,6 +254,8 @@ script:
|
||||
if [ "$TASK" = 'PHPUNIT' ];
|
||||
then
|
||||
vendor/bin/phpunit --fail-on-risky --disallow-test-output --verbose;
|
||||
EXTTESTS_HITS=$(docker logs exttests 2>&1 | grep -Fv -e 'AH00558' -e '[pid 1]' | wc -l)
|
||||
echo -e "\nTest local resources number of hits: ${EXTTESTS_HITS}.\n"
|
||||
fi
|
||||
|
||||
- >
|
||||
|
||||
@@ -105,13 +105,6 @@ if (($hassiteconfig || has_any_capability(array(
|
||||
new lang_string('sitebackpack_help', 'badges'),
|
||||
1, $choices));
|
||||
|
||||
$warning = badges_verify_site_backpack();
|
||||
if (!empty($warning)) {
|
||||
$backpacksettings->add(new admin_setting_description('badges_site_backpack_verify',
|
||||
new lang_string('sitebackpackverify', 'badges'),
|
||||
$warning));
|
||||
}
|
||||
|
||||
$ADMIN->add('badges', $backpacksettings);
|
||||
|
||||
$ADMIN->add('badges',
|
||||
|
||||
@@ -260,10 +260,28 @@ if ($hassiteconfig) {
|
||||
$temp->add($setting);
|
||||
|
||||
// See {@link https://gdpr-info.eu/art-8-gdpr/}.
|
||||
// See {@link https://www.betterinternetforkids.eu/web/portal/practice/awareness/detail?articleId=3017751}.
|
||||
$ageofdigitalconsentmap = implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'AT, 14',
|
||||
'BE, 13',
|
||||
'BG, 14',
|
||||
'CY, 14',
|
||||
'CZ, 15',
|
||||
'DK, 13',
|
||||
'EE, 13',
|
||||
'ES, 14',
|
||||
'FI, 13',
|
||||
'FR, 15',
|
||||
'GB, 13',
|
||||
'GR, 15',
|
||||
'IT, 14',
|
||||
'LT, 14',
|
||||
'LV, 13',
|
||||
'MT, 13',
|
||||
'NO, 13',
|
||||
'PT, 13',
|
||||
'SE, 13',
|
||||
'US, 13'
|
||||
]);
|
||||
$setting = new admin_setting_agedigitalconsentmap('agedigitalconsentmap',
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ $renderer = $PAGE->get_renderer('tool_task');
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->render_from_template('core_admin/tasklogs', (object) [
|
||||
'action' => $pageurl->out(),
|
||||
'filter' => $filter,
|
||||
'filter' => htmlentities($filter),
|
||||
'resultfilteroptions' => [
|
||||
(object) [
|
||||
'value' => -1,
|
||||
|
||||
@@ -49,15 +49,28 @@
|
||||
}}
|
||||
<div class="form-item row" id="{{id}}">
|
||||
<div class="form-label col-sm-3 text-sm-right">
|
||||
<label {{#labelfor}}for="{{labelfor}}"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="form-overridden">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="form-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</label>
|
||||
{{#customcontrol}}
|
||||
<p {{#labelfor}}id="{{labelfor}}_label"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="form-overridden">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="form-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</p>
|
||||
{{/customcontrol}}
|
||||
{{^customcontrol}}
|
||||
<label {{#labelfor}}for="{{labelfor}}"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="form-overridden">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="form-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</label>
|
||||
{{/customcontrol}}
|
||||
<span class="form-shortname d-block small text-muted">{{{name}}}</span>
|
||||
</div>
|
||||
<div class="form-setting col-sm-9">
|
||||
@@ -72,3 +85,16 @@
|
||||
{{#dependenton}}<div class="form-dependenton mb-4 text-muted">{{{.}}}</div>{{/dependenton}}
|
||||
</div>
|
||||
</div>
|
||||
{{#customcontrol}}
|
||||
{{#js}}
|
||||
require(['jquery'], function($) {
|
||||
$('#{{id}}_label').css('cursor', 'default');
|
||||
$('#{{id}}_label').click(function() {
|
||||
$('#{{id}}')
|
||||
.find('button, a, input:not([type="hidden"]), select, textarea, [tabindex]')
|
||||
.filter(':not([disabled]):not([tabindex="0"]):not([tabindex="-1"])')
|
||||
.first().focus();
|
||||
});
|
||||
});
|
||||
{{/js}}
|
||||
{{/customcontrol}}
|
||||
|
||||
@@ -164,6 +164,8 @@ if ($options['install']) {
|
||||
mtrace("Acceptance tests site installed");
|
||||
}
|
||||
|
||||
// Note: Do not build the themes here. This is done during the 'enable' stage.
|
||||
|
||||
} else if ($options['drop']) {
|
||||
// Ensure no tests are running.
|
||||
test_lock::acquire('behat');
|
||||
@@ -182,6 +184,10 @@ if ($options['install']) {
|
||||
// Enable test mode.
|
||||
behat_util::start_test_mode($options['add-core-features-to-theme'], $options['optimize-runs'], $parallel, $run);
|
||||
|
||||
// Themes are only built in the 'enable' command.
|
||||
behat_util::build_themes();
|
||||
mtrace("Testing environment themes built");
|
||||
|
||||
// This is only displayed once for parallel install.
|
||||
if (empty($run)) {
|
||||
// Notify user that 2.5 profile has been converted to 3.5.
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
$string['aim'] = 'This administration tool helps developers and test writers to create .feature files describing Moodle\'s functionalities and run them automatically. Step definitions available for use in .feature files are listed below.';
|
||||
$string['allavailablesteps'] = 'All available step definitions';
|
||||
$string['errorapproot'] = '$CFG->behat_ionic_dirroot is not pointing to a valid Moodle Mobile developer install.';
|
||||
$string['errorapproot'] = '$CFG->behat_ionic_dirroot is not pointing to a valid Moodle app developer install.';
|
||||
$string['errorbehatcommand'] = 'Error running behat CLI command. Try running "{$a} --help" manually from CLI to find out more about the problem.';
|
||||
$string['errorcomposer'] = 'Composer dependencies are not installed.';
|
||||
$string['errordataroot'] = '$CFG->behat_dataroot is not set or is invalid.';
|
||||
|
||||
@@ -36,7 +36,7 @@ $string['customlang:view'] = 'View local translation';
|
||||
$string['filter'] = 'Filter strings';
|
||||
$string['filtercomponent'] = 'Show strings of these components';
|
||||
$string['filtercustomized'] = 'Customised only';
|
||||
$string['filtermodified'] = 'Modified only';
|
||||
$string['filtermodified'] = 'Modified in this session only';
|
||||
$string['filteronlyhelps'] = 'Help only';
|
||||
$string['filtershowstrings'] = 'Show strings';
|
||||
$string['filterstringid'] = 'String identifier';
|
||||
|
||||
@@ -322,5 +322,28 @@ function xmldb_tool_dataprivacy_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.8.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
if ($oldversion < 2019111801) {
|
||||
|
||||
// Define field commentsformat to be added to tool_dataprivacy_request.
|
||||
$table = new xmldb_table('tool_dataprivacy_request');
|
||||
$field = new xmldb_field('commentsformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'comments');
|
||||
|
||||
// Conditionally launch add field commentsformat.
|
||||
if (!$dbman->field_exists($table, $field)) {
|
||||
$dbman->add_field($table, $field);
|
||||
}
|
||||
|
||||
// Define field dpocommentformat to be added to tool_dataprivacy_request.
|
||||
$field = new xmldb_field('dpocommentformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'dpocomment');
|
||||
|
||||
// Conditionally launch add field dpocommentformat.
|
||||
if (!$dbman->field_exists($table, $field)) {
|
||||
$dbman->add_field($table, $field);
|
||||
}
|
||||
|
||||
// Dataprivacy savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2019111801, 'tool', 'dataprivacy');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ Feature: Manage data categories
|
||||
And I press "Add category"
|
||||
And I set the field "Name" to "Category 1"
|
||||
And I set the field "Description" to "Category 1 description"
|
||||
When I click on "Save" "button" in the "Delete category" "dialogue"
|
||||
When I click on "Save" "button" in the "Add category" "dialogue"
|
||||
Then I should see "Category 1" in the "List of data categories" "table"
|
||||
And I should see "Category 1 description" in the "Category 1" "table_row"
|
||||
|
||||
@@ -30,5 +30,5 @@ Feature: Manage data categories
|
||||
And I choose "Delete" in the open action menu
|
||||
And I should see "Delete category"
|
||||
And I should see "Are you sure you want to delete the category 'Category 1'?"
|
||||
When I click on "Delete" "button" in the "Confirm" "dialogue"
|
||||
When I click on "Delete" "button" in the "Delete category" "dialogue"
|
||||
Then I should not see "Category 1" in the "List of data categories" "table"
|
||||
|
||||
@@ -52,5 +52,5 @@ Feature: Manage data storage purposes
|
||||
And I choose "Delete" in the open action menu
|
||||
And I should see "Delete purpose"
|
||||
And I should see "Are you sure you want to delete the purpose 'Purpose 1'?"
|
||||
When I click on "Delete" "button" in the "Confirm" "dialogue"
|
||||
When I click on "Delete" "button" in the "Delete purpose" "dialogue"
|
||||
Then I should not see "Purpose 1" in the "List of data purposes" "table"
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$plugin->version = 2019111800;
|
||||
$plugin->version = 2019111801;
|
||||
$plugin->requires = 2019111200; // Moodle 3.5dev (Build 2018031600) and upwards.
|
||||
$plugin->component = 'tool_dataprivacy';
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("tool_lp/dialogue",["core/yui"],function(a){var b=function(b,c,d,e,f){this.yuiDialogue=null;var g=this;if("undefined"==typeof f){f=!1}a.use("moodle-core-notification","timers",function(){var h="480px";if(f){h="800px"}g.yuiDialogue=new M.core.dialogue({headerContent:b,bodyContent:c,draggable:!0,visible:!1,center:!0,modal:!0,width:h});g.yuiDialogue.after("visibleChange",function(b){if(b.newVal){if("undefined"!=typeof d){a.soon(function(){d(g);g.yuiDialogue.centerDialogue()})}}else{if("undefined"!=typeof e){a.soon(function(){e(g)})}}});g.yuiDialogue.show()})};b.prototype.close=function(){this.yuiDialogue.hide();this.yuiDialogue.destroy()};b.prototype.getContent=function(){return this.yuiDialogue.bodyNode.getDOMNode()};return b});
|
||||
define ("tool_lp/dialogue",["core/yui"],function(a){var b=function(b,c,d,e,f){M.util.js_pending("tool_lp/dialogue:dialogue");this.yuiDialogue=null;var g=this;if("undefined"==typeof f){f=!1}a.use("moodle-core-notification","timers",function(){var h="480px";if(f){h="800px"}g.yuiDialogue=new M.core.dialogue({headerContent:b,bodyContent:c,draggable:!0,visible:!1,center:!0,modal:!0,width:h});g.yuiDialogue.before("visibleChange",function(){M.util.js_pending("tool_lp/dialogue:before:visibleChange")});g.yuiDialogue.after("visibleChange",function(b){if(b.newVal){if("undefined"!=typeof d){a.soon(function(){d(g);g.yuiDialogue.centerDialogue();M.util.js_complete("tool_lp/dialogue:before:visibleChange")})}else{M.util.js_complete("tool_lp/dialogue:before:visibleChange")}}else{if("undefined"!=typeof e){a.soon(function(){e(g);M.util.js_complete("tool_lp/dialogue:before:visibleChange")})}else{M.util.js_complete("tool_lp/dialogue:before:visibleChange")}}});g.yuiDialogue.show();M.util.js_complete("tool_lp/dialogue:dialogue")})};b.prototype.close=function(){this.yuiDialogue.hide();this.yuiDialogue.destroy()};b.prototype.getContent=function(){return this.yuiDialogue.bodyNode.getDOMNode()};return b});
|
||||
//# sourceMappingURL=dialogue.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("tool_lp/grade_dialogue",["jquery","core/notification","core/templates","tool_lp/dialogue","tool_lp/event_base","core/str"],function(a,b,c,d,e,f){var g=function(a){e.prototype.constructor.apply(this,[]);this._ratingOptions=a};g.prototype=Object.create(e.prototype);g.prototype._popup=null;g.prototype._ratingOptions=null;g.prototype._afterRender=function(){var b=this._find("[data-action=\"rate\"]"),c=this._find("[name=\"rating\"]"),d=this._find("[name=\"comment\"]");this._find("[data-action=\"cancel\"]").click(function(a){a.preventDefault();this._trigger("cancelled");this.close()}.bind(this));c.change(function(){var c=a(this);if(!c.val()){b.prop("disabled",!0)}else{b.prop("disabled",!1)}}).change();b.click(function(a){a.preventDefault();var b=c.val();if(!b){return}this._trigger("rated",{rating:b,note:d.val()});this.close()}.bind(this))};g.prototype.close=function(){this._popup.close();this._popup=null};g.prototype.display=function(){return a.when(f.get_string("rate","tool_lp"),this._render()).then(function(a,b){this._popup=new d(a,b[0],this._afterRender.bind(this));return this._popup}.bind(this)).catch(b.exception)};g.prototype._find=function(b){return a(this._popup.getContent()).find(b)};g.prototype._render=function(){var a={cangrade:this._canGrade,ratings:this._ratingOptions};return c.render("tool_lp/competency_grader",a)};return g});
|
||||
define ("tool_lp/grade_dialogue",["jquery","core/notification","core/templates","tool_lp/dialogue","tool_lp/event_base","core/str"],function(a,b,c,d,e,f){var g=function(a){e.prototype.constructor.apply(this,[]);this._ratingOptions=a};g.prototype=Object.create(e.prototype);g.prototype._popup=null;g.prototype._ratingOptions=null;g.prototype._afterRender=function(){var b=this._find("[data-action=\"rate\"]"),c=this._find("[name=\"rating\"]"),d=this._find("[name=\"comment\"]");this._find("[data-action=\"cancel\"]").click(function(a){a.preventDefault();this._trigger("cancelled");this.close()}.bind(this));c.change(function(){var c=a(this);if(!c.val()){b.prop("disabled",!0)}else{b.prop("disabled",!1)}}).change();b.click(function(a){a.preventDefault();var b=c.val();if(!b){return}this._trigger("rated",{rating:b,note:d.val()});this.close()}.bind(this))};g.prototype.close=function(){this._popup.close();this._popup=null};g.prototype.display=function(){M.util.js_pending("tool_lp/grade_dialogue:display");return a.when(f.get_string("rate","tool_lp"),this._render()).then(function(a,b){this._popup=new d(a,b[0],function(){this._afterRender();M.util.js_complete("tool_lp/grade_dialogue:display")}.bind(this));return this._popup}.bind(this)).catch(b.exception)};g.prototype._find=function(b){return a(this._popup.getContent()).find(b)};g.prototype._render=function(){var a={cangrade:this._canGrade,ratings:this._ratingOptions};return c.render("tool_lp/competency_grader",a)};return g});
|
||||
//# sourceMappingURL=grade_dialogue.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
define ("tool_lp/grade_user_competency_inline",["jquery","core/notification","core/ajax","core/log","tool_lp/grade_dialogue","tool_lp/event_base","tool_lp/scalevalues"],function(a,b,c,d,e,f,g){var h=function(b,c,d,e,g,h,i){f.prototype.constructor.apply(this,[]);var j=a(b);if(!j.length){throw new Error("Could not find the trigger")}this._scaleId=c;this._competencyId=d;this._userId=e;this._planId=g;this._courseId=h;this._chooseStr=i;this._setUp();j.click(function(a){a.preventDefault();this._dialogue.display()}.bind(this));if(this._planId){this._methodName="core_competency_grade_competency_in_plan";this._args={competencyid:this._competencyId,planid:this._planId}}else if(this._courseId){this._methodName="core_competency_grade_competency_in_course";this._args={competencyid:this._competencyId,courseid:this._courseId,userid:this._userId}}else{this._methodName="core_competency_grade_competency";this._args={userid:this._userId,competencyid:this._competencyId}}};h.prototype=Object.create(f.prototype);h.prototype._setUp=function(){var a=[],d=this,f=g.get_values(d._scaleId);f.then(function(b){a.push({value:"",name:d._chooseStr});for(var c=0,e;c<b.length;c++){e=b[c];a.push({value:e.id,name:e.name})}return a}).then(function(a){return new e(a)}).then(function(a){a.on("rated",function(a,e){var f=d._args;f.grade=e.rating;f.note=e.note;c.call([{methodname:d._methodName,args:f,done:function done(a){d._trigger("competencyupdated",{args:f,evidence:a})},fail:b.exception}])});return a}).then(function(a){d._dialogue=a}).fail(b.exception)};h.prototype._scaleId=null;h.prototype._competencyId=null;h.prototype._userId=null;h.prototype._planId=null;h.prototype._courseId=null;h.prototype._chooseStr=null;h.prototype._dialogue=null;return h});
|
||||
define ("tool_lp/grade_user_competency_inline",["jquery","core/notification","core/ajax","core/log","tool_lp/grade_dialogue","tool_lp/event_base","tool_lp/scalevalues"],function(a,b,c,d,e,f,g){var h=function(b,c,d,e,g,h,i){f.prototype.constructor.apply(this,[]);var j=a(b);if(!j.length){throw new Error("Could not find the trigger")}this._scaleId=c;this._competencyId=d;this._userId=e;this._planId=g;this._courseId=h;this._chooseStr=i;this._setUp();j.click(function(a){a.preventDefault();this._dialogue.display()}.bind(this));if(this._planId){this._methodName="core_competency_grade_competency_in_plan";this._args={competencyid:this._competencyId,planid:this._planId}}else if(this._courseId){this._methodName="core_competency_grade_competency_in_course";this._args={competencyid:this._competencyId,courseid:this._courseId,userid:this._userId}}else{this._methodName="core_competency_grade_competency";this._args={userid:this._userId,competencyid:this._competencyId}}};h.prototype=Object.create(f.prototype);h.prototype._setUp=function(){var a=[],d=this;M.util.js_pending("tool_lp/grade_user_competency_inline:_setUp");var f=g.get_values(d._scaleId);f.then(function(b){a.push({value:"",name:d._chooseStr});for(var c=0,e;c<b.length;c++){e=b[c];a.push({value:e.id,name:e.name})}return a}).then(function(a){return new e(a)}).then(function(a){a.on("rated",function(a,e){var f=d._args;f.grade=e.rating;f.note=e.note;c.call([{methodname:d._methodName,args:f,done:function done(a){d._trigger("competencyupdated",{args:f,evidence:a})},fail:b.exception}])});return a}).then(function(a){d._dialogue=a;M.util.js_complete("tool_lp/grade_user_competency_inline:_setUp")}).fail(b.exception)};h.prototype._scaleId=null;h.prototype._competencyId=null;h.prototype._userId=null;h.prototype._planId=null;h.prototype._courseId=null;h.prototype._chooseStr=null;h.prototype._dialogue=null;return h});
|
||||
//# sourceMappingURL=grade_user_competency_inline.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -35,6 +35,8 @@ define(['core/yui'], function(Y) {
|
||||
* @param {Boolean} wide Specify we want an extra wide dialogue (the size is standard, but wider than the default).
|
||||
*/
|
||||
var dialogue = function(title, content, afterShow, afterHide, wide) {
|
||||
M.util.js_pending('tool_lp/dialogue:dialogue');
|
||||
|
||||
this.yuiDialogue = null;
|
||||
var parent = this;
|
||||
|
||||
@@ -59,6 +61,10 @@ define(['core/yui'], function(Y) {
|
||||
width: width
|
||||
});
|
||||
|
||||
parent.yuiDialogue.before('visibleChange', function() {
|
||||
M.util.js_pending('tool_lp/dialogue:before:visibleChange');
|
||||
});
|
||||
|
||||
parent.yuiDialogue.after('visibleChange', function(e) {
|
||||
if (e.newVal) {
|
||||
// Delay the callback call to the next tick, otherwise it can happen that it is
|
||||
@@ -67,18 +73,25 @@ define(['core/yui'], function(Y) {
|
||||
Y.soon(function() {
|
||||
afterShow(parent);
|
||||
parent.yuiDialogue.centerDialogue();
|
||||
M.util.js_complete('tool_lp/dialogue:before:visibleChange');
|
||||
});
|
||||
} else {
|
||||
M.util.js_complete('tool_lp/dialogue:before:visibleChange');
|
||||
}
|
||||
} else {
|
||||
if ((typeof afterHide !== 'undefined')) {
|
||||
Y.soon(function() {
|
||||
afterHide(parent);
|
||||
M.util.js_complete('tool_lp/dialogue:before:visibleChange');
|
||||
});
|
||||
} else {
|
||||
M.util.js_complete('tool_lp/dialogue:before:visibleChange');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
parent.yuiDialogue.show();
|
||||
M.util.js_complete('tool_lp/dialogue:dialogue');
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ define(['jquery',
|
||||
* @return {Promise}
|
||||
*/
|
||||
Grade.prototype.display = function() {
|
||||
M.util.js_pending('tool_lp/grade_dialogue:display');
|
||||
return $.when(
|
||||
Str.get_string('rate', 'tool_lp'),
|
||||
this._render()
|
||||
@@ -110,7 +111,10 @@ define(['jquery',
|
||||
this._popup = new Dialogue(
|
||||
title,
|
||||
templateResult[0],
|
||||
this._afterRender.bind(this)
|
||||
function() {
|
||||
this._afterRender();
|
||||
M.util.js_complete('tool_lp/grade_dialogue:display');
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
return this._popup;
|
||||
|
||||
@@ -94,6 +94,7 @@ define(['jquery',
|
||||
var options = [],
|
||||
self = this;
|
||||
|
||||
M.util.js_pending('tool_lp/grade_user_competency_inline:_setUp');
|
||||
var promise = ScaleValues.get_values(self._scaleId);
|
||||
promise.then(function(scalevalues) {
|
||||
options.push({
|
||||
@@ -134,6 +135,7 @@ define(['jquery',
|
||||
.then(function(dialogue) {
|
||||
self._dialogue = dialogue;
|
||||
|
||||
M.util.js_complete('tool_lp/grade_user_competency_inline:_setUp');
|
||||
return;
|
||||
})
|
||||
.fail(notification.exception);
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("tool_usertours/usertours",["core/ajax","tool_usertours/tour","jquery","core/templates","core/str","core/log","core/notification"],function(a,b,c,d,e,f,g){var h={tourId:null,currentTour:null,context:null,init:function init(a,b,d){h.tourId=a;h.context=d;if("undefined"==typeof b){b=!0}if(b){h.fetchTour(a)}h.addResetLink();c("body").on("click","[data-action=\"tool_usertours/resetpagetour\"]",function(a){a.preventDefault();h.resetTourState(h.tourId)})},fetchTour:function fetchTour(b){M.util.js_pending("admin_usertour_fetchTour"+b);c.when(a.call([{methodname:"tool_usertours_fetch_and_start_tour",args:{tourid:b,context:h.context,pageurl:window.location.href}}])[0],d.render("tool_usertours/tourstep",{})).then(function(a,c){return h.startBootstrapTour(b,c[0],a.tourconfig)}).always(function(){M.util.js_complete("admin_usertour_fetchTour"+b)}).fail(g.exception)},addResetLink:function addResetLink(){var a;M.util.js_pending("admin_usertour_addResetLink");if(c(".tool_usertours-resettourcontainer").length){a=c(".tool_usertours-resettourcontainer")}else if(c(".logininfo").length){a=c(".logininfo")}else if(c("footer").length){a=c("footer")}else{a=c("body")}d.render("tool_usertours/resettour",{}).then(function(b,c){d.appendNodeContents(a,b,c)}).always(function(){M.util.js_complete("admin_usertour_addResetLink")}).fail()},startBootstrapTour:function startBootstrapTour(a,c,d){if(h.currentTour){d.onEnd=null;h.currentTour.endTour();delete h.currentTour}d.eventHandlers={afterEnd:[h.markTourComplete],afterRender:[h.markStepShown]};d.tourName=d.name;delete d.name;d.template=c;d.steps=d.steps.map(function(a){if("undefined"!=typeof a.element){a.target=a.element;delete a.element}if("undefined"!=typeof a.reflex){a.moveOnClick=!!a.reflex;delete a.reflex}if("undefined"!=typeof a.content){a.body=a.content;delete a.content}return a});h.currentTour=new b(d);return h.currentTour.startTour()},markStepShown:function markStepShown(){var b=this.getStepConfig(this.getCurrentStepNumber());c.when(a.call([{methodname:"tool_usertours_step_shown",args:{tourid:h.tourId,context:h.context,pageurl:window.location.href,stepid:b.stepid,stepindex:this.getCurrentStepNumber()}}])[0]).fail(f.error)},markTourComplete:function markTourComplete(){var b=this.getStepConfig(this.getCurrentStepNumber());c.when(a.call([{methodname:"tool_usertours_complete_tour",args:{tourid:h.tourId,context:h.context,pageurl:window.location.href,stepid:b.stepid,stepindex:this.getCurrentStepNumber()}}])[0]).fail(f.error)},resetTourState:function resetTourState(b){c.when(a.call([{methodname:"tool_usertours_reset_tour",args:{tourid:b,context:h.context,pageurl:window.location.href}}])[0]).then(function(a){if(a.startTour){h.fetchTour(a.startTour)}}).fail(g.exception)}};return{init:h.init,resetTourState:h.resetTourState}});
|
||||
define ("tool_usertours/usertours",["core/ajax","tool_usertours/tour","jquery","core/templates","core/str","core/log","core/notification"],function(a,b,c,d,e,f,g){var h={tourId:null,currentTour:null,context:null,init:function init(a,b,d){h.tourId=a;h.context=d;if("undefined"==typeof b){b=!0}if(b){h.fetchTour(a)}h.addResetLink();c("body").on("click","[data-action=\"tool_usertours/resetpagetour\"]",function(a){a.preventDefault();h.resetTourState(h.tourId)})},fetchTour:function fetchTour(b){M.util.js_pending("admin_usertour_fetchTour"+b);c.when(a.call([{methodname:"tool_usertours_fetch_and_start_tour",args:{tourid:b,context:h.context,pageurl:window.location.href}}])[0],d.render("tool_usertours/tourstep",{})).then(function(a,c){if(!a.hasOwnProperty("tourconfig")){return}return h.startBootstrapTour(b,c[0],a.tourconfig)}).always(function(){M.util.js_complete("admin_usertour_fetchTour"+b)}).fail(g.exception)},addResetLink:function addResetLink(){var a;M.util.js_pending("admin_usertour_addResetLink");if(c(".tool_usertours-resettourcontainer").length){a=c(".tool_usertours-resettourcontainer")}else if(c(".logininfo").length){a=c(".logininfo")}else if(c("footer").length){a=c("footer")}else{a=c("body")}d.render("tool_usertours/resettour",{}).then(function(b,c){d.appendNodeContents(a,b,c)}).always(function(){M.util.js_complete("admin_usertour_addResetLink")}).fail()},startBootstrapTour:function startBootstrapTour(a,c,d){if(h.currentTour){d.onEnd=null;h.currentTour.endTour();delete h.currentTour}d.eventHandlers={afterEnd:[h.markTourComplete],afterRender:[h.markStepShown]};d.tourName=d.name;delete d.name;d.template=c;d.steps=d.steps.map(function(a){if("undefined"!=typeof a.element){a.target=a.element;delete a.element}if("undefined"!=typeof a.reflex){a.moveOnClick=!!a.reflex;delete a.reflex}if("undefined"!=typeof a.content){a.body=a.content;delete a.content}return a});h.currentTour=new b(d);return h.currentTour.startTour()},markStepShown:function markStepShown(){var b=this.getStepConfig(this.getCurrentStepNumber());c.when(a.call([{methodname:"tool_usertours_step_shown",args:{tourid:h.tourId,context:h.context,pageurl:window.location.href,stepid:b.stepid,stepindex:this.getCurrentStepNumber()}}])[0]).fail(f.error)},markTourComplete:function markTourComplete(){var b=this.getStepConfig(this.getCurrentStepNumber());c.when(a.call([{methodname:"tool_usertours_complete_tour",args:{tourid:h.tourId,context:h.context,pageurl:window.location.href,stepid:b.stepid,stepindex:this.getCurrentStepNumber()}}])[0]).fail(f.error)},resetTourState:function resetTourState(b){c.when(a.call([{methodname:"tool_usertours_reset_tour",args:{tourid:b,context:h.context,pageurl:window.location.href}}])[0]).then(function(a){if(a.startTour){h.fetchTour(a.startTour)}}).fail(g.exception)}};return{init:h.init,resetTourState:h.resetTourState}});
|
||||
//# sourceMappingURL=usertours.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -69,6 +69,11 @@ function(ajax, BootstrapTour, $, templates, str, log, notification) {
|
||||
templates.render('tool_usertours/tourstep', {})
|
||||
)
|
||||
.then(function(response, template) {
|
||||
// If we don't have any tour config (because it doesn't need showing for the current user), return early.
|
||||
if (!response.hasOwnProperty('tourconfig')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return usertours.startBootstrapTour(tourId, template[0], response.tourconfig);
|
||||
})
|
||||
.always(function() {
|
||||
|
||||
+3
-3
@@ -70,9 +70,9 @@ class tour extends external_api {
|
||||
|
||||
\tool_usertours\event\tour_started::create([
|
||||
'contextid' => $context->id,
|
||||
'objectid' => $tourid,
|
||||
'objectid' => $tour->get_id(),
|
||||
'other' => [
|
||||
'pageurl' => $pageurl,
|
||||
'pageurl' => $params['pageurl'],
|
||||
],
|
||||
])->trigger();
|
||||
|
||||
@@ -104,7 +104,7 @@ class tour extends external_api {
|
||||
'tourconfig' => new external_single_structure([
|
||||
'name' => new external_value(PARAM_RAW, 'Tour Name'),
|
||||
'steps' => new external_multiple_structure(self::step_structure_returns()),
|
||||
])
|
||||
], 'Tour config', VALUE_OPTIONAL)
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
This files describes API changes in the tool_usertours code.
|
||||
|
||||
=== 3.8.4 ===
|
||||
* The `tourconfig` property returned by the `tool_usertours_fetch_and_start_tour`
|
||||
external method is now optional, and will be omitted if the tour shouldn't be
|
||||
shown to the current user
|
||||
|
||||
=== 3.5 ===
|
||||
* Third party library Popper.js was moved from this plugin into core (core/popper)
|
||||
|
||||
@@ -158,5 +158,5 @@ Feature: Manage analytics models
|
||||
Scenario: Delete model
|
||||
When I open the action menu in "Students at risk of not meeting the course completion conditions" "table_row"
|
||||
And I choose "Delete" in the open action menu
|
||||
And I click on "Delete" "button" in the "Confirm" "dialogue"
|
||||
And I click on "Delete" "button" in the "Delete" "dialogue"
|
||||
Then I should not see "Students at risk of not meeting the course completion conditions"
|
||||
|
||||
@@ -76,9 +76,21 @@ class auth_email_external_testcase extends externallib_advanced_testcase {
|
||||
$this->assertEquals(print_password_policy(), $result['passwordpolicy']);
|
||||
$this->assertNotContains('recaptchachallengehash', $result);
|
||||
$this->assertNotContains('recaptchachallengeimage', $result);
|
||||
$this->assertCount(2, $result['profilefields']);
|
||||
$this->assertEquals('text', $result['profilefields'][0]['datatype']);
|
||||
$this->assertEquals('textarea', $result['profilefields'][1]['datatype']);
|
||||
|
||||
// Whip up a array with named entries to easily check against.
|
||||
$namedarray = array();
|
||||
foreach ($result['profilefields'] as $key => $value) {
|
||||
$namedarray[$value['shortname']] = array(
|
||||
'datatype' => $value['datatype']
|
||||
);
|
||||
}
|
||||
|
||||
// Just check if we have the fields from this test. If a plugin adds fields we'll let it slide.
|
||||
$this->assertArrayHasKey('frogname', $namedarray);
|
||||
$this->assertArrayHasKey('sometext', $namedarray);
|
||||
|
||||
$this->assertEquals('text', $namedarray['frogname']['datatype']);
|
||||
$this->assertEquals('textarea', $namedarray['sometext']['datatype']);
|
||||
}
|
||||
|
||||
public function test_signup_user() {
|
||||
|
||||
@@ -455,8 +455,9 @@ class auth extends \auth_plugin_base {
|
||||
}
|
||||
}
|
||||
|
||||
$issuer = $client->get_issuer();
|
||||
// First we try and find a defined mapping.
|
||||
$linkedlogin = api::match_username_to_user($userinfo['username'], $client->get_issuer());
|
||||
$linkedlogin = api::match_username_to_user($userinfo['username'], $issuer);
|
||||
|
||||
if (!empty($linkedlogin) && empty($linkedlogin->get('confirmtoken'))) {
|
||||
$mappeduser = get_complete_user_data('id', $linkedlogin->get('userid'));
|
||||
@@ -474,7 +475,7 @@ class auth extends \auth_plugin_base {
|
||||
$SESSION->loginerrormsg = get_string('invalidlogin');
|
||||
$client->log_out();
|
||||
redirect(new moodle_url('/login/index.php'));
|
||||
} else if ($mappeduser && $mappeduser->confirmed) {
|
||||
} else if ($mappeduser && ($mappeduser->confirmed || !$issuer->get('requireconfirmation'))) {
|
||||
// Update user fields.
|
||||
$userinfo = $this->update_user($userinfo, $mappeduser);
|
||||
$userwasmapped = true;
|
||||
@@ -503,7 +504,7 @@ class auth extends \auth_plugin_base {
|
||||
redirect(new moodle_url('/login/index.php'));
|
||||
}
|
||||
|
||||
$issuer = $client->get_issuer();
|
||||
|
||||
if (!$issuer->is_valid_login_domain($oauthemail)) {
|
||||
// Trigger login failed event.
|
||||
$failurereason = AUTH_LOGIN_UNAUTHORISED;
|
||||
|
||||
@@ -175,6 +175,20 @@ abstract class restore_qtype_plugin extends restore_plugin {
|
||||
}
|
||||
}
|
||||
|
||||
$rules = restore_course_task::define_decode_rules();
|
||||
$rulesactivity = restore_quiz_activity_task::define_decode_rules();
|
||||
$rules = array_merge($rules, $rulesactivity);
|
||||
|
||||
$decoder = $this->task->get_decoder();
|
||||
foreach ($rules as $rule) {
|
||||
$decoder->add_rule($rule);
|
||||
}
|
||||
|
||||
$contentdecoded = $decoder->decode_content($data->answertext);
|
||||
if ($contentdecoded) {
|
||||
$data->answertext = $contentdecoded;
|
||||
}
|
||||
|
||||
if (!isset($this->questionanswercache[$data->answertext])) {
|
||||
// If we haven't found the matching answer, something has gone really wrong, the question in the DB
|
||||
// is missing answers, throw an exception.
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Decode links quiz restore tests.
|
||||
*
|
||||
* @package core_backup
|
||||
* @copyright 2020 Ilya Tregubov <mattp@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
// Include all the needed stuff.
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/course/lib.php');
|
||||
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
|
||||
require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
|
||||
|
||||
/**
|
||||
* restore_decode tests (both rule and content)
|
||||
*/
|
||||
class restore_quiz_decode_testcase extends \core_privacy\tests\provider_testcase {
|
||||
|
||||
/**
|
||||
* Test restore_decode_rule class
|
||||
*/
|
||||
public function test_restore_quiz_decode_links() {
|
||||
global $DB, $CFG, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$this->setAdminUser();
|
||||
|
||||
$generator = $this->getDataGenerator();
|
||||
$course = $generator->create_course(
|
||||
array('format' => 'topics', 'numsections' => 3,
|
||||
'enablecompletion' => COMPLETION_ENABLED),
|
||||
array('createsections' => true));
|
||||
$quiz = $generator->create_module('quiz', array(
|
||||
'course' => $course->id));
|
||||
|
||||
// Create questions.
|
||||
|
||||
$questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
|
||||
$context = context_course::instance($course->id);
|
||||
$cat = $questiongenerator->create_question_category(array('contextid' => $context->id));
|
||||
$question = $questiongenerator->create_question('multichoice', null, array('category' => $cat->id));
|
||||
|
||||
// Add to the quiz.
|
||||
quiz_add_quiz_question($question->id, $quiz);
|
||||
|
||||
$questiondata = question_bank::load_question_data($question->id);
|
||||
|
||||
$firstanswer = array_shift($questiondata->options->answers);
|
||||
$DB->set_field('question_answers', 'answer', $CFG->wwwroot . '/course/view.php?id=' . $course->id,
|
||||
['id' => $firstanswer->id]);
|
||||
|
||||
$secondanswer = array_shift($questiondata->options->answers);
|
||||
$DB->set_field('question_answers', 'answer', $CFG->wwwroot . '/mod/quiz/view.php?id=' . $quiz->cmid,
|
||||
['id' => $secondanswer->id]);
|
||||
|
||||
$thirdanswer = array_shift($questiondata->options->answers);
|
||||
$DB->set_field('question_answers', 'answer', $CFG->wwwroot . '/grade/report/index.php?id=' . $quiz->cmid,
|
||||
['id' => $thirdanswer->id]);
|
||||
|
||||
$fourthanswer = array_shift($questiondata->options->answers);
|
||||
$DB->set_field('question_answers', 'answer', $CFG->wwwroot . '/mod/quiz/index.php?id=' . $quiz->cmid,
|
||||
['id' => $fourthanswer->id]);
|
||||
|
||||
$newcm = duplicate_module($course, get_fast_modinfo($course)->get_cm($quiz->cmid));
|
||||
|
||||
$sql = "SELECT qa.answer
|
||||
FROM {quiz} q
|
||||
LEFT JOIN {quiz_slots} qs ON qs.quizid = q.id
|
||||
LEFT JOIN {question_answers} qa ON qa.question = qs.questionid
|
||||
WHERE q.id = :quizid";
|
||||
$params = array('quizid' => $newcm->instance);
|
||||
$answers = $DB->get_fieldset_sql($sql, $params);
|
||||
$this->assertEquals($CFG->wwwroot . '/course/view.php?id=' . $course->id, $answers[0]);
|
||||
$this->assertEquals($CFG->wwwroot . '/mod/quiz/view.php?id=' . $quiz->cmid, $answers[1]);
|
||||
$this->assertEquals($CFG->wwwroot . '/grade/report/index.php?id=' . $quiz->cmid, $answers[2]);
|
||||
$this->assertEquals($CFG->wwwroot . '/mod/quiz/index.php?id=' . $quiz->cmid, $answers[3]);
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,14 @@ if ($action == 'edit') {
|
||||
echo $output->heading(get_string('managebackpacks', 'badges'));
|
||||
|
||||
$form->display();
|
||||
} else if ($action == 'test') {
|
||||
// If no backpack has been selected, there isn't anything to test.
|
||||
if (empty($id)) {
|
||||
redirect($url);
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $output->render_test_backpack_result($id);
|
||||
} else {
|
||||
echo $OUTPUT->header();
|
||||
echo $output->heading(get_string('managebackpacks', 'badges'));
|
||||
|
||||
@@ -68,9 +68,9 @@ class external_backpacks_page implements \renderable {
|
||||
} else {
|
||||
$backpack->canedit = false;
|
||||
}
|
||||
$backpack->cantest = ($backpack->apiversion == OPEN_BADGES_V2);
|
||||
$data->backpacks[] = $backpack;
|
||||
}
|
||||
$data->warning = badges_verify_site_backpack();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
@@ -1362,4 +1362,35 @@ class core_badges_renderer extends plugin_renderer_base {
|
||||
$data = $page->export_for_template($this);
|
||||
return parent::render_from_template('core_badges/external_backpacks_page', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the result of a backpack validation with its settings. It returns:
|
||||
* - A informative message if the backpack version is different from OBv2.
|
||||
* - A warning with the error if it's not possible to connect to this backpack.
|
||||
* - A successful message if the connection has worked.
|
||||
*
|
||||
* @param int $backpackid The backpack identifier.
|
||||
* @return string A message with the validation result.
|
||||
*/
|
||||
public function render_test_backpack_result(int $backpackid): string {
|
||||
// Get the backpack.
|
||||
$backpack = badges_get_site_backpack($backpackid);
|
||||
|
||||
// Add the header to the result.
|
||||
$result = $this->heading(get_string('testbackpack', 'badges', $backpack->backpackweburl));
|
||||
|
||||
if ($backpack->apiversion != OPEN_BADGES_V2) {
|
||||
// Only OBv2 supports this validation.
|
||||
$result .= get_string('backpackconnectionnottested', 'badges');
|
||||
} else {
|
||||
$message = badges_verify_backpack($backpackid);
|
||||
if (empty($message)) {
|
||||
$result .= get_string('backpackconnectionok', 'badges');
|
||||
} else {
|
||||
$result .= $message;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
Example context (json):
|
||||
{
|
||||
"backpacks": [
|
||||
{"backpackweburl": "http://localhost/", "sitebackpack": true, "canedit": false}
|
||||
],
|
||||
"warning": "<span class='text-warning'>Could not login</span>"
|
||||
{"backpackweburl": "http://localhost/", "sitebackpack": true, "canedit": false, "cantest": true}
|
||||
]
|
||||
}
|
||||
}}
|
||||
<table class="generaltable fullwidth">
|
||||
@@ -46,13 +45,15 @@
|
||||
<td> {{#sitebackpack}}Yes{{/sitebackpack}} </td>
|
||||
<td>
|
||||
{{#canedit}}
|
||||
<a href="{{baseurl}}?id={{id}}&action=edit">
|
||||
{{#str}}editsettings, core_badges{{/str}}
|
||||
</a>
|
||||
<a href="{{baseurl}}?id={{id}}&action=edit">{{#pix}}t/edit, core,{{#str}}editsettings{{/str}}{{/pix}}</a>
|
||||
{{/canedit}}
|
||||
{{#cantest}}
|
||||
<a href="{{baseurl}}?id={{id}}&action=test">
|
||||
{{#pix}}t/check, core,{{#str}}testsettings, core_badges{{/str}}{{/pix}}
|
||||
</a>
|
||||
{{/cantest}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/backpacks}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{{warning}}}
|
||||
|
||||
@@ -342,13 +342,13 @@ class block_activity_results extends block_base {
|
||||
|
||||
$rank = 0;
|
||||
if (!empty($best)) {
|
||||
$this->content->text .= '<table class="grades"><caption>';
|
||||
$this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
|
||||
if ($numbest == 1) {
|
||||
$this->content->text .= get_string('bestgroupgrade', 'block_activity_results');
|
||||
} else {
|
||||
$this->content->text .= get_string('bestgroupgrades', 'block_activity_results', $numbest);
|
||||
}
|
||||
$this->content->text .= '</caption><colgroup class="number" />';
|
||||
$this->content->text .= '</h6></caption><colgroup class="number" />';
|
||||
$this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
|
||||
foreach ($best as $groupid => $averagegrade) {
|
||||
switch ($nameformat) {
|
||||
@@ -398,13 +398,13 @@ class block_activity_results extends block_base {
|
||||
$rank = 0;
|
||||
if (!empty($worst)) {
|
||||
$worst = array_reverse($worst, true);
|
||||
$this->content->text .= '<table class="grades"><caption>';
|
||||
$this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
|
||||
if ($numworst == 1) {
|
||||
$this->content->text .= get_string('worstgroupgrade', 'block_activity_results');
|
||||
} else {
|
||||
$this->content->text .= get_string('worstgroupgrades', 'block_activity_results', $numworst);
|
||||
}
|
||||
$this->content->text .= '</caption><colgroup class="number" />';
|
||||
$this->content->text .= '</h6></caption><colgroup class="number" />';
|
||||
$this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
|
||||
foreach ($worst as $groupid => $averagegrade) {
|
||||
switch ($nameformat) {
|
||||
@@ -529,13 +529,13 @@ class block_activity_results extends block_base {
|
||||
|
||||
$rank = 0;
|
||||
if (!empty($best)) {
|
||||
$this->content->text .= '<table class="grades"><caption>';
|
||||
$this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
|
||||
if ($numbest == 1) {
|
||||
$this->content->text .= get_string('bestgrade', 'block_activity_results');
|
||||
} else {
|
||||
$this->content->text .= get_string('bestgrades', 'block_activity_results', $numbest);
|
||||
}
|
||||
$this->content->text .= '</caption><colgroup class="number" />';
|
||||
$this->content->text .= '</h6></caption><colgroup class="number" />';
|
||||
$this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
|
||||
foreach ($best as $userid => $gradeid) {
|
||||
switch ($nameformat) {
|
||||
@@ -592,13 +592,13 @@ class block_activity_results extends block_base {
|
||||
$rank = 0;
|
||||
if (!empty($worst)) {
|
||||
$worst = array_reverse($worst, true);
|
||||
$this->content->text .= '<table class="grades"><caption>';
|
||||
$this->content->text .= '<table class="grades"><caption class="pb-0"><h6>';
|
||||
if ($numbest == 1) {
|
||||
$this->content->text .= get_string('worstgrade', 'block_activity_results');
|
||||
} else {
|
||||
$this->content->text .= get_string('worstgrades', 'block_activity_results', $numworst);
|
||||
}
|
||||
$this->content->text .= '</caption><colgroup class="number" />';
|
||||
$this->content->text .= '</h6></caption><colgroup class="number" />';
|
||||
$this->content->text .= '<colgroup class="name" /><colgroup class="grade" /><tbody>';
|
||||
foreach ($worst as $userid => $gradeid) {
|
||||
switch ($nameformat) {
|
||||
@@ -678,17 +678,17 @@ class block_activity_results extends block_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the Link to the activity module when displaed outside of the module
|
||||
* Generates the Link to the activity module when displayed outside of the module.
|
||||
* @param stdclass $activity
|
||||
* @param stdclass $cm
|
||||
* @return string
|
||||
*/
|
||||
private function activity_link($activity, $cm) {
|
||||
|
||||
$o = html_writer::start_tag('h3');
|
||||
$o = html_writer::start_tag('h5');
|
||||
$o .= html_writer::link(new moodle_url('/mod/'.$activity->itemmodule.'/view.php',
|
||||
array('id' => $cm->id)), format_string(($activity->itemname), true, ['context' => context_module::instance($cm->id)]));
|
||||
$o .= html_writer::end_tag('h3');
|
||||
$o .= html_writer::end_tag('h5');
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,3 @@
|
||||
.block_activity_results table.grades .grade {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.block_activity_results table.grades caption {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
@@ -99,10 +99,14 @@ class block_blog_menu extends block_base {
|
||||
// Prepare the footer for this block
|
||||
if (has_capability('moodle/blog:search', context_system::instance())) {
|
||||
// Full-text search field
|
||||
$form = html_writer::tag('label', get_string('search', 'admin'), array('for'=>'blogsearchquery', 'class'=>'accesshide'));
|
||||
$form .= html_writer::empty_tag('input', array('id'=>'blogsearchquery', 'type'=>'text', 'name'=>'search'));
|
||||
$form .= html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('search')));
|
||||
$this->content->footer = html_writer::tag('form', html_writer::tag('div', $form), array('class'=>'blogsearchform', 'method'=>'get', 'action'=>new moodle_url('/blog/index.php')));
|
||||
$form = html_writer::tag('label', get_string('search', 'admin'), array('for' => 'blogsearchquery',
|
||||
'class' => 'accesshide'));
|
||||
$form .= html_writer::empty_tag('input', array('id' => 'blogsearchquery', 'class' => 'form-control mr-1',
|
||||
'type' => 'text', 'name' => 'search'));
|
||||
$form .= html_writer::empty_tag('input', array('type' => 'submit', 'class' => 'btn btn-secondary',
|
||||
'value' => get_string('search')));
|
||||
$this->content->footer = html_writer::tag('form', html_writer::tag('div', $form), array(
|
||||
'class' => 'blogsearchform form-inline', 'method' => 'get', 'action' => new moodle_url('/blog/index.php')));
|
||||
} else {
|
||||
// No footer to display
|
||||
$this->content->footer = '';
|
||||
|
||||
@@ -221,6 +221,11 @@ class block_base {
|
||||
public function get_content_for_output($output) {
|
||||
global $CFG;
|
||||
|
||||
// We can exit early if the current user doesn't have the capability to view the block.
|
||||
if (!has_capability('moodle/block:view', $this->context)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$bc = new block_contents($this->html_attributes());
|
||||
$bc->attributes['data-block'] = $this->name();
|
||||
$bc->blockinstanceid = $this->instance->id;
|
||||
|
||||
@@ -267,9 +267,11 @@ class core_block_externallib_testcase extends externallib_advanced_testcase {
|
||||
$returnedblocks[] = $block['name'];
|
||||
// Check the configuration returned for this default block.
|
||||
if ($block['name'] == 'recentlyaccessedcourses') {
|
||||
$this->assertEquals('displaycategories', $block['configs'][0]['name']);
|
||||
$this->assertEquals(json_encode('0'), $block['configs'][0]['value']);
|
||||
$this->assertEquals('plugin', $block['configs'][0]['type']);
|
||||
// Convert config to associative array to avoid DB sorting randomness.
|
||||
$config = array_column($block['configs'], null, 'name');
|
||||
$this->assertArrayHasKey('displaycategories', $config);
|
||||
$this->assertEquals(json_encode('0'), $config['displaycategories']['value']);
|
||||
$this->assertEquals('plugin', $config['displaycategories']['type']);
|
||||
}
|
||||
}
|
||||
// Remove lp block.
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("core_calendar/calendar_filter",["jquery","core_calendar/selectors","core_calendar/events","core/str","core/templates"],function(a,b,c,d,e){var f=function(d){d.on("click",b.eventFilterItem,function(b){var c=a(b.currentTarget);g(c);b.preventDefault()});a("body").on(c.viewUpdated,function(){var c=d.find(b.eventFilterItem);c.each(function(b,c){c=a(c);if(c.data("eventtype-hidden")){var d=i(c);h(d)}})})},g=function(a){var b=i(a);b.hidden=!b.hidden;return d.get_string("eventtype"+b.eventtype,"calendar").then(function(a){b.name=a;b.icon=!0;b.key="i/"+b.eventtype+"event";b.component="core";return b}).then(function(a){return e.render("core_calendar/event_filter_key",a)}).then(function(b,c){return e.replaceNode(a,b,c)}).then(function(){h(b)})},h=function(b){M.util.js_pending("month-mini-filterChanged");a("body").trigger(c.filterChanged,{type:b.eventtype,hidden:b.hidden});M.util.js_complete("month-mini-filterChanged")},i=function(a){return{eventtype:a.data("eventtype"),hidden:a.data("eventtype-hidden")}};return{init:function init(b){b=a(b);f(b)}}});
|
||||
define ("core_calendar/calendar_filter",["jquery","core_calendar/selectors","core_calendar/events","core/str","core/templates"],function(a,b,c,d,e){var f=function(d){d.on("click",b.eventFilterItem,function(b){var c=a(b.currentTarget);g(c);b.preventDefault()});a("body").on(c.viewUpdated,function(){var c=d.find(b.eventFilterItem);c.each(function(b,c){c=a(c);if(c.data("eventtype-hidden")){var d=i(c);h(d)}})})},g=function(a){var b=i(a);b.hidden=!b.hidden;M.util.js_pending("core_calendar/calendar_filter:toggleFilter");return d.get_string("eventtype"+b.eventtype,"calendar").then(function(a){b.name=a;b.icon=!0;b.key="i/"+b.eventtype+"event";b.component="core";return b}).then(function(a){return e.render("core_calendar/event_filter_key",a)}).then(function(b,c){return e.replaceNode(a,b,c)}).then(function(){h(b);M.util.js_complete("core_calendar/calendar_filter:toggleFilter")})},h=function(b){M.util.js_pending("month-mini-filterChanged");a("body").trigger(c.filterChanged,{type:b.eventtype,hidden:b.hidden});M.util.js_complete("month-mini-filterChanged")},i=function(a){return{eventtype:a.data("eventtype"),hidden:a.data("eventtype-hidden")}};return{init:function init(b){b=a(b);f(b)}}});
|
||||
//# sourceMappingURL=calendar_filter.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("core_calendar/crud",["jquery","core/str","core/notification","core/custom_interaction_events","core/modal","core/modal_registry","core/modal_factory","core/modal_events","core_calendar/modal_event_form","core_calendar/repository","core_calendar/events","core_calendar/modal_delete","core_calendar/selectors","core/pending"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){function o(d,e,f){var i=[{key:"deleteevent",component:"calendar"}];f=parseInt(f,10);var m,o=1<f;if(o){i.push({key:"confirmeventseriesdelete",component:"calendar",param:{name:e,count:f}});m=g.create({type:l.TYPE})}else{i.push({key:"confirmeventdelete",component:"calendar",param:e});m=g.create({type:g.types.SAVE_CANCEL})}var p=b.get_strings(i),q=a.when(p,m).then(function(b,e){e.setTitle(b[0]);e.setBody(b[1]);if(!o){e.setSaveButtonText(b[0])}e.show();e.getRoot().on(h.save,function(){var b=new n("calendar/crud:initModal:deletedevent");j.deleteEvent(d,!1).then(function(){a("body").trigger(k.deleted,[d,!1])}).then(b.resolve).catch(c.exception)});e.getRoot().on(k.deleteAll,function(){var b=new n("calendar/crud:initModal:deletedallevent");j.deleteEvent(d,!0).then(function(){a("body").trigger(k.deleted,[d,!0])}).then(b.resolve).catch(c.exception)});return e}).catch(c.exception);return q}return{registerRemove:function(b){b.on("click",m.actions.remove,function(b){var c=a(this).closest(m.eventItem),d=c.data("eventId"),e=c.data("eventTitle"),f=c.data("eventCount");o(d,e,f);b.preventDefault()})},registerEditListeners:function(b,d){d.then(function(c){a("body").on(k.editEvent,function(a,d){var e=b.find(m.wrapper);c.setEventId(d);c.setContextId(e.data("contextId"));c.show();a.stopImmediatePropagation()})}).fail(c.exception);return d},registerEventFormModal:function registerEventFormModal(b){var d=g.create({type:i.TYPE,large:!0});b.on("click",m.actions.create,function(a){d.then(function(a){var c=b.find(m.wrapper),d=c.data("categoryid");if("undefined"!=typeof d){a.setCategoryId(d)}var e=b.find(m.today),f=b.find(m.day);if(!e.length&&f.length){a.setStartTime(f.data("newEventTimestamp"))}a.setContextId(c.data("contextId"));a.setCourseId(c.data("courseid"));a.show()}).fail(c.exception);a.preventDefault()});b.on("click",m.actions.edit,function(b){b.preventDefault();var e=a(b.currentTarget),f=e.closest(m.wrapper),g=e.closest(m.eventItem);d.then(function(a){a.setEventId(g.data("eventId"));a.setContextId(f.data("contextId"));a.show();b.stopImmediatePropagation()}).fail(c.exception)});return d}}});
|
||||
define ("core_calendar/crud",["jquery","core/str","core/notification","core/custom_interaction_events","core/modal","core/modal_registry","core/modal_factory","core/modal_events","core_calendar/modal_event_form","core_calendar/repository","core_calendar/events","core_calendar/modal_delete","core_calendar/selectors","core/pending"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){function o(d,e,f){var i=[{key:"deleteevent",component:"calendar"}];f=parseInt(f,10);var m,o=1<f;if(o){i.push({key:"confirmeventseriesdelete",component:"calendar",param:{name:e,count:f}});m=g.create({type:l.TYPE})}else{i.push({key:"confirmeventdelete",component:"calendar",param:e});m=g.create({type:g.types.SAVE_CANCEL})}var p=b.get_strings(i),q=a.when(p,m).then(function(b,e){e.setTitle(b[0]);e.setBody(b[1]);if(!o){e.setSaveButtonText(b[0])}e.show();e.getRoot().on(h.save,function(){var b=new n("calendar/crud:initModal:deletedevent");j.deleteEvent(d,!1).then(function(){a("body").trigger(k.deleted,[d,!1])}).then(b.resolve).catch(c.exception)});e.getRoot().on(k.deleteAll,function(){var b=new n("calendar/crud:initModal:deletedallevent");j.deleteEvent(d,!0).then(function(){a("body").trigger(k.deleted,[d,!0])}).then(b.resolve).catch(c.exception)});return e}).catch(c.exception);return q}return{registerRemove:function(b){b.on("click",m.actions.remove,function(b){var c=a(this).closest(m.eventItem),d=c.data("eventId"),e=c.data("eventTitle"),f=c.data("eventCount");o(d,e,f);b.preventDefault()})},registerEditListeners:function(b,d){var e=new n("core_calendar/crud:registerEditListeners");return d.then(function(c){a("body").on(k.editEvent,function(a,d){var e=b.find(m.wrapper);c.setEventId(d);c.setContextId(e.data("contextId"));c.show();a.stopImmediatePropagation()});return c}).then(function(a){e.resolve();return a}).catch(c.exception)},registerEventFormModal:function registerEventFormModal(b){var d=g.create({type:i.TYPE,large:!0});b.on("click",m.actions.create,function(a){d.then(function(a){var c=b.find(m.wrapper),d=c.data("categoryid");if("undefined"!=typeof d){a.setCategoryId(d)}var e=b.find(m.today),f=b.find(m.day);if(!e.length&&f.length){a.setStartTime(f.data("newEventTimestamp"))}a.setContextId(c.data("contextId"));a.setCourseId(c.data("courseid"));a.show()}).fail(c.exception);a.preventDefault()});b.on("click",m.actions.edit,function(b){b.preventDefault();var e=a(b.currentTarget),f=e.closest(m.wrapper),g=e.closest(m.eventItem);d.then(function(a){a.setEventId(g.data("eventId"));a.setContextId(f.data("contextId"));a.show();b.stopImmediatePropagation()}).fail(c.exception)});return d}}});
|
||||
//# sourceMappingURL=crud.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("core_calendar/summary_modal",["jquery","core/str","core/notification","core/custom_interaction_events","core/modal","core/modal_registry","core/modal_factory","core/modal_events","core_calendar/repository","core_calendar/events","core_calendar/crud"],function(a,b,c,d,e,f,g,h,i,j,k){var l=!1,m={ROOT:"[data-region='summary-modal-container']",EDIT_BUTTON:"[data-action=\"edit\"]",DELETE_BUTTON:"[data-action=\"delete\"]"},n=function(a){e.call(this,a)};n.TYPE="core_calendar-event_summary";n.prototype=Object.create(e.prototype);n.prototype.constructor=n;n.prototype.getEditButton=function(){if("undefined"==typeof this.editButton){this.editButton=this.getFooter().find(m.EDIT_BUTTON)}return this.editButton};n.prototype.getDeleteButton=function(){if("undefined"==typeof this.deleteButton){this.deleteButton=this.getFooter().find(m.DELETE_BUTTON)}return this.deleteButton};n.prototype.getEventId=function(){return this.getBody().find(m.ROOT).attr("data-event-id")};n.prototype.getEventTitle=function(){return this.getBody().find(m.ROOT).attr("data-event-title")};n.prototype.getEventCount=function(){return this.getBody().find(m.ROOT).attr("data-event-count")};n.prototype.getEditUrl=function(){return this.getBody().find(m.ROOT).attr("data-edit-url")};n.prototype.isActionEvent=function(){return"true"==this.getBody().find(m.ROOT).attr("data-action-event")};n.prototype.registerEventListeners=function(){e.prototype.registerEventListeners.call(this);this.getRoot().on(h.bodyRendered,function(){this.getModal().data({eventTitle:this.getEventTitle(),eventId:this.getEventId(),eventCount:this.getEventCount()}).attr("data-type","event");k.registerRemove(this.getModal())}.bind(this));a("body").on(j.deleted,function(){this.hide()}.bind(this));d.define(this.getEditButton(),[d.events.activate]);this.getEditButton().on(d.events.activate,function(b,c){if(this.isActionEvent()){a("body").trigger(j.editActionEvent,[this.getEditUrl()])}else{a("body").trigger(j.editEvent,[this.getEventId()])}this.hide();b.preventDefault();b.stopPropagation();c.originalEvent.preventDefault();c.originalEvent.stopPropagation()}.bind(this))};if(!l){f.register(n.TYPE,n,"core_calendar/event_summary_modal");l=!0}return n});
|
||||
define ("core_calendar/summary_modal",["jquery","core/str","core/notification","core/custom_interaction_events","core/modal","core/modal_registry","core/modal_factory","core/modal_events","core_calendar/repository","core_calendar/events","core_calendar/crud"],function(a,b,c,d,e,f,g,h,i,j,k){var l=!1,m={ROOT:"[data-region='summary-modal-container']",EDIT_BUTTON:"[data-action=\"edit\"]",DELETE_BUTTON:"[data-action=\"delete\"]"},n=function(a){e.call(this,a)};n.TYPE="core_calendar-event_summary";n.prototype=Object.create(e.prototype);n.prototype.constructor=n;n.prototype.getEditButton=function(){if("undefined"==typeof this.editButton){this.editButton=this.getFooter().find(m.EDIT_BUTTON)}return this.editButton};n.prototype.getDeleteButton=function(){if("undefined"==typeof this.deleteButton){this.deleteButton=this.getFooter().find(m.DELETE_BUTTON)}return this.deleteButton};n.prototype.getEventId=function(){return this.getBody().find(m.ROOT).attr("data-event-id")};n.prototype.getEventTitle=function(){return this.getBody().find(m.ROOT).attr("data-event-title")};n.prototype.getEventCount=function(){return this.getBody().find(m.ROOT).attr("data-event-count")};n.prototype.getEditUrl=function(){return this.getBody().find(m.ROOT).attr("data-edit-url")};n.prototype.isActionEvent=function(){return"true"==this.getBody().find(m.ROOT).attr("data-action-event")};n.prototype.registerEventListeners=function(){e.prototype.registerEventListeners.call(this);M.util.js_pending("core_calendar/summary_modal:registerEventListeners:bodyRendered");this.getRoot().on(h.bodyRendered,function(){this.getModal().data({eventTitle:this.getEventTitle(),eventId:this.getEventId(),eventCount:this.getEventCount()}).attr("data-type","event");k.registerRemove(this.getModal());M.util.js_complete("core_calendar/summary_modal:registerEventListeners:bodyRendered")}.bind(this));a("body").on(j.deleted,function(){this.hide()}.bind(this));d.define(this.getEditButton(),[d.events.activate]);this.getEditButton().on(d.events.activate,function(b,c){if(this.isActionEvent()){a("body").trigger(j.editActionEvent,[this.getEditUrl()])}else{a("body").trigger(j.editEvent,[this.getEventId()])}this.hide();b.preventDefault();b.stopPropagation();c.originalEvent.preventDefault();c.originalEvent.stopPropagation()}.bind(this))};if(!l){f.register(n.TYPE,n,"core_calendar/event_summary_modal");l=!0}return n});
|
||||
//# sourceMappingURL=summary_modal.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -64,6 +64,7 @@ function(
|
||||
// Toggle the hidden. We need to render the template before we change the value.
|
||||
data.hidden = !data.hidden;
|
||||
|
||||
M.util.js_pending("core_calendar/calendar_filter:toggleFilter");
|
||||
return Str.get_string('eventtype' + data.eventtype, 'calendar')
|
||||
.then(function(nameStr) {
|
||||
data.name = nameStr;
|
||||
@@ -81,6 +82,7 @@ function(
|
||||
})
|
||||
.then(function() {
|
||||
fireFilterChangedEvent(data);
|
||||
M.util.js_complete("core_calendar/calendar_filter:toggleFilter");
|
||||
return;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -234,7 +234,9 @@ function(
|
||||
* @returns {Promise}
|
||||
*/
|
||||
function registerEditListeners(root, eventFormModalPromise) {
|
||||
eventFormModalPromise
|
||||
var pendingPromise = new Pending('core_calendar/crud:registerEditListeners');
|
||||
|
||||
return eventFormModalPromise
|
||||
.then(function(modal) {
|
||||
// When something within the calendar tells us the user wants
|
||||
// to edit an event then show the event form modal.
|
||||
@@ -246,11 +248,14 @@ function(
|
||||
|
||||
e.stopImmediatePropagation();
|
||||
});
|
||||
return;
|
||||
return modal;
|
||||
})
|
||||
.fail(Notification.exception);
|
||||
.then(function(modal) {
|
||||
pendingPromise.resolve();
|
||||
|
||||
return eventFormModalPromise;
|
||||
return modal;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -165,6 +165,7 @@ function(
|
||||
|
||||
// We have to wait for the modal to finish rendering in order to ensure that
|
||||
// the data-event-title property is available to use as the modal title.
|
||||
M.util.js_pending('core_calendar/summary_modal:registerEventListeners:bodyRendered');
|
||||
this.getRoot().on(ModalEvents.bodyRendered, function() {
|
||||
this.getModal().data({
|
||||
eventTitle: this.getEventTitle(),
|
||||
@@ -173,7 +174,7 @@ function(
|
||||
})
|
||||
.attr('data-type', 'event');
|
||||
CalendarCrud.registerRemove(this.getModal());
|
||||
|
||||
M.util.js_complete('core_calendar/summary_modal:registerEventListeners:bodyRendered');
|
||||
}.bind(this));
|
||||
|
||||
$('body').on(CalendarEvents.deleted, function() {
|
||||
|
||||
@@ -33,6 +33,7 @@ define([
|
||||
'core/modal_events',
|
||||
'core_calendar/summary_modal',
|
||||
'core/custom_interaction_events',
|
||||
'core/pending',
|
||||
], function(
|
||||
$,
|
||||
Templates,
|
||||
@@ -44,7 +45,8 @@ define([
|
||||
ModalFactory,
|
||||
ModalEvents,
|
||||
SummaryModal,
|
||||
CustomEvents
|
||||
CustomEvents,
|
||||
Pending
|
||||
) {
|
||||
|
||||
/**
|
||||
@@ -57,6 +59,7 @@ define([
|
||||
|
||||
// Bind click events to event links.
|
||||
root.on('click', CalendarSelectors.links.eventLink, function(e) {
|
||||
var pendingPromise = new Pending('core_calendar/view_manager:eventLink:click');
|
||||
var target = $(e.target);
|
||||
var eventId = null;
|
||||
|
||||
@@ -81,7 +84,11 @@ define([
|
||||
// and causing the day click handler to fire.
|
||||
e.stopPropagation();
|
||||
|
||||
renderEventSummaryModal(eventId);
|
||||
renderEventSummaryModal(eventId)
|
||||
.then(pendingPromise.resolve())
|
||||
.catch();
|
||||
} else {
|
||||
pendingPromise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -358,8 +365,8 @@ define([
|
||||
* @param {object} root The container element.
|
||||
* @param {Number} courseId The course id.
|
||||
* @param {Number} categoryId The id of the category whose events are shown
|
||||
* @param {String} template The template to be rendered.
|
||||
* @param {object} target The element being replaced. If not specified, the calendarwrapper is used.
|
||||
* @param {String} template The template to be rendered.
|
||||
* @return {promise}
|
||||
*/
|
||||
var reloadCurrentUpcoming = function(root, courseId, categoryId, target, template) {
|
||||
@@ -408,12 +415,15 @@ define([
|
||||
* Render the event summary modal.
|
||||
*
|
||||
* @param {Number} eventId The calendar event id.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
var renderEventSummaryModal = function(eventId) {
|
||||
var pendingPromise = new Pending('core_calendar/view_manager:renderEventSummaryModal');
|
||||
var typeClass = '';
|
||||
|
||||
// Calendar repository promise.
|
||||
CalendarRepository.getEventById(eventId).then(function(getEventResponse) {
|
||||
return CalendarRepository.getEventById(eventId)
|
||||
.then(function(getEventResponse) {
|
||||
if (!getEventResponse.event) {
|
||||
throw new Error('Error encountered while trying to fetch calendar event with ID: ' + eventId);
|
||||
}
|
||||
@@ -439,7 +449,8 @@ define([
|
||||
// Create the modal.
|
||||
return ModalFactory.create(modalParams);
|
||||
|
||||
}).done(function(modal) {
|
||||
})
|
||||
.then(function(modal) {
|
||||
// Handle hidden event.
|
||||
modal.getRoot().on(ModalEvents.hidden, function() {
|
||||
// Destroy when hidden.
|
||||
@@ -449,7 +460,14 @@ define([
|
||||
// Finally, render the modal!
|
||||
modal.show();
|
||||
|
||||
}).fail(Notification.exception);
|
||||
return modal;
|
||||
})
|
||||
.then(function(modal) {
|
||||
pendingPromise.resolve();
|
||||
|
||||
return modal;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-9
@@ -839,13 +839,6 @@ $CFG->admin = 'admin';
|
||||
// ),
|
||||
// );
|
||||
//
|
||||
// You can force the browser session (not user's sessions) to restart after N seconds. This could
|
||||
// be useful if you are using a cloud-based service with time restrictions in the browser side.
|
||||
// Setting this value the browser session that Behat is using will be restarted. Set the time in
|
||||
// seconds. Is not recommended to use this setting if you don't explicitly need it.
|
||||
// Example:
|
||||
// $CFG->behat_restart_browser_after = 7200; // Restarts the browser session after 2 hours
|
||||
//
|
||||
// All this page's extra Moodle settings are compared against a white list of allowed settings
|
||||
// (the basic and behat_* ones) to avoid problems with production environments. This setting can be
|
||||
// used to expand the default white list with an array of extra settings.
|
||||
@@ -922,8 +915,8 @@ $CFG->admin = 'admin';
|
||||
// Example:
|
||||
// define('BEHAT_DISABLE_HISTOGRAM', true);
|
||||
//
|
||||
// Mobile app Behat testing requires this option, pointing to a developer Moodle Mobile directory:
|
||||
// $CFG->behat_ionic_dirroot = '/where/I/keep/my/git/checkouts/moodlemobile2';
|
||||
// Mobile app Behat testing requires this option, pointing to a developer Moodle app directory:
|
||||
// $CFG->behat_ionic_dirroot = '/where/I/keep/my/git/checkouts/moodleapp';
|
||||
//
|
||||
// The following option can be used to indicate a running Ionic server (otherwise Behat will start
|
||||
// one automatically for each test run, which is convenient but takes ages):
|
||||
|
||||
@@ -1565,7 +1565,10 @@ class core_course_category implements renderable, cacheable_object, IteratorAggr
|
||||
}
|
||||
// Prepare the list of core_course_list_element objects.
|
||||
foreach ($ids as $id) {
|
||||
$courses[$id] = new core_course_list_element($records[$id]);
|
||||
// If a course is deleted after we got the cache entry it may not exist in the database anymore.
|
||||
if (!empty($records[$id])) {
|
||||
$courses[$id] = new core_course_list_element($records[$id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $courses;
|
||||
@@ -1775,7 +1778,10 @@ class core_course_category implements renderable, cacheable_object, IteratorAggr
|
||||
}
|
||||
// Prepare the list of core_course_list_element objects.
|
||||
foreach ($ids as $id) {
|
||||
$courses[$id] = new core_course_list_element($records[$id]);
|
||||
// If a course is deleted after we got the cache entry it may not exist in the database anymore.
|
||||
if (!empty($records[$id])) {
|
||||
$courses[$id] = new core_course_list_element($records[$id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $courses;
|
||||
|
||||
+1
-1
@@ -2568,7 +2568,7 @@ function update_course($data, $editoroptions = NULL) {
|
||||
// The summary might be very long, we don't wan't to fill up the log record with the full text.
|
||||
$updatedfields[$field] = '(updated)';
|
||||
}
|
||||
} else if ($field == 'tags' && !empty($CFG->usetags)) {
|
||||
} else if ($field == 'tags' && isset($data->tags)) {
|
||||
// Tags might not have the same array keys, just check the values.
|
||||
if (array_values($data->$field) !== array_values($value)) {
|
||||
$updatedfields[$field] = $data->$field;
|
||||
|
||||
+15
-1
@@ -277,6 +277,13 @@ function edit_module_post_actions($moduleinfo, $course) {
|
||||
if ($update) {
|
||||
$item->update();
|
||||
}
|
||||
|
||||
if (!empty($moduleinfo->add)) {
|
||||
$gradecategory = $item->get_parent_category();
|
||||
if ($item->set_aggregation_fields_for_aggregation(0, $gradecategory->aggregation)) {
|
||||
$item->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,8 +305,8 @@ function edit_module_post_actions($moduleinfo, $course) {
|
||||
|
||||
if (property_exists($moduleinfo, $elname) and $moduleinfo->$elname) {
|
||||
// Check if this is a new outcome grade item.
|
||||
$outcomeexists = false;
|
||||
if ($items) {
|
||||
$outcomeexists = false;
|
||||
foreach($items as $item) {
|
||||
if ($item->outcomeid == $outcome->id) {
|
||||
$outcomeexists = true;
|
||||
@@ -333,6 +340,13 @@ function edit_module_post_actions($moduleinfo, $course) {
|
||||
} else if (isset($moduleinfo->gradecat)) {
|
||||
$outcomeitem->set_parent($moduleinfo->gradecat);
|
||||
}
|
||||
|
||||
if (!$outcomeexists) {
|
||||
$gradecategory = $outcomeitem->get_parent_category();
|
||||
if ($outcomeitem->set_aggregation_fields_for_aggregation(0, $gradecategory->aggregation)) {
|
||||
$outcomeitem->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1080,4 +1080,26 @@ class core_course_category_testcase extends advanced_testcase {
|
||||
}
|
||||
return $draftid;
|
||||
}
|
||||
|
||||
/**
|
||||
* This test ensures that is the list of courses in a category can be retrieved while a course is being deleted.
|
||||
*/
|
||||
public function test_get_courses_during_delete() {
|
||||
global $DB;
|
||||
$category = self::getDataGenerator()->create_category();
|
||||
$course = self::getDataGenerator()->create_course(['category' => $category->id]);
|
||||
$othercourse = self::getDataGenerator()->create_course(['category' => $category->id]);
|
||||
$coursecategory = core_course_category::get($category->id);
|
||||
// Get a list of courses before deletion to populate the cache.
|
||||
$originalcourses = $coursecategory->get_courses();
|
||||
$this->assertCount(2, $originalcourses);
|
||||
$this->assertArrayHasKey($course->id, $originalcourses);
|
||||
$this->assertArrayHasKey($othercourse->id, $originalcourses);
|
||||
// Simulate the course deletion process being part way though.
|
||||
$DB->delete_records('course', ['id' => $course->id]);
|
||||
// Get the list of courses while a deletion is in progress.
|
||||
$courses = $coursecategory->get_courses();
|
||||
$this->assertCount(1, $courses);
|
||||
$this->assertArrayHasKey($othercourse->id, $courses);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ $string['categoryseparator'] = 'Category separator character';
|
||||
$string['categoryseparator_desc'] = 'Required when "Category idnumber" is enabled. Character to separate the category name and idnumber.';
|
||||
$string['coursesettings'] = 'Course data options';
|
||||
$string['createnewcategories'] = 'Create new (hidden) course categories if not found in Moodle';
|
||||
$string['createnewcategories_desc'] = 'If the <org><orgunit> element is present in a course\'s incoming data, its content will be used to specify a category if the course is to be created from scratch. The plugin will NOT re-categorise existing courses.
|
||||
$string['createnewcategories_desc'] = 'If the <org><orgunit> element is present in a course\'s incoming data, its content will be used to specify a category if the course is to be created from scratch. The plugin will NOT re-categorise existing courses.
|
||||
|
||||
If no category exists with the desired name, then a hidden category will be created.';
|
||||
$string['createnewcourses'] = 'Create new (hidden) courses if not found in Moodle';
|
||||
|
||||
@@ -99,6 +99,13 @@ switch ($action) {
|
||||
|
||||
if (empty($roleid)) {
|
||||
$roleid = null;
|
||||
} else {
|
||||
if (!has_capability('moodle/role:assign', $context)) {
|
||||
throw new enrol_ajax_exception('assignnotpermitted');
|
||||
}
|
||||
if (!array_key_exists($roleid, get_assignable_roles($context, ROLENAME_ALIAS, false))) {
|
||||
throw new enrol_ajax_exception('invalidrole');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($startdate)) {
|
||||
|
||||
@@ -137,6 +137,10 @@ if (!$edit) {
|
||||
redirect($returnurl);
|
||||
|
||||
} else if ($data = $mform->get_data()) {
|
||||
|
||||
// Make sure we are updating the cache.
|
||||
$cache = cache::make('core', 'grade_letters');
|
||||
|
||||
if (!$admin and empty($data->override)) {
|
||||
$records = $DB->get_records('grade_letters', array('contextid' => $context->id));
|
||||
foreach ($records as $record) {
|
||||
@@ -148,6 +152,9 @@ if (!$edit) {
|
||||
));
|
||||
$event->trigger();
|
||||
}
|
||||
|
||||
// Make sure we clear the cache for this context.
|
||||
$cache->delete($context->id);
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
@@ -222,6 +229,15 @@ if (!$edit) {
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the changed letters.
|
||||
if (!empty($letters)) {
|
||||
|
||||
// For some reason, the cache saves it in the order in which they were entered
|
||||
// but we really want to order them in descending order so we sort it here.
|
||||
krsort($letters);
|
||||
$cache->set($context->id, $letters);
|
||||
}
|
||||
|
||||
// Delete the unused records.
|
||||
foreach($pool as $leftover) {
|
||||
$DB->delete_records('grade_letters', array('id' => $leftover->id));
|
||||
|
||||
@@ -37,13 +37,14 @@
|
||||
if (has_capability('moodle/grade:manageoutcomes', $context)) {
|
||||
?>
|
||||
<td class="p-l-1 p-r-1">
|
||||
<p class="arrow_button">
|
||||
<input name="add" class="btn btn_secondary" id="add" type="submit" value="<?php echo ' ' . $OUTPUT->larrow() . ' ' .
|
||||
<div class="m-y-1">
|
||||
<input name="add" class="btn btn-secondary" id="add" type="submit" value="<?php echo $OUTPUT->larrow() . ' ' .
|
||||
get_string('add'); ?>" title="<?php print_string('add'); ?>" />
|
||||
<br />
|
||||
<input name="remove" class="btn btn_secondary" id="remove" type="submit" value="<?php echo ' ' . get_string('remove') . ' ' .
|
||||
$OUTPUT->rarrow(); ?>" title="<?php print_string('remove'); ?>" />
|
||||
</p>
|
||||
</div>
|
||||
<div class="m-y-1">
|
||||
<input name="remove" class="btn btn-secondary" id="remove" type="submit" value="<?php echo get_string('remove') .
|
||||
' ' . $OUTPUT->rarrow(); ?>" title="<?php print_string('remove'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<?php } ?>
|
||||
<td>
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
.gradeimport_data_area {
|
||||
margin: 0 0 10px;
|
||||
width: 475px;
|
||||
height: 209px;
|
||||
}
|
||||
+3
-2
@@ -1791,8 +1791,9 @@ class grade_structure {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $OUTPUT->action_icon($url, new pix_icon('t/preview',
|
||||
get_string('gradeanalysis', 'core_grades')));
|
||||
$title = get_string('gradeanalysis', 'core_grades');
|
||||
return $OUTPUT->action_icon($url, new pix_icon('t/preview', ''), null,
|
||||
['title' => $title, 'aria-label' => $title]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+42
-19
@@ -710,24 +710,30 @@ class grade_report_grader extends grade_report {
|
||||
$rows = $this->get_left_icons_row($rows, $colspan);
|
||||
|
||||
$suspendedstring = null;
|
||||
|
||||
$usercount = 0;
|
||||
foreach ($this->users as $userid => $user) {
|
||||
$userrow = new html_table_row();
|
||||
$userrow->id = 'fixed_user_'.$userid;
|
||||
$userrow->attributes['class'] = ($usercount % 2) ? 'userrow even' : 'userrow odd';
|
||||
|
||||
$usercell = new html_table_cell();
|
||||
$usercell->attributes['class'] = 'header user';
|
||||
$usercell->attributes['class'] = ($usercount % 2) ? 'header user even' : 'header user odd';
|
||||
$usercount++;
|
||||
|
||||
$usercell->header = true;
|
||||
$usercell->scope = 'row';
|
||||
|
||||
if ($showuserimage) {
|
||||
$usercell->text = $OUTPUT->user_picture($user, array('visibletoscreenreaders' => false));
|
||||
$usercell->text = $OUTPUT->user_picture($user, ['link' => false, 'visibletoscreenreaders' => false]);
|
||||
}
|
||||
|
||||
$fullname = fullname($user, $viewfullnames);
|
||||
$usercell->text .= html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $this->course->id)), $fullname, array(
|
||||
'class' => 'username',
|
||||
));
|
||||
$usercell->text = html_writer::link(
|
||||
new moodle_url('/user/view.php', ['id' => $user->id, 'course' => $this->course->id]),
|
||||
$usercell->text . $fullname,
|
||||
['class' => 'username']
|
||||
);
|
||||
|
||||
if (!empty($user->suspendedenrolment)) {
|
||||
$usercell->attributes['class'] .= ' usersuspended';
|
||||
@@ -749,13 +755,18 @@ class grade_report_grader extends grade_report {
|
||||
$a = new stdClass();
|
||||
$a->user = $fullname;
|
||||
$strgradesforuser = get_string('gradesforuser', 'grades', $a);
|
||||
$url = new moodle_url('/grade/report/'.$CFG->grade_profilereport.'/index.php', array('userid' => $user->id, 'id' => $this->course->id));
|
||||
$userreportcell->text .= $OUTPUT->action_icon($url, new pix_icon('t/grades', $strgradesforuser));
|
||||
$url = new moodle_url('/grade/report/'.$CFG->grade_profilereport.'/index.php',
|
||||
['userid' => $user->id, 'id' => $this->course->id]);
|
||||
$userreportcell->text .= $OUTPUT->action_icon($url, new pix_icon('t/grades', ''), null,
|
||||
['title' => $strgradesforuser, 'aria-label' => $strgradesforuser]);
|
||||
}
|
||||
|
||||
if ($canseesingleview) {
|
||||
$url = new moodle_url('/grade/report/singleview/index.php', array('id' => $this->course->id, 'itemid' => $user->id, 'item' => 'user'));
|
||||
$singleview = $OUTPUT->action_icon($url, new pix_icon('t/editstring', get_string('singleview', 'grades', $fullname)));
|
||||
$strsingleview = get_string('singleview', 'grades', $fullname);
|
||||
$url = new moodle_url('/grade/report/singleview/index.php',
|
||||
['id' => $this->course->id, 'itemid' => $user->id, 'item' => 'user']);
|
||||
$singleview = $OUTPUT->action_icon($url, new pix_icon('t/editstring', ''), null,
|
||||
['title' => $strsingleview, 'aria-label' => $strsingleview]);
|
||||
$userreportcell->text .= $singleview;
|
||||
}
|
||||
|
||||
@@ -909,13 +920,16 @@ class grade_report_grader extends grade_report {
|
||||
if (has_all_capabilities(array('gradereport/singleview:view', 'moodle/grade:viewall',
|
||||
'moodle/grade:edit'), $this->context)) {
|
||||
|
||||
$strsingleview = get_string('singleview', 'grades', $element['object']->get_name());
|
||||
$url = new moodle_url('/grade/report/singleview/index.php', array(
|
||||
'id' => $this->course->id,
|
||||
'item' => 'grade',
|
||||
'itemid' => $element['object']->id));
|
||||
$singleview = $OUTPUT->action_icon(
|
||||
$url,
|
||||
new pix_icon('t/editstring', get_string('singleview', 'grades', $element['object']->get_name()))
|
||||
$url,
|
||||
new pix_icon('t/editstring', ''),
|
||||
null,
|
||||
['title' => $strsingleview, 'aria-label' => $strsingleview]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1265,7 +1279,8 @@ class grade_report_grader extends grade_report {
|
||||
$fulltable = new html_table();
|
||||
$fulltable->attributes['class'] = 'gradereport-grader-table';
|
||||
$fulltable->id = 'user-grades';
|
||||
$fulltable->summary = get_string('summarygrader', 'gradereport_grader');
|
||||
$fulltable->caption = get_string('summarygrader', 'gradereport_grader');
|
||||
$fulltable->captionhide = true;
|
||||
|
||||
// Extract rows from each side (left and right) and collate them into one row each
|
||||
foreach ($leftrows as $key => $row) {
|
||||
@@ -1633,24 +1648,32 @@ class grade_report_grader extends grade_report {
|
||||
|
||||
if (in_array($element['object']->id, $this->collapsed['aggregatesonly'])) {
|
||||
$url->param('action', 'switch_plus');
|
||||
$icon = $OUTPUT->action_icon($url, new pix_icon('t/switch_plus', $strswitchplus), null, null);
|
||||
$icon = $OUTPUT->action_icon($url, new pix_icon('t/switch_plus', ''), null,
|
||||
['title' => $strswitchplus, 'aria-label' => $strswitchplus]);
|
||||
$showing = get_string('showingaggregatesonly', 'grades');
|
||||
} else if (in_array($element['object']->id, $this->collapsed['gradesonly'])) {
|
||||
$url->param('action', 'switch_whole');
|
||||
$icon = $OUTPUT->action_icon($url, new pix_icon('t/switch_whole', $strswitchwhole), null, null);
|
||||
$icon = $OUTPUT->action_icon($url, new pix_icon('t/switch_whole', ''), null,
|
||||
['title' => $strswitchwhole, 'aria-label' => $strswitchwhole]);
|
||||
$showing = get_string('showinggradesonly', 'grades');
|
||||
} else {
|
||||
$url->param('action', 'switch_minus');
|
||||
$icon = $OUTPUT->action_icon($url, new pix_icon('t/switch_minus', $strswitchminus), null, null);
|
||||
$icon = $OUTPUT->action_icon($url, new pix_icon('t/switch_minus', ''), null,
|
||||
['title' => $strswitchminus, 'aria-label' => $strswitchminus]);
|
||||
$showing = get_string('showingfullmode', 'grades');
|
||||
}
|
||||
}
|
||||
|
||||
$name = $element['object']->get_name();
|
||||
$courseheaderid = 'courseheader_' . clean_param($name, PARAM_ALPHANUMEXT);
|
||||
$courseheader = html_writer::tag('span', $name, array('id' => $courseheaderid,
|
||||
'title' => $name, 'class' => 'gradeitemheader'));
|
||||
$courseheader .= html_writer::label($showing, $courseheaderid, false, array('class' => 'accesshide'));
|
||||
$describedbyid = uniqid();
|
||||
$courseheader = html_writer::tag('span', $name, [
|
||||
'title' => $name,
|
||||
'class' => 'gradeitemheader',
|
||||
'aria-describedby' => $describedbyid
|
||||
]);
|
||||
$courseheader .= html_writer::div($showing, 'sr-only', [
|
||||
'id' => $describedbyid
|
||||
]);
|
||||
$courseheader .= $icon;
|
||||
|
||||
return $courseheader;
|
||||
|
||||
@@ -46,13 +46,6 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stripped table.
|
||||
*/
|
||||
.path-grade-report-grader .gradeparent tr:nth-of-type(even) .cell {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
/**
|
||||
* All the floating divs.
|
||||
*/
|
||||
@@ -75,13 +68,6 @@
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/**
|
||||
* All the floating cells.
|
||||
*/
|
||||
.path-grade-report-grader .gradeparent .floater .cell {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user cells.
|
||||
*/
|
||||
@@ -177,11 +163,6 @@
|
||||
float: left;
|
||||
}
|
||||
|
||||
.path-grade-report .gradeparent .floater .controls.cell,
|
||||
.path-grade-report-grader .gradeparent .controls {
|
||||
background-color: #f3ead8;
|
||||
}
|
||||
|
||||
.path-grade-report-grader .gradeparent .category {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@@ -378,8 +378,9 @@ abstract class grade_report {
|
||||
$this->currentgroup = -2; // means can not access any groups at all
|
||||
}
|
||||
if ($this->currentgroup) {
|
||||
$group = groups_get_group($this->currentgroup);
|
||||
$this->currentgroupname = $group->name;
|
||||
if ($group = groups_get_group($this->currentgroup)) {
|
||||
$this->currentgroupname = $group->name;
|
||||
}
|
||||
$this->groupsql = " JOIN {groups_members} gm ON gm.userid = u.id ";
|
||||
$this->groupwheresql = " AND gm.groupid = :gr_grpid ";
|
||||
$this->groupwheresql_params = array('gr_grpid'=>$this->currentgroup);
|
||||
@@ -416,8 +417,8 @@ abstract class grade_report {
|
||||
$matrix = array('up' => 'desc', 'down' => 'asc', 'move' => 'desc');
|
||||
$strsort = $this->get_lang_string('sort' . $matrix[$direction]);
|
||||
|
||||
$arrow = $OUTPUT->pix_icon($pix[$direction], $strsort, '', array('class' => 'sorticon'));
|
||||
return html_writer::link($sortlink, $arrow, array('title'=>$strsort));
|
||||
$arrow = $OUTPUT->pix_icon($pix[$direction], '', '', ['class' => 'sorticon']);
|
||||
return html_writer::link($sortlink, $arrow, ['title' => $strsort, 'aria-label' => $strsort]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -208,11 +208,12 @@ class grade extends tablelike implements selectable_items, filterable_items {
|
||||
$url = new moodle_url("/user/view.php", array('id' => $item->id, 'course' => $this->courseid));
|
||||
$iconstring = get_string('filtergrades', 'gradereport_singleview', $fullname);
|
||||
$grade->label = $fullname;
|
||||
$userpic = $OUTPUT->user_picture($item, ['link' => false, 'visibletoscreenreaders' => false]);
|
||||
|
||||
$line = array(
|
||||
$OUTPUT->action_icon($this->format_link('user', $item->id), new pix_icon('t/editstring', $iconstring)),
|
||||
$OUTPUT->user_picture($item, array('visibletoscreenreaders' => false)) .
|
||||
html_writer::link($url, $fullname),
|
||||
$OUTPUT->action_icon($this->format_link('user', $item->id), new pix_icon('t/editstring', ''), null,
|
||||
['title' => $iconstring, 'aria-label' => $iconstring]),
|
||||
html_writer::link($url, $userpic . $fullname),
|
||||
$this->item_range()
|
||||
);
|
||||
$lineclasses = array(
|
||||
|
||||
@@ -172,7 +172,8 @@ abstract class tablelike extends screen {
|
||||
|
||||
$summary = $this->summary();
|
||||
if (!empty($summary)) {
|
||||
$table->summary = $summary;
|
||||
$table->caption = $summary;
|
||||
$table->captionhide = true;
|
||||
}
|
||||
|
||||
// To be used for extra formatting.
|
||||
|
||||
@@ -190,7 +190,8 @@ class user extends tablelike implements selectable_items {
|
||||
$grade->label = $item->get_name();
|
||||
|
||||
$line = array(
|
||||
$OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', $iconstring)),
|
||||
$OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', ''), null,
|
||||
['title' => $iconstring, 'aria-label' => $iconstring]),
|
||||
$this->format_icon($item) . $lockicon . $itemlabel,
|
||||
$this->category($item),
|
||||
new range($item)
|
||||
|
||||
@@ -28,6 +28,6 @@
|
||||
"disabled": "true"
|
||||
}
|
||||
}}
|
||||
<label for="{{name}}" class="accesshide">{{label}}</label>
|
||||
{{#label}}<label for="{{name}}" class="accesshide">{{label}}</label>{{/label}}
|
||||
<input id="{{name}}" name="{{name}}" type="text" value="{{value}}" class="form-control" {{#tabindex}}tabindex="{{.}}"{{/tabindex}} {{#disabled}}disabled{{/disabled}}>
|
||||
<input type="hidden" name="old{{name}}" value="{{value}}">
|
||||
|
||||
@@ -203,7 +203,7 @@ class behat_grade extends behat_base {
|
||||
$inputxpath = "//input[@class='idnumber'][" .
|
||||
"parent::li[@class='item'][text()='" . $gradeitem . "']" .
|
||||
" | " .
|
||||
"parent::li[@class='categoryitem' | @class='courseitem']" .
|
||||
"parent::li[@class='categoryitem' or @class='courseitem']" .
|
||||
"/parent::ul/parent::li[starts-with(text(),'" . $gradeitem . "')]" .
|
||||
"]";
|
||||
$this->execute('behat_forms::i_set_the_field_with_xpath_to', array($inputxpath, $idnumber));
|
||||
|
||||
+16
-1
@@ -26,6 +26,8 @@ namespace core_h5p;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use core\lock\lock_config;
|
||||
|
||||
/**
|
||||
* H5P player class, for displaying any local H5P content.
|
||||
*
|
||||
@@ -299,7 +301,20 @@ class player {
|
||||
$onlyupdatelibs = !helper::can_update_library($file);
|
||||
|
||||
// Validate and store the H5P content before displaying it.
|
||||
$h5pid = helper::save_h5p($this->factory, $file, $config, $onlyupdatelibs, false);
|
||||
// Start lock to prevent synchronous access to save the same h5p.
|
||||
$lockfactory = lock_config::get_lock_factory('core_h5p');
|
||||
$lockkey = 'core_h5p_' . $pathnamehash;
|
||||
if ($lock = $lockfactory->get_lock($lockkey, 10)) {
|
||||
try {
|
||||
// Validate and store the H5P content before displaying it.
|
||||
$h5pid = helper::save_h5p($this->factory, $file, $config, $onlyupdatelibs, false);
|
||||
} finally {
|
||||
$lock->release();
|
||||
}
|
||||
} else {
|
||||
$this->core->h5pF->setErrorMessage(get_string('lockh5pdeploy', 'core_h5p'));
|
||||
return false;
|
||||
};
|
||||
if (!$h5pid && $file->get_userid() != $USER->id && has_capability('moodle/h5p:updatelibraries', $this->context)) {
|
||||
// The user has permission to update libraries but the package has been uploaded by a different
|
||||
// user without this permission. Check if there is some missing required library error.
|
||||
|
||||
@@ -80,8 +80,7 @@ $string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
|
||||
$string['welcomep20'] = 'Sie haben das Paket <strong>{$a->packname} {$a->packversion}</strong> erfolgreich auf Ihrem Computer installiert.';
|
||||
$string['welcomep30'] = 'Diese Version von <strong>{$a->installername}</strong> enthält folgende Anwendungen, mit denen Sie <strong>Moodle</strong> ausführen können:';
|
||||
$string['welcomep40'] = 'Das Paket enthält: <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
|
||||
$string['welcomep50'] = 'Die Nutzung dieser Anwendungen ist lizenzrechtlich geprüft. Alle Anwendungen von <strong>{$a->installername}</strong> sind
|
||||
<a href="http://www.opensource.org/docs/definition_plain.html"> Open Source </a> und unterliegen der <a href="http://www.gnu.org/copyleft/gpl.html"> GPL</a> Lizenz.';
|
||||
$string['welcomep50'] = 'Die Verwendung aller Anwendungen in diesem Paket unterliegt den jeweiligen Lizenzen. Das vollständige Paket <strong>{$a->installername}</strong> ist <a href="https://www.opensource.org/docs/definition_plain.html">Open Source</a> und wird unter mit der Lizenz <a href="https://www.gnu.org/copyleft/gpl.html">GPL</a> angeboten.';
|
||||
$string['welcomep60'] = 'Die folgenden Webseiten führen Sie in einfachen Schritten durch die Installation von <strong>Moodle</strong> auf Ihrem Computer. Sie können die vorgeschlagenen Einstellungen übernehmen oder an eigene Bedürfnisse anpassen.';
|
||||
$string['welcomep70'] = 'Klicken Sie auf die Taste \'Weiter\', um mit der Installation von Moodle fortzufahren.';
|
||||
$string['wwwroot'] = 'Webadresse';
|
||||
|
||||
@@ -48,6 +48,6 @@ $string['invalidmd5'] = 'Kontrolerako aldagaia gaizki zegoen - saiatu berriz ere
|
||||
$string['missingrequiredfield'] = 'Beharrezko eremuren bat falta da.';
|
||||
$string['remotedownloaderror'] = '<p>Errorea osagaia zure zerbitzarian jaistean, mesedez egiaztatu proxy-ezarpenak, PHP cURL hedapena erabat gomendatzen da.</p>
|
||||
<p> <a href="{$a->url}">{$a->url}</a> fitxategia eskuz jaitsi beharko zenuke, zure zerbitzariko "{$a->dest}"-ra kopiatu eta bertan deskonprimatu.</p>';
|
||||
$string['wrongdestpath'] = 'Bide desegokia';
|
||||
$string['wrongdestpath'] = 'Helmuga-bide desegokia';
|
||||
$string['wrongsourcebase'] = 'URL iturriaren oinarri akastuna';
|
||||
$string['wrongzipfilename'] = 'ZIP fitxategiaren izen desegokia';
|
||||
|
||||
@@ -45,7 +45,7 @@ $string['datarootpermission'] = 'Datu-direktorioen baimena';
|
||||
$string['dbprefix'] = 'Taulen aurrizkia';
|
||||
$string['dirroot'] = 'Moodle direktorioa';
|
||||
$string['environmenthead'] = 'Zure ingurunea egiaztatzen...';
|
||||
$string['environmentsub2'] = 'Moodleko bertsio bakoitzak PHPko gutxieneko bertsioa eta derrigorrez instalatu beharreko PHP hedapen batzuk ditu. Ingurunearen azterketa oso bat egiten da instalazioa eta eguneraketa bakoitza egin aurretik. Mesedez, jarri harremanetan zerbitzariaren kudeatzailearekin ez badakizu bertsio berria edo PHP hedapenak nola instalatu.';
|
||||
$string['environmentsub2'] = 'Moodleko bertsio bakoitzak PHPko gutxieneko bertsioa eta derrigorrez instalatu beharreko PHP hedapen batzuk ditu. Ingurunearen azterketa oso bat egiten da instalazioa eta eguneratze bakoitza egin aurretik. Mesedez, jarri harremanetan zerbitzariaren kudeatzailearekin ez badakizu bertsio berria edo PHP hedapenak nola instalatu.';
|
||||
$string['errorsinenvironment'] = 'Huts egin du ingurunearen egiaztatzeak!';
|
||||
$string['installation'] = 'Instalazioa';
|
||||
$string['langdownloaderror'] = 'Zoritxarrez "{$a}" hizkuntza ezin izan da jaitsi. Instalazio-prozesuak ingelesez jarraituko du.';
|
||||
|
||||
@@ -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['parentlanguage'] = 'no';
|
||||
$string['thislanguage'] = 'Kvääni';
|
||||
@@ -0,0 +1,35 @@
|
||||
<?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'] = 'w';
|
||||
$string['cliyesnoprompt'] = 'Tape w (pou wi) oswa n (pou non)';
|
||||
@@ -31,6 +31,7 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['language'] = '언어';
|
||||
$string['moodlelogo'] = '무들 로고';
|
||||
$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'] = 'Mirandés';
|
||||
@@ -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['moodlelogo'] = 'د موډل نښان';
|
||||
$string['next'] = 'بل';
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['cannotcreatelangdir'] = 'Ii sáhte ráhkadit máhpa \'lang\'.';
|
||||
$string['cannotcreatetempdir'] = 'Ii sáhttán ráhkadit máhpa \'temp\\';
|
||||
$string['cannotsavemd5file'] = 'Ii sáhte vurket md5-fiilla.';
|
||||
$string['cannotsavezipfile'] = 'Ii sáhte vurket ZIP-fiilla.';
|
||||
$string['wrongzipfilename'] = 'Boasttu ZIP-fiilanamma.';
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['admindirname'] = 'Adminmáhppa';
|
||||
$string['availablelangs'] = 'Giellapáhkat mat leat gávdnamis';
|
||||
$string['chooselanguagehead'] = 'Vállje giela';
|
||||
$string['chooselanguagesub'] = 'Vállje giela (dušše installašuvdnjii). Don sáhtát válljet neahttabáikki ja geavaheaddji giela šearbmagovas maŋŋelaš.';
|
||||
@@ -38,3 +39,4 @@ $string['clialreadyinstalled'] = 'Fiila config.php gávdno jo. Geavat admin/cli/
|
||||
$string['databasename'] = 'Diehtovuođđonamma';
|
||||
$string['langdownloaderror'] = 'Dađibahábut ii installerejuvvon giellapáhkka "{$a}". Installašuvdnaproseassa joatká eaŋgalsgillii.';
|
||||
$string['phpextension'] = '{$a} PHP gilkor';
|
||||
$string['welcomep70'] = 'Coahkkal "Boahtte"-boalu joatkit<strong>Moodle</strong>-installašuvnnain';
|
||||
|
||||
@@ -42,3 +42,6 @@ $string['cannotsavemd5file'] = 'Md5 ఫైల్ను సేవ్ చేయల
|
||||
$string['cannotsavezipfile'] = 'జిప్ ఫైల్ను సేవ్ చేయడం సాధ్యపడదు';
|
||||
$string['cannotunzipfile'] = 'ఫైల్ అన్జిప్ చేయలేరు';
|
||||
$string['componentisuptodate'] = 'కాంపొనెంటు తాజాగా ఉంది';
|
||||
$string['dmlexceptiononinstall'] = '<p>A డేటాబేస్ లోపం ఏర్పడింది [{$ a-> errorcode}]. <br /> {$a->debuginfo} </p>';
|
||||
$string['downloadedfilecheckfailed'] = 'డౌన్లోడ్ చేసిన ఫైల్ తనిఖీ విఫలమైంది';
|
||||
$string['invalidmd5'] = 'చెక్ వేరియబుల్ తప్పు. - మళ్ళీ ప్రయత్నించండి';
|
||||
|
||||
@@ -31,5 +31,5 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = '';
|
||||
$string['thisdirection'] = '符号(ltr)';
|
||||
$string['thisdirection'] = 'ltr';
|
||||
$string['thislanguage'] = '简体中文';
|
||||
|
||||
@@ -32,6 +32,6 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['language'] = '语言';
|
||||
$string['moodlelogo'] = 'Moodle图标';
|
||||
$string['next'] = '向后';
|
||||
$string['previous'] = '向前';
|
||||
$string['next'] = '下一个';
|
||||
$string['previous'] = '上一个';
|
||||
$string['reload'] = '重新载入';
|
||||
|
||||
+1
-1
@@ -241,7 +241,7 @@ $string['configenablewsdocumentation'] = 'Enable auto-generation of web services
|
||||
$string['configerrorlevel'] = 'Choose the amount of PHP warnings that you want to be displayed. Normal is usually the best choice.';
|
||||
$string['configexportlookahead'] = 'Days to look ahead during export';
|
||||
$string['configexportlookback'] = 'Days to look back during export';
|
||||
$string['configextendedusernamechars'] = 'Enable this setting to allow students to use any characters in their usernames (note this does not affect their actual names). The default is "false" which restricts usernames to be alphanumeric lowercase characters, underscore (_), hyphen (-), period (.) or at symbol (@).';
|
||||
$string['configextendedusernamechars'] = 'If enabled, usernames may include any characters except uppercase letters. Otherwise, only alphanumeric characters with lowercase letters, underscore (_), hyphen (-), period (.) and at symbol (@) are allowed.';
|
||||
$string['configextramemorylimit'] = 'Some scripts like search, backup/restore or cron require more memory. Set higher values for large sites.';
|
||||
$string['configfilterall'] = 'Filter all strings, including headings, titles, navigation bar and so on. This is mostly useful when using the multilang filter, otherwise it will just create extra load on your site for little gain.';
|
||||
$string['configfiltermatchoneperpage'] = 'Automatic linking filters will only generate a single link for the first matching text instance found on the complete page. All others are ignored.';
|
||||
|
||||
@@ -32,7 +32,7 @@ $string['analyticslogstore_help'] = 'The log store that will be used by the anal
|
||||
$string['analyticssettings'] = 'Analytics settings';
|
||||
$string['analyticssiteinfo'] = 'Site information';
|
||||
$string['defaulttimesplittingmethods'] = 'Default analysis intervals for model\'s evaluation';
|
||||
$string['defaulttimesplittingmethods_help'] = 'The analysis interval defines when the system will calculate predictions and the portion of activity logs that will be considered for those predictions.The model evaluation process will iterate through these analysis intervals unless a specific analysis interval is specified.';
|
||||
$string['defaulttimesplittingmethods_help'] = 'The analysis interval defines when the system will calculate predictions and the portion of activity logs that will be considered for those predictions. The model evaluation process will iterate through these analysis intervals unless a specific analysis interval is specified.';
|
||||
$string['defaultpredictionsprocessor'] = 'Default predictions processor';
|
||||
$string['defaultpredictoroption'] = 'Default processor ({$a})';
|
||||
$string['disabledmodel'] = 'Disabled model';
|
||||
|
||||
+3
-3
@@ -75,11 +75,11 @@ $string['emailnowexists'] = 'The email address you tried to assign to your profi
|
||||
$string['emailupdate'] = 'Email address update';
|
||||
$string['emailupdatemessage'] = 'Dear {$a->fullname},
|
||||
|
||||
You have requested a change of your email address for your user account at {$a->site}. Please open the following URL in your browser in order to confirm this change.
|
||||
You have requested a change of your email address for your account on {$a->site}. To confirm this change, please go to the following web address:
|
||||
|
||||
If you have any questions please contact support on: {$a->supportemail}
|
||||
{$a->url}
|
||||
|
||||
{$a->url}';
|
||||
{$a->supportemail}';
|
||||
$string['emailupdatesuccess'] = 'Email address of user <em>{$a->fullname}</em> was successfully updated to <em>{$a->email}</em>.';
|
||||
$string['emailupdatetitle'] = 'Confirmation of email update at {$a->site}';
|
||||
$string['errormaxconsecutiveidentchars'] = 'Passwords must have at most {$a} consecutive identical characters.';
|
||||
|
||||
@@ -81,6 +81,8 @@ $string['awardedtoyou'] = 'Issued to me';
|
||||
$string['awardoncron'] = 'Access to the badges was successfully enabled. Too many users can instantly earn this badge. To ensure site performance, this action will take some time to process.';
|
||||
$string['awards'] = 'Recipients';
|
||||
$string['backpackavailability'] = 'External badge verification';
|
||||
$string['backpackconnectionok'] = 'Backpack connection successfully established';
|
||||
$string['backpackconnectionnottested'] = 'The connection cannot be tested for this backpack because only Open Badges v2.0 backpacks support it.';
|
||||
$string['backpackneedsupdate'] = 'The backpack connected to this profile does not match the backpack for the site. You need to disconnect and reconnect the backpack.';
|
||||
$string['backpackavailability_help'] = 'For badge recipients to be able to prove they earned their badges from you, an external backpack service should be able to access your site and verify badges issued from it. Your site does not currently appear to be accessible, which means that badges you have already issued or will issue in the future cannot be verified.
|
||||
|
||||
@@ -536,6 +538,8 @@ $string['targetframework'] = 'Framework';
|
||||
$string['targetframework_help'] = 'The name of the external skill or standard framework.';
|
||||
$string['targetcode'] = 'Code';
|
||||
$string['targetcode_help'] = 'A unique string identifier for referencing the external skill or standard within its framework.';
|
||||
$string['testbackpack'] = 'Test backpack \'{$a}\'';
|
||||
$string['testsettings'] = 'Test settings';
|
||||
$string['type'] = 'Type';
|
||||
$string['variablesubstitution'] = 'Variable substitution in messages.';
|
||||
$string['variablesubstitution_help'] = 'In a badge message, certain variables can be inserted into the subject and/or body of a message so that they will be replaced with real values when the message is sent. The variables should be inserted into the text exactly as they are shown below. The following variables can be used:
|
||||
|
||||
@@ -74,6 +74,7 @@ $string['cachedef_questiondata'] = 'Question definitions';
|
||||
$string['cachedef_repositories'] = 'Repositories instances data';
|
||||
$string['cachedef_roledefs'] = 'Role definitions';
|
||||
$string['cachedef_grade_categories'] = 'Grade category queries';
|
||||
$string['cachedef_grade_letters'] = 'Grade letter queries';
|
||||
$string['cachedef_string'] = 'Language string cache';
|
||||
$string['cachedef_tags'] = 'Tags collections and areas';
|
||||
$string['cachedef_temp_tables'] = 'Temporary tables cache';
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ $string['privacy:metadata:files:contenthash'] = 'A hash of the file\'s content';
|
||||
$string['privacy:metadata:files:filename'] = 'The name of the file in its file area';
|
||||
$string['privacy:metadata:files:filepath'] = 'The path to the file in its file area';
|
||||
$string['privacy:metadata:files:filesize'] = 'The size of the file';
|
||||
$string['privacy:metadata:files:license'] = 'The license of the file\'s content';
|
||||
$string['privacy:metadata:files:license'] = 'The licence of the file\'s content';
|
||||
$string['privacy:metadata:files:mimetype'] = 'The MIME type of the file';
|
||||
$string['privacy:metadata:files:source'] = 'The source of the file';
|
||||
$string['privacy:metadata:files:timecreated'] = 'The time when the file was created';
|
||||
|
||||
+5
-4
@@ -29,7 +29,7 @@ $string['addedandupdatedsp'] = 'Added {$a->%new} new H5P library and updated {$a
|
||||
$string['addedandupdatedss'] = 'Added {$a->%new} new H5P library and updated {$a->%old} old one.';
|
||||
$string['addednewlibraries'] = 'Added {$a->%new} new H5P libraries.';
|
||||
$string['addednewlibrary'] = 'Added {$a->%new} new H5P library.';
|
||||
$string['additionallicenseinfo'] = 'Any additional information about the license';
|
||||
$string['additionallicenseinfo'] = 'Any additional information about the licence';
|
||||
$string['author'] = 'Author';
|
||||
$string['authorcomments'] = 'Author comments';
|
||||
$string['authorcommentsdescription'] = 'Comments for the editor of the content. (This text will not be published as a part of the copyright info.)';
|
||||
@@ -108,7 +108,7 @@ $string['invalidsemanticstype'] = 'H5P internal error: unknown content type "{$a
|
||||
$string['invalidstring'] = 'Provided string is not valid according to regexp in semantics. (value: "{$a->%value}", regexp: "{$a->%regexp}")';
|
||||
$string['librarydirectoryerror'] = 'Library directory name must match machineName or machineName-majorVersion.minorVersion (from library.json). (Directory: {$a->%directoryName} , machineName: {$a->%machineName}, majorVersion: {$a->%majorVersion}, minorVersion: {$a->%minorVersion})';
|
||||
$string['librariesmanagerdescription'] = '<p>H5P enables users to create interactive content by providing a range of content types.</p><p>To ensure that only trusted H5P content types are used on your site, you need to <i>either</i></p><ul><li>Upload H5P content types from h5p.org <i>or</i></li><li>Enable the scheduled task \'Download available H5P content types from h5p.org\'</li></ul><p>Note that users will only be able to use the H5P content types which are installed on your site.</p>';
|
||||
$string['license'] = 'License';
|
||||
$string['license'] = 'Licence';
|
||||
$string['licenseCC010'] = 'CC0 1.0 Universal (CC0 1.0) Public Domain Dedication';
|
||||
$string['licenseCC010U'] = 'CC0 1.0 Universal';
|
||||
$string['licenseCC10'] = '1.0 Generic';
|
||||
@@ -121,8 +121,9 @@ $string['licenseV1'] = 'Version 1';
|
||||
$string['licenseV2'] = 'Version 2';
|
||||
$string['licenseV3'] = 'Version 3';
|
||||
$string['licensee'] = 'Licensee';
|
||||
$string['licenseextras'] = 'License extras';
|
||||
$string['licenseversion'] = 'License version';
|
||||
$string['licenseextras'] = 'Licence extras';
|
||||
$string['licenseversion'] = 'Licence version';
|
||||
$string['lockh5pdeploy'] = 'This H5P content cannot be accessed because it is being deployed. Please try again later.';
|
||||
$string['missingcontentfolder'] = 'A valid content folder is missing';
|
||||
$string['missingcoreversion'] = 'The system was unable to install the {$a->%component} component from the package, as it requires a newer version of the H5P plugin. This site is currently running version {$a->%current}, whereas the required version is {$a->%required} or higher. Please upgrade and then try again.';
|
||||
$string['missingdependency'] = 'Missing dependency {$a->@dep} required by {$a->@lib}.';
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ $string['clialreadyconfigured'] = 'The configuration file config.php already exi
|
||||
$string['clialreadyinstalled'] = 'The configuration file config.php already exists. Please use admin/cli/install_database.php to upgrade Moodle for this site.';
|
||||
$string['cliinstallfinished'] = 'Installation completed successfully.';
|
||||
$string['cliinstallheader'] = 'Moodle {$a} command line installation program';
|
||||
$string['climustagreelicense'] = 'In non interactive mode you must agree to license by specifying --agree-license option';
|
||||
$string['climustagreelicense'] = 'In non-interactive mode you must agree to the licence by specifying --agree-license option';
|
||||
$string['cliskipdatabase'] = 'Skipping database installation.';
|
||||
$string['clitablesexist'] = 'Database tables already present; CLI installation cannot continue.';
|
||||
$string['compatibilitysettings'] = 'Checking your PHP settings ...';
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ $string['enterausername'] = 'Please enter a username, or a list of usernames sep
|
||||
$string['error7020'] = 'This error normally occurs if the remote site has created a record for you with the wrong wwwroot, for example, https://yoursite.com instead of https://www.yoursite.com. Please contact the administrator of the remote site with your wwwroot (as specified in config.php) and ask them to update the 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['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['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.';
|
||||
$string['error709'] = 'The remote site failed to obtain a SSL key from you.';
|
||||
$string['eventaccesscontrolcreated'] = 'Access control created';
|
||||
|
||||
@@ -841,6 +841,7 @@ $string['first'] = 'First';
|
||||
$string['firstaccess'] = 'First access';
|
||||
$string['firstname'] = 'First name';
|
||||
$string['firstnamephonetic'] = 'First name - phonetic';
|
||||
$string['firstpage'] = 'First page';
|
||||
$string['firstsiteaccess'] = 'First access to site';
|
||||
$string['firsttime'] = 'Is this your first time here?';
|
||||
$string['folder'] = 'Folder';
|
||||
@@ -1114,6 +1115,7 @@ $string['lastlogin'] = 'Last login';
|
||||
$string['lastmodified'] = 'Last modified';
|
||||
$string['lastname'] = 'Surname';
|
||||
$string['lastnamephonetic'] = 'Surname - phonetic';
|
||||
$string['lastpage'] = 'Last page';
|
||||
$string['lastsiteaccess'] = 'Last access to site';
|
||||
$string['lastyear'] = 'Last year';
|
||||
$string['latestlanguagepack'] = 'Check for latest language pack on moodle.org';
|
||||
@@ -1396,6 +1398,7 @@ Cheers from the \'{$a->sitename}\' administrator,
|
||||
$string['newusers'] = 'New users';
|
||||
$string['newwindow'] = 'New window';
|
||||
$string['next'] = 'Next';
|
||||
$string['nextpage'] = 'Next page';
|
||||
$string['nextsection'] = 'Next section';
|
||||
$string['no'] = 'No';
|
||||
$string['noblockstoaddhere'] = 'There are no blocks that you can add to this page.';
|
||||
@@ -1578,6 +1581,7 @@ $string['preview'] = 'Preview';
|
||||
$string['previeworchoose'] = 'Preview or choose a theme';
|
||||
$string['previous'] = 'Previous';
|
||||
$string['previouslyselectedusers'] = 'Previously selected users not matching \'{$a}\'';
|
||||
$string['previouspage'] = 'Previous page';
|
||||
$string['previoussection'] = 'Previous section';
|
||||
$string['primaryadminsetup'] = 'Setup administrator account';
|
||||
$string['privacy:metadata:config_log'] = 'The log of configuration changes.';
|
||||
|
||||
@@ -225,6 +225,7 @@ $string['validationmsg_onedir'] = 'Invalid structure of the ZIP package.';
|
||||
$string['validationmsg_onedir_help'] = 'The ZIP package must contain just one root directory that holds the plugin code. The name of that root directory must match the name of the plugin.';
|
||||
$string['validationmsg_pathwritable'] = 'Write access check';
|
||||
$string['validationmsg_pluginversion'] = 'Plugin version';
|
||||
$string['validationmsg_pluginversiontoolow'] = 'A higher version of this plugin is already installed';
|
||||
$string['validationmsg_release'] = 'Plugin release';
|
||||
$string['validationmsg_requiresmoodle'] = 'Required Moodle version';
|
||||
$string['validationmsg_rootdir'] = 'Name of the plugin to be installed';
|
||||
|
||||
@@ -182,6 +182,7 @@ $string['america/noronha'] = 'America/Noronha';
|
||||
$string['america/north_dakota/beulah'] = 'America/North_Dakota/Beulah';
|
||||
$string['america/north_dakota/center'] = 'America/North_Dakota/Center';
|
||||
$string['america/north_dakota/new_salem'] = 'America/North_Dakota/New_Salem';
|
||||
$string['america/nuuk'] = 'America/Nuuk';
|
||||
$string['america/ojinaga'] = 'America/Ojinaga';
|
||||
$string['america/panama'] = 'America/Panama';
|
||||
$string['america/pangnirtung'] = 'America/Pangnirtung';
|
||||
|
||||
+1
-1
@@ -2206,7 +2206,7 @@ function reset_role_capabilities($roleid) {
|
||||
* the database.
|
||||
*
|
||||
* @access private
|
||||
* @param string $component examples: 'moodle', 'mod/forum', 'block/quiz_results'
|
||||
* @param string $component examples: 'moodle', 'mod_forum', 'block_quiz_results'
|
||||
* @return boolean true if success, exception in case of any problems
|
||||
*/
|
||||
function update_capabilities($component = 'moodle') {
|
||||
|
||||
+52
-6
@@ -1685,6 +1685,8 @@ abstract class admin_setting {
|
||||
private $forceltr = null;
|
||||
/** @var array list of other settings that may cause this setting to be hidden */
|
||||
private $dependenton = [];
|
||||
/** @var bool Whether this setting uses a custom form control */
|
||||
protected $customcontrol = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -2070,6 +2072,16 @@ abstract class admin_setting {
|
||||
public function get_dependent_on() {
|
||||
return $this->dependenton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this setting uses a custom form control.
|
||||
* This function is especially useful to decide if we should render a label element for this setting or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_custom_form_control(): bool {
|
||||
return $this->customcontrol;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8758,6 +8770,7 @@ function format_admin_setting($setting, $title='', $form='', $description='', $l
|
||||
$context->description = highlight($query, markdown_to_html($description));
|
||||
$context->element = $form;
|
||||
$context->forceltr = $setting->get_force_ltr();
|
||||
$context->customcontrol = $setting->has_custom_form_control();
|
||||
|
||||
return $OUTPUT->render_from_template('core_admin/setting', $context);
|
||||
}
|
||||
@@ -8790,6 +8803,40 @@ function any_new_admin_settings($node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a table and optionally a column name should replaces be done?
|
||||
*
|
||||
* @param string $table name
|
||||
* @param string $column name
|
||||
* @return bool success or fail
|
||||
*/
|
||||
function db_should_replace($table, $column = ''): bool {
|
||||
|
||||
// TODO: this is horrible hack, we should do whitelisting and each plugin should be responsible for proper replacing...
|
||||
$skiptables = ['config', 'config_plugins', 'filter_config', 'sessions',
|
||||
'events_queue', 'repository_instance_config', 'block_instances', 'files'];
|
||||
|
||||
// Don't process these.
|
||||
if (in_array($table, $skiptables)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// To be safe never replace inside a table that looks related to logging.
|
||||
if (preg_match('/(^|_)logs?($|_)/', $table)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do column based exclusions.
|
||||
if (!empty($column)) {
|
||||
// Don't touch anything that looks like a hash.
|
||||
if (preg_match('/hash$/', $column)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moved from admin/replace.php so that we can use this in cron
|
||||
*
|
||||
@@ -8800,11 +8847,6 @@ function any_new_admin_settings($node) {
|
||||
function db_replace($search, $replace) {
|
||||
global $DB, $CFG, $OUTPUT;
|
||||
|
||||
// TODO: this is horrible hack, we should do whitelisting and each plugin should be responsible for proper replacing...
|
||||
$skiptables = array('config', 'config_plugins', 'config_log', 'upgrade_log', 'log',
|
||||
'filter_config', 'sessions', 'events_queue', 'repository_instance_config',
|
||||
'block_instances', '');
|
||||
|
||||
// Turn off time limits, sometimes upgrades can be slow.
|
||||
core_php_time_limit::raise();
|
||||
|
||||
@@ -8813,13 +8855,16 @@ function db_replace($search, $replace) {
|
||||
}
|
||||
foreach ($tables as $table) {
|
||||
|
||||
if (in_array($table, $skiptables)) { // Don't process these
|
||||
if (!db_should_replace($table)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($columns = $DB->get_columns($table)) {
|
||||
$DB->set_debug(true);
|
||||
foreach ($columns as $column) {
|
||||
if (!db_should_replace($table, $column->name)) {
|
||||
continue;
|
||||
}
|
||||
$DB->replace_all_text($table, $column, $search, $replace);
|
||||
}
|
||||
$DB->set_debug(false);
|
||||
@@ -10185,6 +10230,7 @@ class admin_setting_configstoredfile extends admin_setting {
|
||||
$this->filearea = $filearea;
|
||||
$this->itemid = $itemid;
|
||||
$this->options = (array)$options;
|
||||
$this->customcontrol = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user