Merge branch 'MDL-50993-master' of git://github.com/ryanwyllie/moodle

This commit is contained in:
Andrew Nicols 2015-10-19 12:43:40 +08:00
commit c95ba7faa8
3 changed files with 99 additions and 20 deletions

View File

@ -89,7 +89,12 @@ class block_news_items extends block_base {
/// Get all the recent discussions we're allowed to see
if (! $discussions = forum_get_discussions($cm, 'p.modified DESC', false,
// This block displays the most recent posts in a forum in
// descending order. The call to default sort order here will use
// that unless the discussion that post is in has a timestart set
// in the future.
$sort = forum_get_default_sort_order(true, 'p.modified');
if (! $discussions = forum_get_discussions($cm, $sort, false,
$currentgroup, $this->page->course->newsitems) ) {
$text .= '('.get_string('nonews', 'forum').')';
$this->content->text = $text;

View File

@ -2473,7 +2473,7 @@ function forum_count_discussions($forum, $cm, $course) {
* Use FORUM_POSTS_ALL_USER_GROUPS for all the user groups
* @return array
*/
function forum_get_discussions($cm, $forumsort="d.timemodified DESC", $fullpost=true, $unused=-1, $limit=-1,
function forum_get_discussions($cm, $forumsort="", $fullpost=true, $unused=-1, $limit=-1,
$userlastmodified=false, $page=-1, $perpage=0, $groupid = -1) {
global $CFG, $DB, $USER;
@ -2568,7 +2568,7 @@ function forum_get_discussions($cm, $forumsort="d.timemodified DESC", $fullpost=
$groupselect = "";
}
if (empty($forumsort)) {
$forumsort = "d.timemodified DESC";
$forumsort = forum_get_default_sort_order();
}
if (empty($fullpost)) {
$postdata = "p.id,p.subject,p.modified,p.discussion,p.userid";
@ -2707,11 +2707,37 @@ function forum_get_discussion_neighbours($cm, $discussion, $forum) {
$timelimit
$groupselect";
$prevsql = $sql . " AND d.timemodified < :disctimemodified
ORDER BY d.timemodified DESC";
if (empty($CFG->forum_enabletimedposts)) {
$prevsql = $sql . " AND d.timemodified < :disctimemodified";
$nextsql = $sql . " AND d.timemodified > :disctimemodified";
$nextsql = $sql . " AND d.timemodified > :disctimemodified
ORDER BY d.timemodified ASC";
} else {
// Normally we would just use the timemodified for sorting
// discussion posts. However, when timed discussions are enabled,
// then posts need to be sorted base on the later of timemodified
// or the release date of the post (timestart).
$params['disctimecompare'] = $discussion->timemodified;
if ($discussion->timemodified < $discussion->timestart) {
$params['disctimecompare'] = $discussion->timestart;
}
$params['disctimecompare2'] = $params['disctimecompare'];
// Here we need to take into account the release time (timestart)
// if one is set, of the neighbouring posts and compare it to the
// timestart or timemodified of *this* post depending on if the
// release date of this post is in the future or not.
// This stops discussions that appear later because of the
// timestart value from being buried under discussions that were
// made afterwards.
$prevsql = $sql . " AND CASE WHEN d.timemodified < d.timestart
THEN d.timestart < :disctimecompare
ELSE d.timemodified < :disctimecompare2 END";
$nextsql = $sql . " AND CASE WHEN d.timemodified < d.timestart
THEN d.timestart > :disctimecompare
ELSE d.timemodified > :disctimecompare2 END";
}
$prevsql .= ' ORDER BY '.forum_get_default_sort_order();
$nextsql .= ' ORDER BY '.forum_get_default_sort_order(false);
$neighbours['prev'] = $DB->get_record_sql($prevsql, $params, IGNORE_MULTIPLE);
$neighbours['next'] = $DB->get_record_sql($nextsql, $params, IGNORE_MULTIPLE);
@ -2720,6 +2746,35 @@ function forum_get_discussion_neighbours($cm, $discussion, $forum) {
return $neighbours;
}
/**
* Get the sql to use in the ORDER BY clause for forum discussions.
*
* This has the ordering take timed discussion windows into account.
*
* @param bool $desc True for DESC, False for ASC.
* @param string $compare The field in the SQL to compare to normally sort by.
* @param string $prefix The prefix being used for the discussion table.
* @return string
*/
function forum_get_default_sort_order($desc = true, $compare = 'd.timemodified', $prefix = 'd') {
global $CFG;
if (!empty($prefix)) {
$prefix .= '.';
}
$dir = $desc ? 'DESC' : 'ASC';
$sort = "{$prefix}timemodified";
if (!empty($CFG->forum_enabletimedposts)) {
$sort = "CASE WHEN {$compare} < {$prefix}timestart
THEN {$prefix}timestart
ELSE {$compare}
END";
}
return "$sort $dir";
}
/**
*
* @global object
@ -5133,7 +5188,7 @@ function forum_print_latest_discussions($course, $forum, $maxdiscussions = -1, $
$context = context_module::instance($cm->id);
if (empty($sort)) {
$sort = "d.timemodified DESC";
$sort = forum_get_default_sort_order();
}
$olddiscussionlink = false;

View File

@ -903,19 +903,30 @@ class mod_forum_lib_testcase extends advanced_testcase {
$record->timestart = $past;
$record->timeend = $future;
$disc12 = $forumgen->create_discussion($record);
sleep(1);
$record->timestart = $future + 1; // Should be last post for those that can see it.
$record->timeend = 0;
$disc13 = $forumgen->create_discussion($record);
// Admin user ignores the timed settings of discussions.
// Post ordering taking into account timestart:
// 8 = t
// 10 = t+3
// 11 = t+4
// 12 = t+5
// 9 = t+60
// 13 = t+61.
$this->setAdminUser();
$neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum);
$this->assertEquals($disc7->id, $neighbours['prev']->id);
$this->assertEquals($disc9->id, $neighbours['next']->id);
$neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum);
$this->assertEquals($disc8->id, $neighbours['prev']->id);
$this->assertEquals($disc10->id, $neighbours['next']->id);
$neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum);
$this->assertEquals($disc12->id, $neighbours['prev']->id);
$this->assertEquals($disc13->id, $neighbours['next']->id);
$neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum);
$this->assertEquals($disc9->id, $neighbours['prev']->id);
$this->assertEquals($disc8->id, $neighbours['prev']->id);
$this->assertEquals($disc11->id, $neighbours['next']->id);
$neighbours = forum_get_discussion_neighbours($cm, $disc11, $forum);
@ -924,20 +935,24 @@ class mod_forum_lib_testcase extends advanced_testcase {
$neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum);
$this->assertEquals($disc11->id, $neighbours['prev']->id);
$this->assertEquals($disc9->id, $neighbours['next']->id);
$neighbours = forum_get_discussion_neighbours($cm, $disc13, $forum);
$this->assertEquals($disc9->id, $neighbours['prev']->id);
$this->assertEmpty($neighbours['next']);
// Normal user can see their own timed discussions.
$this->setUser($user);
$neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum);
$this->assertEquals($disc7->id, $neighbours['prev']->id);
$this->assertEquals($disc9->id, $neighbours['next']->id);
$neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum);
$this->assertEquals($disc8->id, $neighbours['prev']->id);
$this->assertEquals($disc10->id, $neighbours['next']->id);
$neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum);
$this->assertEquals($disc12->id, $neighbours['prev']->id);
$this->assertEquals($disc13->id, $neighbours['next']->id);
$neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum);
$this->assertEquals($disc9->id, $neighbours['prev']->id);
$this->assertEquals($disc8->id, $neighbours['prev']->id);
$this->assertEquals($disc11->id, $neighbours['next']->id);
$neighbours = forum_get_discussion_neighbours($cm, $disc11, $forum);
@ -946,6 +961,10 @@ class mod_forum_lib_testcase extends advanced_testcase {
$neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum);
$this->assertEquals($disc11->id, $neighbours['prev']->id);
$this->assertEquals($disc9->id, $neighbours['next']->id);
$neighbours = forum_get_discussion_neighbours($cm, $disc13, $forum);
$this->assertEquals($disc9->id, $neighbours['prev']->id);
$this->assertEmpty($neighbours['next']);
// Normal user does not ignore timed settings.
@ -975,11 +994,11 @@ class mod_forum_lib_testcase extends advanced_testcase {
$disc3 = $DB->get_record('forum_discussions', array('id' => $disc3->id));
$neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum);
$this->assertEquals($disc12->id, $neighbours['prev']->id);
$this->assertEquals($disc13->id, $neighbours['prev']->id);
$this->assertEmpty($neighbours['next']);
$neighbours = forum_get_discussion_neighbours($cm, $disc3, $forum);
$this->assertEquals($disc12->id, $neighbours['prev']->id);
$this->assertEquals($disc13->id, $neighbours['prev']->id);
$this->assertEmpty($neighbours['next']);
}