diff --git a/mod/forum/classes/local/builders/exported_posts.php b/mod/forum/classes/local/builders/exported_posts.php index ab459e85ad1..7f092e3bf5d 100644 --- a/mod/forum/classes/local/builders/exported_posts.php +++ b/mod/forum/classes/local/builders/exported_posts.php @@ -117,13 +117,15 @@ class exported_posts { * @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. + * @param bool $includeinlineattachments Whether inline attachments should be included or not. * @return stdClass[] List of exported posts in the same order as the $posts array. */ public function build( stdClass $user, array $forums, array $discussions, - array $posts + array $posts, + bool $includeinlineattachments = false ) : array { // Format the forums and discussion to make them more easily accessed later. $forums = array_reduce($forums, function($carry, $forum) { @@ -142,7 +144,10 @@ class exported_posts { $authorsbyid = $this->get_authors_for_posts($posts); $authorcontextids = $this->get_author_context_ids(array_keys($authorsbyid)); $attachmentsbypostid = $this->get_attachments_for_posts($groupedposts); - $inlineattachments = $this->get_inline_attachments_for_posts($groupedposts); + $inlineattachments = []; + if ($includeinlineattachments) { + $inlineattachments = $this->get_inline_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); diff --git a/mod/forum/classes/local/exporters/post.php b/mod/forum/classes/local/exporters/post.php index 6e821377c25..7137510e4e8 100644 --- a/mod/forum/classes/local/exporters/post.php +++ b/mod/forum/classes/local/exporters/post.php @@ -274,6 +274,7 @@ class post extends exporter { 'type' => $attachmentdefinition ], 'messageinlinefiles' => [ + 'optional' => true, 'multiple' => true, 'type' => stored_file_exporter::read_properties_definition(), ], diff --git a/mod/forum/externallib.php b/mod/forum/externallib.php index 222612d84de..1f7e6157b5c 100644 --- a/mod/forum/externallib.php +++ b/mod/forum/externallib.php @@ -170,9 +170,10 @@ class mod_forum_external extends external_api { * @param int $discussionid * @param string $sortby * @param string $sortdirection + * @param bool $includeinlineattachments Whether inline attachments should be included or not. * @return array */ - public static function get_discussion_posts(int $discussionid, ?string $sortby, ?string $sortdirection) { + public static function get_discussion_posts(int $discussionid, ?string $sortby, ?string $sortdirection, bool $includeinlineattachments = false) { global $USER; // Validate the parameter. $params = self::validate_parameters(self::get_discussion_posts_parameters(), [ @@ -225,7 +226,7 @@ class mod_forum_external extends external_api { $legacydatamapper = mod_forum\local\container::get_legacy_data_mapper_factory(); return [ - 'posts' => $postbuilder->build($USER, [$forum], [$discussion], $posts), + 'posts' => $postbuilder->build($USER, [$forum], [$discussion], $posts, $includeinlineattachments), 'forumid' => $discussion->get_forum_id(), 'courseid' => $discussion->get_course_id(), 'ratinginfo' => \core_rating\external\util::get_rating_info( @@ -248,7 +249,9 @@ class mod_forum_external extends external_api { return new external_function_parameters ([ 'discussionid' => new external_value(PARAM_INT, 'The ID of the discussion from which to fetch posts.', VALUE_REQUIRED), 'sortby' => new external_value(PARAM_ALPHA, 'Sort by this element: id, created or modified', VALUE_DEFAULT, 'created'), - 'sortdirection' => new external_value(PARAM_ALPHA, 'Sort direction: ASC or DESC', VALUE_DEFAULT, 'DESC') + 'sortdirection' => new external_value(PARAM_ALPHA, 'Sort direction: ASC or DESC', VALUE_DEFAULT, 'DESC'), + 'includeinlineattachments' => new external_value(PARAM_BOOL, 'Whether inline attachments should be included or not', VALUE_DEFAULT, + false), ]); } diff --git a/mod/forum/tests/externallib_test.php b/mod/forum/tests/externallib_test.php index 5f0da6d5e4e..69fcb1e4805 100644 --- a/mod/forum/tests/externallib_test.php +++ b/mod/forum/tests/externallib_test.php @@ -593,7 +593,7 @@ class mod_forum_external_testcase extends externallib_advanced_testcase { ); // Test a discussion with two additional posts (total 3 posts). - $posts = mod_forum_external::get_discussion_posts($discussion1->id, 'modified', 'DESC'); + $posts = mod_forum_external::get_discussion_posts($discussion1->id, 'modified', 'DESC', true); $posts = external_api::clean_returnvalue(mod_forum_external::get_discussion_posts_returns(), $posts); $this->assertEquals(3, count($posts['posts'])); @@ -733,6 +733,81 @@ class mod_forum_external_testcase extends externallib_advanced_testcase { } } + /** + * Test get forum posts returns inline attachments. + */ + public function test_mod_forum_get_discussion_posts_inline_attachments() { + global $CFG; + + $this->resetAfterTest(true); + + // Create a course and enrol some users in it. + $course = self::getDataGenerator()->create_course(); + + // Create users. + $user = self::getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($user->id, $course->id); + + + // Set the first created user to the test user. + self::setUser($user); + + // Create test data. + $forum = self::getDataGenerator()->create_module('forum', (object) [ + 'course' => $course->id, + ]); + + // Create a file in a draft area for inline attachments. + $draftidinlineattach = file_get_unused_draft_itemid(); + $draftidattach = file_get_unused_draft_itemid(); + self::setUser($user); + $usercontext = context_user::instance($user->id); + $filepath = '/'; + $filearea = 'draft'; + $component = 'user'; + $filenameimg = 'fakeimage.png'; + $filerecordinline = [ + 'contextid' => $usercontext->id, + 'component' => $component, + 'filearea' => $filearea, + 'itemid' => $draftidinlineattach, + 'filepath' => $filepath, + 'filename' => $filenameimg, + ]; + $fs = get_file_storage(); + $fs->create_file_from_string($filerecordinline, 'image contents (not really)'); + + // Create discussion. + $dummytext = 'Here is an inline image: id}/user/draft/{$draftidinlineattach}/{$filenameimg}" . + '" alt="inlineimage">.'; + $options = [ + [ + 'name' => 'inlineattachmentsid', + 'value' => $draftidinlineattach + ], + [ + 'name' => 'attachmentsid', + 'value' => $draftidattach + ] + ]; + $discussion = mod_forum_external::add_discussion($forum->id, 'the inline attachment subject', $dummytext, + -1, $options); + + $posts = mod_forum_external::get_discussion_posts($discussion['discussionid'], 'modified', 'DESC'); + $posts = external_api::clean_returnvalue(mod_forum_external::get_discussion_posts_returns(), $posts); + $post = $posts['posts'][0]; + $this->assertCount(0, $post['messageinlinefiles']); + $this->assertEmpty($post['messageinlinefiles']); + + $posts = mod_forum_external::get_discussion_posts($discussion['discussionid'], 'modified', 'DESC', + true); + $posts = external_api::clean_returnvalue(mod_forum_external::get_discussion_posts_returns(), $posts); + $post = $posts['posts'][0]; + $this->assertCount(1, $post['messageinlinefiles']); + $this->assertEquals('fakeimage.png', $post['messageinlinefiles'][0]['filename']); + } + /** * Test get forum posts (qanda forum) */ @@ -2574,9 +2649,7 @@ class mod_forum_external_testcase extends externallib_advanced_testcase { 'wordcount' => null, 'author' => $exporteduser2, 'attachments' => [], - 'messageinlinefiles' => [ - 0 => $this->get_expected_attachment($file1), - ], + 'messageinlinefiles' => [], 'tags' => [], 'html' => [ 'rating' => null, @@ -2719,9 +2792,7 @@ class mod_forum_external_testcase extends externallib_advanced_testcase { 'wordcount' => null, 'author' => $exporteduser2, 'attachments' => [], - 'messageinlinefiles' => [ - 0 => $this->get_expected_attachment($file2), - ], + 'messageinlinefiles' => [], 'tags' => [], 'html' => [ 'rating' => null, @@ -3139,7 +3210,7 @@ class mod_forum_external_testcase extends externallib_advanced_testcase { $this->assertFalse(\mod_forum\subscriptions::is_subscribed($user->id, $forum, $discussion->id, $cm)); // Get the post from WS. - $result = mod_forum_external::get_discussion_posts($discussion->id, 'modified', 'DESC'); + $result = mod_forum_external::get_discussion_posts($discussion->id, 'modified', 'DESC', true); $result = external_api::clean_returnvalue(mod_forum_external::get_discussion_posts_returns(), $result); $found = false; foreach ($result['posts'] as $post) {