original_string: public function build(
          stdClass $user,
          array $forums,
          array $discussions,
          array $posts
      ) : array {
          // Format the forums and discussion to make them more easily accessed later.
          $forums = array_reduce($forums, function($carry, $forum) {
              $carry[$forum->get_id()] = $forum;
              return $carry;
          }, []);
          $discussions = array_reduce($discussions, function($carry, $discussion) {
              $carry[$discussion->get_id()] = $discussion;
              return $carry;
          }, []);
  
          // Group the posts by discussion and forum so that we can load the resources in
          // batches to improve performance.
          $groupedposts = $this->group_posts_by_discussion($forums, $discussions, $posts);
          // Load all of the resources we need in order to export the posts.
          $authorsbyid = $this->get_authors_for_posts($posts);
          $authorcontextids = $this->get_author_context_ids(array_keys($authorsbyid));
          $attachmentsbypostid = $this->get_attachments_for_posts($groupedposts);
          $groupsbycourseandauthorid = $this->get_author_groups_from_posts($groupedposts);
          $tagsbypostid = $this->get_tags_from_posts($posts);
          $ratingbypostid = $this->get_ratings_from_posts($user, $groupedposts);
          $readreceiptcollectionbyforumid = $this->get_read_receipts_from_posts($user, $groupedposts);
          $exportedposts = [];
  
          // Export each set of posts per discussion because it's the largest chunks we can
          // break them into due to constraints on capability checks.
          foreach ($groupedposts as $grouping) {
              [
                  'forum' => $forum,
                  'discussion' => $discussion,
                  'posts' => $groupedposts
              ] = $grouping;
  
              $forumid = $forum->get_id();
              $courseid = $forum->get_course_record()->id;
              $postsexporter = $this->exporterfactory->get_posts_exporter(
                  $user,
                  $forum,
                  $discussion,
                  $groupedposts,
                  $authorsbyid,
                  $authorcontextids,
                  $attachmentsbypostid,
                  $groupsbycourseandauthorid[$courseid],
                  $readreceiptcollectionbyforumid[$forumid] ?? null,
                  $tagsbypostid,
                  $ratingbypostid,
                  true
              );
              ['posts' => $exportedgroupedposts] = (array) $postsexporter->export($this->renderer);
              $exportedposts = array_merge($exportedposts, $exportedgroupedposts);
          }
  
          if (count($forums) == 1 && count($discussions) == 1) {
              // All of the posts belong to a single discussion in a single forum so
              // the exported order will match the given $posts array.
              return $exportedposts;
          } else {
              // Since we grouped the posts by discussion and forum the ordering of the
              // exported posts may be different to the given $posts array so we should
              // sort it back into the correct order for the caller.
              return $this->sort_exported_posts($posts, $exportedposts);
          }
      }
code: public function build(
          stdClass $user,
          array $forums,
          array $discussions,
          array $posts
      ) : array {
          // Format the forums and discussion to make them more easily accessed later.
          $forums = array_reduce($forums, function($carry, $forum) {
              $carry[$forum->get_id()] = $forum;
              return $carry;
          }, []);
          $discussions = array_reduce($discussions, function($carry, $discussion) {
              $carry[$discussion->get_id()] = $discussion;
              return $carry;
          }, []);
  
          // Group the posts by discussion and forum so that we can load the resources in
          // batches to improve performance.
          $groupedposts = $this->group_posts_by_discussion($forums, $discussions, $posts);
          // Load all of the resources we need in order to export the posts.
          $authorsbyid = $this->get_authors_for_posts($posts);
          $authorcontextids = $this->get_author_context_ids(array_keys($authorsbyid));
          $attachmentsbypostid = $this->get_attachments_for_posts($groupedposts);
          $groupsbycourseandauthorid = $this->get_author_groups_from_posts($groupedposts);
          $tagsbypostid = $this->get_tags_from_posts($posts);
          $ratingbypostid = $this->get_ratings_from_posts($user, $groupedposts);
          $readreceiptcollectionbyforumid = $this->get_read_receipts_from_posts($user, $groupedposts);
          $exportedposts = [];
  
          // Export each set of posts per discussion because it's the largest chunks we can
          // break them into due to constraints on capability checks.
          foreach ($groupedposts as $grouping) {
              [
                  'forum' => $forum,
                  'discussion' => $discussion,
                  'posts' => $groupedposts
              ] = $grouping;
  
              $forumid = $forum->get_id();
              $courseid = $forum->get_course_record()->id;
              $postsexporter = $this->exporterfactory->get_posts_exporter(
                  $user,
                  $forum,
                  $discussion,
                  $groupedposts,
                  $authorsbyid,
                  $authorcontextids,
                  $attachmentsbypostid,
                  $groupsbycourseandauthorid[$courseid],
                  $readreceiptcollectionbyforumid[$forumid] ?? null,
                  $tagsbypostid,
                  $ratingbypostid,
                  true
              );
              ['posts' => $exportedgroupedposts] = (array) $postsexporter->export($this->renderer);
              $exportedposts = array_merge($exportedposts, $exportedgroupedposts);
          }
  
          if (count($forums) == 1 && count($discussions) == 1) {
              // All of the posts belong to a single discussion in a single forum so
              // the exported order will match the given $posts array.
              return $exportedposts;
          } else {
              // Since we grouped the posts by discussion and forum the ordering of the
              // exported posts may be different to the given $posts array so we should
              // sort it back into the correct order for the caller.
              return $this->sort_exported_posts($posts, $exportedposts);
          }
      }
