Compare commits

...

85 Commits

Author SHA1 Message Date
Eloy Lafuente (stronk7) 0fbe41f4cd Moodle release 3.2rc2 2016-11-22 16:22:21 +01:00
Dan Poltawski e122972d3f Merge branch 'MDL-56938-master-fix1' of http://github.com/damyon/moodle 2016-11-22 10:26:52 +00:00
Damyon Wiese 57bfb7c30a MDL-56938 filter_media: Responsive size fallback player
Apply responsive sizing to any video element in a media filter div.

This applys to the HTML5 video player and the fall back player if
video.js fails to load.
2016-11-22 17:04:55 +08:00
John Okely 529e944a8c MDL-56782 custommenu add multilang example 2016-11-22 15:12:55 +08:00
Andrew Nicols 8d294e729f Merge branch 'MDL-57035-master' of git://github.com/FMCorz/moodle 2016-11-22 12:02:45 +08:00
David Monllao 82f9746962 Merge branch 'MDL-56782-master' of git://github.com/damyon/moodle 2016-11-22 11:46:13 +08:00
Frederic Massart cbca970ab7 MDL-57035 repository_skydrive: Compability with converged type apps
http://go.microsoft.com/fwlink/p/?LinkID=615760
2016-11-22 11:46:05 +08:00
Andrew Nicols 282f0437f1 Merge branch 'wip-mdl-56898-fixup' of https://github.com/rajeshtaneja/moodle 2016-11-22 11:33:25 +08:00
Andrew Nicols 873a7e1e86 Merge branch 'MDL-56683-master' of git://github.com/damyon/moodle 2016-11-22 11:27:28 +08:00
Andrew Nicols 38a8590ed0 Merge branch 'wip-mdl-56994' of https://github.com/rajeshtaneja/moodle 2016-11-22 11:22:30 +08:00
Rajesh Taneja 45e862c4bd MDL-56898 behat: Wait for pending JS after setting password 2016-11-22 11:20:30 +08:00
Andrew Nicols d51d8ca2af Merge branch 'MDL-55838-master' of git://github.com/damyon/moodle 2016-11-22 11:17:33 +08:00
Rajesh Taneja f4565e7147 MDL-56994 behat: Fixed activity selector to find proper li
Previous to this patch, only 1 activity was
expected and if there are more than 1 activities
then it will fail. Improved step to find the
correct activity node by name
2016-11-22 11:02:52 +08:00
Damyon Wiese 52a51514f6 MDL-56683 theme_boost: Popovers on dynamic content 2016-11-22 10:28:25 +08:00
David Monllao 42cf4a3470 Merge branch 'MDL-57023-master' of git://github.com/andrewnicols/moodle 2016-11-22 10:23:21 +08:00
Damyon Wiese 5d03ab36b5 MDL-55838 theme_boost: Fix secure layout
It was out of date with the columns2 layout and had links outside it's content.
2016-11-22 10:22:17 +08:00
Andrew Nicols 727145bf1c MDL-56407 message: Additional unit test for unblocked user 2016-11-22 09:45:52 +08:00
Andrew Nicols d10ca75b8c Merge branch 'MDL-56407-master-2' of git://github.com/junpataleta/moodle 2016-11-22 09:06:09 +08:00
Andrew Nicols aacdf8e280 MDL-57023 tool_usertours: Ensure that the tour key is unique
The tour key was already unique, but this change makes it unique to the
current user too.
2016-11-22 09:05:31 +08:00
Andrew Nicols aabebc7516 MDL-57023 tool_usertours: Update to v0.9.10
This new version of the library brings with it storage of the current
step number in the browser session storage.

