MDL-65071 forum: Add sorting in discussion list

This commit is contained in:
Mihail Geshoski 2019-04-30 10:36:39 +08:00
parent 3f9ed16e56
commit 1a9c60e931
19 changed files with 724 additions and 140 deletions

View File

@ -349,6 +349,7 @@ class icon_system_fontawesome extends icon_system_font {
'core:t/dock_to_block' => 'fa-chevron-left',
'core:t/download' => 'fa-download',
'core:t/down' => 'fa-arrow-down',
'core:t/downlong' => 'fa-long-arrow-down',
'core:t/dropdown' => 'fa-cog',
'core:t/editinline' => 'fa-pencil',
'core:t/edit_menu' => 'fa-cog',
@ -402,6 +403,7 @@ class icon_system_fontawesome extends icon_system_font {
'core:t/unlocked' => 'fa-unlock-alt',
'core:t/unlock' => 'fa-lock',
'core:t/up' => 'fa-arrow-up',
'core:t/uplong' => 'fa-long-arrow-up',
'core:t/user' => 'fa-user',
'core:t/viewdetails' => 'fa-list',
];

View File

@ -147,7 +147,30 @@ class exported_discussion_summaries {
$favourites
);
return (array) $summaryexporter->export($this->renderer);
$exportedposts = (array) $summaryexporter->export($this->renderer);
$firstposts = $postvault->get_first_post_for_discussion_ids($discussionids);
array_walk($exportedposts['summaries'], function($summary) use ($firstposts) {
$summary->discussion->times['created'] = (int) $firstposts[$summary->discussion->firstpostid]->created;
});
// Pass the current, preferred sort order for the discussions list.
$discussionlistvault = $this->vaultfactory->get_discussions_in_forum_vault();
$sortorder = get_user_preferences('forum_discussionlistsortorder',
$discussionlistvault::SORTORDER_LASTPOST_DESC);
$sortoptions = array(
'islastpostdesc' => $sortorder == $discussionlistvault::SORTORDER_LASTPOST_DESC,
'islastpostasc' => $sortorder == $discussionlistvault::SORTORDER_LASTPOST_ASC,
'isrepliesdesc' => $sortorder == $discussionlistvault::SORTORDER_REPLIES_DESC,
'isrepliesasc' => $sortorder == $discussionlistvault::SORTORDER_REPLIES_ASC,
'iscreateddesc' => $sortorder == $discussionlistvault::SORTORDER_CREATED_DESC,
'iscreatedasc' => $sortorder == $discussionlistvault::SORTORDER_CREATED_ASC
);
$exportedposts['state']['sortorder'] = $sortoptions;
return $exportedposts;
}
/**

View File

@ -83,7 +83,8 @@ class container {
return new exporter_factory(
self::get_legacy_data_mapper_factory(),
self::get_manager_factory(),
self::get_url_factory()
self::get_url_factory(),
self::get_vault_factory()
);
}

View File

@ -67,6 +67,7 @@ class discussion extends exporter {
'locked' => ['type' => PARAM_BOOL],
'istimelocked' => ['type' => PARAM_BOOL],
'name' => ['type' => PARAM_TEXT],
'firstpostid' => ['type' => PARAM_INT],
'group' => [
'optional' => true,
'type' => [
@ -195,6 +196,7 @@ class discussion extends exporter {
'name' => format_string($discussion->get_name(), true, [
'context' => $this->related['context']
]),
'firstpostid' => $discussion->get_first_post_id(),
'times' => [
'modified' => $discussion->get_time_modified(),
'start' => $discussion->get_time_start(),

View File

@ -83,6 +83,12 @@ class forum extends exporter {
'create' => ['type' => PARAM_URL],
'markasread' => ['type' => PARAM_URL],
'view' => ['type' => PARAM_URL],
'sortrepliesasc' => ['type' => PARAM_URL],
'sortrepliesdesc' => ['type' => PARAM_URL],
'sortlastpostasc' => ['type' => PARAM_URL],
'sortlastpostdesc' => ['type' => PARAM_URL],
'sortcreatedasc' => ['type' => PARAM_URL],
'sortcreateddesc' => ['type' => PARAM_URL],
],
],
];
@ -99,6 +105,8 @@ class forum extends exporter {
$urlfactory = $this->related['urlfactory'];
$user = $this->related['user'];
$currentgroup = $this->related['currentgroup'];
$vaultfactory = $this->related['vaultfactory'];
$discussionvault = $vaultfactory->get_discussions_in_forum_vault();
return [
'id' => $this->forum->get_id(),
@ -117,6 +125,18 @@ class forum extends exporter {
'create' => $urlfactory->get_discussion_create_url($this->forum)->out(false),
'markasread' => $urlfactory->get_mark_all_discussions_as_read_url($this->forum)->out(false),
'view' => $urlfactory->get_forum_view_url_from_forum($this->forum)->out(false),
'sortrepliesasc' => $urlfactory->get_forum_view_url_from_forum($this->forum, null,
$discussionvault::SORTORDER_REPLIES_ASC)->out(false),
'sortrepliesdesc' => $urlfactory->get_forum_view_url_from_forum($this->forum, null,
$discussionvault::SORTORDER_REPLIES_DESC)->out(false),
'sortlastpostasc' => $urlfactory->get_forum_view_url_from_forum($this->forum, null,
$discussionvault::SORTORDER_LASTPOST_ASC)->out(false),
'sortlastpostdesc' => $urlfactory->get_forum_view_url_from_forum($this->forum, null,
$discussionvault::SORTORDER_LASTPOST_DESC)->out(false),
'sortcreatedasc' => $urlfactory->get_forum_view_url_from_forum($this->forum, null,
$discussionvault::SORTORDER_CREATED_ASC)->out(false),
'sortcreateddesc' => $urlfactory->get_forum_view_url_from_forum($this->forum, null,
$discussionvault::SORTORDER_CREATED_DESC)->out(false)
],
];
}
@ -133,6 +153,7 @@ class forum extends exporter {
'urlfactory' => 'mod_forum\local\factories\url',
'user' => 'stdClass',
'currentgroup' => 'int?',
'vaultfactory' => 'mod_forum\local\factories\vault'
];
}

View File

@ -33,6 +33,7 @@ use mod_forum\local\entities\post_read_receipt_collection as post_read_receipt_c
use mod_forum\local\factories\legacy_data_mapper as legacy_data_mapper_factory;
use mod_forum\local\factories\manager as manager_factory;
use mod_forum\local\factories\url as url_factory;
use mod_forum\local\factories\vault as vault_factory;
use mod_forum\local\exporters\forum as forum_exporter;
use mod_forum\local\exporters\discussion as discussion_exporter;
use mod_forum\local\exporters\discussion_summaries as discussion_summaries_exporter;
@ -61,21 +62,23 @@ class exporter {
/** @var url_factory The factory to create urls */
private $urlfactory;
/** @var vault_factory The vault factory */
private $vaultfactory;
/**
* Constructor for the exporter factory.
*
* @param legacy_data_mapper_factory $legacydatamapperfactory The factory to fetch a legacy data mapper instance
* @param manager_factory $managerfactory The factory fo fetch a manager instance
* @param url_factory $urlfactory The factory to create urls
* @param vault_factory $vaultfactory The vault factory
*/
public function __construct(
legacy_data_mapper_factory $legacydatamapperfactory,
manager_factory $managerfactory,
url_factory $urlfactory
) {
public function __construct(legacy_data_mapper_factory $legacydatamapperfactory, manager_factory $managerfactory,
url_factory $urlfactory, vault_factory $vaultfactory) {
$this->legacydatamapperfactory = $legacydatamapperfactory;
$this->managerfactory = $managerfactory;
$this->urlfactory = $urlfactory;
$this->vaultfactory = $vaultfactory;
}
/**
@ -97,6 +100,7 @@ class exporter {
'urlfactory' => $this->urlfactory,
'user' => $user,
'currentgroup' => $currentgroup,
'vaultfactory' => $this->vaultfactory,
]);
}

View File

@ -95,10 +95,13 @@ class url {
*
* @param forum_entity $forum The forum entity
* @param int|null $pageno The page number
* @param int|null $sortorder The sorting order
* @return moodle_url
*/
public function get_forum_view_url_from_forum(forum_entity $forum, ?int $pageno = null) : moodle_url {
return $this->get_forum_view_url_from_course_module_id($forum->get_course_module_record()->id, $pageno);
public function get_forum_view_url_from_forum(forum_entity $forum, ?int $pageno = null,
?int $sortorder = null) : moodle_url {
return $this->get_forum_view_url_from_course_module_id($forum->get_course_module_record()->id, $pageno, $sortorder);
}
/**
@ -106,15 +109,22 @@ class url {
*
* @param int $coursemoduleid The course module id
* @param int|null $pageno The page number
* @param int|null $sortorder The sorting order
* @return moodle_url
*/
public function get_forum_view_url_from_course_module_id(int $coursemoduleid, ?int $pageno = null) : moodle_url {
public function get_forum_view_url_from_course_module_id(int $coursemoduleid, ?int $pageno = null,
?int $sortorder = null) : moodle_url {
$url = new moodle_url('/mod/forum/view.php', [
'id' => $coursemoduleid,
]);
if (null !== $pageno) {
$url->param('page', $pageno);
$url->param('p', $pageno);
}
if (null !== $sortorder) {
$url->param('o', $sortorder);
}
return $url;

View File

@ -328,11 +328,27 @@ class capability {
* @param discussion_entity $discussion The discussion to check
* @return bool
*/
public function can_favourite_discussion(stdClass $user, discussion_entity $discussion) : bool {
public function can_favourite_discussion(stdClass $user, discussion_entity $discussion) : bool
{
$context = $this->get_context();
return has_capability('mod/forum:cantogglefavourite', $context, $user);
}
/**
* Can the user view the content of a discussion?
*
* @param stdClass $user The user to check
* @param discussion_entity $discussion The discussion to check
* @return bool
*/
public function can_view_discussion(stdClass $user, discussion_entity $discussion) : bool {
$forumrecord = $this->get_forum_record();
$discussionrecord = $this->get_discussion_record($discussion);
$context = $this->get_context();
return forum_user_can_see_discussion($forumrecord, $discussionrecord, $context, $user);
}
/**
* Can the user view the content of the post in this discussion?
*

View File

@ -145,21 +145,20 @@ class discussion_list {
$forum = $this->forum;
$pagesize = $this->get_page_size($pagesize);
$pageno = $this->get_page_number($pageno);
$groupids = $this->get_groups_from_groupid($user, $groupid);
$forumexporter = $this->exporterfactory->get_forum_exporter(
$user,
$this->forum,
$groupid
);
$pagesize = $this->get_page_size($pagesize);
$pageno = $this->get_page_number($pageno);
// Count all forum discussion posts.
$alldiscussionscount = $this->get_count_all_discussions($user, $groupids);
$alldiscussionscount = get_count_all_discussions($forum, $user, $groupid);
// Get all forum discussions posts.
$discussions = $this->get_discussions($user, $groupids, $sortorder, $pageno, $pagesize);
$discussions = get_discussions($forum, $user, $groupid, $sortorder, $pageno, $pagesize);
$forumview = [
'forum' => (array) $forumexporter->export($this->renderer),
@ -186,10 +185,12 @@ class discussion_list {
$exportedposts = ($this->postprocessfortemplate) ($discussions, $user, $forum);
}
$baseurl = new \moodle_url($PAGE->url, array('o' => $sortorder));
$forumview = array_merge(
$forumview,
[
'pagination' => $this->renderer->render(new \paging_bar($alldiscussionscount, $pageno, $pagesize, $PAGE->url, 'p')),
'pagination' => $this->renderer->render(new \paging_bar($alldiscussionscount, $pageno, $pagesize, $baseurl, 'p')),
],
$exportedposts
);
@ -256,102 +257,6 @@ class discussion_list {
return $mformpost->render();
}
/**
* Get the list of groups to show based on the current user and requested groupid.
*
* @param stdClass $user The user viewing
* @param int $groupid The groupid requested
* @return array The list of groups to show
*/
private function get_groups_from_groupid(stdClass $user, ?int $groupid) : ?array {
$forum = $this->forum;
$effectivegroupmode = $forum->get_effective_group_mode();
if (empty($effectivegroupmode)) {
// This forum is not in a group mode. Show all posts always.
return null;
}
if (null == $groupid) {
// No group was specified.
$showallgroups = (VISIBLEGROUPS == $effectivegroupmode);
$showallgroups = $showallgroups || $this->capabilitymanager->can_access_all_groups($user);
if ($showallgroups) {
// Return null to show all groups.
return null;
} else {
// No group was specified. Only show the users current groups.
return array_keys(
groups_get_all_groups(
$forum->get_course_id(),
$user->id,
$forum->get_course_module_record()->groupingid
)
);
}
} else {
// A group was specified. Just show that group.
return [$groupid];
}
}
/**
* Fetch the data used to display the discussions on the current page.
*
* @param stdClass $user The user to render for
* @param int[]|null $groupids The group ids for this list of discussions
* @param int|null $sortorder The sort order to use when selecting the discussions in the list
* @param int|null $pageno The zero-indexed page number to use
* @param int|null $pagesize The number of discussions to show on the page
* @return stdClass The data to use for display
*/
private function get_discussions(stdClass $user, ?array $groupids, ?int $sortorder, ?int $pageno, ?int $pagesize) {
$forum = $this->forum;
$discussionvault = $this->vaultfactory->get_discussions_in_forum_vault();
if (null === $groupids) {
return $discussions = $discussionvault->get_from_forum_id(
$forum->get_id(),
$this->capabilitymanager->can_view_hidden_posts($user),
$user->id,
$sortorder,
$this->get_page_size($pagesize),
$this->get_page_number($pageno) * $this->get_page_size($pagesize),
$user);
} else {
return $discussions = $discussionvault->get_from_forum_id_and_group_id(
$forum->get_id(),
$groupids,
$this->capabilitymanager->can_view_hidden_posts($user),
$user->id,
$sortorder,
$this->get_page_size($pagesize),
$this->get_page_number($pageno) * $this->get_page_size($pagesize),
$user);
}
}
/**
* Get a count of all discussions in a forum.
*
* @param stdClass $user The user to render for
* @param array $groupids The array of groups to render
* @return int The number of discussions in a forum
*/
public function get_count_all_discussions(stdClass $user, ?array $groupids) {
$discussionvault = $this->vaultfactory->get_discussions_in_forum_vault();
if (null === $groupids) {
return $discussionvault->get_total_discussion_count_from_forum_id(
$this->forum->get_id(),
$this->capabilitymanager->can_view_hidden_posts($user),
$user->id);
} else {
return $discussionvault->get_total_discussion_count_from_forum_id_and_group_id(
$this->forum->get_id(),
$groupids,
$this->capabilitymanager->can_view_hidden_posts($user),
$user->id);
}
}
/**
* Fetch the page size to use when displaying the page.
*

View File

@ -59,11 +59,17 @@ class discussion_list extends db_table_vault {
public const PAGESIZE_DEFAULT = 100;
/** Sort by newest first */
public const SORTORDER_NEWEST_FIRST = 1;
public const SORTORDER_LASTPOST_DESC = 1;
/** Sort by oldest first */
public const SORTORDER_OLDEST_FIRST = 2;
public const SORTORDER_LASTPOST_ASC = 2;
/** Sort by created desc */
public const SORTORDER_CREATED_DESC = 3;
/** Sort by created asc */
public const SORTORDER_CREATED_ASC = 4;
/** Sort by number of replies desc */
public const SORTORDER_REPLIES_DESC = 5;
/** Sort by number of replies desc */
public const SORTORDER_REPLIES_ASC = 6;
/**
* Get the table alias.
@ -119,12 +125,29 @@ class discussion_list extends db_table_vault {
$latestuserfields,
]);
$sortkeys = [
$this->get_sort_order(self::SORTORDER_REPLIES_DESC),
$this->get_sort_order(self::SORTORDER_REPLIES_ASC)
];
$issortbyreplies = in_array($sortsql, $sortkeys);
$tables = $thistable->get_from_sql();
$tables .= ' JOIN {user} fa ON fa.id = ' . $alias . '.userid';
$tables .= ' JOIN {user} la ON la.id = ' . $alias . '.usermodified';
$tables .= ' JOIN ' . $posttable->get_from_sql() . ' ON fp.id = ' . $alias . '.firstpost';
$tables .= isset($favsql) ? $favsql : '';
if ($issortbyreplies) {
// Join the discussion replies.
$tables .= ' JOIN (
SELECT rd.id, COUNT(rp.id) as replycount
FROM {forum_discussions} rd
LEFT JOIN {forum_posts} rp
ON rp.discussion = rd.id AND rp.id != rd.firstpost
GROUP BY rd.id
) r ON d.id = r.id';
}
$selectsql = 'SELECT ' . $fields . ' FROM ' . $tables;
$selectsql .= $wheresql ? ' WHERE ' . $wheresql : '';
$selectsql .= $sortsql ? ' ORDER BY ' . $sortsql : '';
@ -191,31 +214,64 @@ class discussion_list extends db_table_vault {
}, $results);
}
/**
* Get the field to sort by.
*
* @param int|null $sortmethod
* @return string
*/
protected function get_keyfield(?int $sortmethod) : string {
switch ($sortmethod) {
case self::SORTORDER_CREATED_DESC:
case self::SORTORDER_CREATED_ASC:
return 'fp.created';
case self::SORTORDER_REPLIES_DESC:
case self::SORTORDER_REPLIES_ASC:
return 'replycount';
default:
global $CFG;
$alias = $this->get_table_alias();
$field = "{$alias}.timemodified";
if (!empty($CFG->forum_enabletimedposts)) {
return "CASE WHEN {$field} < {$alias}.timestart THEN {$alias}.timestart ELSE {$field} END";
}
return $field;
}
}
/**
* Get the sort direction.
*
* @param int|null $sortmethod
* @return string
*/
protected function get_sort_direction(?int $sortmethod) : string {
switch ($sortmethod) {
case self::SORTORDER_LASTPOST_ASC:
case self::SORTORDER_CREATED_ASC:
case self::SORTORDER_REPLIES_ASC:
return "ASC";
case self::SORTORDER_LASTPOST_DESC:
case self::SORTORDER_CREATED_DESC:
case self::SORTORDER_REPLIES_DESC:
return "DESC";
default:
return "DESC";
}
}
/**
* Get the sort order SQL for a sort method.
*
* @param int|null $sortmethod
* @return string
*/
public function get_sort_order(?int $sortmethod, $includefavourites = true) : string {
global $CFG;
$alias = $this->get_table_alias();
if ($sortmethod == self::SORTORDER_CREATED_DESC) {
$keyfield = "fp.created";
$direction = "DESC";
} else {
$keyfield = "{$alias}.timemodified";
$direction = "DESC";
if ($sortmethod == self::SORTORDER_OLDEST_FIRST) {
$direction = "ASC";
}
if (!empty($CFG->forum_enabletimedposts)) {
$keyfield = "CASE WHEN {$keyfield} < {$alias}.timestart THEN {$alias}.timestart ELSE {$keyfield} END";
}
}
// TODO consider user favourites...
$keyfield = $this->get_keyfield($sortmethod);
$direction = $this->get_sort_direction($sortmethod);
$favouritesort = '';
if ($includefavourites) {

View File

@ -414,4 +414,31 @@ class post extends db_table_vault {
'params' => $params,
];
}
/**
* Get a mapping of the first post in each discussion based on post creation time.
*
* @param int[] $discussionids The list of discussions to fetch counts for
* @return stdClass[] The post object of the first post for each discussions returned in an associative array
*/
public function get_first_post_for_discussion_ids(array $discussionids) : array {
if (empty($discussionids)) {
return [];
}
list($insql, $params) = $this->get_db()->get_in_or_equal($discussionids, SQL_PARAMS_NAMED);
$sql = "
SELECT p.*
FROM {" . self::TABLE . "} p
JOIN (
SELECT mp.discussion, MIN(mp.created) AS created
FROM {" . self::TABLE . "} mp
WHERE mp.discussion {$insql}
GROUP BY mp.discussion
) lp ON lp.discussion = p.discussion AND lp.created = p.created";
return $this->get_db()->get_records_sql($sql, $params);
}
}

View File

@ -140,6 +140,8 @@ class provider implements
$items->add_user_preference('autosubscribe', 'privacy:metadata:preference:autosubscribe');
$items->add_user_preference('trackforums', 'privacy:metadata:preference:trackforums');
$items->add_user_preference('markasreadonnotification', 'privacy:metadata:preference:markasreadonnotification');
$items->add_user_preference('forum_discussionlistsortorder',
'privacy:metadata:preference:forum_discussionlistsortorder');
return $items;
}
@ -407,8 +409,42 @@ class provider implements
writer::export_user_preference('mod_forum', 'markasreadonnotification', $markasreadonnotification,
$markasreadonnotificationdescription);
}
$vaultfactory = \mod_forum\local\container::get_vault_factory();
$discussionlistvault = $vaultfactory->get_discussions_in_forum_vault();
$discussionlistsortorder = get_user_preferences('forum_discussionlistsortorder',
$discussionlistvault::SORTORDER_LASTPOST_DESC);
switch ($discussionlistsortorder) {
case $discussionlistvault::SORTORDER_LASTPOST_DESC:
$discussionlistsortorderdescription = get_string('discussionlistsortbylastpostdesc',
'mod_forum');
break;
case $discussionlistvault::SORTORDER_LASTPOST_ASC:
$discussionlistsortorderdescription = get_string('discussionlistsortbylastpostasc',
'mod_forum');
break;
case $discussionlistvault::SORTORDER_CREATED_DESC:
$discussionlistsortorderdescription = get_string('discussionlistsortbycreateddesc',
'mod_forum');
break;
case $discussionlistvault::SORTORDER_CREATED_ASC:
$discussionlistsortorderdescription = get_string('discussionlistsortbycreatedasc',
'mod_forum');
break;
case $discussionlistvault::SORTORDER_REPLIES_DESC:
$discussionlistsortorderdescription = get_string('discussionlistsortbyrepliesdesc',
'mod_forum');
break;
case $discussionlistvault::SORTORDER_REPLIES_ASC:
$discussionlistsortorderdescription = get_string('discussionlistsortbyrepliesasc',
'mod_forum');
break;
}
writer::export_user_preference('mod_forum', 'forum_discussionlistsortorder',
$discussionlistsortorder, $discussionlistsortorderdescription);
}
/**
* Export all user data for the specified user, in the specified contexts.
*

View File

@ -61,6 +61,17 @@ $functions = array(
'classname' => 'mod_forum_external',
'methodname' => 'get_forum_discussions_paginated',
'classpath' => 'mod/forum/externallib.php',
'description' => '** DEPRECATED ** Please do not call this function any more.
Returns a list of forum discussions optionally sorted and paginated.',
'type' => 'read',
'capabilities' => 'mod/forum:viewdiscussion, mod/forum:viewqandawithoutposting',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
'mod_forum_get_forum_discussions' => array(
'classname' => 'mod_forum_external',
'methodname' => 'get_forum_discussions',
'classpath' => 'mod/forum/externallib.php',
'description' => 'Returns a list of forum discussions optionally sorted and paginated.',
'type' => 'read',
'capabilities' => 'mod/forum:viewdiscussion, mod/forum:viewqandawithoutposting',

View File

@ -496,6 +496,7 @@ class mod_forum_external extends external_api {
/**
* Describes the parameters for get_forum_discussions_paginated.
*
* @deprecated since 3.7
* @return external_function_parameters
* @since Moodle 2.8
*/
@ -515,6 +516,7 @@ class mod_forum_external extends external_api {
/**
* Returns a list of forum discussions optionally sorted and paginated.
*
* @deprecated since 3.7
* @param int $forumid the forum instance id
* @param string $sortby sort by this element (id, timemodified, timestart or timeend)
* @param string $sortdirection sort direction: ASC or DESC
@ -525,7 +527,7 @@ class mod_forum_external extends external_api {
* @since Moodle 2.8
*/
public static function get_forum_discussions_paginated($forumid, $sortby = 'timemodified', $sortdirection = 'DESC',
$page = -1, $perpage = 0) {
$page = -1, $perpage = 0) {
global $CFG, $DB, $USER, $PAGE;
require_once($CFG->dirroot . "/mod/forum/lib.php");
@ -699,6 +701,7 @@ class mod_forum_external extends external_api {
/**
* Describes the get_forum_discussions_paginated return value.
*
* @deprecated since 3.7
* @return external_single_structure
* @since Moodle 2.8
*/
@ -750,6 +753,274 @@ class mod_forum_external extends external_api {
);
}
/**
* Describes the parameters for get_forum_discussions.
*
* @return external_function_parameters
* @since Moodle 3.7
*/
public static function get_forum_discussions_parameters() {
return new external_function_parameters (
array(
'forumid' => new external_value(PARAM_INT, 'forum instance id', VALUE_REQUIRED),
'sortorder' => new external_value(PARAM_INT,
'sort by this element: numreplies, , created or timemodified', VALUE_DEFAULT, -1),
'page' => new external_value(PARAM_INT, 'current page', VALUE_DEFAULT, -1),
'perpage' => new external_value(PARAM_INT, 'items per page', VALUE_DEFAULT, 0),
'groupid' => new external_value(PARAM_INT, 'group id', VALUE_DEFAULT, 0),
)
);
}
/**
* Returns a list of forum discussions optionally sorted and paginated.
*
* @param int $forumid the forum instance id
* @param int $sortorder The sort order
* @param int $page page number
* @param int $perpage items per page
* @param int $groupid the user course group
*
*
* @return array the forum discussion details including warnings
* @since Moodle 3.7
*/
public static function get_forum_discussions(int $forumid, ?int $sortorder = -1, ?int $page = -1,
?int $perpage = 0, ?int $groupid = 0) {
global $CFG, $DB, $USER;
require_once($CFG->dirroot . "/mod/forum/lib.php");
$warnings = array();
$discussions = array();
$params = self::validate_parameters(self::get_forum_discussions_parameters(),
array(
'forumid' => $forumid,
'sortorder' => $sortorder,
'page' => $page,
'perpage' => $perpage,
'groupid' => $groupid
)
);
// Compact/extract functions are not recommended.
$forumid = $params['forumid'];
$sortorder = $params['sortorder'];
$page = $params['page'];
$perpage = $params['perpage'];
$groupid = $params['groupid'];
$vaultfactory = \mod_forum\local\container::get_vault_factory();
$discussionlistvault = $vaultfactory->get_discussions_in_forum_vault();
$sortallowedvalues = array(
$discussionlistvault::SORTORDER_LASTPOST_DESC,
$discussionlistvault::SORTORDER_LASTPOST_ASC,
$discussionlistvault::SORTORDER_CREATED_DESC,
$discussionlistvault::SORTORDER_CREATED_ASC,
$discussionlistvault::SORTORDER_REPLIES_DESC,
$discussionlistvault::SORTORDER_REPLIES_ASC
);
// If sortorder not defined set a default one.
if ($sortorder == -1) {
$sortorder = $discussionlistvault::SORTORDER_LASTPOST_DESC;
}
if (!in_array($sortorder, $sortallowedvalues)) {
throw new invalid_parameter_exception('Invalid value for sortorder parameter (value: ' . $sortorder . '),' .
' allowed values are: ' . implode(',', $sortallowedvalues));
}
$managerfactory = \mod_forum\local\container::get_manager_factory();
$urlfactory = \mod_forum\local\container::get_url_factory();
$legacydatamapperfactory = mod_forum\local\container::get_legacy_data_mapper_factory();
$forumvault = $vaultfactory->get_forum_vault();
$forum = $forumvault->get_from_id($forumid);
$forumdatamapper = $legacydatamapperfactory->get_forum_data_mapper();
$forumrecord = $forumdatamapper->to_legacy_object($forum);
$capabilitymanager = $managerfactory->get_capability_manager($forum);
$course = $DB->get_record('course', array('id' => $forum->get_course_id()), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('forum', $forum->get_id(), $course->id, false, MUST_EXIST);
// Validate the module context. It checks everything that affects the module visibility (including groupings, etc..).
$modcontext = context_module::instance($cm->id);
self::validate_context($modcontext);
$canseeanyprivatereply = $capabilitymanager->can_view_any_private_reply($USER);
// Check they have the view forum capability.
if (!$capabilitymanager->can_view_discussions($USER)) {
throw new moodle_exception('noviewdiscussionspermission', 'forum');
}
$alldiscussions = get_discussions($forum, $USER, $groupid, $sortorder, $page, $perpage);
if ($alldiscussions) {
$discussionids = array_keys($alldiscussions);
$postvault = $vaultfactory->get_post_vault();
// Return the reply count for each discussion in a given forum.
$replies = $postvault->get_reply_count_for_discussion_ids($USER, $discussionids, $canseeanyprivatereply);
// Return the first post for each discussion in a given forum.
$firstposts = $postvault->get_first_post_for_discussion_ids($discussionids);
// Get the unreads array, this takes a forum id and returns data for all discussions.
$unreads = array();
if ($cantrack = forum_tp_can_track_forums($forumrecord)) {
if ($forumtracked = forum_tp_is_tracked($forumrecord)) {
$unreads = $postvault->get_unread_count_for_discussion_ids($USER, $discussionids, $canseeanyprivatereply);
}
}
$canlock = $capabilitymanager->can_manage_forum($USER);
foreach ($alldiscussions as $discussionsummary) {
$discussion = $discussionsummary->get_discussion();
$firstpostauthor = $discussionsummary->get_first_post_author();
$latestpostauthor = $discussionsummary->get_latest_post_author();
// This function checks for qanda forums.
$canviewdiscussion = $capabilitymanager->can_view_discussion($USER, $discussion);
if (!$canviewdiscussion) {
$warning = array();
// Function forum_get_discussions returns forum_posts ids not forum_discussions ones.
$warning['item'] = 'post';
$warning['itemid'] = $discussion->get_id();
$warning['warningcode'] = '1';
$warning['message'] = 'You can\'t see this discussion';
$warnings[] = $warning;
continue;
}
$discussionobject = $firstposts[$discussion->get_first_post_id()];
$discussionobject->groupid = $discussion->get_group_id();
$discussionobject->timemodified = $discussion->get_time_modified();
$discussionobject->usermodified = $discussion->get_user_modified();
$discussionobject->timestart = $discussion->get_time_start();
$discussionobject->timeend = $discussion->get_time_end();
$discussionobject->pinned = $discussion->is_pinned();
$discussionobject->numunread = 0;
if ($cantrack && $forumtracked) {
if (isset($unreads[$discussion->get_id()])) {
$discussionobject->numunread = (int) $unreads[$discussion->get_id()];
}
}
$discussionobject->numreplies = 0;
if (!empty($replies[$discussion->get_id()])) {
$discussionobject->numreplies = (int) $replies[$discussion->get_id()];
}
$discussionobject->name = external_format_string($discussion->get_name(), $modcontext->id);
$discussionobject->subject = external_format_string($discussionobject->subject, $modcontext->id);
// Rewrite embedded images URLs.
list($discussionobject->message, $discussionobject->messageformat) =
external_format_text($discussionobject->message, $discussionobject->messageformat,
$modcontext->id, 'mod_forum', 'post', $discussionobject->id);
// List attachments.
if (!empty($discussionobject->attachment)) {
$discussionobject->attachments = external_util::get_area_files($modcontext->id, 'mod_forum',
'attachment', $discussionobject->id);
}
$messageinlinefiles = external_util::get_area_files($modcontext->id, 'mod_forum', 'post',
$discussionobject->id);
if (!empty($messageinlinefiles)) {
$discussionobject->messageinlinefiles = $messageinlinefiles;
}
$discussionobject->locked = $forum->is_discussion_locked($discussion);
$discussionobject->canlock = $canlock;
$discussionobject->canreply = $capabilitymanager->can_post_in_discussion($USER, $discussion);
if (forum_is_author_hidden($discussionobject, $forumrecord)) {
$discussionobject->userid = null;
$discussionobject->userfullname = null;
$discussionobject->userpictureurl = null;
$discussionobject->usermodified = null;
$discussionobject->usermodifiedfullname = null;
$discussionobject->usermodifiedpictureurl = null;
} else {
$discussionobject->userfullname = $firstpostauthor->get_full_name();
$discussionobject->userpictureurl = $urlfactory->get_author_profile_image_url($firstpostauthor)
->out(false);
$discussionobject->usermodifiedfullname = $latestpostauthor->get_full_name();
$discussionobject->usermodifiedpictureurl = $urlfactory->get_author_profile_image_url($latestpostauthor)
->out(false);
}
$discussions[] = (array) $discussionobject;
}
}
$result = array();
$result['discussions'] = $discussions;
$result['warnings'] = $warnings;
return $result;
}
/**
* Describes the get_forum_discussions return value.
*
* @return external_single_structure
* @since Moodle 3.7
*/
public static function get_forum_discussions_returns() {
return new external_single_structure(
array(
'discussions' => new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_INT, 'Post id'),
'name' => new external_value(PARAM_TEXT, 'Discussion name'),
'groupid' => new external_value(PARAM_INT, 'Group id'),
'timemodified' => new external_value(PARAM_INT, 'Time modified'),
'usermodified' => new external_value(PARAM_INT, 'The id of the user who last modified'),
'timestart' => new external_value(PARAM_INT, 'Time discussion can start'),
'timeend' => new external_value(PARAM_INT, 'Time discussion ends'),
'discussion' => new external_value(PARAM_INT, 'Discussion id'),
'parent' => new external_value(PARAM_INT, 'Parent id'),
'userid' => new external_value(PARAM_INT, 'User who started the discussion id'),
'created' => new external_value(PARAM_INT, 'Creation time'),
'modified' => new external_value(PARAM_INT, 'Time modified'),
'mailed' => new external_value(PARAM_INT, 'Mailed?'),
'subject' => new external_value(PARAM_TEXT, 'The post subject'),
'message' => new external_value(PARAM_RAW, 'The post message'),
'messageformat' => new external_format_value('message'),
'messagetrust' => new external_value(PARAM_INT, 'Can we trust?'),
'messageinlinefiles' => new external_files('post message inline files', VALUE_OPTIONAL),
'attachment' => new external_value(PARAM_RAW, 'Has attachments?'),
'attachments' => new external_files('attachments', VALUE_OPTIONAL),
'totalscore' => new external_value(PARAM_INT, 'The post message total score'),
'mailnow' => new external_value(PARAM_INT, 'Mail now?'),
'userfullname' => new external_value(PARAM_TEXT, 'Post author full name'),
'usermodifiedfullname' => new external_value(PARAM_TEXT, 'Post modifier full name'),
'userpictureurl' => new external_value(PARAM_URL, 'Post author picture.'),
'usermodifiedpictureurl' => new external_value(PARAM_URL, 'Post modifier picture.'),
'numreplies' => new external_value(PARAM_INT, 'The number of replies in the discussion'),
'numunread' => new external_value(PARAM_INT, 'The number of unread discussions.'),
'pinned' => new external_value(PARAM_BOOL, 'Is the discussion pinned'),
'locked' => new external_value(PARAM_BOOL, 'Is the discussion locked'),
'canreply' => new external_value(PARAM_BOOL, 'Can the user reply to the discussion'),
'canlock' => new external_value(PARAM_BOOL, 'Can the user lock the discussion'),
), 'post'
)
),
'warnings' => new external_warnings()
)
);
}
/**
* Returns description of method parameters
*

View File

@ -131,6 +131,7 @@ $string['confirmunsubscribe'] = 'Do you really want to unsubscribe from forum \'
$string['couldnotadd'] = 'Could not add your post due to an unknown error';
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
$string['couldnotupdate'] = 'Could not update your post due to an unknown error';
$string['created'] = 'Created';
$string['crontask'] = 'Forum mailings and maintenance jobs';
$string['cutoffdate'] = 'Cut-off date';
$string['cutoffdate_help'] = 'If set, the forum will not accept posts after this date.';
@ -154,6 +155,12 @@ $string['disallowsubscription'] = 'Subscription';
$string['disallowsubscription_help'] = 'This forum has been configured so that you cannot subscribe to discussions.';
$string['disallowsubscribeteacher'] = 'Subscriptions not allowed (except for teachers)';
$string['discussion'] = 'Discussion';
$string['discussionlistsortbycreatedasc'] = 'Sort the discussions list by the creation date in ascending order';
$string['discussionlistsortbycreateddesc'] = 'Sort the discussions list by the creation date in descending order';
$string['discussionlistsortbylastpostdesc'] = 'Sort the discussions list by the creation date of the last post in descending order';
$string['discussionlistsortbylastpostasc'] = 'Sort the discussions list by the creation date of the last post in ascending order';
$string['discussionlistsortbyrepliesasc'] = 'Sort the discussions list by the number of replies in ascending order';
$string['discussionlistsortbyrepliesdesc'] = 'Sort the discussions list by the number of replies in descending order';
$string['discussionlocked'] = 'This discussion has been locked so you can no longer reply to it.';
$string['discussionlockingheader'] = 'Discussion locking';
$string['discussionlockingdisabled'] = 'Do not lock discussions';
@ -517,6 +524,7 @@ $string['privacy:metadata:forum_track_prefs'] = 'Information about which forums
$string['privacy:metadata:forum_track_prefs:forumid'] = 'The forum that has read tracking enabled.';
$string['privacy:metadata:forum_track_prefs:userid'] = 'The ID of the user that this forum tracking preference relates to.';
$string['privacy:metadata:preference:autosubscribe'] = 'Whether to subscribe to discussions when replying to posts within them.';
$string['privacy:metadata:preference:forum_discussionlistsortorder'] = 'The preferred sorting order of the discussions list';
$string['privacy:metadata:preference:maildigest'] = 'The site-wide mail digest preference';
$string['privacy:metadata:preference:markasreadonnotification'] = 'Whether to mark forum posts as read when receiving them as messages.';
$string['privacy:metadata:preference:trackforums'] = 'Whether to enable read tracking.';

View File

@ -6746,3 +6746,143 @@ function mod_forum_core_calendar_event_timestart_updated(\calendar_event $event,
}
}
}
/**
* Fetch the data used to display the discussions on the current page.
*
* @param \mod_forum\local\entities\forum $forum The forum entity
* @param stdClass $user The user to render for
* @param int[]|null $groupid The group to render
* @param int|null $sortorder The sort order to use when selecting the discussions in the list
* @param int|null $pageno The zero-indexed page number to use
* @param int|null $pagesize The number of discussions to show on the page
* @return stdClass The data to use for display
*/
function get_discussions(\mod_forum\local\entities\forum $forum, stdClass $user, ?int $groupid, ?int $sortorder,
?int $pageno = 0, ?int $pagesize = 0) {
$vaultfactory = mod_forum\local\container::get_vault_factory();
$discussionvault = $vaultfactory->get_discussions_in_forum_vault();
$managerfactory = mod_forum\local\container::get_manager_factory();
$capabilitymanager = $managerfactory->get_capability_manager($forum);
$groupids = get_groups_from_groupid($forum, $user, $groupid);
if (null === $groupids) {
return $discussions = $discussionvault->get_from_forum_id(
$forum->get_id(),
$capabilitymanager->can_view_hidden_posts($user),
$user->id,
$sortorder,
$pagesize,
$pageno * $pagesize);
} else {
return $discussions = $discussionvault->get_from_forum_id_and_group_id(
$forum->get_id(),
$groupids,
$capabilitymanager->can_view_hidden_posts($user),
$user->id,
$sortorder,
$pagesize,
$pageno * $pagesize);
}
}
/**
* Get a count of all discussions in a forum.
*
* @param \mod_forum\local\entities\forum $forum The forum entity
* @param stdClass $user The user to render for
* @param int $groupid The group to render
* @return int The number of discussions in a forum
*/
function get_count_all_discussions(\mod_forum\local\entities\forum $forum, stdClass $user, ?int $groupid) {
$managerfactory = mod_forum\local\container::get_manager_factory();
$capabilitymanager = $managerfactory->get_capability_manager($forum);
$vaultfactory = mod_forum\local\container::get_vault_factory();
$discussionvault = $vaultfactory->get_discussions_in_forum_vault();
$groupids = get_groups_from_groupid($forum, $user, $groupid);
if (null === $groupids) {
return $discussionvault->get_total_discussion_count_from_forum_id(
$forum->get_id(),
$capabilitymanager->can_view_hidden_posts($user),
$user->id);
} else {
return $discussionvault->get_total_discussion_count_from_forum_id_and_group_id(
$forum->get_id(),
$groupids,
$capabilitymanager->can_view_hidden_posts($user),
$user->id);
}
}
/**
* Get the list of groups to show based on the current user and requested groupid.
*
* @param \mod_forum\local\entities\forum $forum The forum entity
* @param stdClass $user The user viewing
* @param int $groupid The groupid requested
* @return array The list of groups to show
*/
function get_groups_from_groupid(\mod_forum\local\entities\forum $forum, stdClass $user, ?int $groupid) : ?array {
$effectivegroupmode = $forum->get_effective_group_mode();
if (empty($effectivegroupmode)) {
// This forum is not in a group mode. Show all posts always.
return null;
}
if (null == $groupid) {
$managerfactory = mod_forum\local\container::get_manager_factory();
$capabilitymanager = $managerfactory->get_capability_manager($forum);
// No group was specified.
$showallgroups = (VISIBLEGROUPS == $effectivegroupmode);
$showallgroups = $showallgroups || $capabilitymanager->can_access_all_groups($user);
if ($showallgroups) {
// Return null to show all groups.
return null;
} else {
// No group was specified. Only show the users current groups.
return array_keys(
groups_get_all_groups(
$forum->get_course_id(),
$user->id,
$forum->get_course_module_record()->groupingid
)
);
}
} else {
// A group was specified. Just show that group.
return [$groupid];
}
}
/**
* Return a list of all the user preferences used by mod_forum.
*
* @return array
*/
function mod_forum_user_preferences() {
$vaultfactory = \mod_forum\local\container::get_vault_factory();
$discussionlistvault = $vaultfactory->get_discussions_in_forum_vault();
$preferences = array();
$preferences['forum_discussionlistsortorder'] = array(
'null' => NULL_NOT_ALLOWED,
'default' => $discussionlistvault::SORTORDER_LASTPOST_DESC,
'type' => PARAM_INT,
'choices' => array(
$discussionlistvault::SORTORDER_LASTPOST_DESC,
$discussionlistvault::SORTORDER_LASTPOST_ASC,
$discussionlistvault::SORTORDER_CREATED_DESC,
$discussionlistvault::SORTORDER_CREATED_ASC,
$discussionlistvault::SORTORDER_REPLIES_DESC,
$discussionlistvault::SORTORDER_REPLIES_ASC
)
);
return $preferences;
}

View File

@ -68,7 +68,20 @@
<th scope="col" class="group">{{#str}}group{{/str}}</th>
{{/forum.state.groupmode}}
{{#forum.capabilities.viewdiscussions}}
<th scope="col" class="text-center">{{#str}}replies, mod_forum{{/str}}</th>
<th scope="col" class="text-center">
{{#state.sortorder.isrepliesdesc}}
<a href="{{{forum.urls.sortrepliesasc}}}" aria-label="{{#str}}discussionlistsortbyrepliesasc, mod_forum{{/str}}">{{#str}}replies, mod_forum{{/str}}</a> <span class="text-primary">{{#pix}}t/downlong, core, {{#str}}desc, core{{/str}}{{/pix}}</span>
{{/state.sortorder.isrepliesdesc}}
{{#state.sortorder.isrepliesasc}}
<a href="{{{forum.urls.sortrepliesdesc}}}" aria-label="{{#str}}discussionlistsortbyrepliesdesc, mod_forum{{/str}}">{{#str}}replies, mod_forum{{/str}}</a> <span class="text-primary">{{#pix}}t/uplong, core, {{#str}}asc, core{{/str}}{{/pix}}</span>
{{/state.sortorder.isrepliesasc}}
{{^state.sortorder.isrepliesdesc}}
{{^state.sortorder.isrepliesasc}}
<a href="{{{forum.urls.sortrepliesdesc}}}" aria-label="{{#str}}discussionlistsortbyrepliesdesc, mod_forum{{/str}}">{{#str}}replies, mod_forum{{/str}}</a>
{{/state.sortorder.isrepliesasc}}
{{/state.sortorder.isrepliesdesc}}
</th>
{{#forum.userstate.tracked}}
<th scope="col" class="text-center">
{{#str}}unread, mod_forum{{/str}}
@ -76,7 +89,32 @@
</th>
{{/forum.userstate.tracked}}
{{/forum.capabilities.viewdiscussions}}
<th scope="col" class="lastpost">{{#str}}lastpost, mod_forum{{/str}}</th>
<th scope="col" class="lastpost">
{{#state.sortorder.islastpostdesc}}
<a href="{{{forum.urls.sortlastpostasc}}}" aria-label="{{#str}}discussionlistsortbylastpostasc, mod_forum{{/str}}">{{#str}}lastpost, mod_forum{{/str}}</a> <span class="text-primary">{{#pix}}t/downlong, core, {{#str}}desc, core{{/str}}{{/pix}}</span>
{{/state.sortorder.islastpostdesc}}
{{#state.sortorder.islastpostasc}}
<a href="{{{forum.urls.sortlastpostdesc}}}" aria-label="{{#str}}discussionlistsortbylastpostdesc, mod_forum{{/str}}">{{#str}}lastpost, mod_forum{{/str}}</a> <span class="text-primary">{{#pix}}t/uplong, core, {{#str}}asc, core{{/str}}{{/pix}}</span>
{{/state.sortorder.islastpostasc}}
{{^state.sortorder.islastpostdesc}}
{{^state.sortorder.islastpostasc}}
<a href="{{{forum.urls.sortlastpostdesc}}}" aria-label="{{#str}}discussionlistsortbylastpostdesc, mod_forum{{/str}}">{{#str}}lastpost, mod_forum{{/str}}</a>
{{/state.sortorder.islastpostasc}}
{{/state.sortorder.islastpostdesc}}
</th>
<th scope="col" class="created">
{{#state.sortorder.iscreateddesc}}
<a href="{{{forum.urls.sortcreatedasc}}}" aria-label="{{#str}}discussionlistsortbycreatedasc, mod_forum{{/str}}">{{#str}}created, mod_forum{{/str}}</a> <span class="text-primary">{{#pix}}t/downlong, core, {{#str}}desc, core{{/str}}{{/pix}}</span>
{{/state.sortorder.iscreateddesc}}
{{#state.sortorder.iscreatedasc}}
<a href="{{{forum.urls.sortcreateddesc}}}" aria-label="{{#str}}discussionlistsortbycreateddesc, mod_forum{{/str}}">{{#str}}created, mod_forum{{/str}}</a> <span class="text-primary">{{#pix}}t/uplong, core, {{#str}}asc, core{{/str}}{{/pix}}</span>
{{/state.sortorder.iscreatedasc}}
{{^state.sortorder.iscreateddesc}}
{{^state.sortorder.iscreatedasc}}
<a href="{{{forum.urls.sortcreateddesc}}}" aria-label="{{#str}}discussionlistsortbycreateddesc, mod_forum{{/str}}">{{#str}}created, mod_forum{{/str}}</a>
{{/state.sortorder.iscreatedasc}}
{{/state.sortorder.iscreateddesc}}
</th>
<th scope="col">&nbsp;</th>
{{#forum.capabilities.subscribe}}
<th scope="col" class="discussionsubscription"></th>
@ -195,6 +233,9 @@
</div>
{{/latestpostid}}
</td>
<td scope="col" class="text-left align-middle">
{{#userdate}}{{discussion.times.created}}, {{#str}}strftimerecentfull{{/str}}{{/userdate}}
</td>
<td scope="col" class="timed p-0 text-center align-middle">
{{#discussion.timed.istimed}}
<div class="timedpost">

View File

@ -11,6 +11,9 @@ information provided here is intended especially for developers.
the Post vault.
* External function get_forums_by_courses now returns two additional fields "duedate" and "cutoffdate" containing the due date and the cutoff date for posting to the forums respectively.
* External function get_forum_discussion_posts now returns an additional field "tags" returning the post tags.
* New external function mod_forum_external::get_forum_discussions returns a list of forum discussions optionally sorted and paginated.
* External function mod_forum_external::get_forum_discussions_paginated has been deprecated.
Use mod_forum_external::get_forum_discussions instead.
=== 3.6 ===

View File

@ -30,6 +30,7 @@ $vaultfactory = mod_forum\local\container::get_vault_factory();
$forumvault = $vaultfactory->get_forum_vault();
$discussionvault = $vaultfactory->get_discussion_vault();
$postvault = $vaultfactory->get_post_vault();
$discussionlistvault = $vaultfactory->get_discussions_in_forum_vault();
$cmid = optional_param('id', 0, PARAM_INT);
$forumid = optional_param('f', 0, PARAM_INT);
@ -134,6 +135,12 @@ if ($mode) {
$displaymode = get_user_preferences('forum_displaymode', $CFG->forum_displaymode);
if ($sortorder) {
set_user_preference('forum_discussionlistsortorder', $sortorder);
}
$sortorder = get_user_preferences('forum_discussionlistsortorder', $discussionlistvault::SORTORDER_LASTPOST_DESC);
// Fetch the current groupid.
$groupid = groups_get_activity_group($cm, true) ?: null;
$rendererfactory = mod_forum\local\container::get_renderer_factory();
@ -141,7 +148,7 @@ switch ($forum->get_type()) {
case 'single':
$discussion = $discussionvault->get_last_discussion_in_forum($forum);
$discussioncount = $discussionvault->get_count_discussions_in_forum($forum);
$hasmultiplediscussions = $discussioncount > 1 ? true : false;
$hasmultiplediscussions = $discussioncount > 1;
$discussionsrenderer = $rendererfactory->get_single_discussion_list_renderer($forum, $discussion,
$hasmultiplediscussions, $displaymode);
$post = $postvault->get_from_id($discussion->get_first_post_id());
@ -156,9 +163,9 @@ switch ($forum->get_type()) {
break;
case 'blog':
$discussionsrenderer = $rendererfactory->get_blog_discussion_list_renderer($forum);
$discussionlistvault = $vaultfactory->get_discussions_in_forum_vault();
// Blog forums always show discussions newest first.
echo $discussionsrenderer->render($USER, $cm, $groupid, $discussionlistvault::SORTORDER_CREATED_DESC, $pageno, $pagesize);
echo $discussionsrenderer->render($USER, $cm, $groupid, $discussionlistvault::SORTORDER_CREATED_DESC,
$pageno, $pagesize);
break;
default:
$discussionsrenderer = $rendererfactory->get_discussion_list_renderer($forum);