Compare commits
467 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d43ba3caf6 | |||
| 099e1e00ee | |||
| 6e42741116 | |||
| f75011fbad | |||
| 1f84f2e54a | |||
| ccc803db33 | |||
| 0f52118a4a | |||
| d5fc9f3d77 | |||
| 218e485ff5 | |||
| 38c5823efc | |||
| 10c6db96fb | |||
| d749cbc9a2 | |||
| 51f55920b5 | |||
| a558b8415b | |||
| cf6fdbd1b0 | |||
| c6f2415757 | |||
| df6266825b | |||
| b845942af5 | |||
| e7a7df3bf8 | |||
| 771053bd83 | |||
| c2fb582ef5 | |||
| b3f8740157 | |||
| cbbdca1264 | |||
| 761dfda279 | |||
| 57b9d94e89 | |||
| 4f558e2741 | |||
| 97846ce94c | |||
| 8256fae97c | |||
| b1e17c1eb0 | |||
| 6441b480f7 | |||
| 888b6ee53c | |||
| 4300a02765 | |||
| 1bfc006d96 | |||
| 3ec12a2173 | |||
| 92e5cbc783 | |||
| d461ecf772 | |||
| 2ab86289de | |||
| 48cafb2b24 | |||
| 173a201f90 | |||
| d5a3a92267 | |||
| 646059869e | |||
| 38fd297dc7 | |||
| ab13a532be | |||
| 71db4e58d7 | |||
| 5379574a7d | |||
| c5c1f07453 | |||
| 40d9932aa3 | |||
| a954624bc8 | |||
| 6369652f17 | |||
| fcf890aa2b | |||
| 2b0b5a203d | |||
| 14c2bada33 | |||
| 8a7bc6c3d8 | |||
| 47e93e02cf | |||
| ee7251689f | |||
| 1b628c489d | |||
| 9aa0a709cd | |||
| d567c29dc9 | |||
| 76cab144c8 | |||
| 0d1fccaf15 | |||
| b30fea4e05 | |||
| 4a8da21c62 | |||
| 18329cbf1e | |||
| 31946300e9 | |||
| 0622ef3aa5 | |||
| 792dab0f75 | |||
| db66ab7898 | |||
| 55b330e6d8 | |||
| c2cef5809e | |||
| c6014dccd9 | |||
| 180e1b2fe9 | |||
| d47f3d499c | |||
| a366e1282a | |||
| 48f3a2495b | |||
| 328b5eab5c | |||
| c3dd18842b | |||
| ac19bd186a | |||
| fa5509b73c | |||
| ded4050f1b | |||
| c3a1ea1843 | |||
| 8e7afd6bf5 | |||
| 0e94caf991 | |||
| fb3f9c4a50 | |||
| ca2a7956b2 | |||
| 2c7cdbb3b0 | |||
| c7eea4e585 | |||
| 0897b1eab1 | |||
| 905ee48370 | |||
| 69313ec423 | |||
| 92eeecdc07 | |||
| 106269b393 | |||
| 02a88f802e | |||
| e97baa19ca | |||
| cc9c8c3672 | |||
| 45dbcbec5f | |||
| 459bb94a47 | |||
| 240a2ee20c | |||
| ac0cb8d956 | |||
| 3583718ce8 | |||
| ce5940cc94 | |||
| d6c3051a52 | |||
| 215c1897a4 | |||
| 119d68fa19 | |||
| 819cdd8041 | |||
| ab882a67c6 | |||
| fce2121e19 | |||
| 9845d1bf52 | |||
| 52f9841809 | |||
| 7215ff4efa | |||
| a6c54ab297 | |||
| 7ef965ce50 | |||
| c4d0c8ada2 | |||
| 6fe4e3c02b | |||
| f3f1f5d3d0 | |||
| a515bc1b58 | |||
| 7a3e11d5b5 | |||
| 65403fcf15 | |||
| 24773be403 | |||
| 7d37889b31 | |||
| 637611a7b3 | |||
| b53e905618 | |||
| 85ee7e13ff | |||
| f1cd94b679 | |||
| 29c7332585 | |||
| a09484cf77 | |||
| b2c16779d2 | |||
| 9b8afa9b55 | |||
| 84cf3cce0b | |||
| cb3a696c05 | |||
| e2e65d25f5 | |||
| 3c509fdc04 | |||
| 51b7049d70 | |||
| feb843633d | |||
| 5d719ed8ec | |||
| c5d3cf1da3 | |||
| a5c0643a1d | |||
| a6a1b51259 | |||
| f8ecf7f7de | |||
| 1716b4a54b | |||
| 00f5a12de7 | |||
| fe8b7cd677 | |||
| 78f3381eb4 | |||
| f5d26c95e8 | |||
| aa38d80df4 | |||
| c4a799ecde | |||
| 5affcb30bc | |||
| e9328f579e | |||
| cb7da8e091 | |||
| eb6dcde62d | |||
| c3724a7002 | |||
| d5e9e15e54 | |||
| 768fdcb979 | |||
| 5c70a6ec3c | |||
| a2eeb58422 | |||
| 15cc42fb9c | |||
| c814b84573 | |||
| 0ca9918428 | |||
| 9f4cd940b1 | |||
| 7e89587526 | |||
| bf78144a45 | |||
| 45c8baafd0 | |||
| e4594f737e | |||
| d623842807 | |||
| 1989bb2ed8 | |||
| 9f2be81a8e | |||
| 39239e299b | |||
| 8b6a3b4e11 | |||
| 156b8e3c9d | |||
| fe0ce21840 | |||
| f60f3b6c39 | |||
| 0bf47bc403 | |||
| 2ceaefb420 | |||
| 0c9e550def | |||
| 31db9c51a2 | |||
| 4bcf7d3e74 | |||
| e30af43f40 | |||
| e0f5cb19a3 | |||
| 41eb312243 | |||
| 9cf21fc4e3 | |||
| 99a2923de2 | |||
| 7d7b959bd6 | |||
| a56ced75e7 | |||
| bbcf8dab4f | |||
| 212fa54826 | |||
| 5f68421b93 | |||
| 856e1568d6 | |||
| dafe3db606 | |||
| 79cccda3a9 | |||
| fff248b163 | |||
| 37010cc708 | |||
| 46c9d980e5 | |||
| 35f7e66ed7 | |||
| 0225b635c4 | |||
| ac45271157 | |||
| a8bf41cec6 | |||
| 35f667d850 | |||
| f81a08b491 | |||
| bced529e0e | |||
| 596881dbaf | |||
| 473b153982 | |||
| c27b257b14 | |||
| a3ded4c023 | |||
| d26cc0a022 | |||
| 9ba2682e38 | |||
| 731ff94a87 | |||
| ffad867dd0 | |||
| ed1f5a1f25 | |||
| e2f455b8ca | |||
| 68c1945a8e | |||
| a0b9816e8b | |||
| 1a3487fc6e | |||
| e429c2c386 | |||
| 772979e593 | |||
| abbda1f869 | |||
| e09f33df1b | |||
| 80dbc147de | |||
| c1921325d4 | |||
| 6337a60521 | |||
| fa3ca744ea | |||
| 2bbe8443cc | |||
| d446475d67 | |||
| 1924628001 | |||
| 0dcf51a8b3 | |||
| 72ffbbad46 | |||
| cd536c6be5 | |||
| 377d577f2d | |||
| 9cb6ecd9aa | |||
| 9efe2ca244 | |||
| c90c4f7775 | |||
| 3c21fdc9ce | |||
| 0da3d58ebd | |||
| afe9c36843 | |||
| e04ddf75cb | |||
| 9aa9fbd0d0 | |||
| d80a777866 | |||
| 8e8a6b78d0 | |||
| d86b640958 | |||
| 4b74b9d617 | |||
| dc5957d568 | |||
| da46d05239 | |||
| 93f09e3ba8 | |||
| 34c5ea24f3 | |||
| 53291c7256 | |||
| fe24496193 | |||
| e20455a5ae | |||
| 7c67ab3c14 | |||
| 32a579e30b | |||
| b4f52cf9af | |||
| ac3fe66f06 | |||
| 1a5f2cf058 | |||
| 6f4c3571b8 | |||
| 567fdbfa33 | |||
| 1a305ff1b9 | |||
| 8e3b8a617d | |||
| ce8cde8b45 | |||
| c962e3f112 | |||
| 7d054079c5 | |||
| 4e6cffa180 | |||
| f5eaec8646 | |||
| 24ed210069 | |||
| 5e5dfabd4a | |||
| 4ab0bf0f31 | |||
| 5e3412d94d | |||
| 31235aa431 | |||
| e17b0a6a8c | |||
| 533064b86a | |||
| 8bdac11f11 | |||
| 07f3c79dd4 | |||
| db30e0b00a | |||
| 8a2c41aa28 | |||
| 2cc9648555 | |||
| 06ffb6544b | |||
| 6e607d44c0 | |||
| 9834ef146e | |||
| 1d65791467 | |||
| aebbfda077 | |||
| b05659dde4 | |||
| 86cc12d5f3 | |||
| 87db6e272e | |||
| 7b86ac4bbc | |||
| 9e9b69fff9 | |||
| 09a8ba4aa6 | |||
| c5b346dc13 | |||
| 3134895c01 | |||
| 8108e113b3 | |||
| 04093db18a | |||
| adf01e854b | |||
| 9fb8d1f275 | |||
| 7efab51a7e | |||
| b19ecdb38d | |||
| f9681cffa4 | |||
| f4b106ee59 | |||
| 9de3aac748 | |||
| ab9008ffb0 | |||
| c01e5b0cd6 | |||
| b0610c8bca | |||
| c2e15c4619 | |||
| d6fdc727ea | |||
| eae7b4d189 | |||
| ac9b9f152c | |||
| 7ec3fd667a | |||
| a83ce21dfb | |||
| b5fe549a3c | |||
| 1892098bf0 | |||
| 7fdb36f523 | |||
| 0acd374832 | |||
| 1ec9eeadae | |||
| 913084399a | |||
| b7e9856937 | |||
| 11c1663d71 | |||
| 4b081e7037 | |||
| d4d06686f7 | |||
| 0bbbabb550 | |||
| db2a65bfa9 | |||
| 45e9749984 | |||
| 5ac332392a | |||
| 16441ae878 | |||
| 30e2ad8b85 | |||
| 7ce10d15d6 | |||
| eed5149f1f | |||
| 9044b7fadf | |||
| 5cf0388b84 | |||
| 3ad0ab4e67 | |||
| 24430c5aad | |||
| 57951b86df | |||
| e88dfd38bd | |||
| 38f688108d | |||
| 166cb23ea4 | |||
| 6042f30d5f | |||
| 9e4c326caf | |||
| 49042e1c8c | |||
| 0302aca4ec | |||
| 211fa38ca5 | |||
| e21f9dd982 | |||
| 72455fca5a | |||
| c90b8f82a8 | |||
| a932d0c4cc | |||
| b210380b4e | |||
| 19740fe4a6 | |||
| 4e3f4bd9be | |||
| c208efa04c | |||
| 8f3ae32b88 | |||
| 9d2f74684c | |||
| ee7411c4b6 | |||
| fd843c7f22 | |||
| 5f9a56011e | |||
| fb5819b13c | |||
| 54a25a2f88 | |||
| d971df89b1 | |||
| 93a91776f6 | |||
| 55ab55ba5c | |||
| 65ac28683e | |||
| 28497b53b3 | |||
| 812ea3aae2 | |||
| b0da482ae0 | |||
| 176bb7570b | |||
| 7a6d23ef25 | |||
| 0d674390c3 | |||
| 7e1f3dda3b | |||
| a2400fcf71 | |||
| cf7ace8a37 | |||
| cfdc33bf08 | |||
| bb92d9053c | |||
| af8ce622b0 | |||
| a12d510c35 | |||
| c56248f14b | |||
| e61f96c55b | |||
| fa0218be0e | |||
| a518f7eff5 | |||
| b61ab6193b | |||
| 92a3802c39 | |||
| 532da94d0e | |||
| e99486c448 | |||
| a59dc25d6d | |||
| 508f42e2f1 | |||
| f20d185c87 | |||
| 4c4ade1ca9 | |||
| f86473cebc | |||
| 5be632e8b6 | |||
| 5919718019 | |||
| d10ca0e697 | |||
| 0ad7caf4c3 | |||
| 4ca741e456 | |||
| 2ed251d007 | |||
| 178d99677b | |||
| c5c330babc | |||
| 1d8066e2d0 | |||
| 50dcac01eb | |||
| b3f92c0ab7 | |||
| 1962821cf5 | |||
| cd0523a78e | |||
| 31f183fd73 | |||
| 9bc178f3e6 | |||
| 7cf0504ac6 | |||
| 5d112775e9 | |||
| 5a3aaea503 | |||
| 34db04595e | |||
| 5f2d7b3009 | |||
| 09ebf8386a | |||
| d7b3cced54 | |||
| 5696c69b3b | |||
| 4090cd2b92 | |||
| dc43bfe372 | |||
| f84e58d809 | |||
| e6b9308a23 | |||
| ded1043407 | |||
| b175cf2c72 | |||
| 0da02e0a20 | |||
| 25ad1dea0e | |||
| 58a52d66b0 | |||
| 091a0b7b00 | |||
| f017aa4bd5 | |||
| 9376a1e59b | |||
| a89c9384fa | |||
| 8784a3b2a2 | |||
| 1ed7c77347 | |||
| e5f6a755e7 | |||
| e48cbfc594 | |||
| a07dccc1c5 | |||
| e25a7aa27e | |||
| a2bbc96b3e | |||
| 4012fc4994 | |||
| b31f52340c | |||
| 3c9148d6d1 | |||
| 0aa5236143 | |||
| bdc678a409 | |||
| 3434298385 | |||
| 7fa6857c3b | |||
| 39bad86b14 | |||
| e824c58aa8 | |||
| 096bb297f7 | |||
| 571c2784d6 | |||
| 6fc65ae5c3 | |||
| d7f4c9c3f5 | |||
| 3daceb9d5c | |||
| df0c2e5fd3 | |||
| 7d9ce8864a | |||
| 86132c35ad | |||
| 5a701d1fbe | |||
| 517f7729ca | |||
| eed2721b71 | |||
| 0a7c94b3d1 | |||
| a34209d566 | |||
| 6df2ead050 | |||
| 7f5290099f | |||
| f7109ce6d8 | |||
| 0fabd97928 | |||
| 975b2f7145 | |||
| a786cf469d | |||
| ab4cb125e4 | |||
| 20b556afa1 | |||
| 3d68b9e954 | |||
| 96ace848cc | |||
| 7de454919b | |||
| 1d15d41073 | |||
| 52f37ef475 | |||
| 845ef47ccd | |||
| b8438776db | |||
| 6990c10576 | |||
| ea8e60c6f8 | |||
| 18a5b8c72e | |||
| 330686c9fb | |||
| b12d8cd881 | |||
| b65bd8b658 | |||
| 9d40987c6d | |||
| 7441838054 | |||
| 2a3af105e6 |
+1
-1
@@ -8,7 +8,7 @@ a few minutes:
|
||||
1) Move the Moodle files into your web directory.
|
||||
|
||||
2) Create a single database for Moodle to store all
|
||||
it's tables in (or choose an existing database).
|
||||
its tables in (or choose an existing database).
|
||||
|
||||
3) Visit your Moodle site with a browser, you should
|
||||
be taken to the install.php script, which will lead
|
||||
|
||||
+1
-1
@@ -28,8 +28,8 @@ require_once(dirname(dirname(__FILE__)) . '/config.php');
|
||||
require_once($CFG->libdir . '/adminlib.php');
|
||||
require_once($CFG->libdir . '/pluginlib.php');
|
||||
|
||||
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
|
||||
admin_externalpage_setup('pluginsoverview');
|
||||
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
|
||||
|
||||
$fetchremote = optional_param('fetchremote', false, PARAM_BOOL);
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@ $return = true;
|
||||
if (!empty($edit) || !empty($new)) {
|
||||
if (!empty($edit)) {
|
||||
$instance = repository::get_instance($edit);
|
||||
if ($instance->instance->contextid != $context->id) {
|
||||
throw new repository_exception('nopermissiontoaccess', 'repository');
|
||||
}
|
||||
$instancetype = repository::get_type_by_id($instance->options['typeid']);
|
||||
$classname = 'repository_' . $instancetype->get_typename();
|
||||
$configs = $instance->get_instance_option_names();
|
||||
@@ -118,10 +121,12 @@ if (!empty($edit) || !empty($new)) {
|
||||
$return = true;
|
||||
} else if (!empty($delete)) {
|
||||
$instance = repository::get_instance($delete);
|
||||
//if you try to delete an instance set as readonly, display an error message
|
||||
if ($instance->readonly) {
|
||||
throw new repository_exception('readonlyinstance', 'repository');
|
||||
}
|
||||
// If you try to delete an instance set as readonly, display an error message.
|
||||
throw new repository_exception('readonlyinstance', 'repository');
|
||||
} else if ($instance->instance->contextid != $context->id) {
|
||||
throw new repository_exception('nopermissiontoaccess', 'repository');
|
||||
}
|
||||
if ($sure) {
|
||||
if ($instance->delete($downloadcontents)) {
|
||||
$deletedstr = get_string('instancedeleted', 'repository');
|
||||
|
||||
@@ -68,7 +68,7 @@ $string['usersrenamed'] = 'Users renamed';
|
||||
$string['usersskipped'] = 'Users skipped';
|
||||
$string['usersupdated'] = 'Users updated';
|
||||
$string['usersweakpassword'] = 'Users having a weak password';
|
||||
$string['uubulk'] = 'Select for bulk operations';
|
||||
$string['uubulk'] = 'Select for bulk user actions';
|
||||
$string['uubulkall'] = 'All users';
|
||||
$string['uubulknew'] = 'New users';
|
||||
$string['uubulkupdated'] = 'Updated users';
|
||||
|
||||
+27
-16
@@ -177,16 +177,39 @@
|
||||
$$column = "<a href=\"user.php?sort=$column&dir=$columndir\">".$string[$column]."</a>$columnicon";
|
||||
}
|
||||
|
||||
if ($sort == "name") {
|
||||
$sort = "firstname";
|
||||
$override = new stdClass();
|
||||
$override->firstname = 'firstname';
|
||||
$override->lastname = 'lastname';
|
||||
$fullnamelanguage = get_string('fullnamedisplay', '', $override);
|
||||
if (($CFG->fullnamedisplay == 'firstname lastname') or
|
||||
($CFG->fullnamedisplay == 'firstname') or
|
||||
($CFG->fullnamedisplay == 'language' and $fullnamelanguage == 'firstname lastname' )) {
|
||||
$fullnamedisplay = "$firstname / $lastname";
|
||||
if ($sort == "name") { // If sort has already been set to something else then ignore.
|
||||
$sort = "firstname";
|
||||
}
|
||||
} else { // ($CFG->fullnamedisplay == 'language' and $fullnamelanguage == 'lastname firstname').
|
||||
$fullnamedisplay = "$lastname / $firstname";
|
||||
if ($sort == "name") { // This should give the desired sorting based on fullnamedisplay.
|
||||
$sort = "lastname";
|
||||
}
|
||||
}
|
||||
|
||||
list($extrasql, $params) = $ufiltering->get_sql_filter();
|
||||
$users = get_users_listing($sort, $dir, $page*$perpage, $perpage, '', '', '',
|
||||
$extrasql, $params, $context);
|
||||
|
||||
$usercount = get_users(false);
|
||||
$usersearchcount = get_users(false, '', false, null, "", '', '', '', '', '*', $extrasql, $params);
|
||||
|
||||
// Exclude guest user from list.
|
||||
$noguestsql = '';
|
||||
if (!empty($extrasql)) {
|
||||
$noguestsql .= ' AND';
|
||||
}
|
||||
$noguestsql .= " id <> :guestid";
|
||||
$params['guestid'] = $CFG->siteguest;
|
||||
$users = get_users_listing($sort, $dir, $page*$perpage, $perpage, '', '', '',
|
||||
$extrasql.$noguestsql, $params, $context);
|
||||
|
||||
if ($extrasql !== '') {
|
||||
echo $OUTPUT->heading("$usersearchcount / $usercount ".get_string('users'));
|
||||
$usercount = $usersearchcount;
|
||||
@@ -231,18 +254,6 @@
|
||||
$users = $nusers;
|
||||
}
|
||||
|
||||
$override = new stdClass();
|
||||
$override->firstname = 'firstname';
|
||||
$override->lastname = 'lastname';
|
||||
$fullnamelanguage = get_string('fullnamedisplay', '', $override);
|
||||
if (($CFG->fullnamedisplay == 'firstname lastname') or
|
||||
($CFG->fullnamedisplay == 'firstname') or
|
||||
($CFG->fullnamedisplay == 'language' and $fullnamelanguage == 'firstname lastname' )) {
|
||||
$fullnamedisplay = "$firstname / $lastname";
|
||||
} else { // ($CFG->fullnamedisplay == 'language' and $fullnamelanguage == 'lastname firstname')
|
||||
$fullnamedisplay = "$lastname / $firstname";
|
||||
}
|
||||
|
||||
$table = new html_table();
|
||||
$table->head = array ();
|
||||
$table->align = array();
|
||||
|
||||
@@ -163,6 +163,7 @@ class external_service_functions_form extends moodleform {
|
||||
|
||||
$mform->addElement('searchableselector', 'fids', get_string('name'),
|
||||
$functions, array('multiple'));
|
||||
$mform->addRule('fids', get_string('required'), 'required', null, 'client');
|
||||
|
||||
$mform->addElement('hidden', 'id');
|
||||
$mform->setType('id', PARAM_INT);
|
||||
|
||||
@@ -1040,6 +1040,24 @@ class moodle1_question_bank_handler extends moodle1_xml_handler {
|
||||
/** @var array holds the instances of qtype specific conversion handlers */
|
||||
private $qtypehandlers = null;
|
||||
|
||||
/**
|
||||
* Return the file manager instance used.
|
||||
*
|
||||
* @return moodle1_file_manager
|
||||
*/
|
||||
public function get_file_manager() {
|
||||
return $this->fileman;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information about the question category context being currently parsed
|
||||
*
|
||||
* @return array with keys contextid, contextlevel and contextinstanceid
|
||||
*/
|
||||
public function get_current_category_context() {
|
||||
return $this->currentcategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers path that are not qtype-specific
|
||||
*/
|
||||
@@ -1191,6 +1209,17 @@ class moodle1_question_bank_handler extends moodle1_xml_handler {
|
||||
$data['generalfeedbackformat'] = FORMAT_HTML;
|
||||
}
|
||||
|
||||
// Migrate files in questiontext.
|
||||
$this->fileman->contextid = $this->currentcategory['contextid'];
|
||||
$this->fileman->component = 'question';
|
||||
$this->fileman->filearea = 'questiontext';
|
||||
$this->fileman->itemid = $data['id'];
|
||||
$data['questiontext'] = moodle1_converter::migrate_referenced_files($data['questiontext'], $this->fileman);
|
||||
|
||||
// Migrate files in generalfeedback.
|
||||
$this->fileman->filearea = 'generalfeedback';
|
||||
$data['generalfeedback'] = moodle1_converter::migrate_referenced_files($data['generalfeedback'], $this->fileman);
|
||||
|
||||
// replay the upgrade step 2010080901 - updating question image
|
||||
if (!empty($data['image'])) {
|
||||
if (textlib::substr(textlib::strtolower($data['image']), 0, 7) == 'http://') {
|
||||
@@ -1736,12 +1765,41 @@ abstract class moodle1_qtype_handler extends moodle1_plugin_handler {
|
||||
foreach ($answers as $elementname => $elements) {
|
||||
foreach ($elements as $element) {
|
||||
$answer = $this->convert_answer($element, $qtype);
|
||||
// Migrate images in answertext.
|
||||
if ($answer['answerformat'] == FORMAT_HTML) {
|
||||
$answer['answertext'] = $this->migrate_files($answer['answertext'], 'question', 'answer', $answer['id']);
|
||||
}
|
||||
// Migrate images in feedback.
|
||||
if ($answer['feedbackformat'] == FORMAT_HTML) {
|
||||
$answer['feedback'] = $this->migrate_files($answer['feedback'], 'question', 'answerfeedback', $answer['id']);
|
||||
}
|
||||
$this->write_xml('answer', $answer, array('/answer/id'));
|
||||
}
|
||||
}
|
||||
$this->xmlwriter->end_tag('answers');
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate files belonging to one qtype plugin text field.
|
||||
*
|
||||
* @param array $text the html fragment containing references to files
|
||||
* @param string $component the component for restored files
|
||||
* @param string $filearea the file area for restored files
|
||||
* @param int $itemid the itemid for restored files
|
||||
*
|
||||
* @return string the text for this field, after files references have been processed
|
||||
*/
|
||||
protected function migrate_files($text, $component, $filearea, $itemid) {
|
||||
$context = $this->qbankhandler->get_current_category_context();
|
||||
$fileman = $this->qbankhandler->get_file_manager();
|
||||
$fileman->contextid = $context['contextid'];
|
||||
$fileman->component = $component;
|
||||
$fileman->filearea = $filearea;
|
||||
$fileman->itemid = $itemid;
|
||||
$text = moodle1_converter::migrate_referenced_files($text, $fileman);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the grouped numerical_units structure
|
||||
*
|
||||
@@ -1900,7 +1958,8 @@ abstract class moodle1_qtype_handler extends moodle1_plugin_handler {
|
||||
if ($qtype !== 'multichoice') {
|
||||
$new['answerformat'] = FORMAT_PLAIN;
|
||||
} else {
|
||||
$new['answerformat'] = FORMAT_MOODLE;
|
||||
$new['answertext'] = text_to_html($new['answertext'], false, false, true);
|
||||
$new['answerformat'] = FORMAT_HTML;
|
||||
}
|
||||
|
||||
if ($CFG->texteditors !== 'textarea') {
|
||||
|
||||
@@ -1274,6 +1274,11 @@ class moodle1_file_manager implements loggable {
|
||||
*/
|
||||
public function migrate_directory($rootpath, $relpath='/') {
|
||||
|
||||
// Check the trailing slash in the $rootpath
|
||||
if (substr($rootpath, -1) === '/') {
|
||||
$rootpath = substr($rootpath, 0, strlen($rootpath) - 1);
|
||||
}
|
||||
|
||||
if (!file_exists($this->basepath.'/'.$rootpath.$relpath)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
@@ -266,13 +266,6 @@ class moodle1_converter_testcase extends advanced_testcase {
|
||||
$fileids = $fileman->get_fileids();
|
||||
$this->assertEquals(gettype($fileids), 'array');
|
||||
$this->assertEquals(0, count($fileids));
|
||||
// try to migrate a non-existing directory
|
||||
$returned = $fileman->migrate_directory('not/existing/directory');
|
||||
$this->assertEquals(gettype($returned), 'array');
|
||||
$this->assertEquals(0, count($returned));
|
||||
$fileids = $fileman->get_fileids();
|
||||
$this->assertEquals(gettype($fileids), 'array');
|
||||
$this->assertEquals(0, count($fileids));
|
||||
// try to migrate an invalid file
|
||||
$fileman->itemid = 1;
|
||||
$thrown = false;
|
||||
@@ -314,6 +307,70 @@ class moodle1_converter_testcase extends advanced_testcase {
|
||||
$converter->drop_stash_storage();
|
||||
}
|
||||
|
||||
public function test_migrate_directory() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Set-up the file manager.
|
||||
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
|
||||
$converter->create_stash_storage();
|
||||
$contextid = $converter->get_contextid(CONTEXT_MODULE, 32);
|
||||
$fileman = $converter->get_file_manager($contextid, 'mod_unittest', 'testarea');
|
||||
// This fileman has not converted anything yet.
|
||||
$fileids = $fileman->get_fileids();
|
||||
$this->assertEquals(gettype($fileids), 'array');
|
||||
$this->assertEquals(0, count($fileids));
|
||||
// Try to migrate a non-existing directory.
|
||||
$returned = $fileman->migrate_directory('not/existing/directory');
|
||||
$this->assertEquals(gettype($returned), 'array');
|
||||
$this->assertEquals(0, count($returned));
|
||||
$fileids = $fileman->get_fileids();
|
||||
$this->assertEquals(gettype($fileids), 'array');
|
||||
$this->assertEquals(0, count($fileids));
|
||||
// Try to migrate whole course_files.
|
||||
$returned = $fileman->migrate_directory('course_files');
|
||||
$this->assertEquals(gettype($returned), 'array');
|
||||
$this->assertEquals(4, count($returned)); // Two files, two directories.
|
||||
$fileids = $fileman->get_fileids();
|
||||
$this->assertEquals(gettype($fileids), 'array');
|
||||
$this->assertEquals(4, count($fileids));
|
||||
$subdir = substr($this->iconhash, 0, 2);
|
||||
$this->assertTrue(is_file($converter->get_workdir_path().'/files/'.$subdir.'/'.$this->iconhash));
|
||||
|
||||
// Check the file records.
|
||||
$files = array();
|
||||
$filerecordids = $converter->get_stash_itemids('files');
|
||||
foreach ($filerecordids as $filerecordid) {
|
||||
$filerecord = $converter->get_stash('files', $filerecordid);
|
||||
$files[$filerecord['filepath'].$filerecord['filename']] = $filerecord;
|
||||
}
|
||||
$this->assertEquals('array', gettype($files['/.']));
|
||||
$this->assertEquals('array', gettype($files['/file1.gif']));
|
||||
$this->assertEquals('array', gettype($files['/sub1/.']));
|
||||
$this->assertEquals('array', gettype($files['/sub1/file2.gif']));
|
||||
$this->assertEquals(sha1(''), $files['/.']['contenthash']);
|
||||
$this->assertEquals(sha1(''), $files['/sub1/.']['contenthash']);
|
||||
$this->assertEquals($this->iconhash, $files['/file1.gif']['contenthash']);
|
||||
$this->assertEquals($this->iconhash, $files['/sub1/file2.gif']['contenthash']);
|
||||
|
||||
$converter->drop_stash_storage();
|
||||
}
|
||||
|
||||
public function test_migrate_directory_with_trailing_slash() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Set-up the file manager.
|
||||
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
|
||||
$converter->create_stash_storage();
|
||||
$contextid = $converter->get_contextid(CONTEXT_MODULE, 32);
|
||||
$fileman = $converter->get_file_manager($contextid, 'mod_unittest', 'testarea');
|
||||
// Try to migrate a subdirectory passed with the trailing slash.
|
||||
$returned = $fileman->migrate_directory('course_files/sub1/');
|
||||
$this->assertEquals(gettype($returned), 'array');
|
||||
$this->assertEquals(2, count($returned)); // One file, one directory.
|
||||
|
||||
$converter->drop_stash_storage();
|
||||
}
|
||||
|
||||
public function test_convert_path() {
|
||||
$path = new convert_path('foo_bar', '/ROOT/THINGS/FOO/BAR');
|
||||
$this->assertEquals('foo_bar', $path->get_name());
|
||||
|
||||
+4
-2
@@ -11,6 +11,8 @@ require_once($CFG->dirroot . '/backup/util/ui/import_extensions.php');
|
||||
$courseid = required_param('id', PARAM_INT);
|
||||
// The id of the course we are importing FROM (will only be set if past first stage
|
||||
$importcourseid = optional_param('importid', false, PARAM_INT);
|
||||
// We just want to check if a search has been run. True if anything is there.
|
||||
$searchcourses = optional_param('searchcourses', false, PARAM_BOOL);
|
||||
// The target method for the restore (adding or deleting)
|
||||
$restoretarget = optional_param('target', backup::TARGET_CURRENT_ADDING, PARAM_INT);
|
||||
|
||||
@@ -36,7 +38,7 @@ $PAGE->set_pagelayout('incourse');
|
||||
$renderer = $PAGE->get_renderer('core','backup');
|
||||
|
||||
// Check if we already have a import course id
|
||||
if ($importcourseid === false) {
|
||||
if ($importcourseid === false || $searchcourses) {
|
||||
// Obviously not... show the selector so one can be chosen
|
||||
$url = new moodle_url('/backup/import.php', array('id'=>$courseid));
|
||||
$search = new import_course_search(array('url'=>$url));
|
||||
@@ -160,4 +162,4 @@ echo $renderer->progress_bar($backup->get_progress_bar());
|
||||
echo $backup->display($renderer);
|
||||
$backup->destroy();
|
||||
unset($backup);
|
||||
echo $OUTPUT->footer();
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
@@ -843,20 +843,12 @@ class restore_groups_structure_step extends restore_structure_step {
|
||||
}
|
||||
|
||||
public function process_grouping_group($data) {
|
||||
global $DB;
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot.'/group/lib.php');
|
||||
|
||||
$data = (object)$data;
|
||||
|
||||
$data->groupingid = $this->get_new_parentid('grouping'); // Use new parentid
|
||||
$data->groupid = $this->get_mappingid('group', $data->groupid); // Get from mappings
|
||||
|
||||
$params = array();
|
||||
$params['groupingid'] = $data->groupingid;
|
||||
$params['groupid'] = $data->groupid;
|
||||
|
||||
if (!$DB->record_exists('groupings_groups', $params)) {
|
||||
$DB->insert_record('groupings_groups', $data); // No need to set this mapping (no child info nor files)
|
||||
}
|
||||
groups_assign_grouping($this->get_new_parentid('grouping'), $this->get_mappingid('group', $data->groupid), $data->timeadded);
|
||||
}
|
||||
|
||||
protected function after_execute() {
|
||||
|
||||
@@ -1148,14 +1148,16 @@ abstract class restore_dbops {
|
||||
*
|
||||
* If restoring users from same site backup:
|
||||
* 1A - Normal check: If match by id and username and mnethost => ok, return target user
|
||||
* 1B - Handle users deleted in DB and "alive" in backup file:
|
||||
* 1B - If restoring an 'anonymous' user (created via the 'Anonymize user information' option) try to find a
|
||||
* match by username only => ok, return target user MDL-31484
|
||||
* 1C - Handle users deleted in DB and "alive" in backup file:
|
||||
* If match by id and mnethost and user is deleted in DB and
|
||||
* (match by username LIKE 'backup_email.%' or by non empty email = md5(username)) => ok, return target user
|
||||
* 1C - Handle users deleted in backup file and "alive" in DB:
|
||||
* 1D - Handle users deleted in backup file and "alive" in DB:
|
||||
* If match by id and mnethost and user is deleted in backup file
|
||||
* and match by email = email_without_time(backup_email) => ok, return target user
|
||||
* 1D - Conflict: If match by username and mnethost and doesn't match by id => conflict, return false
|
||||
* 1E - None of the above, return true => User needs to be created
|
||||
* 1E - Conflict: If match by username and mnethost and doesn't match by id => conflict, return false
|
||||
* 1F - None of the above, return true => User needs to be created
|
||||
*
|
||||
* if restoring from another site backup (cannot match by id here, replace it by email/firstaccess combination):
|
||||
* 2A - Normal check: If match by username and mnethost and (email or non-zero firstaccess) => ok, return target user
|
||||
@@ -1187,7 +1189,16 @@ abstract class restore_dbops {
|
||||
return $rec; // Matching user found, return it
|
||||
}
|
||||
|
||||
// 1B - Handle users deleted in DB and "alive" in backup file
|
||||
// 1B - If restoring an 'anonymous' user (created via the 'Anonymize user information' option) try to find a
|
||||
// match by username only => ok, return target user MDL-31484
|
||||
// This avoids username / id mis-match problems when restoring subsequent anonymized backups.
|
||||
if (backup_anonymizer_helper::is_anonymous_user($user)) {
|
||||
if ($rec = $DB->get_record('user', array('username' => $user->username))) {
|
||||
return $rec; // Matching anonymous user found - return it
|
||||
}
|
||||
}
|
||||
|
||||
// 1C - Handle users deleted in DB and "alive" in backup file
|
||||
// Note: for DB deleted users email is stored in username field, hence we
|
||||
// are looking there for emails. See delete_user()
|
||||
// Note: for DB deleted users md5(username) is stored *sometimes* in the email field,
|
||||
@@ -1210,7 +1221,7 @@ abstract class restore_dbops {
|
||||
return $rec; // Matching user, deleted in DB found, return it
|
||||
}
|
||||
|
||||
// 1C - Handle users deleted in backup file and "alive" in DB
|
||||
// 1D - Handle users deleted in backup file and "alive" in DB
|
||||
// If match by id and mnethost and user is deleted in backup file
|
||||
// and match by email = email_without_time(backup_email) => ok, return target user
|
||||
if ($user->deleted) {
|
||||
@@ -1228,7 +1239,7 @@ abstract class restore_dbops {
|
||||
}
|
||||
}
|
||||
|
||||
// 1D - If match by username and mnethost and doesn't match by id => conflict, return false
|
||||
// 1E - If match by username and mnethost and doesn't match by id => conflict, return false
|
||||
if ($rec = $DB->get_record('user', array('username'=>$user->username, 'mnethostid'=>$user->mnethostid))) {
|
||||
if ($user->id != $rec->id) {
|
||||
return false; // Conflict, username already exists and belongs to another id
|
||||
|
||||
@@ -46,6 +46,24 @@
|
||||
*/
|
||||
class backup_anonymizer_helper {
|
||||
|
||||
/**
|
||||
* Determine if the given user is an 'anonymous' user, based on their username, firstname, lastname
|
||||
* and email address.
|
||||
* @param stdClass $user the user record to test
|
||||
* @return bool true if this is an 'anonymous' user
|
||||
*/
|
||||
public static function is_anonymous_user($user) {
|
||||
if (preg_match('/^anon\d*$/', $user->username)) {
|
||||
$match = preg_match('/^anonfirstname\d*$/', $user->firstname);
|
||||
$match = $match && preg_match('/^anonlastname\d*$/', $user->lastname);
|
||||
$match = $match && preg_match('/^anon\d*@doesntexist\.com$/', $user->email);
|
||||
if ($match) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function process_user_auth($value) {
|
||||
return 'manual'; // Set them to manual always
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ require_once($CFG->dirroot . '/backup/util/interfaces/executable.class.php');
|
||||
require_once($CFG->dirroot . '/backup/util/interfaces/processable.class.php');
|
||||
require_once($CFG->dirroot . '/backup/backup.class.php');
|
||||
require_once($CFG->dirroot . '/backup/util/structure/restore_path_element.class.php');
|
||||
require_once($CFG->dirroot . '/backup/util/helper/backup_anonymizer_helper.class.php');
|
||||
require_once($CFG->dirroot . '/backup/util/helper/backup_file_manager.class.php');
|
||||
require_once($CFG->dirroot . '/backup/util/helper/restore_prechecks_helper.class.php');
|
||||
require_once($CFG->dirroot . '/backup/util/helper/restore_moodlexml_parser_processor.class.php');
|
||||
|
||||
@@ -76,6 +76,17 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
|
||||
* @param string $path xml path which parsing has started
|
||||
*/
|
||||
public function before_path($path) {
|
||||
if ($this->path_is_grouped($path) and !isset($this->currentdata[$path])) {
|
||||
// If the grouped element itself does not contain any final tags,
|
||||
// we would not get any chunk data for it. So we add an artificial
|
||||
// empty data chunk here that will be eventually replaced with
|
||||
// real data later in {@link self::postprocess_chunk()}.
|
||||
$this->currentdata[$path] = array(
|
||||
'path' => $path,
|
||||
'level' => substr_count($path, '/') + 1,
|
||||
'tags' => array(),
|
||||
);
|
||||
}
|
||||
if (!$this->grouped_parent_exists($path)) {
|
||||
parent::before_path($path);
|
||||
}
|
||||
@@ -93,7 +104,10 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
|
||||
// currentdata, properly built
|
||||
$data = $this->currentdata[$path];
|
||||
unset($this->currentdata[$path]);
|
||||
// Always, before dispatching any chunk, send all pending start notifications.
|
||||
$this->process_pending_startend_notifications($path, 'start');
|
||||
// TODO: If running under DEBUG_DEVELOPER notice about >1MB grouped chunks
|
||||
// And, finally, dispatch it.
|
||||
$this->dispatch_chunk($data);
|
||||
}
|
||||
// Normal notification of path end
|
||||
@@ -167,7 +181,7 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
|
||||
*/
|
||||
protected function build_currentdata($grouped, $data) {
|
||||
// Check the grouped already exists into currentdata
|
||||
if (!array_key_exists($grouped, $this->currentdata)) {
|
||||
if (!is_array($this->currentdata) or !array_key_exists($grouped, $this->currentdata)) {
|
||||
$a = new stdclass();
|
||||
$a->grouped = $grouped;
|
||||
$a->child = $data['path'];
|
||||
|
||||
@@ -278,6 +278,6 @@ class progressive_parser {
|
||||
class progressive_parser_exception extends moodle_exception {
|
||||
|
||||
public function __construct($errorcode, $a=NULL, $debuginfo=null) {
|
||||
parent::__construct($errorcode, 'error', '', $a, null, $debuginfo);
|
||||
parent::__construct($errorcode, 'error', '', $a, $debuginfo);
|
||||
}
|
||||
}
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
<test>
|
||||
<MOODLE_BACKUP>
|
||||
<COURSE>
|
||||
<FORMATDATA>
|
||||
<WEEKS>
|
||||
<WEEK>
|
||||
<SECTION>1</SECTION>
|
||||
<HIDENUMBER>1</HIDENUMBER>
|
||||
<HIDEDATE>0</HIDEDATE>
|
||||
<SHOWTO></SHOWTO>
|
||||
<OFFLINEMATERIAL>0</OFFLINEMATERIAL>
|
||||
</WEEK>
|
||||
<WEEK>
|
||||
<SECTION>2</SECTION>
|
||||
<HIDENUMBER>0</HIDENUMBER>
|
||||
<HIDEDATE>0</HIDEDATE>
|
||||
<RESETNUMBER>0</RESETNUMBER>
|
||||
<SHOWTO></SHOWTO>
|
||||
<OFFLINEMATERIAL>0</OFFLINEMATERIAL>
|
||||
</WEEK>
|
||||
</WEEKS>
|
||||
<IMPORTED>
|
||||
</IMPORTED>
|
||||
</FORMATDATA>
|
||||
<GROUPEDNOTOBSERVED>
|
||||
<NOBODYOBSERVERSTHIS>
|
||||
<NOTOBSERVED>Muhehe</NOTOBSERVED>
|
||||
</NOBODYOBSERVERSTHIS>
|
||||
</GROUPEDNOTOBSERVED>
|
||||
<EMPTYGROUPED>
|
||||
</EMPTYGROUPED>
|
||||
<SECONDGROUPED>
|
||||
<SUBS>
|
||||
<SUB>
|
||||
<PROP>Unit tests rock!</PROP>
|
||||
</SUB>
|
||||
</SUBS>
|
||||
</SECONDGROUPED>
|
||||
</COURSE>
|
||||
</MOODLE_BACKUP>
|
||||
<moodle2>
|
||||
<grouped id="this is not parsed at the moment because there are no final elements">
|
||||
<subs>
|
||||
<sub id="34">
|
||||
<prop>Oh yeah</prop>
|
||||
</sub>
|
||||
</subs>
|
||||
</grouped>
|
||||
<groupednonemptywithattr id="78">
|
||||
<prop>Go baby go</prop>
|
||||
<subs>
|
||||
<sub id="89">
|
||||
<prop>http://moodle.org</prop>
|
||||
</sub>
|
||||
</subs>
|
||||
</groupednonemptywithattr>
|
||||
<groupedemptywithattr attr="ay?">
|
||||
</groupedemptywithattr>
|
||||
</moodle2>
|
||||
</test>
|
||||
@@ -632,6 +632,93 @@ class progressive_parser_test extends advanced_testcase {
|
||||
$this->assertEquals($errcount, 0); // No errors found, plz
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function test_grouped_at_empty_node() {
|
||||
global $CFG;
|
||||
// Instantiate progressive_parser.
|
||||
$pp = new progressive_parser();
|
||||
// Instantiate grouped_parser_processor.
|
||||
$pr = new mock_grouped_parser_processor();
|
||||
$this->assertTrue($pr instanceof progressive_parser_processor);
|
||||
// Add interesting paths - moodle1 style.
|
||||
$pr->add_path('/test/MOODLE_BACKUP/COURSE/FORMATDATA', true);
|
||||
$pr->add_path('/test/MOODLE_BACKUP/COURSE/FORMATDATA/WEEKS/WEEK');
|
||||
$pr->add_path('/test/MOODLE_BACKUP/COURSE/EMPTYGROUPED', true);
|
||||
$pr->add_path('/test/MOODLE_BACKUP/COURSE/SECONDGROUPED', true);
|
||||
$pr->add_path('/test/MOODLE_BACKUP/COURSE/SECONDGROUPED/SUBS/SUB');
|
||||
// Add interesting paths - moodle2 style.
|
||||
$pr->add_path('/test/moodle2/grouped', true);
|
||||
$pr->add_path('/test/moodle2/grouped/subs/sub');
|
||||
$pr->add_path('/test/moodle2/groupedemptywithattr', true);
|
||||
$pr->add_path('/test/moodle2/groupednonemptywithattr', true);
|
||||
$pr->add_path('/test/moodle2/groupednonemptywithattr/subs/sub');
|
||||
// Assign processor to parser.
|
||||
$pp->set_processor($pr);
|
||||
// Set file from fixtures.
|
||||
$pp->set_file($CFG->dirroot . '/backup/util/xml/parser/tests/fixtures/test6.xml');
|
||||
// Process the file.
|
||||
$pp->process();
|
||||
|
||||
// Get all the simplified chunks and perform various validations.
|
||||
$chunks = $pr->get_chunks();
|
||||
$this->assertEquals(count($chunks), 6); // All grouped elements.
|
||||
|
||||
// Check some random data.
|
||||
$this->assertEquals('/test/MOODLE_BACKUP/COURSE/FORMATDATA', $chunks[0]['path']);
|
||||
$this->assertEquals(2, $chunks[0]['tags']['WEEKS']['WEEK'][1]['SECTION']);
|
||||
|
||||
$this->assertEquals('/test/MOODLE_BACKUP/COURSE/EMPTYGROUPED', $chunks[1]['path']);
|
||||
$this->assertEquals(array(), $chunks[1]['tags']);
|
||||
|
||||
$this->assertEquals('/test/MOODLE_BACKUP/COURSE/SECONDGROUPED', $chunks[2]['path']);
|
||||
$this->assertEquals('Unit tests rock!', $chunks[2]['tags']['SUBS']['SUB'][0]['PROP']);
|
||||
|
||||
$this->assertEquals('/test/moodle2/grouped', $chunks[3]['path']);
|
||||
$this->assertFalse(isset($chunks[3]['tags']['id'])); // No final elements, this should be fixed one day.
|
||||
$this->assertEquals(34, $chunks[3]['tags']['subs']['sub'][0]['id']); // We have final element so this is parsed.
|
||||
$this->assertEquals('Oh yeah', $chunks[3]['tags']['subs']['sub'][0]['prop']);
|
||||
|
||||
$this->assertEquals('/test/moodle2/groupednonemptywithattr', $chunks[4]['path']);
|
||||
$this->assertEquals(78, $chunks[4]['tags']['id']); // We have final element so this is parsed.
|
||||
$this->assertEquals('Go baby go', $chunks[4]['tags']['prop']);
|
||||
$this->assertEquals(89, $chunks[4]['tags']['subs']['sub'][0]['id']);
|
||||
$this->assertEquals('http://moodle.org', $chunks[4]['tags']['subs']['sub'][0]['prop']);
|
||||
|
||||
$this->assertEquals('/test/moodle2/groupedemptywithattr', $chunks[5]['path']);
|
||||
$this->assertFalse(isset($chunks[5]['tags']['attr'])); // No final elements, this should be fixed one day.
|
||||
|
||||
// Now check start notifications.
|
||||
$snotifs = $pr->get_start_notifications();
|
||||
// Check we have received the correct number of notifications.
|
||||
$this->assertEquals(count($snotifs), 6);
|
||||
// Check the order of notifications (in order they appear in test6.xml).
|
||||
$this->assertEquals('/test/MOODLE_BACKUP/COURSE/FORMATDATA', $snotifs[0]);
|
||||
$this->assertEquals('/test/MOODLE_BACKUP/COURSE/EMPTYGROUPED', $snotifs[1]);
|
||||
$this->assertEquals('/test/MOODLE_BACKUP/COURSE/SECONDGROUPED', $snotifs[2]);
|
||||
$this->assertEquals('/test/moodle2/grouped', $snotifs[3]);
|
||||
$this->assertEquals('/test/moodle2/groupednonemptywithattr', $snotifs[4]);
|
||||
$this->assertEquals('/test/moodle2/groupedemptywithattr', $snotifs[5]);
|
||||
|
||||
// Now check end notifications.
|
||||
$enotifs = $pr->get_end_notifications();
|
||||
// Check we have received the correct number of notifications.
|
||||
$this->assertEquals(count($enotifs), 6);
|
||||
// Check the order of notifications (in order they appear in test6.xml).
|
||||
$this->assertEquals('/test/MOODLE_BACKUP/COURSE/FORMATDATA', $enotifs[0]);
|
||||
$this->assertEquals('/test/MOODLE_BACKUP/COURSE/EMPTYGROUPED', $enotifs[1]);
|
||||
$this->assertEquals('/test/MOODLE_BACKUP/COURSE/SECONDGROUPED', $enotifs[2]);
|
||||
$this->assertEquals('/test/moodle2/grouped', $enotifs[3]);
|
||||
$this->assertEquals('/test/moodle2/groupednonemptywithattr', $enotifs[4]);
|
||||
$this->assertEquals('/test/moodle2/groupedemptywithattr', $enotifs[5]);
|
||||
|
||||
// Now verify that the start/process/end order is correct.
|
||||
$allnotifs = $pr->get_all_notifications();
|
||||
$this->assertEquals(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks));
|
||||
// Check integrity of the notifications.
|
||||
$errcount = $this->helper_check_notifications_order_integrity($allnotifs);
|
||||
$this->assertEquals(0, $errcount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that given one array of ordered start/process/end notifications will
|
||||
|
||||
@@ -217,7 +217,7 @@ class block_completionstatus extends block_base {
|
||||
$this->content->footer = '<br><a href="'.$details->out().'">'.get_string('moredetails', 'completion').'</a>';
|
||||
} else {
|
||||
// If user is not enrolled, show error
|
||||
$this->content->text = get_string('notenroled', 'completion');
|
||||
$this->content->text = get_string('nottracked', 'completion');
|
||||
}
|
||||
|
||||
if (has_capability('report/completion:view', $context)) {
|
||||
|
||||
@@ -24,4 +24,4 @@
|
||||
*/
|
||||
|
||||
$string['coursesummary'] = 'Course summary';
|
||||
$string['pluginname'] = 'Course/Site description';
|
||||
$string['pluginname'] = 'Course/site summary';
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['addentry'] = 'Add your own favorite quotes!';
|
||||
$string['addentry'] = 'Add a new entry';
|
||||
$string['askaddentry'] = 'When users can add entries to the glossary, show a link with this text';
|
||||
$string['askinvisible'] = 'When users cannot edit or view the glossary, show this text (without link)';
|
||||
$string['askviewglossary'] = 'When users can view the glossary but not add entries, show a link with this text';
|
||||
@@ -41,5 +41,5 @@ $string['select_glossary'] = 'Take entries from this glossary';
|
||||
$string['showconcept'] = 'Show concept (heading) for each entry';
|
||||
$string['title'] = 'Title';
|
||||
$string['type'] = 'How a new entry is chosen';
|
||||
$string['viewglossary'] = 'More quotes...';
|
||||
$string['viewglossary'] = 'View all entries';
|
||||
$string['whichfooter'] = 'You can display links to actions of the glossary this block is associated with. The block will only display links to actions which are enabled for that glossary.';
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Provides support for the conversion of moodle1 backup to the moodle2 format
|
||||
*
|
||||
* @package block_html
|
||||
* @copyright 2012 Paul Nicholls
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Block conversion handler for html
|
||||
*/
|
||||
class moodle1_block_html_handler extends moodle1_block_handler {
|
||||
private $fileman = null;
|
||||
protected function convert_configdata(array $olddata) {
|
||||
$instanceid = $olddata['id'];
|
||||
$contextid = $this->converter->get_contextid(CONTEXT_BLOCK, $olddata['id']);
|
||||
$configdata = unserialize(base64_decode($olddata['configdata']));
|
||||
|
||||
// get a fresh new file manager for this instance
|
||||
$this->fileman = $this->converter->get_file_manager($contextid, 'block_html');
|
||||
|
||||
// convert course files embedded in the block content
|
||||
$this->fileman->filearea = 'content';
|
||||
$this->fileman->itemid = 0;
|
||||
$configdata->text = moodle1_converter::migrate_referenced_files($configdata->text, $this->fileman);
|
||||
$configdata->format = FORMAT_HTML;
|
||||
|
||||
return base64_encode(serialize($configdata));
|
||||
}
|
||||
|
||||
protected function write_inforef_xml($newdata, $data) {
|
||||
$this->open_xml_writer("course/blocks/{$data['name']}_{$data['id']}/inforef.xml");
|
||||
$this->xmlwriter->begin_tag('inforef');
|
||||
$this->xmlwriter->begin_tag('fileref');
|
||||
foreach ($this->fileman->get_fileids() as $fileid) {
|
||||
$this->write_xml('file', array('id' => $fileid));
|
||||
}
|
||||
$this->xmlwriter->end_tag('fileref');
|
||||
$this->xmlwriter->end_tag('inforef');
|
||||
$this->close_xml_writer();
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Provides support for the conversion of moodle1 backup to the moodle2 format
|
||||
*
|
||||
* @package block_html
|
||||
* @copyright 2012 Paul Nicholls
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Block conversion handler for html
|
||||
*/
|
||||
class moodle1_block_html_handler extends moodle1_block_handler {
|
||||
private $fileman = null;
|
||||
protected function convert_configdata(array $olddata) {
|
||||
$instanceid = $olddata['id'];
|
||||
$contextid = $this->converter->get_contextid(CONTEXT_BLOCK, $olddata['id']);
|
||||
$configdata = unserialize(base64_decode($olddata['configdata']));
|
||||
|
||||
// get a fresh new file manager for this instance
|
||||
$this->fileman = $this->converter->get_file_manager($contextid, 'block_html');
|
||||
|
||||
// convert course files embedded in the block content
|
||||
$this->fileman->filearea = 'content';
|
||||
$this->fileman->itemid = 0;
|
||||
$configdata->text = moodle1_converter::migrate_referenced_files($configdata->text, $this->fileman);
|
||||
$configdata->format = FORMAT_HTML;
|
||||
|
||||
return base64_encode(serialize($configdata));
|
||||
}
|
||||
|
||||
protected function write_inforef_xml($newdata, $data) {
|
||||
$this->open_xml_writer("course/blocks/{$data['name']}_{$data['id']}/inforef.xml");
|
||||
$this->xmlwriter->begin_tag('inforef');
|
||||
$this->xmlwriter->begin_tag('fileref');
|
||||
foreach ($this->fileman->get_fileids() as $fileid) {
|
||||
$this->write_xml('file', array('id' => $fileid));
|
||||
}
|
||||
$this->xmlwriter->end_tag('fileref');
|
||||
$this->xmlwriter->end_tag('inforef');
|
||||
$this->close_xml_writer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Provides support for the conversion of moodle1 backup to the moodle2 format
|
||||
*
|
||||
* @package block_rss_client
|
||||
* @copyright 2012 Paul Nicholls
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Block conversion handler for rss_client
|
||||
*/
|
||||
class moodle1_block_rss_client_handler extends moodle1_block_handler {
|
||||
public function process_block(array $data) {
|
||||
parent::process_block($data);
|
||||
$instanceid = $data['id'];
|
||||
$contextid = $this->converter->get_contextid(CONTEXT_BLOCK, $data['id']);
|
||||
|
||||
// Moodle 1.9 backups do not include sufficient data to restore feeds, so we need an empty shell rss_client.xml
|
||||
// for the restore process to find
|
||||
$this->open_xml_writer("course/blocks/{$data['name']}_{$instanceid}/rss_client.xml");
|
||||
$this->xmlwriter->begin_tag('block', array('id' => $instanceid, 'contextid' => $contextid, 'blockname' => 'rss_client'));
|
||||
$this->xmlwriter->begin_tag('rss_client', array('id' => $instanceid));
|
||||
$this->xmlwriter->full_tag('feeds', '');
|
||||
$this->xmlwriter->end_tag('rss_client');
|
||||
$this->xmlwriter->end_tag('block');
|
||||
$this->close_xml_writer();
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Provides support for the conversion of moodle1 backup to the moodle2 format
|
||||
*
|
||||
* @package block_rss_client
|
||||
* @copyright 2012 Paul Nicholls
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Block conversion handler for rss_client
|
||||
*/
|
||||
class moodle1_block_rss_client_handler extends moodle1_block_handler {
|
||||
public function process_block(array $data) {
|
||||
parent::process_block($data);
|
||||
$instanceid = $data['id'];
|
||||
$contextid = $this->converter->get_contextid(CONTEXT_BLOCK, $data['id']);
|
||||
|
||||
// Moodle 1.9 backups do not include sufficient data to restore feeds, so we need an empty shell rss_client.xml
|
||||
// for the restore process to find
|
||||
$this->open_xml_writer("course/blocks/{$data['name']}_{$instanceid}/rss_client.xml");
|
||||
$this->xmlwriter->begin_tag('block', array('id' => $instanceid, 'contextid' => $contextid, 'blockname' => 'rss_client'));
|
||||
$this->xmlwriter->begin_tag('rss_client', array('id' => $instanceid));
|
||||
$this->xmlwriter->full_tag('feeds', '');
|
||||
$this->xmlwriter->end_tag('rss_client');
|
||||
$this->xmlwriter->end_tag('block');
|
||||
$this->close_xml_writer();
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ if ($returnurl) {
|
||||
$managefeeds = new moodle_url('/blocks/rss_client/managefeeds.php', $urlparams);
|
||||
|
||||
$PAGE->set_url('/blocks/rss_client/editfeed.php', $urlparams);
|
||||
$PAGE->set_pagelayout('base');
|
||||
$PAGE->set_pagelayout('standard');
|
||||
|
||||
if ($rssid) {
|
||||
$isadding = false;
|
||||
@@ -218,10 +218,9 @@ if ($mform->is_cancelled()) {
|
||||
$PAGE->set_title($strtitle);
|
||||
$PAGE->set_heading($strtitle);
|
||||
|
||||
$settingsurl = new moodle_url('/admin/settings.php?section=blocksettingrss_client');
|
||||
$PAGE->navbar->add(get_string('blocks'));
|
||||
$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'), $settingsurl);
|
||||
$PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'));
|
||||
$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'));
|
||||
$PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'), $managefeeds );
|
||||
$PAGE->navbar->add($strtitle);
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
@@ -83,10 +83,9 @@ $PAGE->set_pagelayout('standard');
|
||||
$PAGE->set_title($strmanage);
|
||||
$PAGE->set_heading($strmanage);
|
||||
|
||||
$settingsurl = new moodle_url('/admin/settings.php?section=blocksettingrss_client');
|
||||
$managefeeds = new moodle_url('/blocks/rss_client/managefeeds.php', $urlparams);
|
||||
$PAGE->navbar->add(get_string('blocks'));
|
||||
$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'), $settingsurl);
|
||||
$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'));
|
||||
$PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'), $managefeeds);
|
||||
echo $OUTPUT->header();
|
||||
|
||||
|
||||
@@ -71,11 +71,10 @@ $strviewfeed = get_string('viewfeed', 'block_rss_client');
|
||||
$PAGE->set_title($strviewfeed);
|
||||
$PAGE->set_heading($strviewfeed);
|
||||
|
||||
$settingsurl = new moodle_url('/admin/settings.php?section=blocksettingrss_client');
|
||||
$managefeeds = new moodle_url('/blocks/rss_client/managefeeds.php', $urlparams);
|
||||
$PAGE->navbar->add(get_string('blocks'));
|
||||
$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'), $settingsurl);
|
||||
$PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'));
|
||||
$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'));
|
||||
$PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'), $managefeeds);
|
||||
$PAGE->navbar->add($strviewfeed);
|
||||
echo $OUTPUT->header();
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ class block_selfcompletion extends block_base {
|
||||
|
||||
// Check this user is enroled
|
||||
if (!$info->is_tracked_user($USER->id)) {
|
||||
$this->content->text = get_string('notenroled', 'completion');
|
||||
$this->content->text = get_string('nottracked', 'completion');
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -87,8 +87,8 @@ class blog_edit_form extends moodleform {
|
||||
}
|
||||
|
||||
if (has_capability('moodle/blog:associatecourse', $context)) {
|
||||
$mform->addElement('header', 'assochdr', get_string('associations', 'blog'));
|
||||
$mform->addElement('advcheckbox', 'courseassoc', get_string('associatewithcourse', 'blog', $a), null, null, array(0, $contextid));
|
||||
$mform->addElement('header', 'assochdr', get_string('associations', 'blog'));
|
||||
$mform->addElement('advcheckbox', 'courseassoc', get_string('associatewithcourse', 'blog', $a), null, null, array(0, $contextid));
|
||||
$mform->setDefault('courseassoc', $contextid);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -602,7 +602,7 @@ function blog_get_options_for_module($module, $user=null) {
|
||||
}
|
||||
if (array_key_exists($key, $moduleoptions)) {
|
||||
// Serve from the cache so we don't have to regenerate
|
||||
return $moduleoptions[$module->id];
|
||||
return $moduleoptions[$key];
|
||||
}
|
||||
|
||||
$canparticipate = (is_enrolled($modcontext) or is_viewing($modcontext));
|
||||
|
||||
+6
-5
@@ -729,7 +729,7 @@ function calendar_get_events($tstart, $tend, $users, $groups, $courses, $withdur
|
||||
* @return string $content return available control for the calender in html
|
||||
*/
|
||||
function calendar_top_controls($type, $data) {
|
||||
global $CFG;
|
||||
global $CFG, $PAGE;
|
||||
$content = '';
|
||||
if(!isset($data['d'])) {
|
||||
$data['d'] = 1;
|
||||
@@ -752,6 +752,7 @@ function calendar_top_controls($type, $data) {
|
||||
|
||||
$data['m'] = $date['mon'];
|
||||
$data['y'] = $date['year'];
|
||||
$urlbase = $PAGE->url;
|
||||
|
||||
//Accessibility: calendar block controls, replaced <table> with <div>.
|
||||
//$nexttext = link_arrow_right(get_string('monthnext', 'access'), $url='', $accesshide=true);
|
||||
@@ -761,8 +762,8 @@ function calendar_top_controls($type, $data) {
|
||||
case 'frontpage':
|
||||
list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
|
||||
list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
|
||||
$nextlink = calendar_get_link_next(get_string('monthnext', 'access'), 'index.php?', 0, $nextmonth, $nextyear, $accesshide=true);
|
||||
$prevlink = calendar_get_link_previous(get_string('monthprev', 'access'), 'index.php?', 0, $prevmonth, $prevyear, true);
|
||||
$nextlink = calendar_get_link_next(get_string('monthnext', 'access'), $urlbase, 0, $nextmonth, $nextyear, true);
|
||||
$prevlink = calendar_get_link_previous(get_string('monthprev', 'access'), $urlbase, 0, $prevmonth, $prevyear, true);
|
||||
|
||||
$calendarlink = calendar_get_link_href(new moodle_url(CALENDAR_URL.'view.php', array('view'=>'month')), 1, $data['m'], $data['y']);
|
||||
if (!empty($data['id'])) {
|
||||
@@ -788,8 +789,8 @@ function calendar_top_controls($type, $data) {
|
||||
case 'course':
|
||||
list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
|
||||
list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
|
||||
$nextlink = calendar_get_link_next(get_string('monthnext', 'access'), 'view.php?id='.$data['id'].'&', 0, $nextmonth, $nextyear, $accesshide=true);
|
||||
$prevlink = calendar_get_link_previous(get_string('monthprev', 'access'), 'view.php?id='.$data['id'].'&', 0, $prevmonth, $prevyear, true);
|
||||
$nextlink = calendar_get_link_next(get_string('monthnext', 'access'), $urlbase, 0, $nextmonth, $nextyear, true);
|
||||
$prevlink = calendar_get_link_previous(get_string('monthprev', 'access'), $urlbase, 0, $prevmonth, $prevyear, true);
|
||||
|
||||
$calendarlink = calendar_get_link_href(new moodle_url(CALENDAR_URL.'view.php', array('view'=>'month')), 1, $data['m'], $data['y']);
|
||||
if (!empty($data['id'])) {
|
||||
|
||||
+2
-4
@@ -157,8 +157,7 @@ bodyContent: '<div class="comment-delete-confirm"><a href="#" id="confirmdelete-
|
||||
scope: scope
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
'User-Agent': 'MoodleComment/3.0'
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
||||
},
|
||||
data: build_querystring(params)
|
||||
};
|
||||
@@ -472,8 +471,7 @@ bodyContent: '<div class="comment-delete-confirm"><a href="#" id="confirmdelete-
|
||||
scope: this
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
'User-Agent': 'MoodleComment/3.0'
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
||||
},
|
||||
data: build_querystring(data)
|
||||
};
|
||||
|
||||
+2
-1
@@ -367,7 +367,8 @@ $CFG->admin = 'admin';
|
||||
//
|
||||
// $CFG->themedir = '/location/of/extra/themes';
|
||||
//
|
||||
// It is possible to specify different cache and temp directories, use local fast filesystem.
|
||||
// It is possible to specify different cache and temp directories, use local fast filesystem
|
||||
// for normal web servers. Server clusters MUST use shared filesystem for cachedir!
|
||||
// The directories must not be accessible via web.
|
||||
//
|
||||
// $CFG->tempdir = '/var/www/moodle/temp';
|
||||
|
||||
@@ -144,6 +144,7 @@ if ($editingon && $sesskeyprovided) {
|
||||
require_capability('moodle/course:visibility', $coursecontext);
|
||||
// Set the visibility of the course. we set the old flag when user manually changes visibility of course.
|
||||
$DB->update_record('course', array('id' => $course->id, 'visible' => $visible, 'visibleold' => $visible, 'timemodified' => time()));
|
||||
add_to_log($course->id, "course", ($visible ? 'show' : 'hide'), "edit.php?id=$course->id", $course->id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +173,7 @@ if ($editingon && $sesskeyprovided) {
|
||||
}
|
||||
$DB->set_field('course', 'sortorder', $swapcourse->sortorder, array('id' => $movecourse->id));
|
||||
$DB->set_field('course', 'sortorder', $movecourse->sortorder, array('id' => $swapcourse->id));
|
||||
add_to_log($movecourse->id, "course", "move", "edit.php?id=$movecourse->id", $movecourse->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -548,7 +548,7 @@ M.course_dndupload = {
|
||||
var extension = '';
|
||||
var dotpos = file.name.lastIndexOf('.');
|
||||
if (dotpos != -1) {
|
||||
extension = file.name.substr(dotpos+1, file.name.length);
|
||||
extension = file.name.substr(dotpos+1, file.name.length).toLowerCase();
|
||||
}
|
||||
|
||||
for (var i=0; i<filehandlers.length; i++) {
|
||||
@@ -728,6 +728,9 @@ M.course_dndupload = {
|
||||
resel.icon.src = result.icon;
|
||||
resel.a.href = result.link;
|
||||
resel.namespan.innerHTML = result.name;
|
||||
if (!parseInt(result.visible, 10)) {
|
||||
resel.a.className = 'dimmed';
|
||||
}
|
||||
|
||||
if (result.groupingname) {
|
||||
resel.groupingspan.innerHTML = '(' + result.groupingname + ')';
|
||||
@@ -915,6 +918,9 @@ M.course_dndupload = {
|
||||
resel.icon.src = result.icon;
|
||||
resel.a.href = result.link;
|
||||
resel.namespan.innerHTML = result.name;
|
||||
if (!parseInt(result.visible, 10)) {
|
||||
resel.a.className = 'dimmed';
|
||||
}
|
||||
|
||||
if (result.groupingname) {
|
||||
resel.groupingspan.innerHTML = '(' + result.groupingname + ')';
|
||||
|
||||
@@ -620,12 +620,18 @@ class dndupload_ajax_processor {
|
||||
throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name);
|
||||
}
|
||||
|
||||
// Note the section visibility
|
||||
$visible = get_fast_modinfo($this->course)->get_section_info($this->section)->visible;
|
||||
|
||||
$DB->set_field('course_modules', 'instance', $instanceid, array('id' => $this->cm->id));
|
||||
|
||||
$sectionid = add_mod_to_section($this->cm);
|
||||
$DB->set_field('course_modules', 'section', $sectionid, array('id' => $this->cm->id));
|
||||
|
||||
set_coursemodule_visible($this->cm->id, true);
|
||||
set_coursemodule_visible($this->cm->id, $visible);
|
||||
if (!$visible) {
|
||||
$DB->set_field('course_modules', 'visibleold', 1, array('id' => $this->cm->id));
|
||||
}
|
||||
|
||||
// Rebuild the course cache and retrieve the final info about this module.
|
||||
rebuild_course_cache($this->course->id, true);
|
||||
@@ -636,7 +642,7 @@ class dndupload_ajax_processor {
|
||||
delete_course_module($this->cm->id);
|
||||
throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name);
|
||||
}
|
||||
$mod = $info->cms[$this->cm->id];
|
||||
$mod = $info->get_cm($this->cm->id);
|
||||
$mod->groupmodelink = $this->cm->groupmodelink;
|
||||
$mod->groupmode = $this->cm->groupmode;
|
||||
|
||||
@@ -675,6 +681,7 @@ class dndupload_ajax_processor {
|
||||
$resp->elementid = 'module-'.$mod->id;
|
||||
$resp->commands = make_editing_buttons($mod, true, true, 0, $mod->sectionnum);
|
||||
$resp->onclick = $mod->get_on_click();
|
||||
$resp->visible = $mod->visible;
|
||||
|
||||
// if using groupings, then display grouping name
|
||||
if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', $this->context)) {
|
||||
|
||||
+2
-10
@@ -130,16 +130,8 @@ if ($editform->is_cancelled()) {
|
||||
}
|
||||
rebuild_course_cache($course->id);
|
||||
|
||||
switch ($returnto) {
|
||||
case 'category':
|
||||
case 'topcat': //redirecting to where the new course was created by default.
|
||||
$url = new moodle_url($CFG->wwwroot.'/course/category.php', array('id'=>$categoryid));
|
||||
break;
|
||||
default:
|
||||
$url = new moodle_url($CFG->wwwroot.'/course/view.php', array('id'=>$course->id));
|
||||
break;
|
||||
}
|
||||
redirect($url);
|
||||
// Redirect user to newly created/updated course.
|
||||
redirect(new moodle_url('/course/view.php', array('id' => $course->id)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ class course_edit_form extends moodleform {
|
||||
array(0=>get_string('completiondisabled','completion'), 1=>get_string('completionenabled','completion')));
|
||||
$mform->setDefault('enablecompletion', $courseconfig->enablecompletion);
|
||||
|
||||
$mform->addElement('checkbox', 'completionstartonenrol', get_string('completionstartonenrol', 'completion'));
|
||||
$mform->addElement('advcheckbox', 'completionstartonenrol', get_string('completionstartonenrol', 'completion'));
|
||||
$mform->setDefault('completionstartonenrol', $courseconfig->completionstartonenrol);
|
||||
$mform->disabledIf('completionstartonenrol', 'enablecompletion', 'eq', 0);
|
||||
} else {
|
||||
|
||||
@@ -102,6 +102,7 @@ if ($mform->is_cancelled()) {
|
||||
$newcategory->theme = $data->theme;
|
||||
}
|
||||
|
||||
$logaction = 'update';
|
||||
if ($id) {
|
||||
// Update an existing category.
|
||||
$newcategory->id = $category->id;
|
||||
@@ -119,10 +120,12 @@ if ($mform->is_cancelled()) {
|
||||
$category = create_course_category($newcategory);
|
||||
$newcategory->id = $category->id;
|
||||
$categorycontext = $category->context;
|
||||
$logaction = 'add';
|
||||
}
|
||||
|
||||
$newcategory = file_postupdate_standard_editor($newcategory, 'description', $editoroptions, $categorycontext, 'coursecat', 'description', 0);
|
||||
$DB->update_record('course_categories', $newcategory);
|
||||
add_to_log(SITEID, "category", $logaction, "editcategory.php?id=$newcategory->id", $newcategory->id);
|
||||
fix_course_sortorder();
|
||||
|
||||
redirect('category.php?id='.$newcategory->id.'&categoryedit=on');
|
||||
|
||||
@@ -57,7 +57,7 @@ if (!empty($CFG->enableavailability)) {
|
||||
}
|
||||
|
||||
$mform = new editsection_form($PAGE->url, array('course' => $course, 'editoroptions' => $editoroptions,
|
||||
'cs' => $section, 'showavailability' => $section->showavailability));
|
||||
'cs' => $section));
|
||||
$mform->set_data($section); // set current value
|
||||
|
||||
$returnurl = course_get_url($course, $sectionreturn);
|
||||
|
||||
@@ -12,10 +12,13 @@ class editsection_form extends moodleform {
|
||||
|
||||
$mform = $this->_form;
|
||||
$course = $this->_customdata['course'];
|
||||
$mform->addElement('checkbox', 'usedefaultname', get_string('sectionusedefaultname'));
|
||||
$mform->setDefault('usedefaultname', true);
|
||||
|
||||
$mform->addElement('text', 'name', get_string('sectionname'), array('size'=>'30'));
|
||||
$elementgroup = array();
|
||||
$elementgroup[] = $mform->createElement('text', 'name', '', array('size' => '30'));
|
||||
$elementgroup[] = $mform->createElement('checkbox', 'usedefaultname', '', get_string('sectionusedefaultname'));
|
||||
$mform->addGroup($elementgroup, 'name_group', get_string('sectionname'), ' ', false);
|
||||
|
||||
$mform->setDefault('usedefaultname', true);
|
||||
$mform->setType('name', PARAM_TEXT);
|
||||
$mform->disabledIf('name','usedefaultname','checked');
|
||||
|
||||
@@ -54,11 +57,19 @@ class editsection_form extends moodleform {
|
||||
$mform->addHelpButton('groupingid', 'groupingsection', 'group');
|
||||
}
|
||||
|
||||
// Date and time conditions
|
||||
// Available from/to defaults to midnight because then the display
|
||||
// will be nicer where it tells users when they can access it (it
|
||||
// shows only the date and not time).
|
||||
$date = usergetdate(time());
|
||||
$midnight = make_timestamp($date['year'], $date['mon'], $date['mday']);
|
||||
|
||||
// Date and time conditions.
|
||||
$mform->addElement('date_time_selector', 'availablefrom',
|
||||
get_string('availablefrom', 'condition'), array('optional' => true));
|
||||
get_string('availablefrom', 'condition'),
|
||||
array('optional' => true, 'defaulttime' => $midnight));
|
||||
$mform->addElement('date_time_selector', 'availableuntil',
|
||||
get_string('availableuntil', 'condition'), array('optional' => true));
|
||||
get_string('availableuntil', 'condition'),
|
||||
array('optional' => true, 'defaulttime' => $midnight));
|
||||
|
||||
// Conditions based on grades
|
||||
$gradeoptions = array();
|
||||
@@ -162,8 +173,6 @@ class editsection_form extends moodleform {
|
||||
CONDITION_STUDENTVIEW_HIDE => get_string('showavailabilitysection_hide', 'condition'));
|
||||
$mform->addElement('select', 'showavailability',
|
||||
get_string('showavailabilitysection', 'condition'), $showhide);
|
||||
|
||||
$mform->setDefault('showavailability', $this->_customdata['showavailability']);
|
||||
}
|
||||
|
||||
$this->add_action_buttons();
|
||||
@@ -174,10 +183,41 @@ class editsection_form extends moodleform {
|
||||
// Conditions: Don't let them set dates which make no sense
|
||||
if (array_key_exists('availablefrom', $data) &&
|
||||
$data['availablefrom'] && $data['availableuntil'] &&
|
||||
$data['availablefrom'] > $data['availableuntil']) {
|
||||
$data['availablefrom'] >= $data['availableuntil']) {
|
||||
$errors['availablefrom'] = get_string('badavailabledates', 'condition');
|
||||
}
|
||||
|
||||
// Conditions: Verify that the grade conditions are numbers, and make sense.
|
||||
if (array_key_exists('conditiongradegroup', $data)) {
|
||||
foreach ($data['conditiongradegroup'] as $i => $gradedata) {
|
||||
if ($gradedata['conditiongrademin'] !== '' &&
|
||||
!is_numeric(unformat_float($gradedata['conditiongrademin']))) {
|
||||
$errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
|
||||
continue;
|
||||
}
|
||||
if ($gradedata['conditiongrademax'] !== '' &&
|
||||
!is_numeric(unformat_float($gradedata['conditiongrademax']))) {
|
||||
$errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
|
||||
continue;
|
||||
}
|
||||
if ($gradedata['conditiongrademin'] !== '' && $gradedata['conditiongrademax'] !== '' &&
|
||||
unformat_float($gradedata['conditiongrademax']) <= unformat_float($gradedata['conditiongrademin'])) {
|
||||
$errors["conditiongradegroup[{$i}]"] = get_string('badgradelimits', 'condition');
|
||||
continue;
|
||||
}
|
||||
if ($gradedata['conditiongrademin'] === '' && $gradedata['conditiongrademax'] === '' &&
|
||||
$gradedata['conditiongradeitemid']) {
|
||||
$errors["conditiongradegroup[{$i}]"] = get_string('gradeitembutnolimits', 'condition');
|
||||
continue;
|
||||
}
|
||||
if (($gradedata['conditiongrademin'] !== '' || $gradedata['conditiongrademax'] !== '') &&
|
||||
!$gradedata['conditiongradeitemid']) {
|
||||
$errors["conditiongradegroup[{$i}]"] = get_string('gradelimitsbutnoitem', 'condition');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1254,7 +1254,6 @@ class core_course_external extends external_api {
|
||||
$newcategory = new stdClass();
|
||||
$newcategory->name = $category['name'];
|
||||
$newcategory->parent = $category['parent'];
|
||||
$newcategory->sortorder = 999; // Same as in the course/editcategory.php .
|
||||
// Format the description.
|
||||
if (!empty($category['description'])) {
|
||||
$newcategory->description = $category['description'];
|
||||
|
||||
+38
-14
@@ -175,7 +175,8 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
|
||||
}
|
||||
$o.= html_writer::end_tag('div');
|
||||
|
||||
$o .= $this->section_availability_message($section);
|
||||
$o .= $this->section_availability_message($section,
|
||||
has_capability('moodle/course:viewhiddensections', $context));
|
||||
|
||||
return $o;
|
||||
}
|
||||
@@ -305,7 +306,9 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
|
||||
$o.= html_writer::end_tag('div');
|
||||
$o.= $this->section_activity_summary($section, $course, $mods);
|
||||
|
||||
$o.= $this->section_availability_message($section);
|
||||
$context = context_course::instance($course->id);
|
||||
$o .= $this->section_availability_message($section,
|
||||
has_capability('moodle/course:viewhiddensections', $context));
|
||||
|
||||
$o .= html_writer::end_tag('div');
|
||||
$o .= html_writer::end_tag('li');
|
||||
@@ -388,22 +391,42 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* If section is not visible to current user, display the message about that
|
||||
* ('Not available until...', that sort of thing). Otherwise, returns blank.
|
||||
* If section is not visible, display the message about that ('Not available
|
||||
* until...', that sort of thing). Otherwise, returns blank.
|
||||
*
|
||||
* For users with the ability to view hidden sections, it shows the
|
||||
* information even though you can view the section and also may include
|
||||
* slightly fuller information (so that teachers can tell when sections
|
||||
* are going to be unavailable etc). This logic is the same as for
|
||||
* activities.
|
||||
*
|
||||
* @param stdClass $section The course_section entry from DB
|
||||
* @param bool $canviewhidden True if user can view hidden sections
|
||||
* @return string HTML to output
|
||||
*/
|
||||
protected function section_availability_message($section) {
|
||||
protected function section_availability_message($section, $canviewhidden) {
|
||||
global $CFG;
|
||||
$o = '';
|
||||
if (!$section->uservisible || $section->availableinfo) {
|
||||
if (!$section->uservisible) {
|
||||
$o .= html_writer::start_tag('div', array('class' => 'availabilityinfo'));
|
||||
if (!empty($section->availableinfo)) {
|
||||
$o .= $section->availableinfo;
|
||||
} else {
|
||||
$o .= get_string('notavailable');
|
||||
}
|
||||
// Note: We only get to this function if availableinfo is non-empty,
|
||||
// so there is definitely something to print.
|
||||
$o .= $section->availableinfo;
|
||||
$o .= html_writer::end_tag('div');
|
||||
} else if ($canviewhidden && !empty($CFG->enableavailability) && $section->visible) {
|
||||
// The CONDITION_MISSING_EXTRATABLE is to hide a performance warning that
|
||||
// only applies in 2.3 because of the way we construct section objects on
|
||||
// the FIRST view of a course. In future views, we shouldn't have anything
|
||||
// missing.
|
||||
$ci = new condition_info_section($section, CONDITION_MISSING_EXTRATABLE);
|
||||
$fullinfo = $ci->get_full_information();
|
||||
if ($fullinfo) {
|
||||
$o .= html_writer::start_tag('div', array('class' => 'availabilityinfo'));
|
||||
$o .= get_string(
|
||||
($section->showavailability ? 'userrestriction_visible' : 'userrestriction_hidden'),
|
||||
'condition', $fullinfo);
|
||||
$o .= html_writer::end_tag('div');
|
||||
}
|
||||
}
|
||||
return $o;
|
||||
}
|
||||
@@ -677,9 +700,10 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
|
||||
$thissection->showavailability = 0;
|
||||
}
|
||||
// Show the section if the user is permitted to access it, OR if it's not available
|
||||
// but showavailability is turned on
|
||||
// but showavailability is turned on (and there is some available info text).
|
||||
$showsection = $thissection->uservisible ||
|
||||
($thissection->visible && !$thissection->available && $thissection->showavailability);
|
||||
($thissection->visible && !$thissection->available && $thissection->showavailability
|
||||
&& !empty($thissection->availableinfo));
|
||||
if (!$showsection) {
|
||||
// Hidden section message is overridden by 'unavailable' control
|
||||
// (showavailability option).
|
||||
@@ -716,7 +740,7 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
|
||||
continue;
|
||||
}
|
||||
echo $this->stealth_section_header($section);
|
||||
print_section($course, $thissection, $mods, $modnamesused, true, "100%", false, $displaysection);
|
||||
print_section($course, $thissection, $mods, $modnamesused, true, "100%", false, 0);
|
||||
echo $this->stealth_section_footer();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ M.course.format.swap_sections = function(Y, node1, node2) {
|
||||
};
|
||||
|
||||
var sectionlist = Y.Node.all('.'+CSS.COURSECONTENT+' '+M.course.format.get_section_selector(Y));
|
||||
// Swap menus
|
||||
// Swap menus.
|
||||
sectionlist.item(node1).one('.'+CSS.SECTIONADDMENUS).swap(sectionlist.item(node2).one('.'+CSS.SECTIONADDMENUS));
|
||||
}
|
||||
|
||||
@@ -56,12 +56,32 @@ M.course.format.swap_sections = function(Y, node1, node2) {
|
||||
M.course.format.process_sections = function(Y, sectionlist, response, sectionfrom, sectionto) {
|
||||
var CSS = {
|
||||
SECTIONNAME : 'sectionname'
|
||||
},
|
||||
SELECTORS = {
|
||||
SECTIONLEFTSIDE : '.left .section-handle img'
|
||||
};
|
||||
|
||||
if (response.action == 'move') {
|
||||
// update titles in all affected sections
|
||||
// If moving up swap around 'sectionfrom' and 'sectionto' so the that loop operates.
|
||||
if (sectionfrom > sectionto) {
|
||||
var temp = sectionto;
|
||||
sectionto = sectionfrom;
|
||||
sectionfrom = temp;
|
||||
}
|
||||
|
||||
// Update titles and move icons in all affected sections.
|
||||
var ele, str, stridx, newstr;
|
||||
|
||||
for (var i = sectionfrom; i <= sectionto; i++) {
|
||||
// Update section title.
|
||||
sectionlist.item(i).one('.'+CSS.SECTIONNAME).setContent(response.sectiontitles[i]);
|
||||
// Update move icon.
|
||||
ele = sectionlist.item(i).one(SELECTORS.SECTIONLEFTSIDE);
|
||||
str = ele.getAttribute('alt');
|
||||
stridx = str.lastIndexOf(' ');
|
||||
newstr = str.substr(0, stridx +1) + i;
|
||||
ele.setAttribute('alt', newstr);
|
||||
ele.setAttribute('title', newstr); // For FireFox as 'alt' is not refreshed.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ M.course.format.swap_sections = function(Y, node1, node2) {
|
||||
};
|
||||
|
||||
var sectionlist = Y.Node.all('.'+CSS.COURSECONTENT+' '+M.course.format.get_section_selector(Y));
|
||||
// Swap menus
|
||||
// Swap menus.
|
||||
sectionlist.item(node1).one('.'+CSS.SECTIONADDMENUS).swap(sectionlist.item(node2).one('.'+CSS.SECTIONADDMENUS));
|
||||
}
|
||||
|
||||
@@ -56,12 +56,32 @@ M.course.format.swap_sections = function(Y, node1, node2) {
|
||||
M.course.format.process_sections = function(Y, sectionlist, response, sectionfrom, sectionto) {
|
||||
var CSS = {
|
||||
SECTIONNAME : 'sectionname'
|
||||
},
|
||||
SELECTORS = {
|
||||
SECTIONLEFTSIDE : '.left .section-handle img'
|
||||
};
|
||||
|
||||
if (response.action == 'move') {
|
||||
// update titles in all affected sections
|
||||
// If moving up swap around 'sectionfrom' and 'sectionto' so the that loop operates.
|
||||
if (sectionfrom > sectionto) {
|
||||
var temp = sectionto;
|
||||
sectionto = sectionfrom;
|
||||
sectionfrom = temp;
|
||||
}
|
||||
|
||||
// Update titles and move icons in all affected sections.
|
||||
var ele, str, stridx, newstr;
|
||||
|
||||
for (var i = sectionfrom; i <= sectionto; i++) {
|
||||
// Update section title.
|
||||
sectionlist.item(i).one('.'+CSS.SECTIONNAME).setContent(response.sectiontitles[i]);
|
||||
// Update move icon.
|
||||
ele = sectionlist.item(i).one(SELECTORS.SECTIONLEFTSIDE);
|
||||
str = ele.getAttribute('alt');
|
||||
stridx = str.lastIndexOf(' ');
|
||||
newstr = str.substr(0, stridx +1) + i;
|
||||
ele.setAttribute('alt', newstr);
|
||||
ele.setAttribute('title', newstr); // For FireFox as 'alt' is not refreshed.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-8
@@ -67,12 +67,11 @@ $straction = get_string('action');
|
||||
$strfulllistofcourses = get_string('fulllistofcourses');
|
||||
|
||||
|
||||
/// Unless it's an editing admin, just print the regular listing of courses/categories
|
||||
// Unless it's an editing admin, just print the regular listing of courses/categories.
|
||||
if (!$adminediting) {
|
||||
|
||||
/// Print form for creating new categories
|
||||
$showaddcoursebutton = true;
|
||||
// Print form for creating new categories.
|
||||
$countcategories = $DB->count_records('course_categories');
|
||||
|
||||
if ($countcategories > 1 || ($countcategories == 1 && $DB->count_records('course') > 200)) {
|
||||
$strcourses = get_string('courses');
|
||||
$strcategories = get_string('categories');
|
||||
@@ -96,14 +95,13 @@ if (!$adminediting) {
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->skip_link_target();
|
||||
echo $OUTPUT->box_start('courseboxes');
|
||||
print_courses(0);
|
||||
$showaddcoursebutton = print_courses(0);
|
||||
echo $OUTPUT->box_end();
|
||||
}
|
||||
|
||||
echo $OUTPUT->container_start('buttons');
|
||||
if (has_capability('moodle/course:create', $systemcontext)) {
|
||||
/// Print link to create a new course
|
||||
/// Get the 1st available category
|
||||
if (has_capability('moodle/course:create', $systemcontext) && $showaddcoursebutton) {
|
||||
// Print link to create a new course, for the 1st available category.
|
||||
$options = array('category' => $CFG->defaultrequestcategory);
|
||||
echo $OUTPUT->single_button(new moodle_url('edit.php', $options), get_string('addnewcourse'), 'get');
|
||||
}
|
||||
@@ -232,6 +230,7 @@ if ((!empty($moveup) or !empty($movedown)) and confirm_sesskey()) {
|
||||
if ($swapcategory and $movecategory) {
|
||||
$DB->set_field('course_categories', 'sortorder', $swapcategory->sortorder, array('id'=>$movecategory->id));
|
||||
$DB->set_field('course_categories', 'sortorder', $movecategory->sortorder, array('id'=>$swapcategory->id));
|
||||
add_to_log(SITEID, "category", "move", "editcategory.php?id=$movecategory->id", $movecategory->id);
|
||||
}
|
||||
|
||||
// finally reorder courses
|
||||
|
||||
+57
-23
@@ -60,6 +60,7 @@ function make_log_url($module, $url) {
|
||||
case 'lib':
|
||||
case 'admin':
|
||||
case 'calendar':
|
||||
case 'category':
|
||||
case 'mnet course':
|
||||
if (strpos($url, '../') === 0) {
|
||||
$url = ltrim($url, '.');
|
||||
@@ -1951,7 +1952,8 @@ function get_module_metadata($course, $modnames, $sectionreturn = null) {
|
||||
// NOTE: this is legacy stuff, module subtypes are very strongly discouraged!!
|
||||
$gettypesfunc = $modname.'_get_types';
|
||||
if (function_exists($gettypesfunc)) {
|
||||
if ($types = $gettypesfunc()) {
|
||||
$types = $gettypesfunc();
|
||||
if (is_array($types) && count($types) > 0) {
|
||||
$group = new stdClass();
|
||||
$group->name = $modname;
|
||||
$group->icon = $OUTPUT->pix_icon('icon', '', $modname, array('class' => 'icon'));
|
||||
@@ -2000,7 +2002,11 @@ function get_module_metadata($course, $modnames, $sectionreturn = null) {
|
||||
$module->archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
|
||||
$modlist[$course->id][$modname] = $module;
|
||||
}
|
||||
$return[$modname] = $modlist[$course->id][$modname];
|
||||
if (isset($modlist[$course->id][$modname])) {
|
||||
$return[$modname] = $modlist[$course->id][$modname];
|
||||
} else {
|
||||
debugging("Invalid module metadata configuration for {$modname}");
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
@@ -2457,7 +2463,9 @@ function update_category_button($categoryid = 0) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Category is 0 (for all courses) or an object
|
||||
* Print courses in category. If category is 0 then all courses are printed.
|
||||
* @param int|stdClass $category category object or id.
|
||||
* @return bool true if courses found and printed, else false.
|
||||
*/
|
||||
function print_courses($category) {
|
||||
global $CFG, $OUTPUT;
|
||||
@@ -2505,8 +2513,10 @@ function print_courses($category) {
|
||||
echo html_writer::start_tag('div', array('class'=>'addcoursebutton'));
|
||||
echo $OUTPUT->single_button(new moodle_url('/course/edit.php', $options), get_string("addnewcourse"));
|
||||
echo html_writer::end_tag('div');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2606,6 +2616,7 @@ function print_course($course, $highlightterms = '') {
|
||||
if ($icons = enrol_get_course_info_icons($course)) {
|
||||
echo html_writer::start_tag('div', array('class'=>'enrolmenticons'));
|
||||
foreach ($icons as $icon) {
|
||||
$icon->attributes["alt"] .= ": ". format_string($coursename, true, array('context'=>$context));
|
||||
echo $OUTPUT->render($icon);
|
||||
}
|
||||
echo html_writer::end_tag('div'); // End of enrolmenticons div
|
||||
@@ -2708,14 +2719,14 @@ function print_course_search($value="", $return=false, $format="plain") {
|
||||
$output = '<form id="'.$id.'" action="'.$CFG->wwwroot.'/course/search.php" method="get">';
|
||||
$output .= '<fieldset class="coursesearchbox invisiblefieldset">';
|
||||
$output .= '<label for="shortsearchbox">'.$strsearchcourses.': </label>';
|
||||
$output .= '<input type="text" id="shortsearchbox" size="12" name="search" alt="'.s($strsearchcourses).'" value="'.s($value).'" />';
|
||||
$output .= '<input type="text" id="shortsearchbox" size="12" name="search" value="'.s($value).'" />';
|
||||
$output .= '<input type="submit" value="'.get_string('go').'" />';
|
||||
$output .= '</fieldset></form>';
|
||||
} else if ($format == 'navbar') {
|
||||
$output = '<form id="coursesearchnavbar" action="'.$CFG->wwwroot.'/course/search.php" method="get">';
|
||||
$output .= '<fieldset class="coursesearchbox invisiblefieldset">';
|
||||
$output .= '<label for="navsearchbox">'.$strsearchcourses.': </label>';
|
||||
$output .= '<input type="text" id="navsearchbox" size="20" name="search" alt="'.s($strsearchcourses).'" value="'.s($value).'" />';
|
||||
$output .= '<input type="text" id="navsearchbox" size="20" name="search" value="'.s($value).'" />';
|
||||
$output .= '<input type="submit" value="'.get_string('go').'" />';
|
||||
$output .= '</fieldset></form>';
|
||||
}
|
||||
@@ -2837,6 +2848,7 @@ function add_mod_to_section($mod, $beforemod=NULL) {
|
||||
}
|
||||
|
||||
$DB->set_field("course_sections", "sequence", $newsequence, array("id"=>$section->id));
|
||||
$DB->set_field("course_modules", "section", $section->id, array("id" => $mod->coursemodule));
|
||||
return $section->id; // Return course_sections ID that was used.
|
||||
|
||||
} else { // Insert a new record
|
||||
@@ -2846,7 +2858,9 @@ function add_mod_to_section($mod, $beforemod=NULL) {
|
||||
$section->summary = "";
|
||||
$section->summaryformat = FORMAT_HTML;
|
||||
$section->sequence = $mod->coursemodule;
|
||||
return $DB->insert_record("course_sections", $section);
|
||||
$section->id = $DB->insert_record("course_sections", $section);
|
||||
$DB->set_field("course_modules", "section", $section->id, array("id" => $mod->coursemodule));
|
||||
return $section->id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2874,6 +2888,13 @@ function set_coursemodule_visible($id, $visible, $prevstateoverrides=false) {
|
||||
if (!$cm = $DB->get_record('course_modules', array('id'=>$id))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create events and propagate visibility to associated grade items if the value has changed.
|
||||
// Only do this if it's changed to avoid accidently overwriting manual showing/hiding of student grades.
|
||||
if ($cm->visible == $visible) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$modulename = $DB->get_field('modules', 'name', array('id'=>$cm->module))) {
|
||||
return false;
|
||||
}
|
||||
@@ -2887,7 +2908,7 @@ function set_coursemodule_visible($id, $visible, $prevstateoverrides=false) {
|
||||
}
|
||||
}
|
||||
|
||||
// hide the associated grade items so the teacher doesn't also have to go to the gradebook and hide them there
|
||||
// Hide the associated grade items so the teacher doesn't also have to go to the gradebook and hide them there.
|
||||
$grade_items = grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$modulename, 'iteminstance'=>$cm->instance, 'courseid'=>$cm->course));
|
||||
if ($grade_items) {
|
||||
foreach ($grade_items as $grade_item) {
|
||||
@@ -3144,13 +3165,16 @@ function moveto_module($mod, $section, $beforemod=NULL) {
|
||||
|
||||
/// Update module itself if necessary
|
||||
|
||||
if ($mod->section != $section->id) {
|
||||
$mod->section = $section->id;
|
||||
$DB->update_record("course_modules", $mod);
|
||||
// if moving to a hidden section then hide module
|
||||
if (!$section->visible) {
|
||||
set_coursemodule_visible($mod->id, 0);
|
||||
}
|
||||
// If moving to a hidden section then hide module.
|
||||
if (!$section->visible && $mod->visible) {
|
||||
// Set this in the object because it is sent as a response to ajax calls.
|
||||
set_coursemodule_visible($mod->id, 0, true);
|
||||
$mod->visible = 0;
|
||||
}
|
||||
if ($section->visible && !$mod->visible) {
|
||||
set_coursemodule_visible($mod->id, 1, true);
|
||||
// Set this in the object because it is sent as a response to ajax calls.
|
||||
$mod->visible = $mod->visibleold;
|
||||
}
|
||||
|
||||
/// Add the module into the new section
|
||||
@@ -3483,6 +3507,7 @@ function category_delete_full($category, $showfeedback=true) {
|
||||
// finally delete the category and it's context
|
||||
$DB->delete_records('course_categories', array('id'=>$category->id));
|
||||
delete_context(CONTEXT_COURSECAT, $category->id);
|
||||
add_to_log(SITEID, "category", "delete", "index.php", "$category->name (ID $category->id)");
|
||||
|
||||
events_trigger('course_category_deleted', $category);
|
||||
|
||||
@@ -3538,6 +3563,7 @@ function category_delete_move($category, $newparentid, $showfeedback=true) {
|
||||
// finally delete the category and it's context
|
||||
$DB->delete_records('course_categories', array('id'=>$category->id));
|
||||
delete_context(CONTEXT_COURSECAT, $category->id);
|
||||
add_to_log(SITEID, "category", "delete", "index.php", "$category->name (ID $category->id)");
|
||||
|
||||
events_trigger('course_category_deleted', $category);
|
||||
|
||||
@@ -3584,6 +3610,7 @@ function move_courses($courseids, $categoryid) {
|
||||
}
|
||||
|
||||
$DB->update_record('course', $course);
|
||||
add_to_log($course->id, "course", "move", "edit.php?id=$course->id", $course->id);
|
||||
|
||||
$context = get_context_instance(CONTEXT_COURSE, $course->id);
|
||||
context_moved($context, $newparent);
|
||||
@@ -3616,6 +3643,7 @@ function course_category_hide($category) {
|
||||
$DB->set_field('course', 'visible', 0, array('category' => $cat->id));
|
||||
}
|
||||
}
|
||||
add_to_log(SITEID, "category", "hide", "editcategory.php?id=$category->id", $category->id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3639,6 +3667,7 @@ function course_category_show($category) {
|
||||
$DB->execute("UPDATE {course} SET visible = visibleold WHERE category = ?", array($cat->id));
|
||||
}
|
||||
}
|
||||
add_to_log(SITEID, "category", "show", "editcategory.php?id=$category->id", $category->id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3671,6 +3700,9 @@ function move_category($category, $newparentcat) {
|
||||
// now make it last in new category
|
||||
$DB->set_field('course_categories', 'sortorder', MAX_COURSES_IN_CATEGORY*MAX_COURSE_CATEGORIES, array('id'=>$category->id));
|
||||
|
||||
// Log action.
|
||||
add_to_log(SITEID, "category", "move", "editcategory.php?id=$category->id", $category->id);
|
||||
|
||||
// and fix the sortorders
|
||||
fix_course_sortorder();
|
||||
|
||||
@@ -4426,16 +4458,18 @@ class course_request {
|
||||
* @param stdClass $currentcontext Current context of block
|
||||
*/
|
||||
function course_page_type_list($pagetype, $parentcontext, $currentcontext) {
|
||||
// if above course context ,display all course fomats
|
||||
list($currentcontext, $course, $cm) = get_context_info_array($currentcontext->id);
|
||||
if ($course->id == SITEID) {
|
||||
return array('*'=>get_string('page-x', 'pagetype'));
|
||||
} else {
|
||||
return array('*'=>get_string('page-x', 'pagetype'),
|
||||
'course-*'=>get_string('page-course-x', 'pagetype'),
|
||||
'course-view-*'=>get_string('page-course-view-x', 'pagetype')
|
||||
);
|
||||
// $currentcontext could be null, get_context_info_array() will throw an error if this is the case.
|
||||
if (isset($currentcontext)) {
|
||||
// if above course context ,display all course fomats
|
||||
list($currentcontext, $course, $cm) = get_context_info_array($currentcontext->id);
|
||||
if ($course->id == SITEID) {
|
||||
return array('*'=>get_string('page-x', 'pagetype'));
|
||||
}
|
||||
}
|
||||
return array('*'=>get_string('page-x', 'pagetype'),
|
||||
'course-*'=>get_string('page-course-x', 'pagetype'),
|
||||
'course-view-*'=>get_string('page-course-view-x', 'pagetype')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -481,6 +481,7 @@ if ($mform->is_cancelled()) {
|
||||
// make sure visibility is set correctly (in particular in calendar)
|
||||
// note: allow them to set it even without moodle/course:activityvisibility
|
||||
set_coursemodule_visible($fromform->coursemodule, $fromform->visible);
|
||||
$DB->set_field('course_modules', 'visibleold', 1, array('id' => $fromform->coursemodule));
|
||||
|
||||
if (isset($fromform->cmidnumber)) { //label
|
||||
// set cm idnumber - uniqueness is already verified by form validation
|
||||
|
||||
@@ -332,7 +332,7 @@ abstract class moodleform_mod extends moodleform {
|
||||
continue;
|
||||
}
|
||||
if ($gradedata['conditiongrademin'] !== '' && $gradedata['conditiongrademax'] !== '' &&
|
||||
unformat_float($gradedata['conditiongrademax']) < unformat_float($gradedata['conditiongrademin'])) {
|
||||
unformat_float($gradedata['conditiongrademax']) <= unformat_float($gradedata['conditiongrademin'])) {
|
||||
$errors["conditiongradegroup[{$i}]"] = get_string('badgradelimits', 'condition');
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -107,6 +107,11 @@ class course_reset_form extends moodleform {
|
||||
|
||||
$defaults = array ('reset_events'=>1, 'reset_logs'=>1, 'reset_roles_local'=>1, 'reset_gradebook_grades'=>1, 'reset_notes'=>1);
|
||||
|
||||
// Set student as default in unenrol user list, if role with student archetype exist.
|
||||
if ($studentrole = get_archetype_roles('student')) {
|
||||
$defaults['unenrol_users'] = array_keys($studentrole);
|
||||
}
|
||||
|
||||
if ($allmods = $DB->get_records('modules') ) {
|
||||
foreach ($allmods as $mod) {
|
||||
$modname = $mod->name;
|
||||
|
||||
@@ -138,6 +138,7 @@ switch($requestmethod) {
|
||||
}
|
||||
|
||||
moveto_module($cm, $section, $beforemod);
|
||||
echo json_encode(array('visible' => $cm->visible));
|
||||
break;
|
||||
case 'gettitle':
|
||||
require_capability('moodle/course:manageactivities', $modcontext);
|
||||
|
||||
@@ -226,4 +226,68 @@ class courselib_testcase extends advanced_testcase {
|
||||
$this->assertGreaterThanOrEqual($category2->sortorder, $category3->sortorder);
|
||||
$this->assertGreaterThanOrEqual($category1->sortorder, $category3->sortorder);
|
||||
}
|
||||
|
||||
public function test_move_module_in_course() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
// Setup fixture
|
||||
$course = $this->getDataGenerator()->create_course(array('numsections'=>5), array('createsections' => true));
|
||||
$forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
|
||||
|
||||
$cms = get_fast_modinfo($course)->get_cms();
|
||||
$cm = reset($cms);
|
||||
|
||||
$newsection = get_fast_modinfo($course)->get_section_info(3);
|
||||
$oldsectionid = $cm->section;
|
||||
|
||||
// Perform the move
|
||||
$result = moveto_module($cm, $newsection);
|
||||
$this->assertTrue($result);
|
||||
|
||||
// get_fast_modinfo(reset) is usually called the code calling moveto_module so call it here
|
||||
$reset = 'reset';
|
||||
get_fast_modinfo($reset);
|
||||
$cms = get_fast_modinfo($course)->get_cms();
|
||||
$cm = reset($cms);
|
||||
|
||||
// Check that the old section's sequence no longer contains this ID
|
||||
$oldsection = $DB->get_record('course_sections', array('id' => $oldsectionid));
|
||||
$oldsequences = explode(',', $newsection->sequence);
|
||||
$this->assertFalse(in_array($cm->id, $oldsequences));
|
||||
|
||||
// Check that the new section's sequence now contains this ID
|
||||
$newsection = $DB->get_record('course_sections', array('id' => $newsection->id));
|
||||
$newsequences = explode(',', $newsection->sequence);
|
||||
$this->assertTrue(in_array($cm->id, $newsequences));
|
||||
|
||||
// Check that the section number has been changed in the cm
|
||||
$this->assertEquals($newsection->id, $cm->section);
|
||||
|
||||
|
||||
// Perform a second move as some issues were only seen on the second move
|
||||
$newsection = get_fast_modinfo($course)->get_section_info(2);
|
||||
$oldsectionid = $cm->section;
|
||||
$result = moveto_module($cm, $newsection);
|
||||
$this->assertTrue($result);
|
||||
|
||||
// get_fast_modinfo(reset) is usually called the code calling moveto_module so call it here
|
||||
$reset = 'reset';
|
||||
get_fast_modinfo($reset);
|
||||
$cms = get_fast_modinfo($course)->get_cms();
|
||||
$cm = reset($cms);
|
||||
|
||||
// Check that the old section's sequence no longer contains this ID
|
||||
$oldsection = $DB->get_record('course_sections', array('id' => $oldsectionid));
|
||||
$oldsequences = explode(',', $newsection->sequence);
|
||||
$this->assertFalse(in_array($cm->id, $oldsequences));
|
||||
|
||||
// Check that the new section's sequence now contains this ID
|
||||
$newsection = $DB->get_record('course_sections', array('id' => $newsection->id));
|
||||
$newsequences = explode(',', $newsection->sequence);
|
||||
$this->assertTrue(in_array($cm->id, $newsequences));
|
||||
|
||||
// Check that the section number has been changed in the cm
|
||||
$this->assertEquals($newsection->id, $cm->section);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,9 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
$createdcats = core_course_external::create_categories($categories);
|
||||
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$createdcats = external_api::clean_returnvalue(core_course_external::create_categories_returns(), $createdcats);
|
||||
|
||||
// Initially confirm that base data was inserted correctly.
|
||||
$this->assertEquals($category1->name, $createdcats[0]['name']);
|
||||
$this->assertEquals($category2->name, $createdcats[1]['name']);
|
||||
@@ -93,6 +96,9 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
$createdsubcats = core_course_external::create_categories($subcategories);
|
||||
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$createdsubcats = external_api::clean_returnvalue(core_course_external::create_categories_returns(), $createdsubcats);
|
||||
|
||||
// Confirm that sub categories were inserted correctly.
|
||||
$this->assertEquals($category3->name, $createdsubcats[0]['name']);
|
||||
|
||||
@@ -105,8 +111,12 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
$category2 = $DB->get_record('course_categories', array('id' => $category2->id));
|
||||
$category3 = $DB->get_record('course_categories', array('id' => $category3->id));
|
||||
|
||||
$this->assertGreaterThanOrEqual($category1->sortorder, $category3->sortorder);
|
||||
$this->assertGreaterThanOrEqual($category2->sortorder, $category3->sortorder);
|
||||
// sortorder sequence (and sortorder) must be:
|
||||
// category 1
|
||||
// category 3
|
||||
// category 2
|
||||
$this->assertGreaterThan($category1->sortorder, $category3->sortorder);
|
||||
$this->assertGreaterThan($category3->sortorder, $category2->sortorder);
|
||||
|
||||
// Call without required capability
|
||||
$this->unassignUserCapability('moodle/category:manage', $contextid, $roleid);
|
||||
@@ -197,6 +207,9 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
array('key' => 'id', 'value' => $category1->id),
|
||||
array('key' => 'visible', 'value' => 1)), 1);
|
||||
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories);
|
||||
|
||||
// Check we retrieve the good total number of categories.
|
||||
$this->assertEquals(2, count($categories));
|
||||
|
||||
@@ -214,6 +227,10 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
array('key' => 'id', 'value' => $category1->id),
|
||||
array('key' => 'idnumber', 'value' => $category1->idnumber),
|
||||
array('key' => 'visible', 'value' => 1)), 0);
|
||||
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories);
|
||||
|
||||
$this->assertEquals(1, count($categories));
|
||||
|
||||
// Retrieve categories from parent.
|
||||
@@ -223,6 +240,10 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
// Retrieve all categories.
|
||||
$categories = core_course_external::get_categories();
|
||||
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories);
|
||||
|
||||
$this->assertEquals($DB->count_records('course_categories'), count($categories));
|
||||
|
||||
// Call without required capability (it will fail cause of the search on idnumber).
|
||||
@@ -305,6 +326,9 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Enable course completion.
|
||||
set_config('enablecompletion', 1);
|
||||
|
||||
// Set the required capabilities by the external function
|
||||
$contextid = context_system::instance()->id;
|
||||
$roleid = $this->assignUserCapability('moodle/course:create', $contextid);
|
||||
@@ -343,6 +367,9 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
$createdcourses = core_course_external::create_courses($courses);
|
||||
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$createdcourses = external_api::clean_returnvalue(core_course_external::create_courses_returns(), $createdcourses);
|
||||
|
||||
// Check that right number of courses were created.
|
||||
$this->assertEquals(2, count($createdcourses));
|
||||
|
||||
@@ -376,13 +403,8 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
$this->assertEquals($dbcourse->theme, $course2['forcetheme']);
|
||||
}
|
||||
|
||||
if (completion_info::is_enabled_for_site()) {
|
||||
$this->assertEquals($dbcourse->enablecompletion, $course2['enabledcompletion']);
|
||||
$this->assertEquals($dbcourse->completionstartonenrol, $course2['completionstartonenrol']);
|
||||
} else {
|
||||
$this->assertEquals($dbcourse->enablecompletion, 0);
|
||||
$this->assertEquals($dbcourse->completionstartonenrol, 0);
|
||||
}
|
||||
$this->assertEquals($dbcourse->enablecompletion, $course2['enablecompletion']);
|
||||
$this->assertEquals($dbcourse->completionstartonenrol, $course2['completionstartonenrol']);
|
||||
|
||||
} else if ($createdcourse['shortname'] == $course1['shortname']) {
|
||||
$courseconfig = get_config('moodlecourse');
|
||||
@@ -475,6 +497,9 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
$courses = core_course_external::get_courses(array('ids' =>
|
||||
array($course1->id, $course2->id)));
|
||||
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$courses = external_api::clean_returnvalue(core_course_external::get_courses_returns(), $courses);
|
||||
|
||||
// Check we retrieve the good total number of categories.
|
||||
$this->assertEquals(2, count($courses));
|
||||
|
||||
@@ -508,6 +533,10 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
// Get all courses in the DB
|
||||
$courses = core_course_external::get_courses(array());
|
||||
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$courses = external_api::clean_returnvalue(core_course_external::get_courses_returns(), $courses);
|
||||
|
||||
$this->assertEquals($DB->count_records('course'), count($courses));
|
||||
}
|
||||
|
||||
@@ -535,6 +564,9 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
$courses = core_course_external::get_course_contents($course->id, array());
|
||||
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$courses = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $courses);
|
||||
|
||||
// Check that the course has the 3 created modules
|
||||
$this->assertEquals(3, count($courses[0]['modules']));
|
||||
}
|
||||
@@ -578,6 +610,9 @@ class core_course_external_testcase extends externallib_advanced_testcase {
|
||||
$duplicate = core_course_external::duplicate_course($course->id, $newcourse['fullname'],
|
||||
$newcourse['shortname'], $newcourse['categoryid'], $newcourse['visible'], $newcourse['options']);
|
||||
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$duplicate = external_api::clean_returnvalue(core_course_external::duplicate_course_returns(), $duplicate);
|
||||
|
||||
// Check that the course has been duplicated.
|
||||
$this->assertEquals($newcourse['shortname'], $duplicate['shortname']);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,11 @@ if ($courseid) {
|
||||
require_login($course);
|
||||
|
||||
$completion = new completion_info($course);
|
||||
if (!$completion->is_enabled()) {
|
||||
throw new moodle_exception('completionnotenabled', 'completion');
|
||||
} elseif (!$completion->is_tracked_user($USER->id)) {
|
||||
throw new moodle_exception('nottracked', 'completion');
|
||||
}
|
||||
|
||||
// Check if we are marking a user complete via the completion report
|
||||
$user = optional_param('user', 0, PARAM_INT);
|
||||
@@ -133,12 +138,17 @@ if (isguestuser() or !confirm_sesskey()) {
|
||||
print_error('error');
|
||||
}
|
||||
|
||||
// Now change state
|
||||
// Set up completion object and check it is enabled.
|
||||
$completion = new completion_info($course);
|
||||
if (!$completion->is_enabled()) {
|
||||
die;
|
||||
throw new moodle_exception('completionnotenabled', 'completion');
|
||||
}
|
||||
|
||||
// NOTE: All users are allowed to toggle their completion state, including
|
||||
// users for whom completion information is not directly tracked. (I.e. even
|
||||
// if you are a teacher, or admin who is not enrolled, you can still toggle
|
||||
// your own completion state. You just don't appear on the reports.)
|
||||
|
||||
// Check completion state is manual
|
||||
if($cm->completion != COMPLETION_TRACKING_MANUAL) {
|
||||
error_or_ajax('cannotmanualctrack', $fromajax);
|
||||
|
||||
Vendored
+3
@@ -385,6 +385,9 @@ YUI.add('moodle-course-dragdrop', function(Y) {
|
||||
spinner.show();
|
||||
},
|
||||
success: function(tid, response) {
|
||||
var responsetext = Y.JSON.parse(response.responseText);
|
||||
var params = {element: dragnode, visible: responsetext.visible};
|
||||
M.course.coursebase.invoke_function('set_visibility_resource_ui', params);
|
||||
this.unlock_drag_handle(drag, CSS.EDITINGMOVE);
|
||||
window.setTimeout(function(e) {
|
||||
spinner.hide();
|
||||
|
||||
Vendored
+3
@@ -152,6 +152,9 @@ YUI.add('moodle-course-modchooser', function(Y) {
|
||||
{
|
||||
NAME : MODCHOOSERNAME,
|
||||
ATTRS : {
|
||||
maxheight : {
|
||||
value : 800
|
||||
}
|
||||
}
|
||||
});
|
||||
M.course = M.course || {};
|
||||
|
||||
Vendored
+23
-17
@@ -259,15 +259,6 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
},
|
||||
_setup_for_resource : function(toolboxtarget) {
|
||||
toolboxtarget = Y.one(toolboxtarget);
|
||||
// "Disable" show/hide icons (change cursor to not look clickable) if section is hidden
|
||||
var showhide = toolboxtarget.all(CSS.COMMANDSPAN + ' ' + CSS.HIDE);
|
||||
showhide.concat(toolboxtarget.all(CSS.COMMANDSPAN + ' ' + CSS.SHOW));
|
||||
showhide.each(function(node) {
|
||||
var section = node.ancestor(CSS.SECTIONLI);
|
||||
if (section && section.hasClass(CSS.SECTIONHIDDENCLASS)) {
|
||||
node.setStyle('cursor', 'auto');
|
||||
}
|
||||
});
|
||||
|
||||
// Set groupmode attribute for use by this.toggle_groupmode()
|
||||
var groups;
|
||||
@@ -566,8 +557,9 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
// Cancel the edit if we lose focus or the escape key is pressed
|
||||
thisevent = editor.on('blur', cancel_edittitle);
|
||||
listenevents.push(thisevent);
|
||||
thisevent = Y.one('document').on('keyup', function(e) {
|
||||
if (e.keyCode == 27) {
|
||||
thisevent = Y.one('document').on('keydown', function(e) {
|
||||
if (e.keyCode === 27) {
|
||||
e.preventDefault();
|
||||
cancel_edittitle(e);
|
||||
}
|
||||
});
|
||||
@@ -600,6 +592,26 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
}
|
||||
}, this);
|
||||
listenevents.push(thisevent);
|
||||
},
|
||||
/**
|
||||
* Set the visibility of the current resource (identified by the element)
|
||||
* to match the hidden parameter (this is not a toggle).
|
||||
* Only changes the visibility in the browser (no ajax update).
|
||||
* @param args An object with 'element' being the A node containing the resource
|
||||
* and 'visible' being the state that the visiblity should be set to.
|
||||
* @return void
|
||||
*/
|
||||
set_visibility_resource_ui: function(args) {
|
||||
var element = args.element;
|
||||
var shouldbevisible = args.visible;
|
||||
var buttonnode = element.one(CSS.SHOW);
|
||||
var visible = (buttonnode === null);
|
||||
if (visible) {
|
||||
buttonnode = element.one(CSS.HIDE);
|
||||
}
|
||||
if (visible != shouldbevisible) {
|
||||
this.toggle_hide_resource_ui(buttonnode);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
NAME : 'course-resource-toolbox',
|
||||
@@ -707,12 +719,6 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
if (Y.Array.indexOf(response.resourcestotoggle, activityid) != -1) {
|
||||
this.toggle_hide_resource_ui(button);
|
||||
}
|
||||
|
||||
if (value == 0) {
|
||||
button.setStyle('cursor', 'auto');
|
||||
} else {
|
||||
button.setStyle('cursor', 'pointer');
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
toggle_highlight : function(e) {
|
||||
|
||||
@@ -43,7 +43,7 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
if (!enrol_is_enabled('database')) {
|
||||
return true;
|
||||
}
|
||||
if (!$this->get_config('dbtype') or !$this->get_config('dbhost') or !$this->get_config('remoteenroltable') or !$this->get_config('remotecoursefield') or !$this->get_config('remoteuserfield')) {
|
||||
if (!$this->get_config('dbtype') or !$this->get_config('remoteenroltable') or !$this->get_config('remotecoursefield') or !$this->get_config('remoteuserfield')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
global $CFG, $DB;
|
||||
|
||||
// we do not create courses here intentionally because it requires full sync and is slow
|
||||
if (!$this->get_config('dbtype') or !$this->get_config('dbhost') or !$this->get_config('remoteenroltable') or !$this->get_config('remotecoursefield') or !$this->get_config('remoteuserfield')) {
|
||||
if (!$this->get_config('dbtype') or !$this->get_config('remoteenroltable') or !$this->get_config('remotecoursefield') or !$this->get_config('remoteuserfield')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
global $CFG, $DB;
|
||||
|
||||
// we do not create courses here intentionally because it requires full sync and is slow
|
||||
if (!$this->get_config('dbtype') or !$this->get_config('dbhost') or !$this->get_config('remoteenroltable') or !$this->get_config('remotecoursefield') or !$this->get_config('remoteuserfield')) {
|
||||
if (!$this->get_config('dbtype') or !$this->get_config('remoteenroltable') or !$this->get_config('remotecoursefield') or !$this->get_config('remoteuserfield')) {
|
||||
if ($verbose) {
|
||||
mtrace('User enrolment synchronisation skipped.');
|
||||
}
|
||||
@@ -593,7 +593,7 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
global $CFG, $DB;
|
||||
|
||||
// make sure we sync either enrolments or courses
|
||||
if (!$this->get_config('dbtype') or !$this->get_config('dbhost') or !$this->get_config('newcoursetable') or !$this->get_config('newcoursefullname') or !$this->get_config('newcourseshortname')) {
|
||||
if (!$this->get_config('dbtype') or !$this->get_config('newcoursetable') or !$this->get_config('newcoursefullname') or !$this->get_config('newcourseshortname')) {
|
||||
if ($verbose) {
|
||||
mtrace('Course synchronisation skipped.');
|
||||
}
|
||||
|
||||
+6
-3
@@ -272,9 +272,10 @@ class course_enrolment_manager {
|
||||
* @param bool $searchanywhere
|
||||
* @param int $page Defaults to 0
|
||||
* @param int $perpage Defaults to 25
|
||||
* @param int $addedenrollment Defaults to 0
|
||||
* @return array Array(totalusers => int, users => array)
|
||||
*/
|
||||
public function get_potential_users($enrolid, $search='', $searchanywhere=false, $page=0, $perpage=25) {
|
||||
public function get_potential_users($enrolid, $search='', $searchanywhere=false, $page=0, $perpage=25, $addedenrollment=0) {
|
||||
global $DB, $CFG;
|
||||
|
||||
// Add some additional sensible conditions
|
||||
@@ -312,7 +313,7 @@ class course_enrolment_manager {
|
||||
$order = ' ORDER BY u.lastname ASC, u.firstname ASC';
|
||||
$params['enrolid'] = $enrolid;
|
||||
$totalusers = $DB->count_records_sql($countfields . $sql, $params);
|
||||
$availableusers = $DB->get_records_sql($fields . $sql . $order, $params, $page*$perpage, $perpage);
|
||||
$availableusers = $DB->get_records_sql($fields . $sql . $order, $params, ($page*$perpage) - $addedenrollment, $perpage);
|
||||
return array('totalusers'=>$totalusers, 'users'=>$availableusers);
|
||||
}
|
||||
|
||||
@@ -792,7 +793,9 @@ class course_enrolment_manager {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$users[$userrole->id]['roles'] = array();
|
||||
if (!isset($users[$userrole->id]['roles'])) {
|
||||
$users[$userrole->id]['roles'] = array();
|
||||
}
|
||||
$users[$userrole->id]['roles'][$userrole->roleid] = array(
|
||||
'text' => $roletext,
|
||||
'unchangeable' => !$changeable
|
||||
|
||||
@@ -67,7 +67,9 @@ switch ($action) {
|
||||
$enrolid = required_param('enrolid', PARAM_INT);
|
||||
$search = optional_param('search', '', PARAM_RAW);
|
||||
$page = optional_param('page', 0, PARAM_INT);
|
||||
$outcome->response = $manager->get_potential_users($enrolid, $search, true, $page);
|
||||
$addedenrollment = optional_param('enrolcount', 0, PARAM_INT);
|
||||
$perpage = optional_param('perpage', 25, PARAM_INT); // This value is hard-coded to 25 in quickenrolment.js
|
||||
$outcome->response = $manager->get_potential_users($enrolid, $search, true, $page, $perpage, $addedenrollment);
|
||||
$extrafields = get_extra_user_fields($context);
|
||||
foreach ($outcome->response['users'] as &$user) {
|
||||
$user->picture = $OUTPUT->user_picture($user);
|
||||
|
||||
+18
-3
@@ -22,7 +22,9 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
|
||||
DEFAULTDURATION : 'defaultDuration',
|
||||
ASSIGNABLEROLES : 'assignableRoles',
|
||||
DISABLEGRADEHISTORY : 'disableGradeHistory',
|
||||
RECOVERGRADESDEFAULT : 'recoverGradesDefault'
|
||||
RECOVERGRADESDEFAULT : 'recoverGradesDefault',
|
||||
ENROLCOUNT : 'enrolCount',
|
||||
PERPAGE : 'perPage'
|
||||
};
|
||||
/** CSS classes for nodes in structure **/
|
||||
var CSS = {
|
||||
@@ -304,6 +306,9 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
|
||||
params['action'] = 'searchusers';
|
||||
params['search'] = this.get(UEP.SEARCH).get('value');
|
||||
params['page'] = this.get(UEP.PAGE);
|
||||
params['enrolcount'] = this.get(UEP.ENROLCOUNT);
|
||||
params['perpage'] = this.get(UEP.PERPAGE);
|
||||
|
||||
if (this.get(UEP.MULTIPLE)) {
|
||||
alert('oh no there are multiple');
|
||||
} else {
|
||||
@@ -371,7 +376,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
|
||||
var content = create('<div class="'+CSS.SEARCHRESULTS+'"></div>')
|
||||
.append(create('<div class="'+CSS.TOTALUSERS+'">'+usersstr+'</div>'))
|
||||
.append(users);
|
||||
if (result.response.totalusers > (this.get(UEP.PAGE)+1)*25) {
|
||||
if (result.response.totalusers > (this.get(UEP.PAGE)+1)*this.get(UEP.PERPAGE)) {
|
||||
var fetchmore = create('<div class="'+CSS.MORERESULTS+'"><a href="#">'+M.str.enrol.ajaxnext25+'</a></div>');
|
||||
fetchmore.on('click', this.search, this, true);
|
||||
content.append(fetchmore)
|
||||
@@ -379,7 +384,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
|
||||
this.setContent(content);
|
||||
Y.delegate("click", this.enrolUser, users, '.'+CSS.USER+' .'+CSS.ENROL, this, args);
|
||||
} else {
|
||||
if (result.response.totalusers <= (this.get(UEP.PAGE)+1)*25) {
|
||||
if (result.response.totalusers <= (this.get(UEP.PAGE)+1)*this.get(UEP.PERPAGE)) {
|
||||
this.get(UEP.BASE).one('.'+CSS.MORERESULTS).remove();
|
||||
}
|
||||
}
|
||||
@@ -415,6 +420,8 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
|
||||
args.userNode.addClass(CSS.ENROLLED);
|
||||
args.userNode.one('.'+CSS.ENROL).remove();
|
||||
this.set(UEP.REQUIREREFRESH, true);
|
||||
var countenrol = this.get(UEP.ENROLCOUNT)+1;
|
||||
this.set(UEP.ENROLCOUNT, countenrol);
|
||||
}
|
||||
} catch (e) {
|
||||
new M.core.exception(e);
|
||||
@@ -527,6 +534,14 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
|
||||
},
|
||||
recoverGradesDefault : {
|
||||
value : ''
|
||||
},
|
||||
enrolCount : {
|
||||
value : 0,
|
||||
validator : Y.Lang.isNumber
|
||||
},
|
||||
perPage : {
|
||||
value: 25,
|
||||
Validator: Y.Lang.isNumber
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Vendored
+11
-5
@@ -56,7 +56,6 @@ YUI.add('moodle-enrol-rolemanager', function(Y) {
|
||||
Y.extend(ROLE, Y.Base, {
|
||||
users : [],
|
||||
roleAssignmentPanel : null,
|
||||
panelsubmitevent : null,
|
||||
rolesLoadedEvent : null,
|
||||
escCloseEvent : null,
|
||||
initializer : function(config) {
|
||||
@@ -75,14 +74,16 @@ YUI.add('moodle-enrol-rolemanager', function(Y) {
|
||||
this.rolesLoadedEvent = this.on('assignablerolesloaded', function(){
|
||||
this.rolesLoadedEvent.detach();
|
||||
var panel = this._getRoleAssignmentPanel();
|
||||
this.panelsubmitevent = panel.on('submit', this.addRoleCallback, this);
|
||||
panel.hide().display(user);
|
||||
panel.hide();
|
||||
panel.submitevent = panel.on('submit', this.addRoleCallback, this);
|
||||
panel.display(user);
|
||||
}, this);
|
||||
this._loadAssignableRoles();
|
||||
},
|
||||
addRoleCallback : function(e, roleid, userid) {
|
||||
this.panelsubmitevent.detach();
|
||||
var panel = this._getRoleAssignmentPanel();
|
||||
panel.submitevent.detach();
|
||||
panel.submitevent = null;
|
||||
Y.io(M.cfg.wwwroot+'/enrol/ajax.php', {
|
||||
method:'POST',
|
||||
data:'id='+this.get(COURSEID)+'&action=assign&sesskey='+M.cfg.sesskey+'&roleid='+roleid+'&user='+userid,
|
||||
@@ -350,6 +351,7 @@ YUI.add('moodle-enrol-rolemanager', function(Y) {
|
||||
Y.extend(ROLEPANEL, Y.Base, {
|
||||
user : null,
|
||||
roles : [],
|
||||
submitevent : null,
|
||||
initializer : function() {
|
||||
var i, m = this.get(MANIPULATOR);
|
||||
var element = Y.Node.create('<div class="enrolpanel roleassign"><div class="container"><div class="header"><h2>'+M.str.role.assignroles+'</h2><div class="close"></div></div><div class="content"></div></div></div>');
|
||||
@@ -398,6 +400,10 @@ YUI.add('moodle-enrol-rolemanager', function(Y) {
|
||||
this.roles = [];
|
||||
this.user = null;
|
||||
this.get('elementNode').removeClass('visible');
|
||||
if (this.submitevent) {
|
||||
this.submitevent.detach();
|
||||
this.submitevent = null;
|
||||
}
|
||||
this.displayed = false;
|
||||
return this;
|
||||
},
|
||||
@@ -416,4 +422,4 @@ YUI.add('moodle-enrol-rolemanager', function(Y) {
|
||||
}
|
||||
}
|
||||
|
||||
}, '@VERSION@', {requires:['base','node','io-base','json-parse','test','moodle-enrol-notification']});
|
||||
}, '@VERSION@', {requires:['base','node','io-base','json-parse','test','moodle-enrol-notification']});
|
||||
|
||||
+4
-1
@@ -304,7 +304,10 @@ class core_files_renderer extends plugin_renderer_base {
|
||||
private function fm_js_template_mkdir() {
|
||||
$rv = '
|
||||
<div class="filemanager fp-mkdir-dlg">
|
||||
<div class="fp-mkdir-dlg-text">'.get_string('newfoldername','repository').'<br/><input type="text" /></div>
|
||||
<div class="fp-mkdir-dlg-text">
|
||||
<label>' . get_string('newfoldername', 'repository') . '</label><br/>
|
||||
<input type="text" />
|
||||
</div>
|
||||
<button class="{!}fp-dlg-butcreate">'.get_string('makeafolder').'</button>
|
||||
<button class="{!}fp-dlg-butcancel">'.get_string('cancel').'</button>
|
||||
</div>';
|
||||
|
||||
@@ -30,7 +30,7 @@ require_once('import_outcomes_form.php');
|
||||
|
||||
$courseid = optional_param('courseid', 0, PARAM_INT);
|
||||
$action = optional_param('action', '', PARAM_ALPHA);
|
||||
$scope = optional_param('scope', 'global', PARAM_ALPHA);
|
||||
$scope = optional_param('scope', 'custom', PARAM_ALPHA);
|
||||
|
||||
$PAGE->set_url('/grade/edit/outcome/import.php', array('courseid' => $courseid));
|
||||
|
||||
|
||||
@@ -81,10 +81,13 @@ switch ($action) {
|
||||
// Warn if the grade is out of bounds.
|
||||
if (is_null($finalgrade)) {
|
||||
// ok
|
||||
} else if ($finalgrade < $grade_item->grademin) {
|
||||
$errorstr = 'lessthanmin';
|
||||
} else if ($finalgrade > $grade_item->grademax) {
|
||||
$errorstr = 'morethanmax';
|
||||
} else {
|
||||
$bounded = $grade_item->bounded_grade($finalgrade);
|
||||
if ($bounded > $finalgrade) {
|
||||
$errorstr = 'lessthanmin';
|
||||
} else if ($bounded < $finalgrade) {
|
||||
$errorstr = 'morethanmax';
|
||||
}
|
||||
}
|
||||
|
||||
if ($errorstr) {
|
||||
|
||||
+118
-119
@@ -181,7 +181,7 @@ class grade_report_grader extends grade_report {
|
||||
// Were any changes made?
|
||||
$changedgrades = false;
|
||||
|
||||
foreach ($data as $varname => $postedvalue) {
|
||||
foreach ($data as $varname => $students) {
|
||||
|
||||
$needsupdate = false;
|
||||
|
||||
@@ -194,113 +194,116 @@ class grade_report_grader extends grade_report {
|
||||
continue;
|
||||
}
|
||||
|
||||
$gradeinfo = explode("_", $varname);
|
||||
$userid = clean_param($gradeinfo[1], PARAM_INT);
|
||||
$itemid = clean_param($gradeinfo[2], PARAM_INT);
|
||||
foreach ($students as $userid => $items) {
|
||||
$userid = clean_param($userid, PARAM_INT);
|
||||
foreach ($items as $itemid => $postedvalue) {
|
||||
$itemid = clean_param($itemid, PARAM_INT);
|
||||
|
||||
// Was change requested?
|
||||
$oldvalue = $this->grades[$userid][$itemid];
|
||||
if ($datatype === 'grade') {
|
||||
// If there was no grade and there still isn't
|
||||
if (is_null($oldvalue->finalgrade) && $postedvalue == -1) {
|
||||
// -1 means no grade
|
||||
continue;
|
||||
}
|
||||
// Was change requested?
|
||||
$oldvalue = $this->grades[$userid][$itemid];
|
||||
if ($datatype === 'grade') {
|
||||
// If there was no grade and there still isn't
|
||||
if (is_null($oldvalue->finalgrade) && $postedvalue == -1) {
|
||||
// -1 means no grade
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the grade item uses a custom scale
|
||||
if (!empty($oldvalue->grade_item->scaleid)) {
|
||||
// If the grade item uses a custom scale
|
||||
if (!empty($oldvalue->grade_item->scaleid)) {
|
||||
|
||||
if ((int)$oldvalue->finalgrade === (int)$postedvalue) {
|
||||
continue;
|
||||
if ((int)$oldvalue->finalgrade === (int)$postedvalue) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// The grade item uses a numeric scale
|
||||
|
||||
// Format the finalgrade from the DB so that it matches the grade from the client
|
||||
if ($postedvalue === format_float($oldvalue->finalgrade, $oldvalue->grade_item->get_decimals())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$changedgrades = true;
|
||||
|
||||
} else if ($datatype === 'feedback') {
|
||||
if (($oldvalue->feedback === $postedvalue) or ($oldvalue->feedback === NULL and empty($postedvalue))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The grade item uses a numeric scale
|
||||
|
||||
// Format the finalgrade from the DB so that it matches the grade from the client
|
||||
if ($postedvalue === format_float($oldvalue->finalgrade, $oldvalue->grade_item->get_decimals())) {
|
||||
continue;
|
||||
if (!$gradeitem = grade_item::fetch(array('id'=>$itemid, 'courseid'=>$this->courseid))) {
|
||||
print_error('invalidgradeitemid');
|
||||
}
|
||||
|
||||
// Pre-process grade
|
||||
if ($datatype == 'grade') {
|
||||
$feedback = false;
|
||||
$feedbackformat = false;
|
||||
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
|
||||
if ($postedvalue == -1) { // -1 means no grade
|
||||
$finalgrade = null;
|
||||
} else {
|
||||
$finalgrade = $postedvalue;
|
||||
}
|
||||
} else {
|
||||
$finalgrade = unformat_float($postedvalue);
|
||||
}
|
||||
|
||||
$errorstr = '';
|
||||
// Warn if the grade is out of bounds.
|
||||
if (is_null($finalgrade)) {
|
||||
// ok
|
||||
} else {
|
||||
$bounded = $gradeitem->bounded_grade($finalgrade);
|
||||
if ($bounded > $finalgrade) {
|
||||
$errorstr = 'lessthanmin';
|
||||
} else if ($bounded < $finalgrade) {
|
||||
$errorstr = 'morethanmax';
|
||||
}
|
||||
}
|
||||
if ($errorstr) {
|
||||
$user = $DB->get_record('user', array('id' => $userid), 'id, firstname, lastname');
|
||||
$gradestr = new stdClass();
|
||||
$gradestr->username = fullname($user);
|
||||
$gradestr->itemname = $gradeitem->get_name();
|
||||
$warnings[] = get_string($errorstr, 'grades', $gradestr);
|
||||
}
|
||||
|
||||
} else if ($datatype == 'feedback') {
|
||||
$finalgrade = false;
|
||||
$trimmed = trim($postedvalue);
|
||||
if (empty($trimmed)) {
|
||||
$feedback = NULL;
|
||||
} else {
|
||||
$feedback = $postedvalue;
|
||||
}
|
||||
}
|
||||
|
||||
// group access control
|
||||
if ($separategroups) {
|
||||
// note: we can not use $this->currentgroup because it would fail badly
|
||||
// when having two browser windows each with different group
|
||||
$sharinggroup = false;
|
||||
foreach($mygroups as $groupid) {
|
||||
if (groups_is_member($groupid, $userid)) {
|
||||
$sharinggroup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$sharinggroup) {
|
||||
// either group membership changed or somebody is hacking grades of other group
|
||||
$warnings[] = get_string('errorsavegrade', 'grades');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$gradeitem->update_final_grade($userid, $finalgrade, 'gradebook', $feedback, FORMAT_MOODLE);
|
||||
|
||||
// We can update feedback without reloading the grade item as it doesn't affect grade calculations
|
||||
if ($datatype === 'feedback') {
|
||||
$this->grades[$userid][$itemid]->feedback = $feedback;
|
||||
}
|
||||
}
|
||||
|
||||
$changedgrades = true;
|
||||
|
||||
} else if ($datatype === 'feedback') {
|
||||
if (($oldvalue->feedback === $postedvalue) or ($oldvalue->feedback === NULL and empty($postedvalue))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$gradeitem = grade_item::fetch(array('id'=>$itemid, 'courseid'=>$this->courseid))) { // we must verify course id here!
|
||||
print_error('invalidgradeitemid');
|
||||
}
|
||||
|
||||
// Pre-process grade
|
||||
if ($datatype == 'grade') {
|
||||
$feedback = false;
|
||||
$feedbackformat = false;
|
||||
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
|
||||
if ($postedvalue == -1) { // -1 means no grade
|
||||
$finalgrade = null;
|
||||
} else {
|
||||
$finalgrade = $postedvalue;
|
||||
}
|
||||
} else {
|
||||
$finalgrade = unformat_float($postedvalue);
|
||||
}
|
||||
|
||||
$errorstr = '';
|
||||
// Warn if the grade is out of bounds.
|
||||
if (is_null($finalgrade)) {
|
||||
// ok
|
||||
} else {
|
||||
$bounded = $gradeitem->bounded_grade($finalgrade);
|
||||
if ($bounded > $finalgrade) {
|
||||
$errorstr = 'lessthanmin';
|
||||
} else if ($bounded < $finalgrade) {
|
||||
$errorstr = 'morethanmax';
|
||||
}
|
||||
}
|
||||
if ($errorstr) {
|
||||
$user = $DB->get_record('user', array('id' => $userid), 'id, firstname, lastname');
|
||||
$gradestr = new stdClass();
|
||||
$gradestr->username = fullname($user);
|
||||
$gradestr->itemname = $gradeitem->get_name();
|
||||
$warnings[] = get_string($errorstr, 'grades', $gradestr);
|
||||
}
|
||||
|
||||
} else if ($datatype == 'feedback') {
|
||||
$finalgrade = false;
|
||||
$trimmed = trim($postedvalue);
|
||||
if (empty($trimmed)) {
|
||||
$feedback = NULL;
|
||||
} else {
|
||||
$feedback = $postedvalue;
|
||||
}
|
||||
}
|
||||
|
||||
// group access control
|
||||
if ($separategroups) {
|
||||
// note: we can not use $this->currentgroup because it would fail badly
|
||||
// when having two browser windows each with different group
|
||||
$sharinggroup = false;
|
||||
foreach($mygroups as $groupid) {
|
||||
if (groups_is_member($groupid, $userid)) {
|
||||
$sharinggroup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$sharinggroup) {
|
||||
// either group membership changed or somebody is hacking grades of other group
|
||||
$warnings[] = get_string('errorsavegrade', 'grades');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$gradeitem->update_final_grade($userid, $finalgrade, 'gradebook', $feedback, FORMAT_MOODLE);
|
||||
|
||||
// We can update feedback without reloading the grade item as it doesn't affect grade calculations
|
||||
if ($datatype === 'feedback') {
|
||||
$this->grades[$userid][$itemid]->feedback = $feedback;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1017,7 +1020,7 @@ class grade_report_grader extends grade_report {
|
||||
}
|
||||
$attributes = array('tabindex' => $tabindices[$item->id]['grade'], 'id'=>'grade_'.$userid.'_'.$item->id);
|
||||
$itemcell->text .= html_writer::label(get_string('typescale', 'grades'), $attributes['id'], false, array('class' => 'accesshide'));
|
||||
$itemcell->text .= html_writer::select($scaleopt, 'grade_'.$userid.'_'.$item->id, $gradeval, array(-1=>$nogradestr), $attributes);
|
||||
$itemcell->text .= html_writer::select($scaleopt, 'grade['.$userid.']['.$item->id.']', $gradeval, array(-1=>$nogradestr), $attributes);
|
||||
} elseif(!empty($scale)) {
|
||||
$scales = explode(",", $scale->scale);
|
||||
|
||||
@@ -1036,8 +1039,8 @@ class grade_report_grader extends grade_report {
|
||||
if ($this->get_pref('quickgrading') and $grade->is_editable()) {
|
||||
$value = format_float($gradeval, $decimalpoints);
|
||||
$itemcell->text .= '<input size="6" tabindex="' . $tabindices[$item->id]['grade']
|
||||
. '" type="text" class="text" title="'. $strgrade .'" name="grade_'
|
||||
.$userid.'_' .$item->id.'" id="grade_'.$userid.'_'.$item->id.'" value="'.$value.'" />';
|
||||
. '" type="text" class="text" title="'. $strgrade .'" name="grade['
|
||||
.$userid.'][' .$item->id.']" id="grade_'.$userid.'_'.$item->id.'" value="'.$value.'" />';
|
||||
} else {
|
||||
$itemcell->text .= html_writer::tag('span', format_float($gradeval, $decimalpoints), array('class'=>"gradevalue$hidden$gradepass"));
|
||||
}
|
||||
@@ -1048,7 +1051,7 @@ class grade_report_grader extends grade_report {
|
||||
if ($this->get_pref('showquickfeedback') and $grade->is_editable()) {
|
||||
|
||||
$itemcell->text .= '<input class="quickfeedback" tabindex="' . $tabindices[$item->id]['feedback'].'" id="feedback_'.$userid.'_'.$item->id
|
||||
. '" size="6" title="' . $strfeedback . '" type="text" name="feedback_'.$userid.'_'.$item->id.'" value="' . s($grade->feedback) . '" />';
|
||||
. '" size="6" title="' . $strfeedback . '" type="text" name="feedback['.$userid.']['.$item->id.']" value="' . s($grade->feedback) . '" />';
|
||||
}
|
||||
|
||||
} else { // Not editing
|
||||
@@ -1730,25 +1733,21 @@ class grade_report_grader extends grade_report {
|
||||
// Will this number of students result in more fields that we are allowed?
|
||||
$maxinputvars = ini_get('max_input_vars');
|
||||
if ($maxinputvars !== false) {
|
||||
$fieldspergradeitem = 0; // The number of fields output per grade item for each student
|
||||
// We can't do anything about there being more grade items than max_input_vars,
|
||||
// but we can decrease number of students per page if there are >= max_input_vars
|
||||
$fieldsperstudent = 0; // The number of fields output per student
|
||||
|
||||
if ($this->get_pref('quickgrading')) {
|
||||
// One grade field
|
||||
$fieldspergradeitem ++;
|
||||
}
|
||||
if ($this->get_pref('showquickfeedback')) {
|
||||
// One feedback field
|
||||
$fieldspergradeitem ++;
|
||||
if ($this->get_pref('quickgrading') || $this->get_pref('showquickfeedback')) {
|
||||
// Each array (grade, feedback) will gain one element
|
||||
$fieldsperstudent ++;
|
||||
}
|
||||
|
||||
$fieldsperstudent = $fieldspergradeitem * count($this->gtree->get_items());
|
||||
$fieldsrequired = $studentsperpage * $fieldsperstudent;
|
||||
if ($fieldsrequired > $maxinputvars) {
|
||||
$studentsperpage = floor($maxinputvars / $fieldsperstudent);
|
||||
if ($fieldsrequired >= $maxinputvars) {
|
||||
$studentsperpage = $maxinputvars - 1; // Subtract one to be on the safe side
|
||||
if ($studentsperpage<1) {
|
||||
// Make sure students per page doesn't fall below 1
|
||||
// PHP max_input_vars could potentially be reached with 1 student
|
||||
// if there are >500 grade items and quickgrading and showquickfeedback are on
|
||||
// Make sure students per page doesn't fall below 1, though if your
|
||||
// max_input_vars is only 1 you've got bigger problems!
|
||||
$studentsperpage = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -322,9 +322,9 @@ M.gradereport_grader.classes.ajax = function(report, cfg) {
|
||||
this.existingfields[userid][itemid] = new M.gradereport_grader.classes.existingfield(this, userid, itemid);
|
||||
}
|
||||
}
|
||||
// Hide the Update button
|
||||
// Disable the Update button as we're saving using ajax.
|
||||
submitbutton = this.report.Y.one('#gradersubmit');
|
||||
submitbutton.setStyle('visibility', 'hidden');
|
||||
submitbutton.set('disabled', true);
|
||||
}
|
||||
};
|
||||
/**
|
||||
@@ -740,9 +740,11 @@ M.gradereport_grader.classes.existingfield = function(ajax, userid, itemid) {
|
||||
this.editfeedback = ajax.showquickfeedback;
|
||||
this.grade = this.report.Y.one('#grade_'+userid+'_'+itemid);
|
||||
|
||||
for(var i = 0; i < this.report.grades.length; i++) {
|
||||
if (this.report.grades[i]['user']==this.userid && this.report.grades[i]['item']==this.itemid) {
|
||||
this.oldgrade = this.report.grades[i]['grade'];
|
||||
if (this.report.grades) {
|
||||
for (var i = 0; i < this.report.grades.length; i++) {
|
||||
if (this.report.grades[i]['user']==this.userid && this.report.grades[i]['item']==this.itemid) {
|
||||
this.oldgrade = this.report.grades[i]['grade'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -578,7 +578,7 @@ background-color:#f3ead8;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
.path-grade-report-grader .yui-overlay {
|
||||
.path-grade-report-grader .yui3-overlay {
|
||||
background-color: #FFEE69;
|
||||
border-color: #D4C237 #A6982B #A6982B;
|
||||
border-style: solid;
|
||||
@@ -588,15 +588,15 @@ background-color:#f3ead8;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.path-grade-report-grader .yui-overlay .fullname {
|
||||
.path-grade-report-grader .yui3-overlay .fullname {
|
||||
color: #5F3E00;
|
||||
font-weight: bold;
|
||||
}
|
||||
.path-grade-report-grader .yui-overlay .itemname {
|
||||
.path-grade-report-grader .yui3-overlay .itemname {
|
||||
color: #194F3E;
|
||||
font-weight: bold;
|
||||
}
|
||||
.path-grade-report-grader .yui-overlay .feedback {
|
||||
.path-grade-report-grader .yui3-overlay .feedback {
|
||||
color: #5F595E;
|
||||
}
|
||||
/* table#user-grades td */
|
||||
@@ -605,7 +605,7 @@ background-color:#f3ead8;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.path-grade-report-grader .yui-overlay a.container-close {
|
||||
.path-grade-report-grader .yui3-overlay a.container-close {
|
||||
margin-top: -3px;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,12 @@ class grade_report_overview extends grade_report {
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* The user's courses
|
||||
* @var array $courses
|
||||
*/
|
||||
public $courses;
|
||||
|
||||
/**
|
||||
* A flexitable to hold the data.
|
||||
* @var object $table
|
||||
@@ -45,7 +51,8 @@ class grade_report_overview extends grade_report {
|
||||
public $table;
|
||||
|
||||
/**
|
||||
* show student ranks
|
||||
* Show student ranks within each course.
|
||||
* @var array $showrank
|
||||
*/
|
||||
public $showrank;
|
||||
|
||||
@@ -64,12 +71,26 @@ class grade_report_overview extends grade_report {
|
||||
global $CFG, $COURSE, $DB;
|
||||
parent::__construct($COURSE->id, $gpr, $context);
|
||||
|
||||
$this->showrank = grade_get_setting($this->courseid, 'report_overview_showrank', !empty($CFG->grade_report_overview_showrank));
|
||||
$this->showtotalsifcontainhidden = grade_get_setting($this->courseid, 'report_overview_showtotalsifcontainhidden', $CFG->grade_report_overview_showtotalsifcontainhidden);
|
||||
|
||||
// get the user (for full name)
|
||||
// Get the user (for full name).
|
||||
$this->user = $DB->get_record('user', array('id' => $userid));
|
||||
|
||||
// Load the user's courses.
|
||||
$this->courses = enrol_get_users_courses($this->user->id, false, 'id, shortname, showgrades');
|
||||
|
||||
$this->showrank = array();
|
||||
$this->showrank['any'] = false;
|
||||
if ($this->courses) {
|
||||
foreach ($this->courses as $course) {
|
||||
$this->showrank[$course->id] = grade_get_setting($course->id, 'report_overview_showrank', !empty($CFG->grade_report_overview_showrank));
|
||||
if ($this->showrank[$course->id]) {
|
||||
$this->showrank['any'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// base url for sorting by first/last name
|
||||
$this->baseurl = $CFG->wwwroot.'/grade/overview/index.php?id='.$userid;
|
||||
$this->pbarurl = $this->baseurl;
|
||||
@@ -87,7 +108,7 @@ class grade_report_overview extends grade_report {
|
||||
*/
|
||||
|
||||
// setting up table headers
|
||||
if ($this->showrank) {
|
||||
if ($this->showrank['any']) {
|
||||
$tablecolumns = array('coursename', 'grade', 'rank');
|
||||
$tableheaders = array($this->get_lang_string('coursename', 'grades'),
|
||||
$this->get_lang_string('grade'),
|
||||
@@ -113,11 +134,11 @@ class grade_report_overview extends grade_report {
|
||||
public function fill_table() {
|
||||
global $CFG, $DB, $OUTPUT;
|
||||
|
||||
// MDL-11679, only show user's courses instead of all courses
|
||||
if ($courses = enrol_get_users_courses($this->user->id, false, 'id, shortname, showgrades')) {
|
||||
// Only show user's courses instead of all courses.
|
||||
if ($this->courses) {
|
||||
$numusers = $this->get_numusers(false);
|
||||
|
||||
foreach ($courses as $course) {
|
||||
foreach ($this->courses as $course) {
|
||||
if (!$course->showgrades) {
|
||||
continue;
|
||||
}
|
||||
@@ -151,10 +172,10 @@ class grade_report_overview extends grade_report {
|
||||
|
||||
$data = array($courselink, grade_format_gradevalue($finalgrade, $course_item, true));
|
||||
|
||||
if (!$this->showrank) {
|
||||
if (!$this->showrank['any']) {
|
||||
//nothing to do
|
||||
|
||||
} else if (!is_null($finalgrade)) {
|
||||
} else if ($this->showrank[$course->id] && !is_null($finalgrade)) {
|
||||
/// find the number of users with a higher grade
|
||||
/// please note this can not work if hidden grades involved :-( to be fixed in 2.0
|
||||
$params = array($finalgrade, $course_item->id);
|
||||
@@ -167,7 +188,8 @@ class grade_report_overview extends grade_report {
|
||||
$data[] = "$rank/$numusers";
|
||||
|
||||
} else {
|
||||
// no grade, no rank
|
||||
// No grade, no rank.
|
||||
// Or this course wants rank hidden.
|
||||
$data[] = '-';
|
||||
}
|
||||
|
||||
|
||||
+10
-4
@@ -634,9 +634,10 @@ function groups_parse_name($format, $groupnumber) {
|
||||
*
|
||||
* @param int groupingid
|
||||
* @param int groupid
|
||||
* @param int $timeadded The time the group was added to the grouping.
|
||||
* @return bool true or exception
|
||||
*/
|
||||
function groups_assign_grouping($groupingid, $groupid) {
|
||||
function groups_assign_grouping($groupingid, $groupid, $timeadded = null) {
|
||||
global $DB;
|
||||
|
||||
if ($DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) {
|
||||
@@ -645,7 +646,11 @@ function groups_assign_grouping($groupingid, $groupid) {
|
||||
$assign = new stdClass();
|
||||
$assign->groupingid = $groupingid;
|
||||
$assign->groupid = $groupid;
|
||||
$assign->timeadded = time();
|
||||
if ($timeadded != null) {
|
||||
$assign->timeadded = (integer)$timeadded;
|
||||
} else {
|
||||
$assign->timeadded = time();
|
||||
}
|
||||
$DB->insert_record('groupings_groups', $assign);
|
||||
|
||||
return true;
|
||||
@@ -767,7 +772,7 @@ function groups_calculate_role_people($rs, $context) {
|
||||
$roles[$roledata->id] = $roledata;
|
||||
}
|
||||
// Record that user has role
|
||||
$users[$rec->userid]->roles[] = $roles[$rec->roleid];
|
||||
$users[$rec->userid]->roles[$rec->roleid] = $roles[$rec->roleid];
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
@@ -797,7 +802,8 @@ function groups_calculate_role_people($rs, $context) {
|
||||
} else if($rolecount > 1) {
|
||||
$roleid = '*';
|
||||
} else {
|
||||
$roleid = $userdata->roles[0]->id;
|
||||
$userrole = reset($userdata->roles);
|
||||
$roleid = $userrole->id;
|
||||
}
|
||||
$roles[$roleid]->users[$userid] = $userdata;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['missingrequiredfield'] = 'بعضی از فیلدهای ضروری خالی است';
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['language'] = 'חבילת שפה';
|
||||
$string['language'] = 'שפת ממשק';
|
||||
$string['next'] = 'הלאה';
|
||||
$string['previous'] = 'קודם';
|
||||
$string['reload'] = 'טען מחדש';
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'he';
|
||||
$string['thislanguage'] = 'Hebrew kids';
|
||||
@@ -80,10 +80,10 @@ $string['phpextension'] = 'PHP ekstenzija {$a}';
|
||||
$string['phpversion'] = 'PHP inačica';
|
||||
$string['phpversionhelp'] = '<p>Moodle zahtijeva najmanje PHP inačicu 4.3.0 ili 5.1.0 (5.0.x funkcionira uz brojne uočene probleme).</p> <p>Trenutno imate inačicu {$a}</p> <p>Morate nadograditi PHP ili premestiti Moodle instalaciju na web poslužitelj s novijom verzijom PHP-a!</br> (U slučaju inačice 5.0.x bilo bi najbolje da je vratite na inačicu 4.4.x)</p>';
|
||||
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
|
||||
$string['welcomep20'] = 'Prikazana vam je ova stranica jer ste uspješno instalirali i pokrenuli <strong>{$a->packname} {$a->packversion}</strong> paket na vašem poslužitelju. Čestitamo!';
|
||||
$string['welcomep30'] = 'Ova inačica <strong>{$a->installername}</strong> uključuje aplikacije za stvaranje okruženja u kojem će <strong>Moodle</strong> uspješno funkcionirati, konkretno:';
|
||||
$string['welcomep20'] = 'Prikazana vam je ova stranica jer ste uspješno instalirali i pokrenuli <strong>{$a->packname} {$a->packversion}</strong> paket na svom poslužitelju. Čestitamo!';
|
||||
$string['welcomep30'] = 'Ova inačica <strong>{$a->installername}</strong> uključuje aplikacije za stvaranje okruženja u kojem će sustav <strong>Moodle</strong> uspješno funkcionirati, konkretno:';
|
||||
$string['welcomep40'] = 'Ovaj paket obuhvaća i <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
|
||||
$string['welcomep50'] = 'Korištenje svih aplikacija u ovom paketu je uređeno licencama pod kojima su izdane. Cijeli <strong>{$a->installername}</strong> paket je rješenje <a href="http://www.opensource.org/docs/definition_plain.html">otvorenog koda</a> distribuirano pod <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> licencom.';
|
||||
$string['welcomep60'] = 'Sljedeće stranice će vas voditi kroz postupak instalacije i podešavanja <em>Moodle</em> na poslužitelju. Možete prihvatiti zadane postavke ili promijeniti iste sukladno vašim potrebama.';
|
||||
$string['welcomep50'] = 'Korištenje svih aplikacija u ovom paketu je uređeno licencama pod kojima su izdane. Cijeli paket <strong>{$a->installername}</strong> je rješenje <a href="http://www.opensource.org/docs/definition_plain.html">otvorenog koda</a> distribuirano pod <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> licencom.';
|
||||
$string['welcomep60'] = 'Sljedeće stranice će vas voditi kroz postupak instalacije i podešavanja sustava <em>Moodle</em> na poslužitelju. Možete prihvatiti zadane postavke ili promijeniti iste sukladno vašim potrebama.';
|
||||
$string['welcomep70'] = 'Kliknite na "Next" gumb kako bi započeli <strong>Moodle</strong> instalaciju.';
|
||||
$string['wwwroot'] = 'Web adresa';
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['thislanguage'] = 'Kurmanji';
|
||||
@@ -78,7 +78,7 @@ $string['phpversionhelp'] = '<p>Moodle trenger en PHP versjon minst 4.3.0 eller
|
||||
<Du kjører nå versjon {$a}</p>
|
||||
<p>Du må oppgradere PHP eller flytte til en server med en nyere versjon av PHP!<br /> (I forhold til 5.0.x kan du også nedgradere til versjon 4.4.x)</p>';
|
||||
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
|
||||
$string['welcomep20'] = 'Du ser denne siden fordi du nå med hell har installert og kjørt <strong>{$a->packname} {$a->packversion}</strong>pakken på datamaskinen din. Gratulerer!';
|
||||
$string['welcomep20'] = 'Du ser denne siden fordi du nå med hell har installert og kjørt pakken <strong>{$a->packname} {$a->packversion}</strong> på datamaskinen din. Gratulerer!';
|
||||
$string['welcomep30'] = 'Denne versjonen av <strong>{$a->installername}</strong> inkluderer programmer for å lage et miljø som <strong>Moodle</strong> jobber i, nemlig:';
|
||||
$string['welcomep40'] = 'Denne pakken inkluderer også <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
|
||||
$string['welcomep50'] = 'Bruken av alle applikasjoner i denne pakken er styrt av egne lisenser. Hele <strong>{$a->installername}</strong> pakken er <a href="http://www.opensource.org/docs/definition_plain.html">åpen kildekode</a> og er distribuert under <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> lisensen.';
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['cannotcreatelangdir'] = 'Nie można utworzyć katalogu językowego';
|
||||
$string['cannotcreatelangdir'] = 'Nie można utworzyć katalogu lang/';
|
||||
$string['cannotcreatetempdir'] = 'Nie można utworzyć katalogu tymczasowego';
|
||||
$string['cannotdownloadcomponents'] = 'Nie można pobrać składowych (komponentów)';
|
||||
$string['cannotdownloadzipfile'] = 'Nie można pobrać pliku ZIP';
|
||||
|
||||
@@ -35,7 +35,7 @@ $string['availablelangs'] = 'Lista de idiomas disponíveis';
|
||||
$string['chooselanguagehead'] = 'Escolha um idioma';
|
||||
$string['chooselanguagesub'] = 'Por favor, escolha o idioma para a instalação.Este idioma também será utilizado como idioma padrão do site, embora você possa mudar mais tarde.';
|
||||
$string['clialreadyconfigured'] = 'Arquivo config.php já existente. Por favor use admin/cli/install_database.php se você quer instalar este site';
|
||||
$string['clialreadyinstalled'] = 'O arquivo config.php já existe, por favor use admin/cli/upgrade.php, se você quiser atualizar o seu site.';
|
||||
$string['clialreadyinstalled'] = 'O arquivo config.php já existe, por favor use admin/cli/upgrade.php, se você quiser atualizar este site.';
|
||||
$string['cliinstallheader'] = 'Programa de instalação por linha de comando do Moodle {$a}';
|
||||
$string['databasehost'] = 'Host da base de dados';
|
||||
$string['databasename'] = 'Nome da base de dados';
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['thislanguage'] = 'тоҷикӣ';
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['thislanguage'] = 'Turkmen';
|
||||
@@ -73,9 +73,9 @@ $string['pathsunsecuredataroot'] = '資料根(Dataroot)目錄的位置不安全'
|
||||
$string['pathswrongadmindir'] = '管理目錄不存在';
|
||||
$string['phpextension'] = '{$a} PHP擴展';
|
||||
$string['phpversion'] = 'PHP版本';
|
||||
$string['phpversionhelp'] = '<p>Moodle 需要至少4.1.0.的PHP版本 </p>
|
||||
$string['phpversionhelp'] = '<p>Moodle 需要的PHP版本至少要4.3.0或是5.1.0 (5.0.x有一些已知的問題) </p>
|
||||
<p>您目前執行的是{$a} 版</p>
|
||||
<p>您必須更新您的 PHP 或在有更新版本的主機進行安裝!</p>';
|
||||
<p>您必須更新您的 PHP 或在有更新版本的主機進行安裝!!(若是5.0.x,你可以下降到4.4.x 版本)</p>';
|
||||
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
|
||||
$string['welcomep20'] = '這個頁面是提醒您已經成功安裝與啟動 <strong>{$a->packname} {$a->packversion}</strong> ,恭喜!';
|
||||
$string['welcomep30'] = '<strong>{$a->installername}</strong>包含了可以建立<strong>Moodle</strong>執行環境的應用程序:';
|
||||
|
||||
+11
-11
@@ -149,7 +149,7 @@ $string['configcookiesecure'] = 'If server is accepting only https connections i
|
||||
$string['configcountry'] = 'If you set a country here, then this country will be selected by default on new user accounts. To force users to choose a country, just leave this unset.';
|
||||
$string['configcourserequestnotify'] = 'Type username of user to be notified when new course requested.';
|
||||
$string['configcourserequestnotify2'] = 'Users who will be notified when a course is requested. Only users who can approve course requests are listed here.';
|
||||
$string['configcoursesperpage'] = 'Enter the number of courses to be display per page in a course listing.';
|
||||
$string['configcoursesperpage'] = 'Enter the number of courses to be displayed per page in a course listing.';
|
||||
$string['configcronclionly'] = 'If this is set, then the cron script can only be run from the command line instead of via the web. This overrides the cron password setting below.';
|
||||
$string['configcronremotepassword'] = 'This means that the cron.php script cannot be run from a web browser without supplying the password using the following form of URL:<pre>
|
||||
http://site.example.com/admin/cron.php?password=opensesame
|
||||
@@ -195,7 +195,7 @@ $string['configenablecomments'] = 'Enable comments';
|
||||
$string['configenablecourserequests'] = 'This will allow any user to request a course be created.';
|
||||
$string['configenablegroupmembersonly'] = 'If enabled, access to activities can be restricted to group members only. This may result in an increased server load. In addition, gradebook categories must be set up in a certain way to ensure that activities are hidden from non-group members.';
|
||||
$string['configenablemobilewebservice'] = 'Enable mobile service for the official Moodle app or other app requesting it. For more information, read the {$a}';
|
||||
$string['configenablerssfeeds'] = 'This switch will enable RSS feeds from across the site. To actually see any change you will need to enable RSS feeds in the individual modules too - go to the Modules settings under Admin Configuration.';
|
||||
$string['configenablerssfeeds'] = 'If enabled, RSS feeds are generated by various features across the site, such as blogs, forums, database activities and glossaries. Note that RSS feeds also need to be enabled for the particular activity modules.';
|
||||
$string['configenablerssfeedsdisabled'] = 'It is not available because RSS feeds are disabled in all the Site. To enable them, go to the Variables settings under Admin Configuration.';
|
||||
$string['configenablerssfeedsdisabled2'] = 'RSS feeds are disabled at the server level. You need to enable them first in Server/RSS.';
|
||||
$string['configenablesafebrowserintegration'] = 'This adds the choice \'Require Safe Exam Browser\' to the \'Browser security\' field on the quiz settings form. See http://www.safeexambrowser.org/ for more information.';
|
||||
@@ -258,7 +258,7 @@ $string['configmycoursesperpage'] = 'Maximum number of courses to display in any
|
||||
$string['configmymoodleredirect'] = 'This setting forces redirects to /my on login for non-admins and replaces the top level site navigation with /my';
|
||||
$string['configmypagelocked'] = 'This setting prevents the default page from being edited by any non-admins';
|
||||
$string['confignavcourselimit'] = 'Limits the number of courses shown to the user when they are either not logged in or are not enrolled in any courses.';
|
||||
$string['confignavshowallcourses'] = 'If enabled users will see courses they are enrolled in both within the My Courses branch and the course structure. When disabled users with enrolments will only see the My Courses branch of the navigaiton. The number of course shown would still be limited by "Course limit(navcourselimit)" setting when user is either not logged in or not enrolled in any course.';
|
||||
$string['confignavshowallcourses'] = 'This setting determines whether users who are enrolled in courses can see Courses (listing all courses) in the navigation, in addition to My Courses (listing courses in which they are enrolled).';
|
||||
$string['confignavshowcategories'] = 'Show course categories in the navigation bar and navigation blocks. This does not occur with courses the user is currently enrolled in, they will still be listed under mycourses without categories.';
|
||||
$string['confignotifyloginfailures'] = 'If login failures have been recorded, email notifications can be sent out. Who should see these notifications?';
|
||||
$string['confignotifyloginthreshold'] = 'If notifications about failed logins are active, how many failed login attempts by one user or one IP address is it worth notifying about?';
|
||||
@@ -318,9 +318,9 @@ $string['configstartwday'] = 'Start of week';
|
||||
$string['configstatsfirstrun'] = 'This specifies how far back the logs should be processed <b>the first time</b> the cronjob wants to process statistics. If you have a lot of traffic and are on shared hosting, it\'s probably not a good idea to go too far back, as it could take a long time to run and be quite resource intensive. (Note that for this setting, 1 month = 28 days. In the graphs and reports generated, 1 month = 1 calendar month.)';
|
||||
$string['configstatsmaxruntime'] = 'Stats processing can be quite intensive, so use a combination of this field and the next one to specify when it will run and how long for.';
|
||||
$string['configstatsmaxruntime2'] = 'Stats processing can be quite intensive, specify maximum time allowed for gathering of one day of statistics. Maximum number of days processed in one cron execution is 31.';
|
||||
$string['configstatsmaxruntime3'] = 'Specify the maximum time allowed to calculate the statistics for one day, bearing in mind that stats processing can put a big load on the server. The maximum number of days processed in one cron can be specified below.';
|
||||
$string['configstatsruntimedays'] = 'Specify the maximum number of days processed in each stats execution. When stats are up-to-date, only one day will be processed, so adjust this value depending of your server load, reducing it if shorter cron executions are needed.';
|
||||
$string['configstatsruntimestart'] = 'What time should the cronjob that does the stats processing <b>start</b>? Please specify different times if there are multiple Moodles on one physical server.';
|
||||
$string['configstatsmaxruntime3'] = 'This specifies the maximum time allowed to calculate the statistics for one day, bearing in mind that statistics processing can put a big load on the server. The maximum number of days processed in one cron can be specified below.';
|
||||
$string['configstatsruntimedays'] = 'This specifies the maximum number of days processed in each statistics execution. Once the statistics are up-to-date, only one day will be processed, so adjust this value depending of your server load, reducing it if shorter cron executions are needed.';
|
||||
$string['configstatsruntimestart'] = 'What time should the cronjob that does the statistics processing start? Specifying different times is recommended if there are multiple Moodle sites on one server.';
|
||||
$string['configstatsuserthreshold'] = 'This setting specifies the minimum number of enrolled users for a course to be included in statistics calculations.';
|
||||
$string['configstrictformsrequired'] = 'If enabled, users are prevented from entering a space or line break only in required fields in forms.';
|
||||
$string['configstripalltitletags'] = 'Uncheck this setting to allow HTML tags in activity and resource names.';
|
||||
@@ -440,7 +440,7 @@ $string['download'] = 'Download';
|
||||
$string['edithelpdocs'] = 'Edit help documents';
|
||||
$string['editingnoncorelangfile'] = 'You are trying to modify translation of an add-on module/plugin. You can save translation of 3rd party modules in your _local folder only. You may want to move the file with translation into the module\'s lang directory and/or send it to the maintainer of the add-on module.';
|
||||
$string['editlang'] = '<b>Edit</b>';
|
||||
$string['editorbackgroundcolor'] = 'Background color';
|
||||
$string['editorbackgroundcolor'] = 'Background colour';
|
||||
$string['editordictionary'] = 'Editor dictionary';
|
||||
$string['editorfontfamily'] = 'Font family';
|
||||
$string['editorfontlist'] = 'Font list';
|
||||
@@ -689,12 +689,12 @@ $string['modeditdefaults'] = 'Default values for activity settings';
|
||||
$string['modsettings'] = 'Manage activities';
|
||||
$string['modulesecurity'] = 'Module security';
|
||||
$string['multilangforceold'] = 'Force old multilang syntax: <span> without the class="multilang" and <lang>';
|
||||
$string['mustenablestats'] = 'Stats have not yet been enabled on this site.';
|
||||
$string['mustenablestats'] = 'Statistics have not yet been enabled on this site.';
|
||||
$string['mycoursesperpage'] = 'Number of courses';
|
||||
$string['mydashboard'] = 'System default dashboard';
|
||||
$string['mymoodle'] = 'My Moodle';
|
||||
$string['mymoodle'] = 'My home';
|
||||
$string['mymoodleredirect'] = 'Force users to use My Moodle';
|
||||
$string['mypage'] = 'Default My Moodle page';
|
||||
$string['mypage'] = 'Default My home page';
|
||||
$string['myprofile'] = 'Default profile page';
|
||||
$string['mypagelocked'] = 'Lock default page';
|
||||
$string['mysql416bypassed'] = 'However, if your site is using iso-8859-1 (latin) languages ONLY, you may continue using your currently installed MySQL 4.1.12 (or higher).';
|
||||
@@ -860,7 +860,7 @@ $string['registermoodleorgli2'] = 'Statistics about your site will be added to t
|
||||
$string['registermoodleorgli3'] = 'Your site is also registered with the Moodle.org Open Community Hub ({$a}), allowing users with the publish courses capability (by default only managers) the option of publishing courses to MOOCH.';
|
||||
$string['registerwithmoodleorg'] = 'Register with Moodle.org';
|
||||
$string['registration'] = 'Registration';
|
||||
$string['registration_help'] = 'It is recommended to register on Moodle.org to receive security email alerts, to contribute to the Moodle growth and statistics, or to be able to share courses on MOOCH.';
|
||||
$string['registration_help'] = 'Registering your site with Moodle.org is recommended in order to receive security alert notifications, to contribute <a href="http://moodle.org/stats">Moodle usage statistics</a> and to be able to share courses on <a href="http://hub.moodle.org/">MOOCH</a>.';
|
||||
$string['registrationwarning'] = 'Your site is not yet registered.';
|
||||
$string['releasenoteslink'] = 'For information about this version of Moodle, please see the online <a target="_blank" href="{$a}">Release Notes</a>';
|
||||
$string['rememberusername'] = 'Remember username';
|
||||
|
||||
@@ -26,9 +26,11 @@
|
||||
$string['addtodock'] = 'Move this to the dock';
|
||||
$string['anypagematchingtheabove'] = 'Any page matching the above';
|
||||
$string['appearsinsubcontexts'] = 'Appears in sub-contexts';
|
||||
$string['assignrolesinblock'] = 'Assign roles in {$a} block';
|
||||
$string['blocksettings'] = 'Block settings';
|
||||
$string['bracketfirst'] = '{$a} (first)';
|
||||
$string['bracketlast'] = '{$a} (last)';
|
||||
$string['configureblock'] = 'Configure {$a} block';
|
||||
$string['contexts'] = 'Page contexts';
|
||||
$string['contexts_help'] = 'Contexts are more specific types of pages where this block can be displayed within the original block location. You will have different options here depending on the original block location and your current location. For example, you can restrict a block to only appearing on forum pages in a course by adding the block to the course (making it appear on all sub-pages), then going into a forum and editing the block settings again to restrict display to just forum pages.';
|
||||
$string['createdat'] = 'Original block location';
|
||||
@@ -38,15 +40,20 @@ $string['defaultregion_help'] = 'Themes may define one or more named block regio
|
||||
$string['defaultweight'] = 'Default weight';
|
||||
$string['defaultweight_help'] = 'The default weight allows you to choose roughly where you want the block to appear in the chosen region, either at the top or the bottom. The final location is calculated from all the blocks in that region (for example, only one block can actually be at the top). This value can be overridden on specific pages if required.';
|
||||
$string['deletecheck'] = 'Delete {$a} block?';
|
||||
$string['deleteblock'] = 'Delete {$a} block';
|
||||
$string['deleteblockcheck'] = 'Are you sure that you want to delete this block titled {$a}?';
|
||||
$string['deleteblockwarning'] = '<p>You are about to delete a block that appears elsewhere.</p><p>Original block location: {$a->location}<br />Display on page types: {$a->pagetype}</p><p>Are you sure you want to continue?</p>';
|
||||
$string['hideblock'] = 'Hide {$a} block';
|
||||
$string['hidedockpanel'] = 'Hide the dock panel';
|
||||
$string['hidepanel'] = 'Hide panel';
|
||||
$string['moveblock'] = 'Move {$a} block';
|
||||
$string['moveblockhere'] = 'Move block here';
|
||||
$string['movingthisblockcancel'] = 'Moving this block ({$a})';
|
||||
$string['onthispage'] = 'On this page';
|
||||
$string['pagetypes'] = 'Page types';
|
||||
$string['pagetypewarning'] = 'The previously specified page type is no longer selectable. Please choose the most appropriate page type below.';
|
||||
$string['region'] = 'Region';
|
||||
$string['showblock'] = 'Show {$a} block';
|
||||
$string['showoncontextandsubs'] = 'Display on \'{$a}\' and any pages within it';
|
||||
$string['showoncontextonly'] = 'Display on \'{$a}\' only';
|
||||
$string['showonentiresite'] = 'Display throughout the entire site';
|
||||
|
||||
@@ -53,9 +53,9 @@ $string['completionexpected_help']='This setting specifies the date when the act
|
||||
$string['completionicons'] = 'Completion tick boxes';
|
||||
$string['completionicons_help'] = 'A tick next an activity name may be used to indicate when the activity is complete.
|
||||
|
||||
If a dotted tick is shown, you can click it to tick the box when you think you have completed the activity. (Clicking it again removes the tick if you change your mind.) The tick is optional and is simply a way of tracking your progress through the course.
|
||||
If a box with a dotted border is shown, a tick will appear automatically when you have completed the activity according to conditions set by the teacher.
|
||||
|
||||
If a blank tick box is shown, a tick will appear automatically when you have completed the activity according to conditions set by the teacher.';
|
||||
If a box with a solid border is shown, you can click it to tick the box when you think you have completed the activity. (Clicking it again removes the tick if you change your mind.) The tick is optional and is simply a way of tracking your progress through the course.';
|
||||
$string['completion_manual'] = 'Students can manually mark the activity as completed';
|
||||
$string['completion_none'] = 'Do not indicate activity completion';
|
||||
$string['completion-title-manual-n'] = 'Mark as complete: {$a}';
|
||||
@@ -135,9 +135,10 @@ $string['markcomplete']='Mark complete';
|
||||
$string['markedcompleteby']='Marked complete by {$a}';
|
||||
$string['markingyourselfcomplete']='Marking yourself complete';
|
||||
$string['moredetails']='More details';
|
||||
$string['notcompleted'] = 'Not completed';
|
||||
$string['nocriteriaset']='No completion criteria set for this course';
|
||||
$string['notcompleted'] = 'Not completed';
|
||||
$string['notenroled']='You are not enrolled in this course';
|
||||
$string['nottracked']='You are currently not being tracked by completion in this course';
|
||||
$string['notyetstarted']='Not yet started';
|
||||
$string['overallcriteriaaggregation']='Overall criteria type aggregation';
|
||||
$string['pending']='Pending';
|
||||
|
||||
@@ -157,7 +157,7 @@ $string['LS'] = 'Lesotho';
|
||||
$string['LT'] = 'Lithuania';
|
||||
$string['LU'] = 'Luxembourg';
|
||||
$string['LV'] = 'Latvia';
|
||||
$string['LY'] = 'Libyan Arab Jamahiriya';
|
||||
$string['LY'] = 'State of Libya';
|
||||
$string['MA'] = 'Morocco';
|
||||
$string['MC'] = 'Monaco';
|
||||
$string['MD'] = 'Moldova, Republic Of';
|
||||
|
||||
+1
-1
@@ -460,7 +460,7 @@ $string['socksnotsupported'] = 'SOCKS5 proxy is not supported in PHP4';
|
||||
$string['spellcheckernotconf'] = 'Spellchecker not configured';
|
||||
$string['sslonlyaccess'] = 'For security reasons only https connections are allowed, sorry.';
|
||||
$string['statscatchupmode'] = 'Statistics is currently in catchup mode. So far {$a->daysdone} day(s) have been processed and {$a->dayspending} are pending. Check back soon!';
|
||||
$string['statsdisable'] = 'Stats is not enabled';
|
||||
$string['statsdisable'] = 'Statistics are not enabled.';
|
||||
$string['statsnodata'] = 'There is no available data for that combination of course and time period';
|
||||
$string['storedfilecannotcreatefiledirs'] = 'Can not create local file pool directories, please verify permissions in dataroot.';
|
||||
$string['storedfilecannotread'] = 'Can not read file, either file does not exist or there are permission problems';
|
||||
|
||||
+13
-11
@@ -313,7 +313,7 @@ $string['coursehelpformat'] = 'The course main page will be displayed in this fo
|
||||
$string['coursehelphiddensections'] = 'How the hidden sections in the course are displayed to students.';
|
||||
$string['coursehelpmaximumupload'] = 'Define the largest size of file that can be uploaded in this course, limited by the site-wide setting.';
|
||||
$string['coursehelpnewsitemsnumber'] = 'Number of recent items appearing on the course home page, in a news box down the right-hand side (0 means the news box won\'t appear).';
|
||||
$string['coursehelpnumberweeks'] = 'Number of weeks/topics displayed on the course main page.';
|
||||
$string['coursehelpnumberweeks'] = 'Number of sections in the course (applies to certain course formats only).';
|
||||
$string['coursehelpshowgrades'] = 'Enable the display of the gradebook. It does not prevent grades from being displayed within the individual activities.';
|
||||
$string['coursehidden'] = 'This course is currently unavailable to students';
|
||||
$string['courseinfo'] = 'Course info';
|
||||
@@ -464,7 +464,7 @@ $string['displayingrecords'] = 'Displaying {$a} records';
|
||||
$string['displayingusers'] = 'Displaying users {$a->start} to {$a->end}';
|
||||
$string['displayonpage'] = 'Display on page';
|
||||
$string['dndenabled'] = 'Drag and drop available';
|
||||
$string['dndenabled_help'] = 'You can drag one or more files from your desktop and drop them onto the box below to upload them.<br />Note: this may not work with other web browsers';
|
||||
$string['dndenabled_help'] = 'You can drag one or more files from your desktop and drop them onto the box below to upload them. Note: This feature does not work in all web browsers.';
|
||||
$string['dndenabled_insentence'] = 'drag and drop available';
|
||||
$string['dndenabled_inbox'] = 'You can drag and drop files here to add them.';
|
||||
$string['dndnotsupported'] = 'Drag and drop upload not supported';
|
||||
@@ -736,8 +736,8 @@ $string['from'] = 'From';
|
||||
$string['frontpagecategorycombo'] = 'Combo list';
|
||||
$string['frontpagecategorynames'] = 'List of categories';
|
||||
$string['frontpagecourselist'] = 'List of courses';
|
||||
$string['frontpagedescription'] = 'Front page description';
|
||||
$string['frontpagedescriptionhelp'] = 'This description of the site will be displayed on the front page.';
|
||||
$string['frontpagedescription'] = 'Front page summary';
|
||||
$string['frontpagedescriptionhelp'] = 'This summary can be displayed on the front page using the course/site summary block or by including a topic section on the front page.';
|
||||
$string['frontpageformat'] = 'Front page format';
|
||||
$string['frontpageformatloggedin'] = 'Front page format when logged in';
|
||||
$string['frontpagenews'] = 'News items';
|
||||
@@ -1014,8 +1014,8 @@ $string['maximumchars'] = 'Maximum of {$a} characters';
|
||||
$string['maximumshort'] = 'Max';
|
||||
$string['maximumupload'] = 'Maximum upload size';
|
||||
$string['maximumupload_help'] = 'This setting determines the largest size of file that can be uploaded to the course, limited by the site-wide setting set by an administrator. Activity modules also include a maximum upload size setting for further restricting the file size.';
|
||||
$string['maxnumberweeks'] = 'Maximum for number of weeks/topics';
|
||||
$string['maxnumberweeks_desc'] = 'This controls the maximum options that appears in the "Number of weeks/topics" setting for courses.';
|
||||
$string['maxnumberweeks'] = 'Maximum number of sections';
|
||||
$string['maxnumberweeks_desc'] = 'The maximum value in the number of sections dropdown menu (applies to certain course formats only).';
|
||||
$string['maxsize'] = 'Max size: {$a}';
|
||||
$string['maxfilesize'] = 'Maximum size for new files: {$a}';
|
||||
$string['maxnumcoursesincombo'] = 'Browse <a href="{$a->link}">{$a->numberofcourses} courses</a>.';
|
||||
@@ -1241,7 +1241,7 @@ $string['novalidcourses'] = 'No valid courses to be shown';
|
||||
$string['now'] = 'now';
|
||||
$string['numattempts'] = '{$a} failed login attempt(s)';
|
||||
$string['numberofcourses'] = 'Number of courses';
|
||||
$string['numberweeks'] = 'Number of weeks/topics';
|
||||
$string['numberweeks'] = 'Number of sections';
|
||||
$string['numdays'] = '{$a} days';
|
||||
$string['numhours'] = '{$a} hours';
|
||||
$string['numletters'] = '{$a} letters';
|
||||
@@ -1265,7 +1265,7 @@ $string['other'] = 'Other';
|
||||
$string['outline'] = 'Outline';
|
||||
$string['outlinereport'] = 'Outline report';
|
||||
$string['page'] = 'Page';
|
||||
$string['pageheaderconfigablock'] = 'Configuring a block in %fullname%';
|
||||
$string['pageheaderconfigablock'] = 'Configuring a block in {$a->fullname}';
|
||||
$string['pagepath'] = 'Page path';
|
||||
$string['pageshouldredirect'] = 'This page should automatically redirect. If nothing is happening please use the continue link below.';
|
||||
$string['parentcategory'] = 'Parent category';
|
||||
@@ -1517,7 +1517,9 @@ $string['selectdefault'] = 'Select default';
|
||||
$string['selectedfile'] = 'Selected file';
|
||||
$string['selectednowmove'] = '{$a} files selected for moving. Now go into the destination folder and press \'Move files to here\'';
|
||||
$string['selectfiles'] = 'Select files';
|
||||
$string['selectmoduletoviewhelp'] = 'Select a module to view its help.';
|
||||
$string['selectmoduletoviewhelp'] = 'Select an activity or resource to view its help.
|
||||
|
||||
Double-click on an activity or resource name to quickly add it.';
|
||||
$string['selectnos'] = 'Select all \'no\'';
|
||||
$string['selectperiod'] = 'Select period';
|
||||
$string['senddetails'] = 'Send my details via email';
|
||||
@@ -1545,7 +1547,7 @@ $string['showblockcourse'] = 'Show list of courses containing block';
|
||||
$string['showcomments'] = 'Show/hide comments';
|
||||
$string['showcommentsnonjs'] = 'Show comments';
|
||||
$string['showdescription'] = 'Display description on course page';
|
||||
$string['showdescription_help'] = 'If enabled, the introduction / description above will be displayed on the course page just below the link to the activity / resource.';
|
||||
$string['showdescription_help'] = 'If enabled, the description above will be displayed on the course page just below the link to the activity or resource.';
|
||||
$string['showgrades'] = 'Show gradebook to students';
|
||||
$string['showgrades_help'] = 'Many activities in the course allow grades to be set. This setting determines whether a student can view a list of all their grades for the course via a grades link in the course administration block.';
|
||||
$string['showlistofcourses'] = 'Show list of courses';
|
||||
@@ -1769,7 +1771,7 @@ $string['userpic'] = 'User picture';
|
||||
$string['users'] = 'Users';
|
||||
$string['userselectorautoselectunique'] = 'If only one user matches the search, select them automatically';
|
||||
$string['userselectorpreserveselected'] = 'Keep selected users, even if they no longer match the search';
|
||||
$string['userselectorsearchanywhere'] = 'Match the search text anywhere in the user\'s name';
|
||||
$string['userselectorsearchanywhere'] = 'Match the search text anywhere in the displayed fields';
|
||||
$string['usersnew'] = 'New users';
|
||||
$string['usersnoaccesssince'] = 'Inactive for more than';
|
||||
$string['userswithfiles'] = 'Users with files';
|
||||
|
||||
+2
-2
@@ -2,9 +2,9 @@
|
||||
// my.php - created with Moodle 1.7 beta + (2006101003)
|
||||
|
||||
|
||||
$string['mymoodle'] = 'My Moodle';
|
||||
$string['mymoodle'] = 'My home';
|
||||
$string['nocourses'] = 'No course information to show.';
|
||||
$string['noguest'] = 'The \'My Moodle\' page is not available to guest users';
|
||||
$string['noguest'] = 'The My home page is not available to guest users';
|
||||
$string['pinblocks'] = 'Configure pinned blocks for my moodle';
|
||||
$string['pinblocksexplan'] = 'Any block settings you configure here will be visible (and non-editable) for any user of moodle on their \'My Moodle\' overview page.';
|
||||
$string['defaultpage'] = 'Default My Moodle page';
|
||||
|
||||
+2
-3
@@ -42,8 +42,7 @@ $string['numupdatable'] = 'Updates available: {$a}';
|
||||
$string['otherplugin'] = '{$a->component}';
|
||||
$string['otherpluginversion'] = '{$a->component} ({$a->version})';
|
||||
$string['showall'] = 'Reload and show all plugins';
|
||||
$string['pluginchecknotice'] = 'This page displays plugins that may require your attention during the upgrade. Highlighted items include new plugins that are about to be installed, updated plugins that are about to be upgraded and any missing plugins. Contributed plugins are also highlighted.
|
||||
It is recommended that you check whether there are more recent versions of contributed plugins available and update their source code before continuing with this Moodle upgrade.';
|
||||
$string['pluginchecknotice'] = 'This page displays plugins that may require your attention during the upgrade. Highlighted items include new plugins that are about to be installed, updated plugins that are about to be upgraded and any missing plugins. Add-ons are also highlighted. It is recommended that you check whether there are more recent versions of add-ons available and update their source code before continuing with this Moodle upgrade.';
|
||||
$string['plugindisable'] = 'Disable';
|
||||
$string['plugindisabled'] = 'Disabled';
|
||||
$string['pluginenable'] = 'Enable';
|
||||
@@ -56,7 +55,7 @@ $string['somehighlighted'] = 'Number of plugins requiring your attention: {$a}';
|
||||
$string['somehighlightedinfo'] = 'Display the full list of installed plugins';
|
||||
$string['somehighlightedonly'] = 'Display only plugins requiring your attention';
|
||||
$string['source'] = 'Source';
|
||||
$string['sourceext'] = 'Contributed';
|
||||
$string['sourceext'] = 'Add-on';
|
||||
$string['sourcestd'] = 'Standard';
|
||||
$string['status'] = 'Status';
|
||||
$string['status_delete'] = 'To be deleted';
|
||||
|
||||
@@ -90,6 +90,7 @@ affected will continue to work in all existing quizzes until you remove them fro
|
||||
$string['cwrqpfsnoprob'] = 'No question categories in your site are affected by the \'Random questions selecting questions from sub categories\' issue.';
|
||||
$string['defaultfor'] = 'Default for {$a}';
|
||||
$string['defaultinfofor'] = 'The default category for questions shared in context \'{$a}\'.';
|
||||
$string['defaultmarkmustbepositive'] = 'The default mark must be positive.';
|
||||
$string['deletebehaviourareyousure'] = 'Delete behaviour {$a}: are you sure?';
|
||||
$string['deletebehaviourareyousuremessage'] = 'You are about to completely delete the question behaviour {$a}. This will completely delete everything in the database associated with this question behaviour. Are you SURE you want to continue?';
|
||||
$string['deletecoursecategorywithquestions'] = 'There are questions in the question bank associated with this course category. If you proceed, they will be deleted. You may wish to move them first, using the question bank interface.';
|
||||
@@ -183,13 +184,13 @@ $string['invalidcategoryidforparent'] = 'Invalid category id for parent!';
|
||||
$string['invalidcategoryidtomove'] = 'Invalid category id to move!';
|
||||
$string['invalidconfirm'] = 'Confirmation string was incorrect';
|
||||
$string['invalidcontextinhasanyquestions'] = 'Invalid context passed to question_context_has_any_questions.';
|
||||
$string['invalidgrade'] = 'Grades ({$a}) do not match grade options - question skipped.';
|
||||
$string['invalidpenalty'] = 'Invalid penalty';
|
||||
$string['invalidwizardpage'] = 'Incorrect or no wizard page specified!';
|
||||
$string['lastmodifiedby'] = 'Last modified by';
|
||||
$string['linkedfiledoesntexist'] = 'Linked file {$a} doesn\'t exist';
|
||||
$string['makechildof'] = 'Make child of \'{$a}\'';
|
||||
$string['maketoplevelitem'] = 'Move to top level';
|
||||
$string['matcherror'] = 'Grades do not match grade options - question skipped';
|
||||
$string['matchgrades'] = 'Match grades';
|
||||
$string['matchgradeserror'] = 'Error if grade not listed';
|
||||
$string['matchgradesnearest'] = 'Nearest grade if not listed';
|
||||
@@ -416,6 +417,7 @@ $string['technicalinfoquestionsummary'] = 'Question summary: {$a}';
|
||||
$string['technicalinforightsummary'] = 'Right answer summary: {$a}';
|
||||
$string['technicalinfostate'] = 'Question state: {$a}';
|
||||
$string['unknownbehaviour'] = 'Unknown behaviour: {$a}.';
|
||||
$string['unknownorunhandledtype'] = 'Unknown or unhandled question type: {$a}';
|
||||
$string['unknownquestion'] = 'Unknown question: {$a}.';
|
||||
$string['unknownquestioncatregory'] = 'Unknown question category: {$a}.';
|
||||
$string['unknownquestiontype'] = 'Unknown question type: {$a}.';
|
||||
|
||||
@@ -99,7 +99,7 @@ $string['enternewname'] = 'Please enter the new file name';
|
||||
$string['error'] = 'An unknown error occurred!';
|
||||
$string['errornotyourfile'] = 'You cannot pick file which is not added by your';
|
||||
$string['erroruniquename'] = 'Repository instance name should be unique';
|
||||
$string['errorpostmaxsize'] = 'The uploaded file may exceed max_post_size directive in php.ini.';
|
||||
$string['errorpostmaxsize'] = 'The uploaded file may exceed the post_max_size directive in php.ini.';
|
||||
$string['errorwhilecommunicatingwith'] = 'Error while communicating with the repository \'{$a}\'.';
|
||||
$string['errorwhiledownload'] = 'An error occured while downloading the file: {$a}';
|
||||
$string['existingrepository'] = 'This repository already exists';
|
||||
@@ -154,7 +154,7 @@ $string['nofilesattached'] = 'No files attached';
|
||||
$string['nofilesavailable'] = 'No files available';
|
||||
$string['nomorefiles'] = 'No more attachments allowed';
|
||||
$string['nopathselected'] = 'No destination path select yet (double click tree node to select)';
|
||||
$string['nopermissiontoaccess'] = 'No permission to access this repository';
|
||||
$string['nopermissiontoaccess'] = 'No permission to access this repository.';
|
||||
$string['noresult'] = 'No search result';
|
||||
$string['norepositoriesavailable'] = 'Sorry, none of your current repositories can return files in the required format.';
|
||||
$string['norepositoriesexternalavailable'] = 'Sorry, none of your current repositories can return external files.';
|
||||
|
||||
+2
-2
@@ -223,8 +223,8 @@ $string['manageroles'] = 'Manage roles';
|
||||
$string['maybeassignedin'] = 'Context types where this role may be assigned';
|
||||
$string['morethan'] = 'More than {$a}';
|
||||
$string['multipleroles'] = 'Multiple roles';
|
||||
$string['my:manageblocks'] = 'Manage My Moodle page blocks';
|
||||
$string['my:configsyspages'] = 'Configure system templates for My Moodle pages';
|
||||
$string['my:manageblocks'] = 'Manage My home page blocks';
|
||||
$string['my:configsyspages'] = 'Configure system templates for My home pages';
|
||||
$string['neededroles'] = 'Roles with permission';
|
||||
$string['nocapabilitiesincontext'] = 'No capabilities available in this context';
|
||||
$string['noneinthisx'] = 'None in this {$a}';
|
||||
|
||||
+1
-1
@@ -7679,7 +7679,7 @@ class admin_setting_configcolourpicker extends admin_setting {
|
||||
$PAGE->requires->js_init_call('M.util.init_colour_picker', array($this->get_id(), $this->previewconfig));
|
||||
$content = html_writer::start_tag('div', array('class'=>'form-colourpicker defaultsnext'));
|
||||
$content .= html_writer::tag('div', $OUTPUT->pix_icon('i/loading', get_string('loading', 'admin'), 'moodle', array('class'=>'loadingicon')), array('class'=>'admin_colourpicker clearfix'));
|
||||
$content .= html_writer::empty_tag('input', array('type'=>'text','id'=>$this->get_id(), 'name'=>$this->get_full_name(), 'value'=>$this->get_setting(), 'size'=>'12'));
|
||||
$content .= html_writer::empty_tag('input', array('type'=>'text','id'=>$this->get_id(), 'name'=>$this->get_full_name(), 'value'=>$data, 'size'=>'12'));
|
||||
if (!empty($this->previewconfig)) {
|
||||
$content .= html_writer::empty_tag('input', array('type'=>'button','id'=>$this->get_id().'_preview', 'value'=>get_string('preview'), 'class'=>'admin_colourpicker_preview'));
|
||||
}
|
||||
|
||||
+36
-6
@@ -1023,13 +1023,15 @@ class block_manager {
|
||||
if ($this->page->user_can_edit_blocks()) {
|
||||
// Move icon.
|
||||
$controls[] = array('url' => $actionurl . '&bui_moveid=' . $block->instance->id,
|
||||
'icon' => 't/move', 'caption' => get_string('move'), 'class' => 'editing_move');
|
||||
'icon' => 't/move', 'caption' => get_string('moveblock', 'block', $block->title),
|
||||
'class' => 'editing_move');
|
||||
}
|
||||
|
||||
if ($this->page->user_can_edit_blocks() || $block->user_can_edit()) {
|
||||
// Edit config icon - always show - needed for positioning UI.
|
||||
$controls[] = array('url' => $actionurl . '&bui_editid=' . $block->instance->id,
|
||||
'icon' => 't/edit', 'caption' => get_string('configuration'), 'class' => 'editing_edit');
|
||||
'icon' => 't/edit', 'caption' => get_string('configureblock', 'block', $block->title),
|
||||
'class' => 'editing_edit');
|
||||
}
|
||||
|
||||
if ($this->page->user_can_edit_blocks() && $block->user_can_edit() && $block->user_can_addto($this->page)) {
|
||||
@@ -1038,7 +1040,8 @@ class block_manager {
|
||||
|| $block->instance->parentcontextid != SITEID) {
|
||||
// Delete icon.
|
||||
$controls[] = array('url' => $actionurl . '&bui_deleteid=' . $block->instance->id,
|
||||
'icon' => 't/delete', 'caption' => get_string('delete'), 'class' => 'editing_delete');
|
||||
'icon' => 't/delete', 'caption' => get_string('deleteblock', 'block', $block->title),
|
||||
'class' => 'editing_delete');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,10 +1049,12 @@ class block_manager {
|
||||
// Show/hide icon.
|
||||
if ($block->instance->visible) {
|
||||
$controls[] = array('url' => $actionurl . '&bui_hideid=' . $block->instance->id,
|
||||
'icon' => 't/hide', 'caption' => get_string('hide'), 'class' => 'editing_hide');
|
||||
'icon' => 't/hide', 'caption' => get_string('hideblock', 'block', $block->title),
|
||||
'class' => 'editing_hide');
|
||||
} else {
|
||||
$controls[] = array('url' => $actionurl . '&bui_showid=' . $block->instance->id,
|
||||
'icon' => 't/show', 'caption' => get_string('show'), 'class' => 'editing_show');
|
||||
'icon' => 't/show', 'caption' => get_string('showblock', 'block', $block->title),
|
||||
'class' => 'editing_show');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1063,7 +1068,8 @@ class block_manager {
|
||||
|
||||
$controls[] = array('url' => $CFG->wwwroot . '/' . $CFG->admin .
|
||||
'/roles/assign.php?contextid=' . $block->context->id . '&returnurl=' . urlencode($return),
|
||||
'icon' => 'i/roles', 'caption' => get_string('assignroles', 'role'), 'class' => 'editing_roles');
|
||||
'icon' => 'i/roles', 'caption' => get_string('assignrolesinblock', 'block', $block->title),
|
||||
'class' => 'editing_roles');
|
||||
}
|
||||
|
||||
return $controls;
|
||||
@@ -1156,6 +1162,27 @@ class block_manager {
|
||||
$strdeletecheck = get_string('deletecheck', 'block', $blocktitle);
|
||||
$message = get_string('deleteblockcheck', 'block', $blocktitle);
|
||||
|
||||
// If the block is being shown in sub contexts display a warning.
|
||||
if ($block->instance->showinsubcontexts == 1) {
|
||||
$parentcontext = context::instance_by_id($block->instance->parentcontextid);
|
||||
$systemcontext = context_system::instance();
|
||||
$messagestring = new stdClass();
|
||||
$messagestring->location = $parentcontext->get_context_name();
|
||||
|
||||
// Checking for blocks that may have visibility on the front page and pages added on that.
|
||||
if ($parentcontext->id != $systemcontext->id && is_inside_frontpage($parentcontext)) {
|
||||
$messagestring->pagetype = get_string('showonfrontpageandsubs', 'block');
|
||||
} else {
|
||||
$pagetypes = generate_page_type_patterns($this->page->pagetype, $parentcontext);
|
||||
$messagestring->pagetype = $block->instance->pagetypepattern;
|
||||
if (isset($pagetypes[$block->instance->pagetypepattern])) {
|
||||
$messagestring->pagetype = $pagetypes[$block->instance->pagetypepattern];
|
||||
}
|
||||
}
|
||||
|
||||
$message = get_string('deleteblockwarning', 'block', $messagestring);
|
||||
}
|
||||
|
||||
$PAGE->navbar->add($strdeletecheck);
|
||||
$PAGE->set_title($blocktitle . ': ' . $strdeletecheck);
|
||||
$PAGE->set_heading($site->fullname);
|
||||
@@ -1271,7 +1298,10 @@ class block_manager {
|
||||
} else if ($data = $mform->get_data()) {
|
||||
$bi = new stdClass;
|
||||
$bi->id = $block->instance->id;
|
||||
|
||||
// This may get overwritten by the special case handling below.
|
||||
$bi->pagetypepattern = $data->bui_pagetypepattern;
|
||||
$bi->showinsubcontexts = (bool) $data->bui_contexts;
|
||||
if (empty($data->bui_subpagepattern) || $data->bui_subpagepattern == '%@NULL@%') {
|
||||
$bi->subpagepattern = null;
|
||||
} else {
|
||||
|
||||
@@ -1021,7 +1021,7 @@ class completion_info {
|
||||
* @return bool
|
||||
*/
|
||||
public function is_tracked_user($userid) {
|
||||
return is_enrolled(context_course::instance($this->course->id), $userid, '', true);
|
||||
return is_enrolled(context_course::instance($this->course->id), $userid, 'moodle/course:isincompletionreports', true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1038,7 +1038,7 @@ class completion_info {
|
||||
global $DB;
|
||||
|
||||
list($enrolledsql, $enrolledparams) = get_enrolled_sql(
|
||||
context_course::instance($this->course->id), '', $groupid, true);
|
||||
context_course::instance($this->course->id), 'moodle/course:isincompletionreports', $groupid, true);
|
||||
$sql = 'SELECT COUNT(eu.id) FROM (' . $enrolledsql . ') eu JOIN {user} u ON u.id = eu.id';
|
||||
if ($where) {
|
||||
$sql .= " WHERE $where";
|
||||
|
||||
+7
-1
@@ -1745,7 +1745,13 @@ class css_rule {
|
||||
$css = $this->out();
|
||||
$errors = array();
|
||||
foreach ($this->styles as $style) {
|
||||
if ($style->has_error()) {
|
||||
if (is_array($style)) {
|
||||
foreach ($style as $s) {
|
||||
if ($style instanceof css_style && $style->has_error()) {
|
||||
$errors[] = " * ".$style->get_last_error();
|
||||
}
|
||||
}
|
||||
} else if ($style instanceof css_style && $style->has_error()) {
|
||||
$errors[] = " * ".$style->get_last_error();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ $logs = array(
|
||||
array('module'=>'course', 'action'=>'view', 'mtable'=>'course', 'field'=>'fullname'),
|
||||
array('module'=>'course', 'action'=>'view section', 'mtable'=>'course_sections', 'field'=>'name'),
|
||||
array('module'=>'course', 'action'=>'update', 'mtable'=>'course', 'field'=>'fullname'),
|
||||
array('module'=>'course', 'action'=>'hide', 'mtable'=>'course', 'field'=>'fullname'),
|
||||
array('module'=>'course', 'action'=>'show', 'mtable'=>'course', 'field'=>'fullname'),
|
||||
array('module'=>'course', 'action'=>'move', 'mtable'=>'course', 'field'=>'fullname'),
|
||||
array('module'=>'course', 'action'=>'enrol', 'mtable'=>'course', 'field'=>'fullname'), // there should be some way to store user id of the enrolled user!
|
||||
array('module'=>'course', 'action'=>'unenrol', 'mtable'=>'course', 'field'=>'fullname'), // there should be some way to store user id of the enrolled user!
|
||||
array('module'=>'course', 'action'=>'report log', 'mtable'=>'course', 'field'=>'fullname'),
|
||||
@@ -47,6 +50,11 @@ $logs = array(
|
||||
array('module'=>'course', 'action'=>'report outline', 'mtable'=>'course', 'field'=>'fullname'),
|
||||
array('module'=>'course', 'action'=>'report participation', 'mtable'=>'course', 'field'=>'fullname'),
|
||||
array('module'=>'course', 'action'=>'report stats', 'mtable'=>'course', 'field'=>'fullname'),
|
||||
array('module'=>'category', 'action'=>'add', 'mtable'=>'course_categories', 'field'=>'name'),
|
||||
array('module'=>'category', 'action'=>'hide', 'mtable'=>'course_categories', 'field'=>'name'),
|
||||
array('module'=>'category', 'action'=>'move', 'mtable'=>'course_categories', 'field'=>'name'),
|
||||
array('module'=>'category', 'action'=>'show', 'mtable'=>'course_categories', 'field'=>'name'),
|
||||
array('module'=>'category', 'action'=>'update', 'mtable'=>'course_categories', 'field'=>'name'),
|
||||
array('module'=>'message', 'action'=>'write', 'mtable'=>'user', 'field'=>$DB->sql_concat('firstname', "' '" , 'lastname')),
|
||||
array('module'=>'message', 'action'=>'read', 'mtable'=>'user', 'field'=>$DB->sql_concat('firstname', "' '" , 'lastname')),
|
||||
array('module'=>'message', 'action'=>'add contact', 'mtable'=>'user', 'field'=>$DB->sql_concat('firstname', "' '" , 'lastname')),
|
||||
|
||||
@@ -992,5 +992,139 @@ function xmldb_main_upgrade($oldversion) {
|
||||
upgrade_main_savepoint(true, 2012062503.07);
|
||||
}
|
||||
|
||||
if ($oldversion < 2012062504.07) {
|
||||
// Fixing possible wrong MIME types for SMART Notebook files.
|
||||
$extensions = array('%.gallery', '%.galleryitem', '%.gallerycollection', '%.nbk', '%.notebook', '%.xbk');
|
||||
$select = $DB->sql_like('filename', '?', false);
|
||||
foreach ($extensions as $extension) {
|
||||
$DB->set_field_select(
|
||||
'files',
|
||||
'mimetype',
|
||||
'application/x-smarttech-notebook',
|
||||
$select,
|
||||
array($extension)
|
||||
);
|
||||
}
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2012062504.07);
|
||||
}
|
||||
|
||||
if ($oldversion < 2012062504.08) {
|
||||
// This upgrade step is fixing broken sequence data in the course_sections table (MDL-37939).
|
||||
// It may take a long time to run on large sites.
|
||||
// Retrieve the list of course_sections as a recordset to save memory.
|
||||
$coursesections = $DB->get_recordset('course_sections', null, 'course, id', 'id, course, sequence');
|
||||
foreach ($coursesections as $coursesection) {
|
||||
// Retrieve all of the actual modules in this course and section combination to reduce DB calls
|
||||
$actualsectionmodules = $DB->get_records('course_modules',
|
||||
array('course' => $coursesection->course, 'section' => $coursesection->id), '', 'id, section');
|
||||
|
||||
// Break out the current sequence so that we can compare it
|
||||
$currentsequence = explode(',', $coursesection->sequence);
|
||||
$newsequence = array();
|
||||
|
||||
// Check each of the modules in the current sequence
|
||||
foreach ($currentsequence as $module) {
|
||||
if (isset($actualsectionmodules[$module])) {
|
||||
$newsequence[] = $module;
|
||||
// We unset the actualsectionmodules so that we don't get duplicates and that we can add orphaned
|
||||
// modules later
|
||||
unset($actualsectionmodules[$module]);
|
||||
}
|
||||
}
|
||||
|
||||
// Append any modules which have somehow been orphaned
|
||||
foreach ($actualsectionmodules as $module) {
|
||||
$newsequence[] = $module->id;
|
||||
}
|
||||
|
||||
// Piece it all back together
|
||||
$sequence = implode(',', $newsequence);
|
||||
|
||||
// Only update if there have been changes
|
||||
if ($sequence !== $coursesection->sequence) {
|
||||
$coursesection->sequence = $sequence;
|
||||
$DB->update_record('course_sections', $coursesection);
|
||||
|
||||
// And clear the sectioncache and modinfo cache - they'll be regenerated on next use
|
||||
$course = new stdClass();
|
||||
$course->id = $coursesection->course;
|
||||
$course->sectioncache = null;
|
||||
$course->modinfo = null;
|
||||
$DB->update_record('course', $course);
|
||||
}
|
||||
}
|
||||
$coursesections->close();
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2012062504.08);
|
||||
}
|
||||
|
||||
// This is checking to see if the site has been running a specific version with a bug in it
|
||||
// because this upgrade step is slow and is only needed if the site has been running with the previous patch installed.
|
||||
// Note the conditions order in not the natual one for intervals, but that way the CI servers will be happy. Ugly swap.
|
||||
if ($oldversion < 2012062504.13 && $oldversion >= 2012062504.08) {
|
||||
// Retrieve the list of course_sections as a recordset to save memory.
|
||||
// This is to fix a regression caused by MDL-37939.
|
||||
// In this case the upgrade step is fixing records where:
|
||||
// The data in course_sections.sequence contains the correct module id
|
||||
// The section field for on the course modules table may have been updated to point to the incorrect id.
|
||||
|
||||
// This query is looking for sections where the sequence is not in sync with the course_modules table.
|
||||
// The syntax for the like query is looking for a value in a comma separated list.
|
||||
// It adds a comma to either site of the list and then searches for LIKE '%,id,%'.
|
||||
$sequenceconcat = $DB->sql_concat("','", 's.sequence', "','");
|
||||
$moduleconcat = $DB->sql_concat("'%,'", 'cm.id', "',%'");
|
||||
$sql = 'SELECT s2.id, s2.course, s2.sequence
|
||||
FROM {course_sections} s2
|
||||
JOIN(
|
||||
SELECT DISTINCT s.id
|
||||
FROM
|
||||
{course_modules} cm
|
||||
JOIN {course_sections} s
|
||||
ON
|
||||
cm.course = s.course
|
||||
WHERE cm.section != s.id AND ' . $sequenceconcat . ' LIKE ' . $moduleconcat . '
|
||||
) d
|
||||
ON s2.id = d.id';
|
||||
$coursesections = $DB->get_recordset_sql($sql);
|
||||
|
||||
foreach ($coursesections as $coursesection) {
|
||||
// Retrieve all of the actual modules in this course and section combination to reduce DB calls.
|
||||
$actualsectionmodules = $DB->get_records('course_modules',
|
||||
array('course' => $coursesection->course, 'section' => $coursesection->id), '', 'id, section');
|
||||
|
||||
// Break out the current sequence so that we can compare it.
|
||||
$currentsequence = explode(',', $coursesection->sequence);
|
||||
$orphanlist = array();
|
||||
|
||||
// Check each of the modules in the current sequence.
|
||||
foreach ($currentsequence as $cmid) {
|
||||
if (!empty($cmid) && !isset($actualsectionmodules[$cmid])) {
|
||||
$orphanlist[] = $cmid;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($orphanlist)) {
|
||||
list($sql, $params) = $DB->get_in_or_equal($orphanlist, SQL_PARAMS_NAMED);
|
||||
$sql = "id $sql";
|
||||
|
||||
$DB->set_field_select('course_modules', 'section', $coursesection->id, $sql, $params);
|
||||
|
||||
// And clear the sectioncache and modinfo cache - they'll be regenerated on next use.
|
||||
$course = new stdClass();
|
||||
$course->id = $coursesection->course;
|
||||
$course->sectioncache = null;
|
||||
$course->modinfo = null;
|
||||
$DB->update_record('course', $course);
|
||||
}
|
||||
}
|
||||
$coursesections->close();
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2012062504.13);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ class sqlsrv_native_moodle_database extends moodle_database {
|
||||
protected $last_error_reporting; // To handle SQL*Server-Native driver default verbosity
|
||||
protected $temptables; // Control existing temptables (sqlsrv_moodle_temptables object)
|
||||
protected $collation; // current DB collation cache
|
||||
/** @var array list of open recordsets */
|
||||
protected $recordsets = array();
|
||||
|
||||
/**
|
||||
* Constructor - instantiates the database, specifying if it's external (connect to other systems) or no (Moodle DB)
|
||||
@@ -789,7 +791,20 @@ class sqlsrv_native_moodle_database extends moodle_database {
|
||||
* @return sqlsrv_native_moodle_recordset
|
||||
*/
|
||||
protected function create_recordset($result) {
|
||||
return new sqlsrv_native_moodle_recordset($result);
|
||||
$rs = new sqlsrv_native_moodle_recordset($result, $this);
|
||||
$this->recordsets[] = $rs;
|
||||
return $rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use outside of recordset class.
|
||||
* @internal
|
||||
* @param sqlsrv_native_moodle_recordset $rs
|
||||
*/
|
||||
public function recordset_closed(sqlsrv_native_moodle_recordset $rs) {
|
||||
if ($key = array_search($rs, $this->recordsets, true)) {
|
||||
unset($this->recordsets[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1363,6 +1378,12 @@ class sqlsrv_native_moodle_database extends moodle_database {
|
||||
* @return void
|
||||
*/
|
||||
protected function begin_transaction() {
|
||||
// Recordsets do not work well with transactions in SQL Server,
|
||||
// let's prefetch the recordsets to memory to work around these problems.
|
||||
foreach ($this->recordsets as $rs) {
|
||||
$rs->transaction_starts();
|
||||
}
|
||||
|
||||
$this->query_start('native sqlsrv_begin_transaction', NULL, SQL_QUERY_AUX);
|
||||
$result = sqlsrv_begin_transaction($this->sqlsrv);
|
||||
$this->query_end($result);
|
||||
|
||||
@@ -31,9 +31,49 @@ class sqlsrv_native_moodle_recordset extends moodle_recordset {
|
||||
protected $rsrc;
|
||||
protected $current;
|
||||
|
||||
public function __construct($rsrc) {
|
||||
$this->rsrc = $rsrc;
|
||||
/** @var array recordset buffer */
|
||||
protected $buffer = null;
|
||||
|
||||
/** @var sqlsrv_native_moodle_database */
|
||||
protected $db;
|
||||
|
||||
public function __construct($rsrc, sqlsrv_native_moodle_database $db) {
|
||||
$this->rsrc = $rsrc;
|
||||
$this->current = $this->fetch_next();
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inform existing open recordsets that transaction
|
||||
* is starting, this works around MARS problem described
|
||||
* in MDL-37734.
|
||||
*/
|
||||
public function transaction_starts() {
|
||||
if ($this->buffer !== null) {
|
||||
$this->unregister();
|
||||
return;
|
||||
}
|
||||
if (!$this->rsrc) {
|
||||
$this->unregister();
|
||||
return;
|
||||
}
|
||||
// This might eat memory pretty quickly...
|
||||
raise_memory_limit('2G');
|
||||
$this->buffer = array();
|
||||
|
||||
while($next = $this->fetch_next()) {
|
||||
$this->buffer[] = $next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister recordset from the global list of open recordsets.
|
||||
*/
|
||||
private function unregister() {
|
||||
if ($this->db) {
|
||||
$this->db->recordset_closed($this);
|
||||
$this->db = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
@@ -41,10 +81,18 @@ class sqlsrv_native_moodle_recordset extends moodle_recordset {
|
||||
}
|
||||
|
||||
private function fetch_next() {
|
||||
if ($row = sqlsrv_fetch_array($this->rsrc, SQLSRV_FETCH_ASSOC)) {
|
||||
unset($row['sqlsrvrownumber']);
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
if (!$this->rsrc) {
|
||||
return false;
|
||||
}
|
||||
if (!$row = sqlsrv_fetch_array($this->rsrc, SQLSRV_FETCH_ASSOC)) {
|
||||
sqlsrv_free_stmt($this->rsrc);
|
||||
$this->rsrc = null;
|
||||
$this->unregister();
|
||||
return false;
|
||||
}
|
||||
|
||||
unset($row['sqlsrvrownumber']);
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
return $row;
|
||||
}
|
||||
|
||||
@@ -62,7 +110,11 @@ class sqlsrv_native_moodle_recordset extends moodle_recordset {
|
||||
}
|
||||
|
||||
public function next() {
|
||||
$this->current = $this->fetch_next();
|
||||
if ($this->buffer === null) {
|
||||
$this->current = $this->fetch_next();
|
||||
} else {
|
||||
$this->current = array_shift($this->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public function valid() {
|
||||
@@ -75,5 +127,7 @@ class sqlsrv_native_moodle_recordset extends moodle_recordset {
|
||||
$this->rsrc = null;
|
||||
}
|
||||
$this->current = null;
|
||||
$this->buffer = null;
|
||||
$this->unregister();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1797,7 +1797,7 @@ class dml_testcase extends database_driver_testcase {
|
||||
$this->assertSame(false, $DB->get_field($tablename, 'course', array('course' => 11), IGNORE_MISSING));
|
||||
try {
|
||||
$DB->get_field($tablename, 'course', array('course' => 4), MUST_EXIST);
|
||||
$this->assertFail('Exception expected due to missing record');
|
||||
$this->fail('Exception expected due to missing record');
|
||||
} catch (dml_exception $ex) {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
@@ -1952,7 +1952,7 @@ class dml_testcase extends database_driver_testcase {
|
||||
// custom sequence - missing id error
|
||||
try {
|
||||
$DB->insert_record_raw($tablename, array('course' => 3, 'onechar' => 'bb'), true, false, true);
|
||||
$this->assertFail('Exception expected due to missing record');
|
||||
$this->fail('Exception expected due to missing record');
|
||||
} catch (coding_exception $ex) {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
@@ -1960,7 +1960,7 @@ class dml_testcase extends database_driver_testcase {
|
||||
// wrong column error
|
||||
try {
|
||||
$DB->insert_record_raw($tablename, array('xxxxx' => 3, 'onechar' => 'bb'));
|
||||
$this->assertFail('Exception expected due to invalid column');
|
||||
$this->fail('Exception expected due to invalid column');
|
||||
} catch (dml_exception $ex) {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
@@ -4314,6 +4314,35 @@ class dml_testcase extends database_driver_testcase {
|
||||
}
|
||||
$rs1->close();
|
||||
$this->assertEquals(3, $i);
|
||||
|
||||
// Test nested recordsets isolation without transaction.
|
||||
$DB->delete_records($tablename);
|
||||
$DB->insert_record($tablename, array('course'=>1));
|
||||
$DB->insert_record($tablename, array('course'=>2));
|
||||
$DB->insert_record($tablename, array('course'=>3));
|
||||
|
||||
$DB->delete_records($tablename2);
|
||||
$DB->insert_record($tablename2, array('course'=>5));
|
||||
$DB->insert_record($tablename2, array('course'=>6));
|
||||
$DB->insert_record($tablename2, array('course'=>7));
|
||||
$DB->insert_record($tablename2, array('course'=>8));
|
||||
|
||||
$rs1 = $DB->get_recordset($tablename);
|
||||
$i = 0;
|
||||
foreach ($rs1 as $record1) {
|
||||
$i++;
|
||||
$rs2 = $DB->get_recordset($tablename2);
|
||||
$j = 0;
|
||||
foreach ($rs2 as $record2) {
|
||||
$DB->set_field($tablename, 'course', $record1->course+1, array('id'=>$record1->id));
|
||||
$DB->set_field($tablename2, 'course', $record2->course+1, array('id'=>$record2->id));
|
||||
$j++;
|
||||
}
|
||||
$rs2->close();
|
||||
$this->assertEquals(4, $j);
|
||||
}
|
||||
$rs1->close();
|
||||
$this->assertEquals(3, $i);
|
||||
}
|
||||
|
||||
function test_transactions_forbidden() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user