Skip to content

Commit

Permalink
MDL-65071 forum: Add sorting in discussion list
Browse files Browse the repository at this point in the history
  • Loading branch information
Mihail Geshoski committed May 1, 2019
1 parent 3f9ed16 commit 1a9c60e
Show file tree
Hide file tree
Showing 19 changed files with 724 additions and 140 deletions.
2 changes: 2 additions & 0 deletions lib/classes/output/icon_system_fontawesome.php
Expand Up @@ -349,6 +349,7 @@ public function get_core_icon_map() {
'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',
Expand Down Expand Up @@ -402,6 +403,7 @@ public function get_core_icon_map() {
'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',
];
Expand Down
Expand Up @@ -147,7 +147,30 @@ public function build(
$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;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion mod/forum/classes/local/container.php
Expand Up @@ -83,7 +83,8 @@ public static function get_exporter_factory() : exporter_factory {
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()
);
}

Expand Down
2 changes: 2 additions & 0 deletions mod/forum/classes/local/exporters/discussion.php
Expand Up @@ -67,6 +67,7 @@ protected static function define_other_properties() {
'locked' => ['type' => PARAM_BOOL],
'istimelocked' => ['type' => PARAM_BOOL],
'name' => ['type' => PARAM_TEXT],
'firstpostid' => ['type' => PARAM_INT],
'group' => [
'optional' => true,
'type' => [
Expand Down Expand Up @@ -195,6 +196,7 @@ protected function get_other_values(renderer_base $output) {
'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(),
Expand Down
21 changes: 21 additions & 0 deletions mod/forum/classes/local/exporters/forum.php
Expand Up @@ -83,6 +83,12 @@ protected static function define_other_properties() {
'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],
],
],
];
Expand All @@ -99,6 +105,8 @@ protected function get_other_values(renderer_base $output) {
$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(),
Expand All @@ -117,6 +125,18 @@ protected function get_other_values(renderer_base $output) {
'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)
],
];
}
Expand All @@ -133,6 +153,7 @@ protected static function define_related() {
'urlfactory' => 'mod_forum\local\factories\url',
'user' => 'stdClass',
'currentgroup' => 'int?',
'vaultfactory' => 'mod_forum\local\factories\vault'
];
}

Expand Down
14 changes: 9 additions & 5 deletions mod/forum/classes/local/factories/exporter.php
Expand Up @@ -33,6 +33,7 @@
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;
Expand Down Expand Up @@ -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;
}

/**
Expand All @@ -97,6 +100,7 @@ public function get_forum_exporter(
'urlfactory' => $this->urlfactory,
'user' => $user,
'currentgroup' => $currentgroup,
'vaultfactory' => $this->vaultfactory,
]);
}

Expand Down
18 changes: 14 additions & 4 deletions mod/forum/classes/local/factories/url.php
Expand Up @@ -95,26 +95,36 @@ public function get_discussion_create_url(forum_entity $forum) : moodle_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);
}

/**
* Get the view forum url for the given course module id and optionally a page number.
*
* @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;
Expand Down
18 changes: 17 additions & 1 deletion mod/forum/classes/local/managers/capability.php
Expand Up @@ -328,11 +328,27 @@ public function can_post_in_discussion(stdClass $user, discussion_entity $discus
* @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?
*
Expand Down
111 changes: 8 additions & 103 deletions mod/forum/classes/local/renderers/discussion_list.php
Expand Up @@ -145,21 +145,20 @@ public function render(stdClass $user, \cm_info $cm, ?int $groupid, ?int $sortor

$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),
Expand All @@ -186,10 +185,12 @@ public function render(stdClass $user, \cm_info $cm, ?int $groupid, ?int $sortor
$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
);
Expand Down Expand Up @@ -256,102 +257,6 @@ private function get_discussion_form(stdClass $user, \cm_info $cm, ?int $groupid
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.
*
Expand Down

0 comments on commit 1a9c60e

Please sign in to comment.