Merge branch 'MDL-68200-master-take2' of git://github.com/rezaies/moodle
This commit is contained in:
Vendored
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("core/user_date",["jquery","core/ajax","core/sessionstorage","core/config"],function(a,b,c,d){var e={},f=function(b){var c=a("html").attr("lang").replace(/-/g,"_");return"core_user_date/"+c+"/"+d.usertimezone+"/"+b.timestamp+"/"+b.format},g=function(a){return c.get(a)},h=function(a,b){c.set(a,b)},i=function(a){return"undefined"!=typeof e[a]},j=function(a){return e[a]},k=function(a,b){e[a]=b},l=function(a){var c=a.map(function(a){return{timestamp:a.timestamp,format:a.format}}),e={methodname:"core_get_user_dates",args:{contextid:d.contextid,timestamps:c}};return b.call([e],!0,!0)[0].then(function(b){b.dates.forEach(function(b,c){var d=a[c],e=f(d);h(e,b);d.deferred.resolve(b)})}).catch(function(b){a.forEach(function(a){a.deferred.reject(b)})})};return{get:function get(b){var c=[],d=[];b.forEach(function(b){var e=f(b);if(i(e)){d.push(j(e))}else{var h=a.Deferred(),l=g(e);if(l){h.resolve(l)}else{b.deferred=h;c.push(b)}k(e,h.promise());d.push(h.promise())}});if(c.length){l(c)}return a.when.apply(a,d).then(function(){return 1===arguments.length?[arguments[0]]:Array.apply(null,arguments)})},getUserMidnightForTimestamp:function getUserMidnightForTimestamp(a,b){var c=a>b,d=Math.abs(a-b),e=c?Math.floor(d/86400):Math.ceil(d/86400),f=e*86400,g=c?b+f:b-f;return g}}});
|
||||
define ("core/user_date",["jquery","core/ajax","core/sessionstorage","core/config"],function(a,b,c,d){var e={},f=function(b){var c=a("html").attr("lang").replace(/-/g,"_");return"core_user_date/"+c+"/"+d.usertimezone+"/"+b.timestamp+"/"+b.format},g=function(a){return c.get(a)},h=function(a,b){c.set(a,b)},i=function(a){return"undefined"!=typeof e[a]},j=function(a){return e[a]},k=function(a,b){e[a]=b},l=function(a){var c=a.map(function(a){var b=a.hasOwnProperty("fixday")?a.fixday:1,c=a.hasOwnProperty("fixhour")?a.fixhour:1;return{timestamp:a.timestamp,format:a.format,type:a.type||"",fixday:b,fixhour:c}}),e={methodname:"core_get_user_dates",args:{contextid:d.contextid,timestamps:c}};return b.call([e],!0,!0)[0].then(function(b){b.dates.forEach(function(b,c){var d=a[c],e=f(d);h(e,b);d.deferred.resolve(b)})}).catch(function(b){a.forEach(function(a){a.deferred.reject(b)})})};return{get:function get(b){var c=[],d=[];b.forEach(function(b){var e=f(b);if(i(e)){d.push(j(e))}else{var h=a.Deferred(),l=g(e);if(l){h.resolve(l)}else{b.deferred=h;c.push(b)}k(e,h.promise());d.push(h.promise())}});if(c.length){l(c)}return a.when.apply(a,d).then(function(){return 1===arguments.length?[arguments[0]]:Array.apply(null,arguments)})},getUserMidnightForTimestamp:function getUserMidnightForTimestamp(a,b){var c=a>b,d=Math.abs(a-b),e=c?Math.floor(d/86400):Math.ceil(d/86400),f=e*86400,g=c?b+f:b-f;return g}}});
|
||||
//# sourceMappingURL=user_date.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -107,9 +107,14 @@ define(['jquery', 'core/ajax', 'core/sessionstorage', 'core/config'],
|
||||
*/
|
||||
var loadDatesFromServer = function(dates) {
|
||||
var args = dates.map(function(data) {
|
||||
var fixDay = data.hasOwnProperty('fixday') ? data.fixday : 1;
|
||||
var fixHour = data.hasOwnProperty('fixhour') ? data.fixhour : 1;
|
||||
return {
|
||||
timestamp: data.timestamp,
|
||||
format: data.format
|
||||
format: data.format,
|
||||
type: data.type || '',
|
||||
fixday: fixDay,
|
||||
fixhour: fixHour
|
||||
};
|
||||
});
|
||||
|
||||
@@ -155,7 +160,8 @@ define(['jquery', 'core/ajax', 'core/sessionstorage', 'core/config'],
|
||||
* Only dates not found in either cache will be sent to the server
|
||||
* for transforming.
|
||||
*
|
||||
* A request object must have a timestamp key and a format key.
|
||||
* A request object must have a timestamp key and a format key and
|
||||
* optionally may have a type key.
|
||||
*
|
||||
* E.g.
|
||||
* var request = [
|
||||
@@ -165,7 +171,10 @@ define(['jquery', 'core/ajax', 'core/sessionstorage', 'core/config'],
|
||||
* },
|
||||
* {
|
||||
* timestamp: 1293876000,
|
||||
* format: '%A, %d %B %Y, %I:%M %p'
|
||||
* format: '%A, %d %B %Y, %I:%M %p',
|
||||
* type: 'gregorian',
|
||||
* fixday: false,
|
||||
* fixhour: false
|
||||
* }
|
||||
* ];
|
||||
*
|
||||
|
||||
Vendored
+14
-6
@@ -120,7 +120,7 @@ class core_external extends external_api {
|
||||
/**
|
||||
* Returns description of get_string() result value
|
||||
*
|
||||
* @return string
|
||||
* @return external_description
|
||||
* @since Moodle 2.4
|
||||
*/
|
||||
public static function get_string_returns() {
|
||||
@@ -189,7 +189,7 @@ class core_external extends external_api {
|
||||
/**
|
||||
* Returns description of get_string() result value
|
||||
*
|
||||
* @return array
|
||||
* @return external_description
|
||||
* @since Moodle 2.4
|
||||
*/
|
||||
public static function get_strings_returns() {
|
||||
@@ -233,6 +233,9 @@ class core_external extends external_api {
|
||||
[
|
||||
'timestamp' => new external_value(PARAM_INT, 'unix timestamp'),
|
||||
'format' => new external_value(PARAM_TEXT, 'format string'),
|
||||
'type' => new external_value(PARAM_PLUGIN, 'The calendar type', VALUE_DEFAULT),
|
||||
'fixday' => new external_value(PARAM_INT, 'Remove leading zero for day', VALUE_DEFAULT, 1),
|
||||
'fixhour' => new external_value(PARAM_INT, 'Remove leading zero for hour', VALUE_DEFAULT, 1),
|
||||
]
|
||||
)
|
||||
)
|
||||
@@ -264,7 +267,12 @@ class core_external extends external_api {
|
||||
self::validate_context($context);
|
||||
|
||||
$formatteddates = array_map(function($timestamp) {
|
||||
return userdate($timestamp['timestamp'], $timestamp['format']);
|
||||
|
||||
$calendartype = $timestamp['type'];
|
||||
$fixday = !empty($timestamp['fixday']);
|
||||
$fixhour = !empty($timestamp['fixhour']);
|
||||
$calendar = \core_calendar\type_factory::get_calendar_instance($calendartype);
|
||||
return $calendar->timestamp_to_date_string($timestamp['timestamp'], $timestamp['format'], 99, $fixday, $fixhour);
|
||||
}, $params['timestamps']);
|
||||
|
||||
return ['dates' => $formatteddates];
|
||||
@@ -273,7 +281,7 @@ class core_external extends external_api {
|
||||
/**
|
||||
* Returns description of get_user_dates() result value
|
||||
*
|
||||
* @return array
|
||||
* @return external_description
|
||||
*/
|
||||
public static function get_user_dates_returns() {
|
||||
return new external_single_structure(
|
||||
@@ -333,7 +341,7 @@ class core_external extends external_api {
|
||||
/**
|
||||
* Returns description of get_component_strings() result value
|
||||
*
|
||||
* @return array
|
||||
* @return external_description
|
||||
* @since Moodle 2.4
|
||||
*/
|
||||
public static function get_component_strings_returns() {
|
||||
@@ -421,7 +429,7 @@ class core_external extends external_api {
|
||||
/**
|
||||
* Returns description of get_fragment() result value
|
||||
*
|
||||
* @return array
|
||||
* @return external_description
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function get_fragment_returns() {
|
||||
|
||||
Vendored
+7
-2
@@ -203,7 +203,6 @@ class core_external_testcase extends externallib_advanced_testcase {
|
||||
}
|
||||
|
||||
public function test_get_user_dates() {
|
||||
global $USER, $CFG, $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->setAdminUser();
|
||||
@@ -222,6 +221,11 @@ class core_external_testcase extends externallib_advanced_testcase {
|
||||
'timestamp' => 1293876000,
|
||||
'format' => '%d %m %Y'
|
||||
],
|
||||
[
|
||||
'timestamp' => 1293876000,
|
||||
'format' => '%d %m %Y',
|
||||
'type' => 'gregorian'
|
||||
],
|
||||
[
|
||||
'timestamp' => 1293876000,
|
||||
'format' => 'some invalid format'
|
||||
@@ -233,6 +237,7 @@ class core_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
$this->assertEquals('Saturday, 1 January 2011, 6:00', $result['dates'][0]);
|
||||
$this->assertEquals('1 01 2011', $result['dates'][1]);
|
||||
$this->assertEquals('some invalid format', $result['dates'][2]);
|
||||
$this->assertEquals('1 01 2011', $result['dates'][2]);
|
||||
$this->assertEquals('some invalid format', $result['dates'][3]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
{{!
|
||||
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/time_element
|
||||
|
||||
Template to display an HTML time element.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* data-timestamp Number - The timestamp for the element.
|
||||
* data-datetimeformat String - A valid format for the datetime attribute.
|
||||
|
||||
Context variables required for this template:
|
||||
* timestamp Number - The timestamp for the element.
|
||||
* userdateformat String - The user-facing date format
|
||||
* datetimeformat String - A valid format for the datetime attribute. Defaults to the ISO-8601 format of '%Y-%m-%dT%H:%M%z'.
|
||||
Example context (json):
|
||||
{
|
||||
"timestamp": 0,
|
||||
"userdateformat": "%d %b %Y",
|
||||
"datetimeformat": "%Y-%m-%dT%H:%M%z"
|
||||
}
|
||||
}}
|
||||
<time id="time-{{$elementid}}{{uniqid}}{{/elementid}}" class="{{$elementclass}}{{timeclass}}{{/elementclass}}" datetime="{{$datetimeval}}{{datetime}}{{/datetimeval}}"
|
||||
data-timestamp="{{$timestampval}}{{timestamp}}{{/timestampval}}"
|
||||
data-datetimeformat="{{$datetimeformatval}}{{#datetimeformat}}{{.}}{{/datetimeformat}}{{^datetimeformat}}%Y-%m-%dT%H:%M%z{{/datetimeformat}}{{/datetimeformatval}}">
|
||||
{{$datedisplay}}
|
||||
{{#userdate}} {{$timestampval}}{{timestamp}}{{/timestampval}}, {{$userdateformatval}}{{userdateformat}}{{/userdateformatval}} {{/userdate}}
|
||||
{{/datedisplay}}
|
||||
</time>
|
||||
{{#js}}
|
||||
/** Fetches the formatted date/time for the time element's datetime attribute. */
|
||||
require(['core/user_date'], function(UserDate) {
|
||||
var root = document.getElementById('time-{{$elementid}}{{uniqid}}{{/elementid}}');
|
||||
// Fetch value for the datetime attribute using core/user_date, if it's not available.
|
||||
if (!root.getAttribute('datetime')) {
|
||||
var dateTimeFormat = root.getAttribute('data-datetimeformat');
|
||||
var timestamp = root.getAttribute('data-timestamp');
|
||||
|
||||
if (!dateTimeFormat.match(/%(?![YmdHMSzZ])./g)) {
|
||||
var zeroPad = function(nNum, nPad) {
|
||||
return ((Math.pow(10, nPad) + nNum) + '').slice(1);
|
||||
};
|
||||
|
||||
var date = new Date(timestamp * 1000);
|
||||
|
||||
var datetime = dateTimeFormat.replace(/%./g, function(sMatch) {
|
||||
return (({
|
||||
'%Y': date.getFullYear(),
|
||||
'%m': zeroPad(date.getMonth() + 1, 2),
|
||||
'%d': zeroPad(date.getDate(), 2),
|
||||
'%H': zeroPad(date.getHours(), 2),
|
||||
'%M': zeroPad(date.getMinutes(), 2),
|
||||
'%S': zeroPad(date.getSeconds(), 2),
|
||||
'%z': date.toTimeString().replace(/.+GMT([+-]\d+).+/, '$1'),
|
||||
'%Z': date.toTimeString().replace(/.+\((.+?)\)$/, '$1')
|
||||
}[sMatch] || '') + '') || sMatch;
|
||||
});
|
||||
root.setAttribute('datetime', datetime);
|
||||
} else {
|
||||
// Otherwise, use core/user_date.
|
||||
var timestamps = [{
|
||||
timestamp: timestamp,
|
||||
format: dateTimeFormat,
|
||||
type: 'gregorian',
|
||||
fixday: 0,
|
||||
fixhour: 0
|
||||
}];
|
||||
UserDate.get(timestamps).done(function(dates) {
|
||||
var datetime = dates.pop();
|
||||
root.setAttribute('datetime', datetime);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
{{/js}}
|
||||
@@ -63,6 +63,10 @@ information provided here is intended especially for developers.
|
||||
* The following functions have been updated to support passing in an array of group IDs (but still support passing in a single ID):
|
||||
* groups_get_members_join()
|
||||
* groups_get_members_ids_sql()
|
||||
* Additional parameters were added to core_get_user_dates:
|
||||
- type: specifies the calendar type. Optional, defaults to Gregorian.
|
||||
- fixday: Whether to remove leading zero for day. Optional, defaults to 1.
|
||||
- fixhour: Whether to remove leading zero for hour. Optional, defaults to 1.
|
||||
|
||||
=== 3.8 ===
|
||||
* Add CLI option to notify all cron tasks to stop: admin/cli/cron.php --stop
|
||||
|
||||
@@ -638,9 +638,8 @@ class post extends exporter {
|
||||
private function get_author_subheading_html(stdClass $exportedauthor, int $timecreated) : string {
|
||||
$fullname = $exportedauthor->fullname;
|
||||
$profileurl = $exportedauthor->urls['profile'] ?? null;
|
||||
$formatteddate = userdate($timecreated, get_string('strftimedaydatetime', 'core_langconfig'));
|
||||
$name = $profileurl ? "<a href=\"{$profileurl}\">{$fullname}</a>" : $fullname;
|
||||
$date = "<time>{$formatteddate}</time>";
|
||||
$date = userdate_htmltime($timecreated, get_string('strftimedaydatetime', 'core_langconfig'));
|
||||
return get_string('bynameondate', 'mod_forum', ['name' => $name, 'date' => $date]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +257,11 @@
|
||||
<div class="author-info align-middle">
|
||||
<div class="mb-1 line-height-3 text-truncate">{{fullname}}</div>
|
||||
<div class="line-height-3">
|
||||
{{#userdate}}{{discussion.times.created}}, {{#str}}strftimedatemonthabbr, langconfig{{/str}}{{/userdate}}
|
||||
{{< core/time_element }}
|
||||
{{$elementid}}created-{{discussion.id}}{{/elementid}}
|
||||
{{$timestampval}}{{discussion.times.created}}{{/timestampval}}
|
||||
{{$userdateformatval}}{{#str}}strftimedatemonthabbr, langconfig{{/str}}{{/userdateformatval}}
|
||||
{{/core/time_element}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -277,7 +281,11 @@
|
||||
<div class="line-height-3">
|
||||
{{#latestpostid}}
|
||||
<a href="{{{discussion.urls.viewlatest}}}" title="{{#userdate}}{{discussion.times.modified}},{{#str}}strftimerecentfull{{/str}}{{/userdate}}">
|
||||
{{#userdate}}{{discussion.times.modified}}, {{#str}}strftimedatemonthabbr, langconfig{{/str}}{{/userdate}}
|
||||
{{< core/time_element }}
|
||||
{{$elementid}}modified-{{discussion.id}}{{/elementid}}
|
||||
{{$timestampval}}{{discussion.times.modified}}{{/timestampval}}
|
||||
{{$userdateformatval}}{{#str}}strftimedatemonthabbr, langconfig{{/str}}{{/userdateformatval}}
|
||||
{{/ core/time_element }}
|
||||
</a>
|
||||
{{/latestpostid}}
|
||||
</div>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
<header id="post-header-{{id}}-{{uniqid}}">
|
||||
{{^isdeleted}}
|
||||
<div class="d-flex flex-wrap align-items-center mb-1">
|
||||
<address class="mb-0 mr-2" tabindex="-1">
|
||||
<div class="mr-2" tabindex="-1">
|
||||
{{#author}}
|
||||
<h4 class="h6 d-lg-inline-block mb-0 author-header mr-1">
|
||||
{{#parentauthorname}}
|
||||
@@ -105,10 +105,13 @@
|
||||
{{/parentauthorname}}
|
||||
</h4>
|
||||
{{/author}}
|
||||
<time class="text-muted">
|
||||
{{#userdate}} {{timecreated}}, {{#str}} strftimerecentfull, core_langconfig {{/str}} {{/userdate}}
|
||||
</time>
|
||||
</address>
|
||||
{{< core/time_element }}
|
||||
{{$elementid}}created-{{id}}-{{uniqid}}{{/elementid}}
|
||||
{{$elementclass}}text-muted{{/elementclass}}
|
||||
{{$timestampval}}{{timecreated}}{{/timestampval}}
|
||||
{{$userdateformatval}}{{#str}} strftimerecentfull, core_langconfig {{/str}}{{/userdateformatval}}
|
||||
{{/core/time_element}}
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center ml-auto">
|
||||
{{#author.groups}}
|
||||
|
||||
@@ -76,14 +76,16 @@
|
||||
}}>{{$subject}}{{{subject}}}{{/subject}}</h3>
|
||||
{{/subjectheading}}
|
||||
{{^isdeleted}}
|
||||
<address tabindex="-1">
|
||||
<div class="mb-3" tabindex="-1">
|
||||
{{#html.authorsubheading}}{{{.}}}{{/html.authorsubheading}}
|
||||
{{^html.authorsubheading}}
|
||||
<time>
|
||||
{{#userdate}} {{timecreated}}, {{#str}} strftimedaydatetime, core_langconfig {{/str}} {{/userdate}}
|
||||
</time>
|
||||
{{< core/time_element }}
|
||||
{{$elementid}}created-{{id}}-{{uniqid}}{{/elementid}}
|
||||
{{$timestampval}}{{timecreated}}{{/timestampval}}
|
||||
{{$userdateformatval}}{{#str}} strftimedaydatetime, core_langconfig {{/str}}{{/userdateformatval}}
|
||||
{{/core/time_element}}
|
||||
{{/html.authorsubheading}}
|
||||
</address>
|
||||
</div>
|
||||
{{/isdeleted}}
|
||||
{{#isprivatereply}}
|
||||
<div class="privatereplyinfo">
|
||||
|
||||
@@ -38,9 +38,7 @@
|
||||
>
|
||||
<a href="{{{urls.viewisolated}}}">{{subject}}</a>
|
||||
{{^isdeleted}}
|
||||
<address class="d-inline-block mb-0">
|
||||
{{{html.authorsubheading}}}
|
||||
</address>
|
||||
{{{html.authorsubheading}}}
|
||||
{{/isdeleted}}
|
||||
|
||||
<div data-region="replies-container">
|
||||
|
||||
@@ -371,9 +371,8 @@ class mod_forum_generator extends testing_module_generator {
|
||||
public function get_author_subheading_html(stdClass $exportedauthor, int $timecreated) : string {
|
||||
$fullname = $exportedauthor->fullname;
|
||||
$profileurl = $exportedauthor->urls['profile'] ?? null;
|
||||
$formatteddate = userdate($timecreated, get_string('strftimedaydatetime', 'core_langconfig'));
|
||||
$name = $profileurl ? "<a href=\"{$profileurl}\">{$fullname}</a>" : $fullname;
|
||||
$date = "<time>{$formatteddate}</time>";
|
||||
$date = userdate_htmltime($timecreated, get_string('strftimedaydatetime', 'core_langconfig'));
|
||||
return get_string('bynameondate', 'mod_forum', ['name' => $name, 'date' => $date]);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ $PAGE->set_heading($course->fullname);
|
||||
$PAGE->set_button(forum_search_form($course, $search));
|
||||
|
||||
if ($istypesingle && $displaymode == FORUM_MODE_NESTED_V2) {
|
||||
$PAGE->add_body_class('reset-style');
|
||||
$PAGE->add_body_class('nested-v2-display-mode reset-style');
|
||||
$settingstrigger = $OUTPUT->render_from_template('mod_forum/settings_drawer_trigger', null);
|
||||
$PAGE->add_header_action($settingstrigger);
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ $allow-reset-style: true !default;
|
||||
vertical-align: top;
|
||||
|
||||
div[role="main"] {
|
||||
flex: 1;
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
.activity-navigation {
|
||||
|
||||
@@ -17737,7 +17737,7 @@ body.reset-style #page-content {
|
||||
padding-right: 1.25rem;
|
||||
vertical-align: top; }
|
||||
body.reset-style #page-content #region-main-box #region-main div[role="main"] {
|
||||
flex: 1; }
|
||||
flex: 1 0 auto; }
|
||||
body.reset-style #page-content #region-main-box #region-main .activity-navigation {
|
||||
overflow: hidden; }
|
||||
body.reset-style #page-content #region-main-box #region-main.has-blocks {
|
||||
|
||||
Reference in New Issue
Block a user