code_tokens: public function build ( stdClass $ user , array $ forums , array $ discussions , array $ posts ) : array { // Format the forums and discussion to make them more easily accessed later. $ forums = array_reduce ( $ forums , function ( $ carry , $ forum ) { $ carry [ $ forum -> get_id ( ) ] = $ forum ; return $ carry ; } , [ ] ) ; $ discussions = array_reduce ( $ discussions , function ( $ carry , $ discussion ) { $ carry [ $ discussion -> get_id ( ) ] = $ discussion ; return $ carry ; } , [ ] ) ; // Group the posts by discussion and forum so that we can load the resources in // batches to improve performance. $ groupedposts = $ this -> group_posts_by_discussion ( $ forums , $ discussions , $ posts ) ; // Load all of the resources we need in order to export the posts. $ authorsbyid = $ this -> get_authors_for_posts ( $ posts ) ; $ authorcontextids = $ this -> get_author_context_ids ( array_keys ( $ authorsbyid ) ) ; $ attachmentsbypostid = $ this -> get_attachments_for_posts ( $ groupedposts ) ; $ groupsbycourseandauthorid = $ this -> get_author_groups_from_posts ( $ groupedposts ) ; $ tagsbypostid = $ this -> get_tags_from_posts ( $ posts ) ; $ ratingbypostid = $ this -> get_ratings_from_posts ( $ user , $ groupedposts ) ; $ readreceiptcollectionbyforumid = $ this -> get_read_receipts_from_posts ( $ user , $ groupedposts ) ; $ exportedposts = [ ] ; // Export each set of posts per discussion because it's the largest chunks we can // break them into due to constraints on capability checks. foreach ( $ groupedposts as $ grouping ) { [ 'forum' => $ forum , 'discussion' => $ discussion , 'posts' => $ groupedposts ] = $ grouping ; $ forumid = $ forum -> get_id ( ) ; $ courseid = $ forum -> get_course_record ( ) -> id ; $ postsexporter = $ this -> exporterfactory -> get_posts_exporter ( $ user , $ forum , $ discussion , $ groupedposts , $ authorsbyid , $ authorcontextids , $ attachmentsbypostid , $ groupsbycourseandauthorid [ $ courseid ] , $ readreceiptcollectionbyforumid [ $ forumid ] ?? null , $ tagsbypostid , $ ratingbypostid , true ) ; [ 'posts' => $ exportedgroupedposts ] = ( array ) $ postsexporter -> export ( $ this -> renderer ) ; $ exportedposts = array_merge ( $ exportedposts , $ exportedgroupedposts ) ; } if ( count ( $ forums ) == 1 && count ( $ discussions ) == 1 ) { // All of the posts belong to a single discussion in a single forum so // the exported order will match the given $posts array. return $ exportedposts ; } else { // Since we grouped the posts by discussion and forum the ordering of the // exported posts may be different to the given $posts array so we should // sort it back into the correct order for the caller. return $ this -> sort_exported_posts ( $ posts , $ exportedposts ) ; } }
docstring: Build the exported posts for a given set of forums, discussions, and posts.
  
  This will typically be used for a list of posts in the same discussion/forum however
  it does support exporting any arbitrary list of posts as long as the caller also provides
  a unique list of all discussions for the list of posts and all forums for the list of discussions.
  
  Increasing the number of different forums being processed will increase the processing time
  due to processing multiple contexts (for things like capabilities, files, etc). The code attempts
  to load the additional resources as efficiently as possible but there is no way around some of
  the additional overhead.
  
  Note: Some posts will be removed as part of the build process according to capabilities.
  A one-to-one mapping should not be expected.
  
  @param stdClass $user The user to export the posts for.
  @param forum_entity[] $forums A list of all forums that each of the $discussions belong to
  @param discussion_entity[] $discussions A list of all discussions that each of the $posts belong to
  @param post_entity[] $posts The list of posts to export.
  @return stdClass[] List of exported posts in the same order as the $posts array.
docstring_tokens: Build the exported posts for a given set of forums discussions and posts .