Compare commits
344 Commits
v3.3.0-rc2
..
v3.3.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e4341402a | |||
| 0a5af1649f | |||
| b194f1a2e3 | |||
| 14ecaeea08 | |||
| c28de2e556 | |||
| 706571e94f | |||
| 0801d7dc95 | |||
| 77da99fe77 | |||
| c88b34c0fa | |||
| 23dbc35541 | |||
| e9609517d2 | |||
| efc9c7572b | |||
| 05263df3b0 | |||
| dc30c8fa2f | |||
| 8b3ee7d311 | |||
| 5823f7e1bd | |||
| 4dfa466691 | |||
| 226ca38be3 | |||
| 145e6deee7 | |||
| d53a5789a8 | |||
| 640534676c | |||
| 49371ca433 | |||
| 5697a42fc2 | |||
| 0ba4ffe353 | |||
| 31bae37249 | |||
| 2423a989fc | |||
| 67103939ac | |||
| 4f91eb0ba1 | |||
| 07cb3212c5 | |||
| 550e03463b | |||
| 4f2c5e18c0 | |||
| 73aad88f63 | |||
| 88d7acff69 | |||
| 59f5f4a9df | |||
| 14509286e4 | |||
| 6b661ab0a2 | |||
| 57cb067173 | |||
| 65e5e9f454 | |||
| 7984ae3581 | |||
| f786e59224 | |||
| c46c38d355 | |||
| 67c112bf9c | |||
| 61812e3dd8 | |||
| eaeed5b281 | |||
| d259cafd3c | |||
| e632f4ece5 | |||
| aff28d6243 | |||
| 653ec0d0b0 | |||
| 62a71e4a17 | |||
| 35657809ed | |||
| c61c5009a8 | |||
| fe9e229248 | |||
| db500a32a1 | |||
| 75ead1e8cf | |||
| c7c9f4a46e | |||
| 8e9c8f6583 | |||
| 037bf82652 | |||
| 5341d76031 | |||
| e71b162d09 | |||
| 58099bd24d | |||
| c7da8264d0 | |||
| ca47e80375 | |||
| 40e7ac2c70 | |||
| d7a2d1a2c8 | |||
| d971e7dffe | |||
| 56855a2842 | |||
| 7563339608 | |||
| 89d85f5a4b | |||
| 74823e4e45 | |||
| 7a0e1cd70c | |||
| 4534c7b531 | |||
| 16f2fe5514 | |||
| eee0d699c3 | |||
| 0d74c11cf7 | |||
| 6aebb4375f | |||
| 32f2e90522 | |||
| 8e62bc79c7 | |||
| c36c507277 | |||
| 813f289b60 | |||
| e318be3772 | |||
| a67ff779d5 | |||
| 222a87ae98 | |||
| 8d0dd90520 | |||
| cccb1a6d21 | |||
| 3d8a2c5cd9 | |||
| ebe0cf3ed4 | |||
| 9938165bb8 | |||
| 101271fd28 | |||
| 4ca3991e56 | |||
| f6736dedd1 | |||
| 5be425cf9e | |||
| 0f0b45fd59 | |||
| f05e2e6690 | |||
| b0b68a0bd4 | |||
| 7abe668bd6 | |||
| b31f3097c2 | |||
| 82b3050e72 | |||
| 153f74956d | |||
| 8b017ea78c | |||
| cea093be87 | |||
| 970c74b280 | |||
| 04e5ef2a3e | |||
| b2a90870ce | |||
| ae60722b14 | |||
| 26277438ed | |||
| 17eb11f801 | |||
| 3ae9ed890f | |||
| 0ff0caefc0 | |||
| a5efab81c9 | |||
| bc84e4e4ae | |||
| e70d1e66d6 | |||
| e256446c75 | |||
| e4780bf151 | |||
| 4b8d403606 | |||
| 8a32c0fdb3 | |||
| a27fa5b50e | |||
| 3cf5c5152e | |||
| c484b0574e | |||
| dec00f6a53 | |||
| d51518e24d | |||
| 94925c38d0 | |||
| 7abd8de776 | |||
| a358927e9e | |||
| 49e5b8438c | |||
| 2b026b44f7 | |||
| 63bfa5afdb | |||
| d08cd28dae | |||
| 5d7d2c0a45 | |||
| 9eb46e7d75 | |||
| 481220cb4c | |||
| d47b680074 | |||
| 76b6407cb8 | |||
| ca1e040bbf | |||
| 1312c844a1 | |||
| a21c3208ea | |||
| a1692f6362 | |||
| 9bcb6e1bec | |||
| 192a355707 | |||
| 3709386ed5 | |||
| c159483796 | |||
| 9bdff1611b | |||
| ca18b0c33d | |||
| 0fb6f059a9 | |||
| 7dc35ed9d2 | |||
| 481a5ce58b | |||
| af153671de | |||
| 48b929667e | |||
| 6dc00c8423 | |||
| 290ec233f5 | |||
| 56aa74ed3c | |||
| fe3d722d69 | |||
| 792560a608 | |||
| 7041dc6f8a | |||
| 57fb48743f | |||
| a9712dacbe | |||
| c0f4b8b3c1 | |||
| 9a9b9e53f0 | |||
| e1d15194bc | |||
| 5b2f32ca92 | |||
| a53a439c08 | |||
| 2c12e7f534 | |||
| 7255306cc8 | |||
| b545e84294 | |||
| 72ebc73897 | |||
| 856e1c24c2 | |||
| 5b1dffd5b0 | |||
| 6ebff58d8c | |||
| 54bee25c65 | |||
| 355fefbe71 | |||
| 11a24a823b | |||
| 75797500ae | |||
| e2b8d30052 | |||
| 571e862135 | |||
| 1e9ba1916b | |||
| ddd849e1d5 | |||
| 760ed1dfde | |||
| 95a6fe8b05 | |||
| 0fca28e197 | |||
| cc5235bb77 | |||
| 1099b7ce1d | |||
| dc403b8386 | |||
| 23bec87007 | |||
| 924db1a0a6 | |||
| f8326931a1 | |||
| 0a98628841 | |||
| d72a096797 | |||
| a6379acaf3 | |||
| e002d8c2db | |||
| 2b7268d645 | |||
| 6e34867b93 | |||
| 9a6e95557f | |||
| 88daff0ff3 | |||
| 3309800768 | |||
| adbba36a63 | |||
| 37ff4578be | |||
| cbc3742d71 | |||
| 56e407f8a0 | |||
| 362e7721f5 | |||
| 53fd95f715 | |||
| 078aaae0cf | |||
| 4f66cd826f | |||
| 028f587670 | |||
| 0b2e862c7a | |||
| 8db0bcc018 | |||
| bb6a2082f8 | |||
| dfac161651 | |||
| f41c1f82bc | |||
| 443f993467 | |||
| 0e72aac68a | |||
| 4cd564dd65 | |||
| c6c462903e | |||
| be4a2e7773 | |||
| 283140134b | |||
| c779c4fa0b | |||
| 4577aa88fd | |||
| 3add309d96 | |||
| 1c2a935975 | |||
| 574aa817c1 | |||
| 98a7bb9cd5 | |||
| f35ff40f4a | |||
| 2529f11ce3 | |||
| 26f4cf3ad8 | |||
| 23ec9e80b4 | |||
| 8710174991 | |||
| e399833263 | |||
| 59411b45f6 | |||
| 767622050e | |||
| 6696cff321 | |||
| f59741cc6c | |||
| 524724c642 | |||
| ca31084da2 | |||
| 52ecbf8f4c | |||
| d9c2abaa65 | |||
| 30613bca8d | |||
| cb3bad1d50 | |||
| e4eab531bf | |||
| 068d573375 | |||
| df78e4c8ab | |||
| 5fbe152a58 | |||
| 7fe005f6d1 | |||
| 2a615a6031 | |||
| cb065a2d2f | |||
| e0adce5360 | |||
| 613db5afcb | |||
| b38538fbdf | |||
| f96167c02e | |||
| c708549705 | |||
| d14281e215 | |||
| 19f6ca9457 | |||
| 7b4eb6082f | |||
| 8b8fbc6b84 | |||
| 906b385784 | |||
| e13e5a42bc | |||
| 1fcfc991b9 | |||
| a4eaa35e23 | |||
| df6749b03b | |||
| 6fc4a6c17a | |||
| f13c34e4a9 | |||
| 0899f6b9f9 | |||
| b68abdc7c2 | |||
| 7e68b9a0af | |||
| 63752139c4 | |||
| 67803cb430 | |||
| 54b24b8a24 | |||
| 3e97f327cf | |||
| e91ffe1531 | |||
| c4d5303ce0 | |||
| 0712ef7f54 | |||
| ddf6c958f8 | |||
| fbf216799c | |||
| f8b0ee68bf | |||
| 069683984a | |||
| 7a7dd2ff1f | |||
| 8a0ed98b81 | |||
| ce904a961d | |||
| 5ff898804f | |||
| 3bb50a471c | |||
| 660182a172 | |||
| e8f0664d53 | |||
| cb495b995c | |||
| c37bbda3ef | |||
| 81432e74f4 | |||
| d231bf1272 | |||
| 1aee3e9394 | |||
| 9362f598dd | |||
| b87a580aa3 | |||
| 206da19cd8 | |||
| 5c3287d5d8 | |||
| cc9857b71a | |||
| 49fa410dd1 | |||
| f0cba09e16 | |||
| 4f3962e4b4 | |||
| c0af95d789 | |||
| ae9da6a222 | |||
| 56fb39316f | |||
| ac8a0c4077 | |||
| 011591a148 | |||
| 2c69d24037 | |||
| 081aad9986 | |||
| 4c8727bad6 | |||
| 0e01f68e3c | |||
| 5ffe41b6c5 | |||
| 3227ac8374 | |||
| d9d2c2f86f | |||
| 95dd5e3bd6 | |||
| f86e8699b9 | |||
| 8f8b210fd6 | |||
| bcf69a655a | |||
| a1c6871bb3 | |||
| 88a7f77525 | |||
| f24e17c93e | |||
| 761ac5a0aa | |||
| e84fefdb09 | |||
| 1b6a8f3fdf | |||
| 3a7afbe9cb | |||
| e838654b4e | |||
| 0d86195e8d | |||
| ef1a227e38 | |||
| 0ac1dcd8d1 | |||
| cf7ac86858 | |||
| cd2c4b8548 | |||
| 79b80ee540 | |||
| cb04995b30 | |||
| a5ea94d85f | |||
| fd8d1648a7 | |||
| 265a1eafc5 | |||
| 9eb5a0417c | |||
| 56d1ddd775 | |||
| 8dada7e334 | |||
| 4133df6fd6 | |||
| 9c98546da6 | |||
| 865e2bc7dc | |||
| 396ae85082 | |||
| 4f705f5d0d | |||
| 675ffb4d05 | |||
| 6f41250d82 | |||
| a011effb49 | |||
| 8a9785a036 | |||
| b5c24c99a0 | |||
| 947f5c3448 | |||
| 406b92c6fd | |||
| 89ab16414a | |||
| e0abc2e405 | |||
| 32ec2da151 |
+28
-2
@@ -2,7 +2,7 @@
|
||||
# process (which uses our internal CI system) this file is here for the benefit
|
||||
# of community developers git clones - see MDL-51458.
|
||||
|
||||
sudo: false
|
||||
sudo: required
|
||||
|
||||
# We currently disable Travis notifications entirely until https://github.com/travis-ci/travis-ci/issues/4976
|
||||
# is fixed.
|
||||
@@ -18,6 +18,10 @@ php:
|
||||
|
||||
addons:
|
||||
postgresql: "9.3"
|
||||
packages:
|
||||
- mysql-server-5.6
|
||||
- mysql-client-core-5.6
|
||||
- mysql-client-5.6
|
||||
|
||||
services:
|
||||
- redis-server
|
||||
@@ -73,6 +77,28 @@ cache:
|
||||
- $HOME/.npm
|
||||
|
||||
install:
|
||||
- sudo apt-get -y install haveged
|
||||
- sudo service haveged start
|
||||
- >
|
||||
if [ "$DB" = 'mysqli' ];
|
||||
then
|
||||
sudo mkdir /mnt/ramdisk
|
||||
sudo mount -t tmpfs -o size=1024m tmpfs /mnt/ramdisk
|
||||
sudo stop mysql
|
||||
sudo mv /var/lib/mysql /mnt/ramdisk
|
||||
sudo ln -s /mnt/ramdisk/mysql /var/lib/mysql
|
||||
sudo start mysql
|
||||
fi
|
||||
- >
|
||||
if [ "$DB" = 'pgsql' ];
|
||||
then
|
||||
sudo mkdir /mnt/ramdisk
|
||||
sudo mount -t tmpfs -o size=1024m tmpfs /mnt/ramdisk
|
||||
sudo service postgresql stop
|
||||
sudo mv /var/lib/postgresql /mnt/ramdisk
|
||||
sudo ln -s /mnt/ramdisk/postgresql /var/lib/postgresql
|
||||
sudo service postgresql start 9.3
|
||||
fi
|
||||
- >
|
||||
if [ "$TASK" = 'PHPUNIT' ];
|
||||
then
|
||||
@@ -187,7 +213,7 @@ before_script:
|
||||
# We need the official upstream for comparison
|
||||
git remote add upstream https://github.com/moodle/moodle.git;
|
||||
|
||||
git fetch upstream master;
|
||||
git fetch upstream MOODLE_33_STABLE;
|
||||
export GIT_PREVIOUS_COMMIT="`git merge-base FETCH_HEAD $TRAVIS_COMMIT`";
|
||||
export GIT_COMMIT="$TRAVIS_COMMIT";
|
||||
export UPSTREAM_FETCH_HEAD=`git rev-parse FETCH_HEAD`
|
||||
|
||||
+1
-1
@@ -338,7 +338,7 @@ module.exports = function(grunt) {
|
||||
opts: {stdio: 'inherit', env: process.env}
|
||||
}, function(error, result, code) {
|
||||
// Propagate the exit code.
|
||||
done(code);
|
||||
done(code === 0);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ if ($PAGE->user_allowed_editing()) {
|
||||
$savebutton = false;
|
||||
$outputhtml = '';
|
||||
foreach ($settingspage->children as $childpage) {
|
||||
if ($childpage->is_hidden()) {
|
||||
if ($childpage->is_hidden() || !$childpage->check_access()) {
|
||||
continue;
|
||||
}
|
||||
if ($childpage instanceof admin_externalpage) {
|
||||
|
||||
@@ -53,7 +53,7 @@ Options:
|
||||
-h, --help Print out this help
|
||||
|
||||
Example:
|
||||
\$ sudo -u www-data /usr/bin/php admin/cli/mysql_collation.php --collation=utf8_general_ci
|
||||
\$ sudo -u www-data /usr/bin/php admin/cli/mysql_collation.php --collation=utf8mb4_unicode_ci
|
||||
";
|
||||
|
||||
if (!empty($options['collation'])) {
|
||||
@@ -145,9 +145,22 @@ if (!empty($options['collation'])) {
|
||||
$skipped++;
|
||||
|
||||
} else {
|
||||
$DB->change_database_structure("ALTER TABLE $table->name DEFAULT CHARACTER SET $charset DEFAULT COLLATE = $collation");
|
||||
echo "CONVERTED\n";
|
||||
$converted++;
|
||||
try {
|
||||
$DB->change_database_structure("ALTER TABLE $table->name CONVERT TO CHARACTER SET $charset COLLATE $collation");
|
||||
echo "CONVERTED\n";
|
||||
$converted++;
|
||||
} catch (ddl_exception $e) {
|
||||
$result = mysql_set_row_format($table->name, $charset, $collation, $engine);
|
||||
if ($result) {
|
||||
echo "CONVERTED\n";
|
||||
$converted++;
|
||||
} else {
|
||||
// We don't know what the problem is. Stop the conversion.
|
||||
cli_error("Error: Tried to convert $table->name, but there was a problem. Please check the details of this
|
||||
table and try again.");
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "SHOW FULL COLUMNS FROM $table->name WHERE collation IS NOT NULL";
|
||||
@@ -290,3 +303,26 @@ function mysql_get_column_collations($tablename) {
|
||||
$rs->close();
|
||||
return $collations;
|
||||
}
|
||||
|
||||
function mysql_set_row_format($tablename, $charset, $collation, $engine) {
|
||||
global $DB;
|
||||
|
||||
$sql = "SELECT row_format
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE table_schema = DATABASE() AND table_name = ?";
|
||||
$rs = $DB->get_record_sql($sql, array($tablename));
|
||||
if ($rs) {
|
||||
if ($rs->row_format == 'Compact' || $rs->row_format == 'Redundant') {
|
||||
$rowformat = $DB->get_row_format_sql($engine, $collation);
|
||||
// Try to convert to compressed format and then try updating the collation again.
|
||||
$DB->change_database_structure("ALTER TABLE $tablename $rowformat");
|
||||
$DB->change_database_structure("ALTER TABLE $tablename CONVERT TO CHARACTER SET $charset COLLATE $collation");
|
||||
} else {
|
||||
// Row format may not be the problem. Can not diagnose problem. Send fail reply.
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -101,6 +101,12 @@ if (function_exists('opcache_invalidate')) {
|
||||
// indirectly calls the protected init() method is good here.
|
||||
core_component::get_core_subsystems();
|
||||
|
||||
if (is_major_upgrade_required() && isloggedin()) {
|
||||
// A major upgrade is required.
|
||||
// Terminate the session and redirect back here before anything DB-related happens.
|
||||
redirect_if_major_upgrade_required();
|
||||
}
|
||||
|
||||
require_once($CFG->libdir.'/adminlib.php'); // various admin-only functions
|
||||
require_once($CFG->libdir.'/upgradelib.php'); // general upgrade/install related functions
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ class site_registration_form extends moodleform {
|
||||
}
|
||||
$language = get_config('hub', 'site_language_' . $cleanhuburl);
|
||||
if ($language === false) {
|
||||
$language = current_language();
|
||||
$language = explode('_', current_language())[0];
|
||||
}
|
||||
$geolocation = get_config('hub', 'site_geolocation_' . $cleanhuburl);
|
||||
$contactable = get_config('hub', 'site_contactable_' . $cleanhuburl);
|
||||
|
||||
@@ -193,8 +193,8 @@ function print_report_tree($contextid, $contexts, $systemcontext, $fullname, $al
|
||||
$strgoto = get_string('gotoassignroles', 'core_role', $a);
|
||||
$strcheck = get_string('checkuserspermissionshere', 'core_role', $a);
|
||||
}
|
||||
echo ' <a title="' . $strgoto . '" href="' . $raurl . '">' . $OUTPUT->pix_icon('t/edit', 'core', $stredit) . '</a> ';
|
||||
echo ' <a title="' . $strcheck . '" href="' . $churl . '">' . $OUTPUT->pix_icon('t/preview', 'core', $strcheckpermissions) . '</a> ';
|
||||
echo ' <a title="' . $strgoto . '" href="' . $raurl . '">' . $OUTPUT->pix_icon('t/edit', $stredit) . '</a> ';
|
||||
echo ' <a title="' . $strcheck . '" href="' . $churl . '">' . $OUTPUT->pix_icon('t/preview', $strcheckpermissions) . '</a> ';
|
||||
echo "</p>\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,8 @@ preferences,moodle|/user/preferences.php|preferences',
|
||||
'idnumber' => new lang_string('sort_idnumber', 'admin'),
|
||||
);
|
||||
$temp->add(new admin_setting_configselect('navsortmycoursessort', new lang_string('navsortmycoursessort', 'admin'), new lang_string('navsortmycoursessort_help', 'admin'), 'sortorder', $sortoptions));
|
||||
$temp->add(new admin_setting_configtext('navcourselimit',new lang_string('navcourselimit','admin'),new lang_string('confignavcourselimit', 'admin'),20,PARAM_INT));
|
||||
$temp->add(new admin_setting_configtext('navcourselimit', new lang_string('navcourselimit', 'admin'),
|
||||
new lang_string('confignavcourselimit', 'admin'), 10, PARAM_INT));
|
||||
$temp->add(new admin_setting_configcheckbox('usesitenameforsitepages', new lang_string('usesitenameforsitepages', 'admin'), new lang_string('configusesitenameforsitepages', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('linkadmincategories', new lang_string('linkadmincategories', 'admin'), new lang_string('linkadmincategories_help', 'admin'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('linkcoursesections', new lang_string('linkcoursesections', 'admin'), new lang_string('linkcoursesections_help', 'admin'), 0));
|
||||
|
||||
@@ -232,7 +232,7 @@ if ($hassiteconfig) {
|
||||
|
||||
// Convert plugins.
|
||||
$ADMIN->add('modules', new admin_category('fileconverterplugins', new lang_string('type_fileconverter_plural', 'plugin')));
|
||||
$temp = new admin_settingpage('managefileconverterplugins', new lang_string('type_fileconverter', 'plugin'));
|
||||
$temp = new admin_settingpage('managefileconverterplugins', new lang_string('type_fileconvertermanage', 'plugin'));
|
||||
$temp->add(new admin_setting_manage_fileconverter_plugins());
|
||||
$ADMIN->add('fileconverterplugins', $temp);
|
||||
|
||||
|
||||
@@ -55,9 +55,6 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$optionalsubsystems->add(new admin_setting_configcheckbox('enableglobalsearch', new lang_string('enableglobalsearch', 'admin'),
|
||||
new lang_string('enableglobalsearch_desc', 'admin'), 0, 1, 0));
|
||||
|
||||
$choices = array();
|
||||
$choices[0] = new lang_string('no');
|
||||
$choices[1] = new lang_string('yes');
|
||||
$optionalsubsystems->add(new admin_setting_configselect('allowstealth', new lang_string('allowstealthmodules'),
|
||||
new lang_string('allowstealthmodules_help'), 0, $choices));
|
||||
$optionalsubsystems->add(new admin_setting_configcheckbox('allowstealth', new lang_string('allowstealthmodules'),
|
||||
new lang_string('allowstealthmodules_help'), 0, 1, 0));
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@ function xmldb_tool_customlang_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ $string['delete_confirmation'] = 'Are you absolutely sure you want to remove <st
|
||||
$string['deletea'] = 'Delete {$a}';
|
||||
$string['deletefiletypes'] = 'Delete a file type';
|
||||
$string['description'] = 'Custom description';
|
||||
$string['description_help'] = 'Simple file type description, e.g. ‘Kindle ebook’. If your site supports multiple languages and uses the multi-language filter, you can enter multi-language tags in this field to supply a description in different languages.';
|
||||
$string['description_help'] = 'Simple file type description, e.g. \'Kindle ebook\'. If your site supports multiple languages and uses the multi-language filter, you can enter multi-language tags in this field to supply a description in different languages.';
|
||||
$string['descriptiontype'] = 'Description type';
|
||||
$string['descriptiontype_help'] = 'There are three possible ways to specify a description.
|
||||
|
||||
@@ -49,15 +49,15 @@ $string['error_defaulticon'] = 'Another file extension with the same MIME type i
|
||||
$string['error_extension'] = 'The file type extension <strong>{$a}</strong> already exists or is invalid. File extensions must be unique and must not contain special characters.';
|
||||
$string['error_notfound'] = 'The file type with extension {$a} cannot be found.';
|
||||
$string['extension'] = 'Extension';
|
||||
$string['extension_help'] = 'File name extension without the dot, e.g. ‘mobi’';
|
||||
$string['extension_help'] = 'File name extension without the dot, e.g. \'mobi\'';
|
||||
$string['groups'] = 'Type groups';
|
||||
$string['groups_help'] = 'Optional list of file type groups that this type belongs to. These are generic categories such as ‘document’ and ‘image’.';
|
||||
$string['groups_help'] = 'Optional list of file type groups that this type belongs to. These are generic categories such as \'document\' and \'image\'.';
|
||||
$string['icon'] = 'File icon';
|
||||
$string['icon_help'] = 'Icon filename.
|
||||
|
||||
The list of icons is taken from the /pix/f directory inside your Moodle installation. You can add custom icons to this folder if required.';
|
||||
$string['mimetype'] = 'MIME type';
|
||||
$string['mimetype_help'] = 'MIME type associated with this file type, e.g. ‘application/x-mobipocket-ebook’';
|
||||
$string['mimetype_help'] = 'MIME type associated with this file type, e.g. \'application/x-mobipocket-ebook\'';
|
||||
$string['pluginname'] = 'File types';
|
||||
$string['revert'] = 'Restore {$a} to Moodle defaults';
|
||||
$string['revert_confirmation'] = 'Are you sure you want to restore <strong>.{$a}</strong> to Moodle defaults, discarding your changes?';
|
||||
|
||||
@@ -40,7 +40,7 @@ if (empty($CFG->langotherroot)) {
|
||||
$mode = optional_param('mode', 0, PARAM_INT); // action
|
||||
$pack = optional_param_array('pack', array(), PARAM_SAFEDIR); // pack to install
|
||||
$uninstalllang = optional_param_array('uninstalllang', array(), PARAM_LANG);// installed pack to uninstall
|
||||
$confirmtounistall = optional_param('confirmtouninstall', '', PARAM_ALPHAEXT); // uninstallation confirmation
|
||||
$confirmtounistall = optional_param('confirmtouninstall', '', PARAM_SAFEPATH); // uninstallation confirmation
|
||||
$purgecaches = optional_param('purgecaches', false, PARAM_BOOL); // explicit caches reset
|
||||
|
||||
if ($purgecaches) {
|
||||
@@ -74,7 +74,7 @@ if ($mode == DELETION_OF_SELECTED_LANG and (!empty($uninstalllang) or !empty($co
|
||||
// Actually deleting languages, languages to delete are passed as GET parameter as string
|
||||
// ...need to populate them to array.
|
||||
if (empty($uninstalllang)) {
|
||||
$uninstalllang = explode('-', $confirmtounistall);
|
||||
$uninstalllang = explode('/', $confirmtounistall);
|
||||
}
|
||||
|
||||
if (in_array('en', $uninstalllang)) {
|
||||
@@ -84,8 +84,10 @@ if ($mode == DELETION_OF_SELECTED_LANG and (!empty($uninstalllang) or !empty($co
|
||||
} else if (empty($confirmtounistall) and confirm_sesskey()) { // User chose langs to be deleted, show confirmation.
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->confirm(get_string('uninstallconfirm', 'tool_langimport', implode(', ', $uninstalllang)),
|
||||
'index.php?mode='.DELETION_OF_SELECTED_LANG.'&confirmtouninstall='.implode('-', $uninstalllang),
|
||||
'index.php');
|
||||
new moodle_url($PAGE->url, array(
|
||||
'mode' => DELETION_OF_SELECTED_LANG,
|
||||
'confirmtouninstall' => implode('/', $uninstalllang),
|
||||
)), $PAGE->url);
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
|
||||
|
||||
@@ -84,8 +84,7 @@ abstract class restore_tool_log_logstore_subplugin extends restore_subplugin {
|
||||
}
|
||||
}
|
||||
|
||||
// Roll dates.
|
||||
$data->timecreated = $this->apply_date_offset($data->timecreated);
|
||||
// There is no need to roll dates. Logs are supposed to be immutable. See MDL-44961.
|
||||
|
||||
// Revert other to its original php way.
|
||||
$data->other = unserialize(base64_decode($data->other));
|
||||
|
||||
@@ -48,5 +48,8 @@ function xmldb_tool_log_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ class store implements \tool_log\log\writer, \core\log\sql_reader {
|
||||
$dboptions['dbport'] = $this->get_config('dbport', '');
|
||||
$dboptions['dbschema'] = $this->get_config('dbschema', '');
|
||||
$dboptions['dbcollation'] = $this->get_config('dbcollation', '');
|
||||
$dboptions['dbhandlesoptions'] = $this->get_config('dbhandlesoptions', false);
|
||||
try {
|
||||
$db->connect($this->get_config('dbhost'), $this->get_config('dbuser'), $this->get_config('dbpass'),
|
||||
$this->get_config('dbname'), false, $dboptions);
|
||||
|
||||
@@ -42,5 +42,8 @@ function xmldb_logstore_database_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ $string['databasesettings_help'] = 'Connection details for the external log data
|
||||
$string['databasepersist'] = 'Persistent database connections';
|
||||
$string['databaseschema'] = 'Database schema';
|
||||
$string['databasecollation'] = 'Database collation';
|
||||
$string['databasehandlesoptions'] = 'Database handles options';
|
||||
$string['databasehandlesoptions_help'] = 'Does the remote database handle its own options.';
|
||||
$string['databasetable'] = 'Database table';
|
||||
$string['databasetable_help'] = 'Name of the table where logs will be stored. This table should have a structure identical to the one used by logstore_standard (mdl_logstore_standard_log).';
|
||||
$string['includeactions'] = 'Include actions of these types';
|
||||
|
||||
@@ -54,6 +54,8 @@ if ($hassiteconfig) {
|
||||
'logstore_database'), '', ''));
|
||||
$settings->add(new admin_setting_configtext('logstore_database/dbcollation', get_string('databasecollation',
|
||||
'logstore_database'), '', ''));
|
||||
$settings->add(new admin_setting_configcheckbox('logstore_database/dbhandlesoptions', get_string('databasehandlesoptions',
|
||||
'logstore_database'), get_string('databasehandlesoptions_help', 'logstore_database'), '0'));
|
||||
$settings->add(new admin_setting_configtext('logstore_database/buffersize', get_string('buffersize',
|
||||
'logstore_database'), get_string('buffersize_help', 'logstore_database'), 50));
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ $dboptions['dbsocket'] = get_config('logstore_database', 'dbsocket');
|
||||
$dboptions['dbport'] = get_config('logstore_database', 'dbport');
|
||||
$dboptions['dbschema'] = get_config('logstore_database', 'dbschema');
|
||||
$dboptions['dbcollation'] = get_config('logstore_database', 'dbcollation');
|
||||
$dboptions['dbhandlesoptions'] = get_config('logstore_database', 'dbhandlesoptions');
|
||||
|
||||
try {
|
||||
$db->connect(get_config('logstore_database', 'dbhost'), get_config('logstore_database', 'dbuser'),
|
||||
|
||||
@@ -83,6 +83,11 @@ class logstore_database_store_testcase extends advanced_testcase {
|
||||
} else {
|
||||
set_config('dbcollation', '', 'logstore_database');
|
||||
}
|
||||
if (!empty($CFG->dboptions['dbhandlesoptions'])) {
|
||||
set_config('dbhandlesoptions', $CFG->dboptions['dbhandlesoptions'], 'logstore_database');
|
||||
} else {
|
||||
set_config('dbhandlesoptions', false, 'logstore_database');
|
||||
}
|
||||
|
||||
// Enable logging plugin.
|
||||
set_config('enabled_stores', 'logstore_database', 'tool_log');
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
This files describes API changes in the logstore_database code.
|
||||
|
||||
=== 3.3.1 ===
|
||||
* PostgreSQL connections now use advanced options to reduce connection overhead. These options are not compatible
|
||||
with some connection poolers. The dbhandlesoptions parameter has been added to allow the database to configure the
|
||||
required defaults. The parameters that are required in the database are;
|
||||
ALTER DATABASE moodle SET client_encoding = UTF8;
|
||||
ALTER DATABASE moodle SET standard_conforming_strings = on;
|
||||
ALTER DATABASE moodle SET search_path = 'moodle,public'; -- Optional, if you wish to use a custom schema.
|
||||
You can set these options against the database or the moodle user who connects.
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2017051501; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->component = 'logstore_database'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -59,5 +59,8 @@ function xmldb_logstore_standard_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div data-region="footer" class="pull-xs-right">
|
||||
<input type="button" data-action="rate" value="{{#str}}rate, tool_lp{{/str}}" class="btn btn-primary">
|
||||
<button data-action="rate" class="btn btn-primary">{{#str}}rate, tool_lp{{/str}}</button>
|
||||
<button data-action="cancel" class="btn btn-secondary">{{#str}}cancel{{/str}}</button>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<div data-region="rule-base" class="form">
|
||||
<div data-region="rule-outcome" class="form-group">
|
||||
<label>{{#str}}outcome, tool_lp{{/str}}</label>
|
||||
<select name="outcome" class="custom-select" ng-label="{{#str}}outcome, tool_lp{{/str}}">
|
||||
<select name="outcome" class="custom-select">
|
||||
{{#outcomes}}
|
||||
<option value="{{code}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/outcomes}}
|
||||
@@ -68,7 +68,7 @@
|
||||
</div>
|
||||
<div data-region="rule-type" class="form-group">
|
||||
<label>{{#str}}when, tool_lp{{/str}}</label>
|
||||
<select name="rule" class="custom-select" ng-label="{{#str}}when, tool_lp{{/str}}">
|
||||
<select name="rule" class="custom-select">
|
||||
<option value="-1">{{#str}}choosedots{{/str}}</option>
|
||||
{{#rules}}
|
||||
<option value="{{type}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
@@ -81,10 +81,11 @@
|
||||
{{/config}}
|
||||
</div>
|
||||
|
||||
<div data-region="footer" class="pull-xs-right">
|
||||
<div data-region="footer" class="pull-xs-right m-t-1">
|
||||
{{#config}}
|
||||
<input type="button" class="btn btn-primary" data-action="save" value="{{#str}}savechanges{{/str}}"/>
|
||||
{{/config}}
|
||||
<input type="button" class="btn btn-secondary" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
|
||||
@@ -97,5 +97,8 @@ function xmldb_tool_monitor_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017021300, 'tool', 'monitor');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -72,15 +72,15 @@ $string['issuerimage'] = 'Logo URL';
|
||||
$string['issuerloginparams'] = 'Additional parameters included in a login request.';
|
||||
$string['issuerloginparams_help'] = 'Some systems require additional parameters for a login request in order to read the user\'s basic profile.';
|
||||
$string['issuerloginparamsoffline'] = 'Additional parameters included in a login request for offline access.';
|
||||
$string['issuerloginparamsoffline_help'] = 'Each OAuth system defines a different way to request offline access. E.g. Google requires the additional params: "access_type=offline&prompt=consent" these parameters should be in url query parameter format.';
|
||||
$string['issuerloginscopes_help'] = 'Some systems require additional scopes for a login request in order to read the users basic profile. The standard scopes for an OpenID Connect compliant system are "openid profile email".';
|
||||
$string['issuerloginscopesoffline_help'] = 'Each OAuth system defines a different way to request offline access. E.g. Microsoft requires an additional scope "offline_access"';
|
||||
$string['issuerloginparamsoffline_help'] = 'Each OAuth system defines a different way to request offline access. E.g. Google requires the additional params: "access_type=offline&prompt=consent". These parameters should be in URL query parameter format.';
|
||||
$string['issuerloginscopes_help'] = 'Some systems require additional scopes for a login request in order to read the user\'s basic profile. The standard scopes for an OpenID Connect compliant system are "openid profile email".';
|
||||
$string['issuerloginscopesoffline_help'] = 'Each OAuth system defines a different way to request offline access. E.g. Microsoft requires an additional scope "offline_access".';
|
||||
$string['issuerloginscopesoffline'] = 'Scopes included in a login request for offline access.';
|
||||
$string['issuerloginscopes'] = 'Scopes included in a login request.';
|
||||
$string['issuername_help'] = 'Name of the identity issuer. May be displayed on login page.';
|
||||
$string['issuername'] = 'Name';
|
||||
$string['issuershowonloginpage_help'] = 'If the OpenID Connect Authentication plugin is enabled, this login issuer will be listed on the login page to allow users to log in with accounts from this issuer.';
|
||||
$string['issuershowonloginpage'] = 'Show on login page.';
|
||||
$string['issuershowonloginpage_help'] = 'If the OAuth 2 authentication plugin is enabled, this login issuer will be listed on the login page to allow users to log in with accounts from this issuer.';
|
||||
$string['issuershowonloginpage'] = 'Show on login page';
|
||||
$string['issuers'] = 'Issuers';
|
||||
$string['loginissuer'] = 'Allow login';
|
||||
$string['notconfigured'] = 'Not configured';
|
||||
|
||||
@@ -31,7 +31,7 @@ $string['default'] = 'Default';
|
||||
$string['disabled'] = 'Disabled';
|
||||
$string['disabled_help'] = 'Disabled scheduled tasks are not executed from cron, however they can still be executed manually via the CLI tool.';
|
||||
$string['edittaskschedule'] = 'Edit task schedule: {$a}';
|
||||
$string['enablerunnow'] = 'Allow ‘Run now’ for scheduled tasks';
|
||||
$string['enablerunnow'] = 'Allow \'Run now\' for scheduled tasks';
|
||||
$string['enablerunnow_desc'] = 'Allows administrators to run a single scheduled task immediately, rather than waiting for it to run as scheduled. The task runs on the web server, so some sites may wish to disable this feature to avoid potential performance issues.';
|
||||
$string['faildelay'] = 'Fail delay';
|
||||
$string['lastruntime'] = 'Last run';
|
||||
@@ -41,7 +41,7 @@ $string['pluginname'] = 'Scheduled task configuration';
|
||||
$string['resettasktodefaults'] = 'Reset task schedule to defaults';
|
||||
$string['resettasktodefaults_help'] = 'This will discard any local changes and revert the schedule for this task back to its original settings.';
|
||||
$string['runnow'] = 'Run now';
|
||||
$string['runnow_confirm'] = 'Are you sure you want to run this task ‘{$a}’ now? The task will run on the web server and may take some time to complete.';
|
||||
$string['runnow_confirm'] = 'Are you sure you want to run this task \'{$a}\' now? The task will run on the web server and may take some time to complete.';
|
||||
$string['scheduledtasks'] = 'Scheduled tasks';
|
||||
$string['scheduledtaskchangesdisabled'] = 'Modifications to the list of scheduled tasks have been prevented in Moodle configuration';
|
||||
$string['taskdisabled'] = 'Task disabled';
|
||||
|
||||
@@ -70,6 +70,9 @@ class api {
|
||||
// Look at all the templates dirs for subsystems.
|
||||
$subsystems = core_component::get_core_subsystems();
|
||||
foreach ($subsystems as $subsystem => $dir) {
|
||||
if (empty($dir)) {
|
||||
continue;
|
||||
}
|
||||
$dir .= '/templates';
|
||||
if (is_dir($dir)) {
|
||||
$dirs = mustache_template_finder::get_template_directories_for_component('core_' . $subsystem, $themename);
|
||||
|
||||
@@ -45,5 +45,8 @@ function xmldb_tool_usertours_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+12
-12
@@ -3187,6 +3187,18 @@ class CAS_Client
|
||||
false/*$no_response*/, true/*$bad_response*/, $text_response
|
||||
);
|
||||
$result = false;
|
||||
} else if ( $tree_response->getElementsByTagName("authenticationFailure")->length != 0) {
|
||||
// authentication failed, extract the error code and message and throw exception
|
||||
$auth_fail_list = $tree_response
|
||||
->getElementsByTagName("authenticationFailure");
|
||||
throw new CAS_AuthenticationException(
|
||||
$this, 'Ticket not validated', $validate_url,
|
||||
false/*$no_response*/, false/*$bad_response*/,
|
||||
$text_response,
|
||||
$auth_fail_list->item(0)->getAttribute('code')/*$err_code*/,
|
||||
trim($auth_fail_list->item(0)->nodeValue)/*$err_msg*/
|
||||
);
|
||||
$result = false;
|
||||
} else if ($tree_response->getElementsByTagName("authenticationSuccess")->length != 0) {
|
||||
// authentication succeded, extract the user name
|
||||
$success_elements = $tree_response
|
||||
@@ -3227,18 +3239,6 @@ class CAS_Client
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
} else if ( $tree_response->getElementsByTagName("authenticationFailure")->length != 0) {
|
||||
// authentication succeded, extract the error code and message
|
||||
$auth_fail_list = $tree_response
|
||||
->getElementsByTagName("authenticationFailure");
|
||||
throw new CAS_AuthenticationException(
|
||||
$this, 'Ticket not validated', $validate_url,
|
||||
false/*$no_response*/, false/*$bad_response*/,
|
||||
$text_response,
|
||||
$auth_fail_list->item(0)->getAttribute('code')/*$err_code*/,
|
||||
trim($auth_fail_list->item(0)->nodeValue)/*$err_msg*/
|
||||
);
|
||||
$result = false;
|
||||
} else {
|
||||
throw new CAS_AuthenticationException(
|
||||
$this, 'Ticket not validated', $validate_url,
|
||||
|
||||
@@ -2,3 +2,4 @@ Description of phpCAS 1.3.4 library import
|
||||
|
||||
* downloaded from http://downloads.jasig.org/cas-clients/php/current/
|
||||
|
||||
* MDL-59456 phpCAS library has been patched because of an authentication bypass security vulnerability.
|
||||
@@ -66,5 +66,8 @@ function xmldb_auth_cas_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'cas');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ class login implements renderable, templatable {
|
||||
$data->error = $this->error;
|
||||
$data->forgotpasswordurl = $this->forgotpasswordurl->out(false);
|
||||
$data->hasidentityproviders = !empty($this->identityproviders);
|
||||
$data->hasinstructions = !empty($this->instructions);
|
||||
$data->hasinstructions = !empty($this->instructions) || $this->cansignup;
|
||||
$data->identityproviders = $identityproviders;
|
||||
list($data->instructions, $data->instructionsformat) = external_format_text($this->instructions, FORMAT_MOODLE,
|
||||
context_system::instance()->id);
|
||||
|
||||
@@ -42,5 +42,8 @@ function xmldb_auth_db_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017032800, 'auth', 'db');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,5 +42,8 @@ function xmldb_auth_email_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'email');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,5 +42,8 @@ function xmldb_auth_fc_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'fc');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,5 +42,8 @@ function xmldb_auth_imap_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'imap');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+9
-9
@@ -276,7 +276,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
$ldapval = NULL;
|
||||
foreach ($values as $value) {
|
||||
$entry = array_change_key_case($user_entry[0], CASE_LOWER);
|
||||
$entry = $user_entry[0];
|
||||
if (($value == 'dn') || ($value == 'distinguishedname')) {
|
||||
$result[$key] = $user_dn;
|
||||
continue;
|
||||
@@ -634,7 +634,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
if ($sr) {
|
||||
$info = ldap_get_entries_moodle($ldapconnection, $sr);
|
||||
if (!empty ($info)) {
|
||||
$info = array_change_key_case($info[0], CASE_LOWER);
|
||||
$info = $info[0];
|
||||
if (isset($info[$this->config->expireattr][0])) {
|
||||
$expiretime = $this->ldap_expirationtime2unix($info[$this->config->expireattr][0], $ldapconnection, $user_dn);
|
||||
if ($expiretime != 0) {
|
||||
@@ -1201,7 +1201,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
return false;
|
||||
}
|
||||
|
||||
$user_entry = array_change_key_case($user_entry[0], CASE_LOWER);
|
||||
$user_entry = $user_entry[0];
|
||||
|
||||
foreach ($attrmap as $key => $ldapkeys) {
|
||||
$profilefield = '';
|
||||
@@ -1369,7 +1369,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
$sr = ldap_read($ldapconnection, $user_dn, '(objectClass=*)', $search_attribs);
|
||||
if ($sr) {
|
||||
$entry = ldap_get_entries_moodle($ldapconnection, $sr);
|
||||
$info = array_change_key_case($entry[0], CASE_LOWER);
|
||||
$info = $entry[0];
|
||||
$newattrs = array();
|
||||
if (!empty($info[$this->config->expireattr][0])) {
|
||||
// Set expiration time only if passwordExpirationInterval is defined
|
||||
@@ -1844,7 +1844,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
|
||||
$entry = ldap_get_entries_moodle($ldapconn, $sr);
|
||||
$info = array_change_key_case($entry[0], CASE_LOWER);
|
||||
$info = $entry[0];
|
||||
$useraccountcontrol = $info['useraccountcontrol'][0];
|
||||
if ($useraccountcontrol & UF_DONT_EXPIRE_PASSWD) {
|
||||
// Password doesn't expire.
|
||||
@@ -1889,17 +1889,17 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
|
||||
$entry = ldap_get_entries_moodle($ldapconn, $sr);
|
||||
$info = array_change_key_case($entry[0], CASE_LOWER);
|
||||
$info = $entry[0];
|
||||
$domaindn = $info['defaultnamingcontext'][0];
|
||||
|
||||
$sr = ldap_read ($ldapconn, $domaindn, '(objectClass=*)',
|
||||
array('maxPwdAge'));
|
||||
$entry = ldap_get_entries_moodle($ldapconn, $sr);
|
||||
$info = array_change_key_case($entry[0], CASE_LOWER);
|
||||
$info = $entry[0];
|
||||
$maxpwdage = $info['maxpwdage'][0];
|
||||
if ($sr = ldap_read($ldapconn, $user_dn, '(objectClass=*)', array('msDS-ResultantPSO'))) {
|
||||
if ($entry = ldap_get_entries_moodle($ldapconn, $sr)) {
|
||||
$info = array_change_key_case($entry[0], CASE_LOWER);
|
||||
$info = $entry[0];
|
||||
$userpso = $info['msds-resultantpso'][0];
|
||||
|
||||
// If a PSO exists, FGPP is being utilized.
|
||||
@@ -1907,7 +1907,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
if (!empty($userpso)) {
|
||||
$sr = ldap_read($ldapconn, $userpso, '(objectClass=*)', array('msDS-MaximumPasswordAge'));
|
||||
if ($entry = ldap_get_entries_moodle($ldapconn, $sr)) {
|
||||
$info = array_change_key_case($entry[0], CASE_LOWER);
|
||||
$info = $entry[0];
|
||||
// Default value of msds-maximumpasswordage is 42 and is always set.
|
||||
$maxpwdage = $info['msds-maximumpasswordage'][0];
|
||||
}
|
||||
|
||||
@@ -66,5 +66,8 @@ function xmldb_auth_ldap_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'ldap');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -54,5 +54,8 @@ function xmldb_auth_manual_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'manual');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -53,5 +53,8 @@ function xmldb_auth_mnet_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'mnet');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,5 +42,8 @@ function xmldb_auth_nntp_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'nntp');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,5 +42,8 @@ function xmldb_auth_none_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'none');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,16 @@ defined('MOODLE_INTERNAL') || die();
|
||||
*/
|
||||
class api {
|
||||
|
||||
/**
|
||||
* Remove all linked logins that are using issuers that have been deleted.
|
||||
*
|
||||
* @param int $issuerid The issuer id of the issuer to check, or false to check all (defaults to all)
|
||||
* @return boolean
|
||||
*/
|
||||
public static function clean_orphaned_linked_logins($issuerid = false) {
|
||||
return linked_login::delete_orphaned($issuerid);
|
||||
}
|
||||
|
||||
/**
|
||||
* List linked logins
|
||||
*
|
||||
@@ -105,6 +115,10 @@ class api {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
|
||||
if (linked_login::has_existing_issuer_match($issuer, $userinfo['username'])) {
|
||||
throw new moodle_exception('alreadylinked', 'auth_oauth2');
|
||||
}
|
||||
|
||||
if (\core\session\manager::is_loggedinas()) {
|
||||
throw new moodle_exception('notwhileloggedinas', 'auth_oauth2');
|
||||
}
|
||||
@@ -144,9 +158,8 @@ class api {
|
||||
$record->issuerid = $issuer->get('id');
|
||||
$record->username = $userinfo['username'];
|
||||
$record->userid = $userid;
|
||||
$existing = linked_login::get_record((array)$record);
|
||||
if ($existing) {
|
||||
return false;
|
||||
if (linked_login::has_existing_issuer_match($issuer, $userinfo['username'])) {
|
||||
throw new moodle_exception('alreadylinked', 'auth_oauth2');
|
||||
}
|
||||
$record->email = $userinfo['email'];
|
||||
$record->confirmtoken = random_string(32);
|
||||
@@ -179,10 +192,10 @@ class api {
|
||||
];
|
||||
$confirmationurl = new moodle_url('/auth/oauth2/confirm-linkedlogin.php', $params);
|
||||
|
||||
// Remove data parameter just in case it was included in the confirmation so we can add it manually later.
|
||||
$data->link = $confirmationurl->out();
|
||||
$data->link = $confirmationurl->out(false);
|
||||
$message = get_string('confirmlinkedloginemail', 'auth_oauth2', $data);
|
||||
|
||||
$message = get_string('confirmlinkedloginemail', 'auth_oauth2', $data);
|
||||
$data->link = $confirmationurl->out();
|
||||
$messagehtml = text_to_html(get_string('confirmlinkedloginemail', 'auth_oauth2', $data), false, false, true);
|
||||
|
||||
$user->mailformat = 1; // Always send HTML version as well.
|
||||
@@ -239,6 +252,10 @@ class api {
|
||||
require_once($CFG->dirroot.'/user/profile/lib.php');
|
||||
require_once($CFG->dirroot.'/user/lib.php');
|
||||
|
||||
if (linked_login::has_existing_issuer_match($issuer, $userinfo['username'])) {
|
||||
throw new moodle_exception('alreadylinked', 'auth_oauth2');
|
||||
}
|
||||
|
||||
$user = new stdClass();
|
||||
$user->username = $userinfo['username'];
|
||||
$user->email = $userinfo['email'];
|
||||
@@ -286,9 +303,10 @@ class api {
|
||||
];
|
||||
$confirmationurl = new moodle_url('/auth/oauth2/confirm-account.php', $params);
|
||||
|
||||
$data->link = $confirmationurl->out();
|
||||
$data->link = $confirmationurl->out(false);
|
||||
$message = get_string('confirmaccountemail', 'auth_oauth2', $data);
|
||||
|
||||
$message = get_string('confirmaccountemail', 'auth_oauth2', $data);
|
||||
$data->link = $confirmationurl->out();
|
||||
$messagehtml = text_to_html(get_string('confirmaccountemail', 'auth_oauth2', $data), false, false, true);
|
||||
|
||||
$user->mailformat = 1; // Always send HTML version as well.
|
||||
@@ -319,4 +337,28 @@ class api {
|
||||
|
||||
$login->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete linked logins for a user.
|
||||
*
|
||||
* @param \core\event\user_deleted $event
|
||||
* @return boolean
|
||||
*/
|
||||
public static function user_deleted(\core\event\user_deleted $event) {
|
||||
global $DB;
|
||||
|
||||
$userid = $event->objectid;
|
||||
|
||||
return $DB->delete_records(linked_login::TABLE, ['userid' => $userid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the plugin enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_enabled() {
|
||||
$plugininfo = \core_plugin_manager::instance()->get_plugin_info('auth_oauth2');
|
||||
return $plugininfo->is_enabled();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,6 +247,10 @@ class auth extends \auth_plugin_base {
|
||||
if (!empty($user->picture)) {
|
||||
return false;
|
||||
}
|
||||
if (!empty($CFG->enablegravatar)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$picture = $this->get_static_user_picture();
|
||||
if (empty($picture)) {
|
||||
return false;
|
||||
@@ -342,7 +346,7 @@ class auth extends \auth_plugin_base {
|
||||
* Complete the login process after oauth handshake is complete.
|
||||
* @param \core\oauth2\client $client
|
||||
* @param string $redirecturl
|
||||
* @return none Either redirects or throws an exception
|
||||
* @return void Either redirects or throws an exception
|
||||
*/
|
||||
public function complete_login(client $client, $redirecturl) {
|
||||
global $CFG, $SESSION, $PAGE;
|
||||
@@ -352,7 +356,7 @@ class auth extends \auth_plugin_base {
|
||||
if (!$userinfo) {
|
||||
// Trigger login failed event.
|
||||
$failurereason = AUTH_LOGIN_NOUSER;
|
||||
$event = \core\event\user_login_failed::create(['other' => ['username' => $userinfo['username'],
|
||||
$event = \core\event\user_login_failed::create(['other' => ['username' => 'unknown',
|
||||
'reason' => $failurereason]]);
|
||||
$event->trigger();
|
||||
|
||||
@@ -364,7 +368,7 @@ class auth extends \auth_plugin_base {
|
||||
if (empty($userinfo['username']) || empty($userinfo['email'])) {
|
||||
// Trigger login failed event.
|
||||
$failurereason = AUTH_LOGIN_NOUSER;
|
||||
$event = \core\event\user_login_failed::create(['other' => ['username' => $userinfo['username'],
|
||||
$event = \core\event\user_login_failed::create(['other' => ['username' => 'unknown',
|
||||
'reason' => $failurereason]]);
|
||||
$event->trigger();
|
||||
|
||||
|
||||
@@ -65,4 +65,49 @@ class linked_login extends persistent {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether there are any valid linked accounts for this issuer
|
||||
* and username combination.
|
||||
*
|
||||
* @param \core\oauth2\issuer $issuer The issuer
|
||||
* @param string $username The username to check
|
||||
*/
|
||||
public static function has_existing_issuer_match(\core\oauth2\issuer $issuer, $username) {
|
||||
global $DB;
|
||||
|
||||
$where = "issuerid = :issuerid
|
||||
AND username = :username
|
||||
AND (confirmtokenexpires = 0 OR confirmtokenexpires > :maxexpiry)";
|
||||
|
||||
$count = $DB->count_records_select(static::TABLE, $where, [
|
||||
'issuerid' => $issuer->get('id'),
|
||||
'username' => $username,
|
||||
'maxexpiry' => (new \DateTime('NOW'))->getTimestamp(),
|
||||
]);
|
||||
|
||||
return $count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all linked logins that are using issuers that have been deleted.
|
||||
*
|
||||
* @param int $issuerid The issuer id of the issuer to check, or false to check all (defaults to all)
|
||||
* @return boolean
|
||||
*/
|
||||
public static function delete_orphaned($issuerid = false) {
|
||||
global $DB;
|
||||
// Delete any linked_login entries with a issuerid
|
||||
// which does not exist in the issuer table.
|
||||
// In the left join, the issuer id will be null
|
||||
// where a match linked_login.issuerid is not found.
|
||||
$sql = "DELETE FROM {" . self::TABLE . "}
|
||||
WHERE issuerid NOT IN (SELECT id FROM {" . \core\oauth2\issuer::TABLE . "})";
|
||||
$params = [];
|
||||
if (!empty($issuerid)) {
|
||||
$sql .= ' AND issuerid = ?';
|
||||
$params['issuerid'] = $issuerid;
|
||||
}
|
||||
return $DB->execute($sql, $params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ $PAGE->set_context(context_system::instance());
|
||||
|
||||
$auth = get_auth_plugin('oauth2');
|
||||
|
||||
if (!\auth_oauth2\api::is_enabled()) {
|
||||
throw new \moodle_exception('notenabled', 'auth_oauth2');
|
||||
}
|
||||
|
||||
$confirmed = $auth->user_confirm($username, $usersecret);
|
||||
|
||||
if ($confirmed == AUTH_CONFIRM_ALREADY) {
|
||||
@@ -85,7 +89,7 @@ if ($confirmed == AUTH_CONFIRM_ALREADY) {
|
||||
echo $OUTPUT->footer();
|
||||
exit;
|
||||
} else {
|
||||
print_error('invalidconfirmdata');
|
||||
\core\notification::error(get_string('confirmationinvalid', 'auth_oauth2'));
|
||||
}
|
||||
|
||||
redirect("$CFG->wwwroot/");
|
||||
|
||||
@@ -34,6 +34,10 @@ $redirect = optional_param('redirect', '', PARAM_LOCALURL); // Where to redir
|
||||
$PAGE->set_url('/auth/oauth2/confirm-linkedlogin.php');
|
||||
$PAGE->set_context(context_system::instance());
|
||||
|
||||
if (!\auth_oauth2\api::is_enabled()) {
|
||||
throw new \moodle_exception('notenabled', 'auth_oauth2');
|
||||
}
|
||||
|
||||
$confirmed = \auth_oauth2\api::confirm_link_login($userid, $username, $issuerid, $token);
|
||||
|
||||
if ($confirmed) {
|
||||
@@ -72,7 +76,7 @@ if ($confirmed) {
|
||||
echo $OUTPUT->footer();
|
||||
exit;
|
||||
} else {
|
||||
print_error('invalidconfirmdata');
|
||||
\core\notification::error(get_string('confirmationinvalid', 'auth_oauth2'));
|
||||
}
|
||||
|
||||
redirect("$CFG->wwwroot/");
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* This file definies observers needed by the plugin.
|
||||
*
|
||||
* @package auth_oauth2
|
||||
* @copyright 2017 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
// List of observers.
|
||||
$observers = [
|
||||
[
|
||||
'eventname' => '\core\event\user_deleted',
|
||||
'callback' => '\auth_oauth2\api::user_deleted',
|
||||
],
|
||||
];
|
||||
@@ -38,5 +38,8 @@ function xmldb_auth_oauth2_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ line at the top of your web browser window.
|
||||
If you need help, please contact the site administrator,
|
||||
{$a->admin}';
|
||||
$string['confirmaccountemailsubject'] = '{$a}: account confirmation';
|
||||
$string['confirmationinvalid'] = 'The confirmation link is either invalid, or has expired. Please start the login process again to generate a new confirmation email.';
|
||||
$string['confirmationpending'] = 'This account is pending email confirmation.';
|
||||
$string['confirmlinkedloginemail'] = 'Hi {$a->fullname},
|
||||
|
||||
@@ -71,15 +72,19 @@ $string['emailconfirmlinksent'] = '<p>An existing account was found with this em
|
||||
<p>If you have any difficulty, contact the site administrator.</p>';
|
||||
$string['info'] = 'External account';
|
||||
$string['issuer'] = 'OAuth 2 Service';
|
||||
$string['issuernologin'] = 'This issuer can not be used to login';
|
||||
$string['linkedlogins'] = 'Linked logins';
|
||||
$string['linkedloginshelp'] = 'Help with linked logins';
|
||||
$string['loginerror_userincomplete'] = 'The user information returned did not contain a username and email address. The OAuth 2 service may be configured incorrectly.';
|
||||
$string['loginerror_nouserinfo'] = 'No user information was returned. The OAuth 2 service may be configured incorrectly.';
|
||||
$string['loginerror_invaliddomain'] = 'The email address is not allowed at this site.';
|
||||
$string['loginerror_authenticationfailed'] = 'The authentication process failed.';
|
||||
$string['loginerror_cannotcreateaccounts'] = 'The account does not exist and this site does not allow self-registration.';
|
||||
$string['loginerror_cannotcreateaccounts'] = 'An account with your email address could not be found.';
|
||||
$string['noissuersavailable'] = 'None of the configured OAuth2 services allow you to link login accounts';
|
||||
$string['notloggedindebug'] = 'The login attempt failed. Reason: {$a}';
|
||||
$string['notwhileloggedinas'] = 'Linked logins cannot be managed while logged in as another user.';
|
||||
$string['oauth2:managelinkedlogins'] = 'Manage own linked login accounts';
|
||||
$string['notenabled'] = 'Sorry, OAuth 2 authentication plugin is not enabled';
|
||||
$string['plugindescription'] = 'This authentication plugin displays a list of the configured identity providers on the login page. Selecting an identity provider allows users to login with their credentials from an OAuth 2 provider.';
|
||||
$string['pluginname'] = 'OAuth 2';
|
||||
$string['alreadylinked'] = 'This external account is already linked to an account on this site';
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ function auth_oauth2_extend_navigation_user_settings(navigation_node $useraccoun
|
||||
context_course $coursecontext) {
|
||||
global $USER;
|
||||
|
||||
if (!\core\session\manager::is_loggedinas()) {
|
||||
if (\auth_oauth2\api::is_enabled() && !\core\session\manager::is_loggedinas()) {
|
||||
if (has_capability('auth/oauth2:managelinkedlogins', $context) && $user->id == $USER->id) {
|
||||
|
||||
$parent = $useraccount->parent->find('useraccount', navigation_node::TYPE_CONTAINER);
|
||||
|
||||
@@ -35,12 +35,19 @@ $PAGE->set_heading($strheading);
|
||||
|
||||
require_login();
|
||||
|
||||
if (!\auth_oauth2\api::is_enabled()) {
|
||||
throw new \moodle_exception('notenabled', 'auth_oauth2');
|
||||
}
|
||||
|
||||
$action = optional_param('action', '', PARAM_ALPHAEXT);
|
||||
if ($action == 'new') {
|
||||
require_sesskey();
|
||||
$issuerid = required_param('issuerid', PARAM_INT);
|
||||
$issuer = \core\oauth2\api::get_issuer($issuerid);
|
||||
|
||||
if (!$issuer->is_authentication_supported() || !$issuer->get('showonloginpage') || !$issuer->get('enabled')) {
|
||||
throw new \moodle_exception('issuernologin', 'auth_oauth2');
|
||||
}
|
||||
|
||||
// We do a login dance with this issuer.
|
||||
$addparams = ['action' => 'new', 'issuerid' => $issuerid, 'sesskey' => sesskey()];
|
||||
@@ -58,8 +65,12 @@ if ($action == 'new') {
|
||||
$userinfo = $client->get_userinfo();
|
||||
|
||||
if (!empty($userinfo)) {
|
||||
\auth_oauth2\api::link_login($userinfo, $issuer);
|
||||
redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
|
||||
try {
|
||||
\auth_oauth2\api::link_login($userinfo, $issuer);
|
||||
redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
|
||||
} catch (Exception $e) {
|
||||
redirect($PAGE->url, $e->getMessage(), null, \core\output\notification::NOTIFY_ERROR);
|
||||
}
|
||||
} else {
|
||||
redirect($PAGE->url, get_string('notloggedin', 'auth_oauth2'), null, \core\output\notification::NOTIFY_ERROR);
|
||||
}
|
||||
@@ -76,6 +87,29 @@ $renderer = $PAGE->get_renderer('auth_oauth2');
|
||||
$linkedloginid = optional_param('id', '', PARAM_RAW);
|
||||
$linkedlogin = null;
|
||||
|
||||
auth_oauth2\api::clean_orphaned_linked_logins();
|
||||
|
||||
$issuers = \core\oauth2\api::get_all_issuers();
|
||||
|
||||
$anyshowinloginpage = false;
|
||||
$issuerbuttons = array();
|
||||
foreach ($issuers as $issuer) {
|
||||
if (!$issuer->is_authentication_supported() || !$issuer->get('showonloginpage') || !$issuer->get('enabled')) {
|
||||
continue;
|
||||
}
|
||||
$anyshowinloginpage = true;
|
||||
|
||||
$addparams = ['action' => 'new', 'issuerid' => $issuer->get('id'), 'sesskey' => sesskey(), 'logout' => true];
|
||||
$addurl = new moodle_url('/auth/oauth2/linkedlogins.php', $addparams);
|
||||
$issuerbuttons[$issuer->get('id')] = $renderer->single_button($addurl, get_string('createnewlinkedlogin', 'auth_oauth2', s($issuer->get('name'))));
|
||||
}
|
||||
|
||||
if (!$anyshowinloginpage) {
|
||||
// Just a notification that we can't make it.
|
||||
$preferencesurl = new moodle_url('/user/preferences.php');
|
||||
redirect($preferencesurl, get_string('noissuersavailable', 'auth_oauth2'), null, \core\output\notification::NOTIFY_WARNING);
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading(get_string('linkedlogins', 'auth_oauth2'));
|
||||
echo $OUTPUT->doc_link('Linked_Logins', get_string('linkedloginshelp', 'auth_oauth2'));
|
||||
@@ -83,17 +117,10 @@ $linkedlogins = auth_oauth2\api::get_linked_logins();
|
||||
|
||||
echo $renderer->linked_logins_table($linkedlogins);
|
||||
|
||||
$issuers = \core\oauth2\api::get_all_issuers();
|
||||
|
||||
foreach ($issuers as $issuer) {
|
||||
if (!$issuer->is_authentication_supported()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$addparams = ['action' => 'new', 'issuerid' => $issuer->get('id'), 'sesskey' => sesskey(), 'logout' => true];
|
||||
$addurl = new moodle_url('/auth/oauth2/linkedlogins.php', $addparams);
|
||||
echo $renderer->single_button($addurl, get_string('createnewlinkedlogin', 'auth_oauth2', s($issuer->get('name'))));
|
||||
foreach ($issuerbuttons as $issuerbutton) {
|
||||
echo $issuerbutton;
|
||||
}
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@ $wantsurl = new moodle_url(optional_param('wantsurl', '', PARAM_URL));
|
||||
|
||||
require_sesskey();
|
||||
|
||||
if (!\auth_oauth2\api::is_enabled()) {
|
||||
throw new \moodle_exception('notenabled', 'auth_oauth2');
|
||||
}
|
||||
|
||||
$issuer = new \core\oauth2\issuer($issuerid);
|
||||
|
||||
$returnparams = ['wantsurl' => $wantsurl, 'sesskey' => sesskey(), 'id' => $issuerid];
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Auth oauth2 api functions tests.
|
||||
*
|
||||
* @package auth_oauth2
|
||||
* @copyright 2017 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
|
||||
/**
|
||||
* External auth oauth2 API tests.
|
||||
*
|
||||
* @package auth_oauth2
|
||||
* @copyright 2017 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class auth_oauth2_external_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test the cleaning of orphaned linked logins for all issuers.
|
||||
*/
|
||||
public function test_clean_orphaned_linked_logins() {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$issuer = \core\oauth2\api::create_standard_issuer('google');
|
||||
\core\oauth2\api::create_standard_issuer('microsoft');
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$info = [];
|
||||
$info['username'] = 'banana';
|
||||
$info['email'] = 'banana@example.com';
|
||||
\auth_oauth2\api::link_login($info, $issuer, $user->id, false);
|
||||
|
||||
\core\oauth2\api::delete_issuer($issuer->get('id'));
|
||||
|
||||
$linkedlogins = \auth_oauth2\api::get_linked_logins($user->id, $issuer);
|
||||
$this->assertCount(1, $linkedlogins);
|
||||
|
||||
\auth_oauth2\api::clean_orphaned_linked_logins();
|
||||
|
||||
$linkedlogins = \auth_oauth2\api::get_linked_logins($user->id, $issuer);
|
||||
$this->assertCount(0, $linkedlogins);
|
||||
|
||||
$match = \auth_oauth2\api::match_username_to_user('banana', $issuer);
|
||||
$this->assertFalse($match);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the cleaning of orphaned linked logins for a specific issuer.
|
||||
*/
|
||||
public function test_clean_orphaned_linked_logins_with_issuer_id() {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$issuer1 = \core\oauth2\api::create_standard_issuer('google');
|
||||
$issuer2 = \core\oauth2\api::create_standard_issuer('microsoft');
|
||||
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$info = [];
|
||||
$info['username'] = 'banana';
|
||||
$info['email'] = 'banana@example.com';
|
||||
\auth_oauth2\api::link_login($info, $issuer1, $user1->id, false);
|
||||
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$info = [];
|
||||
$info['username'] = 'apple';
|
||||
$info['email'] = 'apple@example.com';
|
||||
\auth_oauth2\api::link_login($info, $issuer2, $user2->id, false);
|
||||
|
||||
\core\oauth2\api::delete_issuer($issuer1->get('id'));
|
||||
|
||||
\auth_oauth2\api::clean_orphaned_linked_logins($issuer1->get('id'));
|
||||
|
||||
$linkedlogins = \auth_oauth2\api::get_linked_logins($user1->id, $issuer1);
|
||||
$this->assertCount(0, $linkedlogins);
|
||||
|
||||
$linkedlogins = \auth_oauth2\api::get_linked_logins($user2->id, $issuer2);
|
||||
$this->assertCount(1, $linkedlogins);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2017051501; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->component = 'auth_oauth2'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -42,5 +42,8 @@ function xmldb_auth_pam_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'pam');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,5 +42,8 @@ function xmldb_auth_pop3_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'pop3');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,5 +42,8 @@ function xmldb_auth_shibboleth_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2017020700, 'auth', 'shibboleth');
|
||||
}
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,17 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* This script is used to configure and execute the backup proccess.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage backup
|
||||
* @copyright Moodle
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||
require_once($CFG->dirroot . '/backup/moodle2/backup_plan_builder.class.php');
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* This script is used to configure and execute the import proccess.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage backup
|
||||
* @copyright Moodle
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
// Require both the backup and restore libs
|
||||
require_once('../config.php');
|
||||
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||
|
||||
@@ -2658,8 +2658,9 @@ class restore_calendarevents_structure_step extends restore_structure_step {
|
||||
$isuseroverride = !$data->courseid && $data->modulename && $data->instance;
|
||||
|
||||
// If we don't want to include user data and this record is a user override event
|
||||
// for an activity then we should not create it.
|
||||
if (!$this->task->get_setting_value('userinfo') && $isuseroverride) {
|
||||
// for an activity then we should not create it. (Only activity events can be user override events - which must have this
|
||||
// setting).
|
||||
if ($isuseroverride && $this->task->setting_exists('userinfo') && !$this->task->get_setting_value('userinfo')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2705,16 +2706,16 @@ class restore_calendarevents_structure_step extends restore_structure_step {
|
||||
'userid' => $data->userid,
|
||||
'repeatid' => $this->get_mappingid('event', $data->repeatid),
|
||||
'modulename' => $data->modulename,
|
||||
'type' => $data->type,
|
||||
'type' => isset($data->type) ? $data->type : 0,
|
||||
'eventtype' => $data->eventtype,
|
||||
'timestart' => $this->apply_date_offset($data->timestart),
|
||||
'timeduration' => $data->timeduration,
|
||||
'timesort' => $this->apply_date_offset($data->timesort),
|
||||
'timesort' => isset($data->timesort) ? $this->apply_date_offset($data->timesort) : null,
|
||||
'visible' => $data->visible,
|
||||
'uuid' => $data->uuid,
|
||||
'sequence' => $data->sequence,
|
||||
'timemodified' => $this->apply_date_offset($data->timemodified),
|
||||
'priority' => $data->priority);
|
||||
'priority' => isset($data->priority) ? $data->priority : null);
|
||||
if ($this->name == 'activity_calendar') {
|
||||
$params['instance'] = $this->task->get_activityid();
|
||||
} else {
|
||||
@@ -3082,7 +3083,8 @@ class restore_course_logs_structure_step extends restore_structure_step {
|
||||
|
||||
$data = (object)($data);
|
||||
|
||||
$data->time = $this->apply_date_offset($data->time);
|
||||
// There is no need to roll dates. Logs are supposed to be immutable. See MDL-44961.
|
||||
|
||||
$data->userid = $this->get_mappingid('user', $data->userid);
|
||||
$data->course = $this->get_courseid();
|
||||
$data->cmid = 0;
|
||||
@@ -3129,7 +3131,8 @@ class restore_activity_logs_structure_step extends restore_course_logs_structure
|
||||
|
||||
$data = (object)($data);
|
||||
|
||||
$data->time = $this->apply_date_offset($data->time);
|
||||
// There is no need to roll dates. Logs are supposed to be immutable. See MDL-44961.
|
||||
|
||||
$data->userid = $this->get_mappingid('user', $data->userid);
|
||||
$data->course = $this->get_courseid();
|
||||
$data->cmid = $this->task->get_moduleid();
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Tests for backup_xml_transformer class.
|
||||
*
|
||||
* @package core_backup
|
||||
* @subpackage moodle2
|
||||
* @category backup
|
||||
* @copyright 2017 Dmitrii Metelkin (dmitriim@catalyst-au.net)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||
require_once($CFG->dirroot . '/backup/moodle2/backup_plan_builder.class.php');
|
||||
|
||||
/**
|
||||
* Tests for backup_xml_transformer.
|
||||
*
|
||||
* @package core_backup
|
||||
* @copyright 2017 Dmitrii Metelkin (dmitriim@catalyst-au.net)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class backup_xml_transformer_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Initial set up.
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for ::test_filephp_links_replace.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function filephp_links_replace_data_provider() {
|
||||
return array(
|
||||
array('http://test.test/', 'http://test.test/'),
|
||||
array('http://test.test/file.php/1', 'http://test.test/file.php/1'),
|
||||
array('http://test.test/file.php/2/1.jpg', 'http://test.test/file.php/2/1.jpg'),
|
||||
array('http://test.test/file.php/2', 'http://test.test/file.php/2'),
|
||||
array('http://test.test/file.php/1/1.jpg', '$@FILEPHP@$$@SLASH@$1.jpg'),
|
||||
array('http://test.test/file.php/1//1.jpg', '$@FILEPHP@$$@SLASH@$$@SLASH@$1.jpg'),
|
||||
array('http://test.test/file.php?file=/1', '$@FILEPHP@$'),
|
||||
array('http://test.test/file.php?file=/2/1.jpg', 'http://test.test/file.php?file=/2/1.jpg'),
|
||||
array('http://test.test/file.php?file=/2', 'http://test.test/file.php?file=/2'),
|
||||
array('http://test.test/file.php?file=/1/1.jpg', '$@FILEPHP@$$@SLASH@$1.jpg'),
|
||||
array('http://test.test/file.php?file=/1//1.jpg', '$@FILEPHP@$$@SLASH@$$@SLASH@$1.jpg'),
|
||||
array('http://test.test/file.php?file=%2f1', '$@FILEPHP@$'),
|
||||
array('http://test.test/file.php?file=%2f2%2f1.jpg', 'http://test.test/file.php?file=%2f2%2f1.jpg'),
|
||||
array('http://test.test/file.php?file=%2f2', 'http://test.test/file.php?file=%2f2'),
|
||||
array('http://test.test/file.php?file=%2f1%2f1.jpg', '$@FILEPHP@$$@SLASH@$1.jpg'),
|
||||
array('http://test.test/file.php?file=%2f1%2f%2f1.jpg', '$@FILEPHP@$$@SLASH@$$@SLASH@$1.jpg'),
|
||||
array('http://test.test/file.php?file=%2F1', '$@FILEPHP@$'),
|
||||
array('http://test.test/file.php?file=%2F2%2F1.jpg', 'http://test.test/file.php?file=%2F2%2F1.jpg'),
|
||||
array('http://test.test/file.php?file=%2F2', 'http://test.test/file.php?file=%2F2'),
|
||||
array('http://test.test/file.php?file=%2F1%2F1.jpg', '$@FILEPHP@$$@SLASH@$1.jpg'),
|
||||
array('http://test.test/file.php?file=%2F1%2F%2F1.jpg', '$@FILEPHP@$$@SLASH@$$@SLASH@$1.jpg'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that backup_xml_transformer replaces file php links to $@FILEPHP@$.
|
||||
*
|
||||
* @dataProvider filephp_links_replace_data_provider
|
||||
* @param string $content Testing content.
|
||||
* @param string $expected Expected result.
|
||||
*/
|
||||
public function test_filephp_links_replace($content, $expected) {
|
||||
global $CFG;
|
||||
|
||||
$CFG->wwwroot = 'http://test.test';
|
||||
|
||||
$transformer = new backup_xml_transformer(1);
|
||||
|
||||
$this->assertEquals($expected, $transformer->process($content));
|
||||
}
|
||||
|
||||
}
|
||||
+25
-1
@@ -1,5 +1,29 @@
|
||||
<?php
|
||||
//This script is used to configure and execute the restore proccess.
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* This script is used to configure and execute the restore proccess.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage backup
|
||||
* @copyright Moodle
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
|
||||
|
||||
@@ -60,17 +60,26 @@ class restore_structure_parser_processor extends grouped_parser_processor {
|
||||
} else if (strpos($cdata, '$@FILEPHP@$') === false) { // No $@FILEPHP@$, nothing to convert
|
||||
return $cdata;
|
||||
}
|
||||
|
||||
if ($CFG->slasharguments) {
|
||||
$slash = '/';
|
||||
$forcedownload = '?forcedownload=1';
|
||||
} else {
|
||||
$slash = '%2F';
|
||||
$forcedownload = '&forcedownload=1';
|
||||
}
|
||||
|
||||
// We have to remove trailing slashes, otherwise file URLs will be restored with an extra slash.
|
||||
$basefileurl = rtrim(moodle_url::make_legacyfile_url($this->courseid, null)->out(true), $slash);
|
||||
// Decode file.php calls
|
||||
$search = array ("$@FILEPHP@$");
|
||||
$replace = array(moodle_url::make_legacyfile_url($this->courseid, null));
|
||||
$replace = array($basefileurl);
|
||||
$result = str_replace($search, $replace, $cdata);
|
||||
|
||||
// Now $@SLASH@$ and $@FORCEDOWNLOAD@$ MDL-18799
|
||||
$search = array('$@SLASH@$', '$@FORCEDOWNLOAD@$');
|
||||
if ($CFG->slasharguments) {
|
||||
$replace = array('/', '?forcedownload=1');
|
||||
} else {
|
||||
$replace = array('%2F', '&forcedownload=1');
|
||||
}
|
||||
$replace = array($slash, $forcedownload);
|
||||
|
||||
return str_replace($search, $replace, $result);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Tests for restore_structure_parser_processor class.
|
||||
*
|
||||
* @package core_backup
|
||||
* @category test
|
||||
* @copyright 2017 Dmitrii Metelkin (dmitriim@catalyst-au.net)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||
require_once($CFG->dirroot . '/backup/util/helper/restore_structure_parser_processor.class.php');
|
||||
|
||||
/**
|
||||
* Tests for restore_structure_parser_processor class.
|
||||
*
|
||||
* @package core_backup
|
||||
* @copyright 2017 Dmitrii Metelkin (dmitriim@catalyst-au.net)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class restore_structure_parser_processor_test extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Initial set up.
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for ::test_process_cdata.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function process_cdata_data_provider() {
|
||||
return array(
|
||||
array(null, null, true),
|
||||
array("$@NULL@$", null, true),
|
||||
array("$@NULL@$ ", "$@NULL@$ ", true),
|
||||
array(1, 1, true),
|
||||
array(" ", " ", true),
|
||||
array("1", "1", true),
|
||||
array("$@FILEPHP@$1.jpg", "$@FILEPHP@$1.jpg", true),
|
||||
array(
|
||||
"http://test.test/$@SLASH@$",
|
||||
"http://test.test/$@SLASH@$",
|
||||
true
|
||||
),
|
||||
array(
|
||||
"<a href='$@FILEPHP@$1.jpg'>Image</a>",
|
||||
"<a href='http://test.test/file.php/11.jpg'>Image</a>",
|
||||
true
|
||||
),
|
||||
array(
|
||||
"<a href='$@FILEPHP@$$@SLASH@$1.jpg'>Image</a>",
|
||||
"<a href='http://test.test/file.php/1/1.jpg'>Image</a>",
|
||||
true
|
||||
),
|
||||
array(
|
||||
"<a href='$@FILEPHP@$$@SLASH@$$@SLASH@$1.jpg'>Image</a>",
|
||||
"<a href='http://test.test/file.php/1//1.jpg'>Image</a>",
|
||||
true
|
||||
),
|
||||
array(
|
||||
"<a href='$@FILEPHP@$1.jpg'>Image</a>",
|
||||
"<a href='http://test.test/file.php?file=%2F11.jpg'>Image</a>",
|
||||
false
|
||||
),
|
||||
array(
|
||||
"<a href='$@FILEPHP@$$@SLASH@$1.jpg'>Image</a>",
|
||||
"<a href='http://test.test/file.php?file=%2F1%2F1.jpg'>Image</a>",
|
||||
false
|
||||
),
|
||||
array(
|
||||
"<a href='$@FILEPHP@$$@SLASH@$$@SLASH@$1.jpg'>Image</a>",
|
||||
"<a href='http://test.test/file.php?file=%2F1%2F%2F1.jpg'>Image</a>",
|
||||
false
|
||||
),
|
||||
array(
|
||||
"<a href='$@FILEPHP@$$@SLASH@$1.jpg$@FORCEDOWNLOAD@$'>Image</a>",
|
||||
"<a href='http://test.test/file.php/1/1.jpg?forcedownload=1'>Image</a>",
|
||||
true
|
||||
),
|
||||
array(
|
||||
"<a href='$@FILEPHP@$$@SLASH@$1.jpg$@FORCEDOWNLOAD@$'>Image</a>",
|
||||
"<a href='http://test.test/file.php?file=%2F1%2F1.jpg&forcedownload=1'>Image</a>",
|
||||
false
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that restore_structure_parser_processor replaces $@FILEPHP@$ to correct file php links.
|
||||
*
|
||||
* @dataProvider process_cdata_data_provider
|
||||
* @param string $content Testing content.
|
||||
* @param string $expected Expected result.
|
||||
* @param bool $slasharguments A value for $CFG->slasharguments setting.
|
||||
*/
|
||||
public function test_process_cdata($content, $expected, $slasharguments) {
|
||||
global $CFG;
|
||||
|
||||
$CFG->slasharguments = $slasharguments;
|
||||
$CFG->wwwroot = 'http://test.test';
|
||||
|
||||
$processor = new restore_structure_parser_processor(1, 1);
|
||||
|
||||
$this->assertEquals($expected, $processor->process_cdata($content));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -88,5 +88,8 @@ function xmldb_block_badges_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,5 +88,8 @@ function xmldb_block_calendar_month_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,5 +88,8 @@ function xmldb_block_calendar_upcoming_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -61,5 +61,8 @@ function xmldb_block_community_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -63,5 +63,8 @@ function xmldb_block_completionstatus_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ echo html_writer::start_tag('tbody');
|
||||
if ($USER->id != $user->id) {
|
||||
echo html_writer::start_tag('tr');
|
||||
echo html_writer::start_tag('td', array('colspan' => '2'));
|
||||
echo html_writer::tag('b', get_string('showinguser', 'completion'));
|
||||
echo html_writer::tag('b', get_string('showinguser', 'completion') . ' ');
|
||||
$url = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $course->id));
|
||||
echo html_writer::link($url, fullname($user));
|
||||
echo html_writer::end_tag('td');
|
||||
@@ -99,7 +99,7 @@ if ($USER->id != $user->id) {
|
||||
|
||||
echo html_writer::start_tag('tr');
|
||||
echo html_writer::start_tag('td', array('colspan' => '2'));
|
||||
echo html_writer::tag('b', get_string('status'));
|
||||
echo html_writer::tag('b', get_string('status') . ' ');
|
||||
|
||||
// Is course complete?
|
||||
$coursecomplete = $info->is_course_complete($user->id);
|
||||
@@ -141,7 +141,7 @@ if (empty($completions)) {
|
||||
} else {
|
||||
echo html_writer::start_tag('tr');
|
||||
echo html_writer::start_tag('td', array('colspan' => '2'));
|
||||
echo html_writer::tag('b', get_string('required'));
|
||||
echo html_writer::tag('b', get_string('required') . ' ');
|
||||
|
||||
// Get overall aggregation method.
|
||||
$overall = $info->get_aggregation_method();
|
||||
@@ -214,7 +214,7 @@ if (empty($completions)) {
|
||||
echo core_text::strtolower(get_string('any', 'completion'));
|
||||
}
|
||||
|
||||
echo html_writer::end_tag('i') .core_text::strtolower(get_string('required')).')';
|
||||
echo ' ' . html_writer::end_tag('i') .core_text::strtolower(get_string('required')).')';
|
||||
$agg_type = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,5 +63,8 @@ function xmldb_block_course_summary_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -48,5 +48,8 @@ function xmldb_block_html_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ class block_login extends block_base {
|
||||
$this->content->text .= '<div class="potentialidplist">';
|
||||
foreach ($potentialidps as $idp) {
|
||||
$this->content->text .= '<div class="potentialidp">';
|
||||
$this->content->text .= '<a class="btn btn-secondary btn-block" ';
|
||||
$this->content->text .= '<a class="btn btn-default btn-block" ';
|
||||
$this->content->text .= 'href="' . $idp['url']->out() . '" title="' . s($idp['name']) . '">';
|
||||
if (!empty($idp['iconurl'])) {
|
||||
$this->content->text .= '<img src="' . s($idp['iconurl']) . '" width="24" height="24" class="m-r-1"/>';
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
define(["jquery","core/ajax","core/custom_interaction_events","core/notification"],function(a,b,c,d){var e=function(e){c.define(e,[c.events.activate]),e.on(c.events.activate,"[data-toggle='tab']",function(c){var e=a(c.currentTarget).data("tabname");"function"==typeof window.history.pushState&&window.history.pushState(null,null,"?myoverviewtab="+e);var f={methodname:"core_user_update_user_preferences",args:{preferences:[{type:"block_myoverview_last_tab",value:e}]}};b.call([f])[0].fail(d.exception)})};return{registerEventListeners:e}});
|
||||
@@ -0,0 +1,61 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Javascript used to save the user's tab preference.
|
||||
*
|
||||
* @package block_myoverview
|
||||
* @copyright 2017 Mark Nelson <markn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(['jquery', 'core/ajax', 'core/custom_interaction_events',
|
||||
'core/notification'], function($, Ajax, CustomEvents, Notification) {
|
||||
|
||||
/**
|
||||
* Registers an event that saves the user's tab preference when switching between them.
|
||||
*
|
||||
* @param {object} root The container element
|
||||
*/
|
||||
var registerEventListeners = function(root) {
|
||||
CustomEvents.define(root, [CustomEvents.events.activate]);
|
||||
root.on(CustomEvents.events.activate, "[data-toggle='tab']", function(e) {
|
||||
var tabname = $(e.currentTarget).data('tabname');
|
||||
// Bootstrap does not change the URL when using BS tabs, so need to do this here.
|
||||
// Also check to make sure the browser supports the history API.
|
||||
if (typeof window.history.pushState === "function") {
|
||||
window.history.pushState(null, null, '?myoverviewtab=' + tabname);
|
||||
}
|
||||
var request = {
|
||||
methodname: 'core_user_update_user_preferences',
|
||||
args: {
|
||||
preferences: [
|
||||
{
|
||||
type: 'block_myoverview_last_tab',
|
||||
value: tabname
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
Ajax.call([request])[0]
|
||||
.fail(Notification.exception);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
registerEventListeners: registerEventListeners
|
||||
};
|
||||
});
|
||||
@@ -50,7 +50,16 @@ class block_myoverview extends block_base {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
$renderable = new \block_myoverview\output\main();
|
||||
// Check if the tab to select wasn't passed in the URL, if so see if the user has any preference.
|
||||
if (!$tab = optional_param('myoverviewtab', null, PARAM_ALPHA)) {
|
||||
// Check if the user has no preference, if so get the site setting.
|
||||
if (!$tab = get_user_preferences('block_myoverview_last_tab')) {
|
||||
$config = get_config('block_myoverview');
|
||||
$tab = $config->defaulttab;
|
||||
}
|
||||
}
|
||||
|
||||
$renderable = new \block_myoverview\output\main($tab);
|
||||
$renderer = $this->page->get_renderer('block_myoverview');
|
||||
|
||||
$this->content = new stdClass();
|
||||
@@ -68,4 +77,13 @@ class block_myoverview extends block_base {
|
||||
public function applicable_formats() {
|
||||
return array('my' => true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This block does contain a configuration settings.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function has_config() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,8 @@ class courses_view implements renderable, templatable {
|
||||
* @return array
|
||||
*/
|
||||
public function export_for_template(renderer_base $output) {
|
||||
$today = time();
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot.'/course/lib.php');
|
||||
|
||||
// Build courses view data structure.
|
||||
$coursesview = [
|
||||
@@ -73,8 +74,6 @@ class courses_view implements renderable, templatable {
|
||||
// How many courses we have per status?
|
||||
$coursesbystatus = ['past' => 0, 'inprogress' => 0, 'future' => 0];
|
||||
foreach ($this->courses as $course) {
|
||||
$startdate = $course->startdate;
|
||||
$enddate = $course->enddate;
|
||||
$courseid = $course->id;
|
||||
$context = \context_course::instance($courseid);
|
||||
$exporter = new course_summary_exporter($course, [
|
||||
@@ -84,14 +83,17 @@ class courses_view implements renderable, templatable {
|
||||
// Convert summary to plain text.
|
||||
$exportedcourse->summary = content_to_text($exportedcourse->summary, $exportedcourse->summaryformat);
|
||||
|
||||
$courseprogress = null;
|
||||
|
||||
$classified = course_classify_for_timeline($course);
|
||||
|
||||
if (isset($this->coursesprogress[$courseid])) {
|
||||
$coursecompleted = $this->coursesprogress[$courseid]['completed'];
|
||||
$courseprogress = $this->coursesprogress[$courseid]['progress'];
|
||||
$exportedcourse->hasprogress = !is_null($courseprogress);
|
||||
$exportedcourse->progress = $courseprogress;
|
||||
}
|
||||
|
||||
if ((isset($coursecompleted) && $coursecompleted) || (!empty($enddate) && $enddate < $today)) {
|
||||
if ($classified == COURSE_TIMELINE_PAST) {
|
||||
// Courses that have already ended.
|
||||
$pastpages = floor($coursesbystatus['past'] / $this::COURSES_PER_PAGE);
|
||||
|
||||
@@ -100,7 +102,7 @@ class courses_view implements renderable, templatable {
|
||||
$coursesview['past']['pages'][$pastpages]['page'] = $pastpages + 1;
|
||||
$coursesview['past']['haspages'] = true;
|
||||
$coursesbystatus['past']++;
|
||||
} else if ($startdate > $today) {
|
||||
} else if ($classified == COURSE_TIMELINE_FUTURE) {
|
||||
// Courses that have not started yet.
|
||||
$futurepages = floor($coursesbystatus['future'] / $this::COURSES_PER_PAGE);
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ use renderer_base;
|
||||
use templatable;
|
||||
use core_completion\progress;
|
||||
|
||||
require_once($CFG->dirroot . '/blocks/myoverview/lib.php');
|
||||
require_once($CFG->libdir . '/completionlib.php');
|
||||
|
||||
/**
|
||||
@@ -39,6 +40,20 @@ require_once($CFG->libdir . '/completionlib.php');
|
||||
*/
|
||||
class main implements renderable, templatable {
|
||||
|
||||
/**
|
||||
* @var string The tab to display.
|
||||
*/
|
||||
public $tab;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $tab The tab to display.
|
||||
*/
|
||||
public function __construct($tab) {
|
||||
$this->tab = $tab;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export this data so it can be used as the context for a mustache template.
|
||||
*
|
||||
@@ -73,13 +88,24 @@ class main implements renderable, templatable {
|
||||
$nocoursesurl = $output->image_url('courses', 'block_myoverview')->out();
|
||||
$noeventsurl = $output->image_url('activities', 'block_myoverview')->out();
|
||||
|
||||
// Now, set the tab we are going to be viewing.
|
||||
$viewingtimeline = false;
|
||||
$viewingcourses = false;
|
||||
if ($this->tab == BLOCK_MYOVERVIEW_TIMELINE_VIEW) {
|
||||
$viewingtimeline = true;
|
||||
} else {
|
||||
$viewingcourses = true;
|
||||
}
|
||||
|
||||
return [
|
||||
'midnight' => usergetmidnight(time()),
|
||||
'coursesview' => $coursesview->export_for_template($output),
|
||||
'urls' => [
|
||||
'nocourses' => $nocoursesurl,
|
||||
'noevents' => $noeventsurl
|
||||
]
|
||||
],
|
||||
'viewingtimeline' => $viewingtimeline,
|
||||
'viewingcourses' => $viewingcourses
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['defaulttab'] = 'Default tab';
|
||||
$string['defaulttab_desc'] = 'The tab that will be displayed when a user first views their course overview. When returning to their course overview, the user\'s active tab is remembered.';
|
||||
$string['future'] = 'Future';
|
||||
$string['inprogress'] = 'In progress';
|
||||
$string['morecourses'] = 'More courses';
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Contains functions called by core.
|
||||
*
|
||||
* @package block_myoverview
|
||||
* @copyright 2017 Mark Nelson <markn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* The timeline view.
|
||||
*/
|
||||
define('BLOCK_MYOVERVIEW_TIMELINE_VIEW', 'timeline');
|
||||
|
||||
/**
|
||||
* The courses view.
|
||||
*/
|
||||
define('BLOCK_MYOVERVIEW_COURSES_VIEW', 'courses');
|
||||
|
||||
/**
|
||||
* Returns the name of the user preferences as well as the details this plugin uses.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function block_myoverview_user_preferences() {
|
||||
$preferences = array();
|
||||
$preferences['block_myoverview_last_tab'] = array(
|
||||
'type' => PARAM_ALPHA,
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
'default' => BLOCK_MYOVERVIEW_TIMELINE_VIEW,
|
||||
'choices' => array(BLOCK_MYOVERVIEW_TIMELINE_VIEW, BLOCK_MYOVERVIEW_COURSES_VIEW)
|
||||
);
|
||||
|
||||
return $preferences;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Settings for the overview block.
|
||||
*
|
||||
* @package block_myoverview
|
||||
* @copyright 2017 Mark Nelson <markn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
require_once($CFG->dirroot . '/blocks/myoverview/lib.php');
|
||||
|
||||
if ($ADMIN->fulltree) {
|
||||
|
||||
$options = [
|
||||
BLOCK_MYOVERVIEW_TIMELINE_VIEW => get_string('timeline', 'block_myoverview'),
|
||||
BLOCK_MYOVERVIEW_COURSES_VIEW => get_string('courses')
|
||||
];
|
||||
|
||||
$settings->add(new admin_setting_configselect('block_myoverview/defaulttab',
|
||||
get_string('defaulttab', 'block_myoverview'),
|
||||
get_string('defaulttab_desc', 'block_myoverview'), 'timeline', $options));
|
||||
}
|
||||
@@ -24,26 +24,32 @@
|
||||
}}
|
||||
|
||||
<div id="block-myoverview-{{uniqid}}" class="block-myoverview" data-region="myoverview">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<ul id="block-myoverview-view-choices-{{uniqid}}" class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#myoverview_timeline_view" role="tab" data-toggle="tab">
|
||||
<a class="nav-link {{#viewingtimeline}}active{{/viewingtimeline}}" href="#myoverview_timeline_view" role="tab" data-toggle="tab" data-tabname="timeline">
|
||||
{{#str}} timeline, block_myoverview {{/str}}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#myoverview_courses_view" role="tab" data-toggle="tab">
|
||||
<a class="nav-link {{#viewingcourses}}active{{/viewingcourses}}" href="#myoverview_courses_view" role="tab" data-toggle="tab" data-tabname="courses">
|
||||
{{#str}} courses {{/str}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content content-centred">
|
||||
<div role="tabpanel" class="tab-pane fade in active" id="myoverview_timeline_view">
|
||||
<div role="tabpanel" class="tab-pane fade {{#viewingtimeline}}in active{{/viewingtimeline}}" id="myoverview_timeline_view">
|
||||
{{> block_myoverview/timeline-view }}
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane fade" id="myoverview_courses_view">
|
||||
<div role="tabpanel" class="tab-pane fade {{#viewingcourses}}in active{{/viewingcourses}}" id="myoverview_courses_view">
|
||||
{{#coursesview}}
|
||||
{{> block_myoverview/courses-view }}
|
||||
{{/coursesview}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#js}}
|
||||
require(['jquery', 'block_myoverview/tab_preferences'], function($, TabPreferences) {
|
||||
var root = $('#block-myoverview-view-choices-{{uniqid}}');
|
||||
TabPreferences.registerEventListeners(root);
|
||||
});
|
||||
{{/js}}
|
||||
|
||||
@@ -53,6 +53,7 @@ Feature: Course overview block show users their progress on courses
|
||||
And I am on "Course 1" course homepage
|
||||
And I follow "Test choice 1"
|
||||
And I follow "Dashboard" in the user menu
|
||||
And I click on "Timeline" "link" in the "Course overview" "block"
|
||||
And I click on "Sort by courses" "link" in the "Course overview" "block"
|
||||
And I should see "100%" in the "Course overview" "block"
|
||||
And I click on "Courses" "link" in the "Course overview" "block"
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2017051502; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->component = 'block_myoverview'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -1 +1 @@
|
||||
define(["jquery"],function(a){function b(d,e){var f=a("<ul></ul>");f.attr("role","group"),f.attr("aria-hidden",!0),a.each(e,function(d,e){if("object"==typeof e){var g=a("<li></li>"),h=a("<p></p>"),i=e.id||e.key+"_tree_item",j=null,k=!(!e.expandable&&!e.haschildren);if(h.addClass("tree_item"),h.attr("id",i),h.attr("role","treeitem"),h.attr("tabindex","-1"),e.requiresajaxloading&&(h.attr("data-requires-ajax",!0),h.attr("data-node-id",e.id),h.attr("data-node-key",e.key),h.attr("data-node-type",e.type)),k&&(g.addClass("collapsed contains_branch"),h.attr("aria-expanded",!1),h.addClass("branch")),!e.icon||k&&e.type!==c.ACTIVITY&&e.type!==c.RESOURCE||(g.addClass("item_with_icon"),h.addClass("hasicon"),j=a("<img/>"),j.attr("alt",e.icon.alt),j.attr("title",e.icon.title),j.attr("src",M.util.image_url(e.icon.pix,e.icon.component)),a.each(e.icon.classes,function(a,b){j.addClass(b)})),e.link){var l=a('<a title="'+e.title+'" href="'+e.link+'"></a>');j?(l.append(j),l.append('<span class="item-content-wrap">'+e.name+"</span>")):l.append(e.name),e.hidden&&l.addClass("dimmed"),h.append(l)}else{var m=a("<span></span>");j?(m.append(j),m.append('<span class="item-content-wrap">'+e.name+"</span>")):m.append(e.name),e.hidden&&m.addClass("dimmed"),h.append(m)}g.append(h),f.append(g),e.children&&e.children.length?b(h,e.children):k&&!e.requiresajaxloading&&(g.removeClass("contains_branch"),h.addClass("emptybranch"))}}),d.parent().append(f);var g=d.attr("id")+"_group";f.attr("id",g),d.attr("aria-owns",g),d.attr("role","treeitem")}var c={ACTIVITY:40,RESOURCE:50};return{render:function(a,c){if(c.children&&c.children.length){b(a,c.children);var d=a.children("[role='treeitem']").first(),e=a.find("#"+d.attr("aria-owns"));d.attr("aria-expanded",!0),e.attr("aria-hidden",!1)}else a.parent().hasClass("contains_branch")&&(a.parent().removeClass("contains_branch"),a.addClass("emptybranch"))}}});
|
||||
define(["jquery","core/templates","core/notification","core/url"],function(a,b,c,d){function e(g,h){var i=a("<ul></ul>");i.attr("role","group"),i.attr("aria-hidden",!0),a.each(h,function(g,h){if("object"==typeof h){var j=a("<li></li>"),k=a("<p></p>"),l=h.id||h.key+"_tree_item",m=null,n=!(!h.expandable&&!h.haschildren);k.addClass("tree_item"),k.attr("id",l),k.attr("role","treeitem"),k.attr("tabindex","-1"),h.requiresajaxloading&&(k.attr("data-requires-ajax",!0),k.attr("data-node-id",h.id),k.attr("data-node-key",h.key),k.attr("data-node-type",h.type)),n&&(j.addClass("collapsed contains_branch"),k.attr("aria-expanded",!1),k.addClass("branch"));var o=null;if(h.link){var p=a('<a title="'+h.title+'" href="'+h.link+'"></a>');o=p,p.append('<span class="item-content-wrap">'+h.name+"</span>"),h.hidden&&p.addClass("dimmed"),k.append(p)}else{var q=a("<span></span>");o=q,q.append('<span class="item-content-wrap">'+h.name+"</span>"),h.hidden&&q.addClass("dimmed"),k.append(q)}!h.icon||n&&h.type!==f.ACTIVITY&&h.type!==f.RESOURCE||(j.addClass("item_with_icon"),k.addClass("hasicon"),h.type===f.ACTIVITY||h.type===f.RESOURCE?(m=a("<img/>"),m.attr("alt",h.icon.alt),m.attr("title",h.icon.title),m.attr("src",d.imageUrl(h.icon.pix,h.icon.component)),a.each(h.icon.classes,function(a,b){m.addClass(b)}),o.prepend(m)):("moodle"==h.icon.component&&(h.icon.component="core"),b.renderPix(h.icon.pix,h.icon.component,h.icon.title).then(function(a){o.prepend(a)})["catch"](c.exception))),j.append(k),i.append(j),h.children&&h.children.length?e(k,h.children):n&&!h.requiresajaxloading&&(j.removeClass("contains_branch"),k.addClass("emptybranch"))}}),g.parent().append(i);var j=g.attr("id")+"_group";i.attr("id",j),g.attr("aria-owns",j),g.attr("role","treeitem")}var f={ACTIVITY:40,RESOURCE:50};return{render:function(a,b){if(b.children&&b.children.length){e(a,b.children);var c=a.children("[role='treeitem']").first(),d=a.find("#"+c.attr("aria-owns"));c.attr("aria-expanded",!0),d.attr("aria-hidden",!1)}else a.parent().hasClass("contains_branch")&&(a.parent().removeClass("contains_branch"),a.addClass("emptybranch"))}}});
|
||||
@@ -22,7 +22,7 @@
|
||||
* @copyright 2015 John Okely <john@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['jquery'], function($) {
|
||||
define(['jquery', 'core/templates', 'core/notification', 'core/url'], function($, Templates, Notification, Url) {
|
||||
|
||||
// Mappings for the different types of nodes coming from the navigation.
|
||||
// Copied from lib/navigationlib.php navigation_node constants.
|
||||
@@ -75,28 +75,12 @@ define(['jquery'], function($) {
|
||||
p.addClass('branch');
|
||||
}
|
||||
|
||||
if (node.icon && (!isBranch || node.type === NODETYPE.ACTIVITY || node.type === NODETYPE.RESOURCE)) {
|
||||
li.addClass('item_with_icon');
|
||||
p.addClass('hasicon');
|
||||
|
||||
icon = $('<img/>');
|
||||
icon.attr('alt', node.icon.alt);
|
||||
icon.attr('title', node.icon.title);
|
||||
icon.attr('src', M.util.image_url(node.icon.pix, node.icon.component));
|
||||
$.each(node.icon.classes, function(index, className) {
|
||||
icon.addClass(className);
|
||||
});
|
||||
}
|
||||
|
||||
var eleToAddIcon = null;
|
||||
if (node.link) {
|
||||
var link = $('<a title="' + node.title + '" href="' + node.link + '"></a>');
|
||||
|
||||
if (icon) {
|
||||
link.append(icon);
|
||||
link.append('<span class="item-content-wrap">' + node.name + '</span>');
|
||||
} else {
|
||||
link.append(node.name);
|
||||
}
|
||||
eleToAddIcon = link;
|
||||
link.append('<span class="item-content-wrap">' + node.name + '</span>');
|
||||
|
||||
if (node.hidden) {
|
||||
link.addClass('dimmed');
|
||||
@@ -106,12 +90,8 @@ define(['jquery'], function($) {
|
||||
} else {
|
||||
var span = $('<span></span>');
|
||||
|
||||
if (icon) {
|
||||
span.append(icon);
|
||||
span.append('<span class="item-content-wrap">' + node.name + '</span>');
|
||||
} else {
|
||||
span.append(node.name);
|
||||
}
|
||||
eleToAddIcon = span;
|
||||
span.append('<span class="item-content-wrap">' + node.name + '</span>');
|
||||
|
||||
if (node.hidden) {
|
||||
span.addClass('dimmed');
|
||||
@@ -120,6 +100,31 @@ define(['jquery'], function($) {
|
||||
p.append(span);
|
||||
}
|
||||
|
||||
if (node.icon && (!isBranch || node.type === NODETYPE.ACTIVITY || node.type === NODETYPE.RESOURCE)) {
|
||||
li.addClass('item_with_icon');
|
||||
p.addClass('hasicon');
|
||||
|
||||
if (node.type === NODETYPE.ACTIVITY || node.type === NODETYPE.RESOURCE) {
|
||||
icon = $('<img/>');
|
||||
icon.attr('alt', node.icon.alt);
|
||||
icon.attr('title', node.icon.title);
|
||||
icon.attr('src', Url.imageUrl(node.icon.pix, node.icon.component));
|
||||
$.each(node.icon.classes, function(index, className) {
|
||||
icon.addClass(className);
|
||||
});
|
||||
eleToAddIcon.prepend(icon);
|
||||
} else {
|
||||
if (node.icon.component == 'moodle') {
|
||||
node.icon.component = 'core';
|
||||
}
|
||||
Templates.renderPix(node.icon.pix, node.icon.component, node.icon.title).then(function(html) {
|
||||
// Prepend.
|
||||
eleToAddIcon.prepend(html);
|
||||
return;
|
||||
}).catch(Notification.exception);
|
||||
}
|
||||
}
|
||||
|
||||
li.append(p);
|
||||
ul.append(li);
|
||||
|
||||
|
||||
@@ -70,5 +70,8 @@ function xmldb_block_navigation_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,6 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
.block_navigation .block_tree [aria-hidden="true"] {
|
||||
.block_navigation .block_tree [aria-hidden="true"]:not(.icon) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -113,5 +113,8 @@ function xmldb_block_quiz_results_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -62,5 +62,8 @@ function xmldb_block_recent_activity_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -59,5 +59,8 @@ function xmldb_block_rss_client_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -64,5 +64,8 @@ function xmldb_block_section_links_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -63,5 +63,8 @@ function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -70,5 +70,8 @@ function xmldb_block_settings_upgrade($oldversion, $block) {
|
||||
// Automatically generated Moodle v3.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v3.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
.block_settings .block_tree [aria-hidden="true"] {
|
||||
.block_settings .block_tree [aria-hidden="true"]:not(.icon) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -1077,7 +1077,7 @@ class cache implements cache_loader {
|
||||
$result = $data;
|
||||
}
|
||||
}
|
||||
if ($result) {
|
||||
if ($result !== false) {
|
||||
if ($this->perfdebug) {
|
||||
cache_helper::record_cache_hit('** static acceleration **', $this->definition);
|
||||
}
|
||||
@@ -2162,4 +2162,4 @@ class cache_session extends cache {
|
||||
*/
|
||||
class cache_request extends cache {
|
||||
// This comment appeases code pre-checker ;) !
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user