AutorÃa | Ultima modificación | Ver Log |
<?php// 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/>./*** Exported discussion summaries builder class.** @package mod_forum* @copyright 2019 Mihail Geshoski <mihail@moodle.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/namespace mod_forum\local\builders;defined('MOODLE_INTERNAL') || die();use mod_forum\local\entities\discussion as discussion_entity;use mod_forum\local\entities\forum as forum_entity;use mod_forum\local\entities\post as post_entity;use mod_forum\local\factories\legacy_data_mapper as legacy_data_mapper_factory;use mod_forum\local\factories\exporter as exporter_factory;use mod_forum\local\factories\vault as vault_factory;use mod_forum\local\factories\manager as manager_factory;use rating_manager;use renderer_base;use stdClass;/*** Exported discussion summaries builder class.** This class is an implementation of the builder pattern (loosely). It is responsible* for taking a set of related forums, discussions, and posts and generate the exported* version of the discussion summaries.** It encapsulates the complexity involved with exporting discussions summaries. All of the relevant* additional resources will be loaded by this class in order to ensure the exporting* process can happen.** See this doc for more information on the builder pattern:* https://designpatternsphp.readthedocs.io/en/latest/Creational/Builder/README.html** @package mod_forum* @copyright 2019 Mihail Geshoski <mihail@moodle.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class exported_discussion_summaries {/** @var renderer_base $renderer Core renderer */private $renderer;/** @var legacy_data_mapper_factory $legacydatamapperfactory Data mapper factory */private $legacydatamapperfactory;/** @var exporter_factory $exporterfactory Exporter factory */private $exporterfactory;/** @var vault_factory $vaultfactory Vault factory */private $vaultfactory;/** @var manager_factory $managerfactory Manager factory */private $managerfactory;/** @var rating_manager $ratingmanager Rating manager */private $ratingmanager;/*** Constructor.** @param renderer_base $renderer Core renderer* @param legacy_data_mapper_factory $legacydatamapperfactory Legacy data mapper factory* @param exporter_factory $exporterfactory Exporter factory* @param vault_factory $vaultfactory Vault factory* @param manager_factory $managerfactory Manager factory*/public function __construct(renderer_base $renderer,legacy_data_mapper_factory $legacydatamapperfactory,exporter_factory $exporterfactory,vault_factory $vaultfactory,manager_factory $managerfactory) {$this->renderer = $renderer;$this->legacydatamapperfactory = $legacydatamapperfactory;$this->exporterfactory = $exporterfactory;$this->vaultfactory = $vaultfactory;$this->managerfactory = $managerfactory;$this->ratingmanager = $managerfactory->get_rating_manager();}/*** Build the exported discussion summaries for a given set of discussions.** This will typically be used for a list of discussions in the same forum.** @param stdClass $user The user to export the posts for.* @param forum_entity $forum The forum that each of the $discussions belong to* @param discussion_summary_entity[] $discussions A list of all discussion summaries to export* @return stdClass[] List of exported posts in the same order as the $posts array.*/public function build(stdClass $user,forum_entity $forum,array $discussions): array {$capabilitymanager = $this->managerfactory->get_capability_manager($forum);$canseeanyprivatereply = $capabilitymanager->can_view_any_private_reply($user);$discussionids = array_keys($discussions);$postvault = $this->vaultfactory->get_post_vault();$posts = $postvault->get_from_discussion_ids($user, $discussionids, $canseeanyprivatereply);$groupsbyid = $this->get_groups_available_in_forum($forum);$groupsbyauthorid = $this->get_author_groups_from_posts($posts, $forum);$replycounts = $postvault->get_reply_count_for_discussion_ids($user, $discussionids, $canseeanyprivatereply);$latestposts = $postvault->get_latest_posts_for_discussion_ids($user, $discussionids, $canseeanyprivatereply);$latestauthors = $this->get_latest_posts_authors($latestposts);$latestpostsids = array_map(function($post) {return $post->get_id();}, $latestposts);$postauthorids = array_unique(array_reduce($discussions, function($carry, $summary) use ($latestposts){$firstpostauthorid = $summary->get_first_post_author()->get_id();$discussion = $summary->get_discussion();$lastpostauthorid = $latestposts[$discussion->get_id()]->get_author_id();return array_merge($carry, [$firstpostauthorid, $lastpostauthorid]);}, []));$postauthorcontextids = $this->get_author_context_ids($postauthorids);$unreadcounts = [];$favourites = $this->get_favourites($user);$forumdatamapper = $this->legacydatamapperfactory->get_forum_data_mapper();$forumrecord = $forumdatamapper->to_legacy_object($forum);if (forum_tp_can_track_forums($forumrecord)) {$unreadcounts = $postvault->get_unread_count_for_discussion_ids($user, $discussionids, $canseeanyprivatereply);}$summaryexporter = $this->exporterfactory->get_discussion_summaries_exporter($user,$forum,$discussions,$groupsbyid,$groupsbyauthorid,$replycounts,$unreadcounts,$latestpostsids,$postauthorcontextids,$favourites,$latestauthors);$exportedposts = (array) $summaryexporter->export($this->renderer);$firstposts = $postvault->get_first_post_for_discussion_ids($discussionids);array_walk($exportedposts['summaries'], function($summary) use ($firstposts, $latestposts) {$summary->discussion->times['created'] = (int) $firstposts[$summary->discussion->firstpostid]->get_time_created();$summary->discussion->times['modified'] = (int) $latestposts[$summary->discussion->id]->get_time_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,'isdiscussiondesc' => $sortorder == $discussionlistvault::SORTORDER_DISCUSSION_DESC,'isdiscussionasc' => $sortorder == $discussionlistvault::SORTORDER_DISCUSSION_ASC,'isstarterdesc' => $sortorder == $discussionlistvault::SORTORDER_STARTER_DESC,'isstarterasc' => $sortorder == $discussionlistvault::SORTORDER_STARTER_ASC,'isgroupdesc' => $sortorder == $discussionlistvault::SORTORDER_GROUP_DESC,'isgroupasc' => $sortorder == $discussionlistvault::SORTORDER_GROUP_ASC,);$exportedposts['state']['sortorder'] = $sortoptions;return $exportedposts;}/*** Get a list of all favourited discussions.** @param stdClass $user The user we are getting favourites for* @return int[] A list of favourited itemids*/private function get_favourites(stdClass $user): array {$ids = [];if (isloggedin()) {$usercontext = \context_user::instance($user->id);$ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);$favourites = $ufservice->find_favourites_by_type('mod_forum', 'discussions');foreach ($favourites as $favourite) {$ids[] = $favourite->itemid;}}return $ids;}/*** Returns a mapped array of discussionid to the authors of the latest post** @param array $latestposts Mapped array of discussion to latest posts.* @return array Array of authors mapped to the discussion*/private function get_latest_posts_authors($latestposts) {$authors = $this->vaultfactory->get_author_vault()->get_authors_for_posts($latestposts);$mappedauthors = array_reduce($latestposts, function($carry, $item) use ($authors) {$carry[$item->get_discussion_id()] = $authors[$item->get_author_id()];return $carry;}, []);return $mappedauthors;}/*** Get the groups details for all groups available to the forum.* @param forum_entity $forum The forum entity* @return stdClass[]*/private function get_groups_available_in_forum($forum): array {$course = $forum->get_course_record();$coursemodule = $forum->get_course_module_record();return groups_get_all_groups($course->id, 0, $coursemodule->groupingid);}/*** Get the author's groups for a list of posts.** @param post_entity[] $posts The list of posts* @param forum_entity $forum The forum entity* @return array Author groups indexed by author id*/private function get_author_groups_from_posts(array $posts, $forum): array {$course = $forum->get_course_record();$coursemodule = $forum->get_course_module_record();$authorids = array_reduce($posts, function($carry, $post) {$carry[$post->get_author_id()] = true;return $carry;}, []);$authorgroups = groups_get_all_groups($course->id, array_keys($authorids), $coursemodule->groupingid,'g.*, gm.id, gm.groupid, gm.userid');$authorgroups = array_reduce($authorgroups, function($carry, $group) {// Clean up data returned from groups_get_all_groups.$userid = $group->userid;$groupid = $group->groupid;unset($group->userid);unset($group->groupid);$group->id = $groupid;if (!isset($carry[$userid])) {$carry[$userid] = [$group];} else {$carry[$userid][] = $group;}return $carry;}, []);foreach (array_diff(array_keys($authorids), array_keys($authorgroups)) as $authorid) {$authorgroups[$authorid] = [];}return $authorgroups;}/*** Get the user context ids for each of the authors.** @param int[] $authorids The list of author ids to fetch context ids for.* @return int[] Context ids indexed by author id*/private function get_author_context_ids(array $authorids): array {$authorvault = $this->vaultfactory->get_author_vault();return $authorvault->get_context_ids_for_author_ids($authorids);}}