This allows the page to reload whilst viewing a tour and have the tour
continue.
2016-11-22 09:05:31 +08:00
David Monllao 5009bcd9b4 Merge branch 'MDL-56986-master-fix' of https://github.com/lameze/moodle 2016-11-22 09:04:26 +08:00
Andrew Nicols 4b2790c580 Merge branch 'MDL-56809-master' of git://github.com/ankitagarwal/moodle 2016-11-22 08:49:18 +08:00
Simey Lameze 5e43ccd3b9 MDL-56986 block_course_summary: remove edit icon scenario from behat 2016-11-22 08:39:35 +08:00
Andrew Nicols 783ef76bfc Merge branch 'MDL-56716-master' of git://github.com/damyon/moodle 2016-11-22 08:10:11 +08:00
Dan Poltawski 4b631c2d87 Merge branch 'wip-mdl-56898-fix2' of https://github.com/rajeshtaneja/moodle 2016-11-21 15:07:49 +00:00
Damyon Wiese 7e81bd114e MDL-56782 custommenu - update docs
We don't support sub-menus in all themes (boost) so we want to update
the docs and example.
2016-11-21 21:17:43 +08:00
Dan Poltawski 9446cb507c Merge branch 'MDL-56318-master' of git://github.com/damyon/moodle 2016-11-21 09:55:09 +00:00
Damyon Wiese 21a5c3c447 MDL-56318 assign: Polish for assign grading in boost
These styles mostly remove the responsiveness from the grading form.
2016-11-21 16:59:39 +08:00
David Monllao 9557be1542 Merge branch 'MDL-57063-master' of git://github.com/FMCorz/moodle 2016-11-21 16:53:44 +08:00
Dan Poltawski 05551a935a Merge branch 'MDL-56849-master' of git://github.com/damyon/moodle 2016-11-21 08:36:27 +00:00
Dan Poltawski f7d76254fd Merge branch 'MDL-56994-master-2' of git://github.com/junpataleta/moodle 2016-11-21 07:30:58 +00:00
Damyon Wiese 28f2458448 MDL-56849 mod_wiki: Update styles for boost
Make sure all form field have bootstrap styles. Use bootstrap tables on
tables. Remove custom styling. Prefer left-aligned text.
2016-11-21 15:19:16 +08:00
Damyon Wiese e283c6ca33 MDL-56716 boost: Fix styling for review options
The checkbox form template was changed, so this custom rule needs
updating.
2016-11-21 15:08:41 +08:00
Rajesh Taneja 26fef01b6b MDL-56898 behat: Go to a non html page to avoid any unwanted ajax calls
After scenario is finished, go to README.txt, so
there is no JS/AJAX calls pending and site is ready
for reset before next scenario
2016-11-21 14:16:49 +08:00
Rajesh Taneja d9a9a87835 MDL-56898 behat: Ensure the page is stable before executing 2016-11-21 14:16:48 +08:00
David Monllao e0ba33697f Merge branch 'MDL-56938-master' of git://github.com/damyon/moodle 2016-11-21 14:09:43 +08:00
Ankit Agarwal f318b74b49 MDL-56809 boost: Don't escape html in single select options 2016-11-21 11:38:51 +05:30
Ankit Agarwal 63531fff79 MDL-56809 boost: Add template context info 2016-11-21 11:38:51 +05:30
Andrew Nicols 51e8968635 Merge branch 'MDL-56612_master' of git://github.com/dmonllao/moodle 2016-11-21 13:40:00 +08:00
Andrew Nicols e67c14053e Merge branch 'MDL-56974-master' of git://github.com/jleyva/moodle 2016-11-21 13:21:27 +08:00
David Monllao 30f023b1b3 Merge branch 'MDL-56975-master' of git://github.com/jleyva/moodle 2016-11-21 13:15:40 +08:00
Damyon Wiese fce0f1c235 MDL-56938 messages: Images and videos display badly in messaging
Make sure they get minimum and maximum width so they don't overflow and
don't appear tiny.
2016-11-21 13:01:36 +08:00
David Monllao 57c01bca0e MDL-56612 navigation: Remove redundant load_courses_enrolled call 2016-11-21 12:42:09 +08:00
David Monllao 7d432be4e9 Merge branch 'MDL-57017-master' of git://github.com/andrewnicols/moodle 2016-11-21 12:40:26 +08:00
Andrew Nicols 2380daba7b Merge branch 'MDL-57054-master' of git://github.com/jleyva/moodle 2016-11-21 12:38:05 +08:00
David Monllao 2f5208ea1b Merge branch 'MDL-57049-master' of https://github.com/snake/moodle 2016-11-21 11:49:59 +08:00
Andrew Nicols 1e9487092d Merge branch 'MDL-56877' of https://github.com/eSrem/moodle 2016-11-21 11:08:01 +08:00
Frederic Massart 3d3fb328b4 MDL-57063 backup: Do not try to set default value on locked setting
We cannot set a default value on settings which are 'config' or
'permission' locked or an exception will be thrown from
base_setting::set_value.
2016-11-21 11:03:41 +08:00
Andrew Nicols 23bb1871b3 Merge branch 'MDL-55275' of https://github.com/tobiasreischmann/moodle 2016-11-21 11:01:40 +08:00
Andrew Nicols 896718ef79 Merge branch 'MDL-56943-master' of git://github.com/danpoltawski/moodle 2016-11-21 10:54:09 +08:00
David Monllao dfe7cbe4cf Merge branch 'MDL-57036_master' of git://github.com/markn86/moodle 2016-11-21 10:51:29 +08:00
Jun Pataleta 25bfa25190 MDL-56994 mod_forum: Auto-create news forum if course format supports it 2016-11-21 10:05:05 +08:00
Jun Pataleta e47d61e198 MDL-56994 course: Show News field only if course format supports news 2016-11-21 10:05:01 +08:00
Jun Pataleta 87799e9fba MDL-56994 course: New method to check if format supports news forum 2016-11-21 09:50:55 +08:00
David Monllao 30cfed3731 Merge branch 'MDL-57052-master' of git://github.com/jleyva/moodle 2016-11-21 09:47:51 +08:00
David Monllao 406f1eb76d Merge branch 'MDL-57051-master' of git://github.com/jleyva/moodle 2016-11-21 09:45:44 +08:00
Rajesh Taneja 7f24e5e654 MDL-56898 behat: Click on logout link in footer, it's faster 2016-11-21 09:25:35 +08:00
Rajesh Taneja 65eb39c0b4 MDL-56898 behat: Increase autosavefrequency for behat tests
We don't need editor to autosave, as this cause
unwanted ajax request
2016-11-21 09:25:35 +08:00
Rajesh Taneja 1bce723292 MDL-56898 behat: Try data reset if it fails because of pending process 2016-11-21 09:25:35 +08:00
David Monllao f48cc821db Merge branch 'MDL-56972-master' of https://github.com/snake/moodle 2016-11-21 09:05:40 +08:00
Jake Dallimore 0a5cafcbe9 MDL-57049 libraries: update jqueryui version in requirejs path 2016-11-21 08:57:53 +08:00
Andrew Nicols 5084343b3f Merge branch 'MDL-42977-master' of git://github.com/lameze/moodle 2016-11-21 08:52:42 +08:00
David Monllao a4abacc9a6 Merge branch 'MDL-56986-master' of git://github.com/lameze/moodle 2016-11-21 08:51:47 +08:00
David Monllao ff687b9c15 Merge branch 'MDL-56843-master' of git://github.com/lameze/moodle 2016-11-21 08:48:22 +08:00
Andrew Nicols b0db945b11 Merge branch 'MDL-57002-master' of git://github.com/FMCorz/moodle 2016-11-21 08:21:31 +08:00
Juan Leyva d0da94cdf4 MDL-56974 auth_email: Incorrect param type for redirect in sign_up WS 2016-11-19 18:21:56 +00:00
Juan Leyva 02bb0c0637 MDL-56975 tool_mobile: Fix page set_url 2016-11-19 18:15:59 +00:00
Juan Leyva 8abfb7b1bb MDL-57054 mod_quiz: check_updates_since not returning questionids 2016-11-19 17:44:48 +00:00
Juan Leyva 0840b3e687 MDL-57052 course: Missing required file in check_module_updates_since 2016-11-19 17:27:01 +00:00
Juan Leyva 6706c1cb12 MDL-57051 course: Do not return directories in check_module_updates 2016-11-19 16:54:31 +00:00
Dan Poltawski 835f1f9add Merge branch 'MDL-57038-master' of git://github.com/FMCorz/moodle 2016-11-18 14:41:56 +00:00
Dan Poltawski b3fd942b52 Merge branch 'MDL-56693_master' of git://github.com/dmonllao/moodle 2016-11-18 14:25:20 +00:00
EizEddin AlKatrib af28ceb945 MDL-42977 course: Fixed the default behaviour of the Collapse/Expand all link 2016-11-18 14:24:42 +08:00
Frederic Massart 538ce414a5 MDL-57002 repository_webdav: Use default temporary file name
The WebDAV library does not like when there are UTF-8 characters
in the temporary file name. It changes the path but does not return
it, so the file ends up being saved somewhere unknown. As we do not
need the file name at all, we let repository::prepare_file()
generate one.
2016-11-18 12:47:59 +08:00
David Monllao f2e599d51c MDL-56693 boost: Highlight config.php settings in admin UI 2016-11-18 12:22:59 +08:00
Jake Dallimore fe9864f488 MDL-56972 backup: fix question category stamp duplicates during restore
To kerb future stamp duplication, MDL-54864 added a unique index to the
question_categories table (stamp, contextid) and added an upgrade step
to fix existing duplicate stamps. It missed the case where a course with
duplicate stamps in the same context is directly restored into moodle
3.1, causing index clashes. This issue provides a fix for that.
2016-11-18 11:15:02 +08:00
Mark Nelson f4c39cb983 MDL-57036 core_message: always show profile picture on messaging UI 2016-11-18 11:13:36 +08:00
Frederic Massart 3d66b5a100 MDL-57038 theme_bootstrapbase: Fix expand icon with RTL auto-flipped 2016-11-18 11:05:10 +08:00
Simey Lameze b95a05a536 MDL-56843 theme_boost: remove top margin from repository search div 2016-11-18 09:47:30 +08:00
Simey Lameze 2da36b3750 MDL-56986 block_course_summary: remove unnecessary small cog icon 2016-11-18 09:18:46 +08:00
Virgil Ashruf 5ceb68d169 MDL-56877 autogroup form: no limit on cohorts 2016-11-17 10:46:53 +01:00
Andrew Nicols c6b4421524 MDL-57017 tool_usertours: Allow targetting of the frontpage 2016-11-17 10:23:00 +08:00
Jun Pataleta 26dca05d02 MDL-56407 message: Indicate user is blocked in message area 2016-11-17 09:11:37 +08:00
Dan Poltawski a4e2d64571 MDL-56943 boost: correct ARIA roles
* role="navigation" can't go directly on a list
* role="banner" should only be done once and not on a link
2016-11-16 16:52:03 +00:00
Tobias Reischmann 1cca9a3479 MDL-55275 assign: Prevent exception under admin role assignment.
In group mode the submission status was displayed to admins.
This caused an exception when the admins were enrolled as teachers
in a course while being the only member of a group.
2016-11-16 16:55:22 +01:00
82 changed files with 1010 additions and 389 deletions
+2 -1
View File
@@ -94,7 +94,8 @@ $isios = core_useragent::is_ios();
if ($confirmed or $isios) {
$PAGE->set_context(context_system::instance());
$PAGE->set_heading($COURSE->fullname);
$PAGE->set_url('/local/mobile/launch.php', array('service' => $serviceshortname, 'passport' => $passport, 'urlscheme' => $urlscheme));
$params = array('service' => $serviceshortname, 'passport' => $passport, 'urlscheme' => $urlscheme, 'confirmed' => $confirmed);
$PAGE->set_url("/$CFG->admin/tool/mobile/launch.php", $params);
echo $OUTPUT->header();
if ($confirmed) {
File diff suppressed because one or more lines are too long
+41
View File
@@ -37,6 +37,20 @@ function Tour(config) {
*/
Tour.prototype.tourName;
/**
* The name of the tour storage key.
*
* @property {String} storageKey
*/
Tour.prototype.storageKey;
/**
* The session storage object
*
* @property {Storage} storage
*/
Tour.prototype.storage;
/**
* The original configuration as passed into the constructor.
*
@@ -120,6 +134,14 @@ Tour.prototype.init = function (config) {
// Apply configuration.
this.configure.apply(this, arguments);
try {
this.storage = window.sessionStorage;
this.storageKey = 'tourstate_' + this.tourName;
} catch (e) {
this.storage = false;
this.storageKey = '';
}
return this;
};
@@ -280,6 +302,15 @@ Tour.prototype.getCurrentStepNumber = function () {
*/
Tour.prototype.setCurrentStepNumber = function (stepNumber) {
this.currentStepNumber = stepNumber;
if (this.storage) {
try {
this.storage.setItem(this.storageKey, stepNumber);
} catch (e) {
if (e.code === DOMException.QUOTA_EXCEEDED_ERR) {
this.storage.removeItem(this.storageKey);
}
}
}
};
/**
@@ -957,6 +988,16 @@ Tour.prototype.handleKeyDown = function (e) {
* @chainable
*/
Tour.prototype.startTour = function (startAt) {
if (this.storage && typeof startAt === 'undefined') {
var storageStartValue = this.storage.getItem(this.storageKey);
if (storageStartValue) {
var storageStartAt = parseInt(storageStartValue, 10);
if (storageStartAt <= this.steps.length) {
startAt = storageStartAt;
}
}
}
if (typeof startAt === 'undefined') {
startAt = this.getCurrentStepNumber();
}
+11 -4
View File
@@ -76,15 +76,22 @@ EOF;
/**
* Fetch all enabled tours matching the specified target.
*
* @param string $targetmatch The URL to match.
* @param moodle_url $targetmatch The URL to match.
*/
public static function get_matching_tourdata($targetmatch) {
public static function get_matching_tourdata(\moodle_url $targetmatch) {
$tours = self::get_enabled_tourdata();
return array_filter($tours, function($tour) use ($targetmatch) {
// Attempt to determine whether this is the front page.
// This is a special case because the frontpage uses a shortened page path making it difficult to detect exactly.
$isfrontpage = $targetmatch->compare(new \moodle_url('/'), URL_MATCH_BASE);
$target = $targetmatch->out_as_local_url();
return array_filter($tours, function($tour) use ($isfrontpage, $target) {
if ($isfrontpage && $tour->pathmatch === 'FRONTPAGE') {
return true;
}
$pattern = preg_quote($tour->pathmatch, '@');
$pattern = str_replace('%', '.*', $pattern);
return !!preg_match("@{$pattern}@", $targetmatch);
return !!preg_match("@{$pattern}@", $target);
});
}
+1 -1
View File
@@ -559,7 +559,7 @@ class manager {
public static function get_matching_tours(\moodle_url $pageurl) {
global $PAGE;
$tours = cache::get_matching_tourdata($pageurl->out_as_local_url());
$tours = cache::get_matching_tourdata($pageurl);
foreach ($tours as $record) {
$tour = tour::load_from_record($record);
+3 -1
View File
@@ -608,6 +608,8 @@ class tour {
* This is used in the session cookie to determine whether the user has seen this tour before.
*/
public function get_tour_key() {
global $USER;
$tourtime = $this->get_config('majorupdatetime', null);
if ($tourtime === null) {
@@ -622,7 +624,7 @@ class tour {
$tourtime = max($tourtime, $userresetdate);
}
return sprintf('tool_usertours_%d_%s', $this->get_id(), $tourtime);
return sprintf('tool_usertours_%d_%d_%s', $USER->id, $this->get_id(), $tourtime);
}
/**
@@ -79,7 +79,10 @@ Some example values include:
* /my/% - to match the Dashboard
* /course/view.php?id=2 - to match a specific course
* /mod/forum/view.php% - to match the forum discussion list
* /user/profile.php% - to match the user profile page';
* /user/profile.php% - to match the user profile page
If you wish to display a tour on the Site Home page, you can use the value: "FRONTPAGE".
';
$string['placement'] = 'Placement';
$string['pluginname'] = 'User tours';
$string['resettouronpage'] = 'Reset user tour on this page';
+19 -1
View File
@@ -150,6 +150,14 @@ class cache_testcase extends advanced_testcase {
'name' => 'my_glob_2',
'pathmatch' => '/my/%'
],
(object) [
'name' => 'frontpage_only',
'pathmatch' => 'FRONTPAGE'
],
(object) [
'name' => 'frontpage_match',
'pathmatch' => '/?%'
],
];
return [
@@ -163,6 +171,16 @@ class cache_testcase extends advanced_testcase {
'/my/view.php',
['my_exact_1', 'my_glob_1', 'my_glob_2'],
],
'Special constant FRONTPAGE must match front page only' => [
$tourconfigs,
'/',
['frontpage_only'],
],
'Standard frontpage URL matches both the special constant, and a correctly formed pathmatch' => [
$tourconfigs,
'/?redirect=0',
['frontpage_only', 'frontpage_match'],
],
];
}
@@ -181,7 +199,7 @@ class cache_testcase extends advanced_testcase {
$this->helper_create_step((object) ['tourid' => $tour->get_id()]);
}
$matches = \tool_usertours\cache::get_matching_tourdata((new moodle_url($targetmatch))->out_as_local_url());
$matches = \tool_usertours\cache::get_matching_tourdata(new moodle_url($targetmatch));
$this->assertCount(count($expected), $matches);
for ($i = 0; $i < count($matches); $i++) {
+6 -6
View File
@@ -729,7 +729,7 @@ class tour_testcase extends advanced_testcase {
$this->greaterThanOrEqual($time),
true,
null,
sprintf('tool_usertours_%d_%s', $id, $time),
sprintf('tool_usertours_\d_%d_%s', $id, $time),
],
'Initial tour time, no user pref' => [
@@ -738,7 +738,7 @@ class tour_testcase extends advanced_testcase {
null,
false,
null,
sprintf('tool_usertours_%d_%s', $id, $time),
sprintf('tool_usertours_\d_%d_%s', $id, $time),
],
'Initial tour time, with user reset lower' => [
$id,
@@ -746,7 +746,7 @@ class tour_testcase extends advanced_testcase {
null,
false,
$time - DAYSECS,
sprintf('tool_usertours_%d_%s', $id, $time),
sprintf('tool_usertours_\d_%d_%s', $id, $time),
],
'Initial tour time, with user reset higher' => [
$id,
@@ -754,7 +754,7 @@ class tour_testcase extends advanced_testcase {
null,
false,
$time + DAYSECS,
sprintf('tool_usertours_%d_%s', $id, $time + DAYSECS),
sprintf('tool_usertours_\d_%d_%s', $id, $time + DAYSECS),
],
];
}
@@ -823,8 +823,8 @@ class tour_testcase extends advanced_testcase {
set_user_preference(\tool_usertours\tour::TOUR_REQUESTED_BY_USER . $id, $userpref);
}
$this->assertEquals(
$expectation,
$this->assertRegExp(
'/' . $expectation . '/',
$tour->get_tour_key()
);
}
+1 -1
View File
@@ -4,7 +4,7 @@
<location>amd/src/tour.js</location>
<name>Flexitour</name>
<license>GPLv3</license>
<version>0.9.9</version>
<version>0.9.10</version>
<licenseversion>3</licenseversion>
</library>
<library>
+3 -2
View File
@@ -203,7 +203,8 @@ class auth_email_external extends external_api {
)
), 'User custom fields (also known as user profile fields)', VALUE_DEFAULT, array()
),
'redirect' => new external_value(PARAM_URL, 'Redirect the user to this url after confirmation.', VALUE_DEFAULT, ''),
'redirect' => new external_value(PARAM_LOCALURL, 'Redirect the user to this site url after confirmation.',
VALUE_DEFAULT, ''),
)
);
}
@@ -221,7 +222,7 @@ class auth_email_external extends external_api {
* @param string $recaptchachallengehash recaptcha challenge hash
* @param string $recaptcharesponse recaptcha response
* @param array $customprofilefields user custom fields (also known as user profile fields)
* @param string $redirect Url to redirect the user after confirmation
* @param string $redirect Site url to redirect the user after confirmation
* @return array settings and possible warnings
* @since Moodle 3.2
* @throws moodle_exception
+2 -13
View File
@@ -61,18 +61,7 @@ class behat_auth extends behat_base {
* @Given /^I log out$/
*/
public function i_log_out() {
// There is no longer any need to worry about whether the navigation
// bar needs to be expanded; user_menu now lives outside the
// hamburger.
// However, the user menu *always* needs to be expanded. if running JS.
if ($this->running_javascript()) {
$xpath = "//div[@class='usermenu']//a[contains(concat(' ', @class, ' '), ' toggle-display ')]";
$this->execute('behat_general::i_click_on', array($xpath, "xpath_element"));
}
// No need to check for exceptions as it will checked after this step execution.
$this->execute('behat_general::click_link', get_string('logout'));
// Click on logout link in footer, as it's much faster.
$this->execute('behat_general::i_click_on_in_the', array(get_string('logout'), 'link', '#page-footer', "css_element"));
}
}
+8
View File
@@ -4331,6 +4331,14 @@ class restore_create_categories_and_questions extends restore_structure_step {
}
$data->contextid = $mapping->parentitemid;
// Before 3.1, the 'stamp' field could be erroneously duplicated.
// From 3.1 onwards, there's a unique index of (contextid, stamp).
// If we encounter a duplicate in an old restore file, just generate a new stamp.
// This is the same as what happens during an upgrade to 3.1+ anyway.
if ($DB->record_exists('question_categories', ['stamp' => $data->stamp, 'contextid' => $data->contextid])) {
$data->stamp = make_unique_id_code();
}
// Let's create the question_category and save mapping
$newitemid = $DB->insert_record('question_categories', $data);
$this->set_mapping('question_category', $oldid, $newitemid);
@@ -628,7 +628,9 @@ abstract class backup_controller_dbops extends backup_dbops {
$locked = $uselocks && (get_config('backup', $config.'_locked') == true);
if ($plan->setting_exists($settingname)) {
$setting = $plan->get_setting($settingname);
if ($setting->get_value() != $value || 1==1) {
// We can only update the setting if it isn't already locked by config or permission.
if ($setting->get_status() !== base_setting::LOCKED_BY_CONFIG
&& $setting->get_status() !== base_setting::LOCKED_BY_PERMISSION) {
$setting->set_value($value);
if ($locked) {
$setting->set_status(base_setting::LOCKED_BY_CONFIG);
@@ -65,14 +65,6 @@ class block_course_summary extends block_base {
$context = context_course::instance($this->page->course->id);
$this->page->course->summary = file_rewrite_pluginfile_urls($this->page->course->summary, 'pluginfile.php', $context->id, 'course', 'summary', NULL);
$this->content->text = format_text($this->page->course->summary, $this->page->course->summaryformat, $options);
if ($this->page->user_is_editing()) {
if($this->page->course->id == SITEID) {
$editpage = $CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section=frontpagesettings';
} else {
$editpage = $CFG->wwwroot.'/course/edit.php?id='.$this->page->course->id;
}
$this->content->text .= "<div class=\"editbutton\"><a href=\"$editpage\"><img src=\"" . $OUTPUT->pix_url('t/edit') . "\" alt=\"".get_string('edit')."\" /></a></div>";
}
$this->content->footer = '';
return $this->content;
@@ -29,15 +29,6 @@ Feature: Course summary block used in a course
And I should see "Course summary" in the "Course summary" "block"
And I should see "Proved the course summary block works!" in the "Course summary" "block"
Scenario: Teacher can see an edit icon when edit mode is on and follow it to the course edit page
When I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
Then I should see "Proved the course summary block works!" in the "Course summary" "block"
And I should see "Course summary" in the "Course summary" "block"
And I click on ".editbutton a" "css_element" in the "Course summary" "block"
Then I should see "Edit course settings" in the "h2" "css_element"
Scenario: Teacher can not see edit icon when edit mode is off
When I log in as "teacher1"
And I follow "Course 1"
@@ -22,15 +22,6 @@ Feature: Course summary block used on the frontpage
And I should not see "Course summary" in the "Course/site summary" "block"
And I should see "Proved the summary block works!" in the "Course/site summary" "block"
Scenario: Admin can see an edit icon when edit mode is on and follow it to the front page settings
When I log in as "admin"
And I am on site homepage
And I follow "Turn editing on"
Then I should see "Proved the summary block works!" in the "Course/site summary" "block"
And I should not see "Course summary" in the "Course/site summary" "block"
And I click on ".editbutton a" "css_element" in the "Course/site summary" "block"
Then I should see "Front page settings" in the "h2" "css_element"
Scenario: Admin can not see edit icon when edit mode is off
When I log in as "admin"
And I am on site homepage
+6 -5
View File
@@ -124,11 +124,12 @@ class behat_completion extends behat_base {
} else {
$imgalttext = get_string("completion-alt-auto-y", 'core_completion', $activityname);
}
$csselementforactivitytype = "li.modtype_".strtolower($activitytype);
$activityxpath = "//li[contains(concat(' ', @class, ' '), ' modtype_" . strtolower($activitytype) . " ')]";
$activityxpath .= "[descendant::*[contains(text(), '" . $activityname . "')]]";
$xpathtocheck = "//img[contains(@alt, '$imgalttext')]";
$this->execute("behat_general::should_exist_in_the",
array($xpathtocheck, "xpath_element", $csselementforactivitytype, "css_element")
array($xpathtocheck, "xpath_element", $activityxpath, "xpath_element")
);
}
@@ -144,12 +145,12 @@ class behat_completion extends behat_base {
} else {
$imgalttext = get_string("completion-alt-auto-n", 'core_completion', $activityname);
}
$csselementforactivitytype = "li.modtype_".strtolower($activitytype);
$activityxpath = "//li[contains(concat(' ', @class, ' '), ' modtype_" . strtolower($activitytype) . " ')]";
$activityxpath .= "[descendant::*[contains(text(), '" . $activityname . "')]]";
$xpathtocheck = "//img[contains(@alt, '$imgalttext')]";
$this->execute("behat_general::should_exist_in_the",
array($xpathtocheck, "xpath_element", $csselementforactivitytype, "css_element")
array($xpathtocheck, "xpath_element", $activityxpath, "xpath_element")
);
}
}
+15 -5
View File
@@ -217,11 +217,6 @@ class course_edit_form extends moodleform {
$mform->addElement('select', 'calendartype', get_string('forcecalendartype', 'calendar'), $calendars);
}
$options = range(0, 10);
$mform->addElement('select', 'newsitems', get_string('newsitemsnumber'), $options);
$mform->addHelpButton('newsitems', 'newsitemsnumber');
$mform->setDefault('newsitems', $courseconfig->newsitems);
$mform->addElement('selectyesno', 'showgrades', get_string('showgrades'));
$mform->addHelpButton('showgrades', 'showgrades');
$mform->setDefault('showgrades', $courseconfig->showgrades);
@@ -372,6 +367,21 @@ class course_edit_form extends moodleform {
$mform->insertElementBefore($mform->removeElement($elements[$i]->getName(), false),
'addcourseformatoptionshere');
}
if ($courseformat->supports_news()) {
// Show the news items select field if the course format supports news.
$options = range(0, 10);
$newsitems = $mform->createElement('select', 'newsitems', get_string('newsitemsnumber'), $options);
$mform->insertElementBefore($newsitems, 'showgrades');
$courseconfig = get_config('moodlecourse');
$mform->setDefault('newsitems', $courseconfig->newsitems);
$mform->addHelpButton('newsitems', 'newsitemsnumber');
} else {
// Otherwise, create a hidden newsitems element and set its value to 0.
$newsitems = $mform->addElement('hidden', 'newsitems', 0);
$mform->setType('newsitems', PARAM_INT);
$newsitems->setValue(0);
}
}
}
+20
View File
@@ -1139,6 +1139,26 @@ abstract class format_base {
return $startdate + $courseduration;
}
/**
* Indicates whether the course format supports the creation of the Announcements forum.
*
* For course format plugin developers, please override this to return true if you want the Announcements forum
* to be created upon course creation.
*
* @return bool
*/
public function supports_news() {
// For backwards compatibility, check if default blocks include the news_items block.
$defaultblocks = $this->get_default_blocks();
foreach ($defaultblocks as $blocks) {
if (in_array('news_items', $blocks)) {
return true;
}
}
// Return false by default.
return false;
}
/**
* Get the start date value from the course settings page form.
*
+9
View File
@@ -401,6 +401,15 @@ class format_topics extends format_base {
}
return parent::inplace_editable_render_section_name($section, $linkifneeded, $editable, $edithint, $editlabel);
}
/**
* Indicates whether the course format supports the creation of a news forum.
*
* @return bool
*/
public function supports_news() {
return true;
}
}
/**
+3
View File
@@ -7,6 +7,9 @@ Overview of this plugin type at http://docs.moodle.org/dev/Course_formats
* Course formats can overwrite get_default_course_enddate function to set the default course end date for new courses.
format_base::get_default_course_enddate uses the new "Course duration" site setting to calculate the default course end date
from the default course start date.
* New method format_base::supports_news() which is used to determine whether an Announcements forum will be automatically created on
course creation. For course format plugin developers, please override format_base::supports_news() to return true if you want the
Announcements forum to be created upon course creation and remove the block names defined in format_base::get_default_blocks().
=== 3.1 ===
* Course format may use the inplace_editable template to allow quick editing of section names, see
+9
View File
@@ -488,6 +488,15 @@ class format_weeks extends format_base {
$dates = $this->get_section_dates(intval($numsections), $startdate);
return $dates->end;
}
/**
* Indicates whether the course format supports the creation of a news forum.
*
* @return bool
*/
public function supports_news() {
return true;
}
}
/**
+2 -1
View File
@@ -3935,7 +3935,7 @@ function course_check_module_updates_since($cm, $from, $fileareas = array(), $fi
}
if (!empty($fileareas) and (empty($filter) or in_array('fileareas', $filter))) {
$fs = get_file_storage();
$files = $fs->get_area_files($context->id, $component, $fileareas, false, "filearea, timemodified DESC", true, $from);
$files = $fs->get_area_files($context->id, $component, $fileareas, false, "filearea, timemodified DESC", false, $from);
foreach ($fileareas as $filearea) {
$updates->{$filearea . 'files'} = (object) array('updated' => false);
}
@@ -3993,6 +3993,7 @@ function course_check_module_updates_since($cm, $from, $fileareas = array(), $fi
// Check comments.
if (plugin_supports('mod', $cm->modname, FEATURE_COMMENT) and (empty($filter) or in_array('comments', $filter))) {
$updates->comments = (object) array('updated' => false);
require_once($CFG->dirroot . '/comment/lib.php');
require_once($CFG->dirroot . '/comment/locallib.php');
$manager = new comment_manager();
$comments = $manager->get_component_comments_since($course, $context, $component, $from, $cm);
+2 -5
View File
@@ -1506,14 +1506,11 @@ class core_course_renderer extends plugin_renderer_base {
if ($coursecat->get_children_count()) {
$classes = array(
'collapseexpand',
'collapse-all',
);
if ($chelper->get_subcat_depth() == 1) {
$classes[] = 'disabled';
}
// Only show the collapse/expand if there are children to expand.
$content .= html_writer::start_tag('div', array('class' => 'collapsible-actions'));
$content .= html_writer::link('#', get_string('collapseall'),
$content .= html_writer::link('#', get_string('expandall'),
array('class' => implode(' ', $classes)));
$content .= html_writer::end_tag('div');
$this->page->requires->strings_for_js(array('collapseall', 'expandall'), 'moodle');
+62
View File
@@ -101,4 +101,66 @@ class core_course_courseformat_testcase extends advanced_testcase {
$this->assertFalse($modinfoteacher->get_cm($assign1->cmid)->available);
$this->assertTrue($modinfoteacher->get_cm($assign1->cmid)->uservisible);
}
/**
* Test for supports_news() with a course format plugin that doesn't define 'news_items' in default blocks.
*/
public function test_supports_news() {
$this->resetAfterTest();
$format = course_get_format((object)['format' => 'testformat']);
$this->assertFalse($format->supports_news());
}
/**
* Test for supports_news() for old course format plugins that defines 'news_items' in default blocks.
*/
public function test_supports_news_legacy() {
$this->resetAfterTest();
$format = course_get_format((object)['format' => 'testlegacy']);
$this->assertTrue($format->supports_news());
}
}
/**
* Class format_testformat.
*
* A test class that simulates a course format that doesn't define 'news_items' in default blocks.
*
* @copyright 2016 Jun Pataleta <jun@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class format_testformat extends format_base {
/**
* Returns the list of blocks to be automatically added for the newly created course.
*
* @return array
*/
public function get_default_blocks() {
return [
BLOCK_POS_RIGHT => [],
BLOCK_POS_LEFT => []
];
}
}
/**
* Class format_testlegacy.
*
* A test class that simulates old course formats that define 'news_items' in default blocks.
*
* @copyright 2016 Jun Pataleta <jun@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class format_testlegacy extends format_base {
/**
* Returns the list of blocks to be automatically added for the newly created course.
*
* @return array
*/
public function get_default_blocks() {
return [
BLOCK_POS_RIGHT => ['news_items'],
BLOCK_POS_LEFT => []
];
}
}
@@ -25,10 +25,12 @@ var CSS = {
HASCHILDREN: 'with_children'
},
SELECTORS = {
WITHCHILDRENTREES: '.with_children',
LOADEDTREES: '.with_children.loaded',
CONTENTNODE: '.content',
CATEGORYLISTENLINK: '.category .info .categoryname',
CATEGORYSPINNERLOCATION: '.categoryname',
CATEGORYWITHCOLLAPSEDCHILDREN: '.category.with_children.collapsed',
CATEGORYWITHCOLLAPSEDLOADEDCHILDREN: '.category.with_children.loaded.collapsed',
CATEGORYWITHMAXIMISEDLOADEDCHILDREN: '.category.with_children.loaded:not(.collapsed)',
COLLAPSEEXPAND: '.collapseexpand',
@@ -82,6 +84,58 @@ NS.setup_keyboard_listeners = function() {
Y.one(Y.config.doc).delegate('key', this.collapse_expand_all, 'enter', SELECTORS.COLLAPSEEXPAND, this);
};
/**
* Expand all categories.
*
* @method expand_category
* @private
* @param {Node} categorynode The node to expand
*/
NS.expand_category = function(categorynode) {
// Load the actual dependencies now that we've been called.
Y.use('io-base', 'json-parse', 'moodle-core-notification', 'anim-node-plugin', function() {
// Overload the expand_category with the _expand_category function to ensure that
// this function isn't called in the future, and call it for the first time.
NS.expand_category = NS._expand_category;
NS.expand_category(categorynode);
});
};
NS._expand_category = function(categorynode) {
var categoryid,
depth;
if (!categorynode.hasClass(CSS.HASCHILDREN)) {
// Nothing to do here - this category has no children.
return;
}
if (categorynode.hasClass(CSS.LOADED)) {
// We've already loaded this content so we just need to toggle the view of it.
this.run_expansion(categorynode);
return;
}
// We use Data attributes to store the category.
categoryid = categorynode.getData('categoryid');
depth = categorynode.getData('depth');
if (typeof categoryid === "undefined" || typeof depth === "undefined") {
return;
}
this._toggle_generic_expansion({
parentnode: categorynode,
childnode: categorynode.one(SELECTORS.CONTENTNODE),
spinnerhandle: SELECTORS.CATEGORYSPINNERLOCATION,
data: {
categoryid: categoryid,
depth: depth,
showcourses: categorynode.getData('showcourses'),
type: TYPE_CATEGORY
}
});
};
/**
* Toggle the animation of the clicked category node.
*
@@ -310,12 +364,12 @@ NS._collapse_expand_all = function(e) {
NS.expand_all = function(ancestor) {
var finalexpansions = [];
ancestor.all(SELECTORS.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN)
ancestor.all(SELECTORS.CATEGORYWITHCOLLAPSEDCHILDREN)
.each(function(c) {
if (c.ancestor(SELECTORS.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN)) {
if (c.ancestor(SELECTORS.CATEGORYWITHCOLLAPSEDCHILDREN)) {
// Expand the hidden children first without animation.
c.removeClass(CSS.SECTIONCOLLAPSED);
c.all(SELECTORS.LOADEDTREES).removeClass(CSS.SECTIONCOLLAPSED);
c.all(SELECTORS.WITHCHILDRENTREES).removeClass(CSS.SECTIONCOLLAPSED);
} else {
finalexpansions.push(c);
}
@@ -323,7 +377,7 @@ NS.expand_all = function(ancestor) {
// Run the final expansion with animation on the visible items.
Y.all(finalexpansions).each(function(c) {
this.run_expansion(c);
this.expand_category(c);
}, this);
};
File diff suppressed because one or more lines are too long
@@ -25,10 +25,12 @@ var CSS = {
HASCHILDREN: 'with_children'
},
SELECTORS = {
WITHCHILDRENTREES: '.with_children',
LOADEDTREES: '.with_children.loaded',
CONTENTNODE: '.content',
CATEGORYLISTENLINK: '.category .info .categoryname',
CATEGORYSPINNERLOCATION: '.categoryname',
CATEGORYWITHCOLLAPSEDCHILDREN: '.category.with_children.collapsed',
CATEGORYWITHCOLLAPSEDLOADEDCHILDREN: '.category.with_children.loaded.collapsed',
CATEGORYWITHMAXIMISEDLOADEDCHILDREN: '.category.with_children.loaded:not(.collapsed)',
COLLAPSEEXPAND: '.collapseexpand',
@@ -81,6 +83,58 @@ NS.setup_keyboard_listeners = function() {
Y.one(Y.config.doc).delegate('key', this.collapse_expand_all, 'enter', SELECTORS.COLLAPSEEXPAND, this);
};
/**
* Expand all categories.
*
* @method expand_category
* @private
* @param {Node} categorynode The node to expand
*/
NS.expand_category = function(categorynode) {
// Load the actual dependencies now that we've been called.
Y.use('io-base', 'json-parse', 'moodle-core-notification', 'anim-node-plugin', function() {
// Overload the expand_category with the _expand_category function to ensure that
// this function isn't called in the future, and call it for the first time.
NS.expand_category = NS._expand_category;
NS.expand_category(categorynode);
});
};
NS._expand_category = function(categorynode) {
var categoryid,
depth;
if (!categorynode.hasClass(CSS.HASCHILDREN)) {
// Nothing to do here - this category has no children.
return;
}
if (categorynode.hasClass(CSS.LOADED)) {
// We've already loaded this content so we just need to toggle the view of it.
this.run_expansion(categorynode);
return;
}
// We use Data attributes to store the category.
categoryid = categorynode.getData('categoryid');
depth = categorynode.getData('depth');
if (typeof categoryid === "undefined" || typeof depth === "undefined") {
return;
}
this._toggle_generic_expansion({
parentnode: categorynode,
childnode: categorynode.one(SELECTORS.CONTENTNODE),
spinnerhandle: SELECTORS.CATEGORYSPINNERLOCATION,
data: {
categoryid: categoryid,
depth: depth,
showcourses: categorynode.getData('showcourses'),
type: TYPE_CATEGORY
}
});
};
/**
* Toggle the animation of the clicked category node.
*
@@ -309,12 +363,12 @@ NS._collapse_expand_all = function(e) {
NS.expand_all = function(ancestor) {
var finalexpansions = [];
ancestor.all(SELECTORS.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN)
ancestor.all(SELECTORS.CATEGORYWITHCOLLAPSEDCHILDREN)
.each(function(c) {
if (c.ancestor(SELECTORS.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN)) {
if (c.ancestor(SELECTORS.CATEGORYWITHCOLLAPSEDCHILDREN)) {
// Expand the hidden children first without animation.
c.removeClass(CSS.SECTIONCOLLAPSED);
c.all(SELECTORS.LOADEDTREES).removeClass(CSS.SECTIONCOLLAPSED);
c.all(SELECTORS.WITHCHILDRENTREES).removeClass(CSS.SECTIONCOLLAPSED);
} else {
finalexpansions.push(c);
}
@@ -322,7 +376,7 @@ NS.expand_all = function(ancestor) {
// Run the final expansion with animation on the visible items.
Y.all(finalexpansions).each(function(c) {
this.run_expansion(c);
this.expand_category(c);
}, this);
};
+58 -4
View File
@@ -23,10 +23,12 @@ var CSS = {
HASCHILDREN: 'with_children'
},
SELECTORS = {
WITHCHILDRENTREES: '.with_children',
LOADEDTREES: '.with_children.loaded',
CONTENTNODE: '.content',
CATEGORYLISTENLINK: '.category .info .categoryname',
CATEGORYSPINNERLOCATION: '.categoryname',
CATEGORYWITHCOLLAPSEDCHILDREN: '.category.with_children.collapsed',
CATEGORYWITHCOLLAPSEDLOADEDCHILDREN: '.category.with_children.loaded.collapsed',
CATEGORYWITHMAXIMISEDLOADEDCHILDREN: '.category.with_children.loaded:not(.collapsed)',
COLLAPSEEXPAND: '.collapseexpand',
@@ -80,6 +82,58 @@ NS.setup_keyboard_listeners = function() {
Y.one(Y.config.doc).delegate('key', this.collapse_expand_all, 'enter', SELECTORS.COLLAPSEEXPAND, this);
};
/**
* Expand all categories.
*
* @method expand_category
* @private
* @param {Node} categorynode The node to expand
*/
NS.expand_category = function(categorynode) {
// Load the actual dependencies now that we've been called.
Y.use('io-base', 'json-parse', 'moodle-core-notification', 'anim-node-plugin', function() {
// Overload the expand_category with the _expand_category function to ensure that
// this function isn't called in the future, and call it for the first time.
NS.expand_category = NS._expand_category;
NS.expand_category(categorynode);
});
};
NS._expand_category = function(categorynode) {
var categoryid,
depth;
if (!categorynode.hasClass(CSS.HASCHILDREN)) {
// Nothing to do here - this category has no children.
return;
}
if (categorynode.hasClass(CSS.LOADED)) {
// We've already loaded this content so we just need to toggle the view of it.
this.run_expansion(categorynode);
return;
}
// We use Data attributes to store the category.
categoryid = categorynode.getData('categoryid');
depth = categorynode.getData('depth');
if (typeof categoryid === "undefined" || typeof depth === "undefined") {
return;
}
this._toggle_generic_expansion({
parentnode: categorynode,
childnode: categorynode.one(SELECTORS.CONTENTNODE),
spinnerhandle: SELECTORS.CATEGORYSPINNERLOCATION,
data: {
categoryid: categoryid,
depth: depth,
showcourses: categorynode.getData('showcourses'),
type: TYPE_CATEGORY
}
});
};
/**
* Toggle the animation of the clicked category node.
*
@@ -308,12 +362,12 @@ NS._collapse_expand_all = function(e) {
NS.expand_all = function(ancestor) {
var finalexpansions = [];
ancestor.all(SELECTORS.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN)
ancestor.all(SELECTORS.CATEGORYWITHCOLLAPSEDCHILDREN)
.each(function(c) {
if (c.ancestor(SELECTORS.CATEGORYWITHCOLLAPSEDLOADEDCHILDREN)) {
if (c.ancestor(SELECTORS.CATEGORYWITHCOLLAPSEDCHILDREN)) {
// Expand the hidden children first without animation.
c.removeClass(CSS.SECTIONCOLLAPSED);
c.all(SELECTORS.LOADEDTREES).removeClass(CSS.SECTIONCOLLAPSED);
c.all(SELECTORS.WITHCHILDRENTREES).removeClass(CSS.SECTIONCOLLAPSED);
} else {
finalexpansions.push(c);
}
@@ -321,7 +375,7 @@ NS.expand_all = function(ancestor) {
// Run the final expansion with animation on the visible items.
Y.all(finalexpansions).each(function(c) {
this.run_expansion(c);
this.expand_category(c);
}, this);
};
+8
View File
@@ -8,6 +8,14 @@
text-align: center;
}
.mediaplugin,
.mediaplugin video {
/* Make videos as wide as possible without being wider than their containers */
width: 100vw;
max-width: 100%;
height: auto;
}
.mediaplugin > div {
margin: auto;
}
+1 -1
View File
@@ -83,7 +83,7 @@ class autogroup_form extends moodleform {
}
$coursecontext = context_course::instance($COURSE->id);
if ($cohorts = cohort_get_available_cohorts($coursecontext, COHORT_WITH_ENROLLED_MEMBERS_ONLY)) {
if ($cohorts = cohort_get_available_cohorts($coursecontext, COHORT_WITH_ENROLLED_MEMBERS_ONLY, 0, 0)) {
$options = array(0 => get_string('anycohort', 'cohort'));
foreach ($cohorts as $c) {
$options[$c->id] = format_string($c->name, true, context::instance_by_id($c->contextid));
+3 -4
View File
@@ -170,15 +170,14 @@ $string['configcronremotepassword'] = 'This means that the cron.php script canno
http://site.example.com/admin/cron.php?password=opensesame
</pre>If this is left empty, no password is required.';
$string['configcurlcache'] = 'Time-to-live for cURL cache, in seconds.';
$string['configcustommenuitems'] = 'You can configure a custom menu here to be shown by themes. Each line consists of some menu text, a link URL (optional), a tooltip title (optional) and a language code or comma-separated list of codes (optional, for displaying the line to users of the specified language only), separated by pipe characters. You can specify a structure using hyphens, and dividers can be used by adding a line of one or more # characters where desired. For example:
$string['configcustommenuitems'] = 'You can configure a custom menu here to be shown by themes. Each line consists of some menu text, a link URL (optional), a tooltip title (optional) and a language code or comma-separated list of codes (optional, for displaying the line to users of the specified language only), separated by pipe characters. Lines starting with a hyphen will appear as menu items in the previous top level menu, and dividers can be used by adding a line of one or more # characters where desired. For example:
<pre>
Moodle community|https://moodle.org
-Moodle free support|https://moodle.org/support
-Moodle Docs|http://docs.moodle.org|Moodle Docs
-German Moodle Docs|http://docs.moodle.org/de|Documentation in German|de
-###
-Moodle development|https://moodle.org/development
--Moodle Docs|http://docs.moodle.org|Moodle Docs
--German Moodle Docs|http://docs.moodle.org/de|Documentation in German|de
#####
Moodle.com|http://moodle.com/
</pre>';
$string['configcustomusermenuitems'] = 'You can configure the contents of the user menu (with the exception of the log out link, which is automatically added). Each line is separated by | characters and consists of 1) a string in "langstringname, componentname" form or as plain text, 2) a URL, and 3) an icon either as a pix icon or as a URL. Dividers can be used by adding a line of one or more # characters where desired.';
+1 -1
View File
@@ -1 +1 @@
define(["jquery","core/yui"],function(a,b){return{Events:{FORM_FIELD_VALIDATION:"core_form-field-validation"},notifyFilterContentUpdated:function(c){c=a(c),b.use("event","moodle-core-event",function(b){a(document).trigger(M.core.event.FILTER_CONTENT_UPDATED,c);var d=new b.NodeList(c.get());b.fire(M.core.event.FILTER_CONTENT_UPDATED,{nodes:d})})},notifyEditorContentRestored:function(){b.use("event","moodle-core-event",function(b){a(document).trigger(M.core.event.EDITOR_CONTENT_RESTORED),b.fire(M.core.event.EDITOR_CONTENT_RESTORED)})}}});
define(["jquery","core/yui"],function(a,b){return{Events:{FORM_FIELD_VALIDATION:"core_form-field-validation"},getLegacyEvents:function(){var c=a.Deferred();return b.use("event","moodle-core-event",function(){c.resolve(window.M.core.event)}),c.promise()},notifyFilterContentUpdated:function(c){c=a(c),b.use("event","moodle-core-event",function(b){a(document).trigger(M.core.event.FILTER_CONTENT_UPDATED,[c]);var d=new b.NodeList(c.get());b.fire(M.core.event.FILTER_CONTENT_UPDATED,{nodes:d})})},notifyEditorContentRestored:function(){b.use("event","moodle-core-event",function(b){a(document).trigger(M.core.event.EDITOR_CONTENT_RESTORED),b.fire(M.core.event.EDITOR_CONTENT_RESTORED)})}}});
+15 -1
View File
@@ -35,6 +35,20 @@ define(['jquery', 'core/yui'],
FORM_FIELD_VALIDATION: "core_form-field-validation"
},
/**
* Load the legacy YUI module which defines events in M.core.event and return it.
*
* @method getLegacyEvents
* @return {Promise}
*/
getLegacyEvents: function() {
var result = $.Deferred();
Y.use('event', 'moodle-core-event', function() {
result.resolve(window.M.core.event);
});
return result.promise();
},
/**
* Trigger an event using both JQuery and YUI
*
@@ -45,7 +59,7 @@ define(['jquery', 'core/yui'],
nodes = $(nodes);
Y.use('event', 'moodle-core-event', function(Y) {
// Trigger it the JQuery way.
$(document).trigger(M.core.event.FILTER_CONTENT_UPDATED, nodes);
$(document).trigger(M.core.event.FILTER_CONTENT_UPDATED, [nodes]);
// Create a YUI NodeList from our JQuery Object.
var yuiNodes = new Y.NodeList(nodes.get());
+3
View File
@@ -117,6 +117,9 @@ class behat_util extends testing_util {
// Enable web cron.
set_config('cronclionly', 0);
// Set editor autosave to high value, so as to avoid unwanted ajax.
set_config('autosavefrequency', '604800', 'editor_atto');
// Keeps the current version of database and dataroot.
self::store_versions_hash();
@@ -60,5 +60,10 @@ JS;
}
$this->field->setValue($value);
// Ensure all pending JS is finished.
if ($this->running_javascript()) {
$this->session->wait(behat_base::TIMEOUT * 1000, behat_base::PAGE_READY_JS);
}
}
}
+15
View File
@@ -134,6 +134,13 @@ function behat_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
return true;
}
// No need to report the before_scenario warning generated to clear last error.
// As error_clear_last is only available in php 7.0+, we trigger E_USER_WARNING
// to clear any last error which was generated during reset in before_scenario.
if (($errno === E_USER_WARNING) && $errstr == 'before_scenario') {
return;
}
// This error handler receives E_ALL | E_STRICT, running the behat test site the debug level is
// set to DEVELOPER and will always include E_NOTICE,E_USER_NOTICE... as part of E_ALL, if the current
// error_reporting() value does not include one of those levels is because it has been forced through
@@ -175,6 +182,14 @@ function behat_shutdown_function() {
if ($error = error_get_last()) {
// Ignore E_WARNING, as they might come via ( @ )suppression and might lead to false failure.
if (isset($error['type']) && !($error['type'] & E_WARNING)) {
// No need to report the before_scenario warning generated to clear last error.
// As error_clear_last is only available in php 7.0+, we trigger E_USER_WARNING
// to clear any last error which was generated during reset in before_scenario.
if (($error['type'] & E_USER_WARNING) && $error['message'] == 'before_scenario') {
return;
}
$errors = behat_get_shutdown_process_errors();
$errors[] = $error;
+5 -1
View File
@@ -5616,7 +5616,11 @@ function message_is_user_blocked($recipient, $sender = null) {
debugging('message_is_user_blocked() is deprecated and is no longer used, please use
\core_message\api::is_user_blocked() instead.', DEBUG_DEVELOPER);
return \core_message\api::is_user_blocked($recipient, $sender);
$senderid = null;
if ($sender !== null && isset($sender->id)) {
$senderid = $sender->id;
}
return \core_message\api::is_user_blocked($recipient->id, $senderid);
}
/**
-4
View File
@@ -1246,11 +1246,7 @@ class global_navigation extends navigation_node {
} else {
$this->rootnodes['courses']->isexpandable = true;
}
// Load the users enrolled courses if they are viewing the My Moodle page AND the admin has not
// set that they wish to keep the My Courses branch collapsed by default.
$this->rootnodes['mycourses']->forceopen = true;
$this->load_courses_enrolled();
$canviewcourseprofile = true;
+1 -1
View File
@@ -7,7 +7,7 @@ var require = {
paths: {
jquery: '[JSURL]lib/jquery/jquery-3.1.0.min[JSEXT]',
jqueryui: '[JSURL]lib/jquery/ui-1.11.4/jquery-ui.min[JSEXT]',
jqueryui: '[JSURL]lib/jquery/ui-1.12.1/jquery-ui.min[JSEXT]',
jqueryprivate: '[JSURL]lib/requirejs/jquery-private[JSEXT]'
},
+53
View File
@@ -103,6 +103,13 @@ class behat_hooks extends behat_base {
*/
protected static $runningsuite = '';
/**
* Keeps track of php error generated during reset.
*
* @var int keep track of how many php errors were generated.
*/
public static $phperrorduringresetcounter = 0;
/**
* Hook to capture BeforeSuite event so as to give access to moodle codebase.
* This will try and catch any exception and exists if anything fails.
@@ -339,7 +346,30 @@ class behat_hooks extends behat_base {
// Reset $SESSION.
\core\session\manager::init_empty_session();
// Set custom handler to try reset all data, if failed because of previous ajax.
set_error_handler(
function($errno, $errstr, $errfile, $errline) {
behat_hooks::$phperrorduringresetcounter++;
if (behat_hooks::$phperrorduringresetcounter < self::TIMEOUT) {
sleep(1);
behat_util::reset_all_data();
}
return true;
}, -1 & ~E_NOTICE & ~E_WARNING);
behat_util::reset_all_data();
restore_error_handler();
// Trigger an error which will be ignored by behat_shutdown_function, this is hacky way to clear last error in php < 7.0.
if (self::$phperrorduringresetcounter > 0) {
if (function_exists('error_clear_last')) {
error_clear_last();
} else {
trigger_error('before_scenario', E_USER_WARNING);
}
}
// Reset the counter here, as this won't be required.
self::$phperrorduringresetcounter = 0;
// Assign valid data to admin user (some generator-related code needs a valid user).
$user = $DB->get_record('user', array('username' => 'admin'));
@@ -381,6 +411,29 @@ class behat_hooks extends behat_base {
$this->resize_window('medium');
}
/**
* Executed after scenario to go to a page where no JS is executed.
* This will ensure there are no unwanted ajax calls from browser and
* site can be reset safely.
*
* @param AfterScenarioScope $scope scope passed by event fired after scenario.
* @AfterScenario
*/
public function after_scenario(AfterScenarioScope $scope) {
try {
$this->wait_for_pending_js();
$this->getSession()->visit($this->locate_path('/README.txt'));
$this->getSession()->reset();
} catch (DriverException $e) {
// Try restart session, if DriverException caught.
try {
$this->getSession()->restart();
} catch (DriverException $e) {
// Do nothing, as this will be caught while starting session in before_scenario.
}
}
}
/**
* Wait for JS to complete before beginning interacting with the DOM.
*
+56 -58
View File
@@ -348,58 +348,54 @@ class api {
* @return \stdClass
*/
public static function get_profile($userid, $otheruserid) {
global $CFG, $DB;
global $CFG, $DB, $PAGE;
require_once($CFG->dirroot . '/user/lib.php');
if ($user = \core_user::get_user($otheruserid)) {
// Create the data we are going to pass to the renderable.
$userfields = user_get_user_details($user, null, array('city', 'country', 'email',
'profileimageurl', 'profileimageurlsmall', 'lastaccess'));
if ($userfields) {
$data = new \stdClass();
$data->userid = $userfields['id'];
$data->fullname = $userfields['fullname'];
$data->city = isset($userfields['city']) ? $userfields['city'] : '';
$data->country = isset($userfields['country']) ? $userfields['country'] : '';
$data->email = isset($userfields['email']) ? $userfields['email'] : '';
$data->profileimageurl = isset($userfields['profileimageurl']) ? $userfields['profileimageurl'] : '';
if (isset($userfields['profileimageurlsmall'])) {
$data->profileimageurlsmall = $userfields['profileimageurlsmall'];
} else {
$data->profileimageurlsmall = '';
}
if (isset($userfields['lastaccess'])) {
$data->isonline = helper::is_online($userfields['lastaccess']);
} else {
$data->isonline = false;
}
} else {
// Technically the access checks in user_get_user_details are correct,
// but messaging has never obeyed them. In order to keep messaging working
// we at least need to return a minimal user record.
$data = new \stdClass();
$data->userid = $otheruserid;
$data->fullname = fullname($user);
$data->city = '';
$data->country = '';
$data->email = '';
$data->profileimageurl = '';
$data->profileimageurlsmall = '';
$data->isonline = false;
}
// Check if the contact has been blocked.
$contact = $DB->get_record('message_contacts', array('userid' => $userid, 'contactid' => $otheruserid));
if ($contact) {
$data->isblocked = (bool) $contact->blocked;
$data->iscontact = true;
} else {
$data->isblocked = false;
$data->iscontact = false;
}
$user = \core_user::get_user($otheruserid, '*', MUST_EXIST);
return $data;
// Create the data we are going to pass to the renderable.
$data = new \stdClass();
$data->userid = $otheruserid;
$data->fullname = fullname($user);
$data->city = '';
$data->country = '';
$data->email = '';
$data->isonline = false;
// Get the user picture data - messaging has always shown these to the user.
$userpicture = new \user_picture($user);
$userpicture->size = 1; // Size f1.
$data->profileimageurl = $userpicture->get_url($PAGE)->out(false);
$userpicture->size = 0; // Size f2.
$data->profileimageurlsmall = $userpicture->get_url($PAGE)->out(false);
$userfields = user_get_user_details($user, null, array('city', 'country', 'email', 'lastaccess'));
if ($userfields) {
if (isset($userfields['city'])) {
$data->city = $userfields['city'];
}
if (isset($userfields['country'])) {
$data->country = $userfields['country'];
}
if (isset($userfields['email'])) {
$data->email = $userfields['email'];
}
if (isset($userfields['lastaccess'])) {
$data->isonline = helper::is_online($userfields['lastaccess']);
}
}
// Check if the contact has been blocked.
$contact = $DB->get_record('message_contacts', array('userid' => $userid, 'contactid' => $otheruserid));
if ($contact) {
$data->isblocked = (bool) $contact->blocked;
$data->iscontact = true;
} else {
$data->isblocked = false;
$data->iscontact = false;
}
return $data;
}
/**
@@ -620,8 +616,12 @@ class api {
return false;
}
$senderid = null;
if ($sender !== null && isset($sender->id)) {
$senderid = $sender->id;
}
// The recipient has specifically blocked this sender.
if (self::is_user_blocked($recipient, $sender)) {
if (self::is_user_blocked($recipient->id, $senderid)) {
return false;
}
@@ -667,27 +667,25 @@ class api {
* Note: This function will always return false if the sender has the
* readallmessages capability at the system context level.
*
* @param object $recipient User object.
* @param object $sender User object.
* @param int $recipientid User ID of the recipient.
* @param int $senderid User ID of the sender.
* @return bool true if $sender is blocked, false otherwise.
*/
public static function is_user_blocked($recipient, $sender = null) {
public static function is_user_blocked($recipientid, $senderid = null) {
global $USER, $DB;
if (is_null($sender)) {
if (is_null($senderid)) {
// The message is from the logged in user, unless otherwise specified.
$sender = $USER;
$senderid = $USER->id;
}
$systemcontext = \context_system::instance();
if (has_capability('moodle/site:readallmessages', $systemcontext, $sender)) {
if (has_capability('moodle/site:readallmessages', $systemcontext, $senderid)) {
return false;
}
if ($contact = $DB->get_record('message_contacts', array('userid' => $recipient->id, 'contactid' => $sender->id))) {
if ($contact->blocked) {
return true;
}
if ($DB->get_field('message_contacts', 'blocked', ['userid' => $recipientid, 'contactid' => $senderid])) {
return true;
}
return false;
@@ -26,6 +26,7 @@ namespace core_message\output\messagearea;
defined('MOODLE_INTERNAL') || die();
use core_message\api;
use renderable;
use templatable;
@@ -95,6 +96,8 @@ class messages implements templatable, renderable {
$data->messages[] = $message->export_for_template($output);
}
$data->isblocked = api::is_user_blocked($this->currentuserid, $this->otheruserid);
return $data;
}
}
+2 -1
View File
@@ -996,7 +996,8 @@ class core_message_external extends external_api {
'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
'messages' => new external_multiple_structure(
self::get_messagearea_message_structure()
)
),
'isblocked' => new external_value(PARAM_BOOL, 'Is this user blocked by the current user?', VALUE_DEFAULT, false),
)
);
}
@@ -14,6 +14,37 @@
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_message/message_area_messages_area
Messages area template.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* isonline - boolean
* isblocked - boolean
* otheruserid - int
* otheruserfullname - string
* messages - array of messages
Example context (json):
{
"isonline": true,
"isblocked": true,
"otheruserid": 1,
"otheruserfullname": "Sam Student",
"messages": [
{
"text": "Hello there!"
}
]
}
}}
{{#otheruserid}}
<div class="messages-header">
<div class="view-toggle btn-container">
@@ -25,6 +56,11 @@
<div class="name-container">
<div class="name">
<button class="btn btn-link" data-action="view-contact-profile" data-userid="{{otheruserid}}">{{otheruserfullname}}</button>
{{#isblocked}}
<span data-region="contact-icon-blocked">
{{#pix}} t/block, core, {{#str}} contactblocked, message {{/str}} {{/pix}}
</span>
{{/isblocked}}
</div>
<div class="status {{#isonline}}online{{/isonline}}">
<span class="offline-text">{{#str}} offline, message {{/str}}</span>
+7 -3
View File
@@ -839,13 +839,17 @@ class core_message_api_testcase extends core_message_messagelib_testcase {
$this->setUser($user1);
// User shouldn't be blocked.
$this->assertFalse(\core_message\api::is_user_blocked($user1, $user2));
$this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
// Block the user.
message_block_contact($user2->id);
// User should be blocked.
$this->assertTrue(\core_message\api::is_user_blocked($user1, $user2));
$this->assertTrue(\core_message\api::is_user_blocked($user1->id, $user2->id));
// Unblock the user.
message_unblock_contact($user2->id);
$this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
}
/**
@@ -865,7 +869,7 @@ class core_message_api_testcase extends core_message_messagelib_testcase {
$this->setAdminUser();
// As the admin you should still be able to send messages to the user.
$this->assertFalse(\core_message\api::is_user_blocked($user1));
$this->assertFalse(\core_message\api::is_user_blocked($user1->id));
}
/*
+1 -1
View File
@@ -4872,7 +4872,7 @@ class assign {
if ($this->can_view_submission($user->id)) {
if (has_capability('mod/assign:submit', $this->get_context(), $user)) {
if (has_capability('mod/assign:submit', $this->get_context(), $user, false)) {
$submissionstatus = $this->get_assign_submission_status_renderable($user, $showlinks);
$o .= $this->get_renderer()->render($submissionstatus);
}
-8
View File
@@ -927,14 +927,6 @@
display: table-row;
}
.path-mod-assign #page-content [data-region="grade-panel"] .mform:not(.unresponsive) #id_attemptsettings .fitem .fitemtitle,
.path-mod-assign #page-content [data-region="grade-panel"] .mform:not(.unresponsive) #id_attemptsettings .fitem .felement {
display: table-cell;
float: none;
border-top: 1px solid #ddd;
padding: 8px 0;
}
.path-mod-assign #page-content [data-region="grade-panel"] .mform:not(.unresponsive) #id_attemptsettings .fitem:last-of-type .fitemtitle,
.path-mod-assign #page-content [data-region="grade-panel"] .mform:not(.unresponsive) #id_attemptsettings .fitem:last-of-type .felement {
border-bottom: 1px solid #ddd;
@@ -146,13 +146,17 @@ class behat_mod_feedback extends behat_base {
// If chart data is not visible then expand.
$node = $this->get_selected_node("xpath_element", $charttabledataxpath);
if ($node && !$node->isVisible()) {
$this->execute('behat_general::i_click_on_in_the', array(
get_string('showchartdata'),
'link',
$feedbackxpath,
'xpath_element'
));
if ($node) {
if (!$node->isVisible()) {
// Focus on node, before checking if it's visible.
$node->focus();
$this->execute('behat_general::i_click_on_in_the', array(
get_string('showchartdata'),
'link',
$feedbackxpath,
'xpath_element'
));
}
}
}
+4 -4
View File
@@ -124,8 +124,8 @@ class mod_forum_observer {
global $CFG;
$course = $event->get_record_snapshot('course', $event->objectid);
if (!empty($course->newsitems)) {
$format = course_get_format($course);
if ($format->supports_news() && !empty($course->newsitems)) {
require_once($CFG->dirroot . '/mod/forum/lib.php');
// Auto create the announcements forum.
forum_get_course_forum($event->objectid, 'news');
@@ -142,8 +142,8 @@ class mod_forum_observer {
global $CFG;
$course = $event->get_record_snapshot('course', $event->objectid);
if (!empty($course->newsitems)) {
$format = course_get_format($course);
if ($format->supports_news() && !empty($course->newsitems)) {
require_once($CFG->dirroot . '/mod/forum/lib.php');
// Auto create the announcements forum.
forum_get_course_forum($event->objectid, 'news');
@@ -134,6 +134,7 @@ Feature: Lesson user override
And I set the following fields to these values:
| Password protected lesson | Yes |
| id_password | moodle_rules |
And I wait until the page is ready
And I press "Save and display"
And I navigate to "User overrides" node in "Lesson administration"
And I press "Add user override"
+1 -1
View File
@@ -1961,7 +1961,7 @@ function quiz_check_updates_since(cm_info $cm, $from, $filter = array()) {
$select = 'id ' . $questionsql . ' AND (timemodified > :time1 OR timecreated > :time2)';
$params['time1'] = $from;
$params['time2'] = $from;
$questions = $DB->count_records_select('question', $select, $params) > 0;
$questions = $DB->get_records_select('question', $select, $params, '', 'id');
if (!empty($questions)) {
$updates->questions->updated = true;
$updates->questions->itemids = array_keys($questions);
@@ -45,6 +45,7 @@ Feature: Scorm multi-sco completion
And I should see "Play of the game"
And I switch to the main frame
And I follow "Exit activity"
And I wait until the page is ready
Then I should see "Basic Multi-sco SCORM package"
And I log out
And I log in as "teacher1"
@@ -80,6 +81,7 @@ Feature: Scorm multi-sco completion
And I should see "Play of the game"
And I switch to the main frame
And I follow "Exit activity"
And I wait until the page is ready
Then I should see "ADV Multi-sco SCORM package"
And I log out
And I log in as "teacher1"
+3 -2
View File
@@ -24,9 +24,10 @@ function wiki_print_editor_html($pageid, $content, $version = -1, $section = nul
$action .= "&section=".urlencode($section);
}
echo $OUTPUT->container_start('mdl-align');
echo $OUTPUT->container_start('container');
echo '<form method="post" action="'.$action.'">';
echo $OUTPUT->container(print_textarea(true, 20, 100, 0, 0, "newcontent", $content, 0, true, '', 'form-textarea-advanced'), 'wiki_editor');
$textarea = print_textarea(true, 20, 100, 0, 0, "newcontent", $content, 0, true, '', 'form-textarea-advanced');
echo $OUTPUT->container($textarea, 'wiki_editor');
wiki_print_edit_form_default_fields('html', $pageid, $version, $upload, $deleteuploads);
echo '</form>';
echo $OUTPUT->container_end();
+2 -2
View File
@@ -64,7 +64,7 @@ function wiki_print_editor_wiki($pageid, $content, $editor, $version = -1, $sect
$PAGE->requires->js('/mod/wiki/editors/wiki/buttons.js');
echo $OUTPUT->container_start('mdl-align');
echo $OUTPUT->container_start();
foreach ($wiki_editor as $button) {
echo "<a href=\"javascript:insertTags";
echo "('" . $button[2] . "','" . $button[3] . "','" . $button[4] . "');\">";
@@ -73,7 +73,7 @@ function wiki_print_editor_wiki($pageid, $content, $editor, $version = -1, $sect
}
echo $OUTPUT->container_end();
echo $OUTPUT->container_start('mdl-align');
echo $OUTPUT->container_start();
echo '<form method="post" id="mform1" action="' . $action . '">';
echo $OUTPUT->container(print_textarea(false, 20, 60, 0, 0, "newcontent", $content, 0, true), false, 'wiki_editor');
echo $OUTPUT->container_start();
+10 -3
View File
@@ -53,8 +53,6 @@ class MoodleQuickForm_wikieditor extends MoodleQuickForm_textarea {
$this->files = $attributes['files'];
unset($attributes['files']);
}
parent::__construct($elementName, $elementLabel, $attributes);
$this->_type = 'wikieditor';
}
@@ -144,7 +142,8 @@ class MoodleQuickForm_wikieditor extends MoodleQuickForm_textarea {
$html .= "</a>";
}
$html .= "<label class='accesshide' for='addtags'>" . get_string('insertimage', 'wiki') . "</label>";
$html .= "<select id='addtags' onchange=\"insertTags('{$imagetag[0]}', '{$imagetag[1]}', this.value)\">";
$html .= "<select id='addtags' class='custom-select m-x-1' " .
"onchange=\"insertTags('{$imagetag[0]}', '{$imagetag[1]}', this.value)\">";
$html .= "<option value='" . s(get_string('wikiimage', 'wiki')) . "'>" . get_string('insertimage', 'wiki') . '</option>';
foreach ($this->files as $filename) {
$html .= "<option value='".s($filename)."'>";
@@ -178,7 +177,15 @@ class MoodleQuickForm_wikieditor extends MoodleQuickForm_textarea {
public function export_for_template(renderer_base $output) {
$context = $this->export_for_template_base($output);
// We do want the form-control class on the output from toHTML - but we dont' want it when calling export_for_template.
// This is because in this type of form element the export_for_template calls toHTML to get the html for the context.
// If we did both we would be duplicating the form-control which messes up the styles.
$saved = $this->getAttribute('class');
$this->updateAttributes(['class' => $saved . ' form-control']);
$context['html'] = $this->toHtml();
$this->updateAttributes(['class' => $saved]);
return $context;
}
+2 -2
View File
@@ -1438,14 +1438,14 @@ function wiki_print_edit_form_default_fields($format, $pageid, $version = -1, $u
echo "<fieldset class=\"wiki-upload-section clearfix\"><legend class=\"ftoggler\">" . get_string("uploadtitle", 'wiki') . "</legend>";
echo $OUTPUT->container_start('mdl-align wiki-form-center aaaaa');
echo $OUTPUT->container_start('container');
print $filemanager->toHtml();
echo $OUTPUT->container_end();
$cm = $PAGE->cm;
$context = context_module::instance($cm->id);
echo $OUTPUT->container_start('mdl-align wiki-form-center wiki-upload-table');
echo $OUTPUT->container_start('container wiki-upload-table');
wiki_print_upload_table($context, 'wiki_upload', $pageid, $deleteuploads);
echo $OUTPUT->container_end();
+24 -29
View File
@@ -1282,7 +1282,6 @@ class page_wiki_history extends page_wiki {
$table = new html_table();
$table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
$table->data = $contents;
$table->attributes['class'] = 'mdl-align';
echo html_writer::table($table);
@@ -1314,15 +1313,15 @@ class page_wiki_history extends page_wiki {
$table->head = array(get_string('diff', 'wiki') . $icon, get_string('version'), get_string('user'), get_string('modified'), '');
$table->data = $contents;
$table->attributes['class'] = 'generaltable mdl-align';
$table->attributes['class'] = 'table generaltable';
$table->rowclasses = $rowclass;
// Print the form.
echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/diff.php'), 'method'=>'get', 'id'=>'diff'));
echo html_writer::tag('div', html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'pageid', 'value'=>$pageid)));
echo html_writer::table($table);
echo html_writer::start_tag('div', array('class'=>'mdl-align'));
echo html_writer::empty_tag('input', array('type'=>'submit', 'class'=>'wiki_form-button', 'value'=>get_string('comparesel', 'wiki')));
echo html_writer::start_tag('div');
echo html_writer::empty_tag('input', array('type'=>'submit', 'class'=>'wiki_form-button btn btn-secondary', 'value'=>get_string('comparesel', 'wiki')));
echo html_writer::end_tag('div');
echo html_writer::end_tag('form');
}
@@ -1336,11 +1335,11 @@ class page_wiki_history extends page_wiki {
//print_paging_bar($vcount, $paging, $rowsperpage,$CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;','paging');
} else {
$link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid));
$OUTPUT->container(html_writer::link($link->out(false), get_string('viewperpage', 'wiki', $this->rowsperpage)), 'mdl-align');
$OUTPUT->container(html_writer::link($link->out(false), get_string('viewperpage', 'wiki', $this->rowsperpage)));
}
if ($vcount > $this->rowsperpage && !$this->allversion) {
$link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid, 'allversion' => 1));
$OUTPUT->container(html_writer::link($link->out(false), get_string('viewallhistory', 'wiki')), 'mdl-align');
$OUTPUT->container(html_writer::link($link->out(false), get_string('viewallhistory', 'wiki')));
}
}
@@ -1484,7 +1483,7 @@ class page_wiki_map extends page_wiki {
$table = new html_table();
$table->head = array(get_string('contributions', 'wiki') . $OUTPUT->help_icon('contributions', 'wiki'));
$table->attributes['class'] = 'wiki_editor generalbox';
$table->attributes['class'] = 'generalbox table';
$table->data = array();
$table->rowclasses = array();
@@ -1548,7 +1547,7 @@ class page_wiki_map extends page_wiki {
$fromlinks = wiki_get_linked_from_pages($page->id);
$table = new html_table();
$table->attributes['class'] = 'wiki_navigation_from';
$table->attributes['class'] = 'wiki_navigation_from table';
$table->head = array(get_string('navigationfrom', 'wiki') . $OUTPUT->help_icon('navigationfrom', 'wiki') . ':');
$table->data = array();
$table->rowclasses = array();
@@ -1556,13 +1555,12 @@ class page_wiki_map extends page_wiki {
$lpage = wiki_get_page($link->frompageid);
$link = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
$table->data[] = array(html_writer::link($link->out(false), format_string($lpage->title)));
$table->rowclasses[] = 'mdl-align';
}
$table_left = html_writer::table($table);
$table_left = $OUTPUT->container(html_writer::table($table), 'col-md-6 span6');
$table = new html_table();
$table->attributes['class'] = 'wiki_navigation_to';
$table->attributes['class'] = 'wiki_navigation_to table';
$table->head = array(get_string('navigationto', 'wiki') . $OUTPUT->help_icon('navigationto', 'wiki') . ':');
$table->data = array();
$table->rowclasses = array();
@@ -1575,10 +1573,9 @@ class page_wiki_map extends page_wiki {
$viewlink = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
$table->data[] = array(html_writer::link($viewlink->out(false), format_string($lpage->title)));
}
$table->rowclasses[] = 'mdl-align';
}
$table_right = html_writer::table($table);
echo $OUTPUT->container($table_left . $table_right, 'wiki_navigation_container');
$table_right = $OUTPUT->container(html_writer::table($table), 'col-md-6 span6');
echo $OUTPUT->container($table_left . $table_right, 'wiki_navigation_container row');
}
/**
@@ -1604,7 +1601,7 @@ class page_wiki_map extends page_wiki {
$table = new html_table();
$table->head = array(get_string('pageindex', 'wiki') . $OUTPUT->help_icon('pageindex', 'wiki'));
$table->attributes['class'] = 'wiki_editor generalbox';
$table->attributes['class'] = 'generalbox table';
$table->data[] = array($this->render_navigation_node($tree));
echo html_writer::table($table);
@@ -1643,8 +1640,7 @@ class page_wiki_map extends page_wiki {
$table = new html_table();
$table->head = array(get_string('pagelist', 'wiki') . $OUTPUT->help_icon('pagelist', 'wiki'));
$table->attributes['class'] = 'wiki_editor generalbox';
$table->align = array('center');
$table->attributes['class'] = 'generalbox table';
foreach ($stdaux as $key => $elem) {
$table->data[] = array($key);
foreach ($elem as $e) {
@@ -1673,7 +1669,7 @@ class page_wiki_map extends page_wiki {
$table = new html_table();
$table->head = array(get_string('orphaned', 'wiki') . $OUTPUT->help_icon('orphaned', 'wiki'));
$table->attributes['class'] = 'wiki_editor generalbox';
$table->attributes['class'] = 'generalbox table';
$table->data = array();
$table->rowclasses = array();
@@ -1709,7 +1705,7 @@ class page_wiki_map extends page_wiki {
$table = new html_table();
$table->head = array(get_string('updatedpages', 'wiki') . $OUTPUT->help_icon('updatedpages', 'wiki'));
$table->attributes['class'] = 'wiki_editor generalbox';
$table->attributes['class'] = 'generalbox table';
$table->data = array();
$table->rowclasses = array();
@@ -1894,7 +1890,7 @@ class page_wiki_restoreversion extends page_wiki {
$restoreurl = new moodle_url('/mod/wiki/restoreversion.php', $optionsyes);
$return = new moodle_url('/mod/wiki/viewversion.php', array('pageid'=>$this->page->id, 'versionid'=>$version->id));
echo $OUTPUT->container_start('wiki-form-center');
echo $OUTPUT->container_start();
echo html_writer::tag('div', get_string('restoreconfirm', 'wiki', $version->version));
echo $OUTPUT->container_start(false, 'wiki_restoreform');
echo '<form class="wiki_restore_yes" action="' . $restoreurl . '" method="post" id="restoreversion">';
@@ -1964,7 +1960,7 @@ class page_wiki_deletecomment extends page_wiki {
$deleteurl = new moodle_url('/mod/wiki/instancecomments.php', $optionsyes);
$return = new moodle_url('/mod/wiki/comments.php', array('pageid'=>$this->page->id));
echo $OUTPUT->container_start('wiki-form-center');
echo $OUTPUT->container_start();
echo html_writer::tag('p', $strdeletecheckfull);
echo $OUTPUT->container_start(false, 'wiki_deletecommentform');
echo '<form class="wiki_deletecomment_yes" action="' . $deleteurl . '" method="post" id="deletecomment">';
@@ -2137,7 +2133,7 @@ class page_wiki_viewversion extends page_wiki {
$viewlink = new moodle_url('/user/view.php', array('id' => $userinfo->id));
$heading .= '&nbsp;&nbsp;&nbsp;<strong>' . get_string('user') . ':</strong>&nbsp;' . html_writer::link($viewlink->out(false), fullname($userinfo));
$heading .= '&nbsp;&nbsp;&rarr;&nbsp;' . $OUTPUT->user_picture(wiki_get_user_info($pageversion->userid), array('popup' => true)) . '</p>';
echo $OUTPUT->container($heading, 'wiki_headingtime', 'mdl-align wiki_modifieduser');
echo $OUTPUT->container($heading, 'wiki_headingtime', 'wiki_modifieduser');
$options = array('swid' => $this->subwiki->id, 'pretty_print' => true, 'pageid' => $this->page->id);
$pageversion->content = file_rewrite_pluginfile_urls($pageversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id);
@@ -2509,7 +2505,7 @@ class page_wiki_admin extends page_wiki {
$contents = array();
$table = new html_table();
$table->head = array('', get_string('pagename','wiki'));
$table->attributes['class'] = 'generaltable mdl-align';
$table->attributes['class'] = 'table generaltable';
$swid = $this->subwiki->id;
if ($showorphan) {
if ($orphanedpages = wiki_get_orphaned_pages($swid)) {
@@ -2536,7 +2532,7 @@ class page_wiki_admin extends page_wiki {
echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
echo html_writer::table($table);
echo html_writer::start_tag('div', array('class' => 'mdl-align'));
echo html_writer::start_tag('div');
if (!$showorphan) {
echo html_writer::empty_tag('input', array(
'type' => 'submit',
@@ -2547,7 +2543,7 @@ class page_wiki_admin extends page_wiki {
echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'listall', 'value'=>'1'));
echo html_writer::empty_tag('input', array(
'type' => 'submit',
'class' => 'wiki_form-button',
'class' => 'wiki_form-button btn btn-secondary',
'value' => get_string('listall', 'wiki'),
'sesskey' => sesskey()));
}
@@ -2629,7 +2625,6 @@ class page_wiki_admin extends page_wiki {
$table = new html_table();
$table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
$table->data = $contents;
$table->attributes['class'] = 'mdl-align';
echo html_writer::table($table);
} else {
@@ -2668,7 +2663,7 @@ class page_wiki_admin extends page_wiki {
$table = new html_table();
$table->head = array(get_string('deleteversions', 'wiki'), get_string('version'), get_string('user'), get_string('modified'), '');
$table->data = $contents;
$table->attributes['class'] = 'generaltable mdl-align';
$table->attributes['class'] = 'table generaltable';
$table->rowclasses = $rowclass;
///Print the form
@@ -2677,8 +2672,8 @@ class page_wiki_admin extends page_wiki {
echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
echo html_writer::table($table);
echo html_writer::start_tag('div', array('class' => 'mdl-align'));
echo html_writer::empty_tag('input', array('type' => 'submit', 'class' => 'wiki_form-button', 'value' => get_string('deleteversions', 'wiki')));
echo html_writer::start_tag('div');
echo html_writer::empty_tag('input', array('type' => 'submit', 'class' => 'wiki_form-button btn btn-secondary', 'value' => get_string('deleteversions', 'wiki')));
echo html_writer::end_tag('div');
echo html_writer::end_tag('form');
}
-19
View File
@@ -35,13 +35,6 @@
min-height: 100px;
}
.wiki_editor {
width: 50%;
margin: auto;
margin-top: 10px;
margin-bottom: 10px;
}
.wiki_previewbox {
width: 50%;
margin: auto;
@@ -92,12 +85,6 @@
margin-left: 0%;
}
.wiki-form-center {
text-align: center;
margin: auto;
width: 320px;
}
.wiki-upload-table {
margin: 8px auto;
clear: both;
@@ -364,12 +351,6 @@ a.wiki_edit_section {
text-align: right;
}
.wikieditor-toolbar img {
width: 22px;
height: 22px;
vertical-align: middle;
}
.path-mod-wiki .printicon {
background: url([[pix:t/print]]) no-repeat scroll 2px center transparent;
padding-left: 20px;
+14 -12
View File
@@ -60,18 +60,6 @@ class microsoft_skydrive extends oauth2_client {
$this->foldernamecache = cache::make('repository_skydrive', 'foldername');
}
/**
* Should HTTP GET be used instead of POST?
*
* The Microsoft API does not support POST, so we should use
* GET instead (with the auth_token passed as a GET param).
*
* @return bool true if GET should be used
*/
protected function use_http_get() {
return true;
}
/**
* Returns the auth url for OAuth 2.0 request
* @return string the auth url
@@ -88,6 +76,20 @@ class microsoft_skydrive extends oauth2_client {
return 'https://login.live.com/oauth20_token.srf';
}
/**
* Post request.
*
* Overridden to convert the data to a string, else curl will set the wrong headers.
*
* @param string $url The URL.
* @param array|string $params The parameters.
* @param array $options The options.
* @return bool
*/
public function post($url, $params = '', $options = array()) {
return parent::post($url, format_postdata_for_curlcall($params), $options);
}
/**
* Downloads a file to a file from skydrive using authenticated request
*
+1 -1
View File
@@ -72,7 +72,7 @@ class repository_webdav extends repository {
}
public function get_file($url, $title = '') {
$url = urldecode($url);
$path = $this->prepare_file($title);
$path = $this->prepare_file();
if (!$this->dav->open()) {
return false;
}
+1 -1
View File
@@ -1 +1 @@
define(["jquery","./tether"],function(a,b){return window.jQuery=a,window.Tether=b,require(["theme_boost/util","theme_boost/alert","theme_boost/button","theme_boost/carousel","theme_boost/collapse","theme_boost/dropdown","theme_boost/modal","theme_boost/scrollspy","theme_boost/tab","theme_boost/tooltip","theme_boost/popover"],function(){a("body").popover({selector:'[data-toggle="popover"]',trigger:"focus"})}),{}});
define(["jquery","./tether","core/event"],function(a,b,c){return window.jQuery=a,window.Tether=b,require(["theme_boost/util","theme_boost/alert","theme_boost/button","theme_boost/carousel","theme_boost/collapse","theme_boost/dropdown","theme_boost/modal","theme_boost/scrollspy","theme_boost/tab","theme_boost/tooltip","theme_boost/popover"],function(){a("body").popover({selector:'[data-toggle="popover"]',trigger:"focus"}),c.getLegacyEvents().done(function(b){a(document).on(b.FILTER_CONTENT_UPDATED,function(){a("body").popover({selector:'[data-toggle="popover"]',trigger:"focus"})})})}),{}});
+13 -1
View File
@@ -23,7 +23,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 2.9
*/
define(['jquery', './tether'], function(jQuery, Tether) {
define(['jquery', './tether', 'core/event'], function(jQuery, Tether, Event) {
window.jQuery = jQuery;
window.Tether = Tether;
@@ -40,11 +40,23 @@ define(['jquery', './tether'], function(jQuery, Tether) {
'theme_boost/tooltip',
'theme_boost/popover'],
function() {
jQuery('body').popover({
selector: '[data-toggle="popover"]',
trigger: 'focus'
});
// We need to call popover automatically if nodes are added to the page later.
Event.getLegacyEvents().done(function(events) {
jQuery(document).on(events.FILTER_CONTENT_UPDATED, function() {
jQuery('body').popover({
selector: '[data-toggle="popover"]',
trigger: 'focus'
});
});
});
});
return {};
});
@@ -694,4 +694,12 @@ class core_renderer extends \core_renderer {
return $skipped;
}
/**
* Secure login info.
*
* @return string
*/
public function secure_login_info() {
return $this->login_info(false);
}
}
+7 -1
View File
@@ -24,10 +24,16 @@
defined('MOODLE_INTERNAL') || die();
$blockshtml = $OUTPUT->blocks('side-pre');
$hasblocks = strpos($blockshtml, 'data-block=') !== false;
$bodyattributes = $OUTPUT->body_attributes();
$templatecontext = [
'sitename' => format_string($SITE->shortname, true, array('context' => context_course::instance(SITEID))),
'output' => $OUTPUT,
'sidepreblocks' => $OUTPUT->blocks('side-pre'),
'bodyattributes' => $bodyattributes,
'sidepreblocks' => $blockshtml,
'hasblocks' => $hasblocks
];
echo $OUTPUT->render_from_template('theme_boost/secure', $templatecontext);
+1
View File
@@ -792,6 +792,7 @@
#adminsettings .form-overridden {
@extend .form-control-feedback;
@extend .alert-info;
}
.modal.modal-in-page {
+3
View File
@@ -64,6 +64,9 @@
width: 98%;
height: 98%;
}
.file-picker .fp-def-search {
margin-top: 0;
}
// Repositories on fp-repo-area (File Picker only)
.file-picker .fp-list {
list-style-type: none;
+4
View File
@@ -50,6 +50,10 @@
border: 1px solid #e3e3e3;
clear: both;
img {
max-width: 100%;
}
.contacts-area {
border-right: 1px solid #e3e3e3;
height: 600px;
+59 -20
View File
@@ -355,7 +355,7 @@ div#dock {
float: left;
width: 20rem;
display: inline-block;
height: 12rem;
min-height: 12rem;
}
#page-mod-quiz-mod #id_reviewoptionshdr .btn-link {
@@ -366,7 +366,7 @@ div#dock {
float: left;
clear: left;
}
#page-mod-quiz-mod #id_reviewoptionshdr .form-check-inline {
#page-mod-quiz-mod #id_reviewoptionshdr .form-check {
width: 90%;
height: 22px;
}
@@ -462,9 +462,8 @@ div#dock {
}
}
/**
* Assign.
*/
// Assign.
.path-mod-assign [data-region="grade-actions-panel"] [data-region="grade-actions"] .collapse-buttons {
top: auto;
}
@@ -472,38 +471,69 @@ div#dock {
overflow: initial;
}
.path-mod-assign [data-region="grade-panel"] .has-popout {
background-color: $card-bg;
// This section removes the responsiveness from the form in the grading panel
$popout-header-font-size: 1.5 * $font-size-base;
// This can't be calculated from modal-title-padding because we are mixing px and rem units.
$popout-header-height: 4rem;
@include border-radius($card-border-radius);
border: $card-border-width solid $card-border-color;
.path-mod-assign #page-content [data-region="grade-panel"] .mform:not(.unresponsive) .fcontainer .fitem.popout .felement {
height: calc(100% - #{$popout-header-height});
}
.path-mod-assign [data-region="grade-panel"] {
padding-top: $spacer;
}
.path-mod-assign [data-region="grade-panel"] .fitem > .col-md-3,
.path-mod-assign [data-region="grade-panel"] .fitem > .col-md-9 {
width: 100%;
padding: 0;
}
.path-mod-assign [data-region="grade-panel"] fieldset,
.path-mod-assign [data-region="grade-panel"] .fitem.row {
margin: 0;
}
.path-mod-assign [data-region="grade-panel"] .fitem > .col-md-3 > .pull-xs-right {
float: none !important; /* stylelint-disable-line declaration-no-important */
}
.path-mod-assign [data-region="grade-panel"] .mform .fitem.has-popout .felement {
width: 100%;
}
.path-mod-assign [data-region="grade-panel"] .mform .fitem .felement {
width: auto;
}
// Now styles for the popout sections.
.path-mod-assign [data-region="grade-panel"] .popout {
background-color: $modal-content-bg;
}
.path-mod-assign [data-region="grade-panel"] .col-md-3 {
width: 100%;
.path-mod-assign [data-region="grade-panel"] .fitem.has-popout {
background-color: $card-bg;
@include border-radius($card-border-radius);
border: $card-border-width solid $card-border-color;
padding: $card-spacer-x;
margin-bottom: $spacer;
}
.path-mod-assign [data-region="grade-panel"] .has-popout .col-md-3 {
border-bottom: $hr-border-width solid $hr-border-color;
margin-bottom: $spacer;
}
.path-mod-assign [data-region="grade-panel"] .popout > .col-md-3 {
@extend .modal-header;
font-size: 1.5rem;
}
.path-mod-assign [data-region="grade-panel"] [data-region="popout-button"] {
margin-top: 0.5rem;
font-size: $popout-header-font-size;
}
.path-mod-assign [data-region="grade-panel"] .popout [data-region="popout-button"] {
margin-top: 0;
}
.path-mod-assign [data-region="grade-panel"] h3 {
margin: 10px 0;
line-height: 40px;
}
// Now style the fixed header elements.
.path-mod-assign [data-region="assignment-info"] {
overflow-y: hidden;
@@ -525,6 +555,15 @@ div#dock {
height: 85px;
}
@media (max-width: 767px) {
.path-mod-assign [data-region="grading-navigation-panel"] {
height: auto;
}
.path-mod-assign [data-region="user-info"] {
margin-top: 1rem;
}
}
.path-mod-assign [data-region="grading-navigation"] [data-region="input-field"] input {
width: auto;
display: inline-block;
+12 -10
View File
@@ -58,13 +58,15 @@
]
}
}}
<ol class="breadcrumb" role="navigation">
{{#get_items}}
{{#has_action}}
<li class="breadcrumb-item"><a href="{{{action}}}" {{#get_title}}title="{{get_title}}"{{/get_title}}>{{{text}}}</a></li>
{{/has_action}}
{{^has_action}}
<li class="breadcrumb-item">{{{text}}}</li>
{{/has_action}}
{{/get_items}}
</ol>
<nav role="navigation">
<ol class="breadcrumb">
{{#get_items}}
{{#has_action}}
<li class="breadcrumb-item"><a href="{{{action}}}" {{#get_title}}title="{{get_title}}"{{/get_title}}>{{{text}}}</a></li>
{{/has_action}}
{{^has_action}}
<li class="breadcrumb-item">{{{text}}}</li>
{{/has_action}}
{{/get_items}}
</ol>
</nav>
@@ -1,3 +1,94 @@
{{!
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/>.
}}
{{!
@template core_form/element-select
Simple select form element template.
Context variables required for this template:
* id - Element id,
* name - Element name,
* label - Element label,
* multiple - multi select?,
* checked - checked?,
* error - Is there an error associated with this element?,
* size - Element size,
* value - Element value,
* helpbutton - Helpbutton,
* hiddenlabel - Element hidden flag,
* frozen - Element frozen flag,
* hardfrozen - Element hard fronzen flag,
* extraclasses - Extra classes assocaited,
* type - Element type,
* attributes - Element attributes,
* options - [
{
text - Option text,
value - Option value,
selected - Selected?,
disabled - Disabled?,
optionattributes - Option attributes
}
]
Example context (json):
{
"element": {
"id": "id_maildisplay",
"name": "maildisplay",
"label": null,
"multiple": null,
"checked": null,
"error": null,
"size": null,
"value": null,
"helpbutton": "",
"hiddenlabel": false,
"frozen": false,
"hardfrozen": false,
"extraclasses": null,
"type": "select",
"attributes": "",
"options": [
{
"text": "Hide my email address from everyone",
"value": 0,
"selected": false,
"disabled": false,
"optionattributes": ""
},
{
"text": "Allow everyone to see my email address",
"value": 1,
"selected": true,
"disabled": false,
"optionattributes": ""
},
{
"text": "Allow only other course members to see my email address",
"value": 2,
"selected": false,
"disabled": false,
"optionattributes": ""
}
]
}
}
}}
{{< core_form/element-template }}
{{$element}}
{{^element.frozen}}
@@ -12,7 +103,8 @@
{{/error}}
{{{element.attributes}}} >
{{#element.options}}
<option value="{{value}}" {{#selected}}selected{{/selected}} {{#disabled}}disabled{{/disabled}} {{{optionattributes}}}>{{text}}</option>
<option value="{{value}}" {{#selected}}selected{{/selected}} {{#disabled}}disabled{{/disabled}}
{{{optionattributes}}}>{{{text}}}</option>
{{/element.options}}
</select>
{{/element.frozen}}
@@ -0,0 +1,43 @@
{{!
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/>.
}}
{{!
Page header.
}}
<header role="banner" class="pos-f-t navbar navbar-full navbar-light bg-faded navbar-static-top moodle-has-zindex">
<div class="container-fluid">
<span class="navbar-brand {{# output.should_display_navbar_logo }}has-logo{{/ output.should_display_navbar_logo }}
{{^ output.should_display_navbar_logo }}
hidden-sm-down
{{/ output.should_display_navbar_logo }}
">
{{# output.should_display_navbar_logo }}
<span class="logo hidden-xs-down">
<img src="{{output.get_compact_logo_url}}" alt="{{sitename}}">
</span>
{{/ output.should_display_navbar_logo }}
<span class="site-name hidden-sm-down">{{{ sitename }}}</span>
</span>
<div class="pull-xs-right nav-link">
{{{ output.secure_login_info }}}
</div>
</div>
</header>
+1 -1
View File
@@ -25,7 +25,7 @@
<button aria-expanded="{{#navdraweropen}}true{{/navdraweropen}}{{^navdraweropen}}false{{/navdraweropen}}" aria-controls="nav-drawer" type="button" class="btn pull-xs-left m-r-1 btn-secondary" data-action="toggle-drawer" data-side="left" data-preference="drawer-open-nav">&#9776;<span class="sr-only">{{#str}}expand, core{{/str}}</span></button>
</div>
<a role="banner" href="{{{ config.wwwroot }}}" class="navbar-brand {{# output.should_display_navbar_logo }}has-logo{{/ output.should_display_navbar_logo }}
<a href="{{{ config.wwwroot }}}" class="navbar-brand {{# output.should_display_navbar_logo }}has-logo{{/ output.should_display_navbar_logo }}
{{^ output.should_display_navbar_logo }}
hidden-sm-down
{{/ output.should_display_navbar_logo }}
+35 -38
View File
@@ -43,56 +43,53 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body {{{ output.body_attributes }}}>
<body {{{ bodyattributes }}}>
{{{ output.standard_top_of_body_html }}}
<div id="page-wrapper">
<header class="navbar navbar-full navbar-light bg-faded navbar-static-top moodle-has-zindex">
<div class="container">
<div class="clearfix">
<button class="navbar-toggler pull-xs-right hidden-sm-up" data-toggle="collapse" data-target="#bd-main-mav">☰<span class="sr-only">{{#str}}expand{{/str}}</span></button>
</div>
{{{ output.standard_top_of_body_html }}}
<a role="banner" href="{{{ config.wwwroot }}}" class="navbar-brand">
{{# output.should_display_navbar_logo }}
<div class="logo">
<img src="{{output.get_compact_logo_url}}" alt={{#quote}}{{sitename}}{{/quote}}>
{{>theme_boost/header-secure}}
<div id="page" class="container-fluid">
{{! Secured full header }}
<div id="page-header" class="row">
<div class="col-xs-12 p-y-1">
<div class="page-context-header">
<div class="page-header-headings">
{{{ output.page_heading }}}
</div>
</div>
{{/ output.should_display_navbar_logo }}
<div class="site-name">{{{ sitename }}}</div>
</a>
<div class="collapse navbar-toggleable-xs" id="bd-main-nav">
<nav class="nav navbar-nav">
<!-- search_box -->
{{{ output.search_box }}}
<!-- custom_menu -->
{{{ output.custom_menu }}}
<!-- page_heading_menu -->
{{{ output.page_heading_menu }}}
<!-- login info -->
{{{ output.login_info }}}
</nav>
</div>
</div>
</div>
</header>
<div id="page" class="container">
{{{ output.full_header }}}
<div id="page-content" class="row">
<div id="region-main-box" class="col-xs-12">
<div class="row">
<section id="region-main" class="col-xs-12">
<div id="page-content" class="row">
<div id="region-main-box" class="col-xs-12">
<section id="region-main" {{#hasblocks}}class="has-blocks"{{/hasblocks}}>
<div class="card card-block">
{{{ output.course_content_header }}}
{{{ output.main_content }}}
{{{ output.course_content_footer }}}
</div>
</section>
{{#hasblocks}}
<section data-region="blocks-column">
{{{ sidepreblocks }}}
</section>
{{/hasblocks}}
</div>
</div>
</div>
{{{ output.standard_end_of_body_html }}}
</div>
<footer id="page-footer" class="p-y-1 bg-inverse">
<div class="container">
<div id="course-footer">{{{ output.course_footer }}}</div>
{{{ output.standard_end_of_body_html }}}
</div>
</footer>
</body>
</html>
{{#js}}
@@ -1,56 +0,0 @@
<?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/>.
/**
* Basic authentication steps definitions.
*
* @package core_auth
* @category test
* @copyright 2012 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
require_once(__DIR__ . '/../../../../lib/behat/behat_base.php');
require_once(__DIR__ . '/../../../../auth/tests/behat/behat_auth.php');
/**
* Log in log out steps definitions.
*
* @package core_auth
* @category test
* @copyright 2012 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_theme_boost_behat_auth extends behat_auth {
public function i_log_out() {
// There is no longer any need to worry about whether the navigation
// bar needs to be expanded; user_menu now lives outside the
// hamburger.
// However, the user menu *always* needs to be expanded. if running JS.
if ($this->running_javascript()) {
$xpath = "//div[@class='usermenu']//a[contains(concat(' ', @class, ' '), ' dropdown-toggle ')]";
$this->execute('behat_general::i_click_on', array($xpath, "xpath_element"));
}
// No need to check for exceptions as it will checked after this step execution.
$this->execute('behat_general::click_link', get_string('logout'));
}
}
+1 -1
View File
@@ -192,7 +192,7 @@ a.autolink.glossary:hover {
}
/*rtl:raw:
.collapsible-actions .collapseexpand {
background: url([[pix:t/collapsed_rtl]]);
background: url([[pix:t/collapsed_rtl]]) right center no-repeat;
}
*/
.collapsible-actions .collapse-all {
+1 -1
View File
@@ -35,7 +35,7 @@ form {
.mform fieldset.collapsible legend a.fheader {
padding: 0 5px 0 20px;
margin-left: -20px;
background: url([[pix:t/expanded]]) 2px center no-repeat;
background: url([[pix:t/expanded]]) left center no-repeat;
}
.mform fieldset.collapsed legend a.fheader {
/*rtl:raw:
@@ -47,6 +47,10 @@
clear: both;
border-radius: 4px;
img {
max-width: 100%;
}
.contacts-area {
border-right: 1px solid #e3e3e3;
height: 600px;
@@ -9,6 +9,17 @@ select {
width: auto;
}
// Assign
.path-mod-assign #page-content [data-region="grade-panel"] .mform:not(.unresponsive) #id_attemptsettings .fitem {
.fitemtitle,
.felement {
display: table-cell;
float: none;
border-top: 1px solid #ddd;
padding: 8px 0;
}
}
// Feedback module
.path-mod-feedback .mform.feedback_form .fitem .fitemtitle {
display: block;
+12 -2
View File
@@ -162,7 +162,7 @@ a.autolink.glossary:hover {
}
/*rtl:raw:
.collapsible-actions .collapseexpand {
background: url([[pix:t/collapsed_rtl]]);
background: url([[pix:t/collapsed_rtl]]) right center no-repeat;
}
*/
.collapsible-actions .collapse-all {
@@ -5838,6 +5838,9 @@ a.ygtvspacer:hover {
clear: both;
border-radius: 4px;
}
.messaging-area-container .messaging-area img {
max-width: 100%;
}
.messaging-area-container .messaging-area .contacts-area {
border-right: 1px solid #e3e3e3;
height: 600px;
@@ -13821,7 +13824,7 @@ form {
.mform fieldset.collapsible legend a.fheader {
padding: 0 5px 0 20px;
margin-left: -20px;
background: url([[pix:t/expanded]]) 2px center no-repeat;
background: url([[pix:t/expanded]]) left center no-repeat;
}
.mform fieldset.collapsed legend a.fheader {
/*rtl:raw:
@@ -14456,6 +14459,13 @@ body.modal-open {
select {
width: auto;
}
.path-mod-assign #page-content [data-region="grade-panel"] .mform:not(.unresponsive) #id_attemptsettings .fitem .fitemtitle,
.path-mod-assign #page-content [data-region="grade-panel"] .mform:not(.unresponsive) #id_attemptsettings .fitem .felement {
display: table-cell;
float: none;
border-top: 1px solid #ddd;
padding: 8px 0;
}
.path-mod-feedback .mform.feedback_form .fitem .fitemtitle {
display: block;
margin-top: 4px;
+2 -2
View File
@@ -29,11 +29,11 @@
defined('MOODLE_INTERNAL') || die();
$version = 2016111800.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2016112200.00; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '3.2rc1 (Build: 20161118)'; // Human-friendly version name
$release = '3.2rc2 (Build: 20161122)'; // Human-friendly version name
$branch = '32'; // This version's branch.
$maturity = MATURITY_RC; // This version's maturity level.