$string['emailsalutation'] = 'Dear {$a},';
$string['errorcannotrequestdeleteforself'] = 'You don\'t have permission to create deletion request for yourself.';
$string['errorcannotrequestdeleteforother'] = 'You don\'t have permission to create deletion request for this user.';
-$string['errorinvalidrequestcomments'] = 'Please ensure your comment contains plain text only.';
+$string['errorinvalidrequestcomments'] = 'The comments field may contain plain text only.';
$string['errorinvalidrequestcreationmethod'] = 'Invalid request creation method!';
$string['errorinvalidrequeststatus'] = 'Invalid request status!';
$string['errorinvalidrequesttype'] = 'Invalid request type!';
| Test-Comp1 | ID-FW1 |
| Test-Comp2 | ID-FW1 |
Given the following "courses" exist:
- | shortname | fullname |
- | C1 | Course 1 |
+ | shortname | fullname | enablecompletion |
+ | C1 | Course 1 | 1 |
And the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
| user | course | role |
| student1 | C1 | student |
And the following "activities" exist:
- | activity | name | intro | course | idnumber |
- | page | PageName1 | PageDesc1 | C1 | PAGE1 |
- | page | PageName2 | PageDesc2 | C1 | PAGE2 |
+ | activity | name | intro | course | idnumber | completion | completionview |
+ | page | PageName1 | PageDesc1 | C1 | PAGE1 | 1 | 1 |
+ | page | PageName2 | PageDesc2 | C1 | PAGE2 | 1 | 1 |
And I log in as "admin"
And I am on site homepage
And I follow "Course 1"
And I should not see "Test-Comp1"
And I should not see "Test-Comp2"
And I should see "No competencies have been linked to this activity or resource."
+
+ @javascript
+ Scenario: None course competencies page.
+ When I log in as "student1"
+ And I am on site homepage
+ And I follow "Course 1"
+ And I follow "PageName1"
+ Then I should see "Test page content"
+ And I am on site homepage
+ And I follow "Course 1"
+ And I follow "PageName1"
+ Then I should see "Test page content"
*/
const CONFIG_SHIPPED_VERSION = 'shipped_version';
+ /**
+ * Helper method to initialize admin page, setting appropriate extra URL parameters
+ *
+ * @param string $action
+ */
+ protected function setup_admin_externalpage(string $action): void {
+ admin_externalpage_setup('tool_usertours/tours', '', array_filter([
+ 'action' => $action,
+ 'id' => optional_param('id', 0, PARAM_INT),
+ 'tourid' => optional_param('tourid', 0, PARAM_INT),
+ 'direction' => optional_param('direction', 0, PARAM_INT),
+ ]));
+ }
+
/**
* This is the entry point for this controller class.
*
* @param string $action The action to perform.
*/
public function execute($action) {
- admin_externalpage_setup('tool_usertours/tours');
+ $this->setup_admin_externalpage($action);
+
// Add the main content.
switch($action) {
case self::ACTION_NEWTOUR:
$cohortmanager = has_capability('moodle/cohort:manage', $cohortcontext);
$cohortcanassign = has_capability('moodle/cohort:assign', $cohortcontext);
- $urlparams = array('id' => $cohort->id, 'returnurl' => $baseurl->out_as_local_url());
+ $urlparams = array('id' => $cohort->id, 'returnurl' => $baseurl->out_as_local_url(false));
$showhideurl = new moodle_url('/cohort/edit.php', $urlparams + array('sesskey' => sesskey()));
if ($cohortmanager) {
if ($cohort->visible) {
$recommend = false;
$strdesc = 'evidence_coursemodulecompleted';
+ if ($outcome == course_module_competency::OUTCOME_NONE) {
+ continue;
+ }
if ($outcome == course_module_competency::OUTCOME_EVIDENCE) {
$action = evidence::ACTION_LOG;
$recommend = false;
$strdesc = 'evidence_coursecompleted';
+ if ($outcome == course_module_competency::OUTCOME_NONE) {
+ continue;
+ }
if ($outcome == course_competency::OUTCOME_EVIDENCE) {
$action = evidence::ACTION_LOG;
unset($library->major_version);
$library->minorVersion = (int) $library->minorversion;
unset($library->minorversion);
+ $library->metadataSettings = json_decode($library->metadatasettings);
// If we already add this library means that it is an old version,as the previous query was sorted by version.
if (isset($added[$library->name])) {
if ($libraries !== null) {
// Get details for the specified libraries.
$librariesin = [];
- $fields = 'title, runnable';
+ $fields = 'title, runnable, metadatasettings';
foreach ($libraries as $library) {
$params = [
if ($details) {
$library->title = $details->title;
$library->runnable = $details->runnable;
+ $library->metadataSettings = json_decode($details->metadatasettings);
$librariesin[] = $library;
}
}
} else {
- $fields = 'id, machinename as name, title, majorversion, minorversion';
+ $fields = 'id, machinename as name, title, majorversion, minorversion, metadatasettings';
$librariesin = api::get_contenttype_libraries($fields);
}
* - dropLibraryCss(optional): list of associative arrays containing:
* - machineName: machine name for the librarys that are to drop their css
* - semantics(optional): Json describing the content structure for the library
+ * - metadataSettings(optional): object containing:
+ * - disable: 1 if metadata is disabled completely
+ * - disableExtraTitleField: 1 if the title field is hidden in the form
* @param bool $new Whether it is a new or existing library.
*/
public function saveLibraryData(&$librarydata, $new = true) {
'addto' => isset($librarydata['addTo']) ? json_encode($librarydata['addTo']) : null,
'coremajor' => isset($librarydata['coreApi']['majorVersion']) ? $librarydata['coreApi']['majorVersion'] : null,
'coreminor' => isset($librarydata['coreApi']['majorVersion']) ? $librarydata['coreApi']['minorVersion'] : null,
+ 'metadatasettings' => isset($librarydata['metadataSettings']) ? $librarydata['metadataSettings'] : null,
);
if ($new) {
'addto' => '/regex11/',
'coremajor' => null,
'coreminor' => null,
+ 'metadatasettings' => null,
];
$this->assertEquals($expected, $data);
Mesedez, erabili --help aukera.';
$string['cliyesnoprompt'] = 'idatzi b (bai esateko) edo e (ez esateko)';
$string['environmentrequireinstall'] = 'derrigorrezkoa da instalatuta eta gaituta izatea';
-$string['environmentrequireversion'] = '{$a->needed} bertsioa beharrezkoa da eta zu {$a->current} ari zara egikaritzen';
+$string['environmentrequireversion'] = '{$a->needed} bertsioa beharrezkoa da eta zu {$a->current} ari zara exekutatzen';
$string['upgradekeyset'] = 'Eguneraketa-kodea (utzi hutsik kodea erabili nahi ez baduzu)';
--- /dev/null
+<?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'] = 'Qaraqalpaq tili';
--- /dev/null
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Automatically generated strings for Moodle installer
+ *
+ * Do not edit this file manually! It contains just a subset of strings
+ * needed during the very first steps of installation. This file was
+ * generated automatically by export-installer.php (which is part of AMOS
+ * {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
+ * list of strings defined in /install/stringnames.txt.
+ *
+ * @package installer
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$string['language'] = 'زبان';
+$string['moodlelogo'] = 'لوگوی مودل (Moodle)';
+$string['next'] = 'بعدی';
+$string['previous'] = 'قبلی';
+$string['reload'] = 'بارگیری مجدد';
$string['error:invalidexpireperiod'] = 'Expiry period cannot be negative or equal 0.';
$string['error:invalidparambadge'] = 'Badge does not exist. ';
$string['error:noactivities'] = 'There are no activities with completion criteria enabled in this course.';
-$string['error:nobadges'] = 'There are no course or site badges with access enabled to be added as criteria.';
+$string['error:nobadges'] = 'There are currently no badges with access enabled to be added as criteria. A site badge can only have other site badges as criteria. A course badge can have other course badges or site badges as criteria.';
$string['error:invalidparamcohort'] = 'Cohort does not exist. ';
$string['error:noactivities'] = 'There are no activities with completion criteria enabled in this course.';
$string['error:nocohorts'] = 'No cohorts';
$string['eventcontentuploaded'] = 'Content uploaded';
$string['eventcontentviewed'] = 'Content viewed';
$string['errordeletingcontentfromcategory'] = 'Error deleting content from category {$a}.';
-$string['errornofile'] = 'A compatible file is needed to create a content';
+$string['errornofile'] = 'A compatible file is needed to create content.';
$string['deletecontent'] = 'Delete content';
$string['deletecontentconfirm'] = 'Are you sure you want to delete the content <em>\'{$a->name}\'</em> and all associated files? This action cannot be undone.';
$string['displaydetails'] = 'Display content bank with file details';
public function execute() {
global $DB;
- $timenow = time();
-
- // Delete old backup_controllers and logs.
$loglifetime = get_config('backup', 'loglifetime');
- if (!empty($loglifetime)) { // Value in days.
- $loglifetime = $timenow - ($loglifetime * 3600 * 24);
- // Delete child records from backup_logs.
- $DB->execute("DELETE FROM {backup_logs}
- WHERE EXISTS (
- SELECT 'x'
- FROM {backup_controllers} bc
- WHERE bc.backupid = {backup_logs}.backupid
- AND bc.timecreated < ?)", array($loglifetime));
- // Delete records from backup_controllers.
- $DB->execute("DELETE FROM {backup_controllers}
- WHERE timecreated < ?", array($loglifetime));
+
+ if (empty($loglifetime)) {
+ throw new coding_exception('The \'loglifetime\' config is not set. Can\'t proceed and delete old backup records.');
}
+ // First, get the list of all backupids older than loglifetime.
+ $timecreated = time() - ($loglifetime * DAYSECS);
+ $records = $DB->get_records_select('backup_controllers', 'timecreated < ?', array($timecreated), 'id', 'id, backupid');
+
+ foreach ($records as $record) {
+ // Check if there is no incomplete adhoc task relying on the given backupid.
+ $params = array('%' . $record->backupid . '%');
+ $select = $DB->sql_like('customdata', '?', false);
+ $count = $DB->count_records_select('task_adhoc', $select, $params);
+ if ($count === 0) {
+ // Looks like there is no adhoc task, so we can delete logs and controllers for this backupid.
+ $DB->delete_records('backup_logs', array('backupid' => $record->backupid));
+ $DB->delete_records('backup_controllers', array('backupid' => $record->backupid));
+ }
+ }
}
}
<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="lib/db" VERSION="20200504" COMMENT="XMLDB file for core Moodle tables"
+<XMLDB PATH="lib/db" VERSION="20200804" COMMENT="XMLDB file for core Moodle tables"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
>
<FIELD NAME="addto" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="Plugin configuration data"/>
<FIELD NAME="coremajor" TYPE="int" LENGTH="4" NOTNULL="false" SEQUENCE="false" COMMENT="H5P core API major version required"/>
<FIELD NAME="coreminor" TYPE="int" LENGTH="4" NOTNULL="false" SEQUENCE="false" COMMENT="H5P core API minor version required"/>
+ <FIELD NAME="metadatasettings" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="Library metadata settings"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</INDEXES>
</TABLE>
</TABLES>
-</XMLDB>
\ No newline at end of file
+</XMLDB>
upgrade_main_savepoint(true, 2020061501.09);
}
+ if ($oldversion < 2020061501.11) {
+
+ // Define field metadatasettings to be added to h5p_libraries.
+ $table = new xmldb_table('h5p_libraries');
+ $field = new xmldb_field('metadatasettings', XMLDB_TYPE_TEXT, null, null, null, null, null, 'coreminor');
+
+ // Conditionally launch add field metadatasettings.
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ // Get installed library files that have no metadata settings value.
+ $params = [
+ 'component' => 'core_h5p',
+ 'filearea' => 'libraries',
+ 'filename' => 'library.json',
+ ];
+ $sql = "SELECT l.id, f.id as fileid
+ FROM {files} f
+ LEFT JOIN {h5p_libraries} l ON f.itemid = l.id
+ WHERE f.component = :component
+ AND f.filearea = :filearea
+ AND f.filename = :filename";
+ $libraries = $DB->get_records_sql($sql, $params);
+
+ // Update metadatasettings field when the attribute is present in the library.json file.
+ $fs = get_file_storage();
+ foreach ($libraries as $library) {
+ $jsonfile = $fs->get_file_by_id($library->fileid);
+ $jsoncontent = json_decode($jsonfile->get_content());
+ if (isset($jsoncontent->metadataSettings)) {
+ unset($library->fileid);
+ $library->metadatasettings = json_encode($jsoncontent->metadataSettings);
+ $DB->update_record('h5p_libraries', $library);
+ }
+ }
+
+ // Main savepoint reached.
+ upgrade_main_savepoint(true, 2020061501.11);
+ }
+
return true;
}
* Duration element
*
* HTML class for a length of time. For example, 30 minutes of 4 days. The
- * values returned to PHP is the duration in seconds.
+ * values returned to PHP is the duration in seconds (an int rounded to the nearest second).
*
* @package core_form
* @category form
if ($this->_options['optional'] && empty($valuearray['enabled'])) {
return $this->_prepareValue(0, $assoc);
}
- return $this->_prepareValue($valuearray['number'] * $valuearray['timeunit'], $assoc);
+ return $this->_prepareValue(
+ (int) round($valuearray['number'] * $valuearray['timeunit']), $assoc);
}
}
*
* @return MoodleQuickForm
*/
- protected function get_test_form() {
+ protected function get_test_form(): MoodleQuickForm {
$form = new temp_form_duration();
return $form->getform();
}
*
* @return array with two elements, a MoodleQuickForm and a MoodleQuickForm_duration.
*/
- protected function get_test_form_and_element() {
+ protected function get_test_form_and_element(): array {
$mform = $this->get_test_form();
$element = $mform->addElement('duration', 'duration');
return [$mform, $element];
}
/**
- * Testcase for testing contructor.
- *
- * @expectedException coding_exception
+ * Test the constructor error handling.
*/
- public function test_constructor() {
+ public function test_constructor_rejects_invalid_unit(): void {
// Test trying to create with an invalid unit.
$mform = $this->get_test_form();
+ $this->expectException('coding_exception');
$mform->addElement('duration', 'testel', null, ['defaultunit' => 123, 'optional' => false]);
}
/**
- * Test contructor only some units.
+ * Test constructor only some units.
*/
- public function test_constructor_limited_units() {
+ public function test_constructor_limited_units(): void {
$mform = $this->get_test_form();
$mform->addElement('duration', 'testel', null, ['units' => [MINSECS, 1], 'optional' => false]);
$html = $mform->toHtml();
/**
* Testcase for testing units (seconds, minutes, hours and days)
*/
- public function test_get_units() {
+ public function test_get_units(): void {
[$mform, $element] = $this->get_test_form_and_element();
$units = $element->get_units();
$this->assertEquals($units, [1 => get_string('seconds'), 60 => get_string('minutes'),
}
/**
- * Testcase for testing conversion of seconds to the best possible unit
+ * Data provider for {@see test_seconds_to_unit()}.
+ *
+ * @return array test cases.
*/
- public function test_seconds_to_unit() {
- [$mform, $element] = $this->get_test_form_and_element();
- $this->assertEquals([0, MINSECS], $element->seconds_to_unit(0)); // Zero minutes, for a nice default unit.
- $this->assertEquals([1, 1], $element->seconds_to_unit(1));
- $this->assertEquals([3601, 1], $element->seconds_to_unit(3601));
- $this->assertEquals([1, MINSECS], $element->seconds_to_unit(60));
- $this->assertEquals([3, MINSECS], $element->seconds_to_unit(180));
- $this->assertEquals([1, HOURSECS], $element->seconds_to_unit(3600));
- $this->assertEquals([2, HOURSECS], $element->seconds_to_unit(7200));
- $this->assertEquals([1, DAYSECS], $element->seconds_to_unit(86400));
- $this->assertEquals([25, HOURSECS], $element->seconds_to_unit(90000));
+ public function seconds_to_unit_cases(): array {
+ return [
+ [[0, MINSECS], 0], // Zero minutes, for a nice default unit.
+ [[1, 1], 1],
+ [[3601, 1], 3601],
+ [[1, MINSECS], 60],
+ [[3, MINSECS], 180],
+ [[1, HOURSECS], 3600],
+ [[2, HOURSECS], 7200],
+ [[1, DAYSECS], 86400],
+ [[25, HOURSECS], 90000],
+ ];
+ }
+ /**
+ * Testcase for testing conversion of seconds to the best possible unit.
+ *
+ * @dataProvider seconds_to_unit_cases
+ * @param array $expected expected return value from seconds_to_unit
+ * @param int $seconds value to pass to seconds_to_unit
+ */
+ public function test_seconds_to_unit(array $expected, int $seconds): void {
+ [, $element] = $this->get_test_form_and_element();
+ $this->assertEquals($expected, $element->seconds_to_unit($seconds));
+ }
+
+ /**
+ * Testcase for testing conversion of seconds to the best possible unit with a non-default default unit.
+ */
+ public function test_seconds_to_unit_different_default_unit() {
+ $mform = $this->get_test_form();
$element = $mform->addElement('duration', 'testel', null,
['defaultunit' => DAYSECS, 'optional' => false]);
- $this->assertEquals([0, DAYSECS], $element->seconds_to_unit(0)); // Zero minutes, for a nice default unit.
+ $this->assertEquals([0, DAYSECS], $element->seconds_to_unit(0));
+ }
+
+ /**
+ * Data provider for {@see test_export_value()}.
+ *
+ * @return array test cases.
+ */
+ public function export_value_cases(): array {
+ return [
+ [10, '10', 1],
+ [9, '9.3', 1],
+ [10, '9.5', 1],
+ [180, '3', MINSECS],
+ [90, '1.5', MINSECS],
+ [7200, '2', HOURSECS],
+ [86400, '1', DAYSECS],
+ [0, '0', HOURSECS],
+ [0, '10', 1, 0, true],
+ [20, '20', 1, 1, true],
+ [0, '10', 1, 0, true, ''],
+ [20, '20', 1, 1, true, ''],
+ ];
}
/**
* Testcase to check generated timestamp
+ *
+ * @dataProvider export_value_cases
+ * @param int $expected Expected value returned by the element.
+ * @param string $number Number entered into the element.
+ * @param int $unit Unit selected in the element.
+ * @param int $enabled Whether the enabled checkbox on the form was selected. (Only used if $optional is true.)
+ * @param bool $optional Whether the element has the optional option on.
+ * @param string|null $label The element's label.
*/
- public function test_exportValue() {
+ public function test_export_value(int $expected, string $number, int $unit, int $enabled = 0,
+ bool $optional = false, ?string $label = null): void {
+
+ // Create the test element.
$mform = $this->get_test_form();
- $el = $mform->addElement('duration', 'testel');
- $values = ['testel' => ['number' => 10, 'timeunit' => 1]];
- $this->assertEquals(['testel' => 10], $el->exportValue($values, true));
- $this->assertEquals(10, $el->exportValue($values));
- $values = ['testel' => ['number' => 3, 'timeunit' => MINSECS]];
- $this->assertEquals(['testel' => 180], $el->exportValue($values, true));
- $this->assertEquals(180, $el->exportValue($values));
- $values = ['testel' => ['number' => 1.5, 'timeunit' => MINSECS]];
- $this->assertEquals(['testel' => 90], $el->exportValue($values, true));
- $this->assertEquals(90, $el->exportValue($values));
- $values = ['testel' => ['number' => 2, 'timeunit' => HOURSECS]];
- $this->assertEquals(['testel' => 7200], $el->exportValue($values, true));
- $this->assertEquals(7200, $el->exportValue($values));
- $values = ['testel' => ['number' => 1, 'timeunit' => DAYSECS]];
- $this->assertEquals(['testel' => 86400], $el->exportValue($values, true));
- $this->assertEquals(86400, $el->exportValue($values));
- $values = ['testel' => ['number' => 0, 'timeunit' => HOURSECS]];
- $this->assertEquals(['testel' => 0], $el->exportValue($values, true));
- $this->assertEquals(0, $el->exportValue($values));
-
- $el = $mform->addElement('duration', 'testel', null, ['optional' => true]);
- $values = ['testel' => ['number' => 10, 'timeunit' => 1]];
- $this->assertEquals(['testel' => 0], $el->exportValue($values, true));
- $this->assertEquals(0, $el->exportValue($values));
- $values = ['testel' => ['number' => 20, 'timeunit' => 1, 'enabled' => 1]];
- $this->assertEquals(['testel' => 20], $el->exportValue($values, true));
- $this->assertEquals(20, $el->exportValue($values));
-
- // Optional element.
- $el2 = $mform->addElement('duration', 'testel', '', ['optional' => true]);
- $values = ['testel' => ['number' => 10, 'timeunit' => 1, 'enabled' => 1]];
- $this->assertEquals(['testel' => 10], $el2->exportValue($values, true));
- $this->assertEquals(10, $el2->exportValue($values));
- $values = ['testel' => ['number' => 10, 'timeunit' => 1, 'enabled' => 0]];
- $this->assertEquals(['testel' => 0], $el2->exportValue($values, true));
- $this->assertEquals(null, $el2->exportValue($values));
+ $el = $mform->addElement('duration', 'testel', $label, $optional ? ['optional' => true] : []);
+
+ // Prepare the submitted values.
+ $values = ['testel' => ['number' => $number, 'timeunit' => $unit]];
+ if ($optional) {
+ $values['testel']['enabled'] = $enabled;
+ }
+
+ // Test.
+ $this->assertEquals(['testel' => $expected], $el->exportValue($values, true));
+ $this->assertEquals($expected, $el->exportValue($values));
}
}
this.set_date_from_selects();
}
M.form.dateselector.currentowner = this;
- M.form.dateselector.calendar.set('mindate', new Date(this.yearselect.firstOptionValue(), 0, 1));
- M.form.dateselector.calendar.set('maxdate', new Date(this.yearselect.lastOptionValue(), 11, 31));
+ M.form.dateselector.calendar.set('minimumDate', new Date(this.yearselect.firstOptionValue(), 0, 1));
+ M.form.dateselector.calendar.set('maximumDate', new Date(this.yearselect.lastOptionValue(), 11, 31));
M.form.dateselector.panel.show();
M.form.dateselector.calendar.show();
M.form.dateselector.fix_position();
$this->assertContains('2:15 AM', core_text::strtoupper($userdate));
}
- public function test_reset_scheduled_tasks_for_component() {
- global $DB;
-
+ public function test_reset_scheduled_tasks_for_component_customised(): void {
$this->resetAfterTest(true);
- // Remember the defaults.
- $defaulttasks = \core\task\manager::load_scheduled_tasks_for_component('moodle');
- $initcount = count($defaulttasks);
+
+ $tasks = \core\task\manager::load_scheduled_tasks_for_component('moodle');
+
// Customise a task.
- $firsttask = reset($defaulttasks);
- $firsttask->set_minute('1');
- $firsttask->set_hour('2');
- $firsttask->set_month('3');
- $firsttask->set_day_of_week('4');
- $firsttask->set_day('5');
- $firsttask->set_customised('1');
- \core\task\manager::configure_scheduled_task($firsttask);
- $firsttaskrecord = \core\task\manager::record_from_scheduled_task($firsttask);
- // We reset this field, because we do not want to compare it.
- $firsttaskrecord->nextruntime = '0';
+ $task = reset($tasks);
+ $task->set_minute('1');
+ $task->set_hour('2');
+ $task->set_month('3');
+ $task->set_day_of_week('4');
+ $task->set_day('5');
+ $task->set_customised('1');
+ \core\task\manager::configure_scheduled_task($task);
+
+ // Now call reset.
+ \core\task\manager::reset_scheduled_tasks_for_component('moodle');
+
+ // Fetch the task again.
+ $taskafterreset = \core\task\manager::get_scheduled_task(get_class($task));
+
+ // The task should still be the same as the customised.
+ $this->assertTaskEquals($task, $taskafterreset);
+ }
+
+ public function test_reset_scheduled_tasks_for_component_deleted(): void {
+ global $DB;
+ $this->resetAfterTest(true);
// Delete a task to simulate the fact that its new.
- $secondtask = next($defaulttasks);
- $DB->delete_records('task_scheduled', array('classname' => '\\' . trim(get_class($secondtask), '\\')));
- $this->assertFalse(\core\task\manager::get_scheduled_task(get_class($secondtask)));
+ $tasklist = \core\task\manager::load_scheduled_tasks_for_component('moodle');
- // Edit a task to simulate a change in its definition (as if it was not customised).
- $thirdtask = next($defaulttasks);
- $thirdtask->set_minute('1');
- $thirdtask->set_hour('2');
- $thirdtask->set_month('3');
- $thirdtask->set_day_of_week('4');
- $thirdtask->set_day('5');
- $thirdtaskbefore = \core\task\manager::get_scheduled_task(get_class($thirdtask));
- $thirdtaskbefore->set_next_run_time(null); // Ignore this value when comparing.
- \core\task\manager::configure_scheduled_task($thirdtask);
- $thirdtask = \core\task\manager::get_scheduled_task(get_class($thirdtask));
- $thirdtask->set_next_run_time(null); // Ignore this value when comparing.
- $this->assertNotEquals($thirdtaskbefore, $thirdtask);
+ // Note: This test must use a task which does not use any random values.
+ $task = \core\task\manager::get_scheduled_task(core\task\session_cleanup_task::class);
+
+ $DB->delete_records('task_scheduled', array('classname' => '\\' . trim(get_class($task), '\\')));
+ $this->assertFalse(\core\task\manager::get_scheduled_task(core\task\session_cleanup_task::class));
// Now call reset on all the tasks.
\core\task\manager::reset_scheduled_tasks_for_component('moodle');
- // Load the tasks again.
- $defaulttasks = \core\task\manager::load_scheduled_tasks_for_component('moodle');
- $finalcount = count($defaulttasks);
- // Compare the first task.
- $newfirsttask = reset($defaulttasks);
- $newfirsttaskrecord = \core\task\manager::record_from_scheduled_task($newfirsttask);
- // We reset this field, because we do not want to compare it.
- $newfirsttaskrecord->nextruntime = '0';
+ // Assert that the second task was added back.
+ $taskafterreset = \core\task\manager::get_scheduled_task(core\task\session_cleanup_task::class);
+ $this->assertNotFalse($taskafterreset);
- // Assert a customised task was not altered by reset.
- $this->assertEquals($firsttaskrecord, $newfirsttaskrecord);
+ $this->assertTaskEquals($task, $taskafterreset);
+ $this->assertCount(count($tasklist), \core\task\manager::load_scheduled_tasks_for_component('moodle'));
+ }
- // Assert that the second task was added back.
- $secondtaskafter = \core\task\manager::get_scheduled_task(get_class($secondtask));
- $secondtaskafter->set_next_run_time(null); // Do not compare the nextruntime.
- $secondtask->set_next_run_time(null);
- $this->assertEquals($secondtask, $secondtaskafter);
-
- // Assert that the third task edits were overridden.
- $thirdtaskafter = \core\task\manager::get_scheduled_task(get_class($thirdtask));
- $thirdtaskafter->set_next_run_time(null);
- $this->assertEquals($thirdtaskbefore, $thirdtaskafter);
-
- // Assert we have the same number of tasks.
- $this->assertEquals($initcount, $finalcount);
+ public function test_reset_scheduled_tasks_for_component_changed_in_source(): void {
+ $this->resetAfterTest(true);
+
+ // Delete a task to simulate the fact that its new.
+ // Note: This test must use a task which does not use any random values.
+ $task = \core\task\manager::get_scheduled_task(core\task\session_cleanup_task::class);
+
+ // Get a copy of the task before maing changes for later comparison.
+ $taskbeforechange = \core\task\manager::get_scheduled_task(core\task\session_cleanup_task::class);
+
+ // Edit a task to simulate a change in its definition (as if it was not customised).
+ $task->set_minute('1');
+ $task->set_hour('2');
+ $task->set_month('3');
+ $task->set_day_of_week('4');
+ $task->set_day('5');
+ \core\task\manager::configure_scheduled_task($task);
+
+ // Fetch the task out for comparison.
+ $taskafterchange = \core\task\manager::get_scheduled_task(core\task\session_cleanup_task::class);
+
+ // The task should now be different to the original.
+ $this->assertTaskNotEquals($taskbeforechange, $taskafterchange);
+
+ // Now call reset.
+ \core\task\manager::reset_scheduled_tasks_for_component('moodle');
+
+ // Fetch the task again.
+ $taskafterreset = \core\task\manager::get_scheduled_task(core\task\session_cleanup_task::class);
+
+ // The task should now be the same as the original.
+ $this->assertTaskEquals($taskbeforechange, $taskafterreset);
}
/**
$this->assertEquals(0, $task->get_fail_delay());
$this->assertLessThan($before + 70, $task->get_next_run_time());
}
+
+ /**
+ * Assert that the specified tasks are equal.
+ *
+ * @param \core\task\task_base $task
+ * @param \core\task\task_base $comparisontask
+ */
+ public function assertTaskEquals(\core\task\task_base $task, \core\task\task_base $comparisontask): void {
+ // Convert both to an object.
+ $task = \core\task\manager::record_from_scheduled_task($task);
+ $comparisontask = \core\task\manager::record_from_scheduled_task($comparisontask);
+
+ // Reset the nextruntime field as it is intentionally dynamic.
+ $task->nextruntime = null;
+ $comparisontask->nextruntime = null;
+
+ $args = array_merge(
+ [
+ $task,
+ $comparisontask,
+ ],
+ array_slice(func_get_args(), 2)
+ );
+
+ call_user_func_array([$this, 'assertEquals'], $args);
+ }
+
+ /**
+ * Assert that the specified tasks are not equal.
+ *
+ * @param \core\task\task_base $task
+ * @param \core\task\task_base $comparisontask
+ */
+ public function assertTaskNotEquals(\core\task\task_base $task, \core\task\task_base $comparisontask): void {
+ // Convert both to an object.
+ $task = \core\task\manager::record_from_scheduled_task($task);
+ $comparisontask = \core\task\manager::record_from_scheduled_task($comparisontask);
+
+ // Reset the nextruntime field as it is intentionally dynamic.
+ $task->nextruntime = null;
+ $comparisontask->nextruntime = null;
+
+ $args = array_merge(
+ [
+ $task,
+ $comparisontask,
+ ],
+ array_slice(func_get_args(), 2)
+ );
+
+ call_user_func_array([$this, 'assertNotEquals'], $args);
+ }
}
return false;
}
- $info = explode('_', $fileinfo->get_filepath() . $fileinfo->get_filename(), 5);
+ // Break the full path-name into path parts.
+ $pathparts = explode('/', $fileinfo->get_filepath() . $fileinfo->get_filename());
- if (count($info) < 5) {
- return false;
- }
+ while (!empty($pathparts)) {
+ // Get the next path part and break it up by underscores.
+ $pathpart = array_shift($pathparts);
+ $info = explode('_', $pathpart, 5);
- $participantid = $info[1];
- $filename = $info[4];
- $plugin = $assignment->get_plugin_by_type($info[2], $info[3]);
+ if (count($info) < 5) {
+ continue;
+ }
- if (!is_numeric($participantid)) {
- return false;
- }
+ // Check the participant id.
+ $participantid = $info[1];
- if (!$plugin) {
- return false;
- }
+ if (!is_numeric($participantid)) {
+ continue;
+ }
- // Convert to int.
- $participantid += 0;
+ // Convert to int.
+ $participantid += 0;
- if (empty($participants[$participantid])) {
- return false;
+ if (empty($participants[$participantid])) {
+ continue;
+ }
+
+ // Set user, which is by reference, so is used by the calling script.
+ $user = $participants[$participantid];
+
+ // Set the plugin. This by reference, and is used by the calling script.
+ $plugin = $assignment->get_plugin_by_type($info[2], $info[3]);
+
+ if (!$plugin) {
+ continue;
+ }
+
+ // Take any remaining text in this part and put it back in the path parts array.
+ array_unshift($pathparts, $info[4]);
+
+ // Combine the remaining parts and set it as the filename.
+ // Note that filename is a 'by reference' variable, so we need to set it before returning.
+ $filename = implode('/', $pathparts);
+
+ return true;
}
- $user = $participants[$participantid];
- return true;
+ return false;
}
/**
--- /dev/null
+<?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/>.
+
+/**
+ * Unit tests for importziplib.
+ *
+ * @package assignfeedback_file
+ * @copyright 2020 Eric Merrill <merrill@oakland.edu>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot . '/mod/assign/tests/generator.php');
+require_once($CFG->dirroot . '/mod/assign/feedback/file/importziplib.php');
+
+/**
+ * Unit tests for importziplib.
+ *
+ * @copyright 2020 Eric Merrill <merrill@oakland.edu>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class assignfeedback_importziplib_testcase extends advanced_testcase {
+
+ // Use the generator helper.
+ use mod_assign_test_generator;
+
+ /**
+ * Test the assignfeedback_file_zip_importer->is_valid_filename_for_import() method.
+ */
+ public function test_is_valid_filename_for_import() {
+ // Do the initial assign setup.
+ $this->resetAfterTest();
+ $course = $this->getDataGenerator()->create_course();
+ $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
+ $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+
+ $assign = $this->create_instance($course, [
+ 'assignsubmission_onlinetext_enabled' => 1,
+ 'assignfeedback_file_enabled' => 1,
+ ]);
+
+ // Create an online text submission.
+ $this->add_submission($student, $assign);
+
+ // Now onto the file work.
+ $fs = get_file_storage();
+
+ // Setup a basic file we will work with. We will keep renaming and repathing it.
+ $record = new stdClass;
+ $record->contextid = $assign->get_context()->id;
+ $record->component = 'assignfeedback_file';
+ $record->filearea = ASSIGNFEEDBACK_FILE_FILEAREA;
+ $record->itemid = $assign->get_user_grade($student->id, true)->id;
+ $record->filepath = '/';
+ $record->filename = '1.txt';
+ $record->source = 'test';
+ $file = $fs->create_file_from_string($record, 'file content');
+
+ // The importer we will use.
+ $importer = new assignfeedback_file_zip_importer();
+
+ // Setup some variable we use.
+ $user = null;
+ $plugin = null;
+ $filename = '';
+
+ $allusers = $assign->list_participants(0, false);
+ $participants = array();
+ foreach ($allusers as $user) {
+ $participants[$assign->get_uniqueid_for_user($user->id)] = $user;
+ }
+
+ $file->rename('/import/', '.hiddenfile');
+ $result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
+ $this->assertFalse($result);
+
+ $file->rename('/import/', '~hiddenfile');
+ $result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
+ $this->assertFalse($result);
+
+ $file->rename('/import/some_path_here/', 'RandomFile.txt');
+ $result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
+ $this->assertFalse($result);
+
+ $file->rename('/import/', '~hiddenfile');
+ $result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
+ $this->assertFalse($result);
+
+ // Get the students assign id.
+ $studentid = $assign->get_uniqueid_for_user($student->id);
+
+ // Submissions are identified with the format:
+ // StudentName_StudentID_PluginType_Plugin_FilePathAndName.
+
+ // Test a string student id.
+ $badname = 'Student Name_StringID_assignsubmission_file_My_cool_filename.txt';
+ $file->rename('/import/', $badname);
+ $result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
+ $this->assertFalse($result);
+
+ // Test an invalid student id.
+ $badname = 'Student Name_' . ($studentid + 100) . '_assignsubmission_file_My_cool_filename.txt';
+ $file->rename('/import/', $badname);
+ $result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
+ $this->assertFalse($result);
+
+ // Test an invalid submission plugin.
+ $badname = 'Student Name_' . $studentid . '_assignsubmission_noplugin_My_cool_filename.txt';
+ $file->rename('/import/', $badname);
+ $result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
+ $this->assertFalse($result);
+
+ // Test a basic, good file.
+ $goodbase = 'Student Name_' . $studentid . '_assignsubmission_file_';
+ $file->rename('/import/', $goodbase . "My_cool_filename.txt");
+ $result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
+ $this->assertTrue($result);
+ $this->assertEquals($participants[$studentid], $user);
+ $this->assertEquals('My_cool_filename.txt', $filename);
+ $this->assertInstanceOf(assign_submission_file::class, $plugin);
+
+ // Test another good file, with some additional path and underscores.
+ $user = null;
+ $plugin = null;
+ $filename = '';
+ $file->rename('/import/some_path_here/' . $goodbase . '/some_path/', 'My File.txt');
+ $result = $importer->is_valid_filename_for_import($assign, $file, $participants, $user, $plugin, $filename);
+ $this->assertTrue($result);
+ $this->assertEquals($participants[$studentid], $user);
+ $this->assertEquals('/some_path/My File.txt', $filename);
+ $this->assertInstanceOf(assign_submission_file::class, $plugin);
+ }
+}
$string['numberofpagesviewedheader'] = 'Number of questions answered';
$string['numberofpagesviewednotice'] = 'Number of questions answered: {$a->nquestions} (You should answer at least {$a->minquestions})';
$string['numerical'] = 'Numerical';
-$string['numericanswer_help'] = 'You can specify a number, or a range of numbers by using colon. For example 2:5 means any answer between 2 and 5 including them are correct.';
+$string['numericanswer_help'] = 'You can specify a single number, or a range of numbers by using colon. For example 2:5 means any answer between 2 and 5 and including 2 and 5 is correct.';
$string['numericanswer'] = 'Numeric answer';
$string['offlinedatamessage'] = 'You have worked on this attempt using a mobile device. Data was last saved to this site {$a} ago. Please check that you do not have any unsaved work.';
$string['ongoing'] = 'Display ongoing score';
$content = lti_initiate_login($cm->course, $id, $lti, $config);
}
+ // Build the allowed URL, since we know what it will be from $lti->toolurl,
+ // If the specified toolurl is invalid the iframe won't load, but we still want to avoid parse related errors here.
+ // So we set an empty default allowed url, and only build a real one if the parse is successful.
+ $ltiallow = '';
+ $urlparts = parse_url($lti->toolurl);
+ if ($urlparts && array_key_exists('scheme', $urlparts) && array_key_exists('host', $urlparts)) {
+ $ltiallow = $urlparts['scheme'] . '://' . $urlparts['host'];
+ // If a port has been specified we append that too.
+ if (array_key_exists('port', $urlparts)) {
+ $ltiallow .= ':' . $urlparts['port'];
+ }
+ }
+
// Request the launch content with an iframe tag.
- echo '<iframe id="contentframe" height="600px" width="100%" src="launch.php?id=' . $cm->id .
- "&triggerview=0\" webkitallowfullscreen mozallowfullscreen allowfullscreen>{$content}</iframe>";
+ $attributes = [];
+ $attributes['id'] = "contentframe";
+ $attributes['height'] = '600px';
+ $attributes['width'] = '100%';
+ $attributes['src'] = 'launch.php?id=' . $cm->id . '&triggerview=0';
+ $attributes['allow'] = "microphone $ltiallow; " .
+ "camera $ltiallow; " .
+ "geolocation $ltiallow; " .
+ "midi $ltiallow; " .
+ "encrypted-media $ltiallow; " .
+ "autoplay $ltiallow";
+ $attributes['allowfullscreen'] = 1;
+ $iframehtml = html_writer::tag('iframe', $content, $attributes);
+ echo $iframehtml;
+
// Output script to make the iframe tag be as large as possible.
$resize = '
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
-]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M10 0v2H6V0h4zm1 2h1c.4 0 .8.1 1.1.3.3-.3.8-.4 1.2-.4.5 0 1 .2 1.4.6l.3.3V2c0-1.1-.9-2-2-2h-3v2zm3 8h2V6.4l-2 2V10zm0 1v1c0 1.1-.9 2-2 2h-1v2h3c1.1 0 2-.9 2-2v-3h-2zm-4 5v-2H6v2h4zm-5-2H4c-1.1 0-2-.9-2-2v-1H0v3c0 1.1.9 2 2 2h3v-2zm-5-4h2V6H0v4zm2-5V4c0-1.1.9-2 2-2h1V0H2C.9 0 0 .9 0 2v3h2zm13.7-1.1l-.7-.7c-.4-.4-1-.4-1.4 0l-6 6L5.4 7c-.4-.3-1-.3-1.4 0l-.7.7c-.4.4-.4 1 0 1.4l3.6 3.6c.4.4 1 .4 1.4 0l7.4-7.4c.4-.4.4-1 0-1.4z" fill="#999"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M10,0V2H6V0Zm1,2h1a2,2,0,0,1,1.1.3,1.75,1.75,0,0,1,1.2-.4,2,2,0,0,1,1.4.6l.3.3V2a2,2,0,0,0-2-2H11Zm3,8h2V6.4l-2,2Zm0,1v1a2,2,0,0,1-2,2H11v2h3a2,2,0,0,0,2-2V11Zm-4,5V14H6v2ZM5,14H4a2,2,0,0,1-2-2V11H0v3a2,2,0,0,0,2,2H5ZM0,10H2V6H0ZM2,5V4A2,2,0,0,1,4,2H5V0H2A2,2,0,0,0,0,2V5ZM15.7,3.9,15,3.2a1,1,0,0,0-1.4,0l-6,6L5.4,7A1.2,1.2,0,0,0,4,7l-.7.7a1,1,0,0,0,0,1.4l3.6,3.6a1,1,0,0,0,1.4,0l7.4-7.4A1,1,0,0,0,15.7,3.9Z" fill="#949494"/></svg>
\ No newline at end of file
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
-]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M10 0v2H6V0h4zm1 2h1c1.1 0 2 .9 2 2v1h2V2c0-1.1-.9-2-2-2h-3v2zm5 4h-2v4h2V6zm-2 5v1c0 1.1-.9 2-2 2h-1v2h3c1.1 0 2-.9 2-2v-3h-2zm-4 5v-2H6v2h4zm-5-2H4c-1.1 0-2-.9-2-2v-1H0v3c0 1.1.9 2 2 2h3v-2zm-5-4h2V6H0v4zm2-5V4c0-1.1.9-2 2-2h1V0H2C.9 0 0 .9 0 2v3h2z" fill="#999"/><path d="M10.2 8l2.6-2.6c.4-.4.4-1 0-1.4l-.8-.7c-.4-.4-1-.4-1.4 0L8 5.9 5.4 3.3c-.4-.4-1-.4-1.4 0l-.7.7c-.4.4-.4 1 0 1.4L5.9 8l-2.6 2.6c-.3.4-.3 1 0 1.4l.7.7c.4.4 1 .4 1.4 0L8 10.2l2.5 2.5c.4.4 1 .4 1.4 0l.7-.7c.4-.4.4-1 0-1.4L10.2 8z" fill="#FF403C"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M10,0V2H6V0Zm1,2h1a2,2,0,0,1,2,2V5h2V2a2,2,0,0,0-2-2H11Zm5,4H14v4h2Zm-2,5v1a2,2,0,0,1-2,2H11v2h3a2,2,0,0,0,2-2V11Zm-4,5V14H6v2ZM5,14H4a2,2,0,0,1-2-2V11H0v3a2,2,0,0,0,2,2H5ZM0,10H2V6H0ZM2,5V4A2,2,0,0,1,4,2H5V0H2A2,2,0,0,0,0,2V5Z" fill="#949494"/><path d="M10.2,8l2.6-2.6a1,1,0,0,0,0-1.4L12,3.3a1,1,0,0,0-1.4,0L8,5.9,5.4,3.3A1,1,0,0,0,4,3.3L3.3,4a1,1,0,0,0,0,1.4L5.9,8,3.3,10.6a1.2,1.2,0,0,0,0,1.4l.7.7a1,1,0,0,0,1.4,0L8,10.2l2.5,2.5a1,1,0,0,0,1.4,0l.7-.7a1,1,0,0,0,0-1.4Z" fill="#ff403c"/></svg>
\ No newline at end of file
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
-]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M10 0v2H6V0h4zm1 2h1c1.1 0 2 .9 2 2v1h2V2c0-1.1-.9-2-2-2h-3v2zm5 4h-2v4h2V6zm-2 5v1c0 1.1-.9 2-2 2h-1v2h3c1.1 0 2-.9 2-2v-3h-2zm-4 5v-2H6v2h4zm-5-2H4c-1.1 0-2-.9-2-2v-1H0v3c0 1.1.9 2 2 2h3v-2zm-5-4h2V6H0v4zm2-5V4c0-1.1.9-2 2-2h1V0H2C.9 0 0 .9 0 2v3h2z" fill="#999"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M10,0V2H6V0Zm1,2h1a2,2,0,0,1,2,2V5h2V2a2,2,0,0,0-2-2H11Zm5,4H14v4h2Zm-2,5v1a2,2,0,0,1-2,2H11v2h3a2,2,0,0,0,2-2V11Zm-4,5V14H6v2ZM5,14H4a2,2,0,0,1-2-2V11H0v3a2,2,0,0,0,2,2H5ZM0,10H2V6H0ZM2,5V4A2,2,0,0,1,4,2H5V0H2A2,2,0,0,0,0,2V5Z" fill="#949494"/></svg>
\ No newline at end of file
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
-]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M10 0v2H6V0h4zm1 2h1c.4 0 .8.1 1.1.3.3-.3.8-.4 1.2-.4.5 0 1 .2 1.4.6l.3.3V2c0-1.1-.9-2-2-2h-3v2zm3 8h2V6.4l-2 2V10zm0 1v1c0 1.1-.9 2-2 2h-1v2h3c1.1 0 2-.9 2-2v-3h-2zm-4 5v-2H6v2h4zm-5-2H4c-1.1 0-2-.9-2-2v-1H0v3c0 1.1.9 2 2 2h3v-2zm-5-4h2V6H0v4zm2-5V4c0-1.1.9-2 2-2h1V0H2C.9 0 0 .9 0 2v3h2z" fill="#999"/><path d="M15.7 3.9l-.7-.7c-.4-.4-1-.4-1.4 0l-6 6L5.4 7c-.4-.3-1-.3-1.4 0l-.7.7c-.4.4-.4 1 0 1.4l3.6 3.6c.4.4 1 .4 1.4 0l7.4-7.4c.4-.4.4-1 0-1.4z" fill="#9C3"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M10,0V2H6V0Zm1,2h1a2,2,0,0,1,1.1.3,1.75,1.75,0,0,1,1.2-.4,2,2,0,0,1,1.4.6l.3.3V2a2,2,0,0,0-2-2H11Zm3,8h2V6.4l-2,2Zm0,1v1a2,2,0,0,1-2,2H11v2h3a2,2,0,0,0,2-2V11Zm-4,5V14H6v2ZM5,14H4a2,2,0,0,1-2-2V11H0v3a2,2,0,0,0,2,2H5ZM0,10H2V6H0ZM2,5V4A2,2,0,0,1,4,2H5V0H2A2,2,0,0,0,0,2V5Z" fill="#949494"/><path d="M15.7,3.9,15,3.2a1,1,0,0,0-1.4,0l-6,6L5.4,7A1.2,1.2,0,0,0,4,7l-.7.7a1,1,0,0,0,0,1.4l3.6,3.6a1,1,0,0,0,1.4,0l7.4-7.4A1,1,0,0,0,15.7,3.9Z" fill="#79a128"/></svg>
\ No newline at end of file
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
-]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M10 0v2H6V0h4zm1 2h1c.4 0 .8.1 1.1.3.3-.3.8-.4 1.2-.4.5 0 1 .2 1.4.6l.3.3V2c0-1.1-.9-2-2-2h-3v2zm3 8h2V6.4l-2 2V10zm0 1v1c0 1.1-.9 2-2 2h-1v2h3c1.1 0 2-.9 2-2v-3h-2zm-4 5v-2H6v2h4zm-5-2H4c-1.1 0-2-.9-2-2v-1H0v3c0 1.1.9 2 2 2h3v-2zm-5-4h2V6H0v4zm2-5V4c0-1.1.9-2 2-2h1V0H2C.9 0 0 .9 0 2v3h2z" fill="#FF2727"/><path d="M15.7 3.9l-.7-.7c-.4-.4-1-.4-1.4 0l-6 6L5.4 7c-.4-.3-1-.3-1.4 0l-.7.7c-.4.4-.4 1 0 1.4l3.6 3.6c.4.4 1 .4 1.4 0l7.4-7.4c.4-.4.4-1 0-1.4z" fill="#76A1F0"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M10,0V2H6V0Zm1,2h1a2,2,0,0,1,1.1.3,1.75,1.75,0,0,1,1.2-.4,2,2,0,0,1,1.4.6l.3.3V2a2,2,0,0,0-2-2H11Zm3,8h2V6.4l-2,2Zm0,1v1a2,2,0,0,1-2,2H11v2h3a2,2,0,0,0,2-2V11Zm-4,5V14H6v2ZM5,14H4a2,2,0,0,1-2-2V11H0v3a2,2,0,0,0,2,2H5ZM0,10H2V6H0ZM2,5V4A2,2,0,0,1,4,2H5V0H2A2,2,0,0,0,0,2V5Z" fill="#ff2727"/><path d="M15.7,3.9,15,3.2a1,1,0,0,0-1.4,0l-6,6L5.4,7A1.2,1.2,0,0,0,4,7l-.7.7a1,1,0,0,0,0,1.4l3.6,3.6a1,1,0,0,0,1.4,0l7.4-7.4A1,1,0,0,0,15.7,3.9Z" fill="#6393ee"/></svg>
\ No newline at end of file
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
-]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M10 0v2H6V0h4zm1 2h1c.4 0 .8.1 1.1.3.3-.3.8-.4 1.2-.4.5 0 1 .2 1.4.6l.3.3V2c0-1.1-.9-2-2-2h-3v2zm3 8h2V6.4l-2 2V10zm0 1v1c0 1.1-.9 2-2 2h-1v2h3c1.1 0 2-.9 2-2v-3h-2zm-4 5v-2H6v2h4zm-5-2H4c-1.1 0-2-.9-2-2v-1H0v3c0 1.1.9 2 2 2h3v-2zm-5-4h2V6H0v4zm2-5V4c0-1.1.9-2 2-2h1V0H2C.9 0 0 .9 0 2v3h2z" fill="#999"/><path d="M15.7 3.9l-.7-.7c-.4-.4-1-.4-1.4 0l-6 6L5.4 7c-.4-.3-1-.3-1.4 0l-.7.7c-.4.4-.4 1 0 1.4l3.6 3.6c.4.4 1 .4 1.4 0l7.4-7.4c.4-.4.4-1 0-1.4z" fill="#76A1F0"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M10,0V2H6V0Zm1,2h1a2,2,0,0,1,1.1.3,1.75,1.75,0,0,1,1.2-.4,2,2,0,0,1,1.4.6l.3.3V2a2,2,0,0,0-2-2H11Zm3,8h2V6.4l-2,2Zm0,1v1a2,2,0,0,1-2,2H11v2h3a2,2,0,0,0,2-2V11Zm-4,5V14H6v2ZM5,14H4a2,2,0,0,1-2-2V11H0v3a2,2,0,0,0,2,2H5ZM0,10H2V6H0ZM2,5V4A2,2,0,0,1,4,2H5V0H2A2,2,0,0,0,0,2V5Z" fill="#949494"/><path d="M15.7,3.9,15,3.2a1,1,0,0,0-1.4,0l-6,6L5.4,7A1.2,1.2,0,0,0,4,7l-.7.7a1,1,0,0,0,0,1.4l3.6,3.6a1,1,0,0,0,1.4,0l7.4-7.4A1,1,0,0,0,15.7,3.9Z" fill="#6393ee"/></svg>
\ No newline at end of file
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
-]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M16 6.4V14c0 1.1-.9 2-2 2H2c-1.1 0-2-.9-2-2V2C0 .9.9 0 2 0h12c1.1 0 2 .9 2 2v.8l-.3-.3c-.4-.4-.9-.6-1.4-.6-.4 0-.9.1-1.2.4-.3-.2-.7-.3-1.1-.3H4c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V8.4l2-2zm-.3-2.5l-.7-.7c-.4-.4-1-.4-1.4 0l-6 6L5.4 7c-.4-.3-1-.3-1.4 0l-.7.7c-.4.4-.4 1 0 1.4l3.6 3.6c.4.4 1 .4 1.4 0l7.4-7.4c.4-.4.4-1 0-1.4z" fill="#999"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M16,6.4V14a2,2,0,0,1-2,2H2a2,2,0,0,1-2-2V2A2,2,0,0,1,2,0H14a2,2,0,0,1,2,2v.8l-.3-.3a2,2,0,0,0-1.4-.6,1.75,1.75,0,0,0-1.2.4A2,2,0,0,0,12,2H4A2,2,0,0,0,2,4v8a2,2,0,0,0,2,2h8a2,2,0,0,0,2-2V8.4Zm-.3-2.5L15,3.2a1,1,0,0,0-1.4,0l-6,6L5.4,7A1.2,1.2,0,0,0,4,7l-.7.7a1,1,0,0,0,0,1.4l3.6,3.6a1,1,0,0,0,1.4,0l7.4-7.4A1,1,0,0,0,15.7,3.9Z" fill="#949494"/></svg>
\ No newline at end of file
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
-]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M14 0H2C.9 0 0 .9 0 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2zm0 12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h8c1.1 0 2 .9 2 2v8z" fill="#999"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M14,0H2A2,2,0,0,0,0,2V14a2,2,0,0,0,2,2H14a2,2,0,0,0,2-2V2A2,2,0,0,0,14,0Zm0,12a2,2,0,0,1-2,2H4a2,2,0,0,1-2-2V4A2,2,0,0,1,4,2h8a2,2,0,0,1,2,2Z" fill="#949494"/></svg>
\ No newline at end of file
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
-]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M14 8.4V12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h8c.4 0 .8.1 1.1.3.3-.3.8-.4 1.2-.4.5 0 1 .2 1.4.6l.3.3V2c0-1.1-.9-2-2-2H2C.9 0 0 .9 0 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V6.4l-2 2z" fill="#FF2727"/><path d="M15.7 3.9l-.7-.7c-.4-.4-1-.4-1.4 0l-6 6L5.4 7c-.4-.3-1-.3-1.4 0l-.7.7c-.4.4-.4 1 0 1.4l3.6 3.6c.4.4 1 .4 1.4 0l7.4-7.4c.4-.4.4-1 0-1.4z" fill="#76A1F0"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M14,8.4V12a2,2,0,0,1-2,2H4a2,2,0,0,1-2-2V4A2,2,0,0,1,4,2h8a2,2,0,0,1,1.1.3,1.75,1.75,0,0,1,1.2-.4,2,2,0,0,1,1.4.6l.3.3V2a2,2,0,0,0-2-2H2A2,2,0,0,0,0,2V14a2,2,0,0,0,2,2H14a2,2,0,0,0,2-2V6.4Z" fill="#ff2727"/><path d="M15.7,3.9,15,3.2a1,1,0,0,0-1.4,0l-6,6L5.4,7A1.2,1.2,0,0,0,4,7l-.7.7a1,1,0,0,0,0,1.4l3.6,3.6a1,1,0,0,0,1.4,0l7.4-7.4A1,1,0,0,0,15.7,3.9Z" fill="#6393ee"/></svg>
\ No newline at end of file
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
-]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M14 8.4V12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h8c.4 0 .8.1 1.1.3.3-.3.8-.4 1.2-.4.5 0 1 .2 1.4.6l.3.3V2c0-1.1-.9-2-2-2H2C.9 0 0 .9 0 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V6.4l-2 2z" fill="#999"/><path d="M15.7 3.9l-.7-.7c-.4-.4-1-.4-1.4 0l-6 6L5.4 7c-.4-.3-1-.3-1.4 0l-.7.7c-.4.4-.4 1 0 1.4l3.6 3.6c.4.4 1 .4 1.4 0l7.4-7.4c.4-.4.4-1 0-1.4z" fill="#76A1F0"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M14,8.4V12a2,2,0,0,1-2,2H4a2,2,0,0,1-2-2V4A2,2,0,0,1,4,2h8a2,2,0,0,1,1.1.3,1.75,1.75,0,0,1,1.2-.4,2,2,0,0,1,1.4.6l.3.3V2a2,2,0,0,0-2-2H2A2,2,0,0,0,0,2V14a2,2,0,0,0,2,2H14a2,2,0,0,0,2-2V6.4Z" fill="#949494"/><path d="M15.7,3.9,15,3.2a1,1,0,0,0-1.4,0l-6,6L5.4,7A1.2,1.2,0,0,0,4,7l-.7.7a1,1,0,0,0,0,1.4l3.6,3.6a1,1,0,0,0,1.4,0l7.4-7.4A1,1,0,0,0,15.7,3.9Z" fill="#6293ee"/></svg>
\ No newline at end of file
$data->noinsights = $notification->export_for_template($output);
}
+ $url = $PAGE->url;
+
if ($this->othermodels) {
$options = array();
}
// New moodle_url instance returned by magic_get_url.
- $url = $PAGE->url;
$url->remove_params('modelid');
$modelselector = new \single_select($url, 'modelid', $options, '',
array('' => get_string('selectotherinsights', 'report_insights')));
$data->modelselector = $modelselector->export_for_template($output);
}
- $data->pagingbar = $output->render(new \paging_bar($total, $this->page, $this->perpage, $PAGE->url));
+ // Add the 'perpage' parameter to the url which is later used to generate the pagination links.
+ $url->param('perpage', $this->perpage);
+ $data->pagingbar = $output->render(new \paging_bar($total, $this->page, $this->perpage, $url));
return $data;
}
$yellow: #ff7518 !default;
$green: #398439 !default;
$teal: #20c997 !default;
-$cyan: #5bc0de !default;
+$cyan: #008196 !default;
$primary: $blue !default;
$success: $green !default;
$enable-responsive-font-sizes: true !default;
// Body
-$body-color: $gray-800 !default;
+$body-color: $gray-900 !default;
// Fonts
$font-size-base: 0.9375rem !default;
--yellow: #ff7518;
--green: #398439;
--teal: #20c997;
- --cyan: #5bc0de;
+ --cyan: #008196;
--white: #fff;
--gray: #6c757d;
--gray-dark: #343a40;
--primary: #1177d1;
--secondary: #ced4da;
--success: #398439;
- --info: #5bc0de;
+ --info: #008196;
--warning: #f0ad4e;
--danger: #d43f3a;
--light: #f8f9fa;
font-size: 0.9375rem;
font-weight: 400;
line-height: 1.5;
- color: #343a40;
+ color: #212529;
text-align: left;
background-color: #fff; }
@media (max-width: 1200px) {
.table {
width: 100%;
margin-bottom: 1rem;
- color: #343a40; }
+ color: #212529; }
.table th,
.table td {
padding: 0.75rem;
background-color: rgba(0, 0, 0, 0.05); }
.table-hover tbody tr:hover {
- color: #343a40;
+ color: #212529;
background-color: rgba(0, 0, 0, 0.075); }
.table-primary,
.table-info,
.table-info > th,
.table-info > td {
- background-color: #d1edf6; }
+ background-color: #b8dce2; }
.table-info th,
.table-info td,
.table-info thead th,
.table-info tbody + tbody {
- border-color: #aadeee; }
+ border-color: #7abdc8; }
.table-hover .table-info:hover {
- background-color: #bce5f2; }
+ background-color: #a6d3db; }
.table-hover .table-info:hover > td,
.table-hover .table-info:hover > th {
- background-color: #bce5f2; }
+ background-color: #a6d3db; }
.table-warning,
.table-warning > th,
margin-bottom: 0;
font-size: 0.9375rem;
line-height: 1.5;
- color: #343a40;
+ color: #212529;
background-color: transparent;
border: solid transparent;
border-width: 1px 0; }
.btn {
display: inline-block;
font-weight: 400;
- color: #343a40;
+ color: #212529;
text-align: center;
vertical-align: middle;
user-select: none;
.btn {
transition: none; } }
.btn:hover {
- color: #343a40;
+ color: #212529;
text-decoration: none; }
.btn:focus, .btn.focus {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(87, 150, 87, 0.5); }
.btn-info {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196; }
.btn-info:hover {
color: #fff;
- background-color: #3bb4d8;
- border-color: #31b0d5; }
+ background-color: #006070;
+ border-color: #005563; }
.btn-info:focus, .btn-info.focus {
color: #fff;
- background-color: #3bb4d8;
- border-color: #31b0d5;
- box-shadow: 0 0 0 0.2rem rgba(82, 169, 195, 0.5); }
+ background-color: #006070;
+ border-color: #005563;
+ box-shadow: 0 0 0 0.2rem rgba(38, 148, 166, 0.5); }
.btn-info.disabled, .btn-info:disabled {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196; }
.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,
.show > .btn-info.dropdown-toggle {
color: #fff;
- background-color: #31b0d5;
- border-color: #2aaacf; }
+ background-color: #005563;
+ border-color: #004a56; }
.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,
.show > .btn-info.dropdown-toggle:focus {
- box-shadow: 0 0 0 0.2rem rgba(82, 169, 195, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(38, 148, 166, 0.5); }
.btn-warning {
color: #212529;
box-shadow: 0 0 0 0.2rem rgba(57, 132, 57, 0.5); }
.btn-outline-info {
- color: #5bc0de;
- border-color: #5bc0de; }
+ color: #008196;
+ border-color: #008196; }
.btn-outline-info:hover {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196; }
.btn-outline-info:focus, .btn-outline-info.focus {
- box-shadow: 0 0 0 0.2rem rgba(91, 192, 222, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(0, 129, 150, 0.5); }
.btn-outline-info.disabled, .btn-outline-info:disabled {
- color: #5bc0de;
+ color: #008196;
background-color: transparent; }
.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,
.show > .btn-outline-info.dropdown-toggle {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196; }
.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,
.show > .btn-outline-info.dropdown-toggle:focus {
- box-shadow: 0 0 0 0.2rem rgba(91, 192, 222, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(0, 129, 150, 0.5); }
.btn-outline-warning {
color: #f0ad4e;
padding: 0.5rem 0;
margin: 0.125rem 0 0;
font-size: 0.9375rem;
- color: #343a40;
+ color: #212529;
text-align: left;
list-style: none;
background-color: #fff;
box-shadow: 0 0 0 0.2rem rgba(57, 132, 57, 0.5); }
.badge-info {
- color: #212529;
- background-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196; }
a.badge-info:hover, a.badge-info:focus {
- color: #212529;
- background-color: #31b0d5; }
+ color: #fff;
+ background-color: #005563; }
a.badge-info:focus, a.badge-info.focus {
outline: 0;
- box-shadow: 0 0 0 0.2rem rgba(91, 192, 222, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(0, 129, 150, 0.5); }
.badge-warning {
color: #212529;
color: #0f210f; }
.alert-info {
- color: #2f6473;
- background-color: #def2f8;
- border-color: #d1edf6; }
+ color: #00434e;
+ background-color: #cce6ea;
+ border-color: #b8dce2; }
.alert-info hr {
- border-top-color: #bce5f2; }
+ border-top-color: #a6d3db; }
.alert-info .alert-link {
- color: #20454f; }
+ color: #00171b; }
.alert-warning {
color: #7d5a29;
text-decoration: none;
background-color: #f8f9fa; }
.list-group-item-action:active {
- color: #343a40;
+ color: #212529;
background-color: #e9ecef; }
.list-group-item {
border-color: #1e451e; }
.list-group-item-info {
- color: #2f6473;
- background-color: #d1edf6; }
+ color: #00434e;
+ background-color: #b8dce2; }
.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {
- color: #2f6473;
- background-color: #bce5f2; }
+ color: #00434e;
+ background-color: #a6d3db; }
.list-group-item-info.list-group-item-action.active {
color: #fff;
- background-color: #2f6473;
- border-color: #2f6473; }
+ background-color: #00434e;
+ border-color: #00434e; }
.list-group-item-warning {
color: #7d5a29;
.popover-body {
padding: 0.5rem 0.75rem;
- color: #343a40; }
+ color: #212529; }
.carousel {
position: relative; }
background-color: #2a602a !important; }
.bg-info {
- background-color: #5bc0de !important; }
+ background-color: #008196 !important; }
a.bg-info:hover, a.bg-info:focus,
button.bg-info:hover,
button.bg-info:focus {
- background-color: #31b0d5 !important; }
+ background-color: #005563 !important; }
.bg-warning {
background-color: #f0ad4e !important; }
border-color: #398439 !important; }
.border-info {
- border-color: #5bc0de !important; }
+ border-color: #008196 !important; }
.border-warning {
border-color: #f0ad4e !important; }
color: #224f22 !important; }
.text-info {
- color: #5bc0de !important; }
+ color: #008196 !important; }
a.text-info:hover, a.text-info:focus {
- color: #28a1c5 !important; }
+ color: #003f4a !important; }
.text-warning {
color: #f0ad4e !important; }
color: #121416 !important; }
.text-body {
- color: #343a40 !important; }
+ color: #212529 !important; }
.text-muted {
color: #6c757d !important; }
background-color: #2a602a; }
.tag-info {
- background-color: #5bc0de; }
+ background-color: #008196; }
.tag-info[href]:hover, .tag-info[href]:focus {
- background-color: #31b0d5; }
+ background-color: #005563; }
.tag-warning {
background-color: #f0ad4e; }
color: #398439; }
.highlight {
- color: #5bc0de; }
+ color: #008196; }
.fitem.advanced .text-info {
font-weight: bold; }
#page-footer a .icon {
color: #fff; }
#page-footer a:focus .icon {
- color: #343a40; }
+ color: #212529; }
.bg-inverse a {
color: #fff;
.dropdown-item a {
display: block;
width: 100%;
- color: #343a40; }
+ color: #212529; }
.dropdown-item:active a {
color: #fff; }
.matchtext {
background-color: #b5d9f9;
- color: #343a40;
+ color: #212529;
height: 1.5rem; }
.emoji-picker {
color: #0f210f; }
.alert-info a {
- color: #20454f; }
+ color: #00171b; }
.alert-warning a {
color: #573e1c; }
width: 4em; }
#adminthemeselector .selectedtheme td.c0 {
- border: 1px solid #d1edf6;
+ border: 1px solid #b8dce2;
border-right-width: 0; }
#adminthemeselector .selectedtheme td.c1 {
- border: 1px solid #d1edf6;
+ border: 1px solid #b8dce2;
border-left-width: 0; }
.admin_colourpicker,
box-sizing: content-box; }
.admin_colourpicker .colourdialogue {
float: left;
- border: 1px solid #d1edf6; }
+ border: 1px solid #b8dce2; }
.admin_colourpicker .previewcolour {
- border: 1px solid #d1edf6;
+ border: 1px solid #b8dce2;
margin-left: 301px; }
.admin_colourpicker .currentcolour {
- border: 1px solid #d1edf6;
+ border: 1px solid #b8dce2;
margin-left: 301px;
border-top-width: 0; } }
#plugins-check-page .pluginupdateinfo,
#plugins-control-panel .pluginupdateinfo {
- background-color: #def2f8;
+ background-color: #cce6ea;
padding: 5px;
margin: 10px 0; }
#plugins-check-page .pluginupdateinfo.maturity50,
.block .block-controls .dropdown-toggle {
/* So that the caret takes the colour of the icon. */
- color: #343a40; }
+ color: #212529; }
[data-region="blocks-column"] {
width: 360px;
margin-left: 30px;
font-size: 0.8203125rem;
padding: .1em .4em;
- background-color: #def2f8;
- color: #5bc0de;
+ background-color: #cce6ea;
+ color: #008196;
text-decoration: none;
z-index: 9999;
- border: 1px solid #d1edf6; }
+ border: 1px solid #b8dce2; }
/* Course drag and drop upload styles */
#dndupload-status {
width: 40%;
margin: 0 30%;
padding: 6px;
- border: 1px solid #d1edf6;
+ border: 1px solid #b8dce2;
text-align: center;
- background: #def2f8;
- color: #5bc0de;
+ background: #cce6ea;
+ color: #008196;
z-index: 1; }
.dndupload-preview {
#course-category-listings .listing-pagination {
text-align: center; }
#course-category-listings .listing-pagination .yui3-button {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de;
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196;
border: 0;
margin: 0.4rem 0.2rem 0.45rem;
font-size: 10.4px; }
#course-category-listings .listing-pagination .yui3-button:hover {
color: #fff;
- background-color: #3bb4d8;
- border-color: #31b0d5; }
+ background-color: #006070;
+ border-color: #005563; }
#course-category-listings .listing-pagination .yui3-button:focus, #course-category-listings .listing-pagination .yui3-button.focus {
color: #fff;
- background-color: #3bb4d8;
- border-color: #31b0d5;
- box-shadow: 0 0 0 0.2rem rgba(82, 169, 195, 0.5); }
+ background-color: #006070;
+ border-color: #005563;
+ box-shadow: 0 0 0 0.2rem rgba(38, 148, 166, 0.5); }
#course-category-listings .listing-pagination .yui3-button.disabled, #course-category-listings .listing-pagination .yui3-button:disabled {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196; }
#course-category-listings .listing-pagination .yui3-button:not(:disabled):not(.disabled):active, #course-category-listings .listing-pagination .yui3-button:not(:disabled):not(.disabled).active,
.show > #course-category-listings .listing-pagination .yui3-button.dropdown-toggle {
color: #fff;
- background-color: #31b0d5;
- border-color: #2aaacf; }
+ background-color: #005563;
+ border-color: #004a56; }
#course-category-listings .listing-pagination .yui3-button:not(:disabled):not(.disabled):active:focus, #course-category-listings .listing-pagination .yui3-button:not(:disabled):not(.disabled).active:focus,
.show > #course-category-listings .listing-pagination .yui3-button.dropdown-toggle:focus {
- box-shadow: 0 0 0 0.2rem rgba(82, 169, 195, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(38, 148, 166, 0.5); }
#course-category-listings .listing-pagination .yui3-button.active-page {
color: #fff;
background-color: #1177d1;
color: #573e1c; }
.que .formulation {
- color: #2f6473;
- background-color: #def2f8;
- border-color: #d1edf6;
+ color: #00434e;
+ background-color: #cce6ea;
+ border-color: #b8dce2;
/* stylelint-disable-line max-line-length */ }
.que .formulation hr {
- border-top-color: #bce5f2; }
+ border-top-color: #a6d3db; }
.que .formulation .alert-link {
- color: #20454f; }
+ color: #00171b; }
.que.multichoice .answer div.r0 .icon.fa-check,
.que.multichoice .answer div.r1 .icon.fa-check,
margin: 0; }
#page-mod-quiz-edit .questionbankwindow div.header .title {
- color: #343a40; }
+ color: #212529; }
#page-mod-quiz-edit div.container div.generalbox {
background-color: transparent;
padding: 0.2em;
margin: 0;
cursor: pointer;
- color: #343a40; }
+ color: #212529; }
.form-autocomplete-suggestions li:hover {
background-color: #3f9def;
color: #495057; }
.form-autocomplete-downarrow {
- color: #343a40;
+ color: #212529;
top: 0.2rem;
right: 0.5rem;
cursor: pointer; }
font-weight: inherit; }
.path-mod-forum .subscriptionmode {
- color: #343a40; }
+ color: #212529; }
.path-mod-forum .activesetting {
- color: #343a40;
+ color: #212529;
font-weight: bold; }
.discussion-settings-container .custom-select {
padding: 0.75rem 1.25rem;
margin-bottom: 1rem;
border: 0 solid transparent;
- color: #2f6473;
- background-color: #def2f8;
- border-color: #d1edf6;
+ color: #00434e;
+ background-color: #cce6ea;
+ border-color: #b8dce2;
/* stylelint-disable-line max-line-length */ }
.assignfeedback_editpdf_widget .label hr {
- border-top-color: #bce5f2; }
+ border-top-color: #a6d3db; }
.assignfeedback_editpdf_widget .label .alert-link {
- color: #20454f; }
+ color: #00171b; }
.assignfeedback_editpdf_menu {
padding: 0; }
.generaltable {
width: 100%;
margin-bottom: 1rem;
- color: #343a40; }
+ color: #212529; }
.generaltable th,
.generaltable td {
padding: 0.75rem;
.generaltable.table-sm td {
padding: 0.3rem; }
.generaltable tbody tr:hover {
- color: #343a40;
+ color: #212529;
background-color: rgba(0, 0, 0, 0.075); }
table caption {
box-shadow: inset 0 0 0 2px #fff; }
.btn-info:focus, .btn-info.focus {
- outline: 0.2rem solid #124a5b;
+ outline: 0.2rem solid black;
box-shadow: inset 0 0 0 2px #fff; }
.btn-warning:focus, .btn-warning.focus {
box-shadow: inset 0 0 0 2px #343a40; }
.btn-outline-info:focus, .btn-outline-info.focus {
- outline: 0.2rem solid #124a5b;
+ outline: 0.2rem solid black;
box-shadow: inset 0 0 0 2px #343a40; }
.btn-outline-warning:focus, .btn-outline-warning.focus {
box-shadow: 0 0 0 0.2rem rgba(57, 132, 57, 0.5); }
.label-info {
- color: #212529;
- background-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196; }
a.label-info:hover, a.label-info:focus {
- color: #212529;
- background-color: #31b0d5; }
+ color: #fff;
+ background-color: #005563; }
a.label-info:focus, a.label-info.focus {
outline: 0;
- box-shadow: 0 0 0 0.2rem rgba(91, 192, 222, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(0, 129, 150, 0.5); }
.label-warning {
color: #212529;
$yellow: #ff7518 !default;
$green: #398439 !default;
$teal: #20c997 !default;
-$cyan: #5bc0de !default;
+$cyan: #008196 !default;
$primary: $blue !default;
$success: $green !default;
$enable-responsive-font-sizes: true !default;
// Body
-$body-color: $gray-800 !default;
+$body-color: $gray-900 !default;
// Fonts
$font-size-base: 0.9375rem !default;
--yellow: #ff7518;
--green: #398439;
--teal: #20c997;
- --cyan: #5bc0de;
+ --cyan: #008196;
--white: #fff;
--gray: #6c757d;
--gray-dark: #343a40;
--primary: #1177d1;
--secondary: #ced4da;
--success: #398439;
- --info: #5bc0de;
+ --info: #008196;
--warning: #f0ad4e;
--danger: #d43f3a;
--light: #f8f9fa;
font-size: 0.9375rem;
font-weight: 400;
line-height: 1.5;
- color: #343a40;
+ color: #212529;
text-align: left;
background-color: #fff; }
@media (max-width: 1200px) {
.table {
width: 100%;
margin-bottom: 1rem;
- color: #343a40; }
+ color: #212529; }
.table th,
.table td {
padding: 0.75rem;
background-color: rgba(0, 0, 0, 0.05); }
.table-hover tbody tr:hover {
- color: #343a40;
+ color: #212529;
background-color: rgba(0, 0, 0, 0.075); }
.table-primary,
.table-info,
.table-info > th,
.table-info > td {
- background-color: #d1edf6; }
+ background-color: #b8dce2; }
.table-info th,
.table-info td,
.table-info thead th,
.table-info tbody + tbody {
- border-color: #aadeee; }
+ border-color: #7abdc8; }
.table-hover .table-info:hover {
- background-color: #bce5f2; }
+ background-color: #a6d3db; }
.table-hover .table-info:hover > td,
.table-hover .table-info:hover > th {
- background-color: #bce5f2; }
+ background-color: #a6d3db; }
.table-warning,
.table-warning > th,
margin-bottom: 0;
font-size: 0.9375rem;
line-height: 1.5;
- color: #343a40;
+ color: #212529;
background-color: transparent;
border: solid transparent;
border-width: 1px 0; }
.btn {
display: inline-block;
font-weight: 400;
- color: #343a40;
+ color: #212529;
text-align: center;
vertical-align: middle;
user-select: none;
.btn {
transition: none; } }
.btn:hover {
- color: #343a40;
+ color: #212529;
text-decoration: none; }
.btn:focus, .btn.focus {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(87, 150, 87, 0.5); }
.btn-info {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196; }
.btn-info:hover {
color: #fff;
- background-color: #3bb4d8;
- border-color: #31b0d5; }
+ background-color: #006070;
+ border-color: #005563; }
.btn-info:focus, .btn-info.focus {
color: #fff;
- background-color: #3bb4d8;
- border-color: #31b0d5;
- box-shadow: 0 0 0 0.2rem rgba(82, 169, 195, 0.5); }
+ background-color: #006070;
+ border-color: #005563;
+ box-shadow: 0 0 0 0.2rem rgba(38, 148, 166, 0.5); }
.btn-info.disabled, .btn-info:disabled {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196; }
.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,
.show > .btn-info.dropdown-toggle {
color: #fff;
- background-color: #31b0d5;
- border-color: #2aaacf; }
+ background-color: #005563;
+ border-color: #004a56; }
.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,
.show > .btn-info.dropdown-toggle:focus {
- box-shadow: 0 0 0 0.2rem rgba(82, 169, 195, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(38, 148, 166, 0.5); }
.btn-warning {
color: #212529;
box-shadow: 0 0 0 0.2rem rgba(57, 132, 57, 0.5); }
.btn-outline-info {
- color: #5bc0de;
- border-color: #5bc0de; }
+ color: #008196;
+ border-color: #008196; }
.btn-outline-info:hover {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196; }
.btn-outline-info:focus, .btn-outline-info.focus {
- box-shadow: 0 0 0 0.2rem rgba(91, 192, 222, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(0, 129, 150, 0.5); }
.btn-outline-info.disabled, .btn-outline-info:disabled {
- color: #5bc0de;
+ color: #008196;
background-color: transparent; }
.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,
.show > .btn-outline-info.dropdown-toggle {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196; }
.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,
.show > .btn-outline-info.dropdown-toggle:focus {
- box-shadow: 0 0 0 0.2rem rgba(91, 192, 222, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(0, 129, 150, 0.5); }
.btn-outline-warning {
color: #f0ad4e;
padding: 0.5rem 0;
margin: 0.125rem 0 0;
font-size: 0.9375rem;
- color: #343a40;
+ color: #212529;
text-align: left;
list-style: none;
background-color: #fff;
box-shadow: 0 0 0 0.2rem rgba(57, 132, 57, 0.5); }
.badge-info {
- color: #212529;
- background-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196; }
a.badge-info:hover, a.badge-info:focus {
- color: #212529;
- background-color: #31b0d5; }
+ color: #fff;
+ background-color: #005563; }
a.badge-info:focus, a.badge-info.focus {
outline: 0;
- box-shadow: 0 0 0 0.2rem rgba(91, 192, 222, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(0, 129, 150, 0.5); }
.badge-warning {
color: #212529;
color: #0f210f; }
.alert-info {
- color: #2f6473;
- background-color: #def2f8;
- border-color: #d1edf6; }
+ color: #00434e;
+ background-color: #cce6ea;
+ border-color: #b8dce2; }
.alert-info hr {
- border-top-color: #bce5f2; }
+ border-top-color: #a6d3db; }
.alert-info .alert-link {
- color: #20454f; }
+ color: #00171b; }
.alert-warning {
color: #7d5a29;
text-decoration: none;
background-color: #f8f9fa; }
.list-group-item-action:active {
- color: #343a40;
+ color: #212529;
background-color: #e9ecef; }
.list-group-item {
border-color: #1e451e; }
.list-group-item-info {
- color: #2f6473;
- background-color: #d1edf6; }
+ color: #00434e;
+ background-color: #b8dce2; }
.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {
- color: #2f6473;
- background-color: #bce5f2; }
+ color: #00434e;
+ background-color: #a6d3db; }
.list-group-item-info.list-group-item-action.active {
color: #fff;
- background-color: #2f6473;
- border-color: #2f6473; }
+ background-color: #00434e;
+ border-color: #00434e; }
.list-group-item-warning {
color: #7d5a29;
.popover-body {
padding: 0.5rem 0.75rem;
- color: #343a40; }
+ color: #212529; }
.carousel {
position: relative; }
background-color: #2a602a !important; }
.bg-info {
- background-color: #5bc0de !important; }
+ background-color: #008196 !important; }
a.bg-info:hover, a.bg-info:focus,
button.bg-info:hover,
button.bg-info:focus {
- background-color: #31b0d5 !important; }
+ background-color: #005563 !important; }
.bg-warning {
background-color: #f0ad4e !important; }
border-color: #398439 !important; }
.border-info {
- border-color: #5bc0de !important; }
+ border-color: #008196 !important; }
.border-warning {
border-color: #f0ad4e !important; }
color: #224f22 !important; }
.text-info {
- color: #5bc0de !important; }
+ color: #008196 !important; }
a.text-info:hover, a.text-info:focus {
- color: #28a1c5 !important; }
+ color: #003f4a !important; }
.text-warning {
color: #f0ad4e !important; }
color: #121416 !important; }
.text-body {
- color: #343a40 !important; }
+ color: #212529 !important; }
.text-muted {
color: #6c757d !important; }
background-color: #2a602a; }
.tag-info {
- background-color: #5bc0de; }
+ background-color: #008196; }
.tag-info[href]:hover, .tag-info[href]:focus {
- background-color: #31b0d5; }
+ background-color: #005563; }
.tag-warning {
background-color: #f0ad4e; }
color: #398439; }
.highlight {
- color: #5bc0de; }
+ color: #008196; }
.fitem.advanced .text-info {
font-weight: bold; }
#page-footer a .icon {
color: #fff; }
#page-footer a:focus .icon {
- color: #343a40; }
+ color: #212529; }
.bg-inverse a {
color: #fff;
.dropdown-item a {
display: block;
width: 100%;
- color: #343a40; }
+ color: #212529; }
.dropdown-item:active a {
color: #fff; }
.matchtext {
background-color: #b5d9f9;
- color: #343a40;
+ color: #212529;
height: 1.5rem; }
.border-radius {
color: #0f210f; }
.alert-info a {
- color: #20454f; }
+ color: #00171b; }
.alert-warning a {
color: #573e1c; }
width: 4em; }
#adminthemeselector .selectedtheme td.c0 {
- border: 1px solid #d1edf6;
+ border: 1px solid #b8dce2;
border-right-width: 0; }
#adminthemeselector .selectedtheme td.c1 {
- border: 1px solid #d1edf6;
+ border: 1px solid #b8dce2;
border-left-width: 0; }
.admin_colourpicker,
box-sizing: content-box; }
.admin_colourpicker .colourdialogue {
float: left;
- border: 1px solid #d1edf6; }
+ border: 1px solid #b8dce2; }
.admin_colourpicker .previewcolour {
- border: 1px solid #d1edf6;
+ border: 1px solid #b8dce2;
margin-left: 301px; }
.admin_colourpicker .currentcolour {
- border: 1px solid #d1edf6;
+ border: 1px solid #b8dce2;
margin-left: 301px;
border-top-width: 0; } }
#plugins-check-page .pluginupdateinfo,
#plugins-control-panel .pluginupdateinfo {
- background-color: #def2f8;
+ background-color: #cce6ea;
padding: 5px;
margin: 10px 0;
border-radius: 5px; }
.block .block-controls .dropdown-toggle {
/* So that the caret takes the colour of the icon. */
- color: #343a40; }
+ color: #212529; }
[data-region="blocks-column"] {
width: 360px;
margin-left: 30px;
font-size: 0.8203125rem;
padding: .1em .4em;
- background-color: #def2f8;
- color: #5bc0de;
+ background-color: #cce6ea;
+ color: #008196;
text-decoration: none;
z-index: 9999;
- border: 1px solid #d1edf6; }
+ border: 1px solid #b8dce2; }
/* Course drag and drop upload styles */
#dndupload-status {
width: 40%;
margin: 0 30%;
padding: 6px;
- border: 1px solid #d1edf6;
+ border: 1px solid #b8dce2;
text-align: center;
- background: #def2f8;
- color: #5bc0de;
+ background: #cce6ea;
+ color: #008196;
z-index: 1;
border-radius: 8px; }
#course-category-listings .listing-pagination {
text-align: center; }
#course-category-listings .listing-pagination .yui3-button {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de;
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196;
border: 0;
margin: 0.4rem 0.2rem 0.45rem;
font-size: 10.4px; }
#course-category-listings .listing-pagination .yui3-button:hover {
color: #fff;
- background-color: #3bb4d8;
- border-color: #31b0d5; }
+ background-color: #006070;
+ border-color: #005563; }
#course-category-listings .listing-pagination .yui3-button:focus, #course-category-listings .listing-pagination .yui3-button.focus {
color: #fff;
- background-color: #3bb4d8;
- border-color: #31b0d5;
- box-shadow: 0 0 0 0.2rem rgba(82, 169, 195, 0.5); }
+ background-color: #006070;
+ border-color: #005563;
+ box-shadow: 0 0 0 0.2rem rgba(38, 148, 166, 0.5); }
#course-category-listings .listing-pagination .yui3-button.disabled, #course-category-listings .listing-pagination .yui3-button:disabled {
- color: #212529;
- background-color: #5bc0de;
- border-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196;
+ border-color: #008196; }
#course-category-listings .listing-pagination .yui3-button:not(:disabled):not(.disabled):active, #course-category-listings .listing-pagination .yui3-button:not(:disabled):not(.disabled).active,
.show > #course-category-listings .listing-pagination .yui3-button.dropdown-toggle {
color: #fff;
- background-color: #31b0d5;
- border-color: #2aaacf; }
+ background-color: #005563;
+ border-color: #004a56; }
#course-category-listings .listing-pagination .yui3-button:not(:disabled):not(.disabled):active:focus, #course-category-listings .listing-pagination .yui3-button:not(:disabled):not(.disabled).active:focus,
.show > #course-category-listings .listing-pagination .yui3-button.dropdown-toggle:focus {
- box-shadow: 0 0 0 0.2rem rgba(82, 169, 195, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(38, 148, 166, 0.5); }
#course-category-listings .listing-pagination .yui3-button.active-page {
color: #fff;
background-color: #1177d1;
color: #573e1c; }
.que .formulation {
- color: #2f6473;
- background-color: #def2f8;
- border-color: #d1edf6;
+ color: #00434e;
+ background-color: #cce6ea;
+ border-color: #b8dce2;
/* stylelint-disable-line max-line-length */ }
.que .formulation hr {
- border-top-color: #bce5f2; }
+ border-top-color: #a6d3db; }
.que .formulation .alert-link {
- color: #20454f; }
+ color: #00171b; }
.que.multichoice .answer div.r0 .icon.fa-check,
.que.multichoice .answer div.r1 .icon.fa-check,
margin: 0; }
#page-mod-quiz-edit .questionbankwindow div.header .title {
- color: #343a40; }
+ color: #212529; }
#page-mod-quiz-edit div.container div.generalbox {
background-color: transparent;
padding: 0.2em;
margin: 0;
cursor: pointer;
- color: #343a40; }
+ color: #212529; }
.form-autocomplete-suggestions li:hover {
background-color: #3f9def;
color: #495057; }
.form-autocomplete-downarrow {
- color: #343a40;
+ color: #212529;
top: 0.2rem;
right: 0.5rem;
cursor: pointer; }
font-weight: inherit; }
.path-mod-forum .subscriptionmode {
- color: #343a40; }
+ color: #212529; }
.path-mod-forum .activesetting {
- color: #343a40;
+ color: #212529;
font-weight: bold; }
.discussion-settings-container .custom-select {
margin-bottom: 1rem;
border: 0 solid transparent;
border-radius: 0.25rem;
- color: #2f6473;
- background-color: #def2f8;
- border-color: #d1edf6;
+ color: #00434e;
+ background-color: #cce6ea;
+ border-color: #b8dce2;
/* stylelint-disable-line max-line-length */ }
.assignfeedback_editpdf_widget .label hr {
- border-top-color: #bce5f2; }
+ border-top-color: #a6d3db; }
.assignfeedback_editpdf_widget .label .alert-link {
- color: #20454f; }
+ color: #00171b; }
.assignfeedback_editpdf_menu {
padding: 0; }
.generaltable {
width: 100%;
margin-bottom: 1rem;
- color: #343a40; }
+ color: #212529; }
.generaltable th,
.generaltable td {
padding: 0.75rem;
.generaltable.table-sm td {
padding: 0.3rem; }
.generaltable tbody tr:hover {
- color: #343a40;
+ color: #212529;
background-color: rgba(0, 0, 0, 0.075); }
table caption {
box-shadow: inset 0 0 0 2px #fff; }
.btn-info:focus, .btn-info.focus {
- outline: 0.2rem solid #124a5b;
+ outline: 0.2rem solid black;
box-shadow: inset 0 0 0 2px #fff; }
.btn-warning:focus, .btn-warning.focus {
box-shadow: inset 0 0 0 2px #343a40; }
.btn-outline-info:focus, .btn-outline-info.focus {
- outline: 0.2rem solid #124a5b;
+ outline: 0.2rem solid black;
box-shadow: inset 0 0 0 2px #343a40; }
.btn-outline-warning:focus, .btn-outline-warning.focus {
box-shadow: 0 0 0 0.2rem rgba(57, 132, 57, 0.5); }
.label-info {
- color: #212529;
- background-color: #5bc0de; }
+ color: #fff;
+ background-color: #008196; }
a.label-info:hover, a.label-info:focus {
- color: #212529;
- background-color: #31b0d5; }
+ color: #fff;
+ background-color: #005563; }
a.label-info:focus, a.label-info.focus {
outline: 0;
- box-shadow: 0 0 0 0.2rem rgba(91, 192, 222, 0.5); }
+ box-shadow: 0 0 0 0.2rem rgba(0, 129, 150, 0.5); }
.label-warning {
color: #212529;
defined('MOODLE_INTERNAL') || die();
-$version = 2020061501.10; // 20200615 = branching date YYYYMMDD - do not modify!
+$version = 2020061501.12; // 20200615 = branching date YYYYMMDD - do not modify!
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
-$release = '3.9.1+ (Build: 20200822)'; // Human-friendly version name
+$release = '3.9.1+ (Build: 20200827)'; // Human-friendly version name
$branch = '39'; // This version's branch.
$maturity = MATURITY_STABLE; // This version's maturity level.