MDL-8501 mod_forum: New function to retrieve discussion neighbours

This commit is contained in:
Frederic Massart 2014-07-02 12:33:56 +08:00
parent ec36fafc0f
commit 8d3a5ba176

View file

@ -2638,6 +2638,95 @@ function forum_get_discussions($cm, $forumsort="d.timemodified DESC", $fullpost=
return $DB->get_records_sql($sql, $params, $limitfrom, $limitnum);
}
/**
* Gets the neighbours (previous and next) of a discussion.
*
* The calculation is based on the timemodified of the discussion and does not handle
* the neighbours having an identical timemodified. The reason is that we do not have any
* other mean to sort the records, e.g. we cannot use IDs as a greater ID can have a lower
* timemodified.
*
* Please note that this does not check whether or not the discussion passed is accessible
* by the user, it simply uses it as a reference to find the neighbours. On the other hand,
* the returned neighbours are checked and are accessible to the current user.
*
* @param object $cm The CM record.
* @param object $discussion The discussion record.
* @return array That always contains the keys 'prev' and 'next'. When there is a result
* they contain the record with minimal information such as 'id' and 'name'.
* When the neighbour is not found the value is false.
*/
function forum_get_discussion_neighbours($cm, $discussion) {
global $CFG, $DB, $USER;
if ($cm->instance != $discussion->forum) {
throw new coding_exception('Discussion is not part of the same forum.');
}
$neighbours = array('prev' => false, 'next' => false);
$now = round(time(), -2);
$params = array();
$modcontext = context_module::instance($cm->id);
$groupmode = groups_get_activity_groupmode($cm);
$currentgroup = groups_get_activity_group($cm);
// Users must fulfill timed posts.
$timelimit = '';
if (!empty($CFG->forum_enabletimedposts)) {
if (!has_capability('mod/forum:viewhiddentimedposts', $modcontext)) {
$timelimit = ' AND ((d.timestart <= :tltimestart AND (d.timeend = 0 OR d.timeend > :tltimeend))';
$params['tltimestart'] = $now;
$params['tltimeend'] = $now;
if (isloggedin()) {
$timelimit .= ' OR d.userid = :tluserid';
$params['tluserid'] = $USER->id;
}
$timelimit .= ')';
}
}
// Limiting to posts accessible according to groups.
$groupselect = '';
if ($groupmode) {
if ($groupmode == VISIBLEGROUPS || has_capability('moodle/site:accessallgroups', $modcontext)) {
if ($currentgroup) {
$groupselect = 'AND (d.groupid = :groupid OR d.groupid = -1)';
$params['groupid'] = $currentgroup;
}
} else {
if ($currentgroup) {
$groupselect = 'AND (d.groupid = :groupid OR d.groupid = -1)';
$params['groupid'] = $currentgroup;
} else {
$groupselect = 'AND d.groupid = -1';
}
}
}
$params['forumid'] = $cm->instance;
$params['discid'] = $discussion->id;
$params['disctimemodified'] = $discussion->timemodified;
$sql = "SELECT d.id, d.name, d.timemodified, d.groupid, d.timestart, d.timeend
FROM {forum_discussions} d
WHERE d.forum = :forumid
AND d.id <> :discid
$timelimit
$groupselect";
$prevsql = $sql . " AND d.timemodified < :disctimemodified
ORDER BY d.timemodified DESC";
$nextsql = $sql . " AND d.timemodified > :disctimemodified
ORDER BY d.timemodified ASC";
$neighbours['prev'] = $DB->get_record_sql($prevsql, $params, IGNORE_MULTIPLE);
$neighbours['next'] = $DB->get_record_sql($nextsql, $params, IGNORE_MULTIPLE);
return $neighbours;
}
/**
*
* @global object