Compare commits
214 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f285d9203f | |||
| 6766dabe82 | |||
| d56e2cd3eb | |||
| 9b7f4e9e8e | |||
| 7b3608625e | |||
| 0a76cd2ca1 | |||
| 36706f5b98 | |||
| ff2b56b538 | |||
| b6a8a31088 | |||
| 3fe3805d79 | |||
| 3ce9798faf | |||
| 238b87a2fb | |||
| 7ea1dd1580 | |||
| 1a13098682 | |||
| ed961702c6 | |||
| 17da61847f | |||
| 6805a9e11b | |||
| fe785db8db | |||
| b6500c619a | |||
| 62fbaeecbb | |||
| 80e10c2278 | |||
| dcbcc94a51 | |||
| 0ce3aa0562 | |||
| 47dc780e98 | |||
| e52a7a4fe0 | |||
| 5e1a2d2a42 | |||
| 20c506c970 | |||
| c8e6ceb4c4 | |||
| 6098e65822 | |||
| fb1fcfb4f3 | |||
| 39e019735f | |||
| b95cb5e0e5 | |||
| 44b6b2318f | |||
| c89650cd42 | |||
| 3d062e2cdf | |||
| f9465c0974 | |||
| ced9b94a04 | |||
| 55bf30c23c | |||
| c91507f8d5 | |||
| c8d7affbb5 | |||
| 188892a7a8 | |||
| 12ec6228a5 | |||
| b7265c5a4f | |||
| bdff8c070f | |||
| 3b8f30b128 | |||
| f76f70f1b3 | |||
| 7b14fef527 | |||
| cf350bc4f4 | |||
| 99105dabb5 | |||
| 9634c940d4 | |||
| 330f27b3fd | |||
| 48f3c5744d | |||
| 8b913c588a | |||
| 3bf7fdb1e8 | |||
| 6a85db36f5 | |||
| ac4c7623fe | |||
| d0f5f3ad11 | |||
| 8a63956d8d | |||
| 957f81aaa6 | |||
| 9a910e7e8c | |||
| 2135c7e9ed | |||
| 87cafedcc0 | |||
| 5911ac9525 | |||
| 5a6e167a0b | |||
| 771f6902df | |||
| 1626dc7c1f | |||
| 4eb15e3225 | |||
| 1d9bd31e42 | |||
| 34502102b4 | |||
| 95cd5edfab | |||
| c36e94ad98 | |||
| 8225414388 | |||
| 71f3a6c9c0 | |||
| c1ee0772ff | |||
| f5b9fddac4 | |||
| ea76a7cde3 | |||
| 8e99e8c014 | |||
| 131e69e29b | |||
| 9c6cc265da | |||
| 0767770d95 | |||
| 79fcb7446a | |||
| 91f22e1486 | |||
| b2a8d8af06 | |||
| b34f0b369f | |||
| 8163446fee | |||
| a331f6b0d8 | |||
| b3094c4751 | |||
| 2d47619503 | |||
| 1494620bfb | |||
| f1fd291473 | |||
| b20d56c357 | |||
| 9e49655f16 | |||
| 805a4017ab | |||
| 0e69daef28 | |||
| c704f0da1a | |||
| f15c70ab7f | |||
| 26ef0c5c79 | |||
| 7f5df63d6e | |||
| ae1cb40c5e | |||
| 609d5f1826 | |||
| 70b465a75c | |||
| 341af0a779 | |||
| 1e2f25c79c | |||
| 95004c72af | |||
| da83f4d2fc | |||
| 5799fb8640 | |||
| e1c3a4d24f | |||
| c20f9c6678 | |||
| 556ca7fa16 | |||
| 7dfbe69352 | |||
| bc091a045b | |||
| 257ef7c065 | |||
| d8b7b023a6 | |||
| 622a713fa1 | |||
| 7b48139c7a | |||
| 5ef761f4d8 | |||
| 4f865489f0 | |||
| 475a266e31 | |||
| d77412d35f | |||
| 5fee906a30 | |||
| a04076a1f2 | |||
| d0ed5742d0 | |||
| 2ba930d7bb | |||
| 650197e4dc | |||
| 53b48f0116 | |||
| 21f77735fc | |||
| 049838f998 | |||
| 6df1f24a6b | |||
| 1f47d41b03 | |||
| 903ef33978 | |||
| 7d2477a859 | |||
| 054a23264c | |||
| 9e50e8c386 | |||
| 1a52d63ea9 | |||
| 78d40d3e6d | |||
| afaeae1796 | |||
| f518505d71 | |||
| b5c0146072 | |||
| d5b78c7c81 | |||
| 99e0439396 | |||
| 9660b5f471 | |||
| 742671e7c9 | |||
| 81e812c697 | |||
| b984606f45 | |||
| 072a971908 | |||
| 829e7ae8a3 | |||
| df222f7338 | |||
| 8a0eb277db | |||
| 836747b10a | |||
| b638f51bd0 | |||
| 371f4c2e72 | |||
| 787e897899 | |||
| c341626927 | |||
| 86ef5ce6be | |||
| eee6c61ea6 | |||
| 79441b56ba | |||
| c4b9228d18 | |||
| 571f5aba3e | |||
| 8a954a1571 | |||
| 4e9072d20b | |||
| f49ff4b736 | |||
| 52c14af205 | |||
| 087e52eccf | |||
| 26c76fcc0b | |||
| 544a47fc07 | |||
| dfbbb39a25 | |||
| c52766af64 | |||
| 4af0bb82e1 | |||
| c2a9f46692 | |||
| 3398ecbfc2 | |||
| 3ce28cce2e | |||
| 54cbf4279a | |||
| e611797d37 | |||
| db27b57aa5 | |||
| 8d270f56e2 | |||
| 1e25d9306d | |||
| b3b8d045b7 | |||
| ab1c2037fc | |||
| 29aafc0ec7 | |||
| 03ed7684d4 | |||
| 8d1bf87c0e | |||
| ec4e2838cd | |||
| d3bfb8ceac | |||
| 10ce06e159 | |||
| 23cf2f6db3 | |||
| d3a22bc5a8 | |||
| 18937c1577 | |||
| 93c8f9347e | |||
| 26c09bc165 | |||
| 35ce557a91 | |||
| bdccf17907 | |||
| 91557e03ee | |||
| 5b5424a8ee | |||
| 3a5de34b03 | |||
| 6608a30b15 | |||
| bb21b0ad57 | |||
| 8e2349f196 | |||
| c4f051e2e9 | |||
| 691868bdaa | |||
| bc1643135c | |||
| 1910eaf251 | |||
| e3d53b99aa | |||
| d05d5cd4c7 | |||
| 1790647ff9 | |||
| fe51a68590 | |||
| 62ca5c4b91 | |||
| 33952ce027 | |||
| 893ed748bc | |||
| 13c9addc7d | |||
| 0d1c739aeb | |||
| 3ef9d54387 | |||
| 29c62b300c | |||
| b7afb51132 | |||
| d346c55175 |
+3
-1
@@ -137,11 +137,13 @@ before_script:
|
||||
sed -i \
|
||||
-e "s%= 'pgsql'%= 'mysqli'%" \
|
||||
-e "s%= 'username'%= 'travis'%" \
|
||||
-e "s%=> 'utf8mb4_unicode_ci'%=> 'utf8mb4_bin'%" \
|
||||
config.php;
|
||||
|
||||
mysql -u root -e 'SET GLOBAL innodb_file_format=barracuda;' ;
|
||||
mysql -u root -e 'SET GLOBAL innodb_file_per_table=ON;' ;
|
||||
mysql -e 'CREATE DATABASE travis_ci_test DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_bin;' ;
|
||||
mysql -u root -e 'SET GLOBAL innodb_large_prefix=ON;' ;
|
||||
mysql -e 'CREATE DATABASE travis_ci_test DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_bin;' ;
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -64,6 +64,71 @@ if (!empty($options['collation'])) {
|
||||
cli_error("Error: collation '$collation' is not available on this server!");
|
||||
}
|
||||
|
||||
$collationinfo = explode('_', $collation);
|
||||
$charset = reset($collationinfo);
|
||||
|
||||
$engine = strtolower($DB->get_dbengine());
|
||||
|
||||
// Do checks for utf8mb4.
|
||||
if (strpos($collation, 'utf8mb4') === 0) {
|
||||
// Do we have the right engine?
|
||||
if ($engine !== 'innodb' && $engine !== 'xtradb') {
|
||||
cli_error("Error: '$collation' requires InnoDB or XtraDB set as the engine.");
|
||||
}
|
||||
// Are we using Barracuda?
|
||||
if ($DB->get_row_format() != 'Barracuda') {
|
||||
// Try setting it here.
|
||||
try {
|
||||
$DB->execute("SET GLOBAL innodb_file_format=Barracuda");
|
||||
} catch (dml_exception $e) {
|
||||
cli_error("Error: '$collation' requires the file format to be set to Barracuda.
|
||||
An attempt was made to change the format, but it failed. Please try doing this manually.");
|
||||
}
|
||||
echo "GLOBAL SETTING: innodb_file_format changed to Barracuda\n";
|
||||
}
|
||||
// Is one file per table being used?
|
||||
if (!$DB->is_file_per_table_enabled()) {
|
||||
try {
|
||||
$DB->execute("SET GLOBAL innodb_file_per_table=1");
|
||||
} catch (dml_exception $e) {
|
||||
cli_error("Error: '$collation' requires the setting 'innodb_file_per_table' be set to 'ON'.
|
||||
An attempt was made to change the format, but it failed. Please try doing this manually.");
|
||||
}
|
||||
echo "GLOBAL SETTING: innodb_file_per_table changed to 1\n";
|
||||
}
|
||||
// Is large prefix set?
|
||||
if (!$DB->is_large_prefix_enabled()) {
|
||||
try {
|
||||
$DB->execute("SET GLOBAL innodb_large_prefix=1");
|
||||
} catch (dml_exception $e) {
|
||||
cli_error("Error: '$collation' requires the setting 'innodb_large_prefix' be set to 'ON'.
|
||||
An attempt was made to change the format, but it failed. Please try doing this manually.");
|
||||
}
|
||||
echo "GLOBAL SETTING: innodb_large_prefix changed to 1\n";
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "SHOW VARIABLES LIKE 'collation_database'";
|
||||
if (!$dbcollation = $DB->get_record_sql($sql)) {
|
||||
cli_error("Error: Could not access collation information on the database.");
|
||||
}
|
||||
$sql = "SHOW VARIABLES LIKE 'character_set_database'";
|
||||
if (!$dbcharset = $DB->get_record_sql($sql)) {
|
||||
cli_error("Error: Could not access character set information on the database.");
|
||||
}
|
||||
if ($dbcollation->value !== $collation || $dbcharset->value !== $charset) {
|
||||
// Try to convert the DB.
|
||||
echo "Converting database to '$collation' for $CFG->wwwroot:\n";
|
||||
$sql = "ALTER DATABASE $CFG->dbname DEFAULT CHARACTER SET $charset DEFAULT COLLATE = $collation";
|
||||
try {
|
||||
$DB->change_database_structure($sql);
|
||||
} catch (exception $e) {
|
||||
cli_error("Error: Tried to alter the database with no success. Please try manually changing the database
|
||||
to the new collation and character set and then run this script again.");
|
||||
}
|
||||
echo "DATABASE CONVERTED\n";
|
||||
}
|
||||
|
||||
echo "Converting tables and columns to '$collation' for $CFG->wwwroot:\n";
|
||||
$prefix = $DB->get_prefix();
|
||||
$prefix = str_replace('_', '\\_', $prefix);
|
||||
@@ -80,7 +145,7 @@ if (!empty($options['collation'])) {
|
||||
$skipped++;
|
||||
|
||||
} else {
|
||||
$DB->change_database_structure("ALTER TABLE $table->name DEFAULT COLLATE = $collation");
|
||||
$DB->change_database_structure("ALTER TABLE $table->name DEFAULT CHARACTER SET $charset DEFAULT COLLATE = $collation");
|
||||
echo "CONVERTED\n";
|
||||
$converted++;
|
||||
}
|
||||
@@ -96,18 +161,32 @@ if (!empty($options['collation'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for utf8mb4 collation.
|
||||
$rowformat = $DB->get_row_format_sql($engine, $collation);
|
||||
|
||||
if ($column->type === 'tinytext' or $column->type === 'mediumtext' or $column->type === 'text' or $column->type === 'longtext') {
|
||||
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
|
||||
$default = (!is_null($column->default) and $column->default !== '') ? "DEFAULT '$column->default'" : '';
|
||||
// primary, unique and inc are not supported for texts
|
||||
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default";
|
||||
$sql = "ALTER TABLE $table->name
|
||||
MODIFY COLUMN $column->field $column->type
|
||||
CHARACTER SET $charset
|
||||
COLLATE $collation $notnull $default";
|
||||
$DB->change_database_structure($sql);
|
||||
|
||||
} else if (strpos($column->type, 'varchar') === 0) {
|
||||
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
|
||||
$default = !is_null($column->default) ? "DEFAULT '$column->default'" : '';
|
||||
// primary, unique and inc are not supported for texts
|
||||
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default";
|
||||
|
||||
if ($rowformat != '') {
|
||||
$sql = "ALTER TABLE $table->name $rowformat";
|
||||
$DB->change_database_structure($sql);
|
||||
}
|
||||
|
||||
$sql = "ALTER TABLE $table->name
|
||||
MODIFY COLUMN $column->field $column->type
|
||||
CHARACTER SET $charset
|
||||
COLLATE $collation $notnull $default";
|
||||
$DB->change_database_structure($sql);
|
||||
} else {
|
||||
echo "ERROR (unknown column type: $column->type)\n";
|
||||
@@ -180,7 +259,9 @@ function mysql_get_collations() {
|
||||
global $DB;
|
||||
|
||||
$collations = array();
|
||||
$sql = "SHOW COLLATION WHERE Collation LIKE 'utf8\_%' AND Charset = 'utf8'";
|
||||
$sql = "SHOW COLLATION
|
||||
WHERE Collation LIKE 'utf8\_%' AND Charset = 'utf8'
|
||||
OR Collation LIKE 'utf8mb4\_%' AND Charset = 'utf8mb4'";
|
||||
$rs = $DB->get_recordset_sql($sql);
|
||||
foreach ($rs as $collation) {
|
||||
$collations[$collation->collation] = $collation->collation;
|
||||
|
||||
@@ -1723,6 +1723,21 @@
|
||||
<ON_CHECK message="libcurlwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfileformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfilepertable" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddblargeprefix" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
<MOODLE version="3.2" requires="2.7">
|
||||
@@ -1873,6 +1888,21 @@
|
||||
<ON_CHECK message="libcurlwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfileformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfilepertable" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddblargeprefix" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
</COMPATIBILITY_MATRIX>
|
||||
|
||||
@@ -7,8 +7,7 @@ Feature: Forms manipulation
|
||||
@javascript
|
||||
Scenario: Basic forms manipulation
|
||||
Given I log in as "admin"
|
||||
And I follow "Preferences" in the user menu
|
||||
And I follow "Edit profile"
|
||||
And I open my profile in edit mode
|
||||
When I set the field "First name" to "Field value"
|
||||
And I set the field "Select a country" to "Japan"
|
||||
And I set the field "Unmask" to "1"
|
||||
|
||||
@@ -10,8 +10,7 @@ Feature: Transform steps arguments
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And I log in as "admin"
|
||||
And I follow "Preferences" in the user menu
|
||||
And I follow "Edit profile"
|
||||
And I open my profile in edit mode
|
||||
|
||||
Scenario: Use nasty strings on steps arguments
|
||||
When I set the field "Surname" to "$NASTYSTRING1"
|
||||
|
||||
@@ -99,7 +99,7 @@ class competency extends persistent {
|
||||
// Description.
|
||||
$mform->addElement('editor', 'description',
|
||||
get_string('description', 'tool_lp'), array('rows' => 4));
|
||||
$mform->setType('description', PARAM_RAW);
|
||||
$mform->setType('description', PARAM_CLEANHTML);
|
||||
// ID number.
|
||||
$mform->addElement('text', 'idnumber', get_string('idnumber', 'tool_lp'), 'maxlength="100"');
|
||||
$mform->setType('idnumber', PARAM_RAW);
|
||||
|
||||
@@ -62,7 +62,7 @@ class competency_framework extends persistent {
|
||||
// Description.
|
||||
$mform->addElement('editor', 'description',
|
||||
get_string('description', 'tool_lp'), array('rows' => 4));
|
||||
$mform->setType('description', PARAM_RAW);
|
||||
$mform->setType('description', PARAM_CLEANHTML);
|
||||
// ID number.
|
||||
$mform->addElement('text', 'idnumber', get_string('idnumber', 'tool_lp'), 'maxlength="100"');
|
||||
$mform->setType('idnumber', PARAM_RAW);
|
||||
|
||||
@@ -184,8 +184,14 @@ abstract class persistent extends moodleform {
|
||||
$data = $this->get_persistent()->to_record();
|
||||
$class = static::$persistentclass;
|
||||
$properties = $class::get_formatted_properties();
|
||||
$allproperties = $class::properties_definition();
|
||||
|
||||
foreach ($data as $field => $value) {
|
||||
// Clean data if it is to be displayed in a form.
|
||||
if (isset($allproperties[$field]['type'])) {
|
||||
$data->$field = clean_param($data->$field, $allproperties[$field]['type']);
|
||||
}
|
||||
|
||||
// Convert formatted properties.
|
||||
if (isset($properties[$field])) {
|
||||
$data->$field = array(
|
||||
|
||||
@@ -59,7 +59,7 @@ class plan extends persistent {
|
||||
$mform->addRule('name', get_string('maximumchars', '', 100), 'maxlength', 100, 'client');
|
||||
// Description.
|
||||
$mform->addElement('editor', 'description', get_string('plandescription', 'tool_lp'), array('rows' => 4));
|
||||
$mform->setType('description', PARAM_RAW);
|
||||
$mform->setType('description', PARAM_CLEANHTML);
|
||||
|
||||
$mform->addElement('date_time_selector', 'duedate', get_string('duedate', 'tool_lp'), array('optional' => true));
|
||||
$mform->addHelpButton('duedate', 'duedate', 'tool_lp');
|
||||
|
||||
@@ -58,7 +58,7 @@ class template extends persistent {
|
||||
// Description.
|
||||
$mform->addElement('editor', 'description',
|
||||
get_string('description', 'tool_lp'), array('rows' => 4));
|
||||
$mform->setType('description', PARAM_RAW);
|
||||
$mform->setType('description', PARAM_CLEANHTML);
|
||||
$mform->addElement('selectyesno', 'visible',
|
||||
get_string('visible', 'tool_lp'));
|
||||
$mform->addElement('date_time_selector',
|
||||
|
||||
@@ -54,7 +54,7 @@ class user_evidence extends persistent {
|
||||
$mform->addRule('name', get_string('maximumchars', '', 100), 'maxlength', 100, 'client');
|
||||
// Description.
|
||||
$mform->addElement('editor', 'description', get_string('userevidencedescription', 'tool_lp'), array('rows' => 10));
|
||||
$mform->setType('description', PARAM_RAW);
|
||||
$mform->setType('description', PARAM_CLEANHTML);
|
||||
|
||||
$mform->addElement('url', 'url', get_string('userevidenceurl', 'tool_lp'), array(), array('usefilepicker' => false));
|
||||
$mform->setType('url', PARAM_RAW_TRIMMED); // Can not use PARAM_URL, it silently converts bad URLs to ''.
|
||||
|
||||
@@ -92,7 +92,7 @@ require(['core/str'], function(Str) {
|
||||
{ key: 'comments', component: 'moodle' },
|
||||
{ key: 'commentscount', component: 'moodle' },
|
||||
{ key: 'commentsrequirelogin', component: 'moodle' },
|
||||
{ key: 'deletecomment', component: 'moodle' },
|
||||
{ key: 'deletecommentbyon', component: 'moodle' },
|
||||
]).then(function() {
|
||||
// Kick off when strings are loaded.
|
||||
Y.use('core_comment', function(Y) {
|
||||
|
||||
@@ -53,10 +53,13 @@ class eventobservers {
|
||||
* @param \core\event\course_deleted $event The course deleted event.
|
||||
*/
|
||||
public static function course_deleted(\core\event\course_deleted $event) {
|
||||
// Delete rules defined inside this course and associated subscriptions.
|
||||
$rules = rule_manager::get_rules_by_courseid($event->courseid, 0, 0, false);
|
||||
foreach ($rules as $rule) {
|
||||
rule_manager::delete_rule($rule->id, $event->get_context());
|
||||
}
|
||||
// Delete remaining subscriptions inside this course (from site-wide rules).
|
||||
subscription_manager::remove_all_subscriptions_in_course($event->get_context());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -176,8 +176,12 @@ class subscription {
|
||||
if (empty($courseid)) {
|
||||
return get_string('site');
|
||||
} else {
|
||||
$course = get_course($courseid);
|
||||
return format_string($course->fullname, true, array('context' => $context));
|
||||
try {
|
||||
$course = get_course($courseid);
|
||||
return format_string($course->fullname, true, array('context' => $context));
|
||||
} catch (\dml_exception $e) {
|
||||
return '-';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -118,9 +118,10 @@ class subscription_manager {
|
||||
|
||||
// If successful trigger a subscription_deleted event.
|
||||
if ($success) {
|
||||
if (!empty($subscription->courseid)) {
|
||||
if (!empty($subscription->courseid) &&
|
||||
($coursecontext = \context_course::instance($subscription->courseid, IGNORE_MISSING))) {
|
||||
$courseid = $subscription->courseid;
|
||||
$context = \context_course::instance($subscription->courseid);
|
||||
$context = $coursecontext;
|
||||
} else {
|
||||
$courseid = 0;
|
||||
$context = \context_system::instance();
|
||||
@@ -222,6 +223,31 @@ class subscription_manager {
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all subscriptions in a course.
|
||||
*
|
||||
* This is called after a course was deleted, context no longer exists but we kept the object
|
||||
*
|
||||
* @param \context_course $coursecontext the context of the course
|
||||
*/
|
||||
public static function remove_all_subscriptions_in_course($coursecontext) {
|
||||
global $DB;
|
||||
|
||||
// Store all the subscriptions we have to delete.
|
||||
if ($subscriptions = $DB->get_records('tool_monitor_subscriptions', ['courseid' => $coursecontext->instanceid])) {
|
||||
// Delete subscriptions in bulk.
|
||||
$DB->delete_records('tool_monitor_subscriptions', ['courseid' => $coursecontext->instanceid]);
|
||||
|
||||
// Trigger events one by one.
|
||||
foreach ($subscriptions as $subscription) {
|
||||
$params = ['objectid' => $subscription->id, 'context' => $coursecontext];
|
||||
$event = \tool_monitor\event\subscription_deleted::create($params);
|
||||
$event->add_record_snapshot('tool_monitor_subscriptions', $subscription);
|
||||
$event->trigger();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a subscription instance for an given subscription id.
|
||||
*
|
||||
|
||||
@@ -77,5 +77,22 @@ function xmldb_tool_monitor_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2016052305, 'tool', 'monitor');
|
||||
}
|
||||
|
||||
if ($oldversion < 2016052306) {
|
||||
|
||||
// Delete "orphaned" subscriptions.
|
||||
$sql = "SELECT DISTINCT s.courseid
|
||||
FROM {tool_monitor_subscriptions} s
|
||||
LEFT OUTER JOIN {course} c ON c.id = s.courseid
|
||||
WHERE s.courseid <> 0 and c.id IS NULL";
|
||||
$deletedcourses = $DB->get_field_sql($sql);
|
||||
if ($deletedcourses) {
|
||||
list($sql, $params) = $DB->get_in_or_equal($deletedcourses);
|
||||
$DB->execute("DELETE FROM {tool_monitor_subscriptions} WHERE courseid " . $sql, $params);
|
||||
}
|
||||
|
||||
// Monitor savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2016052306, 'tool', 'monitor');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ if (empty($courseid)) {
|
||||
// check system level capability.
|
||||
if (!has_capability('tool/monitor:subscribe', $context)) {
|
||||
// If not system level then check to see if they have access to any course level rules.
|
||||
if (tool_monitor_get_user_courses()){
|
||||
if (tool_monitor_can_subscribe()) {
|
||||
// Make them choose a course.
|
||||
$choose = true;
|
||||
} else {
|
||||
|
||||
@@ -75,12 +75,20 @@ function tool_monitor_extend_navigation_frontpage($navigation, $course, $context
|
||||
* @param context $coursecontext The context of the course
|
||||
*/
|
||||
function tool_monitor_extend_navigation_user_settings($navigation, $user, $usercontext, $course, $coursecontext) {
|
||||
global $USER, $SITE;
|
||||
global $USER, $PAGE;
|
||||
|
||||
// Don't bother doing needless calculations unless we are on the relevant pages.
|
||||
$onpreferencepage = $PAGE->url->compare(new moodle_url('/user/preferences.php'), URL_MATCH_BASE);
|
||||
$onmonitorpage = $PAGE->url->compare(new moodle_url('/admin/tool/monitor/index.php'), URL_MATCH_BASE);
|
||||
if (!$onpreferencepage && !$onmonitorpage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Don't show the setting if the event monitor isn't turned on. No access to other peoples subscriptions.
|
||||
if (get_config('tool_monitor', 'enablemonitor') && $USER->id == $user->id) {
|
||||
// Now let's check to see if the user has any courses / site rules that they can subscribe to.
|
||||
if ($courses = tool_monitor_get_user_courses()) {
|
||||
// We skip doing a check here if we are on the event monitor page as the check is done internally on that page.
|
||||
if ($onmonitorpage || tool_monitor_can_subscribe()) {
|
||||
$url = new moodle_url('/admin/tool/monitor/index.php');
|
||||
$subsnode = navigation_node::create(get_string('managesubscriptions', 'tool_monitor'), $url,
|
||||
navigation_node::TYPE_SETTING, null, 'monitor', new pix_icon('i/settings', ''));
|
||||
@@ -92,6 +100,19 @@ function tool_monitor_extend_navigation_user_settings($navigation, $user, $userc
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has the capacity to subscribe to an event monitor anywhere.
|
||||
*
|
||||
* @return bool True if a capability in a course is found. False otherwise.
|
||||
*/
|
||||
function tool_monitor_can_subscribe() {
|
||||
if (has_capability('tool/monitor:subscribe', context_system::instance())) {
|
||||
return true;
|
||||
}
|
||||
$courses = get_user_capability_course('tool/monitor:subscribe', null, true, '', '', 1);
|
||||
return empty($courses) ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of courses and also include 'Site' for site wide rules.
|
||||
*
|
||||
@@ -103,8 +124,11 @@ function tool_monitor_get_user_courses() {
|
||||
if (has_capability('tool/monitor:subscribe', context_system::instance())) {
|
||||
$options[0] = get_string('site');
|
||||
}
|
||||
if ($courses = get_user_capability_course('tool/monitor:subscribe', null, true, 'fullname, visible', $orderby)) {
|
||||
|
||||
$fields = 'fullname, visible, ctxid, ctxpath, ctxdepth, ctxlevel, ctxinstance';
|
||||
if ($courses = get_user_capability_course('tool/monitor:subscribe', null, true, $fields, $orderby)) {
|
||||
foreach ($courses as $course) {
|
||||
context_helper::preload_from_record($course);
|
||||
$coursectx = context_course::instance($course->id);
|
||||
if ($course->visible || has_capability('moodle/course:viewhiddencourses', $coursectx)) {
|
||||
$options[$course->id] = format_string($course->fullname, true, array('context' => $coursectx));
|
||||
|
||||
@@ -26,6 +26,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$plugin->version = 2016052305; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2016052306; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2016051900; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_monitor'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
+24
-2
@@ -99,9 +99,31 @@ if (!isset($config->removeuser)) {
|
||||
$yesno = array( get_string('no'), get_string('yes') );
|
||||
|
||||
$disabled = '';
|
||||
if (!ldap_paged_results_supported($config->ldap_version)) {
|
||||
$pagedresultssupported = false;
|
||||
if ($config->host_url !== '') {
|
||||
/**
|
||||
* We try to connect each and every time we open the config, because we want to set the Page
|
||||
* Size setting as enabled or disabled depending on the configured LDAP server supporting
|
||||
* pagination or not, and to notify the user about it. If the user changed the LDAP server (or
|
||||
* the LDAP protocol version) last time, it might happen that paged results are no longer
|
||||
* available and we want to show that to the user the next time she goes to the settings page.
|
||||
*/
|
||||
try {
|
||||
$ldapconn = $this->ldap_connect();
|
||||
$pagedresultssupported = ldap_paged_results_supported($config->ldap_version, $ldapconn);
|
||||
} catch (Exception $e) {
|
||||
// If we couldn't connect and get the supported options, we can only assume we don't support paged results.
|
||||
$pagedresultssupported = false;
|
||||
}
|
||||
}
|
||||
/* Make sure we only disable the paged result size setting and show the notification about it if
|
||||
* there is a configured server that we tried to contact. Othersiwe, if someone's LDAP server does
|
||||
* support paged results, they won't be able to turn it on the first time they set it up (because
|
||||
* the field will be disabled).
|
||||
*/
|
||||
if (($config->host_url !== '') && (!$pagedresultssupported)) {
|
||||
$disabled = ' disabled="disabled"';
|
||||
echo $OUTPUT->notification(get_string('pagedresultsnotsupp', 'auth_ldap'));
|
||||
echo $OUTPUT->notification(get_string('pagedresultsnotsupp', 'auth_ldap'), \core\output\notification::NOTIFY_INFO);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
+2
-2
@@ -695,7 +695,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
array_push($contexts, $this->config->create_context);
|
||||
}
|
||||
|
||||
$ldap_pagedresults = ldap_paged_results_supported($this->config->ldap_version);
|
||||
$ldap_pagedresults = ldap_paged_results_supported($this->config->ldap_version, $ldapconnection);
|
||||
$ldap_cookie = '';
|
||||
foreach ($contexts as $context) {
|
||||
$context = trim($context);
|
||||
@@ -1540,7 +1540,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
|
||||
$ldap_cookie = '';
|
||||
$ldap_pagedresults = ldap_paged_results_supported($this->config->ldap_version);
|
||||
$ldap_pagedresults = ldap_paged_results_supported($this->config->ldap_version, $ldapconnection);
|
||||
foreach ($contexts as $context) {
|
||||
$context = trim($context);
|
||||
if (empty($context)) {
|
||||
|
||||
+24
-2
@@ -117,9 +117,31 @@ $fastpathoptions = array(AUTH_NTLM_FASTPATH_YESFORM => get_string('auth_ntlmsso_
|
||||
AUTH_NTLM_FASTPATH_ATTEMPT => get_string('auth_ntlmsso_ie_fastpath_attempt', 'auth_ldap'));
|
||||
|
||||
$disabled = '';
|
||||
if (!ldap_paged_results_supported($config->ldap_version)) {
|
||||
$pagedresultssupported = false;
|
||||
if ($config->host_url !== '') {
|
||||
/**
|
||||
* We try to connect each and every time we open the config, because we want to set the Page
|
||||
* Size setting as enabled or disabled depending on the configured LDAP server supporting
|
||||
* pagination or not, and to notify the user about it. If the user changed the LDAP server (or
|
||||
* the LDAP protocol version) last time, it might happen that paged results are no longer
|
||||
* available and we want to show that to the user the next time she goes to the settings page.
|
||||
*/
|
||||
try {
|
||||
$ldapconn = $this->ldap_connect();
|
||||
$pagedresultssupported = ldap_paged_results_supported($config->ldap_version, $ldapconn);
|
||||
} catch (Exception $e) {
|
||||
// If we couldn't connect and get the supported options, we can only assume we don't support paged results.
|
||||
$pagedresultssupported = false;
|
||||
}
|
||||
}
|
||||
/* Make sure we only disable the paged result size setting and show the notification about it if
|
||||
* there is a configured server that we tried to contact. Othersiwe, if someone's LDAP server does
|
||||
* support paged results, they won't be able to turn it on the first time they set it up (because
|
||||
* the field will be disabled).
|
||||
*/
|
||||
if (($config->host_url !== '') && (!$pagedresultssupported)) {
|
||||
$disabled = ' disabled="disabled"';
|
||||
echo $OUTPUT->notification(get_string('pagedresultsnotsupp', 'auth_ldap'));
|
||||
echo $OUTPUT->notification(get_string('pagedresultsnotsupp', 'auth_ldap'), \core\output\notification::NOTIFY_INFO);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -132,7 +132,7 @@ $string['ntlmsso_attempting'] = 'Attempting Single Sign On via NTLM...';
|
||||
$string['ntlmsso_failed'] = 'Auto-login failed, try the normal login page...';
|
||||
$string['ntlmsso_isdisabled'] = 'NTLM SSO is disabled.';
|
||||
$string['ntlmsso_unknowntype'] = 'Unknown ntlmsso type!';
|
||||
$string['pagedresultsnotsupp'] = 'LDAP paged results not supported (either your PHP version lacks support or you have configured Moodle to use LDAP protocol version 2)';
|
||||
$string['pagedresultsnotsupp'] = 'LDAP paged results not supported (either your PHP version lacks support, you have configured Moodle to use LDAP protocol version 2 or Moodle cannot contact your LDAP server to see if paged support is available.)';
|
||||
$string['pagesize'] = 'Make sure this value is smaller than your LDAP server result set size limit (the maximum number of entries that can be returned in a single query)';
|
||||
$string['pagesize_key'] = 'Page Size';
|
||||
$string['pluginname'] = 'LDAP server';
|
||||
|
||||
@@ -2666,7 +2666,7 @@ class restore_calendarevents_structure_step extends restore_structure_step {
|
||||
'courseid' => $this->get_courseid(),
|
||||
'groupid' => $data->groupid,
|
||||
'userid' => $data->userid,
|
||||
'repeatid' => $data->repeatid,
|
||||
'repeatid' => $this->get_mappingid('event', $data->repeatid),
|
||||
'modulename' => $data->modulename,
|
||||
'eventtype' => $data->eventtype,
|
||||
'timestart' => $this->apply_date_offset($data->timestart),
|
||||
@@ -2684,18 +2684,27 @@ class restore_calendarevents_structure_step extends restore_structure_step {
|
||||
FROM {event}
|
||||
WHERE " . $DB->sql_compare_text('name', 255) . " = " . $DB->sql_compare_text('?', 255) . "
|
||||
AND courseid = ?
|
||||
AND repeatid = ?
|
||||
AND modulename = ?
|
||||
AND timestart = ?
|
||||
AND timeduration = ?
|
||||
AND " . $DB->sql_compare_text('description', 255) . " = " . $DB->sql_compare_text('?', 255);
|
||||
$arg = array ($params['name'], $params['courseid'], $params['repeatid'], $params['modulename'], $params['timestart'], $params['timeduration'], $params['description']);
|
||||
$arg = array ($params['name'], $params['courseid'], $params['modulename'], $params['timestart'], $params['timeduration'], $params['description']);
|
||||
$result = $DB->record_exists_sql($sql, $arg);
|
||||
if (empty($result)) {
|
||||
$newitemid = $DB->insert_record('event', $params);
|
||||
$this->set_mapping('event', $oldid, $newitemid);
|
||||
$this->set_mapping('event_description', $oldid, $newitemid, $restorefiles);
|
||||
}
|
||||
// With repeating events, each event has the repeatid pointed at the first occurrence.
|
||||
// Since the repeatid will be empty when the first occurrence is restored,
|
||||
// Get the repeatid from the second occurrence of the repeating event and use that to update the first occurrence.
|
||||
// Then keep a list of repeatids so we only perform this update once.
|
||||
static $repeatids = array();
|
||||
if (!empty($params['repeatid']) && !in_array($params['repeatid'], $repeatids)) {
|
||||
// This entry is repeated so the repeatid field must be set.
|
||||
$DB->set_field('event', 'repeatid', $params['repeatid'], array('id' => $params['repeatid']));
|
||||
$repeatids[] = $params['repeatid'];
|
||||
}
|
||||
|
||||
}
|
||||
protected function after_execute() {
|
||||
|
||||
@@ -31,8 +31,7 @@ Feature: Award badges
|
||||
And I press "Enable access"
|
||||
And I press "Continue"
|
||||
And I click on "Admin User" "link"
|
||||
And I follow "Profile" in the open menu
|
||||
And I follow "Edit profile"
|
||||
And I open my profile in edit mode
|
||||
And I expand all fieldsets
|
||||
And I set the field "Phone" to "123456789"
|
||||
And I press "Update profile"
|
||||
|
||||
@@ -49,6 +49,7 @@ class block_activity_results_edit_form extends block_edit_form {
|
||||
$sql = 'SELECT id, itemname FROM {grade_items} WHERE courseid = ? and itemtype = ? and (gradetype = ? or gradetype = ?)';
|
||||
$params = array($this->page->course->id, 'mod', GRADE_TYPE_VALUE, GRADE_TYPE_SCALE);
|
||||
$activities = $DB->get_records_sql_menu($sql, $params);
|
||||
core_collator::asort($activities);
|
||||
|
||||
if (empty($activities)) {
|
||||
$mform->addElement('static', 'noactivitieswarning', get_string('config_select_activity', 'block_activity_results'),
|
||||
|
||||
@@ -86,7 +86,7 @@ function block_course_overview_get_myorder() {
|
||||
// If preference was not found, look in the old location and convert if found.
|
||||
$order = array();
|
||||
if ($value = get_user_preferences('course_overview_course_order')) {
|
||||
$order = unserialize($value);
|
||||
$order = unserialize_array($value);
|
||||
block_course_overview_update_myorder($order);
|
||||
unset_user_preference('course_overview_course_order');
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -213,7 +213,7 @@ class cache implements cache_loader {
|
||||
$this->definition = $definition;
|
||||
$this->store = $store;
|
||||
$this->storetype = get_class($store);
|
||||
$this->perfdebug = !empty($CFG->perfdebug);
|
||||
$this->perfdebug = (!empty($CFG->perfdebug) and $CFG->perfdebug > 7);
|
||||
if ($loader instanceof cache_loader) {
|
||||
$this->loader = $loader;
|
||||
// Mark the loader as a sub (chained) loader.
|
||||
|
||||
Vendored
+53
@@ -2170,4 +2170,57 @@ class core_cache_testcase extends advanced_testcase {
|
||||
$this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['sets'] -
|
||||
$startstats[$requestid]['stores']['cachestore_static']['sets']);
|
||||
}
|
||||
|
||||
public function test_performance_debug_off() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest(true);
|
||||
$CFG->perfdebug = 7;
|
||||
|
||||
$instance = cache_config_testing::instance();
|
||||
$applicationid = 'phpunit/applicationperfoff';
|
||||
$instance->phpunit_add_definition($applicationid, array(
|
||||
'mode' => cache_store::MODE_APPLICATION,
|
||||
'component' => 'phpunit',
|
||||
'area' => 'applicationperfoff'
|
||||
));
|
||||
$sessionid = 'phpunit/sessionperfoff';
|
||||
$instance->phpunit_add_definition($sessionid, array(
|
||||
'mode' => cache_store::MODE_SESSION,
|
||||
'component' => 'phpunit',
|
||||
'area' => 'sessionperfoff'
|
||||
));
|
||||
$requestid = 'phpunit/requestperfoff';
|
||||
$instance->phpunit_add_definition($requestid, array(
|
||||
'mode' => cache_store::MODE_REQUEST,
|
||||
'component' => 'phpunit',
|
||||
'area' => 'requestperfoff'
|
||||
));
|
||||
|
||||
$application = cache::make('phpunit', 'applicationperfoff');
|
||||
$session = cache::make('phpunit', 'sessionperfoff');
|
||||
$request = cache::make('phpunit', 'requestperfoff');
|
||||
|
||||
// Check that no stats are recorded for these definitions yet.
|
||||
$stats = cache_helper::get_stats();
|
||||
$this->assertArrayNotHasKey($applicationid, $stats);
|
||||
$this->assertArrayNotHasKey($sessionid, $stats);
|
||||
$this->assertArrayNotHasKey($requestid, $stats);
|
||||
|
||||
// Trigger cache misses, cache sets and cache hits.
|
||||
$this->assertFalse($application->get('missMe'));
|
||||
$this->assertTrue($application->set('setMe', 1));
|
||||
$this->assertEquals(1, $application->get('setMe'));
|
||||
$this->assertFalse($session->get('missMe'));
|
||||
$this->assertTrue($session->set('setMe', 3));
|
||||
$this->assertEquals(3, $session->get('setMe'));
|
||||
$this->assertFalse($request->get('missMe'));
|
||||
$this->assertTrue($request->set('setMe', 4));
|
||||
$this->assertEquals(4, $request->get('setMe'));
|
||||
|
||||
// Check that no stats are being recorded for these definitions.
|
||||
$endstats = cache_helper::get_stats();
|
||||
$this->assertArrayNotHasKey($applicationid, $endstats);
|
||||
$this->assertArrayNotHasKey($sessionid, $endstats);
|
||||
$this->assertArrayNotHasKey($requestid, $endstats);
|
||||
}
|
||||
}
|
||||
|
||||
+24
-1
@@ -57,6 +57,12 @@ M.core_comment = {
|
||||
this.view(0);
|
||||
return false;
|
||||
}, this);
|
||||
// Also handle space/enter key.
|
||||
handle.on('key', function(e) {
|
||||
e.preventDefault();
|
||||
this.view(0);
|
||||
return false;
|
||||
}, '13,32', this);
|
||||
}
|
||||
scope.toggle_textarea(false);
|
||||
},
|
||||
@@ -186,7 +192,17 @@ M.core_comment = {
|
||||
val = val.replace('___name___', list[i].fullname);
|
||||
}
|
||||
if (list[i]['delete']||newcmt) {
|
||||
list[i].content = '<div class="comment-delete"><a href="#" id ="comment-delete-'+this.client_id+'-'+list[i].id+'" title="'+M.util.get_string('deletecomment', 'moodle')+'"><img alt="" src="'+M.util.image_url('t/delete', 'core')+'" /></a></div>' + list[i].content;
|
||||
var tokens = {
|
||||
user: list[i].fullname,
|
||||
time: list[i].time
|
||||
};
|
||||
var deleteStr = Y.Escape.html(M.util.get_string('deletecommentbyon', 'moodle', tokens));
|
||||
list[i].content = '<div class="comment-delete">' +
|
||||
'<a href="#" role="button" id ="comment-delete-' + this.client_id + '-' + list[i].id + '"' +
|
||||
' title="' + deleteStr + '">' +
|
||||
'<img alt="' + deleteStr + '" src="' + M.util.image_url('t/delete', 'core') + '" />' +
|
||||
'</a>' +
|
||||
'</div>' + list[i].content;
|
||||
}
|
||||
val = val.replace('___time___', list[i].time);
|
||||
val = val.replace('___picture___', list[i].avatar);
|
||||
@@ -335,6 +351,7 @@ M.core_comment = {
|
||||
);
|
||||
},
|
||||
view: function(page) {
|
||||
var commenttoggler = Y.one('#comment-link-' + this.client_id);
|
||||
var container = Y.one('#comment-ctrl-'+this.client_id);
|
||||
var ta = Y.one('#dlg-content-'+this.client_id);
|
||||
var img = Y.one('#comment-img-'+this.client_id);
|
||||
@@ -351,6 +368,9 @@ M.core_comment = {
|
||||
if (img) {
|
||||
img.set('src', M.util.image_url('t/expanded', 'core'));
|
||||
}
|
||||
if (commenttoggler) {
|
||||
commenttoggler.setAttribute('aria-expanded', 'true');
|
||||
}
|
||||
} else {
|
||||
// hide
|
||||
container.setStyle('display', 'none');
|
||||
@@ -364,6 +384,9 @@ M.core_comment = {
|
||||
if (ta) {
|
||||
ta.set('value','');
|
||||
}
|
||||
if (commenttoggler) {
|
||||
commenttoggler.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
}
|
||||
if (ta) {
|
||||
//toggle_textarea.apply(ta, [false]);
|
||||
|
||||
+8
-2
@@ -263,7 +263,7 @@ class comment {
|
||||
'comments',
|
||||
'commentscount',
|
||||
'commentsrequirelogin',
|
||||
'deletecomment',
|
||||
'deletecommentbyon',
|
||||
),
|
||||
'moodle'
|
||||
);
|
||||
@@ -460,7 +460,13 @@ class comment {
|
||||
} else {
|
||||
$collapsedimage= 't/collapsed';
|
||||
}
|
||||
$html .= html_writer::start_tag('a', array('class' => 'comment-link', 'id' => 'comment-link-'.$this->cid, 'href' => '#'));
|
||||
$html .= html_writer::start_tag('a', array(
|
||||
'class' => 'comment-link',
|
||||
'id' => 'comment-link-'.$this->cid,
|
||||
'href' => '#',
|
||||
'role' => 'button',
|
||||
'aria-expanded' => 'false')
|
||||
);
|
||||
$html .= html_writer::empty_tag('img', array('id' => 'comment-img-'.$this->cid, 'src' => $OUTPUT->pix_url($collapsedimage), 'alt' => $this->linktext, 'title' => $this->linktext));
|
||||
$html .= html_writer::tag('span', $this->linktext.' '.$countstring, array('id' => 'comment-link-text-'.$this->cid));
|
||||
$html .= html_writer::end_tag('a');
|
||||
|
||||
@@ -68,7 +68,7 @@ class competency extends persistent {
|
||||
),
|
||||
'description' => array(
|
||||
'default' => '',
|
||||
'type' => PARAM_RAW
|
||||
'type' => PARAM_CLEANHTML
|
||||
),
|
||||
'descriptionformat' => array(
|
||||
'choices' => array(FORMAT_HTML, FORMAT_MOODLE, FORMAT_PLAIN, FORMAT_MARKDOWN),
|
||||
|
||||
@@ -90,7 +90,7 @@ class competency_framework extends persistent {
|
||||
'type' => PARAM_RAW
|
||||
),
|
||||
'description' => array(
|
||||
'type' => PARAM_RAW,
|
||||
'type' => PARAM_CLEANHTML,
|
||||
'default' => ''
|
||||
),
|
||||
'descriptionformat' => array(
|
||||
|
||||
+3
-2
@@ -334,7 +334,8 @@ abstract class exporter {
|
||||
*/
|
||||
final protected static function get_format_field($definitions, $property) {
|
||||
$formatproperty = $property . 'format';
|
||||
if ($definitions[$property]['type'] == PARAM_RAW && isset($definitions[$formatproperty])
|
||||
if (($definitions[$property]['type'] == PARAM_RAW || $definitions[$property]['type'] == PARAM_CLEANHTML)
|
||||
&& isset($definitions[$formatproperty])
|
||||
&& $definitions[$formatproperty]['type'] == PARAM_INT) {
|
||||
return $formatproperty;
|
||||
}
|
||||
@@ -451,7 +452,7 @@ abstract class exporter {
|
||||
// This is a nested array of more properties.
|
||||
$thisvalue = self::get_read_structure_from_properties($type, $proprequired, $propdefault);
|
||||
} else {
|
||||
if ($definition['type'] == PARAM_TEXT) {
|
||||
if ($definition['type'] == PARAM_TEXT || $definition['type'] == PARAM_CLEANHTML) {
|
||||
// PARAM_TEXT always becomes PARAM_RAW because filters may be applied.
|
||||
$type = PARAM_RAW;
|
||||
}
|
||||
|
||||
@@ -248,7 +248,8 @@ abstract class persistent {
|
||||
$formatted = array();
|
||||
foreach ($properties as $property => $definition) {
|
||||
$propertyformat = $property . 'format';
|
||||
if ($definition['type'] == PARAM_RAW && array_key_exists($propertyformat, $properties)
|
||||
if (($definition['type'] == PARAM_RAW || $definition['type'] == PARAM_CLEANHTML)
|
||||
&& array_key_exists($propertyformat, $properties)
|
||||
&& $properties[$propertyformat]['type'] == PARAM_INT) {
|
||||
$formatted[$property] = $propertyformat;
|
||||
}
|
||||
@@ -616,6 +617,10 @@ abstract class persistent {
|
||||
// Validate_param() does not like false with PARAM_BOOL, better to convert it to int.
|
||||
$value = 0;
|
||||
}
|
||||
if ($definition['type'] === PARAM_CLEANHTML) {
|
||||
// We silently clean for this type. It may introduce changes even to valid data.
|
||||
$value = clean_param($value, PARAM_CLEANHTML);
|
||||
}
|
||||
validate_param($value, $definition['type'], $definition['null']);
|
||||
} catch (invalid_parameter_exception $e) {
|
||||
$errors[$property] = static::get_property_error_message($property);
|
||||
|
||||
@@ -71,7 +71,7 @@ class plan extends persistent {
|
||||
'type' => PARAM_TEXT,
|
||||
),
|
||||
'description' => array(
|
||||
'type' => PARAM_RAW,
|
||||
'type' => PARAM_CLEANHTML,
|
||||
'default' => ''
|
||||
),
|
||||
'descriptionformat' => array(
|
||||
|
||||
@@ -53,7 +53,7 @@ class template extends persistent {
|
||||
),
|
||||
'description' => array(
|
||||
'default' => '',
|
||||
'type' => PARAM_RAW,
|
||||
'type' => PARAM_CLEANHTML,
|
||||
),
|
||||
'descriptionformat' => array(
|
||||
'choices' => array(FORMAT_HTML, FORMAT_MOODLE, FORMAT_PLAIN, FORMAT_MARKDOWN),
|
||||
|
||||
@@ -53,7 +53,7 @@ class user_evidence extends persistent {
|
||||
'type' => PARAM_TEXT
|
||||
),
|
||||
'description' => array(
|
||||
'type' => PARAM_RAW,
|
||||
'type' => PARAM_CLEANHTML,
|
||||
'default' => '',
|
||||
),
|
||||
'descriptionformat' => array(
|
||||
|
||||
@@ -288,6 +288,7 @@ function core_competency_pluginfile($course, $cm, $context, $filearea, $args, $f
|
||||
if ($filearea == 'userevidence' && $context->contextlevel == CONTEXT_USER) {
|
||||
if (user_evidence::can_read_user($context->instanceid)) {
|
||||
$file = $fs->get_file($context->id, 'core_competency', $filearea, $itemid, $filepath, $filename);
|
||||
$forcedownload = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,12 +121,13 @@ class behat_completion extends behat_base {
|
||||
public function activity_marked_as_complete($activityname, $activitytype, $completiontype) {
|
||||
if ($completiontype == "manual") {
|
||||
$imgalttext = get_string("completion-alt-manual-y", 'core_completion', $activityname);
|
||||
$xpathtocheck = "//input[@type='image'][contains(@alt, '$imgalttext')]";
|
||||
} else {
|
||||
$imgalttext = get_string("completion-alt-auto-y", 'core_completion', $activityname);
|
||||
$xpathtocheck = "//img[contains(@alt, '$imgalttext')]";
|
||||
}
|
||||
$csselementforactivitytype = "li.modtype_".strtolower($activitytype);
|
||||
|
||||
$xpathtocheck = "//img[contains(@alt, '$imgalttext')]";
|
||||
$this->execute("behat_general::should_exist_in_the",
|
||||
array($xpathtocheck, "xpath_element", $csselementforactivitytype, "css_element")
|
||||
);
|
||||
@@ -141,12 +142,13 @@ class behat_completion extends behat_base {
|
||||
public function activity_marked_as_not_complete($activityname, $activitytype, $completiontype) {
|
||||
if ($completiontype == "manual") {
|
||||
$imgalttext = get_string("completion-alt-manual-n", 'core_completion', $activityname);
|
||||
$xpathtocheck = "//input[@type='image'][contains(@alt, '$imgalttext')]";
|
||||
} else {
|
||||
$imgalttext = get_string("completion-alt-auto-n", 'core_completion', $activityname);
|
||||
$xpathtocheck = "//img[contains(@alt, '$imgalttext')]";
|
||||
}
|
||||
$csselementforactivitytype = "li.modtype_".strtolower($activitytype);
|
||||
|
||||
$xpathtocheck = "//img[contains(@alt, '$imgalttext')]";
|
||||
$this->execute("behat_general::should_exist_in_the",
|
||||
array($xpathtocheck, "xpath_element", $csselementforactivitytype, "css_element")
|
||||
);
|
||||
|
||||
@@ -25,15 +25,16 @@ Feature: Allow students to manually mark an activity as complete
|
||||
And I set the following fields to these values:
|
||||
| Enable completion tracking | Yes |
|
||||
And I press "Save and display"
|
||||
When I add a "Forum" to section "1" and I fill the form with:
|
||||
And I add a "Forum" to section "1" and I fill the form with:
|
||||
| Forum name | Test forum name |
|
||||
| Description | Test forum description |
|
||||
Then "Student First" user has not completed "Test forum name" activity
|
||||
And "Student First" user has not completed "Test forum name" activity
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I am on site homepage
|
||||
And I follow "Course 1"
|
||||
And I press "Mark as complete: Test forum name"
|
||||
When I press "Mark as complete: Test forum name"
|
||||
Then the "Test forum name" "forum" activity with "manual" completion should be marked as complete
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I am on site homepage
|
||||
|
||||
+1
-1
@@ -4,6 +4,6 @@
|
||||
"phpunit/dbUnit": "1.4.1",
|
||||
"sebastian/environment": "1.3.7",
|
||||
"sebastian/recursion-context": "1.0.2",
|
||||
"moodlehq/behat-extension": "3.31.5"
|
||||
"moodlehq/behat-extension": "3.31.6"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+137
-135
@@ -4,8 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "718062e279632fdee27a7d1af74bf0db",
|
||||
"content-hash": "795038882ba93b89ab58b678ce582f87",
|
||||
"content-hash": "be501c2af95e3e00762b8cf30d957b2b",
|
||||
"packages": [],
|
||||
"packages-dev": [
|
||||
{
|
||||
@@ -86,7 +85,7 @@
|
||||
"symfony",
|
||||
"testing"
|
||||
],
|
||||
"time": "2016-03-28 07:04:45"
|
||||
"time": "2016-03-28T07:04:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "behat/gherkin",
|
||||
@@ -145,7 +144,7 @@
|
||||
"gherkin",
|
||||
"parser"
|
||||
],
|
||||
"time": "2016-10-30 11:50:56"
|
||||
"time": "2016-10-30T11:50:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "behat/mink",
|
||||
@@ -203,7 +202,7 @@
|
||||
"testing",
|
||||
"web"
|
||||
],
|
||||
"time": "2016-03-05 08:26:18"
|
||||
"time": "2016-03-05T08:26:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "behat/mink-browserkit-driver",
|
||||
@@ -259,7 +258,7 @@
|
||||
"browser",
|
||||
"testing"
|
||||
],
|
||||
"time": "2016-03-05 08:59:47"
|
||||
"time": "2016-03-05T08:59:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "behat/mink-extension",
|
||||
@@ -318,7 +317,7 @@
|
||||
"test",
|
||||
"web"
|
||||
],
|
||||
"time": "2016-02-15 07:55:18"
|
||||
"time": "2016-02-15T07:55:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "behat/mink-goutte-driver",
|
||||
@@ -373,7 +372,7 @@
|
||||
"headless",
|
||||
"testing"
|
||||
],
|
||||
"time": "2016-03-05 09:04:22"
|
||||
"time": "2016-03-05T09:04:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "behat/mink-selenium2-driver",
|
||||
@@ -434,7 +433,7 @@
|
||||
"testing",
|
||||
"webdriver"
|
||||
],
|
||||
"time": "2016-03-05 09:10:18"
|
||||
"time": "2016-03-05T09:10:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "behat/transliterator",
|
||||
@@ -474,7 +473,7 @@
|
||||
"slug",
|
||||
"transliterator"
|
||||
],
|
||||
"time": "2015-09-28 16:26:35"
|
||||
"time": "2015-09-28T16:26:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
@@ -528,7 +527,7 @@
|
||||
"constructor",
|
||||
"instantiate"
|
||||
],
|
||||
"time": "2015-06-14 21:17:01"
|
||||
"time": "2015-06-14T21:17:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fabpot/goutte",
|
||||
@@ -577,7 +576,7 @@
|
||||
"keywords": [
|
||||
"scraper"
|
||||
],
|
||||
"time": "2015-05-05 21:14:57"
|
||||
"time": "2015-05-05T21:14:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
@@ -629,7 +628,7 @@
|
||||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"time": "2016-07-15 19:28:39"
|
||||
"time": "2016-07-15T19:28:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/ringphp",
|
||||
@@ -680,7 +679,7 @@
|
||||
}
|
||||
],
|
||||
"description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.",
|
||||
"time": "2015-05-20 03:37:09"
|
||||
"time": "2015-05-20T03:37:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/streams",
|
||||
@@ -730,7 +729,7 @@
|
||||
"Guzzle",
|
||||
"stream"
|
||||
],
|
||||
"time": "2014-10-12 19:18:40"
|
||||
"time": "2014-10-12T19:18:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "instaclick/php-webdriver",
|
||||
@@ -788,20 +787,20 @@
|
||||
"webdriver",
|
||||
"webtest"
|
||||
],
|
||||
"time": "2015-06-15 20:19:33"
|
||||
"time": "2015-06-15T20:19:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "moodlehq/behat-extension",
|
||||
"version": "v3.31.5",
|
||||
"version": "v3.31.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/moodlehq/moodle-behat-extension.git",
|
||||
"reference": "1f0393a5b3505e7e95c5708368ec7ea15e0910e0"
|
||||
"reference": "ae6be43e359fb36f825da1f248b727d7a46a94ed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/moodlehq/moodle-behat-extension/zipball/1f0393a5b3505e7e95c5708368ec7ea15e0910e0",
|
||||
"reference": "1f0393a5b3505e7e95c5708368ec7ea15e0910e0",
|
||||
"url": "https://api.github.com/repos/moodlehq/moodle-behat-extension/zipball/ae6be43e359fb36f825da1f248b727d7a46a94ed",
|
||||
"reference": "ae6be43e359fb36f825da1f248b727d7a46a94ed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -837,7 +836,7 @@
|
||||
"Behat",
|
||||
"moodle"
|
||||
],
|
||||
"time": "2016-11-10 23:37:45"
|
||||
"time": "2017-01-19T00:08:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-docblock",
|
||||
@@ -886,20 +885,20 @@
|
||||
"email": "mike.vanriel@naenius.com"
|
||||
}
|
||||
],
|
||||
"time": "2015-02-03 12:10:50"
|
||||
"time": "2015-02-03T12:10:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "v1.6.1",
|
||||
"version": "v1.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "58a8137754bc24b25740d4281399a4a3596058e0"
|
||||
"reference": "6c52c2722f8460122f96f86346600e1077ce22cb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0",
|
||||
"reference": "58a8137754bc24b25740d4281399a4a3596058e0",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb",
|
||||
"reference": "6c52c2722f8460122f96f86346600e1077ce22cb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -907,10 +906,11 @@
|
||||
"php": "^5.3|^7.0",
|
||||
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
|
||||
"sebastian/comparator": "^1.1",
|
||||
"sebastian/recursion-context": "^1.0"
|
||||
"sebastian/recursion-context": "^1.0|^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "^2.0"
|
||||
"phpspec/phpspec": "^2.0",
|
||||
"phpunit/phpunit": "^4.8 || ^5.6.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
@@ -948,7 +948,7 @@
|
||||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"time": "2016-06-07 08:13:47"
|
||||
"time": "2016-11-21T14:58:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/dbunit",
|
||||
@@ -1007,7 +1007,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-08-07 04:57:38"
|
||||
"time": "2015-08-07T04:57:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
@@ -1069,20 +1069,20 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-10-06 15:47:00"
|
||||
"time": "2015-10-06T15:47:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
"version": "1.4.1",
|
||||
"version": "1.4.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
||||
"reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
|
||||
"reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
|
||||
"reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
|
||||
"reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1116,7 +1116,7 @@
|
||||
"filesystem",
|
||||
"iterator"
|
||||
],
|
||||
"time": "2015-06-21 13:08:43"
|
||||
"time": "2016-10-03T07:40:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-text-template",
|
||||
@@ -1157,7 +1157,7 @@
|
||||
"keywords": [
|
||||
"template"
|
||||
],
|
||||
"time": "2015-06-21 13:50:34"
|
||||
"time": "2015-06-21T13:50:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-timer",
|
||||
@@ -1201,20 +1201,20 @@
|
||||
"keywords": [
|
||||
"timer"
|
||||
],
|
||||
"time": "2016-05-12 18:03:57"
|
||||
"time": "2016-05-12T18:03:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-token-stream",
|
||||
"version": "1.4.8",
|
||||
"version": "1.4.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
||||
"reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
|
||||
"reference": "3b402f65a4cc90abf6e1104e388b896ce209631b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
|
||||
"reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b",
|
||||
"reference": "3b402f65a4cc90abf6e1104e388b896ce209631b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1250,7 +1250,7 @@
|
||||
"keywords": [
|
||||
"tokenizer"
|
||||
],
|
||||
"time": "2015-09-15 10:49:45"
|
||||
"time": "2016-11-15T14:06:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
@@ -1322,7 +1322,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2016-07-21 06:48:14"
|
||||
"time": "2016-07-21T06:48:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit-mock-objects",
|
||||
@@ -1378,7 +1378,7 @@
|
||||
"mock",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-10-02 06:51:40"
|
||||
"time": "2015-10-02T06:51:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
@@ -1425,31 +1425,26 @@
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2016-10-10 12:19:37"
|
||||
"time": "2016-10-10T12:19:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/promise",
|
||||
"version": "v2.4.1",
|
||||
"version": "v2.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/promise.git",
|
||||
"reference": "8025426794f1944de806618671d4fa476dc7626f"
|
||||
"reference": "2760f3898b7e931aa71153852dcd48a75c9b95db"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/promise/zipball/8025426794f1944de806618671d4fa476dc7626f",
|
||||
"reference": "8025426794f1944de806618671d4fa476dc7626f",
|
||||
"url": "https://api.github.com/repos/reactphp/promise/zipball/2760f3898b7e931aa71153852dcd48a75c9b95db",
|
||||
"reference": "2760f3898b7e931aa71153852dcd48a75c9b95db",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\Promise\\": "src/"
|
||||
@@ -1469,26 +1464,30 @@
|
||||
}
|
||||
],
|
||||
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
|
||||
"time": "2016-05-03 17:50:52"
|
||||
"keywords": [
|
||||
"promise",
|
||||
"promises"
|
||||
],
|
||||
"time": "2016-12-22T14:09:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/comparator",
|
||||
"version": "1.2.0",
|
||||
"version": "1.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/comparator.git",
|
||||
"reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
|
||||
"reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
|
||||
"reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f",
|
||||
"reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"sebastian/diff": "~1.2",
|
||||
"sebastian/exporter": "~1.2"
|
||||
"sebastian/exporter": "~1.2 || ~2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.4"
|
||||
@@ -1533,7 +1532,7 @@
|
||||
"compare",
|
||||
"equality"
|
||||
],
|
||||
"time": "2015-07-26 15:48:44"
|
||||
"time": "2016-11-19T09:18:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/diff",
|
||||
@@ -1585,7 +1584,7 @@
|
||||
"keywords": [
|
||||
"diff"
|
||||
],
|
||||
"time": "2015-12-08 07:14:41"
|
||||
"time": "2015-12-08T07:14:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
@@ -1635,7 +1634,7 @@
|
||||
"environment",
|
||||
"hhvm"
|
||||
],
|
||||
"time": "2016-05-17 03:18:57"
|
||||
"time": "2016-05-17T03:18:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
@@ -1702,7 +1701,7 @@
|
||||
"export",
|
||||
"exporter"
|
||||
],
|
||||
"time": "2016-06-17 09:04:28"
|
||||
"time": "2016-06-17T09:04:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/global-state",
|
||||
@@ -1753,7 +1752,7 @@
|
||||
"keywords": [
|
||||
"global state"
|
||||
],
|
||||
"time": "2015-10-12 03:26:01"
|
||||
"time": "2015-10-12T03:26:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/recursion-context",
|
||||
@@ -1806,7 +1805,7 @@
|
||||
],
|
||||
"description": "Provides functionality to recursively process PHP variables",
|
||||
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
||||
"time": "2015-11-11 19:50:13"
|
||||
"time": "2015-11-11T19:50:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/version",
|
||||
@@ -1841,20 +1840,20 @@
|
||||
],
|
||||
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
|
||||
"homepage": "https://github.com/sebastianbergmann/version",
|
||||
"time": "2015-06-21 13:59:46"
|
||||
"time": "2015-06-21T13:59:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/browser-kit",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/browser-kit.git",
|
||||
"reference": "165bf6d1e72cd72f2fe170a070aa2a1f17f2d744"
|
||||
"reference": "d2a5de15c8341a470a66becf4597bc675686a72b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/165bf6d1e72cd72f2fe170a070aa2a1f17f2d744",
|
||||
"reference": "165bf6d1e72cd72f2fe170a070aa2a1f17f2d744",
|
||||
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/d2a5de15c8341a470a66becf4597bc675686a72b",
|
||||
"reference": "d2a5de15c8341a470a66becf4597bc675686a72b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1898,20 +1897,20 @@
|
||||
],
|
||||
"description": "Symfony BrowserKit Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-09-06 10:55:00"
|
||||
"time": "2017-01-02T20:30:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/class-loader",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/class-loader.git",
|
||||
"reference": "fb50892408036f9f431b563aac51a3f2f0087e81"
|
||||
"reference": "7c46951128f7169cbece2c303fba4a9eb35cbe68"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/class-loader/zipball/fb50892408036f9f431b563aac51a3f2f0087e81",
|
||||
"reference": "fb50892408036f9f431b563aac51a3f2f0087e81",
|
||||
"url": "https://api.github.com/repos/symfony/class-loader/zipball/7c46951128f7169cbece2c303fba4a9eb35cbe68",
|
||||
"reference": "7c46951128f7169cbece2c303fba4a9eb35cbe68",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1951,26 +1950,29 @@
|
||||
],
|
||||
"description": "Symfony ClassLoader Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-09-06 23:19:39"
|
||||
"time": "2017-01-10T14:03:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/config",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/config.git",
|
||||
"reference": "f8b1922bbda9d2ac86aecd649399040bce849fde"
|
||||
"reference": "4537f2413348fe271c2c4b09da219ed615d79f9c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/config/zipball/f8b1922bbda9d2ac86aecd649399040bce849fde",
|
||||
"reference": "f8b1922bbda9d2ac86aecd649399040bce849fde",
|
||||
"url": "https://api.github.com/repos/symfony/config/zipball/4537f2413348fe271c2c4b09da219ed615d79f9c",
|
||||
"reference": "4537f2413348fe271c2c4b09da219ed615d79f9c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.9",
|
||||
"symfony/filesystem": "~2.3|~3.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/yaml": "~2.7|~3.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/yaml": "To use the yaml reference dumper"
|
||||
},
|
||||
@@ -2004,20 +2006,20 @@
|
||||
],
|
||||
"description": "Symfony Config Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-09-14 20:31:12"
|
||||
"time": "2017-01-02T20:30:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "7350016c8abcab897046f1aead2b766b84d3eff8"
|
||||
"reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/7350016c8abcab897046f1aead2b766b84d3eff8",
|
||||
"reference": "7350016c8abcab897046f1aead2b766b84d3eff8",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/2e18b8903d9c498ba02e1dfa73f64d4894bb6912",
|
||||
"reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2065,20 +2067,20 @@
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-10-06 01:43:09"
|
||||
"time": "2017-01-08T20:43:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/css-selector.git",
|
||||
"reference": "71c8c3a04c126300c37089b1baa7c6322dfb845f"
|
||||
"reference": "f45daea42232d9ca5cf561ec64f0d4aea820877f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/71c8c3a04c126300c37089b1baa7c6322dfb845f",
|
||||
"reference": "71c8c3a04c126300c37089b1baa7c6322dfb845f",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/f45daea42232d9ca5cf561ec64f0d4aea820877f",
|
||||
"reference": "f45daea42232d9ca5cf561ec64f0d4aea820877f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2118,20 +2120,20 @@
|
||||
],
|
||||
"description": "Symfony CssSelector Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-09-06 10:55:00"
|
||||
"time": "2017-01-02T20:30:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/debug",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/debug.git",
|
||||
"reference": "8c29235936a47473af16fb91c7c4b7b193c5693c"
|
||||
"reference": "567681e2c4e5431704e884e4be25a95fd900770f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/8c29235936a47473af16fb91c7c4b7b193c5693c",
|
||||
"reference": "8c29235936a47473af16fb91c7c4b7b193c5693c",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/567681e2c4e5431704e884e4be25a95fd900770f",
|
||||
"reference": "567681e2c4e5431704e884e4be25a95fd900770f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2175,20 +2177,20 @@
|
||||
],
|
||||
"description": "Symfony Debug Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-09-06 10:55:00"
|
||||
"time": "2017-01-02T20:30:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dependency-injection",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dependency-injection.git",
|
||||
"reference": "3d61c765daa1a5832f1d7c767f48886b8d8ea64c"
|
||||
"reference": "b75356611675364607d697f314850d9d870a84aa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/3d61c765daa1a5832f1d7c767f48886b8d8ea64c",
|
||||
"reference": "3d61c765daa1a5832f1d7c767f48886b8d8ea64c",
|
||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b75356611675364607d697f314850d9d870a84aa",
|
||||
"reference": "b75356611675364607d697f314850d9d870a84aa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2238,20 +2240,20 @@
|
||||
],
|
||||
"description": "Symfony DependencyInjection Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-10-24 15:52:36"
|
||||
"time": "2017-01-10T14:27:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dom-crawler",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dom-crawler.git",
|
||||
"reference": "a94f3fe6f179d6453e5ed8188cf4bfdf933d85f4"
|
||||
"reference": "52cc211afa9458c0a54c478010a55f44892c1c02"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/a94f3fe6f179d6453e5ed8188cf4bfdf933d85f4",
|
||||
"reference": "a94f3fe6f179d6453e5ed8188cf4bfdf933d85f4",
|
||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/52cc211afa9458c0a54c478010a55f44892c1c02",
|
||||
"reference": "52cc211afa9458c0a54c478010a55f44892c1c02",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2294,20 +2296,20 @@
|
||||
],
|
||||
"description": "Symfony DomCrawler Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-10-18 15:35:45"
|
||||
"time": "2017-01-02T20:30:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934"
|
||||
"reference": "74877977f90fb9c3e46378d5764217c55f32df34"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
|
||||
"reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/74877977f90fb9c3e46378d5764217c55f32df34",
|
||||
"reference": "74877977f90fb9c3e46378d5764217c55f32df34",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2354,20 +2356,20 @@
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-10-13 01:43:15"
|
||||
"time": "2017-01-02T20:30:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "a3784111af9f95f102b6411548376e1ae7c93898"
|
||||
"reference": "5b77d49ab76e5b12743b359ef4b4a712e6f5360d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/a3784111af9f95f102b6411548376e1ae7c93898",
|
||||
"reference": "a3784111af9f95f102b6411548376e1ae7c93898",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/5b77d49ab76e5b12743b359ef4b4a712e6f5360d",
|
||||
"reference": "5b77d49ab76e5b12743b359ef4b4a712e6f5360d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2403,7 +2405,7 @@
|
||||
],
|
||||
"description": "Symfony Filesystem Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-10-18 04:28:30"
|
||||
"time": "2017-01-08T20:43:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-apcu",
|
||||
@@ -2456,7 +2458,7 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2016-11-14 01:06:16"
|
||||
"time": "2016-11-14T01:06:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
@@ -2515,20 +2517,20 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2016-11-14 01:06:16"
|
||||
"time": "2016-11-14T01:06:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f"
|
||||
"reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
|
||||
"reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/ebb3c2abe0940a703f08e0cbe373f62d97d40231",
|
||||
"reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2564,20 +2566,20 @@
|
||||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-09-29 14:03:54"
|
||||
"time": "2017-01-02T20:30:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "cca6ff892355876534b01a927f789bac9601c935"
|
||||
"reference": "b4ac4a393f6970cc157fba17be537380de396a86"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/cca6ff892355876534b01a927f789bac9601c935",
|
||||
"reference": "cca6ff892355876534b01a927f789bac9601c935",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/b4ac4a393f6970cc157fba17be537380de396a86",
|
||||
"reference": "b4ac4a393f6970cc157fba17be537380de396a86",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2628,20 +2630,20 @@
|
||||
],
|
||||
"description": "Symfony Translation Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-10-18 04:28:30"
|
||||
"time": "2017-01-02T20:30:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.8.13",
|
||||
"version": "v2.8.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "396784cd06b91f3db576f248f2402d547a077787"
|
||||
"reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/396784cd06b91f3db576f248f2402d547a077787",
|
||||
"reference": "396784cd06b91f3db576f248f2402d547a077787",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2",
|
||||
"reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2677,7 +2679,7 @@
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-10-21 20:59:10"
|
||||
"time": "2017-01-03T13:49:52+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
||||
@@ -59,6 +59,13 @@ $CFG->dboptions = array(
|
||||
'dbport' => '', // the TCP port number to use when connecting
|
||||
// to the server. keep empty string for the
|
||||
// default port
|
||||
'dbcollation' => 'utf8mb4_unicode_ci', // MySQL has partial and full UTF-8
|
||||
// support. If you wish to use partial UTF-8
|
||||
// (three bytes) then set this option to
|
||||
// 'utf8_unicode_ci', otherwise this option
|
||||
// can be removed for MySQL (by default it will
|
||||
// use 'utf8mb4_unicode_ci'. This option should
|
||||
// be removed for all other databases.
|
||||
);
|
||||
|
||||
|
||||
|
||||
@@ -774,6 +774,10 @@ M.course_dndupload = {
|
||||
resel.li.outerHTML = unescape(resel.li.outerHTML);
|
||||
}
|
||||
self.add_editing(result.elementid);
|
||||
// Fire the content updated event.
|
||||
require(['core/event', 'jquery'], function(event, $) {
|
||||
event.notifyFilterContentUpdated($(result.fullcontent));
|
||||
});
|
||||
} else {
|
||||
// Error - remove the dummy element
|
||||
resel.parent.removeChild(resel.li);
|
||||
|
||||
@@ -33,8 +33,7 @@ Feature: Browse course list and return back from enrolment page
|
||||
@javascript
|
||||
Scenario: A user can return to the previous page from enrolment page by clicking navigation links
|
||||
When I log in as "user2"
|
||||
And I follow "Preferences" in the user menu
|
||||
And I follow "Edit profile"
|
||||
And I open my profile in edit mode
|
||||
And I expand "Courses" node
|
||||
And I expand "Sample category" node
|
||||
And I follow "Course 1"
|
||||
|
||||
@@ -2016,7 +2016,7 @@ class core_course_courselib_testcase extends advanced_testcase {
|
||||
|
||||
// Create the course with sections.
|
||||
$course = $this->getDataGenerator()->create_course(array('numsections' => 10), array('createsections' => true));
|
||||
$sections = $DB->get_records('course_sections', array('course' => $course->id));
|
||||
$sections = $DB->get_records('course_sections', array('course' => $course->id), 'section');
|
||||
$coursecontext = context_course::instance($course->id);
|
||||
$section = array_pop($sections);
|
||||
course_delete_section($course, $section);
|
||||
|
||||
@@ -80,9 +80,10 @@ switch ($action) {
|
||||
} else {
|
||||
$useroptions['link'] = false;
|
||||
}
|
||||
$viewfullnames = has_capability('moodle/site:viewfullnames', $context);
|
||||
foreach ($outcome->response['users'] as &$user) {
|
||||
$user->picture = $OUTPUT->user_picture($user, $useroptions);
|
||||
$user->fullname = fullname($user);
|
||||
$user->fullname = fullname($user, $viewfullnames);
|
||||
$fieldvalues = array();
|
||||
foreach ($extrafields as $field) {
|
||||
$fieldvalues[] = s($user->{$field});
|
||||
|
||||
@@ -37,6 +37,7 @@ $context = context_course::instance($course->id, MUST_EXIST);
|
||||
require_login($course);
|
||||
$canenrol = has_capability('enrol/manual:enrol', $context);
|
||||
$canunenrol = has_capability('enrol/manual:unenrol', $context);
|
||||
$viewfullnames = has_capability('moodle/site:viewfullnames', $context);
|
||||
|
||||
// Note: manage capability not used here because it is used for editing
|
||||
// of existing enrolments which is not possible here.
|
||||
@@ -74,7 +75,9 @@ navigation_node::override_active_url(new moodle_url('/enrol/users.php', array('i
|
||||
$options = array('enrolid' => $enrolid, 'accesscontext' => $context);
|
||||
|
||||
$potentialuserselector = new enrol_manual_potential_participant('addselect', $options);
|
||||
$potentialuserselector->viewfullnames = $viewfullnames;
|
||||
$currentuserselector = new enrol_manual_current_participant('removeselect', $options);
|
||||
$currentuserselector->viewfullnames = $viewfullnames;
|
||||
|
||||
// Build the list of options for the enrolment period dropdown.
|
||||
$unlimitedperiod = get_string('unlimited');
|
||||
|
||||
@@ -236,6 +236,7 @@ class gradingform_guide_renderer extends plugin_renderer_base {
|
||||
$input = html_writer::tag('textarea', s($currentremark), $remarkparams);
|
||||
|
||||
// Show the frequently-used comments chooser only if there are defined entries.
|
||||
$commentchooser = '';
|
||||
if (!empty($comments)) {
|
||||
// Frequently used comments chooser.
|
||||
$chooserbuttonid = 'criteria-' . $criterion['id'] . '-commentchooser';
|
||||
|
||||
@@ -45,6 +45,13 @@ class grade_report_grader extends grade_report {
|
||||
*/
|
||||
private $allgrades;
|
||||
|
||||
/**
|
||||
* Contains all grade items expect GRADE_TYPE_NONE.
|
||||
*
|
||||
* @var array $allgradeitems
|
||||
*/
|
||||
private $allgradeitems;
|
||||
|
||||
/**
|
||||
* Array of errors for bulk grades updating.
|
||||
* @var array $gradeserror
|
||||
@@ -183,6 +190,7 @@ class grade_report_grader extends grade_report {
|
||||
array_unshift($mygroups, $this->currentgroup);
|
||||
}
|
||||
}
|
||||
$viewfullnames = has_capability('moodle/site:viewfullnames', $this->context);
|
||||
|
||||
// always initialize all arrays
|
||||
$queue = array();
|
||||
@@ -288,7 +296,7 @@ class grade_report_grader extends grade_report {
|
||||
$userfields = 'id, ' . get_all_user_name_fields(true);
|
||||
$user = $DB->get_record('user', array('id' => $userid), $userfields);
|
||||
$gradestr = new stdClass();
|
||||
$gradestr->username = fullname($user);
|
||||
$gradestr->username = fullname($user, $viewfullnames);
|
||||
$gradestr->itemname = $gradeitem->get_name();
|
||||
$warnings[] = get_string($errorstr, 'grades', $gradestr);
|
||||
if ($skip) {
|
||||
@@ -519,6 +527,22 @@ class grade_report_grader extends grade_report {
|
||||
return $this->users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all grade items.
|
||||
*/
|
||||
protected function get_allgradeitems() {
|
||||
if (!empty($this->allgradeitems)) {
|
||||
return $this->allgradeitems;
|
||||
}
|
||||
$allgradeitems = grade_item::fetch_all(array('courseid' => $this->courseid));
|
||||
// But hang on - don't include ones which are set to not show the grade at all.
|
||||
$this->allgradeitems = array_filter($allgradeitems, function($item) {
|
||||
return $item->gradetype != GRADE_TYPE_NONE;
|
||||
});
|
||||
|
||||
return $this->allgradeitems;
|
||||
}
|
||||
|
||||
/**
|
||||
* we supply the userids in this query, and get all the grades
|
||||
* pulls out all the grades, this does not need to worry about paging
|
||||
@@ -542,11 +566,16 @@ class grade_report_grader extends grade_report {
|
||||
WHERE g.itemid = gi.id AND gi.courseid = :courseid {$this->userselect}";
|
||||
|
||||
$userids = array_keys($this->users);
|
||||
$allgradeitems = $this->get_allgradeitems();
|
||||
|
||||
if ($grades = $DB->get_records_sql($sql, $params)) {
|
||||
foreach ($grades as $graderec) {
|
||||
$grade = new grade_grade($graderec, false);
|
||||
$this->allgrades[$graderec->userid][$graderec->itemid] = $grade;
|
||||
if (!empty($allgradeitems[$graderec->itemid])) {
|
||||
// Note: Filter out grades which have a grade type of GRADE_TYPE_NONE.
|
||||
// Only grades without this type are present in $allgradeitems.
|
||||
$this->allgrades[$graderec->userid][$graderec->itemid] = $grade;
|
||||
}
|
||||
if (in_array($graderec->userid, $userids) and array_key_exists($graderec->itemid, $this->gtree->get_items())) { // some items may not be present!!
|
||||
$this->grades[$graderec->userid][$graderec->itemid] = $grade;
|
||||
$this->grades[$graderec->userid][$graderec->itemid]->grade_item = $this->gtree->get_item($graderec->itemid); // db caching
|
||||
@@ -567,6 +596,18 @@ class grade_report_grader extends grade_report {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pre fill grades for any remaining items which might be collapsed.
|
||||
foreach ($userids as $userid) {
|
||||
foreach ($allgradeitems as $itemid => $gradeitem) {
|
||||
if (!isset($this->allgrades[$userid][$itemid])) {
|
||||
$this->allgrades[$userid][$itemid] = new grade_grade();
|
||||
$this->allgrades[$userid][$itemid]->itemid = $itemid;
|
||||
$this->allgrades[$userid][$itemid]->userid = $userid;
|
||||
$this->allgrades[$userid][$itemid]->grade_item = $gradeitem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -611,6 +652,7 @@ class grade_report_grader extends grade_report {
|
||||
'moodle/grade:edit'), $this->context);
|
||||
}
|
||||
$hasuserreportcell = $canseeuserreport || $canseesingleview;
|
||||
$viewfullnames = has_capability('moodle/site:viewfullnames', $this->context);
|
||||
|
||||
$strfeedback = $this->get_lang_string("feedback");
|
||||
$strgrade = $this->get_lang_string('grade');
|
||||
@@ -682,7 +724,7 @@ class grade_report_grader extends grade_report {
|
||||
$usercell->text = $OUTPUT->user_picture($user, array('visibletoscreenreaders' => false));
|
||||
}
|
||||
|
||||
$fullname = fullname($user);
|
||||
$fullname = fullname($user, $viewfullnames);
|
||||
$usercell->text .= html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $this->course->id)), $fullname, array(
|
||||
'class' => 'username',
|
||||
));
|
||||
@@ -781,6 +823,8 @@ class grade_report_grader extends grade_report {
|
||||
$strexcludedgrades = get_string('excluded', 'grades');
|
||||
$strerror = get_string('error');
|
||||
|
||||
$viewfullnames = has_capability('moodle/site:viewfullnames', $this->context);
|
||||
|
||||
foreach ($this->gtree->get_levels() as $key => $row) {
|
||||
$headingrow = new html_table_row();
|
||||
$headingrow->attributes['class'] = 'heading_name_row';
|
||||
@@ -918,7 +962,7 @@ class grade_report_grader extends grade_report {
|
||||
// grade items (in case one has been hidden) as the course total shown needs to be adjusted for this particular
|
||||
// user.
|
||||
if (!$this->canviewhidden) {
|
||||
$allgradeitems = grade_item::fetch_all(array('courseid' => $this->courseid));
|
||||
$allgradeitems = $this->get_allgradeitems();
|
||||
}
|
||||
|
||||
foreach ($this->users as $userid => $user) {
|
||||
@@ -937,7 +981,7 @@ class grade_report_grader extends grade_report {
|
||||
$itemrow = new html_table_row();
|
||||
$itemrow->id = 'user_'.$userid;
|
||||
|
||||
$fullname = fullname($user);
|
||||
$fullname = fullname($user, $viewfullnames);
|
||||
$jsarguments['users'][$userid] = $fullname;
|
||||
|
||||
foreach ($this->gtree->items as $itemid => $unused) {
|
||||
@@ -1729,7 +1773,7 @@ class grade_report_grader extends grade_report {
|
||||
|
||||
// Try looking for old location of user setting that used to store all courses in one serialized user preference.
|
||||
if (($oldcollapsedpref = get_user_preferences('grade_report_grader_collapsed_categories')) !== null) {
|
||||
if ($collapsedall = @unserialize($oldcollapsedpref)) {
|
||||
if ($collapsedall = unserialize_array($oldcollapsedpref)) {
|
||||
// We found the old-style preference, filter out only categories that belong to this course and update the prefs.
|
||||
$collapsed = static::filter_collapsed_categories($courseid, $collapsedall);
|
||||
if (!empty($collapsed['aggregatesonly']) || !empty($collapsed['gradesonly'])) {
|
||||
|
||||
@@ -12,6 +12,7 @@ Feature: We can change what we are viewing on the grader report
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
| student1 | Student | 1 | student1@example.com |
|
||||
| student2 | Student | 1 | student2@example.com |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
@@ -95,6 +96,9 @@ Feature: We can change what we are viewing on the grader report
|
||||
| capability | permission |
|
||||
| moodle/grade:viewhidden | Prevent |
|
||||
And I log out
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student2 | C1 | student |
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Grades" node in "Course administration"
|
||||
|
||||
@@ -29,9 +29,16 @@ require_once $CFG->dirroot.'/grade/report/user/lib.php';
|
||||
|
||||
$courseid = required_param('id', PARAM_INT);
|
||||
$userid = optional_param('userid', $USER->id, PARAM_INT);
|
||||
$userview = optional_param('userview', 0, PARAM_INT);
|
||||
|
||||
$PAGE->set_url(new moodle_url('/grade/report/user/index.php', array('id'=>$courseid)));
|
||||
|
||||
if ($userview == 0) {
|
||||
$userview = get_user_preferences('gradereport_user_view_user', GRADE_REPORT_USER_VIEW_USER);
|
||||
} else {
|
||||
set_user_preference('gradereport_user_view_user', $userview);
|
||||
}
|
||||
|
||||
/// basic access checks
|
||||
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
|
||||
print_error('nocourseid');
|
||||
@@ -103,6 +110,15 @@ if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all
|
||||
$defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol);
|
||||
$showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
|
||||
$showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $context);
|
||||
|
||||
$renderer = $PAGE->get_renderer('gradereport_user');
|
||||
|
||||
if ($userview == GRADE_REPORT_USER_VIEW_USER) {
|
||||
$viewasuser = true;
|
||||
} else {
|
||||
$viewasuser = false;
|
||||
}
|
||||
|
||||
if (empty($userid)) {
|
||||
$gui = new graded_users_iterator($course, null, $currentgroup);
|
||||
$gui->require_active_enrolment($showonlyactiveenrol);
|
||||
@@ -112,13 +128,14 @@ if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all
|
||||
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, array('userid'=>0)));
|
||||
|
||||
if ($user_selector) {
|
||||
$renderer = $PAGE->get_renderer('gradereport_user');
|
||||
echo $renderer->graded_users_selector('user', $course, $userid, $currentgroup, true);
|
||||
}
|
||||
|
||||
echo $renderer->view_user_selector($userid, $userview);
|
||||
|
||||
while ($userdata = $gui->next_user()) {
|
||||
$user = $userdata->user;
|
||||
$report = new grade_report_user($courseid, $gpr, $context, $user->id);
|
||||
$report = new grade_report_user($courseid, $gpr, $context, $user->id, $viewasuser);
|
||||
|
||||
$studentnamelink = html_writer::link(new moodle_url('/user/view.php', array('id' => $report->user->id, 'course' => $courseid)), fullname($report->user));
|
||||
echo $OUTPUT->heading(get_string('pluginname', 'gradereport_user') . ' - ' . $studentnamelink);
|
||||
@@ -130,7 +147,7 @@ if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all
|
||||
}
|
||||
$gui->close();
|
||||
} else { // Only show one user's report
|
||||
$report = new grade_report_user($courseid, $gpr, $context, $userid);
|
||||
$report = new grade_report_user($courseid, $gpr, $context, $userid, $viewasuser);
|
||||
|
||||
$studentnamelink = html_writer::link(new moodle_url('/user/view.php', array('id' => $report->user->id, 'course' => $courseid)), fullname($report->user));
|
||||
print_grade_page_head($courseid, 'report', 'user', get_string('pluginname', 'gradereport_user') . ' - ' . $studentnamelink,
|
||||
@@ -139,11 +156,12 @@ if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all
|
||||
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, array('userid'=>0)));
|
||||
|
||||
if ($user_selector) {
|
||||
$renderer = $PAGE->get_renderer('gradereport_user');
|
||||
$showallusersoptions = true;
|
||||
echo $renderer->graded_users_selector('user', $course, $userid, $currentgroup, $showallusersoptions);
|
||||
}
|
||||
|
||||
echo $renderer->view_user_selector($userid, $userview);
|
||||
|
||||
if ($currentgroup and !groups_is_member($currentgroup, $userid)) {
|
||||
echo $OUTPUT->notification(get_string('groupusernotmember', 'error'));
|
||||
} else {
|
||||
|
||||
@@ -25,4 +25,7 @@
|
||||
$string['eventgradereportviewed'] = 'Grade user report viewed';
|
||||
$string['pluginname'] = 'User report';
|
||||
$string['user:view'] = 'View your own grade report';
|
||||
$string['myself'] = 'Myself';
|
||||
$string['otheruser'] = 'User';
|
||||
$string['tablesummary'] = 'The table is arranged as a list of graded items including categories of graded items. When items are in a category they will be indicated as such.';
|
||||
$string['viewas'] = 'View report as';
|
||||
|
||||
@@ -30,6 +30,9 @@ define("GRADE_REPORT_USER_HIDE_HIDDEN", 0);
|
||||
define("GRADE_REPORT_USER_HIDE_UNTIL", 1);
|
||||
define("GRADE_REPORT_USER_SHOW_HIDDEN", 2);
|
||||
|
||||
define("GRADE_REPORT_USER_VIEW_SELF", 1);
|
||||
define("GRADE_REPORT_USER_VIEW_USER", 2);
|
||||
|
||||
/**
|
||||
* Class providing an API for the user report building and displaying.
|
||||
* @uses grade_report
|
||||
|
||||
@@ -43,4 +43,29 @@ class gradereport_user_renderer extends plugin_renderer_base {
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and renders the single select box for the user view.
|
||||
*
|
||||
* @param int $userid The selected userid
|
||||
* @param int $userview The current view user setting constant
|
||||
* @return string
|
||||
*/
|
||||
public function view_user_selector($userid, $userview) {
|
||||
global $PAGE, $USER;
|
||||
$url = $PAGE->url;
|
||||
if ($userid != $USER->id) {
|
||||
$url->param('userid', $userid);
|
||||
}
|
||||
|
||||
$options = array(GRADE_REPORT_USER_VIEW_USER => get_string('otheruser', 'gradereport_user'),
|
||||
GRADE_REPORT_USER_VIEW_SELF => get_string('myself', 'gradereport_user'));
|
||||
$select = new single_select($url, 'userview', $options, $userview, null);
|
||||
|
||||
$select->label = get_string('viewas', 'gradereport_user');
|
||||
|
||||
$output = html_writer::tag('div', $this->output->render($select), array('class' => 'view_users_selector'));
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,15 @@
|
||||
float: right;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.path-grade-report-user #graded_users_selector .singleselect label {
|
||||
|
||||
.path-grade-report-user .view_users_selector {
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.path-grade-report-user #graded_users_selector .singleselect label,
|
||||
.path-grade-report-user .view_users_selector .singleselect label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
@core @core_grades @gradereport_user
|
||||
Feature: View the user report as the student will see it
|
||||
In order to know what grades students will see
|
||||
As a teacher
|
||||
I need to be able to view the user report as that other user
|
||||
|
||||
Background:
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | category | groupmode |
|
||||
| Course 1 | C1 | 0 | 1 |
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email | idnumber |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com | t1 |
|
||||
| student1 | Student | 1 | student1@example.com | s1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And the following "grade categories" exist:
|
||||
| fullname | course |
|
||||
| Sub category 1 | C1 |
|
||||
| Sub category 2 | C1 |
|
||||
And the following "activities" exist:
|
||||
| activity | course | idnumber | name | intro | gradecategory| grade |
|
||||
| assign | C1 | a1 | Test assignment one | Submit something! | Sub category 1 | 100 |
|
||||
| assign | C1 | a2 | Test assignment two | Submit something! | Sub category 1 | 100 |
|
||||
| assign | C1 | a3 | Test assignment three | Submit something! | Sub category 2 | 100 |
|
||||
| assign | C1 | a4 | Test assignment four | Submit something! | Sub category 2 | 100 |
|
||||
And the following "activities" exist:
|
||||
| activity | course | idnumber | name | intro | grade |
|
||||
| assign | C1 | a5 | Test assignment five | Submit something! | 100 |
|
||||
| assign | C1 | a6 | Test assignment six | Submit something! | 100 |
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Gradebook setup" node in "Course administration"
|
||||
And I hide the grade item "Test assignment six"
|
||||
And I hide the grade item "Sub category 2"
|
||||
And I navigate to "Grades" node in "Course administration"
|
||||
And I turn editing mode on
|
||||
And I change window size to "large"
|
||||
And I give the grade "80.00" to the user "Student 1" for the grade item "Test assignment one"
|
||||
And I give the grade "35.00" to the user "Student 1" for the grade item "Test assignment two"
|
||||
And I give the grade "100.00" to the user "Student 1" for the grade item "Test assignment three"
|
||||
And I give the grade "50.00" to the user "Student 1" for the grade item "Test assignment four"
|
||||
And I give the grade "21.00" to the user "Student 1" for the grade item "Test assignment five"
|
||||
And I give the grade "97.00" to the user "Student 1" for the grade item "Test assignment six"
|
||||
And I press "Save changes"
|
||||
And I change window size to "medium"
|
||||
|
||||
Scenario: View the report as the teacher themselves
|
||||
When I navigate to "User report" node in "Grade administration"
|
||||
And I select "Student 1" from the "Select all or one user" singleselect
|
||||
And I select "Myself" from the "View report as" singleselect
|
||||
Then the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
|
||||
| Test assignment one | 50.00 % | 80.00 | 0–100 | 80.00 % | 13.33 % |
|
||||
| Test assignment two | 50.00 % | 35.00 | 0–100 | 35.00 % | 5.83 % |
|
||||
| Sub category 1 total | 33.33 % | 115.00 | 0–200 | 57.50 % | - |
|
||||
| Test assignment three | 50.00 % | 100.00 | 0–100 | 100.00 % | 16.67 % |
|
||||
| Test assignment four | 50.00 % | 50.00 | 0–100 | 50.00 % | 8.33 % |
|
||||
| Sub category 2 total | 33.33 % | 150.00 | 0–200 | 75.00 % | - |
|
||||
| Test assignment five | 16.67 % | 21.00 | 0–100 | 21.00 % | 3.50 % |
|
||||
| Test assignment six | 16.67 % | 97.00 | 0–100 | 97.00 % | 16.17 % |
|
||||
| Course total | - | 383.00 | 0–600 | 63.83 % | - |
|
||||
|
||||
Scenario: View the report as the student from both the teachers and students perspective
|
||||
When I navigate to "User report" node in "Grade administration"
|
||||
And I select "Student 1" from the "Select all or one user" singleselect
|
||||
And I select "User" from the "View report as" singleselect
|
||||
Then the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
|
||||
| Test assignment one | - | 80.00 | 0–100 | 80.00 % | - |
|
||||
| Test assignment two | - | 35.00 | 0–100 | 35.00 % | - |
|
||||
| Sub category 1 total | 33.33 % | - | 0–200 | - | - |
|
||||
| Test assignment five | - | 21.00 | 0–100 | 21.00 % | - |
|
||||
| Course total | - | - | 0–600 | - | - |
|
||||
And the following should not exist in the "user-grade" table:
|
||||
| Grade item |
|
||||
| Test assignment three |
|
||||
| Test assignment four |
|
||||
| Sub category 2 total |
|
||||
| Test assignment six |
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Grades" node in "Course administration"
|
||||
Then the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
|
||||
| Test assignment one | - | 80.00 | 0–100 | 80.00 % | - |
|
||||
| Test assignment two | - | 35.00 | 0–100 | 35.00 % | - |
|
||||
| Sub category 1 total | 33.33 % | - | 0–200 | - | - |
|
||||
| Test assignment five | - | 21.00 | 0–100 | 21.00 % | - |
|
||||
| Course total | - | - | 0–600 | - | - |
|
||||
And the following should not exist in the "user-grade" table:
|
||||
| Grade item |
|
||||
| Test assignment three |
|
||||
| Test assignment four |
|
||||
| Sub category 2 total |
|
||||
| Test assignment six |
|
||||
|
||||
Scenario: View the report as the student from both the teachers and students perspective with totals excluding hidden
|
||||
Given I navigate to "Course grade settings" node in "Grade administration > Setup"
|
||||
And I set the field with xpath "//select[@name='report_user_showtotalsifcontainhidden']" to "Show totals excluding hidden items"
|
||||
And I press "Save changes"
|
||||
And I navigate to "User report" node in "Grade administration"
|
||||
When I select "Student 1" from the "Select all or one user" singleselect
|
||||
And I select "User" from the "View report as" singleselect
|
||||
Then the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
|
||||
| Test assignment one | 50.00 % | 80.00 | 0–100 | 80.00 % | 26.67 % |
|
||||
| Test assignment two | 50.00 % | 35.00 | 0–100 | 35.00 % | 11.67 % |
|
||||
| Sub category 1 total | 66.67 % | 115.00 | 0–200 | 57.50 | - |
|
||||
| Test assignment five | 33.33 % | 21.00 | 0–100 | 21.00 % | 7.00 % |
|
||||
| Course total | - | 136.00 | 0–300 | 45.33 % | - |
|
||||
And the following should not exist in the "user-grade" table:
|
||||
| Grade item |
|
||||
| Test assignment three |
|
||||
| Test assignment four |
|
||||
| Sub category 2 total |
|
||||
| Test assignment six |
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Grades" node in "Course administration"
|
||||
Then the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
|
||||
| Test assignment one | 50.00 % | 80.00 | 0–100 | 80.00 % | 26.67 % |
|
||||
| Test assignment two | 50.00 % | 35.00 | 0–100 | 35.00 % | 11.67 % |
|
||||
| Sub category 1 total | 66.67 % | 115.00 | 0–200 | 57.50 | - |
|
||||
| Test assignment five | 33.33 % | 21.00 | 0–100 | 21.00 % | 7.00 % |
|
||||
| Course total | - | 136.00 | 0–300 | 45.33 % | - |
|
||||
And the following should not exist in the "user-grade" table:
|
||||
| Grade item |
|
||||
| Test assignment three |
|
||||
| Test assignment four |
|
||||
| Sub category 2 total |
|
||||
| Test assignment six |
|
||||
|
||||
Scenario: View the report as the student from both the teachers and students perspective with totals including hidden
|
||||
Given I navigate to "Course grade settings" node in "Grade administration > Setup"
|
||||
And I set the field with xpath "//select[@name='report_user_showtotalsifcontainhidden']" to "Show totals including hidden items"
|
||||
And I press "Save changes"
|
||||
And I navigate to "User report" node in "Grade administration"
|
||||
When I select "Student 1" from the "Select all or one user" singleselect
|
||||
And I select "User" from the "View report as" singleselect
|
||||
Then the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
|
||||
| Test assignment one | 50.00 % | 80.00 | 0–100 | 80.00 % | 13.33 % |
|
||||
| Test assignment two | 50.00 % | 35.00 | 0–100 | 35.00 % | 5.83 % |
|
||||
| Sub category 1 total | 33.33 % | 115.00 | 0–200 | 57.50 % | - |
|
||||
| Test assignment five | 16.67 % | 21.00 | 0–100 | 21.00 % | 3.50 % |
|
||||
| Course total | - | 383.00 | 0–600 | 63.83 % | - |
|
||||
And the following should not exist in the "user-grade" table:
|
||||
| Grade item |
|
||||
| Test assignment three |
|
||||
| Test assignment four |
|
||||
| Sub category 2 total |
|
||||
| Test assignment six |
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Grades" node in "Course administration"
|
||||
Then the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
|
||||
| Test assignment one | 50.00 % | 80.00 | 0–100 | 80.00 % | 13.33 % |
|
||||
| Test assignment two | 50.00 % | 35.00 | 0–100 | 35.00 % | 5.83 % |
|
||||
| Sub category 1 total | 33.33 % | 115.00 | 0–200 | 57.50 % | - |
|
||||
| Test assignment five | 16.67 % | 21.00 | 0–100 | 21.00 % | 3.50 % |
|
||||
| Course total | - | 383.00 | 0–600 | 63.83 % | - |
|
||||
And the following should not exist in the "user-grade" table:
|
||||
| Grade item |
|
||||
| Test assignment three |
|
||||
| Test assignment four |
|
||||
| Sub category 2 total |
|
||||
| Test assignment six |
|
||||
|
||||
Scenario: View the report as the student from both the teachers and students perspective when the student can view hidden
|
||||
Given I log out
|
||||
And I log in as "admin"
|
||||
And I set the following system permissions of "Student" role:
|
||||
| capability | permission |
|
||||
| moodle/grade:viewhidden | Allow |
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Gradebook setup" node in "Course administration"
|
||||
And I navigate to "Course grade settings" node in "Grade administration > Setup"
|
||||
And I set the field with xpath "//select[@name='report_user_showtotalsifcontainhidden']" to "Show totals excluding hidden items"
|
||||
And I press "Save changes"
|
||||
And I navigate to "User report" node in "Grade administration"
|
||||
When I select "Student 1" from the "Select all or one user" singleselect
|
||||
And I select "User" from the "View report as" singleselect
|
||||
Then the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
|
||||
| Test assignment one | 50.00 % | 80.00 | 0–100 | 80.00 % | 13.33 % |
|
||||
| Test assignment two | 50.00 % | 35.00 | 0–100 | 35.00 % | 5.83 % |
|
||||
| Sub category 1 total | 33.33 % | 115.00 | 0–200 | 57.50 % | - |
|
||||
| Test assignment three | 50.00 % | 100.00 | 0–100 | 100.00 % | 16.67 % |
|
||||
| Test assignment four | 50.00 % | 50.00 | 0–100 | 50.00 % | 8.33 % |
|
||||
| Sub category 2 total | 33.33 % | 150.00 | 0–200 | 75.00 % | - |
|
||||
| Test assignment five | 16.67 % | 21.00 | 0–100 | 21.00 % | 3.50 % |
|
||||
| Test assignment six | 16.67 % | 97.00 | 0–100 | 97.00 % | 16.17 % |
|
||||
| Course total | - | 383.00 | 0–600 | 63.83 % | - |
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Grades" node in "Course administration"
|
||||
Then the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
|
||||
| Test assignment one | 50.00 % | 80.00 | 0–100 | 80.00 % | 13.33 % |
|
||||
| Test assignment two | 50.00 % | 35.00 | 0–100 | 35.00 % | 5.83 % |
|
||||
| Sub category 1 total | 33.33 % | 115.00 | 0–200 | 57.50 % | - |
|
||||
| Test assignment three | 50.00 % | 100.00 | 0–100 | 100.00 % | 16.67 % |
|
||||
| Test assignment four | 50.00 % | 50.00 | 0–100 | 50.00 % | 8.33 % |
|
||||
| Sub category 2 total | 33.33 % | 150.00 | 0–200 | 75.00 % | - |
|
||||
| Test assignment five | 16.67 % | 21.00 | 0–100 | 21.00 % | 3.50 % |
|
||||
| Test assignment six | 16.67 % | 97.00 | 0–100 | 97.00 % | 16.17 % |
|
||||
| Course total | - | 383.00 | 0–600 | 63.83 % | - |
|
||||
@@ -91,6 +91,31 @@ class behat_grade extends behat_base {
|
||||
$this->execute('behat_forms::press_button', $this->escape($savechanges));
|
||||
}
|
||||
|
||||
/**
|
||||
* Hids a grade item or category.
|
||||
*
|
||||
* Teacher must be either on the grade setup page or on the Grader report page with editing mode turned on.
|
||||
*
|
||||
* @Given /^I hide the grade item "(?P<grade_item_string>(?:[^"]|\\")*)"$/
|
||||
* @param string $gradeitem
|
||||
*/
|
||||
public function i_hide_the_grade_item($gradeitem) {
|
||||
|
||||
$gradeitem = behat_context_helper::escape($gradeitem);
|
||||
|
||||
if ($this->running_javascript()) {
|
||||
$xpath = "//tr[contains(.,$gradeitem)]//*[contains(@class,'moodle-actionmenu')]//a[contains(@class,'toggle-display')]";
|
||||
if ($this->getSession()->getPage()->findAll('xpath', $xpath)) {
|
||||
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
|
||||
}
|
||||
}
|
||||
|
||||
$hide = behat_context_helper::escape(get_string('hide') . ' ');
|
||||
$linkxpath = "//a[./img[starts-with(@title,$hide) and contains(@title,$gradeitem)]]";
|
||||
|
||||
$this->execute("behat_general::i_click_on", array($this->escape($linkxpath), "xpath_element"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a calculated manual grade item. Needs a table with item name - idnumber relation.
|
||||
* The step requires you to be in the 'Gradebook setup' page.
|
||||
|
||||
@@ -345,6 +345,7 @@ Feature: We can use calculated grade totals
|
||||
And I set the field "Show weightings" to "Show"
|
||||
And I press "Save changes"
|
||||
And I select "User report" from the "Grade report" singleselect
|
||||
And I select "Myself" from the "View report as" singleselect
|
||||
And I select "Student 1" from the "Select all or one user" singleselect
|
||||
And the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Range | Contribution to course total |
|
||||
@@ -534,6 +535,7 @@ Feature: We can use calculated grade totals
|
||||
And I press "Save changes"
|
||||
Then I should see "75.00 (16.85 %)" in the ".course" "css_element"
|
||||
And I select "User report" from the "Grade report" singleselect
|
||||
And I select "Myself" from the "View report as" singleselect
|
||||
And I select "Student 1" from the "Select all or one user" singleselect
|
||||
And the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Contribution to course total |
|
||||
|
||||
@@ -46,6 +46,7 @@ Feature: Student and teacher's view of aggregated grade items is consistent when
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Grades" node in "Course administration"
|
||||
And I select "User report" from the "Grade report" singleselect
|
||||
And I select "Myself" from the "View report as" singleselect
|
||||
And I select "Student 1" from the "Select all or one user" singleselect
|
||||
Then the following should exist in the "user-grade" table:
|
||||
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
|
||||
|
||||
@@ -230,6 +230,74 @@ class core_grade_report_graderlib_testcase extends advanced_testcase {
|
||||
$this->assertEquals(count($toobigvalue['gradesonly']) - 1, count($report1->collapsed['gradesonly']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the get_right_rows function with one 'normal' and one 'ungraded' quiz.
|
||||
*
|
||||
* Previously, with an ungraded quiz (which results in a grade item with type GRADETYPE_NONE)
|
||||
* there was a bug in get_right_rows in some situations.
|
||||
*/
|
||||
public function test_get_right_rows() {
|
||||
global $USER, $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Create manager and student on a course.
|
||||
$generator = $this->getDataGenerator();
|
||||
$manager = $generator->create_user();
|
||||
$student = $generator->create_user();
|
||||
$course = $generator->create_course();
|
||||
$generator->enrol_user($manager->id, $course->id, 'manager');
|
||||
$generator->enrol_user($student->id, $course->id, 'student');
|
||||
|
||||
// Create a couple of quizzes on the course.
|
||||
$normalquiz = $generator->create_module('quiz', array('course' => $course->id,
|
||||
'name' => 'NormalQuiz'));
|
||||
$ungradedquiz = $generator->create_module('quiz', array('course' => $course->id,
|
||||
'name' => 'UngradedQuiz'));
|
||||
|
||||
// Set the grade for the second one to 0 (note, you have to do this after creating it,
|
||||
// otherwise it doesn't create an ungraded grade item).
|
||||
$ungradedquiz->instance = $ungradedquiz->id;
|
||||
quiz_set_grade(0, $ungradedquiz);
|
||||
|
||||
// Set current user.
|
||||
$this->setUser($manager);
|
||||
$USER->gradeediting[$course->id] = false;
|
||||
|
||||
// Get the report.
|
||||
$report = $this->create_report($course);
|
||||
$report->load_users();
|
||||
$report->load_final_grades();
|
||||
$result = $report->get_right_rows(false);
|
||||
|
||||
// There should be 3 rows (2 header rows, plus the grades for the first user).
|
||||
$this->assertCount(3, $result);
|
||||
|
||||
// The second row should contain 2 cells - one for the graded quiz and course total.
|
||||
$this->assertCount(2, $result[1]->cells);
|
||||
$this->assertContains('NormalQuiz', $result[1]->cells[0]->text);
|
||||
$this->assertContains('Course total', $result[1]->cells[1]->text);
|
||||
|
||||
// User row should contain grade values '-'.
|
||||
$this->assertCount(2, $result[2]->cells);
|
||||
$this->assertContains('>-<', $result[2]->cells[0]->text);
|
||||
$this->assertContains('>-<', $result[2]->cells[1]->text);
|
||||
|
||||
// Supposing the user cannot view hidden grades, this shouldn't make any difference (due
|
||||
// to a bug, it previously did).
|
||||
$context = context_course::instance($course->id);
|
||||
$managerroleid = $DB->get_field('role', 'id', array('shortname' => 'manager'));
|
||||
assign_capability('moodle/grade:viewhidden', CAP_PROHIBIT, $managerroleid, $context->id, true);
|
||||
$context->mark_dirty();
|
||||
$this->assertFalse(has_capability('moodle/grade:viewhidden', $context));
|
||||
|
||||
// Recreate the report. Confirm it returns successfully still.
|
||||
$report = $this->create_report($course);
|
||||
$report->load_users();
|
||||
$report->load_final_grades();
|
||||
$result = $report->get_right_rows(false);
|
||||
$this->assertCount(3, $result);
|
||||
}
|
||||
|
||||
private function create_grade_category($course) {
|
||||
static $cnt = 0;
|
||||
$cnt++;
|
||||
|
||||
@@ -42,3 +42,4 @@ $string['cliunknowoption'] = 'অচেনা অপশন:
|
||||
$string['cliyesnoprompt'] = 'y (মানে হ্যাঁ) বা n (মানে না) টাইপ করুন';
|
||||
$string['environmentrequireinstall'] = 'অবশ্যই ইনস্টল ও সক্রিয় করতে হবে';
|
||||
$string['environmentrequireversion'] = '{$a->needed} সংস্করণ আবশ্যক এবং আপনি {$a->current} চালাচ্ছেন';
|
||||
$string['upgradekeyset'] = 'আপগ্রেড কুঞ্জিকা (এটি সেট না করতে খালি রাখুন)';
|
||||
|
||||
@@ -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'] = 'Èʋegbe';
|
||||
@@ -90,10 +90,9 @@ $string['pathsunsecuredataroot'] = 'Dataroot location is not secure';
|
||||
$string['pathswrongadmindir'] = 'Admin directory does not exist';
|
||||
$string['phpextension'] = '{$a} PHP extension';
|
||||
$string['phpversion'] = 'PHP version';
|
||||
$string['phpversionhelp'] = '<p>Moodle requires a PHP version of at least 4.3.0 or 5.1.0 (5.0.x has a number of known problems).</p>
|
||||
<p>You are currently running version {$a}</p>
|
||||
<p>You must upgrade PHP or move to a host with a newer version of PHP!<br />
|
||||
(In case of 5.0.x you could also downgrade to 4.4.x version)</p>';
|
||||
$string['phpversionhelp'] = '<p>Moodle requires a PHP version of at least 5.4.4 (7.x has some engine limitations).</p>
|
||||
<p>You are currently running version {$a}.</p>
|
||||
<p>You must upgrade PHP or move to a host with a newer version of PHP.</p>';
|
||||
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
|
||||
$string['welcomep20'] = 'You are seeing this page because you have successfully installed and
|
||||
launched the <strong>{$a->packname} {$a->packversion}</strong> package in your computer. Congratulations!';
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Automatically generated strings for Moodle installer
|
||||
*
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['thisdirection'] = 'ltr';
|
||||
$string['thislanguage'] = 'English US - K12';
|
||||
@@ -44,8 +44,8 @@ $string['dmlexceptiononinstall'] = '<p>Ocurrió un error en la BasedeDatos[{$a->
|
||||
$string['downloadedfilecheckfailed'] = 'Ha fallado la comprobación del archivo descargado';
|
||||
$string['invalidmd5'] = 'La variable de verificación MD5 es incorrecta no es valida - trate nuevamente';
|
||||
$string['missingrequiredfield'] = 'Falta algún campo necesario';
|
||||
$string['remotedownloaderror'] = '<p>Falló la descarga del componente a su servidor. Se recomienda ampliamente verificar los ajustes del proxy, extensión PHP cURL.</p>
|
||||
<p>Debe descargar el<a href="{$a->url}">{$a->url}</a> archivo manualmente, copiarlo en "{$a->dest}" en su servidor y descomprimirlo allí.</p>';
|
||||
$string['remotedownloaderror'] = '<p>Falló la descarga del componente a su servidor. Por favor verifique los ajustes del proxy, la extensión PHP cURL.está altamente recomendada.</p>
|
||||
<p>Debe descargar el archivo <a href="{$a->url}">{$a->url}</a> manualmente, copiarlo a "{$a->dest}" en su servidor y descomprimirlo allí.</p>';
|
||||
$string['wrongdestpath'] = 'Ruta de destino errónea.';
|
||||
$string['wrongsourcebase'] = 'Base de fuente de URL errónea.';
|
||||
$string['wrongzipfilename'] = 'Nombre de archivo ZIP erróneo.';
|
||||
|
||||
@@ -31,4 +31,4 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = 'es_mx';
|
||||
$string['thislanguage'] = 'Español - México - kids';
|
||||
$string['thislanguage'] = 'Español de México para niños';
|
||||
|
||||
@@ -41,8 +41,8 @@ $string['cannotunzipfile'] = 'Ei saa lahti pakkida faili.';
|
||||
$string['componentisuptodate'] = 'Komponent on ajakohane';
|
||||
$string['downloadedfilecheckfailed'] = 'Alla laetud faili kontroll ebaõnnestus.';
|
||||
$string['invalidmd5'] = 'Vigane md5';
|
||||
$string['missingrequiredfield'] = 'Mõned nõutud väljad on puudu';
|
||||
$string['missingrequiredfield'] = 'Mõni nõutav väli on puudu';
|
||||
$string['remotedownloaderror'] = 'Komponendi alla tõmbamine serverisse ebaõnnestus, palun kontrolli proksi seadeid, PHP cURL laiendus on tungivalt soovitatav.<br /><br />Sa pead tõmbama <a href="{$a->url}">{$a->url}</a> faili käsitsi, kopeerima selle "{$a->dest}" oma serveris ja pakkima lahti sinna.';
|
||||
$string['wrongdestpath'] = 'Vale sihtrada';
|
||||
$string['wrongdestpath'] = 'Vale sihtkohatee';
|
||||
$string['wrongsourcebase'] = 'Vale allika URL\'i baas.';
|
||||
$string['wrongzipfilename'] = 'Vale ZIP failinimi';
|
||||
$string['wrongzipfilename'] = 'Vale ZIP-faili nimi';
|
||||
|
||||
+16
-16
@@ -32,23 +32,23 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['admindirname'] = 'Administreerimiskataloog';
|
||||
$string['availablelangs'] = 'Saadaval keelte nimekiri';
|
||||
$string['chooselanguagehead'] = 'Keele valik';
|
||||
$string['chooselanguagehead'] = 'Valige keel';
|
||||
$string['chooselanguagesub'] = 'Palun vali keel, mida kasutatakse AINULT installeerimise käigus. Hiljem saab valida õpikeskkonna ja kasutajate keelt.';
|
||||
$string['clialreadyinstalled'] = 'Fail config.php juba eksisteerib, palun kasuta admin/cli/upgrade.php kui soovid uuendada oma saiti.';
|
||||
$string['cliinstallheader'] = 'Moodle {$a} käsurea põhine installeerimise programm';
|
||||
$string['cliinstallheader'] = 'Moodle’i {$a} käsureapõhine installiprogramm';
|
||||
$string['databasehost'] = 'Andmebaasi host';
|
||||
$string['databasename'] = 'Andmebaasi nimi';
|
||||
$string['databasetypehead'] = 'Vali andmebaasi draiver';
|
||||
$string['databasetypehead'] = 'Valige andmebaasi draiver';
|
||||
$string['dataroot'] = 'Andmete kataloog';
|
||||
$string['datarootpermission'] = 'Andmete kataloogide õigus';
|
||||
$string['datarootpermission'] = 'Andmekataloogide õigus';
|
||||
$string['dbprefix'] = 'Tabeli eesliide';
|
||||
$string['dirroot'] = 'Moodle kataloog';
|
||||
$string['environmenthead'] = 'Keskkonna kontrollimine...';
|
||||
$string['environmentsub2'] = 'Iga Moodle väljalaskel on oma minimaalne PHP versiooni nõue ja kohustuslikud PHP laiendused.
|
||||
Täielik keskkonna kontroll tehakse enne iga installeerimist ja uuendamist. Palun võta ühendust serveri administraatoriga, kui sa ei sa kuidas installeerida või võimaldada PHP laiendusi.';
|
||||
$string['errorsinenvironment'] = 'Keskkonna sobivuse kontroll ebaõnnestus!';
|
||||
$string['installation'] = 'Installeerimine';
|
||||
$string['langdownloaderror'] = 'Kahjuks keelt "{$a}" ei paigaldatud. Paigaldamine jätkub inglise keeles.';
|
||||
$string['errorsinenvironment'] = 'Keskkonna sobivuse kontroll nurjus.';
|
||||
$string['installation'] = 'Installimine';
|
||||
$string['langdownloaderror'] = 'Keelt "{$a}" ei saanud alla laadida. Installimine jätkub inglise keeles.';
|
||||
$string['memorylimithelp'] = '<p>PHP mälu limiit sinu serveri jaoks on hetkel {$a}.</p>
|
||||
<p>See võib hiljem tekitada Moodle\'il mäluprobleeme, eriti kui sul on palju mooduleid ja/või kasutajaid.
|
||||
</p>
|
||||
@@ -60,11 +60,11 @@ See lubab Moodle\'il ise mälu limiiti määrata.</li>
|
||||
<li>Mõnedes PHP serverites saad luua Moodle kataloogi .htaccess faili, mis sisaldab seda rida:<p><blockquote>php_value memory_limit 16M</blockquote></p>
|
||||
<p>Kuigi mõnedes serverites tõkestab see <b>kõigi</b> PHP lehekülgede tööd (sa näed veateateid, kui vaatad lehti), nii et pead eemaldama .htaccess faili.</p></li>
|
||||
</ol>';
|
||||
$string['paths'] = 'Rajad';
|
||||
$string['paths'] = 'Teed';
|
||||
$string['pathserrcreatedataroot'] = 'Andmete kataloogi ({$a->dataroot}) ei saa installeerija luua.';
|
||||
$string['pathshead'] = 'Radade kinnitused';
|
||||
$string['pathsrodataroot'] = 'Andmete juurkataloog (Dataroot) ei ole kirjutatav.';
|
||||
$string['pathsroparentdataroot'] = 'Ülemkataloog ({$a->parent}) ei ole kirjutatav. Installeerija ei saanud andmete kataloogi ({$a->dataroot}) luua.';
|
||||
$string['pathshead'] = 'Kinnita teed';
|
||||
$string['pathsrodataroot'] = 'Andmete juurkataloog ei võimalda kirjutust.';
|
||||
$string['pathsroparentdataroot'] = 'Ülemkataloog ({$a->parent}) ei võimalda kirjutust. Installiprogramm ei saanud andmete kataloogi ({$a->dataroot}) luua.';
|
||||
$string['pathssubadmindir'] = 'Väga vähesed veebihostid kasutavad /admin spetsiaalse URL-na, et pääseda ligi kontrollpaneelile või millegile sarnasele. Kahjuks on see konfliktis Moodle administreerimislehtedega. Sa saad olukorda parandada, kui nimetad kataloogi admin ümber oma üaigalduses ning kirjutad selle uue nime siia. Näiteks: <em>moodleadmin</em>. See parandab administreerimisliidese lingid Moodle\'s.';
|
||||
$string['pathssubdataroot'] = 'Sa pead näitama koha, kuhu Moodle saaks salvestada üles laetud failid. See kataloog peab olema loetav JA KIRJUTATAV veebiserveri kasutaja poolt (tavaliselt \'nobody\' or \'apache\'), samas see kataloog ei tohiks olla ligipääsetav otse veebi kaudu. Kui kataloogi ei eksisteeri, siis installeerija püüab selle ise luua.';
|
||||
$string['pathssubdirroot'] = 'Täistee Moodle paigalduse kataloogile.';
|
||||
@@ -73,9 +73,9 @@ Ei ole võimalik kasutada mitmest kohast kohast ligipääsu.
|
||||
Kui Su sait omab mitut avalikku aadress, siis pead seadistama ümbersuunamised kõikidelt teistest aadressidelt.
|
||||
Kui Su sait on ligipääsetav nii Internetist kui intranetist (sisevõrgust), siis kasuta Interneti ehk avalikku aadressi ja seadista DNS sellisellt, et intraneti kasutajad kasutaksid ka avalikku aadressi.
|
||||
Kui aadress pole korrektne, siis palun muuda URL oma brauseris, et taasalustada installeerimist erineva väärtusega.';
|
||||
$string['pathsunsecuredataroot'] = 'Andmete juurkataloogi asukoht pole turvamine';
|
||||
$string['pathswrongadmindir'] = 'Admin kataloogi ei eksisteeri';
|
||||
$string['phpextension'] = '{$a} PHP laiendus';
|
||||
$string['pathsunsecuredataroot'] = 'Andmete juurkataloogi asukoht pole turvaline';
|
||||
$string['pathswrongadmindir'] = 'Halduskataloogi pole olemas';
|
||||
$string['phpextension'] = '{$a} PHP-laiendus';
|
||||
$string['phpversion'] = 'PHP versioon';
|
||||
$string['phpversionhelp'] = '<p>Moodle vajab vähemalt PHP versiooni 4.1.0</p>
|
||||
<p>Sinu jooksev versioon on {$a}</p>
|
||||
@@ -83,8 +83,8 @@ $string['phpversionhelp'] = '<p>Moodle vajab vähemalt PHP versiooni 4.1.0</p>
|
||||
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
|
||||
$string['welcomep20'] = 'Sa näed seda lehte, sest oled edukalt installeerinud ja käivitanud <strong>{$a->packname} {$a->packversion}</strong> paketi Sinu arvutis. Õnnitleme!';
|
||||
$string['welcomep30'] = 'See <strong>{$a->installername}</strong> väljalase rakendusi loomaks keskkonda, millel <strong>Moodle</strong> hakkab will operate, namely:';
|
||||
$string['welcomep40'] = 'Pakett sisaldab ka <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
|
||||
$string['welcomep40'] = 'Pakett sisaldab ka järgmist: <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
|
||||
$string['welcomep50'] = 'Kasutamaks kõiki selle rakendusi selles paketis on kaetud nende vastavad litsentsid. Täielik <strong>{$a->installername}</strong> pakett on <a href="http://www.opensource.org/docs/definition_plain.html">avatud lähtekoodil</a> ja jaotatud <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> litsentsi alusel.';
|
||||
$string['welcomep60'] = 'Järgnevatel lehtedel juhitakse sind läbi mõnede lihtsate sammude seadistamaks ja seadmaks üles <strong>Moodle</strong> oma arvutis. Sa võid nõustuda vaikeväärtustega või fakultatiivselt täiendada vastavalt oma vajadustele.';
|
||||
$string['welcomep70'] = 'Vajuta "Järgmine" nuppu all jätkamaks <strong>Moodle</strong> paigaldamisega.';
|
||||
$string['welcomep70'] = '<strong>Moodle\\’i</strong> installi jätkamiseks klõpsake nuppu Edasi.';
|
||||
$string['wwwroot'] = 'Veebiaadress';
|
||||
|
||||
@@ -32,4 +32,4 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['parentlanguage'] = '';
|
||||
$string['thisdirection'] = 'ltr';
|
||||
$string['thislanguage'] = 'Eesti';
|
||||
$string['thislanguage'] = 'inglise';
|
||||
|
||||
@@ -34,31 +34,35 @@ $string['admindirname'] = 'Admin direktorioa';
|
||||
$string['availablelangs'] = 'Hizkuntza-pakete eskuragarriak';
|
||||
$string['chooselanguagehead'] = 'Aukeratu hizkuntza bat';
|
||||
$string['chooselanguagesub'] = 'Mesedez, aukeratu instalaziorako hizkuntza bat. Hizkuntza hori erabiliko da gunearen berezko hizkuntza gisa, baina aurrerago alda daiteke.';
|
||||
$string['clialreadyconfigured'] = 'Dagoeneko badago config.php fitxategia. Mesedez erabili admin/cli/install_database.php gune hau instalatu nahi baduzu.';
|
||||
$string['clialreadyinstalled'] = 'Dagoeneko badago config.php fitxategia. Mesedez erabili admin/cli/install_database.php gune hau instalatu nahi baduzu.';
|
||||
$string['clialreadyconfigured'] = 'Dagoeneko badago config.php konfigurazio-fitxategia. Mesedez erabili admin/cli/install_database.php Moodle gune honetan instalatu nahi baduzu.';
|
||||
$string['clialreadyinstalled'] = 'Dagoeneko badago config.php konfigurazio-fitxategia. Mesedez erabili admin/cli/upgrade.php zure Moodle gunea eguneratu nahi baduzu.';
|
||||
$string['cliinstallheader'] = 'Moodle {$a} komando-lerro bidezko instalaziorako programa';
|
||||
$string['databasehost'] = 'Datu-basearen ostalaria';
|
||||
$string['databasename'] = 'Datu-basearen izena';
|
||||
$string['databasetypehead'] = 'Aukeratu datu-base kontrolatzailea';
|
||||
$string['dataroot'] = 'Datuen karpeta';
|
||||
$string['datarootpermission'] = 'Datu-direktorioen baimena';
|
||||
$string['dbprefix'] = 'Taulen aurrizkia';
|
||||
$string['dirroot'] = 'Moodle direktorioa';
|
||||
$string['environmenthead'] = 'Zure ingurunea egiaztatzen...';
|
||||
$string['errorsinenvironment'] = 'Kale egin du ingurunearen egiaztatzeak!';
|
||||
$string['environmentsub2'] = 'Moodle-ko bertsio bakoitzak PHPko gutxieneko bertsioa eta derrigorrez instalatu beharreko PHP luzapen batzuk ditu. Ingurunearen azterketa oso bat egiten da instalazioa eta eguneraketa bakoitza egin aurretik. Mesedez, jarri harremanetan zerbitzariaren kudeatzailearekin ez badakizu bertsio berria edo PHP luzapenak nola instalatu.';
|
||||
$string['errorsinenvironment'] = 'Huts egin du ingurunearen egiaztatzeak!';
|
||||
$string['installation'] = 'Instalazioa';
|
||||
$string['langdownloaderror'] = 'Zoritxarrez "{$a}" hizkuntza ezin izan da jaitsi. Instalazio-prozesuak ingelesez jarraituko du.';
|
||||
$string['memorylimithelp'] = '<p>Zure zerbitzarian PHP memoria-muga {$a} da une honetan.</p>
|
||||
|
||||
<p>Aurrerago honek Moodle-ri arazoak sor diezaizkioke, bereziki modulu edota erabiltzaile asko badituzu.</p>
|
||||
<p>Aurrerago honek Moodle-ri arazoak sor diezaizkioke,
|
||||
bereziki modulu edo/eta erabiltzaile asko badituzu.</p>
|
||||
|
||||
<p>PHP muga altuagoa konfiguratzea aholkatzen dizugu, ad. 40MB.
|
||||
<p>PHP memoria-muga ahal bezain altu konfiguratzea aholkatzen dizugu, ad. 40M.
|
||||
Hori egiteko modu asko daude:</p>
|
||||
<ol>
|
||||
<li>Ahal baduzu, PHP <i>--enable-memory-limit</i>-ekin berriz konpilatu.
|
||||
Horrek Moodle-k berak memoria-muga ezartzea ahalbidetzen du.</li>
|
||||
<li>php.ini fitxategirako sarbidea baduzu,<b>memory_limit</b> ezarpena alda dezakezu
|
||||
40MBra, adibidez. Sarbiderik ez baduzu, zure administratzaileari egin dezala eska diezaiokezu.</li>
|
||||
<li>PHP zerbitzari batzuetan Moodle-ren karpetan beheko lerro hau daukan .htaccess fitxategia sor dezakezu:
|
||||
<blockquote>php_value memory_limit 40M</blockquote>
|
||||
40Mra, adibidez. Sarbiderik ez baduzu, zure administratzaileari egin dezala eska diezaiokezu.</li>
|
||||
<li>PHP zerbitzari batzuetan Moodle-ren direktorioan beheko lerro hau daukan .htaccess fitxategia sor dezakezu:
|
||||
<blockquote><div>php_value memory_limit 40M</div></blockquote>
|
||||
<p>Hala ere, zerbitzari batzuetan horrek PHP orri <b>guztiek</b> ez funtzionatzea ekar dezake
|
||||
(orriak ikustean erroreak ere ikusiko dituzu). Kasu horretan, .htaccess fitxategia ezabatu beharko duzu.</p></li>
|
||||
</ol>';
|
||||
@@ -67,8 +71,18 @@ $string['pathserrcreatedataroot'] = 'Instalatzaileak ezin du datuen karpeta ({$a
|
||||
$string['pathshead'] = 'Egiaztatu bideak';
|
||||
$string['pathsrodataroot'] = 'Dataroot direktorioa ez da idazteko modukoa.';
|
||||
$string['pathsroparentdataroot'] = 'Goragoko direktorioan ({$a->parent}) ezin da idatzi. Instalatzaileak ezin du datuen karpeta ({$a->dataroot}) sortu.';
|
||||
$string['pathssubadmindir'] = 'Web ostalari gutxi batzuk /admin URL berezi gisa erabiltzen dute kontrol-panel edo antzekora sarbidea emateko. Zoritxarrez, honek Moodle-ren kudeatze-orrien berezko kokapenarekin gatazka sortzen du. Hau konpondu dezakezu zure instalazioko admin karpeta berrizendatuz, eta izen berria hemen sartuta. Adibidez <em>moodleadmin</em>. Honek Moodle-ko admin estekak konponduko du.';
|
||||
$string['pathssubdataroot'] = '<p>Moodle-k erabiltzaileek igotako fitxategien edukiak bilduko dituen direktorio bat.</p>
|
||||
<p>Direktorio honetan web-zerbitzariaren erabiltzaileak irakurtzeko eta idazteko baimena izan beharko ditu (normalean \'www-data\', \'nobody\', edo \'apache\').</p>
|
||||
<p>Ez litzateke web bidez eskuragarri egon beharko.</p>
|
||||
<p>Direktorioa existitzen ez bada, instalazioan sortzeko saiakera egingo da.</p>';
|
||||
$string['pathssubdirroot'] = '<p>Moodle-ko kodea daukan direktorioaren helbide osoa.</p>';
|
||||
$string['pathssubwwwroot'] = '<p>Moodle eskuragarri egongo den helbide osoa, hau da, erabiltzaileek Moodle-n sartzeko nabigatzaileareko helbide barran idatziko duten helbidea</p>
|
||||
<p>Moodle ezin da hainbat helbidetatik eskuragarri egon. Zure gunea hainbat helbidetatik eskuragarri badago errazena aukeratu eta bertara beste helbideetatik behin-betiko berbideraketak konfiguratu itzazu.</p>
|
||||
<p>Zure gunea Internetetik eta barne-sare batetik eskuragarri badago (batzuetan Intranet deitutakoa), hemen helbide publikoa erabili ezazu.</p>
|
||||
<p>Oraingo helbidea egokia ez bada, mesedez aldatu ezazu URLa zure nabigatzailean eta instalazioa berriz abiatu ezazu.</p>';
|
||||
$string['pathsunsecuredataroot'] = 'Dataroot-en kokapena ez da segurua';
|
||||
$string['pathswrongadmindir'] = 'Kudeaketa direktorioa ez da existitzen';
|
||||
$string['pathswrongadmindir'] = 'Admin direktorioa ez da existitzen';
|
||||
$string['phpextension'] = '{$a} PHP luzapena';
|
||||
$string['phpversion'] = 'PHP bertsioa';
|
||||
$string['phpversionhelp'] = '<p>Moodle-k gutxienez PHP 4.3.0 edo 5.1.0 (5.0.x errore batzuk ditu). </p>
|
||||
|
||||
@@ -30,5 +30,17 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['cannotcreatedboninstall'] = '<p>پایگاه داده نتوانست ساخته شود.</p>
|
||||
<p>پایگاه دادهٔ تعیین شده وجود ندارد و کاربر ارائهشده هم مجوز ساختن پایگاه داده را ندارد.</p>
|
||||
<p>مدیر سایت باید پیکربندی پایگاه داده را بررسی کند.</p>';
|
||||
$string['cannotcreatelangdir'] = 'دایرکتوری lang نتوانست ساخته شود';
|
||||
$string['cannotcreatetempdir'] = 'نمیتوان دایرکتوری temp را ساخت';
|
||||
$string['cannotdownloadcomponents'] = 'اجزا (کامپوننتها) را نمیتوان دریافت کرد';
|
||||
$string['cannotdownloadzipfile'] = 'فایل ZIP نتوانست دریافت شود.';
|
||||
$string['cannotfindcomponent'] = 'کامپوننت پیدا نشد';
|
||||
$string['cannotsavemd5file'] = 'نمیتوانم فایل md5 را ذخیره کنم';
|
||||
$string['cannotsavezipfile'] = 'نمیتوانم فایل ZIP را ذخیره کنم';
|
||||
$string['cannotunzipfile'] = 'فایل نمیتواند unzip شود';
|
||||
$string['componentisuptodate'] = 'کامپوننت بهروز است';
|
||||
$string['dmlexceptiononinstall'] = '<p>یک خطای پایگاه داده رخ داد [{$a->errorcode}].<br />{$a->debuginfo}</p>';
|
||||
$string['missingrequiredfield'] = 'بعضی از فیلدهای ضروری خالی است';
|
||||
|
||||
@@ -36,6 +36,7 @@ $string['chooselanguagehead'] = 'انتخاب زبان';
|
||||
$string['chooselanguagesub'] = 'لطفاً زبانی را به جهت استفاده در حین نصب انتخاب نمایید. زبانی که در این صفحه انتخاب میکنید به عنوان زبان پیشفرض سایت نیز مورد استفاده قرار خواهد گرفت. البته میتوانید بعداً آن را تغییر دهید.<br />ترجمهٔ فارسی این نسخه با همکاری <a href="http://foodle.org" target="_blank">گروه فودل</a> آماده شده است.';
|
||||
$string['databasehost'] = 'میزبان پایگاه داده';
|
||||
$string['databasename'] = 'نام پایگاه داده';
|
||||
$string['databasetypehead'] = 'راهانداز پایگاه داده را انتخاب کنید';
|
||||
$string['dataroot'] = 'دایرکتوری داده';
|
||||
$string['dbprefix'] = 'پیشوند جدولها';
|
||||
$string['dirroot'] = 'دایرکتوری مودل';
|
||||
@@ -62,10 +63,9 @@ $string['memorylimithelp'] = '<p>حد حافظهٔ PHP کارگزار شما ه
|
||||
(هنگام مشاهدهٔ صفحهها خطاهایی خواهید دید) و مجبور خواهید بود که فایل <span dir="ltr">.htaccess</span> را پاک کنید.</p></li>
|
||||
</ol>';
|
||||
$string['phpversion'] = 'نسخهٔ PHP';
|
||||
$string['phpversionhelp'] = '<p>مودل نیاز به PHP نسخهٔ حداقل 4.3.0 یا 5.1.0 دارد (<span dir="ltr">5.0.x</span> مشکلات شناختهشدهای دارد).</p>
|
||||
$string['phpversionhelp'] = '<p>مودل نیاز به PHP نسخهٔ حداقل 5.4.4 دارد (<span dir="ltr" style="direction: ltr; display: inline-block">7.x</span> محدودیتهایی در engine اش دارد).</p>
|
||||
<p>شما در حال حاضر از نسخهٔ {$a} استفاده میکنید</p>
|
||||
<p>باید PHP را ارتقاء دهید یا از کارگزاری دارای نسخهٔ جدیدتر PHP استفاده نمائید!<br />
|
||||
(در صورت استفاده از <span dir="ltr">5.0.x</span> به نسخهٔ <span dir="ltr">4.4.x</span> هم میتوانید برگردید)</p>';
|
||||
<p>باید PHP را ارتقاء دهید یا از کارگزاری دارای نسخهٔ جدیدتر PHP استفاده نمائید.</p>';
|
||||
$string['welcomep10'] = '{$a->installername} (<span dir="ltr">{$a->installerversion}</span>)';
|
||||
$string['welcomep20'] = 'دیدن این صفحه به معنی نصب و راهاندازی موفق بستهٔ
|
||||
<strong>{$a->packname} <span dir="ltr">{$a->packversion}</span></b></strong> است. تبریک!';
|
||||
|
||||
@@ -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'] = 'ʻŌlelo Hawaiʻi';
|
||||
@@ -30,5 +30,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['clianswerno'] = 'n';
|
||||
$string['cliansweryes'] = 'j';
|
||||
$string['environmentrequireinstall'] = 'nepieciešams instalēt/iespējot';
|
||||
$string['environmentrequireversion'] = 'nepieciešama versija {$a->needed}, bet jūs izmantojat versiju {$a->current}';
|
||||
|
||||
@@ -40,7 +40,7 @@ $string['cannotsavezipfile'] = 'Nevar saglabāt ZIP failu';
|
||||
$string['cannotunzipfile'] = 'Nevar atzipot failu';
|
||||
$string['componentisuptodate'] = 'Komponents atbilst visjaunākajai versijai.';
|
||||
$string['downloadedfilecheckfailed'] = 'Lejupielādētā faila pārbaudes rezultāts nesekmīgs.';
|
||||
$string['invalidmd5'] = 'Nederīgs md5';
|
||||
$string['invalidmd5'] = 'Pārbaudītais mainīgais bija nepareizs - mēģiniet vēlreiz';
|
||||
$string['missingrequiredfield'] = 'Trūkst kāda nepieciešamā lauka';
|
||||
$string['wrongdestpath'] = 'Nepareizs mērķa ceļš.';
|
||||
$string['wrongsourcebase'] = 'Nepareiza avota URL bāze.';
|
||||
|
||||
@@ -34,11 +34,13 @@ $string['admindirname'] = 'Administratora direktorijs';
|
||||
$string['availablelangs'] = 'Pieejamās valodu pakotnes';
|
||||
$string['chooselanguagehead'] = 'Valodas izvēle';
|
||||
$string['chooselanguagesub'] = 'Lūdzu izvēlieties šīs instalācijas valodu. Izvēlētā valoda tiks izmantota arī kā noklusētā šīs vietnes valoda, lai gan tā var tikt nomainīta vēlāk.';
|
||||
$string['databasename'] = 'Datubāzes nosaukums';
|
||||
$string['databasetypehead'] = 'Izvēlēties datubāzes draiveru';
|
||||
$string['dataroot'] = 'Datu direktorijs';
|
||||
$string['dbprefix'] = 'Tabulu prefikss';
|
||||
$string['dirroot'] = 'Moodle direktorijs';
|
||||
$string['environmenthead'] = 'Vides pārbaude...';
|
||||
$string['errorsinenvironment'] = 'Vides pārbaude neizdevās!';
|
||||
$string['installation'] = 'Instalēšana';
|
||||
$string['langdownloaderror'] = '“{$a}” valodas pakotne diemžēl netika instalēta. Instalēšana tiks turpināta angļu valodā.';
|
||||
$string['memorylimithelp'] = '<p>Pašlaik iestatītais PHP atmiņas apjoma ierobežojums jūsu serverī ir {$a}.</p>
|
||||
@@ -55,6 +57,8 @@ $string['memorylimithelp'] = '<p>Pašlaik iestatītais PHP atmiņas apjoma ierob
|
||||
<p>Tomēr dažos serveros tas neļaus darboties <b>nevienai</b> PHP lapai
|
||||
(atverot šīs lapas, tiks parādīti kļūdas ziņojumi), un fails .htaccess būs jānoņem.</p></li>
|
||||
</ol>';
|
||||
$string['paths'] = 'Ceļi';
|
||||
$string['pathshead'] = 'Apstiprināt ceļus';
|
||||
$string['phpversion'] = 'PHP versija';
|
||||
$string['phpversionhelp'] = '<p>Sistēmā Moodle jāizmanto PHP, kuras versija ir vismaz 4.3.0 vai 5.1.0 (versijai 5.0.x piemīt vairākas zināmas problēmas).</p>
|
||||
<p>Jūs pašlaik lietojat versiju {$a}</p>
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['language'] = 'Valoda';
|
||||
$string['moodlelogo'] = 'Moodle logo';
|
||||
$string['next'] = 'Nākamais';
|
||||
$string['previous'] = 'Iepriekšējais';
|
||||
$string['reload'] = 'Atkārtoti ielādēt';
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['language'] = 'Хэл';
|
||||
$string['moodlelogo'] = 'Мүүдл лого';
|
||||
$string['next'] = 'Дараагийн';
|
||||
$string['previous'] = 'Өмнөх';
|
||||
$string['reload'] = 'Дахин ачаалах';
|
||||
|
||||
@@ -71,7 +71,7 @@ $string['pathssubdataroot'] = '<p>Директоријум где ће Moodle ч
|
||||
<p>Овај директоријум треба да буде подешен тако да корисник веб сервера (обично \'nobody\' или \'apache\') може да га чита и у њега уписује.</p>
|
||||
<p>Директоријум не сме бити доступан директно преко веба. </p>
|
||||
<p>Уколико овај директоријум не постоји процес инсталације ће покушати да га креира.</p>';
|
||||
$string['pathssubdirroot'] = '<p>Пуна путања до директоријума који садржи код Moodlea.</p>';
|
||||
$string['pathssubdirroot'] = '<p>Пуна путања до директоријума који садржи кôд Moodlea.</p>';
|
||||
$string['pathssubwwwroot'] = '<p>Пуна адреса путем које ће се приступати Moodleu, тј. адреса коју ће корисници унети у адресну траку својих веб читача како би приступили Moodleu.</p>
|
||||
<p>Није могуће приступати Moodleu коришћењем више адреса Ако се вашем сајту може приступити са више адреса, онда изаберите најлакшу, а за све остале адресе подесите перманентну редирекцију.</p>
|
||||
<p>Ако се вашем сајту може приступити са интернета али и са унутрашње мреже (која се понекад назив интранет), онда овде употребите јавну адресу.</p>
|
||||
|
||||
@@ -71,7 +71,7 @@ $string['pathssubdataroot'] = '<p>Direktorijum gde će Moodle čuvati datoteke i
|
||||
<p>Ovaj direktorijum treba da bude podešen tako da korisnik veb servera (obično \'nobody\' ili \'apache\') može da ga čita i u njega upisuje.</p>
|
||||
<p>Direktorijum ne sme biti dostupan direktno preko veba. </p>
|
||||
<p>Ukoliko ovaj direktorijum ne postoji proces instalacije će pokušati da ga kreira.</p>';
|
||||
$string['pathssubdirroot'] = '<p>Puna putanja do direktorijuma koji sadrži kod Moodlea.</p>';
|
||||
$string['pathssubdirroot'] = '<p>Puna putanja do direktorijuma koji sadrži kôd Moodlea.</p>';
|
||||
$string['pathssubwwwroot'] = '<p>Puna adresa putem koje će se pristupati Moodleu, tj. adresa koju će korisnici uneti u adresnu traku svojih veb čitača kako bi pristupili Moodleu.</p>
|
||||
<p>Nije moguće pristupati Moodleu korišćenjem više adresa Ako se vašem sajtu može pristupiti sa više adresa, onda izaberite najlakšu, a za sve ostale adrese podesite permanentnu redirekciju.</p>
|
||||
<p>Ako se vašem sajtu može pristupiti sa interneta ali i sa unutrašnje mreže (koja se ponekad naziv intranet), onda ovde upotrebite javnu adresu.</p>
|
||||
|
||||
@@ -575,6 +575,7 @@ $string['htmlsettings'] = 'HTML settings';
|
||||
$string['http'] = 'HTTP';
|
||||
$string['httpsecurity'] = 'HTTP security';
|
||||
$string['hubs'] = 'Hubs';
|
||||
$string['incompleteunicodesupport'] = 'The current setup of MySQL or MariaDB is using \'utf8\'. This character set does not support four byte characters which include some emoji. Trying to use these characters will result in an error when updating a record, and any information being sent to the database will be lost. Please consider changing your settings to \'utf8mb4\'. See the documentation for full details.';
|
||||
$string['change'] = 'change';
|
||||
$string['checkboxno'] = 'No';
|
||||
$string['checkboxyes'] = 'Yes';
|
||||
@@ -1077,6 +1078,9 @@ $string['unlockaccount'] = 'Unlock account';
|
||||
$string['unoconvwarning'] = 'The version of unoconv you have installed is not supported. Moodle\'s assignment grading feature requires version 0.7 or higher.';
|
||||
$string['unsettheme'] = 'Unset theme';
|
||||
$string['unsupported'] = 'Unsupported';
|
||||
$string['unsupporteddbfileformat'] = 'Your database has tables using Antelope as the file format. Full UTF-8 support in MySQL and MariaDB requires the Barracuda file format. Please convert the tables to the Barracuda file format. See the documentation <a href="https://docs.moodle.org/en/cli">Administration via command line</a> for details of a tool for converting InnoDB tables to Barracuda.';
|
||||
$string['unsupporteddbfilepertable'] = 'For full support of UTF-8 both MySQL and MariaDB require you to change your MySQL setting \'innodb_file_per_table\' to \'ON\'. See the documentation for further details.';
|
||||
$string['unsupporteddblargeprefix'] = 'For full support of UTF-8 both MySQL and MariaDB require you to change your MySQL setting \'innodb_large_prefix\' to \'ON\'. See the documentation for further details.';
|
||||
$string['unsupporteddbstorageengine'] = 'The database storage engine being used is no longer supported.';
|
||||
$string['unsupporteddbtablerowformat'] = 'Your database has tables using Antelope as the file format. You are recommended to convert the tables to the Barracuda file format. See the documentation <a href="https://docs.moodle.org/en/cli">Administration via command line</a> for details of a tool for converting InnoDB tables to Barracuda.';
|
||||
$string['unsupportedphpversion7'] = 'PHP version 7 is not supported.';
|
||||
|
||||
+3
-4
@@ -217,10 +217,9 @@ $string['pathswrongadmindir'] = 'Admin directory does not exist';
|
||||
$string['pgsqlextensionisnotpresentinphp'] = 'PHP has not been properly configured with the PGSQL extension so that it can communicate with PostgreSQL. Please check your php.ini file or recompile PHP.';
|
||||
$string['phpextension'] = '{$a} PHP extension';
|
||||
$string['phpversion'] = 'PHP version';
|
||||
$string['phpversionhelp'] = '<p>Moodle requires a PHP version of at least 4.3.0 or 5.1.0 (5.0.x has a number of known problems).</p>
|
||||
<p>You are currently running version {$a}</p>
|
||||
<p>You must upgrade PHP or move to a host with a newer version of PHP!<br />
|
||||
(In case of 5.0.x you could also downgrade to 4.4.x version)</p>';
|
||||
$string['phpversionhelp'] = '<p>Moodle requires a PHP version of at least 5.4.4 (7.x has some engine limitations).</p>
|
||||
<p>You are currently running version {$a}.</p>
|
||||
<p>You must upgrade PHP or move to a host with a newer version of PHP.</p>';
|
||||
$string['releasenoteslink'] = 'For information about this version of Moodle, please see the release notes at {$a}';
|
||||
$string['safemode'] = 'Safe mode';
|
||||
$string['safemodeerror'] = 'Moodle may have trouble with safe mode on';
|
||||
|
||||
@@ -464,6 +464,7 @@ $string['deletecategoryempty'] = 'This category is empty.';
|
||||
$string['deletecategorycheck'] = 'Are you absolutely sure you want to completely delete this category <b>\'{$a}\'</b>?<br />This will move all courses into the parent category if there is one, or into Miscellaneous.';
|
||||
$string['deletecategorycheck2'] = 'If you delete this category, you need to choose what to do with the courses and subcategories it contains.';
|
||||
$string['deletecomment'] = 'Delete this comment';
|
||||
$string['deletecommentbyon'] = 'Delete comment posted by {$a->user} on {$a->time}';
|
||||
$string['deletecompletely'] = 'Delete completely';
|
||||
$string['deletecourse'] = 'Delete a course';
|
||||
$string['deletecoursecheck'] = 'Are you absolutely sure you want to completely delete this course and all the data it contains?';
|
||||
|
||||
+36
-8
@@ -3989,9 +3989,13 @@ function get_users_by_capability(context $context, $capability, $fields = '', $s
|
||||
} else {
|
||||
$unions[] = "SELECT userid
|
||||
FROM {role_assignments}
|
||||
WHERE contextid IN ($ctxids)
|
||||
AND roleid IN (".implode(',', array_keys($needed[$cap])) .")
|
||||
AND roleid NOT IN (".implode(',', array_keys($prohibited[$cap])) .")";
|
||||
WHERE contextid IN ($ctxids) AND roleid IN (".implode(',', array_keys($needed[$cap])) .")
|
||||
AND userid NOT IN (
|
||||
SELECT userid
|
||||
FROM {role_assignments}
|
||||
WHERE contextid IN ($ctxids)
|
||||
AND roleid IN (" . implode(',', array_keys($prohibited[$cap])) . ")
|
||||
)";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4322,20 +4326,26 @@ function count_role_users($roleid, context $context, $parent = false) {
|
||||
* @param int $userid User ID or null for current user
|
||||
* @param bool $doanything True if 'doanything' is permitted (default)
|
||||
* @param string $fieldsexceptid Leave blank if you only need 'id' in the course records;
|
||||
* otherwise use a comma-separated list of the fields you require, not including id
|
||||
* otherwise use a comma-separated list of the fields you require, not including id.
|
||||
* Add ctxid, ctxpath, ctxdepth etc to return course context information for preloading.
|
||||
* @param string $orderby If set, use a comma-separated list of fields from course
|
||||
* table with sql modifiers (DESC) if needed
|
||||
* @param int $limit Limit the number of courses to return on success. Zero equals all entries.
|
||||
* @return array|bool Array of courses, if none found false is returned.
|
||||
*/
|
||||
function get_user_capability_course($capability, $userid = null, $doanything = true, $fieldsexceptid = '', $orderby = '') {
|
||||
function get_user_capability_course($capability, $userid = null, $doanything = true, $fieldsexceptid = '', $orderby = '',
|
||||
$limit = 0) {
|
||||
global $DB;
|
||||
|
||||
// Convert fields list and ordering
|
||||
$fieldlist = '';
|
||||
if ($fieldsexceptid) {
|
||||
$fields = explode(',', $fieldsexceptid);
|
||||
$fields = array_map('trim', explode(',', $fieldsexceptid));
|
||||
foreach($fields as $field) {
|
||||
$fieldlist .= ',c.'.$field;
|
||||
// Context fields have a different alias and are added further down.
|
||||
if (strpos($field, 'ctx') !== 0) {
|
||||
$fieldlist .= ',c.'.$field;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($orderby) {
|
||||
@@ -4356,6 +4366,13 @@ function get_user_capability_course($capability, $userid = null, $doanything = t
|
||||
|
||||
$contextpreload = context_helper::get_preload_record_columns_sql('x');
|
||||
|
||||
$contextlist = ['ctxid', 'ctxpath', 'ctxdepth', 'ctxlevel', 'ctxinstance'];
|
||||
$unsetitems = $contextlist;
|
||||
if ($fieldsexceptid) {
|
||||
$coursefields = array_map('trim', explode(',', $fieldsexceptid));
|
||||
$unsetitems = array_diff($contextlist, $coursefields);
|
||||
}
|
||||
|
||||
$courses = array();
|
||||
$rs = $DB->get_recordset_sql("SELECT c.id $fieldlist, $contextpreload
|
||||
FROM {course} c
|
||||
@@ -4363,12 +4380,23 @@ function get_user_capability_course($capability, $userid = null, $doanything = t
|
||||
$orderby");
|
||||
// Check capability for each course in turn
|
||||
foreach ($rs as $course) {
|
||||
context_helper::preload_from_record($course);
|
||||
// The preload_from_record() unsets the context related fields, but it is possible that our caller may
|
||||
// want them returned too (so they can use them for their own context preloading). For that reason we
|
||||
// pass a clone.
|
||||
context_helper::preload_from_record(clone($course));
|
||||
$context = context_course::instance($course->id);
|
||||
if (has_capability($capability, $context, $userid, $doanything)) {
|
||||
// Unset context fields if they were not asked for.
|
||||
foreach ($unsetitems as $item) {
|
||||
unset($course->$item);
|
||||
}
|
||||
// We've got the capability. Make the record look like a course record
|
||||
// and store it
|
||||
$courses[] = $course;
|
||||
$limit--;
|
||||
if ($limit == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
define(["jquery","core/config"],function(a,b){var c=function(a){var b,c,d=this,e=null,f=0;for(f=0;f<d.length;f++){if(b=d[f],c=a[f],"undefined"==typeof c){e=new Error("missing response");break}if(c.error!==!1){e=c.exception;break}b.deferred.resolve(c.data)}if(null!==e)for(;f<d.length;f++)b=d[f],b.deferred.reject(e)},d=function(a,b){var c=this,d=0;for(d=0;d<c.length;d++){var e=c[d];"undefined"!=typeof e.fail&&e.deferred.reject(b)}};return{call:function(e,f,g){var h,i=[],j=[];for("undefined"==typeof g&&(g=!0),"undefined"==typeof f&&(f=!0),h=0;h<e.length;h++){var k=e[h];i.push({index:h,methodname:k.methodname,args:k.args}),k.deferred=a.Deferred(),j.push(k.deferred.promise()),"undefined"!=typeof k.done&&k.deferred.done(k.done),"undefined"!=typeof k.fail&&k.deferred.fail(k.fail),k.index=h}i=JSON.stringify(i);var l={type:"POST",data:i,context:e,dataType:"json",processData:!1,async:f,contentType:"application/json"},m=b.wwwroot+"/lib/ajax/service.php?sesskey="+b.sesskey;return g||(m=b.wwwroot+"/lib/ajax/service-nologin.php?sesskey="+b.sesskey),f?a.ajax(m,l).done(c).fail(d):(l.success=c,l.error=d,a.ajax(m,l)),j}}});
|
||||
define(["jquery","core/config"],function(a,b){var c=function(a){var b,c,d=this,e=null,f=0;for(f=0;f<d.length;f++){if(b=d[f],c=a[f],"undefined"==typeof c){e=new Error("missing response");break}if(c.error!==!1){e=c.exception;break}b.deferred.resolve(c.data)}if(null!==e)for(;f<d.length;f++)b=d[f],b.deferred.reject(e)},d=function(a,b){var c=this,d=0;for(d=0;d<c.length;d++){var e=c[d];e.deferred.reject(b)}};return{call:function(e,f,g){var h,i=[],j=[];for("undefined"==typeof g&&(g=!0),"undefined"==typeof f&&(f=!0),h=0;h<e.length;h++){var k=e[h];i.push({index:h,methodname:k.methodname,args:k.args}),k.deferred=a.Deferred(),j.push(k.deferred.promise()),"undefined"!=typeof k.done&&k.deferred.done(k.done),"undefined"!=typeof k.fail&&k.deferred.fail(k.fail),k.index=h}i=JSON.stringify(i);var l={type:"POST",data:i,context:e,dataType:"json",processData:!1,async:f,contentType:"application/json"},m=b.wwwroot+"/lib/ajax/service.php?sesskey="+b.sesskey;return g||(m=b.wwwroot+"/lib/ajax/service-nologin.php?sesskey="+b.sesskey),f?a.ajax(m,l).done(c).fail(d):(l.success=c,l.error=d,a.ajax(m,l)),j}}});
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
||||
define(["jquery","core/ajax","core/localstorage"],function(a,b,c){return{get_string:function(a,b,c,d){var e=this.get_strings([{key:a,component:b,param:c,lang:d}]);return e.then(function(a){return a[0]})},get_strings:function(d){var e,f=a.Deferred(),g=[],h=0,i=!1;for(h=0;h<d.length;h++)if(e=d[h],"undefined"==typeof e.lang&&(e.lang=a("html").attr("lang").replace("-","_")),"undefined"==typeof M.str[e.component]||"undefined"==typeof M.str[e.component][e.key]){var j=c.get("core_str/"+e.key+"/"+e.component+"/"+e.lang);j?("undefined"==typeof M.str[e.component]&&(M.str[e.component]=[]),M.str[e.component][e.key]=j):i=!0}if(i){var k=[];for(h=0;h<d.length;h++)e=d[h],k.push({methodname:"core_get_string",args:{stringid:e.key,component:e.component,lang:e.lang,stringparams:[]}});var l=b.call(k,!0,!1);a.when.apply(null,l).done(function(){var a=0;for(a=0;a<arguments.length;a++)e=d[a],"undefined"==typeof M.str[e.component]&&(M.str[e.component]=[]),M.str[e.component][e.key]=arguments[a],c.set("core_str/"+e.key+"/"+e.component+"/"+e.lang,arguments[a]),g[a]=M.util.get_string(e.key,e.component,e.param).trim();f.resolve(g)}).fail(function(a){f.reject(a)})}else{for(h=0;h<d.length;h++)e=d[h],g[h]=M.util.get_string(e.key,e.component,e.param);f.resolve(g)}return f.promise()}}});
|
||||
define(["jquery","core/ajax","core/localstorage"],function(a,b,c){var d=[];return{get_string:function(a,b,c,d){var e=this.get_strings([{key:a,component:b,param:c,lang:d}]);return e.then(function(a){return a[0]})},get_strings:function(e){var f,g=a.Deferred(),h=[],i=0,j=!1;for(i=0;i<e.length;i++)if(f=e[i],"undefined"==typeof f.lang&&(f.lang=a("html").attr("lang").replace("-","_")),f.cacheKey="core_str/"+f.key+"/"+f.component+"/"+f.lang,"undefined"==typeof M.str[f.component]||"undefined"==typeof M.str[f.component][f.key]){var k=c.get(f.cacheKey);k?("undefined"==typeof M.str[f.component]&&(M.str[f.component]=[]),M.str[f.component][f.key]=k):j=!0}if(j){var l=[],m=[],n=function(a){this.resolve(a)},o=function(a){this.reject(a)};for(i=0;i<e.length;i++)if(f=e[i],"undefined"!=typeof d[f.cacheKey])m.push(d[f.cacheKey]);else{var p=a.Deferred();l.push({methodname:"core_get_string",args:{stringid:f.key,component:f.component,lang:f.lang,stringparams:[]},done:n.bind(p),fail:o.bind(p)}),d[f.cacheKey]=p.promise(),m.push(d[f.cacheKey])}l.length>0&&b.call(l,!0,!1),a.when.apply(null,m).done(function(){var a=0;for(a=0;a<arguments.length;a++)f=e[a],"undefined"==typeof M.str[f.component]&&(M.str[f.component]=[]),M.str[f.component][f.key]=arguments[a],c.set("core_str/"+f.key+"/"+f.component+"/"+f.lang,arguments[a]),h[a]=M.util.get_string(f.key,f.component,f.param).trim();g.resolve(h)}).fail(function(a){g.reject(a)})}else{for(i=0;i<e.length;i++)f=e[i],h[i]=M.util.get_string(f.key,f.component,f.param);g.resolve(h)}return g.promise()}}});
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
define(["core/mustache","jquery","core/ajax","core/str","core/notification","core/url","core/config","core/localstorage","core/event","core/yui","core/log"],function(a,b,c,d,e,f,g,h,i,j,k){var l=0,m={},n=function(){this.requiredStrings=[],this.requiredJS=[],this.currentThemeName=""};n.prototype.requiredStrings=null,n.prototype.requiredJS=null,n.prototype.currentThemeName="",n.prototype.getTemplate=function(a,d){var e=b.Deferred(),f=a.split("/"),g=f.shift(),i=f.shift(),j=this.currentThemeName+"/"+a;if(j in m)return e.resolve(m[j]),e.promise();var k=h.get("core_template/"+j);if(k)return e.resolve(k),m[j]=k,e.promise();var l=c.call([{methodname:"core_output_load_template",args:{component:g,template:i,themename:this.currentThemeName}}],d,!1);return l[0].done(function(a){h.set("core_template/"+j,a),m[j]=a,e.resolve(a)}).fail(function(a){e.reject(a)}),e.promise()},n.prototype.partialHelper=function(a){var b="";return this.getTemplate(a,!1).done(function(a){b=a}).fail(e.exception),b},n.prototype.pixHelper=function(b,c,d){var e,g=c.split(","),h="",i="",j="";g.length>0&&(h=g.shift().trim()),g.length>0&&(i=g.shift().trim()),g.length>0&&(j=g.join(",").trim());var k=f.imageUrl(h,i),l={attributes:[{name:"src",value:k},{name:"alt",value:d(j)},{name:"title",value:d(j)},{name:"class",value:"smallicon"}]},n=m[this.currentThemeName+"/core/pix_icon"];return e=a.render(n,l,this.partialHelper.bind(this)),e.trim()},n.prototype.jsHelper=function(a,b,c){return this.requiredJS.push(c(b,a)),""},n.prototype.stringHelper=function(a,b,c){var d=b.split(","),e="",f="",g="";d.length>0&&(e=d.shift().trim()),d.length>0&&(f=d.shift().trim()),d.length>0&&(g=d.join(",").trim()),""!==g&&(g=c(g,a)),0===g.indexOf("{")&&0!==g.indexOf("{{")&&(g=JSON.parse(g));var h=this.requiredStrings.length;return this.requiredStrings.push({key:e,component:f,param:g}),"[[_s"+h+"]]"},n.prototype.quoteHelper=function(a,b,c){var d=c(b.trim(),a);return d=d.replace('"','\\"').replace(/([\{\}]{2,3})/g,"{{=<% %>=}}$1<%={{ }}=%>"),'"'+d+'"'},n.prototype.addHelpers=function(a,b){this.currentThemeName=b,this.requiredStrings=[],this.requiredJS=[],a.uniqid=l++,a.str=function(){return this.stringHelper.bind(this,a)}.bind(this),a.pix=function(){return this.pixHelper.bind(this,a)}.bind(this),a.js=function(){return this.jsHelper.bind(this,a)}.bind(this),a.quote=function(){return this.quoteHelper.bind(this,a)}.bind(this),a.globals={config:g},a.currentTheme=b},n.prototype.getJS=function(a){var b="";return this.requiredJS.length>0&&(b=this.requiredJS.join(";\n")),this.treatStringsInContent(b,a)},n.prototype.treatStringsInContent=function(a,b){var c,d,e,f,g,h,i=/\[\[_s\d+\]\]/;do{for(c="",d=a.search(i);d>-1;){c+=a.substring(0,d),a=a.substr(d),e="",f=4,g=a.substr(f,1);do e+=g,f++,g=a.substr(f,1);while("]"!=g);h=b[parseInt(e,10)],"undefined"==typeof h&&(k.debug("Could not find string for pattern [[_s"+e+"]]."),h=""),c+=h,a=a.substr(6+e.length),d=a.search(i)}a=c+a,d=a.search(i)}while(d>-1);return a},n.prototype.doRender=function(c,e,f){var g=b.Deferred();this.currentThemeName=f;var h=this.getTemplate("core/pix_icon",!0);return h.done(function(){this.addHelpers(e,f);var b="";try{b=a.render(c,e,this.partialHelper.bind(this))}catch(h){g.reject(h)}this.requiredStrings.length>0?d.get_strings(this.requiredStrings).then(function(a){b=this.treatStringsInContent(b,a),g.resolve(b,this.getJS(a))}.bind(this)).fail(g.reject):g.resolve(b.trim(),this.getJS([]))}.bind(this)).fail(g.reject),g.promise()};var o=function(a){if(""!==a.trim()){var c=b("<script>").attr("type","text/javascript").html(a);b("head").append(c)}},p=function(a,c,d,e){var f=b(a);if(f.length){var g=b(c),h=null;e?(h=new j.NodeList(f.children().get()),h.destroy(!0),f.empty(),f.append(g)):(h=new j.NodeList(f.get()),h.destroy(!0),f.replaceWith(g)),o(d),i.notifyFilterContentUpdated(g)}};return n.prototype.render=function(a,c,d){var e=b.Deferred();"undefined"==typeof d&&(d=g.theme),this.currentThemeName=d;var f=this.getTemplate(a,!0);return f.done(function(a){var b=this.doRender(a,c,d);b.done(function(a,b){e.resolve(a,b)}).fail(function(a){e.reject(a)})}.bind(this)).fail(function(a){e.reject(a)}),e.promise()},{render:function(a,b,c){var d=new n;return d.render(a,b,c)},runTemplateJS:o,replaceNodeContents:function(a,b,c){return p(a,b,c,!0)},replaceNode:function(a,b,c){return p(a,b,c,!1)}}});
|
||||
define(["core/mustache","jquery","core/ajax","core/str","core/notification","core/url","core/log","core/config","core/localstorage","core/event","core/yui","core/log"],function(a,b,c,d,e,f,g,h,i,j,k,l){var m=0,n={},o={},p=function(){this.requiredStrings=[],this.requiredJS=[],this.currentThemeName=""};p.prototype.requiredStrings=null,p.prototype.requiredJS=null,p.prototype.currentThemeName="",p.prototype.getTemplate=function(a){var d=a.split("/"),e=d.shift(),f=d.shift(),g=this.currentThemeName+"/"+a;if(g in o)return o[g];var h=i.get("core_template/"+g);if(h)return n[g]=h,o[g]=b.Deferred().resolve(h).promise(),o[g];var j=c.call([{methodname:"core_output_load_template",args:{component:e,template:f,themename:this.currentThemeName}}],!0,!1);return o[g]=j[0].then(function(a){return n[g]=a,i.set("core_template/"+g,a),a}),o[g]},p.prototype.partialHelper=function(a){var b=this.currentThemeName+"/"+a;return b in n||e.exception(new Error("Failed to pre-fetch the template: "+a)),n[b]},p.prototype.pixHelper=function(b,c,d){var e,g=c.split(","),h="",i="",j="";g.length>0&&(h=g.shift().trim()),g.length>0&&(i=g.shift().trim()),g.length>0&&(j=g.join(",").trim());var k=f.imageUrl(h,i),l={attributes:[{name:"src",value:k},{name:"alt",value:d(j)},{name:"title",value:d(j)},{name:"class",value:"smallicon"}]},m=this.currentThemeName+"/core/pix_icon",o=n[m];return e=a.render(o,l,this.partialHelper.bind(this)),e.trim()},p.prototype.jsHelper=function(a,b,c){return this.requiredJS.push(c(b,a)),""},p.prototype.stringHelper=function(a,b,c){var d=b.split(","),e="",f="",g="";d.length>0&&(e=d.shift().trim()),d.length>0&&(f=d.shift().trim()),d.length>0&&(g=d.join(",").trim()),""!==g&&(g=c(g,a)),0===g.indexOf("{")&&0!==g.indexOf("{{")&&(g=JSON.parse(g));var h=this.requiredStrings.length;return this.requiredStrings.push({key:e,component:f,param:g}),"[[_s"+h+"]]"},p.prototype.quoteHelper=function(a,b,c){var d=c(b.trim(),a);return d=d.replace('"','\\"').replace(/([\{\}]{2,3})/g,"{{=<% %>=}}$1<%={{ }}=%>"),'"'+d+'"'},p.prototype.addHelpers=function(a,b){this.currentThemeName=b,this.requiredStrings=[],this.requiredJS=[],a.uniqid=m++,a.str=function(){return this.stringHelper.bind(this,a)}.bind(this),a.pix=function(){return this.pixHelper.bind(this,a)}.bind(this),a.js=function(){return this.jsHelper.bind(this,a)}.bind(this),a.quote=function(){return this.quoteHelper.bind(this,a)}.bind(this),a.globals={config:h},a.currentTheme=b},p.prototype.getJS=function(a){var b="";return this.requiredJS.length>0&&(b=this.requiredJS.join(";\n")),this.treatStringsInContent(b,a)},p.prototype.treatStringsInContent=function(a,b){var c,d,e,f,g,h,i=/\[\[_s\d+\]\]/;do{for(c="",d=a.search(i);d>-1;){c+=a.substring(0,d),a=a.substr(d),e="",f=4,g=a.substr(f,1);do e+=g,f++,g=a.substr(f,1);while("]"!=g);h=b[parseInt(e,10)],"undefined"==typeof h&&(l.debug("Could not find string for pattern [[_s"+e+"]]."),h=""),c+=h,a=a.substr(6+e.length),d=a.search(i)}a=c+a,d=a.search(i)}while(d>-1);return a},p.prototype.doRender=function(c,e,f){return this.currentThemeName=f,this.getTemplate("core/pix_icon").then(function(){this.addHelpers(e,f);var g=a.render(c,e,this.partialHelper.bind(this));return this.requiredStrings.length>0?d.get_strings(this.requiredStrings).then(function(a){return g=this.treatStringsInContent(g,a),b.Deferred().resolve(g,this.getJS(a)).promise()}.bind(this)):b.Deferred().resolve(g.trim(),this.getJS([])).promise()}.bind(this))};var q=function(a){if(""!==a.trim()){var c=b("<script>").attr("type","text/javascript").html(a);b("head").append(c)}},r=function(a,c,d,e){var f=b(a);if(f.length){var g=b(c),h=null;e?(h=new k.NodeList(f.children().get()),h.destroy(!0),f.empty(),f.append(g)):(h=new k.NodeList(f.get()),h.destroy(!0),f.replaceWith(g)),q(d),j.notifyFilterContentUpdated(g)}};return p.prototype.scanForPartials=function(b){var c=a.parse(b),d=[],e=function(a,b){var c,d;for(c=0;c<a.length;c++)d=a[c],(">"==d[0]||"<"==d[0])&&b.push(d[1]),d.length>4&&e(d[4],b)};return e(c,d),d},p.prototype.cachePartials=function(a){return this.getTemplate(a).then(function(a){var c,d=this.scanForPartials(a),e=[];for(c=0;c<d.length;c++){var f=this.currentThemeName+"/"+d[c];f in o||e.push(this.cachePartials(d[c]))}return b.when.apply(b,e).then(function(){return a})}.bind(this))},p.prototype.render=function(a,b,c){return"undefined"==typeof c&&(c=h.theme),this.currentThemeName=c,this.cachePartials(a).then(function(a){return this.doRender(a,b,c)}.bind(this))},{render:function(a,b,c){var d=new p;return d.render(a,b,c)},runTemplateJS:q,replaceNodeContents:function(a,b,c){return r(a,b,c,!0)},replaceNode:function(a,b,c){return r(a,b,c,!1)}}});
|
||||
+1
-3
@@ -87,9 +87,7 @@ define(['jquery', 'core/config'], function($, config) {
|
||||
for (i = 0; i < requests.length; i++) {
|
||||
var request = requests[i];
|
||||
|
||||
if (typeof request.fail != "undefined") {
|
||||
request.deferred.reject(textStatus);
|
||||
}
|
||||
request.deferred.reject(textStatus);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
|
||||
ENTER: 13,
|
||||
SPACE: 32,
|
||||
ESCAPE: 27,
|
||||
COMMA: 188,
|
||||
COMMA: 44,
|
||||
UP: 38
|
||||
};
|
||||
|
||||
@@ -544,14 +544,6 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
|
||||
// We handled this event, so prevent it.
|
||||
e.preventDefault();
|
||||
return false;
|
||||
case KEYS.COMMA:
|
||||
if (options.tags) {
|
||||
// If we are allowing tags, comma should create a tag (or enter).
|
||||
createItem(options, state, originalSelect);
|
||||
}
|
||||
// We handled this event, so prevent it.
|
||||
e.preventDefault();
|
||||
return false;
|
||||
case KEYS.UP:
|
||||
// Choose the previous active item.
|
||||
activatePreviousItem(state);
|
||||
@@ -582,6 +574,19 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
|
||||
}
|
||||
return true;
|
||||
});
|
||||
// Support multi lingual COMMA keycode (44).
|
||||
inputElement.on('keypress', function(e) {
|
||||
if (e.keyCode === KEYS.COMMA) {
|
||||
if (options.tags) {
|
||||
// If we are allowing tags, comma should create a tag (or enter).
|
||||
createItem(options, state, originalSelect);
|
||||
}
|
||||
// We handled this event, so prevent it.
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
// Handler used to force set the value from behat.
|
||||
inputElement.on('behat:set-value', function() {
|
||||
var suggestionsElement = $(document.getElementById(state.suggestionsId));
|
||||
|
||||
+43
-13
@@ -26,6 +26,7 @@
|
||||
*/
|
||||
define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage) {
|
||||
|
||||
var promiseCache = [];
|
||||
|
||||
return /** @alias module:core/str */ {
|
||||
// Public variables and functions.
|
||||
@@ -67,6 +68,7 @@ define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage)
|
||||
var i = 0;
|
||||
var missing = false;
|
||||
var request;
|
||||
|
||||
// Try from local storage. If it's there - put it in M.str and resolve it.
|
||||
|
||||
for (i = 0; i < requests.length; i++) {
|
||||
@@ -74,10 +76,11 @@ define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage)
|
||||
if (typeof request.lang === "undefined") {
|
||||
request.lang = $('html').attr('lang').replace('-', '_');
|
||||
}
|
||||
request.cacheKey = 'core_str/' + request.key + '/' + request.component + '/' + request.lang;
|
||||
if (typeof M.str[request.component] === "undefined" ||
|
||||
typeof M.str[request.component][request.key] === "undefined") {
|
||||
// Try and revive it from local storage.
|
||||
var cached = storage.get('core_str/' + request.key + '/' + request.component + '/' + request.lang);
|
||||
var cached = storage.get(request.cacheKey);
|
||||
if (cached) {
|
||||
if (typeof M.str[request.component] === "undefined") {
|
||||
M.str[request.component] = [];
|
||||
@@ -99,25 +102,52 @@ define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage)
|
||||
}
|
||||
deferred.resolve(results);
|
||||
} else {
|
||||
// Something is missing, we might as well load them all.
|
||||
var ajaxrequests = [];
|
||||
var fetchpromises = [];
|
||||
|
||||
// Done handler for ajax call. Must be bound to the current fetchpromise. We do this
|
||||
// to avoid creating a function in a loop.
|
||||
var doneFunc = function(str) {
|
||||
this.resolve(str);
|
||||
};
|
||||
|
||||
var failFunc = function(reason) {
|
||||
this.reject(reason);
|
||||
};
|
||||
|
||||
for (i = 0; i < requests.length; i++) {
|
||||
request = requests[i];
|
||||
|
||||
ajaxrequests.push({
|
||||
methodname: 'core_get_string',
|
||||
args: {
|
||||
stringid: request.key,
|
||||
component: request.component,
|
||||
lang: request.lang,
|
||||
stringparams: []
|
||||
}
|
||||
});
|
||||
// If we ever fetched this string with a promise, reuse it.
|
||||
if (typeof promiseCache[request.cacheKey] !== 'undefined') {
|
||||
fetchpromises.push(promiseCache[request.cacheKey]);
|
||||
} else {
|
||||
// Add this to the list we need to really fetch.
|
||||
var fetchpromise = $.Deferred();
|
||||
|
||||
ajaxrequests.push({
|
||||
methodname: 'core_get_string',
|
||||
args: {
|
||||
stringid: request.key,
|
||||
component: request.component,
|
||||
lang: request.lang,
|
||||
stringparams: []
|
||||
},
|
||||
done: doneFunc.bind(fetchpromise),
|
||||
fail: failFunc.bind(fetchpromise)
|
||||
});
|
||||
|
||||
promiseCache[request.cacheKey] = fetchpromise.promise();
|
||||
fetchpromises.push(promiseCache[request.cacheKey]);
|
||||
}
|
||||
}
|
||||
|
||||
var deferreds = ajax.call(ajaxrequests, true, false);
|
||||
$.when.apply(null, deferreds).done(
|
||||
// Everything might already be queued so we need to check if we have real ajax requests to run.
|
||||
if (ajaxrequests.length > 0) {
|
||||
ajax.call(ajaxrequests, true, false);
|
||||
}
|
||||
|
||||
$.when.apply(null, fetchpromises).done(
|
||||
function() {
|
||||
// Turn the list of arguments (unknown length) into a real array.
|
||||
var i = 0;
|
||||
|
||||
+106
-84
@@ -29,21 +29,25 @@ define([ 'core/mustache',
|
||||
'core/str',
|
||||
'core/notification',
|
||||
'core/url',
|
||||
'core/log',
|
||||
'core/config',
|
||||
'core/localstorage',
|
||||
'core/event',
|
||||
'core/yui',
|
||||
'core/log'
|
||||
],
|
||||
function(mustache, $, ajax, str, notification, coreurl, config, storage, event, Y, Log) {
|
||||
function(mustache, $, ajax, str, notification, coreurl, log, config, storage, event, Y, Log) {
|
||||
|
||||
// Module variables.
|
||||
/** @var {Number} uniqInstances Count of times this constructor has been called. */
|
||||
var uniqInstances = 0;
|
||||
|
||||
/** @var {string[]} templateCache - Cache of already loaded templates */
|
||||
/** @var {String[]} templateCache - Cache of already loaded template strings */
|
||||
var templateCache = {};
|
||||
|
||||
/** @var {Promise[]} templatePromises - Cache of already loaded template promises */
|
||||
var templatePromises = {};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -75,8 +79,7 @@ define([ 'core/mustache',
|
||||
* tool_bananas/yellow (admin/tool/bananas/templates/yellow.mustache)
|
||||
* @return {Promise} JQuery promise object resolved when the template has been fetched.
|
||||
*/
|
||||
Renderer.prototype.getTemplate = function(templateName, async) {
|
||||
var deferred = $.Deferred();
|
||||
Renderer.prototype.getTemplate = function(templateName) {
|
||||
var parts = templateName.split('/');
|
||||
var component = parts.shift();
|
||||
var name = parts.shift();
|
||||
@@ -84,18 +87,17 @@ define([ 'core/mustache',
|
||||
var searchKey = this.currentThemeName + '/' + templateName;
|
||||
|
||||
// First try request variables.
|
||||
if (searchKey in templateCache) {
|
||||
deferred.resolve(templateCache[searchKey]);
|
||||
return deferred.promise();
|
||||
if (searchKey in templatePromises) {
|
||||
return templatePromises[searchKey];
|
||||
}
|
||||
|
||||
// Now try local storage.
|
||||
var cached = storage.get('core_template/' + searchKey);
|
||||
|
||||
if (cached) {
|
||||
deferred.resolve(cached);
|
||||
templateCache[searchKey] = cached;
|
||||
return deferred.promise();
|
||||
templatePromises[searchKey] = $.Deferred().resolve(cached).promise();
|
||||
return templatePromises[searchKey];
|
||||
}
|
||||
|
||||
// Oh well - load via ajax.
|
||||
@@ -106,20 +108,16 @@ define([ 'core/mustache',
|
||||
template: name,
|
||||
themename: this.currentThemeName
|
||||
}
|
||||
}], async, false);
|
||||
}], true, false);
|
||||
|
||||
promises[0].done(
|
||||
function (templateSource) {
|
||||
storage.set('core_template/' + searchKey, templateSource);
|
||||
templatePromises[searchKey] = promises[0].then(
|
||||
function(templateSource) {
|
||||
templateCache[searchKey] = templateSource;
|
||||
deferred.resolve(templateSource);
|
||||
}
|
||||
).fail(
|
||||
function (ex) {
|
||||
deferred.reject(ex);
|
||||
storage.set('core_template/' + searchKey, templateSource);
|
||||
return templateSource;
|
||||
}
|
||||
);
|
||||
return deferred.promise();
|
||||
return templatePromises[searchKey];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -131,15 +129,14 @@ define([ 'core/mustache',
|
||||
* @return {string}
|
||||
*/
|
||||
Renderer.prototype.partialHelper = function(name) {
|
||||
var template = '';
|
||||
|
||||
this.getTemplate(name, false).done(
|
||||
function(source) {
|
||||
template = source;
|
||||
}
|
||||
).fail(notification.exception);
|
||||
var searchKey = this.currentThemeName + '/' + name;
|
||||
|
||||
return template;
|
||||
if (!(searchKey in templateCache)) {
|
||||
notification.exception(new Error('Failed to pre-fetch the template: ' + name));
|
||||
}
|
||||
|
||||
return templateCache[searchKey];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -179,7 +176,8 @@ define([ 'core/mustache',
|
||||
]
|
||||
};
|
||||
// We forced loading of this early, so it will be in the cache.
|
||||
var template = templateCache[this.currentThemeName + '/core/pix_icon'];
|
||||
var searchKey = this.currentThemeName + '/core/pix_icon';
|
||||
var template = templateCache[searchKey];
|
||||
result = mustache.render(template, templatecontext, this.partialHelper.bind(this));
|
||||
return result.trim();
|
||||
};
|
||||
@@ -391,44 +389,29 @@ define([ 'core/mustache',
|
||||
* @return {Promise} object
|
||||
*/
|
||||
Renderer.prototype.doRender = function(templateSource, context, themeName) {
|
||||
var deferred = $.Deferred();
|
||||
|
||||
this.currentThemeName = themeName;
|
||||
|
||||
// Make sure we fetch this first.
|
||||
var loadPixTemplate = this.getTemplate('core/pix_icon', true);
|
||||
return this.getTemplate('core/pix_icon').then(function() {
|
||||
this.addHelpers(context, themeName);
|
||||
var result = mustache.render(templateSource, context, this.partialHelper.bind(this));
|
||||
|
||||
loadPixTemplate.done(
|
||||
function() {
|
||||
this.addHelpers(context, themeName);
|
||||
var result = '';
|
||||
try {
|
||||
result = mustache.render(templateSource, context, this.partialHelper.bind(this));
|
||||
} catch (ex) {
|
||||
deferred.reject(ex);
|
||||
}
|
||||
if (this.requiredStrings.length > 0) {
|
||||
return str.get_strings(this.requiredStrings).then(function(strings) {
|
||||
|
||||
if (this.requiredStrings.length > 0) {
|
||||
str.get_strings(this.requiredStrings)
|
||||
.then(function(strings) {
|
||||
// Why do we not do another call the render here?
|
||||
//
|
||||
// Because that would expose DOS holes. E.g.
|
||||
// I create an assignment called "{{fish" which
|
||||
// would get inserted in the template in the first pass
|
||||
// and cause the template to die on the second pass (unbalanced).
|
||||
|
||||
// Why do we not do another call the render here?
|
||||
//
|
||||
// Because that would expose DOS holes. E.g.
|
||||
// I create an assignment called "{{fish" which
|
||||
// would get inserted in the template in the first pass
|
||||
// and cause the template to die on the second pass (unbalanced).
|
||||
|
||||
result = this.treatStringsInContent(result, strings);
|
||||
deferred.resolve(result, this.getJS(strings));
|
||||
}.bind(this))
|
||||
.fail(deferred.reject);
|
||||
} else {
|
||||
deferred.resolve(result.trim(), this.getJS([]));
|
||||
}
|
||||
}.bind(this)
|
||||
).fail(deferred.reject);
|
||||
return deferred.promise();
|
||||
result = this.treatStringsInContent(result, strings);
|
||||
return $.Deferred().resolve(result, this.getJS(strings)).promise();
|
||||
}.bind(this));
|
||||
} else {
|
||||
return $.Deferred().resolve(result.trim(), this.getJS([])).promise();
|
||||
}
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -485,6 +468,66 @@ define([ 'core/mustache',
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Scan a template source for partial tags and return a list of the found partials.
|
||||
*
|
||||
* @method scanForPartials
|
||||
* @private
|
||||
* @param {string} templateSource - source template to scan.
|
||||
* @return {Array} List of partials.
|
||||
*/
|
||||
Renderer.prototype.scanForPartials = function(templateSource) {
|
||||
var tokens = mustache.parse(templateSource),
|
||||
partials = [];
|
||||
|
||||
var findPartial = function(tokens, partials) {
|
||||
var i, token;
|
||||
for (i = 0; i < tokens.length; i++) {
|
||||
token = tokens[i];
|
||||
if (token[0] == '>' || token[0] == '<') {
|
||||
partials.push(token[1]);
|
||||
}
|
||||
if (token.length > 4) {
|
||||
findPartial(token[4], partials);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
findPartial(tokens, partials);
|
||||
|
||||
return partials;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load a template and scan it for partials. Recursively fetch the partials.
|
||||
*
|
||||
* @method cachePartials
|
||||
* @private
|
||||
* @param {string} templateName - should consist of the component and the name of the template like this:
|
||||
* core/menu (lib/templates/menu.mustache) or
|
||||
* tool_bananas/yellow (admin/tool/bananas/templates/yellow.mustache)
|
||||
* @return {Promise} JQuery promise object resolved when all partials are in the cache.
|
||||
*/
|
||||
Renderer.prototype.cachePartials = function(templateName) {
|
||||
return this.getTemplate(templateName).then(function(templateSource) {
|
||||
var i;
|
||||
var partials = this.scanForPartials(templateSource);
|
||||
var fetchThemAll = [];
|
||||
|
||||
for (i = 0; i < partials.length; i++) {
|
||||
var searchKey = this.currentThemeName + '/' + partials[i];
|
||||
if (searchKey in templatePromises) {
|
||||
continue;
|
||||
}
|
||||
fetchThemAll.push(this.cachePartials(partials[i]));
|
||||
}
|
||||
|
||||
return $.when.apply($, fetchThemAll).then(function() {
|
||||
return templateSource;
|
||||
});
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
* Load a template and call doRender on it.
|
||||
*
|
||||
@@ -498,8 +541,6 @@ define([ 'core/mustache',
|
||||
* @return {Promise} JQuery promise object resolved when the template has been rendered.
|
||||
*/
|
||||
Renderer.prototype.render = function(templateName, context, themeName) {
|
||||
var deferred = $.Deferred();
|
||||
|
||||
if (typeof (themeName) === "undefined") {
|
||||
// System context by default.
|
||||
themeName = config.theme;
|
||||
@@ -507,28 +548,9 @@ define([ 'core/mustache',
|
||||
|
||||
this.currentThemeName = themeName;
|
||||
|
||||
var loadTemplate = this.getTemplate(templateName, true);
|
||||
|
||||
loadTemplate.done(
|
||||
function(templateSource) {
|
||||
var renderPromise = this.doRender(templateSource, context, themeName);
|
||||
|
||||
renderPromise.done(
|
||||
function(result, js) {
|
||||
deferred.resolve(result, js);
|
||||
}
|
||||
).fail(
|
||||
function(ex) {
|
||||
deferred.reject(ex);
|
||||
}
|
||||
);
|
||||
}.bind(this)
|
||||
).fail(
|
||||
function(ex) {
|
||||
deferred.reject(ex);
|
||||
}
|
||||
);
|
||||
return deferred.promise();
|
||||
return this.cachePartials(templateName).then(function(templateSource) {
|
||||
return this.doRender(templateSource, context, themeName);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -886,4 +886,22 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
|
||||
// Look for exceptions.
|
||||
$this->look_for_exceptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actual user in the behat session (note $USER does not correspond to the behat session's user).
|
||||
* @return mixed
|
||||
* @throws coding_exception
|
||||
*/
|
||||
protected function get_session_user() {
|
||||
global $DB;
|
||||
$sid = $this->getSession()->getCookie('MoodleSession');
|
||||
if (empty($sid)) {
|
||||
throw new coding_exception('failed to get moodle session');
|
||||
}
|
||||
$userid = $DB->get_field('sessions', 'userid', ['sid' => $sid]);
|
||||
if (empty($userid)) {
|
||||
throw new coding_exception('failed to get user from seession id '.$sid);
|
||||
}
|
||||
return $DB->get_record('user', ['id' => $userid]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,16 @@ abstract class base implements \IteratorAggregate {
|
||||
*/
|
||||
const NOT_FOUND = -31338;
|
||||
|
||||
/**
|
||||
* User id to use when the user is not logged in.
|
||||
*/
|
||||
const USER_NOTLOGGEDIN = 0;
|
||||
|
||||
/**
|
||||
* User id to use when actor is not an actual user but system, cli or cron.
|
||||
*/
|
||||
const USER_OTHER = -1;
|
||||
|
||||
/** @var array event data */
|
||||
protected $data;
|
||||
|
||||
|
||||
@@ -53,10 +53,12 @@ class user_graded extends base {
|
||||
* Utility method to create new event.
|
||||
*
|
||||
* @param \grade_grade $grade
|
||||
* @param null|int $userid Id of user responsible for this event.
|
||||
*
|
||||
* @return user_graded
|
||||
*/
|
||||
public static function create_from_grade(\grade_grade $grade) {
|
||||
$event = self::create(array(
|
||||
public static function create_from_grade(\grade_grade $grade, $userid = null) {
|
||||
$gradedata = array(
|
||||
'context' => \context_course::instance($grade->grade_item->courseid),
|
||||
'objectid' => $grade->id,
|
||||
'relateduserid' => $grade->userid,
|
||||
@@ -64,7 +66,11 @@ class user_graded extends base {
|
||||
'itemid' => $grade->itemid,
|
||||
'overridden' => !empty($grade->overridden),
|
||||
'finalgrade' => $grade->finalgrade),
|
||||
));
|
||||
);
|
||||
if ($userid !== null) {
|
||||
$gradedata["userid"] = $userid;
|
||||
}
|
||||
$event = self::create($gradedata);
|
||||
$event->grade = $grade;
|
||||
return $event;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ namespace core;
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use stdClass;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
class notification {
|
||||
@@ -82,6 +84,10 @@ class notification {
|
||||
// Add the notification directly to the session.
|
||||
// This will either be fetched in the header, or by JS in the footer.
|
||||
if (!isset($SESSION->notifications) || !array($SESSION->notifications)) {
|
||||
// Initialise $SESSION if necessary.
|
||||
if (!is_object($SESSION)) {
|
||||
$SESSION = new stdClass();
|
||||
}
|
||||
$SESSION->notifications = [];
|
||||
}
|
||||
$SESSION->notifications[] = (object) array(
|
||||
|
||||
@@ -80,6 +80,7 @@ class manager {
|
||||
}
|
||||
|
||||
self::initialise_user_session($isnewsession);
|
||||
self::$sessionactive = true; // Set here, so the session can be cleared if the security check fails.
|
||||
self::check_security();
|
||||
|
||||
// Link global $USER and $SESSION,
|
||||
@@ -97,8 +98,6 @@ class manager {
|
||||
self::$sessionactive = false;
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
self::$sessionactive = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -421,8 +421,16 @@ class manager {
|
||||
|
||||
foreach ($records as $record) {
|
||||
|
||||
if ($lock = $cronlockfactory->get_lock('adhoc_' . $record->id, 10)) {
|
||||
if ($lock = $cronlockfactory->get_lock('adhoc_' . $record->id, 0)) {
|
||||
$classname = '\\' . $record->classname;
|
||||
|
||||
// Safety check, see if the task has been already processed by another cron run.
|
||||
$record = $DB->get_record('task_adhoc', array('id' => $record->id));
|
||||
if (!$record) {
|
||||
$lock->release();
|
||||
continue;
|
||||
}
|
||||
|
||||
$task = self::adhoc_task_from_record($record);
|
||||
// Safety check in case the task in the DB does not match a real class (maybe something was uninstalled).
|
||||
if (!$task) {
|
||||
@@ -472,7 +480,7 @@ class manager {
|
||||
|
||||
foreach ($records as $record) {
|
||||
|
||||
if ($lock = $cronlockfactory->get_lock(($record->classname), 10)) {
|
||||
if ($lock = $cronlockfactory->get_lock(($record->classname), 0)) {
|
||||
$classname = '\\' . $record->classname;
|
||||
$task = self::scheduled_task_from_record($record);
|
||||
// Safety check in case the task in the DB does not match a real class (maybe something was uninstalled).
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user